
From: Abdellatif El Khlifi abdellatif.elkhlifi@arm.com
Provide a Sandbox driver to emulate the FF-A ABIs
The emulated ABIs are those supported by the FF-A core driver and according to FF-A specification v1.0.
The Sandbox driver provides operations allowing the test application to read the status of all the inspected ABIs and perform functional tests based on that.
Signed-off-by: Abdellatif El Khlifi abdellatif.elkhlifi@arm.com --- MAINTAINERS | 2 + common/board_r.c | 2 +- configs/sandbox64_defconfig | 2 + configs/sandbox_defconfig | 2 + doc/arch/sandbox.rst | 1 + drivers/arm-ffa/Kconfig | 8 +- drivers/arm-ffa/Makefile | 1 + drivers/arm-ffa/arm-ffa-uclass.c | 47 +- drivers/arm-ffa/core.c | 97 ++-- drivers/arm-ffa/sandbox.c | 669 ++++++++++++++++++++++++++ drivers/arm-ffa/sandbox_arm_ffa_prv.h | 131 +++++ include/arm_ffa.h | 9 +- include/sandbox_arm_ffa.h | 31 ++ include/sandbox_arm_ffa_helper.h | 26 + lib/arm-ffa/Makefile | 1 + lib/arm-ffa/arm_ffa_helper.c | 2 +- lib/arm-ffa/sandbox_arm_ffa_helper.c | 23 + lib/efi_loader/efi_boottime.c | 4 +- 18 files changed, 1017 insertions(+), 41 deletions(-) create mode 100644 drivers/arm-ffa/sandbox.c create mode 100644 drivers/arm-ffa/sandbox_arm_ffa_prv.h create mode 100644 include/sandbox_arm_ffa.h create mode 100644 include/sandbox_arm_ffa_helper.h create mode 100644 lib/arm-ffa/sandbox_arm_ffa_helper.c
diff --git a/MAINTAINERS b/MAINTAINERS index ca2e13b9ec..7c439ed1fd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -239,6 +239,8 @@ F: cmd/armffa.c F: drivers/arm-ffa/ F: include/arm_ffa.h F: include/arm_ffa_helper.h +F: include/sandbox_arm_ffa.h +F: include/sandbox_arm_ffa_helper.h F: lib/arm-ffa/
ARM FREESCALE IMX diff --git a/common/board_r.c b/common/board_r.c index bb5f1d0aa6..a03b5254b7 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -775,7 +775,7 @@ static init_fnc_t init_sequence_r[] = { INIT_FUNC_WATCHDOG_RESET initr_net, #endif -#ifdef CONFIG_ARM_FFA_TRANSPORT +#if defined(CONFIG_ARM_FFA_TRANSPORT) && !defined(CONFIG_SANDBOX_FFA) ffa_helper_bus_discover, #endif #ifdef CONFIG_POST diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 4fbe148074..d6b3a137e3 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -252,3 +252,5 @@ CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_ARM_FFA_TRANSPORT=y +CONFIG_SANDBOX_FFA=y \ No newline at end of file diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 1826cf0195..161ff221bf 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -326,3 +326,5 @@ CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_ARM_FFA_TRANSPORT=y +CONFIG_SANDBOX_FFA=y \ No newline at end of file diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst index f8804e1f41..7cb5ea307c 100644 --- a/doc/arch/sandbox.rst +++ b/doc/arch/sandbox.rst @@ -203,6 +203,7 @@ Supported Drivers
U-Boot sandbox supports these emulations:
+- Arm FF-A - Block devices - Chrome OS EC - GPIO diff --git a/drivers/arm-ffa/Kconfig b/drivers/arm-ffa/Kconfig index fa2b2fecfb..5774ae6496 100644 --- a/drivers/arm-ffa/Kconfig +++ b/drivers/arm-ffa/Kconfig @@ -2,7 +2,7 @@
config ARM_FFA_TRANSPORT bool "Enable Arm Firmware Framework for Armv8-A driver" - depends on DM && ARM64 + depends on DM && (ARM64 || SANDBOX) select ARM_SMCCC if ARM64 select CMD_ARMFFA select LIB_UUID @@ -26,3 +26,9 @@ config ARM_FFA_TRANSPORT FF-A communication is handled by one device and one instance (the bus). This FF-A driver takes care of all the interactions between Normal world and Secure World. + +config SANDBOX_FFA + bool "FF-A Sandbox driver" + depends on ARM_FFA_TRANSPORT && SANDBOX + help + This emulates the FF-A handling under Sandbox and allows to test the FF-A driver diff --git a/drivers/arm-ffa/Makefile b/drivers/arm-ffa/Makefile index 7bc9a336a9..df1cfe6ef0 100644 --- a/drivers/arm-ffa/Makefile +++ b/drivers/arm-ffa/Makefile @@ -4,3 +4,4 @@ #
obj-y += arm-ffa-uclass.o core.o +obj-$(CONFIG_SANDBOX_FFA) += sandbox.o diff --git a/drivers/arm-ffa/arm-ffa-uclass.c b/drivers/arm-ffa/arm-ffa-uclass.c index 2439f87586..418aa06dd6 100644 --- a/drivers/arm-ffa/arm-ffa-uclass.c +++ b/drivers/arm-ffa/arm-ffa-uclass.c @@ -11,6 +11,10 @@ #include <log.h> #include <asm/global_data.h>
+#if CONFIG_IS_ENABLED(SANDBOX_FFA) +#include <sandbox_arm_ffa.h> +#endif + DECLARE_GLOBAL_DATA_PTR;
UCLASS_DRIVER(ffa) = { @@ -42,16 +46,42 @@ int __ffa_runtime ffa_get_invoke_func(u32 func_id, struct ffa_interface_data *fu return ffa_device_get_ops()->invoke_func(func_id, func_data); }
+#if CONFIG_IS_ENABLED(SANDBOX_FFA) + +/** + * sandbox_ffa_get_invoke_func - performs a call to the Sandbox FF-A driver dispatcher + * @func_id: The FF-A function to be queried + * @func_data: Pointer to the query arguments + * container structure. + * + * This function passes the FF-A function ID to be queried during sandbox test cases + * and its arguments to the Sandbox FF-A driver dispatcher. + * This function is called by the Sandbox FF-A helper function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +int sandbox_ffa_get_invoke_func(u32 func_id, struct ffa_interface_data *func_data) +{ + if (!sandbox_ffa_device_get_ops()->invoke_func) + return -EINVAL; + + return sandbox_ffa_device_get_ops()->invoke_func(func_id, func_data); +} +#endif + /** - * ffa_bus_discover - discover FF-A bus and probe the arm_ffa device + * ffa_bus_discover - discover FF-A bus and probe arm_ffa and sandbox_arm_ffa devices * * This boot time function makes sure the FF-A bus is discoverable. - * Then, the arm_ffa device is probed and ready to use. + * Then, the arm_ffa and sandbox_arm_ffa devices are ready to use. + * * This function is called automatically at initcalls * level (after u-boot relocation). * * Arm FF-A transport is implemented through arm_ffa u-boot device managing the FF-A - * communication. + * communication. In Sandbox mode sandbox_arm_ffa is used to test arm_ffa driver. * All FF-A clients should use the arm_ffa device to use the FF-A transport. * * Return: @@ -60,5 +90,14 @@ int __ffa_runtime ffa_get_invoke_func(u32 func_id, struct ffa_interface_data *fu */ int ffa_bus_discover(void) { - return ffa_get_device(); + int ret; + + ret = ffa_get_device(); + +#if CONFIG_IS_ENABLED(SANDBOX_FFA) + if (ret == FFA_ERR_STAT_SUCCESS) + ret = sandbox_ffa_get_device(); +#endif + + return ret; } diff --git a/drivers/arm-ffa/core.c b/drivers/arm-ffa/core.c index 09e4eb753a..246abc1473 100644 --- a/drivers/arm-ffa/core.c +++ b/drivers/arm-ffa/core.c @@ -5,6 +5,11 @@ */
#include "arm_ffa_prv.h" + +#if CONFIG_IS_ENABLED(SANDBOX_FFA) +#include "sandbox_arm_ffa_prv.h" +#endif + #include <asm/global_data.h> #include <asm/io.h> #include <common.h> @@ -88,8 +93,10 @@ static int ffa_get_version(void)
FFA_DECLARE_ARGS;
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
a0 = FFA_VERSION; a1 = FFA_VERSION_1_0; @@ -132,8 +139,10 @@ static int ffa_get_endpoint_id(void) { FFA_DECLARE_ARGS;
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
a0 = FFA_ID_GET;
@@ -206,8 +215,10 @@ static int ffa_get_rxtx_map_features(void) { FFA_DECLARE_ARGS;
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
a0 = FFA_FEATURES; a1 = FFA_RXTX_MAP; @@ -433,8 +444,10 @@ static int ffa_map_rxtx_buffers(size_t buf_4k_pages)
FFA_DECLARE_ARGS;
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
ret = ffa_alloc_rxtx_buffers(buf_4k_pages); if (ret != FFA_ERR_STAT_SUCCESS) @@ -502,8 +515,10 @@ static int ffa_unmap_rxtx_buffers(void) { FFA_DECLARE_ARGS;
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
a0 = FFA_RXTX_UNMAP; a1 = PREP_SELF_ENDPOINT_ID(ffa_priv_data.id); @@ -514,11 +529,12 @@ static int ffa_unmap_rxtx_buffers(void) case FFA_ERROR: { if (((int)res.a2) == FFA_ERR_STAT_NOT_SUPPORTED) - panic("[FFA] FFA_RXTX_UNMAP is not implemented at this FF-A instance\n"); + ffa_panic("FFA_RXTX_UNMAP is not implemented at this FF-A instance\n"); else if (((int)res.a2) == FFA_ERR_STAT_INVALID_PARAMETERS) - panic("[FFA] There is no buffer pair registered on behalf of the caller\n"); + ffa_panic("There is no buffer pair registered on behalf of the caller\n"); else - panic("[FFA] Undefined error (%d)\n", ((int)res.a2)); + ffa_panic("Undefined error (%d)\n", ((int)res.a2)); + return -ENODEV; } case FFA_SUCCESS: { @@ -526,19 +542,24 @@ static int ffa_unmap_rxtx_buffers(void) int ret;
ret = ffa_get_rxtx_buffers_pages_cnt(&buf_4k_pages); - if (ret != FFA_ERR_STAT_SUCCESS) - panic("[FFA] RX/TX buffers unmapped but failure in getting pages count\n"); + if (ret != FFA_ERR_STAT_SUCCESS) { + ffa_panic("RX/TX buffers unmapped but failure in getting pages count\n"); + return -ENODEV; + }
ret = ffa_free_rxtx_buffers(buf_4k_pages); - if (ret != FFA_ERR_STAT_SUCCESS) - panic("[FFA] RX/TX buffers unmapped but failure in freeing the memory\n"); + if (ret != FFA_ERR_STAT_SUCCESS) { + ffa_panic("RX/TX buffers unmapped but failure in freeing the memory\n"); + return -ENODEV; + }
ffa_info("RX/TX buffers unmapped and memory freed");
return FFA_ERR_STAT_SUCCESS; } default: - panic("[FFA] Undefined response function (0x%lx)", res.a0); + ffa_panic("Undefined response function (0x%lx)", res.a0); + return -ENODEV; } }
@@ -556,8 +577,10 @@ static int ffa_release_rx_buffer(void) { FFA_DECLARE_ARGS;
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
a0 = FFA_RX_RELEASE;
@@ -567,17 +590,19 @@ static int ffa_release_rx_buffer(void) case FFA_ERROR: { if (((int)res.a2) == FFA_ERR_STAT_NOT_SUPPORTED) - panic("[FFA] FFA_RX_RELEASE is not implemented at this FF-A instance\n"); + ffa_panic("FFA_RX_RELEASE is not implemented at this FF-A instance\n"); else if (((int)res.a2) == FFA_ERR_STAT_DENIED) - panic("[FFA] Caller did not have ownership of the RX buffer\n"); + ffa_panic("Caller did not have ownership of the RX buffer\n"); else - panic("[FFA] Undefined error (%d)\n", ((int)res.a2)); + ffa_panic("Undefined error (%d)\n", ((int)res.a2)); + return -ENODEV; } case FFA_SUCCESS: return FFA_ERR_STAT_SUCCESS;
default: - panic("[FFA] Undefined response function (0x%lx)\n", res.a0); + ffa_panic("Undefined response function (0x%lx)\n", res.a0); + return -ENODEV; } }
@@ -769,8 +794,10 @@ static int ffa_query_partitions_info(union ffa_partition_uuid *part_uuid, unsigned long a7 = 0; struct arm_smccc_res res = {0};
- if (!ffa_priv_data.invoke_ffa_fn) - panic("[FFA] no private data found\n"); + if (!ffa_priv_data.invoke_ffa_fn) { + ffa_panic("no private data found\n"); + return -ENODEV; + }
a0 = FFA_PARTITION_INFO_GET;
@@ -846,7 +873,7 @@ static int ffa_query_partitions_info(union ffa_partition_uuid *part_uuid, ret = ffa_release_rx_buffer();
if (!part_uuid && !res.a2) { - ffa_err("[FFA] no partition installed in the system"); + ffa_err("no partition installed in the system"); return -ENODEV; }
@@ -937,8 +964,10 @@ static int ffa_get_partitions_info(struct ffa_interface_data *func_data) return -EINVAL; }
- if (!ffa_priv_data.partitions.count || !ffa_priv_data.partitions.descs) - panic("[FFA] No partition installed\n"); + if (!ffa_priv_data.partitions.count || !ffa_priv_data.partitions.descs) { + ffa_panic("No partition installed\n"); + return -ENODEV; + }
if (func_data->data0_size == sizeof(union ffa_partition_uuid) && func_data->data0 && @@ -1176,6 +1205,7 @@ static int __ffa_runtime ffa_msg_send_direct_req(struct ffa_interface_data /* Undefined error */ return -ENXIO; } + return -ENODEV; } case FFA_SUCCESS:
@@ -1238,7 +1268,7 @@ int __ffa_runtime invoke_ffa_drv_api(u32 func_id, /** * ffa_set_conduit - Set the conduit * - * This boot time function clears the private data structure and sets the conduit + * This boot time function sets the conduit * * Return: * @@ -1248,7 +1278,12 @@ static int ffa_set_conduit(void) { ffa_priv_data.conduit = FFA_CONDUIT_SMC;
- ffa_priv_data.invoke_ffa_fn = arm_ffa_smccc_smc; +#if CONFIG_IS_ENABLED(SANDBOX_FFA) + ffa_priv_data.invoke_ffa_fn = sandbox_arm_ffa_smccc_smc; + ffa_info("Using SMC emulation"); +#else + ffa_priv_data.invoke_ffa_fn = arm_ffa_smccc_smc; +#endif
ffa_info("Conduit is SMC");
diff --git a/drivers/arm-ffa/sandbox.c b/drivers/arm-ffa/sandbox.c new file mode 100644 index 0000000000..d4a953fc3b --- /dev/null +++ b/drivers/arm-ffa/sandbox.c @@ -0,0 +1,669 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com + */ + +#include "sandbox_arm_ffa_prv.h" +#include <asm/global_data.h> +#include <common.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/root.h> +#include <linux/errno.h> +#include <linux/sizes.h> +#include <mapmem.h> +#include <string.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * The device private data structure containing all the emulated secure world data + */ +static struct sandbox_ffa_prvdata sandbox_ffa_priv_data = {0}; + +/* The partitions (SPs) table */ +static struct ffa_partition_desc sandbox_partitions[SANDBOX_PARTITIONS_CNT] = { + { + .info = { .id = 0x1245, .exec_ctxt = 0x5687, .properties = 0x89325621 }, + .UUID = { .bytes = {SANDBOX_SERVICE1_UUID_DATA}} + }, + { + .info = { .id = 0x9836, .exec_ctxt = 0x9587, .properties = 0x45325621 }, + .UUID = { .bytes = {SANDBOX_SERVICE2_UUID_DATA}} + }, + { + .info = { .id = 0x6452, .exec_ctxt = 0x7687, .properties = 0x23325621 }, + .UUID = { .bytes = {SANDBOX_SERVICE1_UUID_DATA}} + }, + { + .info = { .id = 0x7814, .exec_ctxt = 0x1487, .properties = 0x70325621 }, + .UUID = { .bytes = {SANDBOX_SERVICE2_UUID_DATA}} + } + +}; + +/* + * Driver functions + */ + +/** + * sandbox_ffa_get_device - probes the sandbox_arm_ffa device + * + * This function makes sure the sandbox_arm_ffa device is probed + * This function makes sure the sandbox_arm_ffa device is + * created, bound to this driver, probed and ready to use. + * + * sandbox_arm_ffa depends on arm_ffa device. This dependency is + * handled by ffa_bus_discover function. arm_ffa is probed first then + * sandbox_arm_ffa. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +int sandbox_ffa_get_device(void) +{ + int ret; + + if (sandbox_ffa_priv_data.dev) + return FFA_ERR_STAT_SUCCESS; + + ret = device_bind(dm_root(), + DM_DRIVER_GET(sandbox_arm_ffa), + FFA_SANDBOX_DRV_NAME, + NULL, + ofnode_null(), + &sandbox_ffa_priv_data.dev); + if (ret) { + sandbox_ffa_priv_data.dev = NULL; + return ret; + } + + ret = device_probe(sandbox_ffa_priv_data.dev); + if (ret) { + ffa_err("[Sandbox] can not probe the device"); + device_unbind(sandbox_ffa_priv_data.dev); + sandbox_ffa_priv_data.dev = NULL; + return ret; + } + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_version - Emulated FFA_VERSION handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_VERSION FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_version) +{ + sandbox_ffa_priv_data.fwk_version = FFA_VERSION_1_0; + res->a0 = sandbox_ffa_priv_data.fwk_version; + + /* w1-w7 MBZ */ + memset(FFA_W1W7_MBZ_REG_START, 0, FFA_W1W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_id_get - Emulated FFA_ID_GET handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_ID_GET FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_id_get) +{ + res->a0 = FFA_SUCCESS; + res->a1 = 0; + + sandbox_ffa_priv_data.id = NS_PHYS_ENDPOINT_ID; + res->a2 = sandbox_ffa_priv_data.id; + + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_features - Emulated FFA_FEATURES handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_FEATURES FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_features) +{ + switch (a1) { + case FFA_RXTX_MAP: + { + res->a0 = FFA_SUCCESS; + res->a2 = RXTX_BUFFERS_MIN_SIZE; + res->a3 = 0; + /* w4-w7 MBZ */ + memset(FFA_W4W7_MBZ_REG_START, + 0, FFA_W4W7_MBZ_CNT * sizeof(unsigned long)); + break; + } + default: + { + res->a0 = FFA_ERROR; + res->a2 = FFA_ERR_STAT_NOT_SUPPORTED; + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, + 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + ffa_err("[Sandbox] FF-A interface 0x%lx not implemented", a1); + } + } + + res->a1 = 0; + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_partition_info_get - Emulated FFA_PARTITION_INFO_GET handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_PARTITION_INFO_GET FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_partition_info_get) +{ + struct ffa_partition_info *rxbuf_desc_info = NULL; + u32 descs_cnt; + u32 descs_size_bytes; + + res->a0 = FFA_ERROR; + + if (!sandbox_ffa_priv_data.pair.rxbuf) { + res->a2 = FFA_ERR_STAT_DENIED; + goto cleanup; + } + + if (sandbox_ffa_priv_data.pair_info.rxbuf_owned) { + res->a2 = FFA_ERR_STAT_BUSY; + goto cleanup; + } + + if (!sandbox_ffa_priv_data.partitions.descs) { + sandbox_ffa_priv_data.partitions.descs = sandbox_partitions; + sandbox_ffa_priv_data.partitions.count = SANDBOX_PARTITIONS_CNT; + } + + descs_size_bytes = SANDBOX_PARTITIONS_CNT * sizeof(struct ffa_partition_desc); + + /* Abort if the RX buffer size is smaller than the descriptors buffer size */ + if ((sandbox_ffa_priv_data.pair_info.rxtx_buf_size * SZ_4K) < descs_size_bytes) { + res->a2 = FFA_ERR_STAT_NO_MEMORY; + goto cleanup; + } + + rxbuf_desc_info = (struct ffa_partition_info *)sandbox_ffa_priv_data.pair.rxbuf; + + /* No UUID specified. Return the information of all partitions */ + if (!a1 && !a2 && !a3 && !a4) { + for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) + *(rxbuf_desc_info++) = + sandbox_ffa_priv_data.partitions.descs[descs_cnt].info; + + res->a0 = FFA_SUCCESS; + res->a2 = SANDBOX_PARTITIONS_CNT; + /* transfer ownership to the consumer: the non secure world */ + sandbox_ffa_priv_data.pair_info.rxbuf_owned = 1; + + goto cleanup; + } + + /* + * A UUID is specified. Return the information of all partitions matching + * the UUID + */ + + for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) + if (a1 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].UUID.words.a1 && + a2 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].UUID.words.a2 && + a3 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].UUID.words.a3 && + a4 == sandbox_ffa_priv_data.partitions.descs[descs_cnt].UUID.words.a4) { + *(rxbuf_desc_info++) = + sandbox_ffa_priv_data.partitions.descs[descs_cnt].info; + } + + if (rxbuf_desc_info != ((struct ffa_partition_info *)sandbox_ffa_priv_data.pair.rxbuf)) { + res->a0 = FFA_SUCCESS; + /* store the partitions count */ + res->a2 = (unsigned long) + (rxbuf_desc_info - (struct ffa_partition_info *) + sandbox_ffa_priv_data.pair.rxbuf); + + /* transfer ownership to the consumer: the non secure world */ + sandbox_ffa_priv_data.pair_info.rxbuf_owned = 1; + } else { + res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS; + } + +cleanup: + + ffa_err("[Sandbox] FFA_PARTITION_INFO_GET (%ld)", res->a2); + + res->a1 = 0; + + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_rxtx_map - Emulated FFA_RXTX_MAP handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_RXTX_MAP FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_rxtx_map) +{ + res->a0 = FFA_ERROR; + + if (sandbox_ffa_priv_data.pair.txbuf && sandbox_ffa_priv_data.pair.rxbuf) { + res->a2 = FFA_ERR_STAT_DENIED; + goto feedback; + } + + if (a3 >= RXTX_BUFFERS_MIN_PAGES && a1 && a2) { + sandbox_ffa_priv_data.pair.txbuf = a1; + sandbox_ffa_priv_data.pair.rxbuf = a2; + sandbox_ffa_priv_data.pair_info.rxtx_buf_size = a3; + sandbox_ffa_priv_data.pair_info.rxbuf_mapped = 1; + res->a0 = FFA_SUCCESS; + res->a2 = 0; + goto feedback; + } + + if (!a1 || !a2) + res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS; + else + res->a2 = FFA_ERR_STAT_NO_MEMORY; + + ffa_err("[Sandbox] error in FFA_RXTX_MAP arguments (%d)", (int)res->a2); + +feedback: + + res->a1 = 0; + + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, + 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_rxtx_unmap - Emulated FFA_RXTX_UNMAP handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_RXTX_UNMAP FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_rxtx_unmap) +{ + res->a0 = FFA_ERROR; + res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS; + + if (GET_NS_PHYS_ENDPOINT_ID(a1) != sandbox_ffa_priv_data.id) + goto feedback; + + if (sandbox_ffa_priv_data.pair.txbuf && sandbox_ffa_priv_data.pair.rxbuf) { + sandbox_ffa_priv_data.pair.txbuf = 0; + sandbox_ffa_priv_data.pair.rxbuf = 0; + sandbox_ffa_priv_data.pair_info.rxtx_buf_size = 0; + sandbox_ffa_priv_data.pair_info.rxbuf_mapped = 0; + res->a0 = FFA_SUCCESS; + res->a2 = 0; + goto feedback; + } + + ffa_err("[Sandbox] No buffer pair registered on behalf of the caller"); + +feedback: + + res->a1 = 0; + + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, + 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_rx_release - Emulated FFA_RX_RELEASE handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_RX_RELEASE FF-A function. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_rx_release) +{ + if (!sandbox_ffa_priv_data.pair_info.rxbuf_owned) { + res->a0 = FFA_ERROR; + res->a2 = FFA_ERR_STAT_DENIED; + } else { + sandbox_ffa_priv_data.pair_info.rxbuf_owned = 0; + res->a0 = FFA_SUCCESS; + res->a2 = 0; + } + + res->a1 = 0; + + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, + 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_sp_valid - Checks SP validity + * @part_id: partition ID to check + * + * This is the function searches the input ID in the descriptors table. + * + * Return: + * + * 1 on success (Partition found). Otherwise, failure + */ +int sandbox_ffa_sp_valid(u16 part_id) +{ + u32 descs_cnt; + + for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) + if (sandbox_ffa_priv_data.partitions.descs[descs_cnt].info.id == part_id) + return 1; + + return 0; +} + +/** + * sandbox_ffa_msg_send_direct_req - Emulated FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function + * @{a0-a7} , res: The SMC call arguments and return structure. + * + * This is the function that emulates FFA_MSG_SEND_DIRECT_{REQ,RESP} + * FF-A functions. + * + * Emulating interrupts is not supported. So, FFA_RUN and FFA_INTERRUPT are not supported. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +SANDBOX_SMC_FFA_ABI(ffa_msg_send_direct_req) +{ + u16 part_id; + + part_id = GET_DST_SP_ID(a1); + + if ((GET_NS_PHYS_ENDPOINT_ID(a1) != sandbox_ffa_priv_data.id) || + !sandbox_ffa_sp_valid(part_id) || + a2) { + res->a0 = FFA_ERROR; + res->a1 = 0; + res->a2 = FFA_ERR_STAT_INVALID_PARAMETERS; + + /* w3-w7 MBZ */ + memset(FFA_W3_MBZ_REG_START, + 0, FFA_W3W7_MBZ_CNT * sizeof(unsigned long)); + + return FFA_ERR_STAT_SUCCESS; + } + + res->a0 = FFA_MSG_SEND_DIRECT_RESP; + + res->a1 = PREP_SRC_SP_ID(part_id) | + PREP_NS_PHYS_ENDPOINT_ID(sandbox_ffa_priv_data.id); + + res->a2 = 0; + + /* + * return 0xff bytes as a response + */ + res->a3 = 0xffffffff; + res->a4 = 0xffffffff; + res->a5 = 0xffffffff; + res->a6 = 0xffffffff; + res->a7 = 0xffffffff; + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_get_prv_data - Returns the pointer to FF-A core pivate data + * @func_data: Pointer to the FF-A function arguments container structure + * + * This is the handler that returns the address of the FF-A core pivate data. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +int sandbox_ffa_get_prv_data(struct ffa_interface_data *func_data) +{ + if (!func_data) + return -EINVAL; + + if (!func_data->data0 || func_data->data0_size != sizeof(struct ffa_prvdata **)) + return -EINVAL; + + if (!func_data->data1 || func_data->data1_size != sizeof(struct sandbox_ffa_prvdata **)) + return -EINVAL; + + *((struct ffa_prvdata **)func_data->data0) = &ffa_priv_data; + *((struct sandbox_ffa_prvdata **)func_data->data1) = &sandbox_ffa_priv_data; + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_ffa_get_rxbuf_flags - Reading the mapping/ownership flags + * @queried_func_id: The FF-A function to be queried + * @func_data: Pointer to the FF-A function arguments container structure + * + * This is the handler that queries the status flags of the following emulated ABIs: + * FFA_RXTX_MAP, FFA_RXTX_UNMAP, FFA_RX_RELEASE + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +int sandbox_ffa_get_rxbuf_flags(u32 queried_func_id, struct ffa_interface_data *func_data) +{ + if (!func_data) + return -EINVAL; + + if (!func_data->data0 || func_data->data0_size != sizeof(u8)) + return -EINVAL; + + switch (queried_func_id) { + case FFA_RXTX_MAP: + case FFA_RXTX_UNMAP: + *((u8 *)func_data->data0) = sandbox_ffa_priv_data.pair_info.rxbuf_mapped; + return FFA_ERR_STAT_SUCCESS; + case FFA_RX_RELEASE: + *((u8 *)func_data->data0) = sandbox_ffa_priv_data.pair_info.rxbuf_owned; + return FFA_ERR_STAT_SUCCESS; + default: + ffa_err("[Sandbox] The querried FF-A interface flag (%d) undefined", + queried_func_id); + return -EINVAL; + } +} + +/** + * invoke_sandbox_ffa_drv_api - The driver dispatcher function + * @queried_func_id: The FF-A function to be queried + * @func_data: Pointer to the FF-A function arguments container structure + * + * The dispatcher function that selects the handler that queries the + * status of FF-A ABIs given in the input argument. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +int invoke_sandbox_ffa_drv_api(u32 queried_func_id, struct ffa_interface_data *func_data) +{ + switch (queried_func_id) { + case FFA_VERSION: + case FFA_ID_GET: + case FFA_FEATURES: + return sandbox_ffa_get_prv_data(func_data); + case FFA_RXTX_MAP: + case FFA_RXTX_UNMAP: + case FFA_RX_RELEASE: + return sandbox_ffa_get_rxbuf_flags(queried_func_id, func_data); + default: + ffa_err("[Sandbox] The querried FF-A interface (%d) undefined", queried_func_id); + return -EINVAL; + } +} + +/** + * sandbox_ffa_set_conduit - Set the conduit used by Sandbox + * + * Sets the conduit in the private data structure + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +static int sandbox_ffa_set_conduit(void) +{ + sandbox_ffa_priv_data.conduit = FFA_CONDUIT_SMC; + + ffa_info("[Sandbox] Conduit is SMC"); + + return FFA_ERR_STAT_SUCCESS; +} + +/** + * sandbox_arm_ffa_smccc_smc - FF-A SMC call emulation + * @dev: the SMC arguments to be passed to the FF-A ABI + * + * Sandbox driver emulates the FF-A ABIs SMC call using this function. + * The emulated FF-A ABI is identified and invoked. + * FF-A emulation is based on the FF-A specification 1.0 + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure. + * FF-A protocol error codes are returned using the registers arguments as described + * by the specification + */ +void sandbox_arm_ffa_smccc_smc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, + struct arm_smccc_res *res) +{ + int ret = FFA_ERR_STAT_SUCCESS; + + switch (a0) { + case FFA_VERSION: + ret = sandbox_ffa_version(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_PARTITION_INFO_GET: + ret = sandbox_ffa_partition_info_get(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_RXTX_UNMAP: + ret = sandbox_ffa_rxtx_unmap(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_MSG_SEND_DIRECT_REQ: + ret = sandbox_ffa_msg_send_direct_req(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_ID_GET: + ret = sandbox_ffa_id_get(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_FEATURES: + ret = sandbox_ffa_features(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_RXTX_MAP: + ret = sandbox_ffa_rxtx_map(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + case FFA_RX_RELEASE: + ret = sandbox_ffa_rx_release(a0, a1, a2, a3, a4, a5, a6, a7, res); + break; + default: + ffa_err("[Sandbox] Undefined FF-A interface (0x%x)", (unsigned int)a0); + } + + if (ret != FFA_ERR_STAT_SUCCESS) + ffa_err("[Sandbox] FF-A ABI internal failure (%d)", ret); +} + +/** + * sandbox_ffa_probe - The driver probe function + * @dev: the sandbox_arm_ffa device + * + * At probe level the conduit is set + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +static int sandbox_ffa_probe(struct udevice *dev) +{ + return sandbox_ffa_set_conduit(); +} + +/** + * sandbox_ffa_drv_ops - The driver operations structure + * @invoke_func: The driver dispatcher + */ +struct ffa_ops sandbox_ffa_drv_ops = { + .invoke_func = invoke_sandbox_ffa_drv_api +}; + +/** + * sandbox_ffa_device_get_ops - driver operations getter + * + * Return: + * This function returns a pointer to the driver operations structure + */ +const struct ffa_ops *sandbox_ffa_device_get_ops(void) +{ + return &sandbox_ffa_drv_ops; +} + +/** + * Declaring the sandbox_arm_ffa driver under UCLASS_FFA + */ +U_BOOT_DRIVER(sandbox_arm_ffa) = { + .name = FFA_SANDBOX_DRV_NAME, + .id = UCLASS_FFA, + .probe = sandbox_ffa_probe, +}; diff --git a/drivers/arm-ffa/sandbox_arm_ffa_prv.h b/drivers/arm-ffa/sandbox_arm_ffa_prv.h new file mode 100644 index 0000000000..56b8d50a96 --- /dev/null +++ b/drivers/arm-ffa/sandbox_arm_ffa_prv.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com + */ + +#ifndef __SANDBOX_ARM_FFA_PRV_H +#define __SANDBOX_ARM_FFA_PRV_H + +#include "arm_ffa_prv.h" + +/* + * This header is private. It is exclusively used by the Sandbox FF-A driver + */ + +/* FF-A core driver name */ +#define FFA_SANDBOX_DRV_NAME "sandbox_arm_ffa" + +/* Non-secure physical FF-A instance */ +#define NS_PHYS_ENDPOINT_ID (0) + +#define GET_NS_PHYS_ENDPOINT_ID_MASK GENMASK(31, 16) +#define GET_NS_PHYS_ENDPOINT_ID(x) \ + ((u16)(FIELD_GET(GET_NS_PHYS_ENDPOINT_ID_MASK, (x)))) + +/* Helper macro for reading the destination partition ID */ +#define GET_DST_SP_ID_MASK GENMASK(15, 0) +#define GET_DST_SP_ID(x) \ + ((u16)(FIELD_GET(GET_DST_SP_ID_MASK, (x)))) + +/* Helper macro for setting the source partition ID */ +#define PREP_SRC_SP_ID_MASK GENMASK(31, 16) +#define PREP_SRC_SP_ID(x) \ + (FIELD_PREP(PREP_SRC_SP_ID_MASK, (x))) + +/* Helper macro for setting the destination endpoint ID */ +#define PREP_NS_PHYS_ENDPOINT_ID_MASK GENMASK(15, 0) +#define PREP_NS_PHYS_ENDPOINT_ID(x) \ + (FIELD_PREP(PREP_NS_PHYS_ENDPOINT_ID_MASK, (x))) + +/* RX/TX buffers minimum size */ +#define RXTX_BUFFERS_MIN_SIZE (RXTX_4K) +#define RXTX_BUFFERS_MIN_PAGES (1) + +/* MBZ registers info */ + +/* w1-w7 MBZ */ +#define FFA_W1W7_MBZ_CNT (7) +#define FFA_W1W7_MBZ_REG_START (&res->a1) + +/* w4-w7 MBZ */ +#define FFA_W4W7_MBZ_CNT (4) +#define FFA_W4W7_MBZ_REG_START (&res->a4) + +/* w3-w7 MBZ */ +#define FFA_W3W7_MBZ_CNT (5) +#define FFA_W3_MBZ_REG_START (&res->a3) + +/* secure partitions count */ +#define SANDBOX_PARTITIONS_CNT (4) + +/* service 1 UUID binary data (little-endian format) */ +#define SANDBOX_SERVICE1_UUID_DATA \ + 0xed, 0x32, 0xd5, 0x33, \ + 0x99, 0xe6, 0x42, 0x09, \ + 0x9c, 0xc0, 0x2d, 0x72, \ + 0xcd, 0xd9, 0x98, 0xa7 + +/* service 2 UUID binary data (little-endian format) */ +#define SANDBOX_SERVICE2_UUID_DATA \ + 0xab, 0xcd, 0xd5, 0x33, \ + 0x99, 0xe6, 0x42, 0x09, \ + 0x9c, 0xc0, 0x2d, 0x72, \ + 0xcd, 0xd9, 0x98, 0xa7 + +/** + * struct ffa_rxtxpair_info - structure hosting the RX/TX buffers flags + * @rxbuf_owned: RX buffer ownership flag (the owner is non secure world: the consumer) + * @rxbuf_mapped: RX buffer mapping flag + * @txbuf_owned TX buffer ownership flag + * @txbuf_mapped: TX buffer mapping flag + * @rxtx_buf_size: RX/TX buffers size as set by the FF-A core driver + * + * Data structure hosting the ownership/mapping flags of the RX/TX buffers + * When a buffer is owned/mapped its corresponding flag is set to 1 otherwise 0. + */ +struct ffa_rxtxpair_info { + u8 rxbuf_owned; + u8 rxbuf_mapped; + u8 txbuf_owned; + u8 txbuf_mapped; + u32 rxtx_buf_size; +}; + +/** + * struct sandbox_ffa_prvdata - the driver private data structure + * + * @dev: The arm_ffa device under u-boot driver model + * @fwk_version: FF-A framework version + * @id: u-boot endpoint ID + * @partitions: The partitions descriptors structure + * @pair: The RX/TX buffers pair + * @pair_info: The RX/TX buffers pair flags and size + * @conduit: The selected conduit + * + * The driver data structure hosting all the emulated secure world data. + */ +struct sandbox_ffa_prvdata { + struct udevice *dev; + u32 fwk_version; + u16 id; + struct ffa_partitions partitions; + struct ffa_rxtxpair pair; + struct ffa_rxtxpair_info pair_info; + enum ffa_conduit conduit; +}; + +void sandbox_arm_ffa_smccc_smc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, + struct arm_smccc_res *res); + +#define SANDBOX_SMC_FFA_ABI(ffabi) static int sandbox_##ffabi(unsigned long a0, unsigned long a1, \ + unsigned long a2, unsigned long a3, unsigned long a4, \ + unsigned long a5, unsigned long a6, unsigned long a7, \ + struct arm_smccc_res *res) + +/* The core FF-A private data structure to inspect */ +extern struct ffa_prvdata ffa_priv_data; + +#endif diff --git a/include/arm_ffa.h b/include/arm_ffa.h index 98db01ee72..c400de4a70 100644 --- a/include/arm_ffa.h +++ b/include/arm_ffa.h @@ -22,6 +22,13 @@ #define ffa_info(fmt, ...) pr_info("[FFA] " fmt "\n", ##__VA_ARGS__) #define ffa_err(fmt, ...) pr_err("[FFA] " fmt "\n", ##__VA_ARGS__)
+/* panic only on real HW. On sandbox mode return an error code */ +#if CONFIG_IS_ENABLED(SANDBOX_FFA) +#define ffa_panic(fmt, ...) ffa_err("[FFA] " fmt "\n", ##__VA_ARGS__) +#else +#define ffa_panic(fmt, ...) panic("[FFA] " fmt "\n", ##__VA_ARGS__) +#endif + /* * The driver operations success error code */ @@ -184,7 +191,7 @@ const struct ffa_ops * __ffa_runtime ffa_device_get_ops(void); int ffa_get_device(void);
/** - * ffa_bus_discover - discover FF-A bus and probes the arm_ffa device + * ffa_bus_discover - discover FF-A bus and probes the arm_ffa and sandbox_arm_ffa devices */ int ffa_bus_discover(void); #endif diff --git a/include/sandbox_arm_ffa.h b/include/sandbox_arm_ffa.h new file mode 100644 index 0000000000..aa7a3454b9 --- /dev/null +++ b/include/sandbox_arm_ffa.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com + */ + +#ifndef __SANDBOX_ARM_FFA_H +#define __SANDBOX_ARM_FFA_H + +#include <arm_ffa.h> + +/** + * The device driver and the Uclass driver public functions + */ + +/** + * sandbox_ffa_get_invoke_func - performs a call to the Sandbox FF-A driver dispatcher + */ +int sandbox_ffa_get_invoke_func(u32 func_id, struct ffa_interface_data *func_data); + +/** + * sandbox_ffa_device_get_ops - driver operations getter + */ +const struct ffa_ops *sandbox_ffa_device_get_ops(void); + +/** + * sandbox_ffa_get_device - create, bind and probe the sandbox_arm_ffa device + */ +int sandbox_ffa_get_device(void); + +#endif diff --git a/include/sandbox_arm_ffa_helper.h b/include/sandbox_arm_ffa_helper.h new file mode 100644 index 0000000000..f0fcd04536 --- /dev/null +++ b/include/sandbox_arm_ffa_helper.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com + */ + +#ifndef __SANDBOX_ARM_FFA_HELPER_H +#define __SANDBOX_ARM_FFA_HELPER_H + +#include <arm_ffa_helper.h> +#include <sandbox_arm_ffa.h> +#include "../drivers/arm-ffa/sandbox_arm_ffa_prv.h" + +/* + * This header is public. Including this header provides all FF-A Sandbox data structures + * It also provides the helper function allowing to pass data and invoke Sandbox FF-A functions + * used for testing the FF-A core driver + */ + +/** + * sandbox_ffa_helper_query_core_state - Wrapper function for + * reading the FF-A core driver data + */ +int sandbox_ffa_helper_query_core_state(u32 queried_func_id, struct ffa_interface_data *func_data); + +#endif diff --git a/lib/arm-ffa/Makefile b/lib/arm-ffa/Makefile index cba625fde4..04159da8eb 100644 --- a/lib/arm-ffa/Makefile +++ b/lib/arm-ffa/Makefile @@ -6,3 +6,4 @@ # This file only gets included when CONFIG_ARM_FFA_TRANSPORT_HELPERS is set
obj-y += arm_ffa_helper.o +obj-$(CONFIG_SANDBOX_FFA) += sandbox_arm_ffa_helper.o diff --git a/lib/arm-ffa/arm_ffa_helper.c b/lib/arm-ffa/arm_ffa_helper.c index a291b000a7..3ee6ee304f 100644 --- a/lib/arm-ffa/arm_ffa_helper.c +++ b/lib/arm-ffa/arm_ffa_helper.c @@ -108,7 +108,7 @@ int __ffa_runtime ffa_helper_msg_send_direct_req(struct ffa_interface_data * ffa_helper_bus_discover - Wrapper function for FF-A bus discovery * * This boot time function should be called to discover the FF-A bus and - * probe the FF-A device. + * probe the arm_ffa and sandbox_arm_ffa devices. * To achieve that, this function is called automatically at initcalls * level (after u-boot relocation). * diff --git a/lib/arm-ffa/sandbox_arm_ffa_helper.c b/lib/arm-ffa/sandbox_arm_ffa_helper.c new file mode 100644 index 0000000000..7859f30fc7 --- /dev/null +++ b/lib/arm-ffa/sandbox_arm_ffa_helper.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi abdellatif.elkhlifi@arm.com + */ + +#include <common.h> +#include <sandbox_arm_ffa_helper.h> + +/** + * sandbox_ffa_helper_query_core_state - Wrapper function for querying FF-A implementation + * + * A helper function used for querying the status of FF-A ABIs given in the input argument + * and the FF-A core driver. + * + * Return: + * + * FFA_ERR_STAT_SUCCESS on success. Otherwise, failure + */ +int sandbox_ffa_helper_query_core_state(u32 queried_func_id, struct ffa_interface_data *func_data) +{ + return sandbox_ffa_get_invoke_func(queried_func_id, func_data); +} diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index cffa2c69d6..12fc28fd82 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2118,7 +2118,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, struct efi_event *evt, *next_event; efi_status_t ret = EFI_SUCCESS;
-#if defined(CONFIG_ARM_FFA_TRANSPORT) +#if defined(CONFIG_ARM_FFA_TRANSPORT) && !defined(CONFIG_SANDBOX_FFA) int ffa_ret; #endif
@@ -2182,7 +2182,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); }
-#if defined(CONFIG_ARM_FFA_TRANSPORT) +#if defined(CONFIG_ARM_FFA_TRANSPORT) && !defined(CONFIG_SANDBOX_FFA) /* unmap FF-A RX/TX buffers */ ffa_ret = ffa_helper_unmap_rxtx_buffers(); if (ffa_ret)