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