diff options
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0006-FF-A-v15-arm_ffa-introduce-sandbox-FF-A-support.patch')
-rw-r--r-- | meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0006-FF-A-v15-arm_ffa-introduce-sandbox-FF-A-support.patch | 1314 |
1 files changed, 1314 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0006-FF-A-v15-arm_ffa-introduce-sandbox-FF-A-support.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0006-FF-A-v15-arm_ffa-introduce-sandbox-FF-A-support.patch new file mode 100644 index 0000000000..4f94b72228 --- /dev/null +++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0006-FF-A-v15-arm_ffa-introduce-sandbox-FF-A-support.patch @@ -0,0 +1,1314 @@ +From 4f104ef6804ffd6483d166840d113630be85edb0 Mon Sep 17 00:00:00 2001 +From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> +Date: Mon, 17 Jul 2023 15:18:58 +0100 +Subject: [PATCH 06/33] FF-A v15: arm_ffa: introduce sandbox FF-A support + +Emulate Secure World's FF-A ABIs and allow testing U-Boot FF-A support + +Features of the sandbox FF-A support: + +- Introduce an FF-A emulator +- Introduce an FF-A device driver for FF-A comms with emulated Secure World +- Provides test methods allowing to read the status of the inspected ABIs + +The sandbox FF-A emulator supports only 64-bit direct messaging. + +Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> +Reviewed-by: Simon Glass <sjg@chromium.org> +Upstream-Status: Submitted [cover letter: https://lore.kernel.org/all/20230713132847.176000-1-abdellatif.elkhlifi@arm.com/] +--- + MAINTAINERS | 3 +- + arch/sandbox/dts/sandbox.dtsi | 9 + + arch/sandbox/dts/test.dts | 9 + + arch/sandbox/include/asm/sandbox_arm_ffa.h | 72 ++ + .../include/asm/sandbox_arm_ffa_priv.h | 121 +++ + configs/sandbox64_defconfig | 2 + + configs/sandbox_defconfig | 2 + + doc/arch/arm64.ffa.rst | 19 +- + doc/arch/sandbox/sandbox.rst | 1 + + drivers/firmware/arm-ffa/Kconfig | 13 +- + drivers/firmware/arm-ffa/Makefile | 10 +- + drivers/firmware/arm-ffa/ffa-emul-uclass.c | 720 ++++++++++++++++++ + .../firmware/arm-ffa/sandbox_arm_ffa_priv.h | 14 - + drivers/firmware/arm-ffa/sandbox_ffa.c | 110 +++ + include/dm/uclass-id.h | 1 + + 15 files changed, 1084 insertions(+), 22 deletions(-) + create mode 100644 arch/sandbox/include/asm/sandbox_arm_ffa.h + create mode 100644 arch/sandbox/include/asm/sandbox_arm_ffa_priv.h + create mode 100644 drivers/firmware/arm-ffa/ffa-emul-uclass.c + delete mode 100644 drivers/firmware/arm-ffa/sandbox_arm_ffa_priv.h + create mode 100644 drivers/firmware/arm-ffa/sandbox_ffa.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 4ae82229fc..679a3acdd8 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -269,12 +269,13 @@ F: configs/cortina_presidio-asic-pnand_defconfig + ARM FF-A + M: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> + S: Maintained ++F: arch/sandbox/include/asm/sandbox_arm_ffa.h ++F: arch/sandbox/include/asm/sandbox_arm_ffa_priv.h + F: cmd/armffa.c + F: doc/arch/arm64.ffa.rst + F: doc/usage/cmd/armffa.rst + F: drivers/firmware/arm-ffa/ + F: include/arm_ffa.h +-F: include/sandbox_arm_ffa.h + + ARM FREESCALE IMX + M: Stefano Babic <sbabic@denx.de> +diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi +index 30a305c4d2..94a08814b8 100644 +--- a/arch/sandbox/dts/sandbox.dtsi ++++ b/arch/sandbox/dts/sandbox.dtsi +@@ -445,6 +445,15 @@ + thermal { + compatible = "sandbox,thermal"; + }; ++ ++ arm-ffa-emul { ++ compatible = "sandbox,arm-ffa-emul"; ++ ++ sandbox-arm-ffa { ++ compatible = "sandbox,arm-ffa"; ++ }; ++ }; ++ + }; + + &cros_ec { +diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts +index ff9f9222e6..c6807ee031 100644 +--- a/arch/sandbox/dts/test.dts ++++ b/arch/sandbox/dts/test.dts +@@ -1820,6 +1820,15 @@ + extcon { + compatible = "sandbox,extcon"; + }; ++ ++ arm-ffa-emul { ++ compatible = "sandbox,arm-ffa-emul"; ++ ++ sandbox-arm-ffa { ++ compatible = "sandbox,arm-ffa"; ++ }; ++ }; ++ + }; + + #include "sandbox_pmic.dtsi" +diff --git a/arch/sandbox/include/asm/sandbox_arm_ffa.h b/arch/sandbox/include/asm/sandbox_arm_ffa.h +new file mode 100644 +index 0000000000..be2790f496 +--- /dev/null ++++ b/arch/sandbox/include/asm/sandbox_arm_ffa.h +@@ -0,0 +1,72 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> ++ * ++ * Authors: ++ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> ++ */ ++ ++#ifndef __SANDBOX_ARM_FFA_H ++#define __SANDBOX_ARM_FFA_H ++ ++#include <arm_ffa.h> ++ ++/* ++ * This header provides public sandbox FF-A emulator declarations ++ * and declarations needed by FF-A sandbox clients ++ */ ++ ++/* UUIDs strings of the emulated services */ ++#define SANDBOX_SERVICE1_UUID "ed32d533-4209-99e6-2d72-cdd998a79cc0" ++#define SANDBOX_SERVICE2_UUID "ed32d544-4209-99e6-2d72-cdd998a79cc0" ++ ++/* IDs of the emulated secure partitions (SPs) */ ++#define SANDBOX_SP1_ID 0x1245 ++#define SANDBOX_SP2_ID 0x9836 ++#define SANDBOX_SP3_ID 0x6452 ++#define SANDBOX_SP4_ID 0x7814 ++ ++/* Invalid service UUID (no matching SP) */ ++#define SANDBOX_SERVICE3_UUID "55d532ed-0942-e699-722d-c09ca798d9cd" ++ ++/* Invalid service UUID (invalid UUID string format) */ ++#define SANDBOX_SERVICE4_UUID "32ed-0942-e699-722d-c09ca798d9cd" ++ ++/* Number of valid services */ ++#define SANDBOX_SP_COUNT_PER_VALID_SERVICE 2 ++ ++/** ++ * struct ffa_sandbox_data - query ABI state data structure ++ * @data0_size: size of the first argument ++ * @data0: pointer to the first argument ++ * @data1_size>: size of the second argument ++ * @data1: pointer to the second argument ++ * ++ * Used to pass various types of data with different sizes between ++ * the test cases and the sandbox emulator. ++ * The data is for querying FF-A ABIs state. ++ */ ++struct ffa_sandbox_data { ++ u32 data0_size; /* size of the first argument */ ++ void *data0; /* pointer to the first argument */ ++ u32 data1_size; /* size of the second argument */ ++ void *data1; /* pointer to the second argument */ ++}; ++ ++/* The sandbox FF-A emulator public functions */ ++ ++/** ++ * sandbox_query_ffa_emul_state() - Inspect the FF-A ABIs ++ * @queried_func_id: The FF-A function to be queried ++ * @func_data: Pointer to the FF-A function arguments container structure ++ * ++ * Query the status of FF-A ABI specified in the input argument. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++int sandbox_query_ffa_emul_state(u32 queried_func_id, ++ struct ffa_sandbox_data *func_data); ++ ++#endif +diff --git a/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h b/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h +new file mode 100644 +index 0000000000..b0881822d7 +--- /dev/null ++++ b/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h +@@ -0,0 +1,121 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> ++ * ++ * Authors: ++ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> ++ */ ++ ++#ifndef __SANDBOX_ARM_FFA_PRV_H ++#define __SANDBOX_ARM_FFA_PRV_H ++ ++#include <arm_ffa_priv.h> ++ ++/* This header is exclusively used by the Sandbox FF-A driver and emulator */ ++ ++/* 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 */ ++ ++/* x1-x7 MBZ */ ++#define FFA_X1X7_MBZ_CNT (7) ++#define FFA_X1X7_MBZ_REG_START (&res->a1) ++ ++/* x4-x7 MBZ */ ++#define FFA_X4X7_MBZ_CNT (4) ++#define FFA_X4X7_MBZ_REG_START (&res->a4) ++ ++/* x3-x7 MBZ */ ++#define FFA_X3X7_MBZ_CNT (5) ++#define FFA_X3_MBZ_REG_START (&res->a3) ++ ++/* number of emulated FF-A secure partitions (SPs) */ ++#define SANDBOX_PARTITIONS_CNT (4) ++ ++/* Binary data of the emulated services UUIDs */ ++ ++/* service 1 UUID binary data (little-endian format) */ ++#define SANDBOX_SERVICE1_UUID_A1 0xed32d533 ++#define SANDBOX_SERVICE1_UUID_A2 0x99e64209 ++#define SANDBOX_SERVICE1_UUID_A3 0x9cc02d72 ++#define SANDBOX_SERVICE1_UUID_A4 0xcdd998a7 ++ ++/* service 2 UUID binary data (little-endian format) */ ++#define SANDBOX_SERVICE2_UUID_A1 0xed32d544 ++#define SANDBOX_SERVICE2_UUID_A2 0x99e64209 ++#define SANDBOX_SERVICE2_UUID_A3 0x9cc02d72 ++#define SANDBOX_SERVICE2_UUID_A4 0xcdd998a7 ++ ++/** ++ * struct ffa_rxtxpair_info - structure hosting the RX/TX buffers flags ++ * @rxbuf_owned: RX buffer ownership flag (the owner is non secure world) ++ * @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 ++ * ++ * Hosts 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_emul - emulator data ++ * ++ * @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 ++ * @test_ffa_data: The data of the FF-A bus under test ++ * ++ * Hosts all the emulated secure world data. ++ */ ++struct sandbox_ffa_emul { ++ u32 fwk_version; ++ u16 id; ++ struct ffa_partitions partitions; ++ struct ffa_rxtxpair pair; ++ struct ffa_rxtxpair_info pair_info; ++}; ++ ++/** ++ * ffa_emul_find() - Finds the FF-A emulator ++ * @dev: the sandbox FF-A device (sandbox-arm-ffa) ++ * @emulp: the FF-A emulator device (sandbox-ffa-emul) ++ * Return: ++ * 0 on success. Otherwise, failure ++ */ ++int ffa_emul_find(struct udevice *dev, struct udevice **emulp); ++ ++#endif +diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig +index 98b3e0cda4..2db69b8e52 100644 +--- a/configs/sandbox64_defconfig ++++ b/configs/sandbox64_defconfig +@@ -260,3 +260,5 @@ CONFIG_FWU_MULTI_BANK_UPDATE=y + CONFIG_UNIT_TEST=y + CONFIG_UT_TIME=y + CONFIG_UT_DM=y ++CONFIG_NVMXIP_QSPI=y ++CONFIG_ARM_FFA_TRANSPORT=y +diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig +index 1ec44d5b33..f77733377d 100644 +--- a/configs/sandbox_defconfig ++++ b/configs/sandbox_defconfig +@@ -344,3 +344,5 @@ CONFIG_TEST_FDTDEC=y + CONFIG_UNIT_TEST=y + CONFIG_UT_TIME=y + CONFIG_UT_DM=y ++CONFIG_CMD_2048=y ++CONFIG_ARM_FFA_TRANSPORT=y +diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst +index aefd527447..b7c754fa3d 100644 +--- a/doc/arch/arm64.ffa.rst ++++ b/doc/arch/arm64.ffa.rst +@@ -33,6 +33,10 @@ The U-Boot FF-A support provides the following parts: + + - A Uclass driver providing generic FF-A methods. + - An Arm FF-A device driver providing Arm-specific methods and reusing the Uclass methods. ++- A sandbox emulator for Arm FF-A, emulates the FF-A side of the Secure World and provides ++ FF-A ABIs inspection methods. ++- An FF-A sandbox device driver for FF-A communication with the emulated Secure World. ++ The driver leverages the FF-A Uclass to establish FF-A communication. + + FF-A and SMC specifications + ------------------------------------------- +@@ -62,6 +66,7 @@ CONFIG_ARM_FFA_TRANSPORT + Enables the FF-A support. Turn this on if you want to use FF-A + communication. + When using an Arm 64-bit platform, the Arm FF-A driver will be used. ++ When using sandbox, the sandbox FF-A emulator and FF-A sandbox driver will be used. + + FF-A ABIs under the hood + --------------------------------------- +@@ -98,10 +103,8 @@ architecture features including FF-A bus. + + Class Index Probed Driver Name + ----------------------------------------------------------- +- ... + firmware 0 [ + ] psci |-- psci + ffa 0 [ ] arm_ffa | `-- arm_ffa +- ... + + The PSCI driver is bound to the PSCI device and when probed it tries to discover + the architecture features by calling a callback the features drivers provide. +@@ -205,6 +208,18 @@ The following features are provided: + + - FF-A bus can be compiled and used without EFI + ++Relationship between the sandbox emulator and the FF-A device ++--------------------------------------------------------------- ++ ++:: ++ ++ => dm tree ++ ++ Class Index Probed Driver Name ++ ----------------------------------------------------------- ++ ffa_emul 0 [ + ] sandbox_ffa_emul `-- arm-ffa-emul ++ ffa 0 [ ] sandbox_arm_ffa `-- sandbox-arm-ffa ++ + The armffa command + ----------------------------------- + +diff --git a/doc/arch/sandbox/sandbox.rst b/doc/arch/sandbox/sandbox.rst +index 77ca6bc4cc..a3631de749 100644 +--- a/doc/arch/sandbox/sandbox.rst ++++ b/doc/arch/sandbox/sandbox.rst +@@ -200,6 +200,7 @@ Supported Drivers + + U-Boot sandbox supports these emulations: + ++- Arm FF-A + - Block devices + - Chrome OS EC + - GPIO +diff --git a/drivers/firmware/arm-ffa/Kconfig b/drivers/firmware/arm-ffa/Kconfig +index a7d5392859..d75f8b53fd 100644 +--- a/drivers/firmware/arm-ffa/Kconfig ++++ b/drivers/firmware/arm-ffa/Kconfig +@@ -2,9 +2,9 @@ + + config ARM_FFA_TRANSPORT + bool "Enable Arm Firmware Framework for Armv8-A driver" +- depends on DM && ARM64 +- select ARM_SMCCC +- select ARM_SMCCC_FEATURES ++ depends on DM && (ARM64 || SANDBOX) ++ select ARM_SMCCC if !SANDBOX ++ select ARM_SMCCC_FEATURES if !SANDBOX + imply CMD_ARMFFA + select LIB_UUID + select DEVRES +@@ -33,5 +33,10 @@ config ARM_FFA_TRANSPORT + Generic FF-A methods are implemented in the Uclass (arm-ffa-uclass.c). + Arm specific methods are implemented in the Arm driver (arm-ffa.c). + +- For more details about the FF-A support, please refer to doc/arch/arm64.ffa.rst ++ FF-A sandbox is provided to run FF-A under sandbox and allows to test the FF-A Uclass. ++ Sandbox support includes an emulator for Arm FF-A which emulates the FF-A side of ++ the Secure World and provides FF-A ABIs inspection methods (ffa-emul-uclass.c). ++ An FF-A sandbox driver is also provided for FF-A communication with the emulated ++ Secure World (sandbox_ffa.c). + ++ For more details about the FF-A support, please refer to doc/arch/arm64.ffa.rst +diff --git a/drivers/firmware/arm-ffa/Makefile b/drivers/firmware/arm-ffa/Makefile +index 11b1766285..318123a7f4 100644 +--- a/drivers/firmware/arm-ffa/Makefile ++++ b/drivers/firmware/arm-ffa/Makefile +@@ -5,4 +5,12 @@ + # Authors: + # Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> + +-obj-y += arm-ffa-uclass.o arm-ffa.o ++# build the generic FF-A methods ++obj-y += arm-ffa-uclass.o ++ifeq ($(CONFIG_SANDBOX),y) ++# build the FF-A sandbox emulator and driver ++obj-y += ffa-emul-uclass.o sandbox_ffa.o ++else ++# build the Arm64 FF-A driver ++obj-y += arm-ffa.o ++endif +diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c +new file mode 100644 +index 0000000000..5562bbaac3 +--- /dev/null ++++ b/drivers/firmware/arm-ffa/ffa-emul-uclass.c +@@ -0,0 +1,720 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> ++ * ++ * Authors: ++ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> ++ */ ++#include <common.h> ++#include <dm.h> ++#include <mapmem.h> ++#include <string.h> ++#include <asm/global_data.h> ++#include <asm/sandbox_arm_ffa.h> ++#include <asm/sandbox_arm_ffa_priv.h> ++#include <dm/device-internal.h> ++#include <dm/lists.h> ++#include <dm/root.h> ++#include <linux/errno.h> ++#include <linux/sizes.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* The partitions (SPs) table */ ++static struct ffa_partition_desc sandbox_partitions[SANDBOX_PARTITIONS_CNT] = { ++ { ++ .info = { .id = SANDBOX_SP1_ID, .exec_ctxt = 0x5687, .properties = 0x89325621 }, ++ .sp_uuid = { ++ .a1 = SANDBOX_SERVICE1_UUID_A1, ++ .a2 = SANDBOX_SERVICE1_UUID_A2, ++ .a3 = SANDBOX_SERVICE1_UUID_A3, ++ .a4 = SANDBOX_SERVICE1_UUID_A4, ++ } ++ }, ++ { ++ .info = { .id = SANDBOX_SP3_ID, .exec_ctxt = 0x7687, .properties = 0x23325621 }, ++ .sp_uuid = { ++ .a1 = SANDBOX_SERVICE2_UUID_A1, ++ .a2 = SANDBOX_SERVICE2_UUID_A2, ++ .a3 = SANDBOX_SERVICE2_UUID_A3, ++ .a4 = SANDBOX_SERVICE2_UUID_A4, ++ } ++ }, ++ { ++ .info = { .id = SANDBOX_SP2_ID, .exec_ctxt = 0x9587, .properties = 0x45325621 }, ++ .sp_uuid = { ++ .a1 = SANDBOX_SERVICE1_UUID_A1, ++ .a2 = SANDBOX_SERVICE1_UUID_A2, ++ .a3 = SANDBOX_SERVICE1_UUID_A3, ++ .a4 = SANDBOX_SERVICE1_UUID_A4, ++ } ++ }, ++ { ++ .info = { .id = SANDBOX_SP4_ID, .exec_ctxt = 0x1487, .properties = 0x70325621 }, ++ .sp_uuid = { ++ .a1 = SANDBOX_SERVICE2_UUID_A1, ++ .a2 = SANDBOX_SERVICE2_UUID_A2, ++ .a3 = SANDBOX_SERVICE2_UUID_A3, ++ .a4 = SANDBOX_SERVICE2_UUID_A4, ++ } ++ } ++ ++}; ++ ++/* The emulator functions */ ++ ++/** ++ * sandbox_ffa_version() - Emulated FFA_VERSION handler function ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_VERSION FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++ ++static int sandbox_ffa_version(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) ++{ ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ priv->fwk_version = FFA_VERSION_1_0; ++ res->a0 = priv->fwk_version; ++ ++ /* x1-x7 MBZ */ ++ memset(FFA_X1X7_MBZ_REG_START, 0, FFA_X1X7_MBZ_CNT * sizeof(ulong)); ++ ++ return 0; ++} ++ ++/** ++ * sandbox_ffa_id_get() - Emulated FFA_ID_GET handler function ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_ID_GET FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_id_get(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) ++{ ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ res->a1 = 0; ++ ++ priv->id = NS_PHYS_ENDPOINT_ID; ++ res->a2 = priv->id; ++ ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ ++ return 0; ++} ++ ++/** ++ * sandbox_ffa_features() - Emulated FFA_FEATURES handler function ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_FEATURES FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_features(ffa_value_t *pargs, ffa_value_t *res) ++{ ++ res->a1 = 0; ++ ++ if (pargs->a1 == FFA_SMC_64(FFA_RXTX_MAP)) { ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ res->a2 = RXTX_BUFFERS_MIN_SIZE; ++ res->a3 = 0; ++ /* x4-x7 MBZ */ ++ memset(FFA_X4X7_MBZ_REG_START, 0, FFA_X4X7_MBZ_CNT * sizeof(ulong)); ++ return 0; ++ } ++ ++ res->a0 = FFA_SMC_32(FFA_ERROR); ++ res->a2 = -NOT_SUPPORTED; ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ log_err("FF-A interface %lx not implemented\n", pargs->a1); ++ ++ return ffa_to_std_errmap[NOT_SUPPORTED]; ++} ++ ++/** ++ * sandbox_ffa_partition_info_get() - Emulated FFA_PARTITION_INFO_GET handler ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_PARTITION_INFO_GET FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_partition_info_get(struct udevice *emul, ffa_value_t *pargs, ++ ffa_value_t *res) ++{ ++ struct ffa_partition_info *rxbuf_desc_info = NULL; ++ u32 descs_cnt; ++ u32 descs_size_bytes; ++ int ret; ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ res->a0 = FFA_SMC_32(FFA_ERROR); ++ ++ if (!priv->pair.rxbuf) { ++ res->a2 = -DENIED; ++ ret = ffa_to_std_errmap[DENIED]; ++ goto cleanup; ++ } ++ ++ if (priv->pair_info.rxbuf_owned) { ++ res->a2 = -BUSY; ++ ret = ffa_to_std_errmap[BUSY]; ++ goto cleanup; ++ } ++ ++ if (!priv->partitions.descs) { ++ priv->partitions.descs = sandbox_partitions; ++ priv->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 descs buffer size */ ++ if ((priv->pair_info.rxtx_buf_size * SZ_4K) < descs_size_bytes) { ++ res->a2 = -NO_MEMORY; ++ ret = ffa_to_std_errmap[NO_MEMORY]; ++ goto cleanup; ++ } ++ ++ rxbuf_desc_info = priv->pair.rxbuf; ++ ++ /* No UUID specified. Return the information of all partitions */ ++ if (!pargs->a1 && !pargs->a2 && !pargs->a3 && !pargs->a4) { ++ for (descs_cnt = 0; descs_cnt < SANDBOX_PARTITIONS_CNT; descs_cnt++) ++ *(rxbuf_desc_info++) = priv->partitions.descs[descs_cnt].info; ++ ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ res->a2 = SANDBOX_PARTITIONS_CNT; ++ /* Transfer ownership to the consumer: the non secure world */ ++ priv->pair_info.rxbuf_owned = 1; ++ ret = 0; ++ ++ goto cleanup; ++ } ++ ++ /* A UUID specified. Return the info of all SPs matching the UUID */ ++ ++ for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) ++ if (pargs->a1 == priv->partitions.descs[descs_cnt].sp_uuid.a1 && ++ pargs->a2 == priv->partitions.descs[descs_cnt].sp_uuid.a2 && ++ pargs->a3 == priv->partitions.descs[descs_cnt].sp_uuid.a3 && ++ pargs->a4 == priv->partitions.descs[descs_cnt].sp_uuid.a4) { ++ *(rxbuf_desc_info++) = priv->partitions.descs[descs_cnt].info; ++ } ++ ++ if (rxbuf_desc_info != priv->pair.rxbuf) { ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ /* Store the partitions count */ ++ res->a2 = (ulong) ++ (rxbuf_desc_info - (struct ffa_partition_info *) ++ priv->pair.rxbuf); ++ ret = 0; ++ ++ /* Transfer ownership to the consumer: the non secure world */ ++ priv->pair_info.rxbuf_owned = 1; ++ } else { ++ /* Unrecognized UUID */ ++ res->a2 = -INVALID_PARAMETERS; ++ ret = ffa_to_std_errmap[INVALID_PARAMETERS]; ++ } ++ ++cleanup: ++ ++ log_err("FFA_PARTITION_INFO_GET (%ld)\n", res->a2); ++ ++ res->a1 = 0; ++ ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ ++ return ret; ++} ++ ++/** ++ * sandbox_ffa_rxtx_map() - Emulated FFA_RXTX_MAP handler ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_RXTX_MAP FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_rxtx_map(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) ++{ ++ int ret; ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ res->a0 = FFA_SMC_32(FFA_ERROR); ++ ++ if (priv->pair.txbuf && priv->pair.rxbuf) { ++ res->a2 = -DENIED; ++ ret = ffa_to_std_errmap[DENIED]; ++ goto feedback; ++ } ++ ++ if (pargs->a3 >= RXTX_BUFFERS_MIN_PAGES && pargs->a1 && pargs->a2) { ++ priv->pair.txbuf = map_sysmem(pargs->a1, 0); ++ priv->pair.rxbuf = map_sysmem(pargs->a2, 0); ++ priv->pair_info.rxtx_buf_size = pargs->a3; ++ priv->pair_info.rxbuf_mapped = 1; ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ res->a2 = 0; ++ ret = 0; ++ goto feedback; ++ } ++ ++ if (!pargs->a1 || !pargs->a2) { ++ res->a2 = -INVALID_PARAMETERS; ++ ret = ffa_to_std_errmap[INVALID_PARAMETERS]; ++ } else { ++ res->a2 = -NO_MEMORY; ++ ret = ffa_to_std_errmap[NO_MEMORY]; ++ } ++ ++ log_err("Error in FFA_RXTX_MAP arguments (%d)\n", ++ (int)res->a2); ++ ++feedback: ++ ++ res->a1 = 0; ++ ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ ++ return ret; ++} ++ ++/** ++ * sandbox_ffa_rxtx_unmap() - Emulated FFA_RXTX_UNMAP handler ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_RXTX_UNMAP FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_rxtx_unmap(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) ++{ ++ int ret; ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ res->a0 = FFA_SMC_32(FFA_ERROR); ++ res->a2 = -INVALID_PARAMETERS; ++ ret = ffa_to_std_errmap[INVALID_PARAMETERS]; ++ ++ if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != priv->id) ++ goto feedback; ++ ++ if (priv->pair.txbuf && priv->pair.rxbuf) { ++ priv->pair.txbuf = 0; ++ priv->pair.rxbuf = 0; ++ priv->pair_info.rxtx_buf_size = 0; ++ priv->pair_info.rxbuf_mapped = 0; ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ res->a2 = 0; ++ ret = 0; ++ goto feedback; ++ } ++ ++ log_err("No buffer pair registered on behalf of the caller\n"); ++ ++feedback: ++ ++ res->a1 = 0; ++ ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ ++ return ret; ++} ++ ++/** ++ * sandbox_ffa_rx_release() - Emulated FFA_RX_RELEASE handler ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_RX_RELEASE FF-A function. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_rx_release(struct udevice *emul, ffa_value_t *pargs, ffa_value_t *res) ++{ ++ int ret; ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ if (!priv->pair_info.rxbuf_owned) { ++ res->a0 = FFA_SMC_32(FFA_ERROR); ++ res->a2 = -DENIED; ++ ret = ffa_to_std_errmap[DENIED]; ++ } else { ++ priv->pair_info.rxbuf_owned = 0; ++ res->a0 = FFA_SMC_32(FFA_SUCCESS); ++ res->a2 = 0; ++ ret = 0; ++ } ++ ++ res->a1 = 0; ++ ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ ++ return ret; ++} ++ ++/** ++ * sandbox_ffa_sp_valid() - Check SP validity ++ * @emul: The sandbox FF-A emulator device ++ * @part_id: partition ID to check ++ * ++ * Search the input ID in the descriptors table. ++ * ++ * Return: ++ * ++ * 1 on success (Partition found). Otherwise, failure ++ */ ++static int sandbox_ffa_sp_valid(struct udevice *emul, u16 part_id) ++{ ++ u32 descs_cnt; ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ for (descs_cnt = 0 ; descs_cnt < SANDBOX_PARTITIONS_CNT ; descs_cnt++) ++ if (priv->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 ++ * @emul: The sandbox FF-A emulator device ++ * @pargs: The SMC call input arguments a0-a7 ++ * @res: The SMC return data ++ * ++ * Emulate FFA_MSG_SEND_DIRECT_{REQ,RESP} FF-A ABIs. ++ * Only SMC 64-bit is supported in Sandbox. ++ * ++ * Emulating interrupts is not supported. So, FFA_RUN and FFA_INTERRUPT are not ++ * supported. In case of success FFA_MSG_SEND_DIRECT_RESP is returned with ++ * default pattern data (0xff). ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_msg_send_direct_req(struct udevice *emul, ++ ffa_value_t *pargs, ffa_value_t *res) ++{ ++ u16 part_id; ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ part_id = GET_DST_SP_ID(pargs->a1); ++ ++ if (GET_NS_PHYS_ENDPOINT_ID(pargs->a1) != priv->id || ++ !sandbox_ffa_sp_valid(emul, part_id) || pargs->a2) { ++ res->a0 = FFA_SMC_32(FFA_ERROR); ++ res->a1 = 0; ++ res->a2 = -INVALID_PARAMETERS; ++ ++ /* x3-x7 MBZ */ ++ memset(FFA_X3_MBZ_REG_START, 0, FFA_X3X7_MBZ_CNT * sizeof(ulong)); ++ ++ return ffa_to_std_errmap[INVALID_PARAMETERS]; ++ } ++ ++ res->a0 = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP); ++ ++ res->a1 = PREP_SRC_SP_ID(part_id) | ++ PREP_NS_PHYS_ENDPOINT_ID(priv->id); ++ ++ res->a2 = 0; ++ ++ /* Return 0xff bytes as a response */ ++ res->a3 = -1UL; ++ res->a4 = -1UL; ++ res->a5 = -1UL; ++ res->a6 = -1UL; ++ res->a7 = -1UL; ++ ++ return 0; ++} ++ ++/** ++ * sandbox_ffa_get_rxbuf_flags() - Read the mapping/ownership flags ++ * @emul: The sandbox FF-A emulator device ++ * @queried_func_id: The FF-A function to be queried ++ * @func_data: Pointer to the FF-A function arguments container structure ++ * ++ * Query the status flags of the following emulated ++ * ABIs: FFA_RXTX_MAP, FFA_RXTX_UNMAP, FFA_RX_RELEASE. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_get_rxbuf_flags(struct udevice *emul, u32 queried_func_id, ++ struct ffa_sandbox_data *func_data) ++{ ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ 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) = priv->pair_info.rxbuf_mapped; ++ return 0; ++ case FFA_RX_RELEASE: ++ *((u8 *)func_data->data0) = priv->pair_info.rxbuf_owned; ++ return 0; ++ default: ++ log_err("The querried FF-A interface flag (%d) undefined\n", ++ queried_func_id); ++ return -EINVAL; ++ } ++} ++ ++/** ++ * sandbox_ffa_get_fwk_version() - Return the FFA framework version ++ * @emul: The sandbox FF-A emulator device ++ * @func_data: Pointer to the FF-A function arguments container structure ++ * ++ * Return the FFA framework version read from the FF-A emulator data. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_get_fwk_version(struct udevice *emul, struct ffa_sandbox_data *func_data) ++{ ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ if (!func_data) ++ return -EINVAL; ++ ++ if (!func_data->data0 || ++ func_data->data0_size != sizeof(priv->fwk_version)) ++ return -EINVAL; ++ ++ *((u32 *)func_data->data0) = priv->fwk_version; ++ ++ return 0; ++} ++ ++/** ++ * sandbox_ffa_get_parts() - Return the address of partitions data ++ * @emul: The sandbox FF-A emulator device ++ * @func_data: Pointer to the FF-A function arguments container structure ++ * ++ * Return the address of partitions data read from the FF-A emulator data. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_get_parts(struct udevice *emul, struct ffa_sandbox_data *func_data) ++{ ++ struct sandbox_ffa_emul *priv = dev_get_priv(emul); ++ ++ if (!func_data) ++ return -EINVAL; ++ ++ if (!func_data->data0 || ++ func_data->data0_size != sizeof(struct ffa_partitions *)) ++ return -EINVAL; ++ ++ *((struct ffa_partitions **)func_data->data0) = &priv->partitions; ++ ++ return 0; ++} ++ ++/** ++ * sandbox_query_ffa_emul_state() - Inspect the FF-A ABIs ++ * @queried_func_id: The FF-A function to be queried ++ * @func_data: Pointer to the FF-A function arguments container structure ++ * ++ * Query the status of FF-A ABI specified in the input argument. ++ * ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++int sandbox_query_ffa_emul_state(u32 queried_func_id, ++ struct ffa_sandbox_data *func_data) ++{ ++ struct udevice *emul; ++ int ret; ++ ++ ret = uclass_first_device_err(UCLASS_FFA_EMUL, &emul); ++ if (ret) { ++ log_err("Cannot find FF-A emulator during querying state\n"); ++ return ret; ++ } ++ ++ switch (queried_func_id) { ++ case FFA_RXTX_MAP: ++ case FFA_RXTX_UNMAP: ++ case FFA_RX_RELEASE: ++ return sandbox_ffa_get_rxbuf_flags(emul, queried_func_id, func_data); ++ case FFA_VERSION: ++ return sandbox_ffa_get_fwk_version(emul, func_data); ++ case FFA_PARTITION_INFO_GET: ++ return sandbox_ffa_get_parts(emul, func_data); ++ default: ++ log_err("Undefined FF-A interface (%d)\n", ++ queried_func_id); ++ return -EINVAL; ++ } ++} ++ ++/** ++ * sandbox_arm_ffa_smccc_smc() - FF-A SMC call emulation ++ * @args: the SMC call arguments ++ * @res: the SMC call returned data ++ * ++ * Emulate the FF-A ABIs SMC call. ++ * The emulated FF-A ABI is identified and invoked. ++ * FF-A emulation is based on the FF-A specification 1.0 ++ * ++ * Return: ++ * ++ * 0 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(ffa_value_t *args, ffa_value_t *res) ++{ ++ int ret = 0; ++ struct udevice *emul; ++ ++ ret = uclass_first_device_err(UCLASS_FFA_EMUL, &emul); ++ if (ret) { ++ log_err("Cannot find FF-A emulator during SMC emulation\n"); ++ return; ++ } ++ ++ switch (args->a0) { ++ case FFA_SMC_32(FFA_VERSION): ++ ret = sandbox_ffa_version(emul, args, res); ++ break; ++ case FFA_SMC_32(FFA_PARTITION_INFO_GET): ++ ret = sandbox_ffa_partition_info_get(emul, args, res); ++ break; ++ case FFA_SMC_32(FFA_RXTX_UNMAP): ++ ret = sandbox_ffa_rxtx_unmap(emul, args, res); ++ break; ++ case FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ): ++ ret = sandbox_ffa_msg_send_direct_req(emul, args, res); ++ break; ++ case FFA_SMC_32(FFA_ID_GET): ++ ret = sandbox_ffa_id_get(emul, args, res); ++ break; ++ case FFA_SMC_32(FFA_FEATURES): ++ ret = sandbox_ffa_features(args, res); ++ break; ++ case FFA_SMC_64(FFA_RXTX_MAP): ++ ret = sandbox_ffa_rxtx_map(emul, args, res); ++ break; ++ case FFA_SMC_32(FFA_RX_RELEASE): ++ ret = sandbox_ffa_rx_release(emul, args, res); ++ break; ++ default: ++ log_err("Undefined FF-A interface (%lx)\n", ++ args->a0); ++ } ++ ++ if (ret != 0) ++ log_err("FF-A ABI internal failure (%d)\n", ret); ++} ++ ++/** ++ * invoke_ffa_fn() - SMC wrapper ++ * @args: FF-A ABI arguments to be copied to Xn registers ++ * @res: FF-A ABI return data to be copied from Xn registers ++ * ++ * Calls the emulated SMC call. ++ */ ++void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res) ++{ ++ sandbox_arm_ffa_smccc_smc(&args, res); ++} ++ ++/** ++ * ffa_emul_find() - Find the FF-A emulator ++ * @dev: the sandbox FF-A device (sandbox-arm-ffa) ++ * @emulp: the FF-A emulator device (sandbox-ffa-emul) ++ * ++ * Search for the FF-A emulator and returns its device pointer. ++ * ++ * Return: ++ * 0 on success. Otherwise, failure ++ */ ++int ffa_emul_find(struct udevice *dev, struct udevice **emulp) ++{ ++ int ret; ++ ++ ret = uclass_first_device_err(UCLASS_FFA_EMUL, emulp); ++ if (ret) { ++ log_err("Cannot find FF-A emulator\n"); ++ return ret; ++ } ++ ++ log_info("FF-A emulator ready to use\n"); ++ ++ return 0; ++} ++ ++UCLASS_DRIVER(ffa_emul) = { ++ .name = "ffa_emul", ++ .id = UCLASS_FFA_EMUL, ++ .post_bind = dm_scan_fdt_dev, ++}; ++ ++static const struct udevice_id sandbox_ffa_emul_ids[] = { ++ { .compatible = "sandbox,arm-ffa-emul" }, ++ { } ++}; ++ ++/* Declaring the sandbox FF-A emulator under UCLASS_FFA_EMUL */ ++U_BOOT_DRIVER(sandbox_ffa_emul) = { ++ .name = "sandbox_ffa_emul", ++ .id = UCLASS_FFA_EMUL, ++ .of_match = sandbox_ffa_emul_ids, ++ .priv_auto = sizeof(struct sandbox_ffa_emul), ++}; +diff --git a/drivers/firmware/arm-ffa/sandbox_arm_ffa_priv.h b/drivers/firmware/arm-ffa/sandbox_arm_ffa_priv.h +deleted file mode 100644 +index 4338f9c9b1..0000000000 +--- a/drivers/firmware/arm-ffa/sandbox_arm_ffa_priv.h ++++ /dev/null +@@ -1,14 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ */ +-/* +- * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> +- * +- * Authors: +- * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> +- */ +- +-#ifndef __SANDBOX_ARM_FFA_PRV_H +-#define __SANDBOX_ARM_FFA_PRV_H +- +-/* Future sandbox support private declarations */ +- +-#endif +diff --git a/drivers/firmware/arm-ffa/sandbox_ffa.c b/drivers/firmware/arm-ffa/sandbox_ffa.c +new file mode 100644 +index 0000000000..ef9491ccea +--- /dev/null ++++ b/drivers/firmware/arm-ffa/sandbox_ffa.c +@@ -0,0 +1,110 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> ++ * ++ * Authors: ++ * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> ++ */ ++#include <common.h> ++#include <arm_ffa.h> ++#include <dm.h> ++#include <log.h> ++#include <asm/global_data.h> ++#include <asm/sandbox_arm_ffa_priv.h> ++#include <dm/device-internal.h> ++#include <linux/errno.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/** ++ * sandbox_ffa_discover() - perform sandbox FF-A discovery ++ * @dev: The sandbox FF-A bus device ++ * Try to discover the FF-A framework. Discovery is performed by ++ * querying the FF-A framework version from secure world using the FFA_VERSION ABI. ++ * Return: ++ * ++ * 0 on success. Otherwise, failure ++ */ ++static int sandbox_ffa_discover(struct udevice *dev) ++{ ++ int ret; ++ struct udevice *emul; ++ ++ log_info("Emulated FF-A framework discovery\n"); ++ ++ ret = ffa_emul_find(dev, &emul); ++ if (ret) { ++ log_err("Cannot find FF-A emulator\n"); ++ return ret; ++ } ++ ++ ret = ffa_get_version_hdlr(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++/** ++ * sandbox_ffa_probe() - The sandbox FF-A driver probe function ++ * @dev: the sandbox-arm-ffa device ++ * Save the emulator device in uc_priv. ++ * Return: ++ * ++ * 0 on success. ++ */ ++static int sandbox_ffa_probe(struct udevice *dev) ++{ ++ int ret; ++ struct ffa_priv *uc_priv = dev_get_uclass_priv(dev); ++ ++ ret = uclass_first_device_err(UCLASS_FFA_EMUL, &uc_priv->emul); ++ if (ret) { ++ log_err("Cannot find FF-A emulator\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * sandbox_ffa_bind() - The sandbox FF-A driver bind function ++ * @dev: the sandbox-arm-ffa device ++ * Try to discover the emulated FF-A bus. ++ * Return: ++ * ++ * 0 on success. ++ */ ++static int sandbox_ffa_bind(struct udevice *dev) ++{ ++ int ret; ++ ++ ret = sandbox_ffa_discover(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++/* Sandbox Arm FF-A emulator operations */ ++ ++static const struct ffa_bus_ops sandbox_ffa_ops = { ++ .partition_info_get = ffa_get_partitions_info_hdlr, ++ .sync_send_receive = ffa_msg_send_direct_req_hdlr, ++ .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, ++}; ++ ++static const struct udevice_id sandbox_ffa_id[] = { ++ { "sandbox,arm-ffa", 0 }, ++ { }, ++}; ++ ++/* Declaring the sandbox FF-A driver under UCLASS_FFA */ ++U_BOOT_DRIVER(sandbox_arm_ffa) = { ++ .name = "sandbox_arm_ffa", ++ .of_match = sandbox_ffa_id, ++ .id = UCLASS_FFA, ++ .bind = sandbox_ffa_bind, ++ .probe = sandbox_ffa_probe, ++ .ops = &sandbox_ffa_ops, ++}; +diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h +index 3c6af2e3d2..0432c95c9e 100644 +--- a/include/dm/uclass-id.h ++++ b/include/dm/uclass-id.h +@@ -63,6 +63,7 @@ enum uclass_id { + UCLASS_ETH_PHY, /* Ethernet PHY device */ + UCLASS_EXTCON, /* External Connector Class */ + UCLASS_FFA, /* Arm Firmware Framework for Armv8-A */ ++ UCLASS_FFA_EMUL, /* sandbox FF-A device emulator */ + UCLASS_FIRMWARE, /* Firmware */ + UCLASS_FPGA, /* FPGA device */ + UCLASS_FUZZING_ENGINE, /* Fuzzing engine */ +-- +2.25.1 + |