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