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>
Cc: Tom Rini <trini@konsulko.com>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index f0ee0b3..8aaf911 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -451,6 +451,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 b5509ee..f351d5c 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1831,6 +1831,14 @@
 	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 0000000..be2790f
--- /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 0000000..b088182
--- /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