blob: 739f7810c19dc0fa80dc5823e1d7eccbe8f6a7a3 [file] [log] [blame]
Patrick Williams8dd68482022-10-04 07:57:18 -05001From 553b57e39808ef04bc6aa54e0324f92b0175e476 Mon Sep 17 00:00:00 2001
2From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
3Date: Mon, 6 Jun 2022 12:55:08 +0100
4Subject: [PATCH 11/26] arm_ffa: introduce the FF-A Sandbox driver
5
6Provide a Sandbox driver to emulate the FF-A ABIs
7
8The emulated ABIs are those supported by the FF-A core driver
9and according to FF-A specification v1.0.
10
11The Sandbox driver provides operations allowing the test
12application to read the status of all the inspected ABIs
13and perform functional tests based on that.
14
15Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
16Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20220926101723.9965-1-abdellatif.elkhlifi@arm.com/]
17---
18
19Changelog:
20===============
21
22v4: align sandbox driver with the new FF-A driver interfaces
23 and new way of error handling
24
25v1: introduce the sandbox driver
26
27 MAINTAINERS | 1 +
28 common/board_r.c | 2 +-
29 configs/sandbox64_defconfig | 2 +
30 configs/sandbox_defconfig | 2 +
31 doc/arch/sandbox.rst | 1 +
32 drivers/firmware/arm-ffa/Kconfig | 10 +-
33 drivers/firmware/arm-ffa/Makefile | 1 +
34 drivers/firmware/arm-ffa/arm_ffa_prv.h | 15 +-
35 drivers/firmware/arm-ffa/core.c | 24 +-
36 drivers/firmware/arm-ffa/sandbox.c | 659 ++++++++++++++++++
37 .../firmware/arm-ffa/sandbox_arm_ffa_prv.h | 144 ++++
38 include/arm_ffa.h | 2 +-
39 include/sandbox_arm_ffa.h | 91 +++
40 lib/efi_loader/efi_boottime.c | 2 +-
41 14 files changed, 941 insertions(+), 15 deletions(-)
42 create mode 100644 drivers/firmware/arm-ffa/sandbox.c
43 create mode 100644 drivers/firmware/arm-ffa/sandbox_arm_ffa_prv.h
44 create mode 100644 include/sandbox_arm_ffa.h
45
46diff --git a/MAINTAINERS b/MAINTAINERS
47index 9f0a1b7387..96157db6b6 100644
48--- a/MAINTAINERS
49+++ b/MAINTAINERS
50@@ -251,6 +251,7 @@ F: cmd/armffa.c
51 F: doc/README.ffa.drv
52 F: drivers/firmware/arm-ffa/
53 F: include/arm_ffa.h
54+F: include/sandbox_arm_ffa.h
55
56 ARM FREESCALE IMX
57 M: Stefano Babic <sbabic@denx.de>
58diff --git a/common/board_r.c b/common/board_r.c
59index c75634286b..f838cd5958 100644
60--- a/common/board_r.c
61+++ b/common/board_r.c
62@@ -783,7 +783,7 @@ static init_fnc_t init_sequence_r[] = {
63 INIT_FUNC_WATCHDOG_RESET
64 initr_net,
65 #endif
66-#ifdef CONFIG_ARM_FFA_TRANSPORT
67+#if defined(CONFIG_ARM_FFA_TRANSPORT) && !defined(CONFIG_SANDBOX_FFA)
68 ffa_bus_discover,
69 #endif
70 #ifdef CONFIG_POST
71diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
72index d7f22b39ae..78bc5aaa96 100644
73--- a/configs/sandbox64_defconfig
74+++ b/configs/sandbox64_defconfig
75@@ -250,3 +250,5 @@ CONFIG_TEST_FDTDEC=y
76 CONFIG_UNIT_TEST=y
77 CONFIG_UT_TIME=y
78 CONFIG_UT_DM=y
79+CONFIG_ARM_FFA_TRANSPORT=y
80+CONFIG_SANDBOX_FFA=y
81\ No newline at end of file
82diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
83index c509a924e6..8942aa7157 100644
84--- a/configs/sandbox_defconfig
85+++ b/configs/sandbox_defconfig
86@@ -327,3 +327,5 @@ CONFIG_TEST_FDTDEC=y
87 CONFIG_UNIT_TEST=y
88 CONFIG_UT_TIME=y
89 CONFIG_UT_DM=y
90+CONFIG_ARM_FFA_TRANSPORT=y
91+CONFIG_SANDBOX_FFA=y
92\ No newline at end of file
93diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
94index 068d4a3be4..5d7e1b2c48 100644
95--- a/doc/arch/sandbox.rst
96+++ b/doc/arch/sandbox.rst
97@@ -203,6 +203,7 @@ Supported Drivers
98
99 U-Boot sandbox supports these emulations:
100
101+- Arm FF-A
102 - Block devices
103 - Chrome OS EC
104 - GPIO
105diff --git a/drivers/firmware/arm-ffa/Kconfig b/drivers/firmware/arm-ffa/Kconfig
106index 40b467b0a5..263481de96 100644
107--- a/drivers/firmware/arm-ffa/Kconfig
108+++ b/drivers/firmware/arm-ffa/Kconfig
109@@ -2,8 +2,8 @@
110
111 config ARM_FFA_TRANSPORT
112 bool "Enable Arm Firmware Framework for Armv8-A driver"
113- depends on DM && ARM64
114- select ARM_SMCCC
115+ depends on DM && (ARM64 || SANDBOX)
116+ select ARM_SMCCC if !SANDBOX
117 select CMD_ARMFFA
118 select LIB_UUID
119 select DEVRES
120@@ -38,3 +38,9 @@ config ARM_FFA_EFI_RUNTIME_MODE
121 The driver Code needed at runtime is placed at EFI runtime code section.
122 Turning this on makes ffa_copy_runtime_data available for use and the driver
123 code placed at EFI runtime code section.
124+
125+config SANDBOX_FFA
126+ bool "FF-A Sandbox driver"
127+ depends on ARM_FFA_TRANSPORT && SANDBOX
128+ help
129+ This emulates the FF-A handling under Sandbox and allows to test the FF-A driver
130diff --git a/drivers/firmware/arm-ffa/Makefile b/drivers/firmware/arm-ffa/Makefile
131index 0b9b0a61b4..d50060b836 100644
132--- a/drivers/firmware/arm-ffa/Makefile
133+++ b/drivers/firmware/arm-ffa/Makefile
134@@ -5,3 +5,4 @@
135
136 obj-y += arm-ffa-uclass.o core.o
137 obj-$(CONFIG_ARM_FFA_EFI_RUNTIME_MODE) += efi_ffa_runtime_data_mgr.o
138+obj-$(CONFIG_SANDBOX_FFA) += sandbox.o
139diff --git a/drivers/firmware/arm-ffa/arm_ffa_prv.h b/drivers/firmware/arm-ffa/arm_ffa_prv.h
140index 7bc90f7f66..3e0d4c112c 100644
141--- a/drivers/firmware/arm-ffa/arm_ffa_prv.h
142+++ b/drivers/firmware/arm-ffa/arm_ffa_prv.h
143@@ -19,6 +19,16 @@
144 /* FF-A core driver name */
145 #define FFA_DRV_NAME "arm_ffa"
146
147+/* The FF-A SMC function definitions */
148+
149+#if CONFIG_IS_ENABLED(SANDBOX_FFA)
150+#include "sandbox_arm_ffa.h"
151+#else
152+typedef struct arm_smccc_1_2_regs ffa_value_t;
153+#endif
154+
155+typedef void (*invoke_ffa_fn_t)(ffa_value_t args, ffa_value_t *res);
156+
157 /* FF-A driver version definitions */
158
159 #define MAJOR_VERSION_MASK GENMASK(30, 16)
160@@ -94,11 +104,6 @@ struct ffa_abi_errmap {
161 #define FFA_ERRMAP_COUNT (FFA_LAST_ID - FFA_FIRST_ID + 1)
162 #define FFA_ID_TO_ERRMAP_ID(ffa_id) ((ffa_id) - FFA_FIRST_ID)
163
164-/* The FF-A SMC function definitions */
165-
166-typedef struct arm_smccc_1_2_regs ffa_value_t;
167-typedef void (*invoke_ffa_fn_t)(ffa_value_t args, ffa_value_t *res);
168-
169 /*
170 * struct ffa_partition_uuid - 16 bytes UUID transmitted by FFA_PARTITION_INFO_GET
171 * @a1-4: 32-bit words access to the UUID data
172diff --git a/drivers/firmware/arm-ffa/core.c b/drivers/firmware/arm-ffa/core.c
173index 41c7b96e68..caba10caae 100644
174--- a/drivers/firmware/arm-ffa/core.c
175+++ b/drivers/firmware/arm-ffa/core.c
176@@ -1101,6 +1101,7 @@ static int __ffa_runtime ffa_msg_send_direct_req(u16 dst_part_id, struct ffa_sen
177 return ffa_to_std_errno(ffa_errno);
178 }
179
180+#if !CONFIG_IS_ENABLED(SANDBOX_FFA)
181 /**
182 * __arm_ffa_fn_smc - SMC wrapper
183 * @args: FF-A ABI arguments to be copied to Xn registers
184@@ -1114,6 +1115,7 @@ void __ffa_runtime __arm_ffa_fn_smc(ffa_value_t args, ffa_value_t *res)
185 {
186 arm_smccc_1_2_smc(&args, res);
187 }
188+#endif
189
190 /**
191 * ffa_set_smc_conduit - Set the SMC conduit
192@@ -1127,7 +1129,12 @@ void __ffa_runtime __arm_ffa_fn_smc(ffa_value_t args, ffa_value_t *res)
193 */
194 static int ffa_set_smc_conduit(void)
195 {
196- ffa_priv_data->invoke_ffa_fn = __arm_ffa_fn_smc;
197+#if CONFIG_IS_ENABLED(SANDBOX_FFA)
198+ ffa_priv_data->invoke_ffa_fn = sandbox_arm_ffa_smccc_smc;
199+ ffa_info("Using SMC emulation");
200+#else
201+ ffa_priv_data->invoke_ffa_fn = __arm_ffa_fn_smc;
202+#endif
203
204 if (!ffa_priv_data->invoke_ffa_fn) {
205 ffa_err("failure to set the invoke function");
206@@ -1304,17 +1311,18 @@ struct ffa_prvdata **ffa_bus_prvdata_get(void)
207 }
208
209 /**
210- * ffa_bus_discover - discover FF-A bus and probe the arm_ffa device
211+ * ffa_bus_discover - discover FF-A bus and probe arm_ffa and sandbox_arm_ffa devices
212 *
213 * This boot time function makes sure the FF-A bus is discoverable.
214- * Then, the arm_ffa device is probed and ready to use.
215+ * Then, the arm_ffa and sandbox_arm_ffa devices are ready to use.
216+ *
217 * This function is called automatically at initcalls
218 * level (after u-boot relocation).
219 *
220 * When the bus was already discovered successfully the discovery will not run again.
221 *
222 * Arm FF-A transport is implemented through arm_ffa u-boot device managing the FF-A
223- * communication.
224+ * communication. In Sandbox mode sandbox_arm_ffa is used to test arm_ffa driver.
225 * All FF-A clients should use the arm_ffa device to use the FF-A transport.
226 *
227 * Return:
228@@ -1325,9 +1333,15 @@ int ffa_bus_discover(void)
229 {
230 int ret = 0;
231
232- if (!ffa_priv_data)
233+ if (!ffa_priv_data) {
234 ret = ffa_device_get();
235
236+#if CONFIG_IS_ENABLED(SANDBOX_FFA)
237+ if (ret == 0)
238+ ret = sandbox_ffa_device_get();
239+#endif
240+ }
241+
242 return ret;
243 }
244
245diff --git a/drivers/firmware/arm-ffa/sandbox.c b/drivers/firmware/arm-ffa/sandbox.c
246new file mode 100644
247index 0000000000..16e1fdc809
248--- /dev/null
249+++ b/drivers/firmware/arm-ffa/sandbox.c
250@@ -0,0 +1,659 @@
251+// SPDX-License-Identifier: GPL-2.0+
252+/*
253+ * (C) Copyright 2022 ARM Limited
254+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
255+ */
256+
257+#include "sandbox_arm_ffa_prv.h"
258+#include <asm/global_data.h>
259+#include <common.h>
260+#include <dm.h>
261+#include <dm/device-internal.h>
262+#include <dm/root.h>
263+#include <linux/errno.h>
264+#include <linux/sizes.h>
265+#include <mapmem.h>
266+#include <string.h>
267+
268+DECLARE_GLOBAL_DATA_PTR;
269+
270+/**
271+ * The device private data structure containing all the emulated secure world data
272+ */
273+static struct sandbox_ffa_prvdata sandbox_ffa_priv_data = {0};
274+
275+/* The partitions (SPs) table */
276+static struct ffa_partition_desc sandbox_partitions[SANDBOX_PARTITIONS_CNT] = {
277+ {
278+ .info = { .id = SANDBOX_SP1_ID, .exec_ctxt = 0x5687, .properties = 0x89325621 },
279+ .sp_uuid = {
280+ .a1 = SANDBOX_SERVICE1_UUID_A1,
281+ .a2 = SANDBOX_SERVICE1_UUID_A2,
282+ .a3 = SANDBOX_SERVICE1_UUID_A3,
283+ .a4 = SANDBOX_SERVICE1_UUID_A4,
284+ }
285+ },
286+ {
287+ .info = { .id = SANDBOX_SP2_ID, .exec_ctxt = 0x9587, .properties = 0x45325621 },
288+ .sp_uuid = {
289+ .a1 = SANDBOX_SERVICE2_UUID_A1,
290+ .a2 = SANDBOX_SERVICE2_UUID_A2,
291+ .a3 = SANDBOX_SERVICE2_UUID_A3,
292+ .a4 = SANDBOX_SERVICE2_UUID_A4,
293+ }
294+ },
295+ {
296+ .info = { .id = SANDBOX_SP3_ID, .exec_ctxt = 0x7687, .properties = 0x23325621 },
297+ .sp_uuid = {
298+ .a1 = SANDBOX_SERVICE1_UUID_A1,
299+ .a2 = SANDBOX_SERVICE1_UUID_A2,
300+ .a3 = SANDBOX_SERVICE1_UUID_A3,
301+ .a4 = SANDBOX_SERVICE1_UUID_A4,
302+ }
303+ },
304+ {
305+ .info = { .id = SANDBOX_SP4_ID, .exec_ctxt = 0x1487, .properties = 0x70325621 },
306+ .sp_uuid = {
307+ .a1 = SANDBOX_SERVICE2_UUID_A1,
308+ .a2 = SANDBOX_SERVICE2_UUID_A2,
309+ .a3 = SANDBOX_SERVICE2_UUID_A3,
310+ .a4 = SANDBOX_SERVICE2_UUID_A4,
311+ }
312+ }
313+
314+};
315+
316+/*
317+ * Driver functions
318+ */
319+
320+/**
321+ * sandbox_ffa_get_device - probes the sandbox_arm_ffa device
322+ *
323+ * This function makes sure the sandbox_arm_ffa device is probed
324+ * This function makes sure the sandbox_arm_ffa device is
325+ * created, bound to this driver, probed and ready to use.
326+ *
327+ * sandbox_arm_ffa depends on arm_ffa device. This dependency is
328+ * handled by ffa_bus_discover function. arm_ffa is probed first then
329+ * sandbox_arm_ffa.
330+ *
331+ * Return:
332+ *
333+ * 0 on success. Otherwise, failure
334+ */
335+int sandbox_ffa_device_get(void)
336+{
337+ int ret;
338+
339+ if (sandbox_ffa_priv_data.dev)
340+ return 0;
341+
342+ ret = device_bind(dm_root(),
343+ DM_DRIVER_GET(sandbox_arm_ffa),
344+ FFA_SANDBOX_DRV_NAME,
345+ NULL,
346+ ofnode_null(),
347+ &sandbox_ffa_priv_data.dev);
348+ if (ret) {
349+ sandbox_ffa_priv_data.dev = NULL;
350+ return ret;
351+ }
352+
353+ ret = device_probe(sandbox_ffa_priv_data.dev);
354+ if (ret) {
355+ ffa_err("[Sandbox] can not probe the device");
356+ device_unbind(sandbox_ffa_priv_data.dev);
357+ sandbox_ffa_priv_data.dev = NULL;
358+ return ret;
359+ }
360+
361+ return 0;
362+}
363+
364+/**
365+ * sandbox_ffa_version - Emulated FFA_VERSION handler function
366+ * @{a0-a7} , res: The SMC call arguments and return structure.
367+ *
368+ * This is the function that emulates FFA_VERSION FF-A function.
369+ *
370+ * Return:
371+ *
372+ * 0 on success. Otherwise, failure
373+ */
374+SANDBOX_SMC_FFA_ABI(ffa_version)
375+{
376+ sandbox_ffa_priv_data.fwk_version = FFA_VERSION_1_0;
377+ res->a0 = sandbox_ffa_priv_data.fwk_version;
378+
379+ /* x1-x7 MBZ */
380+ memset(FFA_X1X7_MBZ_REG_START, 0, FFA_X1X7_MBZ_CNT * sizeof(unsigned long));
381+
382+ return 0;
383+}
384+
385+/**
386+ * sandbox_ffa_id_get - Emulated FFA_ID_GET handler function
387+ * @{a0-a7} , res: The SMC call arguments and return structure.
388+ *
389+ * This is the function that emulates FFA_ID_GET FF-A function.
390+ *
391+ * Return:
392+ *
393+ * 0 on success. Otherwise, failure
394+ */
395+SANDBOX_SMC_FFA_ABI(ffa_id_get)
396+{
397+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
398+ res->a1 = 0;
399+
400+ sandbox_ffa_priv_data.id = NS_PHYS_ENDPOINT_ID;
401+ res->a2 = sandbox_ffa_priv_data.id;
402+
403+ /* x3-x7 MBZ */
404+ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
405+
406+ return 0;
407+}
408+
409+/**
410+ * sandbox_ffa_features - Emulated FFA_FEATURES handler function
411+ * @{a0-a7} , res: The SMC call arguments and return structure.
412+ *
413+ * This is the function that emulates FFA_FEATURES FF-A function.
414+ *
415+ * Return:
416+ *
417+ * 0 on success. Otherwise, failure
418+ */
419+SANDBOX_SMC_FFA_ABI(ffa_features)
420+{
421+ if (pargs->a1 == FFA_SMC_64(FFA_RXTX_MAP)) {
422+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
423+ res->a2 = RXTX_BUFFERS_MIN_SIZE;
424+ res->a3 = 0;
425+ /* x4-x7 MBZ */
426+ memset(FFA_X4X7_MBZ_REG_START,
427+ 0, FFA_X4X7_MBZ_CNT * sizeof(unsigned long));
428+ } else {
429+ res->a0 = FFA_SMC_32(FFA_ERROR);
430+ res->a2 = FFA_ERR_STAT_NOT_SUPPORTED;
431+ /* x3-x7 MBZ */
432+ memset(FFA_X3_MBZ_REG_START,
433+ 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
434+ ffa_err("[Sandbox] FF-A interface 0x%lx not implemented", pargs->a1);
435+ }
436+
437+ res->a1 = 0;
438+
439+ return 0;
440+}
441+
442+/**
443+ * sandbox_ffa_partition_info_get - Emulated FFA_PARTITION_INFO_GET handler function
444+ * @{a0-a7} , res: The SMC call arguments and return structure.
445+ *
446+ * This is the function that emulates FFA_PARTITION_INFO_GET FF-A function.
447+ *
448+ * Return:
449+ *
450+ * 0 on success. Otherwise, failure
451+ */
452+SANDBOX_SMC_FFA_ABI(ffa_partition_info_get)
453+{
454+ struct ffa_partition_info *rxbuf_desc_info = NULL;
455+ u32 descs_cnt;
456+ u32 descs_size_bytes;
457+
458+ res->a0 = FFA_SMC_32(FFA_ERROR);
459+
460+ if (!sandbox_ffa_priv_data.pair.rxbuf) {
461+ res->a2 = FFA_ERR_STAT_DENIED;
462+ goto cleanup;
463+ }
464+
465+ if (sandbox_ffa_priv_data.pair_info.rxbuf_owned) {
466+ res->a2 = FFA_ERR_STAT_BUSY;
467+ goto cleanup;
468+ }
469+
470+ if (!sandbox_ffa_priv_data.partitions.descs) {
471+ sandbox_ffa_priv_data.partitions.descs = sandbox_partitions;
472+ sandbox_ffa_priv_data.partitions.count = SANDBOX_PARTITIONS_CNT;
473+ }
474+
475+ descs_size_bytes = SANDBOX_PARTITIONS_CNT * sizeof(struct ffa_partition_desc);
476+
477+ /* Abort if the RX buffer size is smaller than the descriptors buffer size */
478+ if ((sandbox_ffa_priv_data.pair_info.rxtx_buf_size * SZ_4K) < descs_size_bytes) {
479+ res->a2 = FFA_ERR_STAT_NO_MEMORY;
480+ goto cleanup;
481+ }
482+
483+ rxbuf_desc_info = (struct ffa_partition_info *)sandbox_ffa_priv_data.pair.rxbuf;
484+
485+ /* No UUID specified. Return the information of all partitions */
486+ if (!pargs->a1 && !pargs->a2 && !pargs->a3 && !pargs->a4) {
487+ for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++)
488+ *(rxbuf_desc_info++) =
489+ sandbox_ffa_priv_data.partitions.descs[descs_cnt].info;
490+
491+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
492+ res->a2 = SANDBOX_PARTITIONS_CNT;
493+ /* transfer ownership to the consumer: the non secure world */
494+ sandbox_ffa_priv_data.pair_info.rxbuf_owned = 1;
495+
496+ goto cleanup;
497+ }
498+
499+ /*
500+ * A UUID is specified. Return the information of all partitions matching
501+ * the UUID
502+ */
503+
504+ for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++)
505+ if (pargs->a1 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].sp_uuid.a1 &&
506+ pargs->a2 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].sp_uuid.a2 &&
507+ pargs->a3 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].sp_uuid.a3 &&
508+ pargs->a4 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].sp_uuid.a4) {
509+ *(rxbuf_desc_info++) =
510+ sandbox_ffa_priv_data.partitions.descs[descs_cnt].info;
511+ }
512+
513+ if (rxbuf_desc_info != ((struct ffa_partition_info *)sandbox_ffa_priv_data.pair.rxbuf)) {
514+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
515+ /* store the partitions count */
516+ res->a2 = (unsigned long)
517+ (rxbuf_desc_info - (struct ffa_partition_info *)
518+ sandbox_ffa_priv_data.pair.rxbuf);
519+
520+ /* transfer ownership to the consumer: the non secure world */
521+ sandbox_ffa_priv_data.pair_info.rxbuf_owned = 1;
522+ } else {
523+ /* Unrecognized UUID */
524+ res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS;
525+ }
526+
527+cleanup:
528+
529+ ffa_err("[Sandbox] FFA_PARTITION_INFO_GET (%ld)", res->a2);
530+
531+ res->a1 = 0;
532+
533+ /* x3-x7 MBZ */
534+ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
535+
536+ return 0;
537+}
538+
539+/**
540+ * sandbox_ffa_rxtx_map - Emulated FFA_RXTX_MAP handler function
541+ * @{a0-a7} , res: The SMC call arguments and return structure.
542+ *
543+ * This is the function that emulates FFA_RXTX_MAP FF-A function.
544+ *
545+ * Return:
546+ *
547+ * 0 on success. Otherwise, failure
548+ */
549+SANDBOX_SMC_FFA_ABI(ffa_rxtx_map)
550+{
551+ res->a0 = FFA_SMC_32(FFA_ERROR);
552+
553+ if (sandbox_ffa_priv_data.pair.txbuf && sandbox_ffa_priv_data.pair.rxbuf) {
554+ res->a2 = FFA_ERR_STAT_DENIED;
555+ goto feedback;
556+ }
557+
558+ if (pargs->a3 >= RXTX_BUFFERS_MIN_PAGES && pargs->a1 && pargs->a2) {
559+ sandbox_ffa_priv_data.pair.txbuf = pargs->a1;
560+ sandbox_ffa_priv_data.pair.rxbuf = pargs->a2;
561+ sandbox_ffa_priv_data.pair_info.rxtx_buf_size = pargs->a3;
562+ sandbox_ffa_priv_data.pair_info.rxbuf_mapped = 1;
563+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
564+ res->a2 = 0;
565+ goto feedback;
566+ }
567+
568+ if (!pargs->a1 || !pargs->a2)
569+ res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS;
570+ else
571+ res->a2 = FFA_ERR_STAT_NO_MEMORY;
572+
573+ ffa_err("[Sandbox] error in FFA_RXTX_MAP arguments (%d)", (int)res->a2);
574+
575+feedback:
576+
577+ res->a1 = 0;
578+
579+ /* x3-x7 MBZ */
580+ memset(FFA_X3_MBZ_REG_START,
581+ 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
582+
583+ return 0;
584+}
585+
586+/**
587+ * sandbox_ffa_rxtx_unmap - Emulated FFA_RXTX_UNMAP handler function
588+ * @{a0-a7} , res: The SMC call arguments and return structure.
589+ *
590+ * This is the function that emulates FFA_RXTX_UNMAP FF-A function.
591+ *
592+ * Return:
593+ *
594+ * 0 on success. Otherwise, failure
595+ */
596+SANDBOX_SMC_FFA_ABI(ffa_rxtx_unmap)
597+{
598+ res->a0 = FFA_SMC_32(FFA_ERROR);
599+ res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS;
600+
601+ if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != sandbox_ffa_priv_data.id)
602+ goto feedback;
603+
604+ if (sandbox_ffa_priv_data.pair.txbuf && sandbox_ffa_priv_data.pair.rxbuf) {
605+ sandbox_ffa_priv_data.pair.txbuf = 0;
606+ sandbox_ffa_priv_data.pair.rxbuf = 0;
607+ sandbox_ffa_priv_data.pair_info.rxtx_buf_size = 0;
608+ sandbox_ffa_priv_data.pair_info.rxbuf_mapped = 0;
609+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
610+ res->a2 = 0;
611+ goto feedback;
612+ }
613+
614+ ffa_err("[Sandbox] No buffer pair registered on behalf of the caller");
615+
616+feedback:
617+
618+ res->a1 = 0;
619+
620+ /* x3-x7 MBZ */
621+ memset(FFA_X3_MBZ_REG_START,
622+ 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
623+
624+ return 0;
625+}
626+
627+/**
628+ * sandbox_ffa_rx_release - Emulated FFA_RX_RELEASE handler function
629+ * @{a0-a7} , res: The SMC call arguments and return structure.
630+ *
631+ * This is the function that emulates FFA_RX_RELEASE FF-A function.
632+ *
633+ * Return:
634+ *
635+ * 0 on success. Otherwise, failure
636+ */
637+SANDBOX_SMC_FFA_ABI(ffa_rx_release)
638+{
639+ if (!sandbox_ffa_priv_data.pair_info.rxbuf_owned) {
640+ res->a0 = FFA_SMC_32(FFA_ERROR);
641+ res->a2 = FFA_ERR_STAT_DENIED;
642+ } else {
643+ sandbox_ffa_priv_data.pair_info.rxbuf_owned = 0;
644+ res->a0 = FFA_SMC_32(FFA_SUCCESS);
645+ res->a2 = 0;
646+ }
647+
648+ res->a1 = 0;
649+
650+ /* x3-x7 MBZ */
651+ memset(FFA_X3_MBZ_REG_START,
652+ 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
653+
654+ return 0;
655+}
656+
657+/**
658+ * sandbox_ffa_sp_valid - Checks SP validity
659+ * @part_id: partition ID to check
660+ *
661+ * This is the function searches the input ID in the descriptors table.
662+ *
663+ * Return:
664+ *
665+ * 1 on success (Partition found). Otherwise, failure
666+ */
667+static int sandbox_ffa_sp_valid(u16 part_id)
668+{
669+ u32 descs_cnt;
670+
671+ for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++)
672+ if (sandbox_ffa_priv_data.partitions.descs[descs_cnt].info.id == part_id)
673+ return 1;
674+
675+ return 0;
676+}
677+
678+/**
679+ * sandbox_ffa_msg_send_direct_req - Emulated FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function
680+ * @{a0-a7} , res: The SMC call arguments and return structure.
681+ *
682+ * This is the function that emulates FFA_MSG_SEND_DIRECT_{REQ,RESP}
683+ * FF-A functions.
684+ *
685+ * Emulating interrupts is not supported. So, FFA_RUN and FFA_INTERRUPT are not supported.
686+ * In case of success FFA_MSG_SEND_DIRECT_RESP is returned with default pattern data (0xff).
687+ *
688+ * Return:
689+ *
690+ * 0 on success. Otherwise, failure
691+ */
692+SANDBOX_SMC_FFA_ABI(ffa_msg_send_direct_req)
693+{
694+ u16 part_id;
695+
696+ part_id = GET_DST_SP_ID(pargs->a1);
697+
698+ if ((GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != sandbox_ffa_priv_data.id) ||
699+ !sandbox_ffa_sp_valid(part_id) ||
700+ pargs->a2) {
701+ res->a0 = FFA_SMC_32(FFA_ERROR);
702+ res->a1 = 0;
703+ res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS;
704+
705+ /* x3-x7 MBZ */
706+ memset(FFA_X3_MBZ_REG_START,
707+ 0, FFA_X3X7_MBZ_CNT * sizeof(unsigned long));
708+
709+ return 0;
710+ }
711+
712+ res->a0 = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP);
713+
714+ res->a1 = PREP_SRC_SP_ID(part_id) |
715+ PREP_NS_PHYS_ENDPOINT_ID(sandbox_ffa_priv_data.id);
716+
717+ res->a2 = 0;
718+
719+ /*
720+ * return 0xff bytes as a response
721+ */
722+ res->a3 = 0xffffffffffffffff;
723+ res->a4 = 0xffffffffffffffff;
724+ res->a5 = 0xffffffffffffffff;
725+ res->a6 = 0xffffffffffffffff;
726+ res->a7 = 0xffffffffffffffff;
727+
728+ return 0;
729+}
730+
731+/**
732+ * sandbox_ffa_get_prv_data - Returns the pointer to FF-A core pivate data
733+ * @func_data: Pointer to the FF-A function arguments container structure
734+ *
735+ * This is the handler that returns the address of the FF-A core pivate data.
736+ *
737+ * Return:
738+ *
739+ * 0 on success. Otherwise, failure
740+ */
741+static int sandbox_ffa_get_prv_data(struct ffa_sandbox_data *func_data)
742+{
743+ if (!func_data)
744+ return -EINVAL;
745+
746+ if (!func_data->data0 || func_data->data0_size != sizeof(struct ffa_prvdata **))
747+ return -EINVAL;
748+
749+ if (!func_data->data1 || func_data->data1_size != sizeof(struct sandbox_ffa_prvdata **))
750+ return -EINVAL;
751+
752+ *((struct ffa_prvdata **)func_data->data0) = *(ffa_bus_prvdata_get());
753+ *((struct sandbox_ffa_prvdata **)func_data->data1) = &sandbox_ffa_priv_data;
754+
755+ return 0;
756+}
757+
758+/**
759+ * sandbox_ffa_get_rxbuf_flags - Reading the mapping/ownership flags
760+ * @queried_func_id: The FF-A function to be queried
761+ * @func_data: Pointer to the FF-A function arguments container structure
762+ *
763+ * This is the handler that queries the status flags of the following emulated ABIs:
764+ * FFA_RXTX_MAP, FFA_RXTX_UNMAP, FFA_RX_RELEASE
765+ *
766+ * Return:
767+ *
768+ * 0 on success. Otherwise, failure
769+ */
770+static int sandbox_ffa_get_rxbuf_flags(u32 queried_func_id, struct ffa_sandbox_data *func_data)
771+{
772+ if (!func_data)
773+ return -EINVAL;
774+
775+ if (!func_data->data0 || func_data->data0_size != sizeof(u8))
776+ return -EINVAL;
777+
778+ switch (queried_func_id) {
779+ case FFA_RXTX_MAP:
780+ case FFA_RXTX_UNMAP:
781+ *((u8 *)func_data->data0) = sandbox_ffa_priv_data.pair_info.rxbuf_mapped;
782+ return 0;
783+ case FFA_RX_RELEASE:
784+ *((u8 *)func_data->data0) = sandbox_ffa_priv_data.pair_info.rxbuf_owned;
785+ return 0;
786+ default:
787+ ffa_err("[Sandbox] The querried FF-A interface flag (%d) undefined",
788+ queried_func_id);
789+ return -EINVAL;
790+ }
791+}
792+
793+/**
794+ * sandbox_ffa_query_core_state - The driver dispatcher function
795+ * @queried_func_id: The FF-A function to be queried
796+ * @func_data: Pointer to the FF-A function arguments container structure
797+ *
798+ * Queries the status of FF-A ABI specified in the input argument.
799+ *
800+ * Return:
801+ *
802+ * 0 on success. Otherwise, failure
803+ */
804+int sandbox_ffa_query_core_state(u32 queried_func_id, struct ffa_sandbox_data *func_data)
805+{
806+ switch (queried_func_id) {
807+ case FFA_VERSION:
808+ case FFA_ID_GET:
809+ case FFA_FEATURES:
810+ return sandbox_ffa_get_prv_data(func_data);
811+ case FFA_RXTX_MAP:
812+ case FFA_RXTX_UNMAP:
813+ case FFA_RX_RELEASE:
814+ return sandbox_ffa_get_rxbuf_flags(queried_func_id, func_data);
815+ default:
816+ ffa_err("[Sandbox] The querried FF-A interface (%d) undefined", queried_func_id);
817+ return -EINVAL;
818+ }
819+}
820+
821+/**
822+ * sandbox_arm_ffa_smccc_smc - FF-A SMC call emulation
823+ * @args: the SMC call arguments
824+ * @res: the SMC call returned data
825+ *
826+ * Sandbox driver emulates the FF-A ABIs SMC call using this function.
827+ * The emulated FF-A ABI is identified and invoked.
828+ * FF-A emulation is based on the FF-A specification 1.0
829+ *
830+ * Return:
831+ *
832+ * 0 on success. Otherwise, failure.
833+ * FF-A protocol error codes are returned using the registers arguments as described
834+ * by the specification
835+ */
836+void sandbox_arm_ffa_smccc_smc(ffa_value_t args, ffa_value_t *res)
837+{
838+ int ret = 0;
839+
840+ switch (args.a0) {
841+ case FFA_SMC_32(FFA_VERSION):
842+ ret = sandbox_ffa_version(&args, res);
843+ break;
844+ case FFA_SMC_32(FFA_PARTITION_INFO_GET):
845+ ret = sandbox_ffa_partition_info_get(&args, res);
846+ break;
847+ case FFA_SMC_32(FFA_RXTX_UNMAP):
848+ ret = sandbox_ffa_rxtx_unmap(&args, res);
849+ break;
850+ case FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ):
851+ ret = sandbox_ffa_msg_send_direct_req(&args, res);
852+ break;
853+ case FFA_SMC_32(FFA_ID_GET):
854+ ret = sandbox_ffa_id_get(&args, res);
855+ break;
856+ case FFA_SMC_32(FFA_FEATURES):
857+ ret = sandbox_ffa_features(&args, res);
858+ break;
859+ case FFA_SMC_64(FFA_RXTX_MAP):
860+ ret = sandbox_ffa_rxtx_map(&args, res);
861+ break;
862+ case FFA_SMC_32(FFA_RX_RELEASE):
863+ ret = sandbox_ffa_rx_release(&args, res);
864+ break;
865+ default:
866+ ffa_err("[Sandbox] Undefined FF-A interface (0x%lx)", args.a0);
867+ }
868+
869+ if (ret != 0)
870+ ffa_err("[Sandbox] FF-A ABI internal failure (%d)", ret);
871+}
872+
873+/**
874+ * sandbox_ffa_probe - The driver probe function
875+ * @dev: the sandbox_arm_ffa device
876+ *
877+ * Return:
878+ *
879+ * 0 on success. Otherwise, failure
880+ */
881+static int sandbox_ffa_probe(struct udevice *dev)
882+{
883+ return 0;
884+}
885+
886+/**
887+ * sandbox_ffa_remove - The driver remove function
888+ * @dev: the sandbox_arm_ffa device
889+ *
890+ * Return:
891+ *
892+ * 0 on success. Otherwise, failure
893+ */
894+static int sandbox_ffa_remove(struct udevice *dev)
895+{
896+ ffa_info("[Sandbox] removing the device");
897+ memset(&sandbox_ffa_priv_data, 0, sizeof(sandbox_ffa_priv_data));
898+ return 0;
899+}
900+
901+/**
902+ * Declaring the sandbox_arm_ffa driver under UCLASS_FFA
903+ */
904+U_BOOT_DRIVER(sandbox_arm_ffa) = {
905+ .name = FFA_SANDBOX_DRV_NAME,
906+ .id = UCLASS_FFA,
907+ .probe = sandbox_ffa_probe,
908+ .remove = sandbox_ffa_remove,
909+};
910diff --git a/drivers/firmware/arm-ffa/sandbox_arm_ffa_prv.h b/drivers/firmware/arm-ffa/sandbox_arm_ffa_prv.h
911new file mode 100644
912index 0000000000..4db57f5092
913--- /dev/null
914+++ b/drivers/firmware/arm-ffa/sandbox_arm_ffa_prv.h
915@@ -0,0 +1,144 @@
916+/* SPDX-License-Identifier: GPL-2.0+ */
917+/*
918+ * (C) Copyright 2022 ARM Limited
919+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
920+ */
921+
922+#ifndef __SANDBOX_ARM_FFA_PRV_H
923+#define __SANDBOX_ARM_FFA_PRV_H
924+
925+#include "arm_ffa_prv.h"
926+#include <sandbox_arm_ffa.h>
927+
928+/*
929+ * This header is private. It is exclusively used by the Sandbox FF-A driver
930+ */
931+
932+/* FF-A core driver name */
933+#define FFA_SANDBOX_DRV_NAME "sandbox_arm_ffa"
934+
935+/* FF-A ABIs internal error codes (as defined by the spec) */
936+
937+#define FFA_ERR_STAT_NOT_SUPPORTED -1
938+#define FFA_ERR_STAT_INVALID_PARAMETERS -2
939+#define FFA_ERR_STAT_NO_MEMORY -3
940+#define FFA_ERR_STAT_BUSY -4
941+#define FFA_ERR_STAT_DENIED -6
942+
943+/* Providing Arm SMCCC declarations to sandbox */
944+
945+#define ARM_SMCCC_FAST_CALL 1UL
946+#define ARM_SMCCC_OWNER_STANDARD 4
947+#define ARM_SMCCC_SMC_32 0
948+#define ARM_SMCCC_SMC_64 1
949+#define ARM_SMCCC_TYPE_SHIFT 31
950+#define ARM_SMCCC_CALL_CONV_SHIFT 30
951+#define ARM_SMCCC_OWNER_MASK 0x3F
952+#define ARM_SMCCC_OWNER_SHIFT 24
953+#define ARM_SMCCC_FUNC_MASK 0xFFFF
954+
955+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
956+ (((type) << ARM_SMCCC_TYPE_SHIFT) | \
957+ ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
958+ (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
959+ ((func_num) & ARM_SMCCC_FUNC_MASK))
960+
961+/* Non-secure physical FF-A instance */
962+#define NS_PHYS_ENDPOINT_ID (0)
963+
964+#define GET_NS_PHYS_ENDPOINT_ID_MASK GENMASK(31, 16)
965+#define GET_NS_PHYS_ENDPOINT_ID(x) \
966+ ((u16)(FIELD_GET(GET_NS_PHYS_ENDPOINT_ID_MASK, (x))))
967+
968+/* Helper macro for reading the destination partition ID */
969+#define GET_DST_SP_ID_MASK GENMASK(15, 0)
970+#define GET_DST_SP_ID(x) \
971+ ((u16)(FIELD_GET(GET_DST_SP_ID_MASK, (x))))
972+
973+/* Helper macro for setting the source partition ID */
974+#define PREP_SRC_SP_ID_MASK GENMASK(31, 16)
975+#define PREP_SRC_SP_ID(x) \
976+ (FIELD_PREP(PREP_SRC_SP_ID_MASK, (x)))
977+
978+/* Helper macro for setting the destination endpoint ID */
979+#define PREP_NS_PHYS_ENDPOINT_ID_MASK GENMASK(15, 0)
980+#define PREP_NS_PHYS_ENDPOINT_ID(x) \
981+ (FIELD_PREP(PREP_NS_PHYS_ENDPOINT_ID_MASK, (x)))
982+
983+/* RX/TX buffers minimum size */
984+#define RXTX_BUFFERS_MIN_SIZE (RXTX_4K)
985+#define RXTX_BUFFERS_MIN_PAGES (1)
986+
987+/* MBZ registers info */
988+
989+/* x1-x7 MBZ */
990+#define FFA_X1X7_MBZ_CNT (7)
991+#define FFA_X1X7_MBZ_REG_START (&res->a1)
992+
993+/* x4-x7 MBZ */
994+#define FFA_X4X7_MBZ_CNT (4)
995+#define FFA_X4X7_MBZ_REG_START (&res->a4)
996+
997+/* x3-x7 MBZ */
998+#define FFA_X3X7_MBZ_CNT (5)
999+#define FFA_X3_MBZ_REG_START (&res->a3)
1000+
1001+/* secure partitions count */
1002+#define SANDBOX_PARTITIONS_CNT (4)
1003+
1004+/* service 1 UUID binary data (little-endian format) */
1005+#define SANDBOX_SERVICE1_UUID_A1 0xed32d533
1006+#define SANDBOX_SERVICE1_UUID_A2 0x99e64209
1007+#define SANDBOX_SERVICE1_UUID_A3 0x9cc02d72
1008+#define SANDBOX_SERVICE1_UUID_A4 0xcdd998a7
1009+
1010+/* service 2 UUID binary data (little-endian format) */
1011+#define SANDBOX_SERVICE2_UUID_A1 0xed32d544
1012+#define SANDBOX_SERVICE2_UUID_A2 0x99e64209
1013+#define SANDBOX_SERVICE2_UUID_A3 0x9cc02d72
1014+#define SANDBOX_SERVICE2_UUID_A4 0xcdd998a7
1015+
1016+/**
1017+ * struct ffa_rxtxpair_info - structure hosting the RX/TX buffers flags
1018+ * @rxbuf_owned: RX buffer ownership flag (the owner is non secure world: the consumer)
1019+ * @rxbuf_mapped: RX buffer mapping flag
1020+ * @txbuf_owned TX buffer ownership flag
1021+ * @txbuf_mapped: TX buffer mapping flag
1022+ * @rxtx_buf_size: RX/TX buffers size as set by the FF-A core driver
1023+ *
1024+ * Data structure hosting the ownership/mapping flags of the RX/TX buffers
1025+ * When a buffer is owned/mapped its corresponding flag is set to 1 otherwise 0.
1026+ */
1027+struct ffa_rxtxpair_info {
1028+ u8 rxbuf_owned;
1029+ u8 rxbuf_mapped;
1030+ u8 txbuf_owned;
1031+ u8 txbuf_mapped;
1032+ u32 rxtx_buf_size;
1033+};
1034+
1035+/**
1036+ * struct sandbox_ffa_prvdata - the driver private data structure
1037+ *
1038+ * @dev: The arm_ffa device under u-boot driver model
1039+ * @fwk_version: FF-A framework version
1040+ * @id: u-boot endpoint ID
1041+ * @partitions: The partitions descriptors structure
1042+ * @pair: The RX/TX buffers pair
1043+ * @pair_info: The RX/TX buffers pair flags and size
1044+ * @conduit: The selected conduit
1045+ *
1046+ * The driver data structure hosting all the emulated secure world data.
1047+ */
1048+struct sandbox_ffa_prvdata {
1049+ struct udevice *dev;
1050+ u32 fwk_version;
1051+ u16 id;
1052+ struct ffa_partitions partitions;
1053+ struct ffa_rxtxpair pair;
1054+ struct ffa_rxtxpair_info pair_info;
1055+};
1056+
1057+#define SANDBOX_SMC_FFA_ABI(ffabi) static int sandbox_##ffabi(ffa_value_t *pargs, ffa_value_t *res)
1058+
1059+#endif
1060diff --git a/include/arm_ffa.h b/include/arm_ffa.h
1061index f17b100497..665413a0c5 100644
1062--- a/include/arm_ffa.h
1063+++ b/include/arm_ffa.h
1064@@ -111,7 +111,7 @@ struct ffa_bus_ops {
1065 const struct ffa_bus_ops * __ffa_runtime ffa_bus_ops_get(void);
1066
1067 /**
1068- * ffa_bus_discover - discover FF-A bus and probes the arm_ffa device
1069+ * ffa_bus_discover - discover FF-A bus and probes the arm_ffa and sandbox_arm_ffa devices
1070 */
1071 int ffa_bus_discover(void);
1072
1073diff --git a/include/sandbox_arm_ffa.h b/include/sandbox_arm_ffa.h
1074new file mode 100644
1075index 0000000000..d5df16f282
1076--- /dev/null
1077+++ b/include/sandbox_arm_ffa.h
1078@@ -0,0 +1,91 @@
1079+/* SPDX-License-Identifier: GPL-2.0+ */
1080+/*
1081+ * (C) Copyright 2022 ARM Limited
1082+ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
1083+ */
1084+
1085+#ifndef __SANDBOX_ARM_FFA_H
1086+#define __SANDBOX_ARM_FFA_H
1087+
1088+#include <arm_ffa.h>
1089+
1090+/**
1091+ * struct sandbox_smccc_1_2_regs - Arguments for or Results from emulated SMC call
1092+ * @a0-a17 argument values from registers 0 to 17
1093+ */
1094+struct sandbox_smccc_1_2_regs {
1095+ unsigned long a0;
1096+ unsigned long a1;
1097+ unsigned long a2;
1098+ unsigned long a3;
1099+ unsigned long a4;
1100+ unsigned long a5;
1101+ unsigned long a6;
1102+ unsigned long a7;
1103+ unsigned long a8;
1104+ unsigned long a9;
1105+ unsigned long a10;
1106+ unsigned long a11;
1107+ unsigned long a12;
1108+ unsigned long a13;
1109+ unsigned long a14;
1110+ unsigned long a15;
1111+ unsigned long a16;
1112+ unsigned long a17;
1113+};
1114+
1115+typedef struct sandbox_smccc_1_2_regs ffa_value_t;
1116+
1117+/* UUIDs of services supported by the sandbox driver */
1118+#define SANDBOX_SERVICE1_UUID "ed32d533-4209-99e6-2d72-cdd998a79cc0"
1119+#define SANDBOX_SERVICE2_UUID "ed32d544-4209-99e6-2d72-cdd998a79cc0"
1120+#define SANDBOX_SP1_ID 0x1245
1121+#define SANDBOX_SP2_ID 0x9836
1122+#define SANDBOX_SP3_ID 0x6452
1123+#define SANDBOX_SP4_ID 0x7814
1124+
1125+/* invalid service UUID (no matching SP) */
1126+#define SANDBOX_SERVICE3_UUID "55d532ed-0942-e699-722d-c09ca798d9cd"
1127+
1128+/* invalid service UUID (invalid UUID string format) */
1129+#define SANDBOX_SERVICE4_UUID "32ed-0942-e699-722d-c09ca798d9cd"
1130+
1131+#define SANDBOX_SP_COUNT_PER_VALID_SERVICE 2
1132+
1133+/**
1134+ * struct ffa_sandbox_data - generic data structure used to exchange
1135+ * data between test cases and the sandbox driver
1136+ * @data0_size: size of the first argument
1137+ * @data0: pointer to the first argument
1138+ * @data1_size>: size of the second argument
1139+ * @data1: pointer to the second argument
1140+ *
1141+ * Using this structure sandbox test cases can pass various types of data with different sizes.
1142+ */
1143+struct ffa_sandbox_data {
1144+ u32 data0_size; /* size of the first argument */
1145+ void *data0; /* pointer to the first argument */
1146+ u32 data1_size; /* size of the second argument */
1147+ void *data1; /* pointer to the second argument */
1148+};
1149+
1150+/**
1151+ * The sandbox driver public functions
1152+ */
1153+
1154+/**
1155+ * sandbox_ffa_query_core_state - Queries the status of FF-A ABIs
1156+ */
1157+int sandbox_ffa_query_core_state(u32 queried_func_id, struct ffa_sandbox_data *func_data);
1158+
1159+/**
1160+ * sandbox_ffa_get_device - create, bind and probe the sandbox_arm_ffa device
1161+ */
1162+int sandbox_ffa_device_get(void);
1163+
1164+/**
1165+ * sandbox_arm_ffa_smccc_smc - FF-A SMC call emulation
1166+ */
1167+void sandbox_arm_ffa_smccc_smc(ffa_value_t args, ffa_value_t *res);
1168+
1169+#endif
1170diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
1171index 0ec002ac8b..8fa9a58d76 100644
1172--- a/lib/efi_loader/efi_boottime.c
1173+++ b/lib/efi_loader/efi_boottime.c
1174@@ -2177,7 +2177,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
1175 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
1176 }
1177
1178-#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
1179+#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT) && !CONFIG_IS_ENABLED(SANDBOX_FFA)
1180 /* unmap FF-A RX/TX buffers */
1181 if (ffa_bus_ops_get()->rxtx_unmap())
1182 debug("[efi_boottime][ERROR]: can not unmap FF-A RX/TX buffers\n");
1183--
11842.17.1
1185