blob: 4bf9f6041fecbe46bbdddfefc6ff7828d6afbaef [file] [log] [blame]
Abdellatif El Khlifi4970d5b2023-08-04 14:33:41 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
4 *
5 * Authors:
6 * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
7 */
8#include <common.h>
9#include <dm.h>
10#include <mapmem.h>
11#include <string.h>
12#include <asm/global_data.h>
13#include <asm/sandbox_arm_ffa.h>
14#include <asm/sandbox_arm_ffa_priv.h>
15#include <dm/device-internal.h>
16#include <dm/lists.h>
17#include <dm/root.h>
18#include <linux/errno.h>
19#include <linux/sizes.h>
20
21DECLARE_GLOBAL_DATA_PTR;
22
23/* The partitions (SPs) table */
24static struct ffa_partition_desc sandbox_partitions[SANDBOX_PARTITIONS_CNT] = {
25 {
26 .info = { .id = SANDBOX_SP1_ID, .exec_ctxt = 0x5687, .properties = 0x89325621 },
27 .sp_uuid = {
28 .a1 = SANDBOX_SERVICE1_UUID_A1,
29 .a2 = SANDBOX_SERVICE1_UUID_A2,
30 .a3 = SANDBOX_SERVICE1_UUID_A3,
31 .a4 = SANDBOX_SERVICE1_UUID_A4,
32 }
33 },
34 {
35 .info = { .id = SANDBOX_SP3_ID, .exec_ctxt = 0x7687, .properties = 0x23325621 },
36 .sp_uuid = {
37 .a1 = SANDBOX_SERVICE2_UUID_A1,
38 .a2 = SANDBOX_SERVICE2_UUID_A2,
39 .a3 = SANDBOX_SERVICE2_UUID_A3,
40 .a4 = SANDBOX_SERVICE2_UUID_A4,
41 }
42 },
43 {
44 .info = { .id = SANDBOX_SP2_ID, .exec_ctxt = 0x9587, .properties = 0x45325621 },
45 .sp_uuid = {
46 .a1 = SANDBOX_SERVICE1_UUID_A1,
47 .a2 = SANDBOX_SERVICE1_UUID_A2,
48 .a3 = SANDBOX_SERVICE1_UUID_A3,
49 .a4 = SANDBOX_SERVICE1_UUID_A4,
50 }
51 },
52 {
53 .info = { .id = SANDBOX_SP4_ID, .exec_ctxt = 0x1487, .properties = 0x70325621 },
54 .sp_uuid = {
55 .a1 = SANDBOX_SERVICE2_UUID_A1,
56 .a2 = SANDBOX_SERVICE2_UUID_A2,
57 .a3 = SANDBOX_SERVICE2_UUID_A3,
58 .a4 = SANDBOX_SERVICE2_UUID_A4,
59 }
60 }
61
62};
63
64/* The emulator functions */
65
66/**
67 * sandbox_ffa_version() - Emulated FFA_VERSION handler function
68 * @emul: The sandbox FF-A emulator device
69 * @pargs: The SMC call input arguments a0-a7
70 * @res: The SMC return data
71 *
72 * Emulate FFA_VERSION FF-A function.
73 *
74 * Return:
75 *
76 * 0 on success. Otherwise, failure
77 */
78
79static int sandbox_ffa_version(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res)
80{
81 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
82
83 priv->fwk_version = FFA_VERSION_1_0;
84 res->a0 = priv->fwk_version;
85
86 /* x1-x7 MBZ */
87 memset(FFA_X1X7_MBZ_REG_START, 0, FFA_X1X7_MBZ_CNT * sizeof(ulong));
88
89 return 0;
90}
91
92/**
93 * sandbox_ffa_id_get() - Emulated FFA_ID_GET handler function
94 * @emul: The sandbox FF-A emulator device
95 * @pargs: The SMC call input arguments a0-a7
96 * @res: The SMC return data
97 *
98 * Emulate FFA_ID_GET FF-A function.
99 *
100 * Return:
101 *
102 * 0 on success. Otherwise, failure
103 */
104static int sandbox_ffa_id_get(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res)
105{
106 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
107
108 res->a0 = FFA_SMC_32(FFA_SUCCESS);
109 res->a1 = 0;
110
111 priv->id = NS_PHYS_ENDPOINT_ID;
112 res->a2 = priv->id;
113
114 /* x3-x7 MBZ */
115 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
116
117 return 0;
118}
119
120/**
121 * sandbox_ffa_features() - Emulated FFA_FEATURES handler function
122 * @pargs: The SMC call input arguments a0-a7
123 * @res: The SMC return data
124 *
125 * Emulate FFA_FEATURES FF-A function.
126 *
127 * Return:
128 *
129 * 0 on success. Otherwise, failure
130 */
131static int sandbox_ffa_features(ffa_value_t *pargs, ffa_value_t *res)
132{
133 res->a1 = 0;
134
135 if (pargs->a1 == FFA_SMC_64(FFA_RXTX_MAP)) {
136 res->a0 = FFA_SMC_32(FFA_SUCCESS);
137 res->a2 = RXTX_BUFFERS_MIN_SIZE;
138 res->a3 = 0;
139 /* x4-x7 MBZ */
140 memset(FFA_X4X7_MBZ_REG_START, 0, FFA_X4X7_MBZ_CNT * sizeof(ulong));
141 return 0;
142 }
143
144 res->a0 = FFA_SMC_32(FFA_ERROR);
145 res->a2 = -NOT_SUPPORTED;
146 /* x3-x7 MBZ */
147 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
148 log_err("FF-A interface %lx not implemented\n", pargs->a1);
149
150 return ffa_to_std_errmap[NOT_SUPPORTED];
151}
152
153/**
154 * sandbox_ffa_partition_info_get() - Emulated FFA_PARTITION_INFO_GET handler
155 * @emul: The sandbox FF-A emulator device
156 * @pargs: The SMC call input arguments a0-a7
157 * @res: The SMC return data
158 *
159 * Emulate FFA_PARTITION_INFO_GET FF-A function.
160 *
161 * Return:
162 *
163 * 0 on success. Otherwise, failure
164 */
165static int sandbox_ffa_partition_info_get(struct udevice *emul, ffa_value_t *pargs,
166 ffa_value_t *res)
167{
168 struct ffa_partition_info *rxbuf_desc_info = NULL;
169 u32 descs_cnt;
170 u32 descs_size_bytes;
171 int ret;
172 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
173
174 res->a0 = FFA_SMC_32(FFA_ERROR);
175
176 if (!priv->pair.rxbuf) {
177 res->a2 = -DENIED;
178 ret = ffa_to_std_errmap[DENIED];
179 goto cleanup;
180 }
181
182 if (priv->pair_info.rxbuf_owned) {
183 res->a2 = -BUSY;
184 ret = ffa_to_std_errmap[BUSY];
185 goto cleanup;
186 }
187
188 if (!priv->partitions.descs) {
189 priv->partitions.descs = sandbox_partitions;
190 priv->partitions.count = SANDBOX_PARTITIONS_CNT;
191 }
192
193 descs_size_bytes = SANDBOX_PARTITIONS_CNT *
194 sizeof(struct ffa_partition_desc);
195
196 /* Abort if the RX buffer size is smaller than the descs buffer size */
197 if ((priv->pair_info.rxtx_buf_size * SZ_4K) < descs_size_bytes) {
198 res->a2 = -NO_MEMORY;
199 ret = ffa_to_std_errmap[NO_MEMORY];
200 goto cleanup;
201 }
202
203 rxbuf_desc_info = priv->pair.rxbuf;
204
205 /* No UUID specified. Return the information of all partitions */
206 if (!pargs->a1 && !pargs->a2 && !pargs->a3 && !pargs->a4) {
207 for (descs_cnt = 0; descs_cnt < SANDBOX_PARTITIONS_CNT; descs_cnt++)
208 *(rxbuf_desc_info++) = priv->partitions.descs[descs_cnt].info;
209
210 res->a0 = FFA_SMC_32(FFA_SUCCESS);
211 res->a2 = SANDBOX_PARTITIONS_CNT;
212 /* Transfer ownership to the consumer: the non secure world */
213 priv->pair_info.rxbuf_owned = 1;
214 ret = 0;
215
216 goto cleanup;
217 }
218
219 /* A UUID specified. Return the info of all SPs matching the UUID */
220
221 for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++)
222 if (pargs->a1 == priv->partitions.descs[descs_cnt].sp_uuid.a1 &&
223 pargs->a2 == priv->partitions.descs[descs_cnt].sp_uuid.a2 &&
224 pargs->a3 == priv->partitions.descs[descs_cnt].sp_uuid.a3 &&
225 pargs->a4 == priv->partitions.descs[descs_cnt].sp_uuid.a4) {
226 *(rxbuf_desc_info++) = priv->partitions.descs[descs_cnt].info;
227 }
228
229 if (rxbuf_desc_info != priv->pair.rxbuf) {
230 res->a0 = FFA_SMC_32(FFA_SUCCESS);
231 /* Store the partitions count */
232 res->a2 = (ulong)
233 (rxbuf_desc_info - (struct ffa_partition_info *)
234 priv->pair.rxbuf);
235 ret = 0;
236
237 /* Transfer ownership to the consumer: the non secure world */
238 priv->pair_info.rxbuf_owned = 1;
239 } else {
240 /* Unrecognized UUID */
241 res->a2 = -INVALID_PARAMETERS;
242 ret = ffa_to_std_errmap[INVALID_PARAMETERS];
243 }
244
245cleanup:
246
247 log_err("FFA_PARTITION_INFO_GET (%ld)\n", res->a2);
248
249 res->a1 = 0;
250
251 /* x3-x7 MBZ */
252 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
253
254 return ret;
255}
256
257/**
258 * sandbox_ffa_rxtx_map() - Emulated FFA_RXTX_MAP handler
259 * @emul: The sandbox FF-A emulator device
260 * @pargs: The SMC call input arguments a0-a7
261 * @res: The SMC return data
262 *
263 * Emulate FFA_RXTX_MAP FF-A function.
264 *
265 * Return:
266 *
267 * 0 on success. Otherwise, failure
268 */
269static int sandbox_ffa_rxtx_map(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res)
270{
271 int ret;
272 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
273
274 res->a0 = FFA_SMC_32(FFA_ERROR);
275
276 if (priv->pair.txbuf && priv->pair.rxbuf) {
277 res->a2 = -DENIED;
278 ret = ffa_to_std_errmap[DENIED];
279 goto feedback;
280 }
281
282 if (pargs->a3 >= RXTX_BUFFERS_MIN_PAGES && pargs->a1 && pargs->a2) {
283 priv->pair.txbuf = map_sysmem(pargs->a1, 0);
284 priv->pair.rxbuf = map_sysmem(pargs->a2, 0);
285 priv->pair_info.rxtx_buf_size = pargs->a3;
286 priv->pair_info.rxbuf_mapped = 1;
287 res->a0 = FFA_SMC_32(FFA_SUCCESS);
288 res->a2 = 0;
289 ret = 0;
290 goto feedback;
291 }
292
293 if (!pargs->a1 || !pargs->a2) {
294 res->a2 = -INVALID_PARAMETERS;
295 ret = ffa_to_std_errmap[INVALID_PARAMETERS];
296 } else {
297 res->a2 = -NO_MEMORY;
298 ret = ffa_to_std_errmap[NO_MEMORY];
299 }
300
301 log_err("Error in FFA_RXTX_MAP arguments (%d)\n",
302 (int)res->a2);
303
304feedback:
305
306 res->a1 = 0;
307
308 /* x3-x7 MBZ */
309 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
310
311 return ret;
312}
313
314/**
315 * sandbox_ffa_rxtx_unmap() - Emulated FFA_RXTX_UNMAP handler
316 * @emul: The sandbox FF-A emulator device
317 * @pargs: The SMC call input arguments a0-a7
318 * @res: The SMC return data
319 *
320 * Emulate FFA_RXTX_UNMAP FF-A function.
321 *
322 * Return:
323 *
324 * 0 on success. Otherwise, failure
325 */
326static int sandbox_ffa_rxtx_unmap(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res)
327{
328 int ret;
329 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
330
331 res->a0 = FFA_SMC_32(FFA_ERROR);
332 res->a2 = -INVALID_PARAMETERS;
333 ret = ffa_to_std_errmap[INVALID_PARAMETERS];
334
335 if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != priv->id)
336 goto feedback;
337
338 if (priv->pair.txbuf && priv->pair.rxbuf) {
339 priv->pair.txbuf = 0;
340 priv->pair.rxbuf = 0;
341 priv->pair_info.rxtx_buf_size = 0;
342 priv->pair_info.rxbuf_mapped = 0;
343 res->a0 = FFA_SMC_32(FFA_SUCCESS);
344 res->a2 = 0;
345 ret = 0;
346 goto feedback;
347 }
348
349 log_err("No buffer pair registered on behalf of the caller\n");
350
351feedback:
352
353 res->a1 = 0;
354
355 /* x3-x7 MBZ */
356 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
357
358 return ret;
359}
360
361/**
362 * sandbox_ffa_rx_release() - Emulated FFA_RX_RELEASE handler
363 * @emul: The sandbox FF-A emulator device
364 * @pargs: The SMC call input arguments a0-a7
365 * @res: The SMC return data
366 *
367 * Emulate FFA_RX_RELEASE FF-A function.
368 *
369 * Return:
370 *
371 * 0 on success. Otherwise, failure
372 */
373static int sandbox_ffa_rx_release(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res)
374{
375 int ret;
376 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
377
378 if (!priv->pair_info.rxbuf_owned) {
379 res->a0 = FFA_SMC_32(FFA_ERROR);
380 res->a2 = -DENIED;
381 ret = ffa_to_std_errmap[DENIED];
382 } else {
383 priv->pair_info.rxbuf_owned = 0;
384 res->a0 = FFA_SMC_32(FFA_SUCCESS);
385 res->a2 = 0;
386 ret = 0;
387 }
388
389 res->a1 = 0;
390
391 /* x3-x7 MBZ */
392 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
393
394 return ret;
395}
396
397/**
398 * sandbox_ffa_sp_valid() - Check SP validity
399 * @emul: The sandbox FF-A emulator device
400 * @part_id: partition ID to check
401 *
402 * Search the input ID in the descriptors table.
403 *
404 * Return:
405 *
406 * 1 on success (Partition found). Otherwise, failure
407 */
408static int sandbox_ffa_sp_valid(struct udevice *emul, u16 part_id)
409{
410 u32 descs_cnt;
411 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
412
413 for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++)
414 if (priv->partitions.descs[descs_cnt].info.id == part_id)
415 return 1;
416
417 return 0;
418}
419
420/**
421 * sandbox_ffa_msg_send_direct_req() - Emulated FFA_MSG_SEND_DIRECT_{REQ,RESP} handler
422 * @emul: The sandbox FF-A emulator device
423 * @pargs: The SMC call input arguments a0-a7
424 * @res: The SMC return data
425 *
426 * Emulate FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A ABIs.
427 * Only SMC 64-bit is supported in Sandbox.
428 *
429 * Emulating interrupts is not supported. So, FFA_RUN and FFA_INTERRUPT are not
430 * supported. In case of success FFA_MSG_SEND_DIRECT_RESP is returned with
431 * default pattern data (0xff).
432 *
433 * Return:
434 *
435 * 0 on success. Otherwise, failure
436 */
437static int sandbox_ffa_msg_send_direct_req(struct udevice *emul,
438 ffa_value_t *pargs, ffa_value_t *res)
439{
440 u16 part_id;
441 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
442
443 part_id = GET_DST_SP_ID(pargs->a1);
444
445 if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != priv->id ||
446 !sandbox_ffa_sp_valid(emul, part_id) || pargs->a2) {
447 res->a0 = FFA_SMC_32(FFA_ERROR);
448 res->a1 = 0;
449 res->a2 = -INVALID_PARAMETERS;
450
451 /* x3-x7 MBZ */
452 memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong));
453
454 return ffa_to_std_errmap[INVALID_PARAMETERS];
455 }
456
457 res->a0 = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP);
458
459 res->a1 = PREP_SRC_SP_ID(part_id) |
460 PREP_NS_PHYS_ENDPOINT_ID(priv->id);
461
462 res->a2 = 0;
463
464 /* Return 0xff bytes as a response */
465 res->a3 = -1UL;
466 res->a4 = -1UL;
467 res->a5 = -1UL;
468 res->a6 = -1UL;
469 res->a7 = -1UL;
470
471 return 0;
472}
473
474/**
475 * sandbox_ffa_get_rxbuf_flags() - Read the mapping/ownership flags
476 * @emul: The sandbox FF-A emulator device
477 * @queried_func_id: The FF-A function to be queried
478 * @func_data: Pointer to the FF-A function arguments container structure
479 *
480 * Query the status flags of the following emulated
481 * ABIs: FFA_RXTX_MAP, FFA_RXTX_UNMAP, FFA_RX_RELEASE.
482 *
483 * Return:
484 *
485 * 0 on success. Otherwise, failure
486 */
487static int sandbox_ffa_get_rxbuf_flags(struct udevice *emul, u32 queried_func_id,
488 struct ffa_sandbox_data *func_data)
489{
490 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
491
492 if (!func_data)
493 return -EINVAL;
494
495 if (!func_data->data0 || func_data->data0_size != sizeof(u8))
496 return -EINVAL;
497
498 switch (queried_func_id) {
499 case FFA_RXTX_MAP:
500 case FFA_RXTX_UNMAP:
501 *((u8 *)func_data->data0) = priv->pair_info.rxbuf_mapped;
502 return 0;
503 case FFA_RX_RELEASE:
504 *((u8 *)func_data->data0) = priv->pair_info.rxbuf_owned;
505 return 0;
506 default:
507 log_err("The querried FF-A interface flag (%d) undefined\n",
508 queried_func_id);
509 return -EINVAL;
510 }
511}
512
513/**
514 * sandbox_ffa_get_fwk_version() - Return the FFA framework version
515 * @emul: The sandbox FF-A emulator device
516 * @func_data: Pointer to the FF-A function arguments container structure
517 *
518 * Return the FFA framework version read from the FF-A emulator data.
519 *
520 * Return:
521 *
522 * 0 on success. Otherwise, failure
523 */
524static int sandbox_ffa_get_fwk_version(struct udevice *emul, struct ffa_sandbox_data *func_data)
525{
526 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
527
528 if (!func_data)
529 return -EINVAL;
530
531 if (!func_data->data0 ||
532 func_data->data0_size != sizeof(priv->fwk_version))
533 return -EINVAL;
534
535 *((u32 *)func_data->data0) = priv->fwk_version;
536
537 return 0;
538}
539
540/**
541 * sandbox_ffa_get_parts() - Return the address of partitions data
542 * @emul: The sandbox FF-A emulator device
543 * @func_data: Pointer to the FF-A function arguments container structure
544 *
545 * Return the address of partitions data read from the FF-A emulator data.
546 *
547 * Return:
548 *
549 * 0 on success. Otherwise, failure
550 */
551static int sandbox_ffa_get_parts(struct udevice *emul, struct ffa_sandbox_data *func_data)
552{
553 struct sandbox_ffa_emul *priv = dev_get_priv(emul);
554
555 if (!func_data)
556 return -EINVAL;
557
558 if (!func_data->data0 ||
559 func_data->data0_size != sizeof(struct ffa_partitions *))
560 return -EINVAL;
561
562 *((struct ffa_partitions **)func_data->data0) = &priv->partitions;
563
564 return 0;
565}
566
567/**
568 * sandbox_query_ffa_emul_state() - Inspect the FF-A ABIs
569 * @queried_func_id: The FF-A function to be queried
570 * @func_data: Pointer to the FF-A function arguments container structure
571 *
572 * Query the status of FF-A ABI specified in the input argument.
573 *
574 * Return:
575 *
576 * 0 on success. Otherwise, failure
577 */
578int sandbox_query_ffa_emul_state(u32 queried_func_id,
579 struct ffa_sandbox_data *func_data)
580{
581 struct udevice *emul;
582 int ret;
583
584 ret = uclass_first_device_err(UCLASS_FFA_EMUL, &emul);
585 if (ret) {
586 log_err("Cannot find FF-A emulator during querying state\n");
587 return ret;
588 }
589
590 switch (queried_func_id) {
591 case FFA_RXTX_MAP:
592 case FFA_RXTX_UNMAP:
593 case FFA_RX_RELEASE:
594 return sandbox_ffa_get_rxbuf_flags(emul, queried_func_id, func_data);
595 case FFA_VERSION:
596 return sandbox_ffa_get_fwk_version(emul, func_data);
597 case FFA_PARTITION_INFO_GET:
598 return sandbox_ffa_get_parts(emul, func_data);
599 default:
600 log_err("Undefined FF-A interface (%d)\n",
601 queried_func_id);
602 return -EINVAL;
603 }
604}
605
606/**
607 * sandbox_arm_ffa_smccc_smc() - FF-A SMC call emulation
608 * @args: the SMC call arguments
609 * @res: the SMC call returned data
610 *
611 * Emulate the FF-A ABIs SMC call.
612 * The emulated FF-A ABI is identified and invoked.
613 * FF-A emulation is based on the FF-A specification 1.0
614 *
615 * Return:
616 *
617 * 0 on success. Otherwise, failure.
618 * FF-A protocol error codes are returned using the registers arguments as
619 * described by the specification
620 */
621void sandbox_arm_ffa_smccc_smc(ffa_value_t *args, ffa_value_t *res)
622{
623 int ret = 0;
624 struct udevice *emul;
625
626 ret = uclass_first_device_err(UCLASS_FFA_EMUL, &emul);
627 if (ret) {
628 log_err("Cannot find FF-A emulator during SMC emulation\n");
629 return;
630 }
631
632 switch (args->a0) {
633 case FFA_SMC_32(FFA_VERSION):
634 ret = sandbox_ffa_version(emul, args, res);
635 break;
636 case FFA_SMC_32(FFA_PARTITION_INFO_GET):
637 ret = sandbox_ffa_partition_info_get(emul, args, res);
638 break;
639 case FFA_SMC_32(FFA_RXTX_UNMAP):
640 ret = sandbox_ffa_rxtx_unmap(emul, args, res);
641 break;
642 case FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ):
643 ret = sandbox_ffa_msg_send_direct_req(emul, args, res);
644 break;
645 case FFA_SMC_32(FFA_ID_GET):
646 ret = sandbox_ffa_id_get(emul, args, res);
647 break;
648 case FFA_SMC_32(FFA_FEATURES):
649 ret = sandbox_ffa_features(args, res);
650 break;
651 case FFA_SMC_64(FFA_RXTX_MAP):
652 ret = sandbox_ffa_rxtx_map(emul, args, res);
653 break;
654 case FFA_SMC_32(FFA_RX_RELEASE):
655 ret = sandbox_ffa_rx_release(emul, args, res);
656 break;
657 default:
658 log_err("Undefined FF-A interface (%lx)\n",
659 args->a0);
660 }
661
662 if (ret != 0)
663 log_err("FF-A ABI internal failure (%d)\n", ret);
664}
665
666/**
667 * invoke_ffa_fn() - SMC wrapper
668 * @args: FF-A ABI arguments to be copied to Xn registers
669 * @res: FF-A ABI return data to be copied from Xn registers
670 *
671 * Calls the emulated SMC call.
672 */
673void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res)
674{
675 sandbox_arm_ffa_smccc_smc(&args, res);
676}
677
678/**
679 * ffa_emul_find() - Find the FF-A emulator
680 * @dev: the sandbox FF-A device (sandbox-arm-ffa)
681 * @emulp: the FF-A emulator device (sandbox-ffa-emul)
682 *
683 * Search for the FF-A emulator and returns its device pointer.
684 *
685 * Return:
686 * 0 on success. Otherwise, failure
687 */
688int ffa_emul_find(struct udevice *dev, struct udevice **emulp)
689{
690 int ret;
691
692 ret = uclass_first_device_err(UCLASS_FFA_EMUL, emulp);
693 if (ret) {
694 log_err("Cannot find FF-A emulator\n");
695 return ret;
696 }
697
Abdellatif El Khlifibf036192023-08-09 12:47:30 +0100698 log_debug("FF-A emulator ready to use\n");
Abdellatif El Khlifi4970d5b2023-08-04 14:33:41 +0100699
700 return 0;
701}
702
703UCLASS_DRIVER(ffa_emul) = {
704 .name = "ffa_emul",
705 .id = UCLASS_FFA_EMUL,
706 .post_bind = dm_scan_fdt_dev,
707};
708
709static const struct udevice_id sandbox_ffa_emul_ids[] = {
710 { .compatible = "sandbox,arm-ffa-emul" },
711 { }
712};
713
714/* Declaring the sandbox FF-A emulator under UCLASS_FFA_EMUL */
715U_BOOT_DRIVER(sandbox_ffa_emul) = {
716 .name = "sandbox_ffa_emul",
717 .id = UCLASS_FFA_EMUL,
718 .of_match = sandbox_ffa_emul_ids,
719 .priv_auto = sizeof(struct sandbox_ffa_emul),
720};