summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0006-FF-A-v15-arm_ffa-introduce-sandbox-FF-A-support.patch
diff options
context:
space:
mode:
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.patch1314
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
+