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