[PATCH 0/3] Corstone-1000: enable platform specific configs
From: Abdellatif El Khlifi This patchset enables configs needed by the Corstone-1000 platform. The enabled configs allow the following: - unzip the kernel before executing it (the kernel has become too large to fit in the available storage) - enable distro_bootcmd (needed to boot distros from storage devices) - enable PSCI reset (Corstone-1000 needs the PSCI reset interface for the system reset) The corstone1000_defconfig is generated using savedefconfig. Cheers, Abdellatif Cc: Tom Rini Cc: Xueliang Zhong Abdellatif El Khlifi (2): corstone1000: add compressed kernel support corstone1000: enable distro booting command Emekcan Aras (1): corstone1000: enable PSCI reset configs/corstone1000_defconfig | 1551 +++- include/configs/corstone1000.h |3 +- 2 files changed, 1552 insertions(+), 2 deletions(-) -- 2.25.1
[PATCH 2/3] corstone1000: enable distro booting command
From: Abdellatif El Khlifi enable distro_bootcmd Signed-off-by: Abdellatif El Khlifi Signed-off-by: Rui Miguel Silva --- include/configs/corstone1000.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/configs/corstone1000.h b/include/configs/corstone1000.h index 3347c11792..3ada21cbba 100644 --- a/include/configs/corstone1000.h +++ b/include/configs/corstone1000.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * (C) Copyright 2022 ARM Limited + * Copyright 2022-2023 Arm Limited and/or its affiliates * (C) Copyright 2022 Linaro * Rui Miguel Silva * Abdellatif El Khlifi @@ -29,5 +29,6 @@ #include +#define CFG_EXTRA_ENV_SETTINGS BOOTENV #endif -- 2.25.1
[PATCH 1/3] corstone1000: add compressed kernel support
From: Abdellatif El Khlifi unzip the kernel before executing it The Corstone-1000 kernel has become too large to fit in the available storage. Switching to a compressed kernel avoids the problem, but requires uncompressing it. Changes made are generated using savedefconfig. Signed-off-by: Abdellatif El Khlifi Signed-off-by: Jon Mason Signed-off-by: Rui Miguel Silva --- configs/corstone1000_defconfig | 1551 +++- 1 file changed, 1550 insertions(+), 1 deletion(-) diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig index 3b5733b777..f25da79ec8 100644 --- a/configs/corstone1000_defconfig +++ b/configs/corstone1000_defconfig @@ -1,69 +1,1618 @@ +# +# Automatically generated file; DO NOT EDIT. +# U-Boot 2023.10-rc4 Configuration +# + +# +# Compiler: aarch64-poky-linux-gcc (GCC) 12.2.0 +# +CONFIG_CREATE_ARCH_SYMLINK=y +CONFIG_SYS_CACHE_SHIFT_6=y +CONFIG_SYS_CACHELINE_SIZE=64 +CONFIG_LINKER_LIST_ALIGN=8 +# CONFIG_ARC is not set CONFIG_ARM=y +# CONFIG_M68K is not set +# CONFIG_MICROBLAZE is not set +# CONFIG_MIPS is not set +# CONFIG_NIOS2 is not set +# CONFIG_PPC is not set +# CONFIG_RISCV is not set +# CONFIG_SANDBOX is not set +# CONFIG_SH is not set +# CONFIG_X86 is not set +# CONFIG_XTENSA is not set +CONFIG_SYS_ARCH="arm" +CONFIG_SYS_CPU="armv8" +CONFIG_SYS_VENDOR="armltd" +CONFIG_SYS_BOARD="corstone1000" +CONFIG_SYS_CONFIG_NAME="corstone1000" + +# +# Skipping low level initialization functions +# CONFIG_SKIP_LOWLEVEL_INIT=y +# CONFIG_SKIP_LOWLEVEL_INIT_ONLY is not set +# CONFIG_SYS_ICACHE_OFF is not set +# CONFIG_SYS_DCACHE_OFF is not set + +# +# ARM architecture +# +CONFIG_ARM64=y +CONFIG_ARM64_CRC32=y +CONFIG_COUNTER_FREQUENCY=0 +# CONFIG_POSITION_INDEPENDENT is not set +# CONFIG_INIT_SP_RELATIVE is not set +# CONFIG_GIC_V3_ITS is not set +CONFIG_STATIC_RELA=y +CONFIG_DMA_ADDR_T_64BIT=y +CONFIG_ARM_ASM_UNIFIED=y +# CONFIG_SYS_ARM_CACHE_CP15 is not set +# CONFIG_SYS_ARM_MMU is not set +# CONFIG_SYS_ARM_MPU is not set +CONFIG_SYS_ARM_ARCH=8 +CONFIG_SYS_ARM_CACHE_WRITEBACK=y +# CONFIG_SYS_ARM_CACHE_WRITETHROUGH is not set +# CONFIG_SYS_ARM_CACHE_WRITEALLOC is not set +# CONFIG_ARCH_CPU_INIT is not set +CONFIG_SYS_ARCH_TIMER=y +CONFIG_ARM_SMCCC=y +# CONFIG_SYS_L2_PL310 is not set +# CONFIG_SPL_SYS_L2_PL310 is not set +# CONFIG_SYS_L2CACHE_OFF is not set +# CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK is not set +# CONFIG_USE_ARCH_MEMCPY is not set +# CONFIG_USE_ARCH_MEMSET is not set +CONFIG_ARM64_SUPPORT_AARCH32=y +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_HISTB is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_TARGET_STV0991 is not set +# CONFIG_ARCH_BCM283X is not set +# CONFIG_ARCH_BCMSTB is not set +# CONFIG_ARCH_BCMBCA is not set +# CONFIG_TARGET_VEXPRESS_CA9X4 is not set +# CONFIG_TARGET_BCMNS is not set +# CONFIG_TARGET_BCMNS2 is not set +# CONFIG_TARGET_BCMNS3 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IPQ40XX is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_K3 is not set +# CONFIG_ARCH_OMAP2PLUS is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_IMX8 is not set +# CONFIG_ARCH_IMX8M is not set +# CONFIG_ARCH_IMX8ULP is not set +# CONFIG_ARCH_IMX9 is not set +# CONFIG_ARCH_IMXRT is not set +# CONFIG_ARCH_MX23 is not set +# CONFIG_ARCH_MX28 is not set +# CONFIG_ARCH_MX31 is not set +# CONFIG_ARCH_MX7ULP is not set +# CONFIG_ARCH_MX7 is not set +# CONFIG_ARCH_MX6 is not set +# CONFIG_ARCH_MX5 is not set +# CONFIG_ARCH_NEXELL is not set +# CONFIG_ARCH_NPCM is not set +# CONFIG_ARCH_APPLE is not set +# CONFIG_ARCH_OWL is not set +# CONFIG_ARCH_QEMU is not set +# CONFIG_ARCH_RMOBILE is not set +# CONFIG_ARCH_SNAPDRAGON is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VERSAL is not set +# CONFIG_ARCH_VERSAL_NET is not set +# CONFIG_ARCH_VF610 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_ARCH_ZYNQMP_R5 is not set +# CONFIG_ARCH_ZYNQMP is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_VEXPRESS64 is not set CONFIG_TARGET_CORSTONE1000=y +# CONFIG_TARGET_TOTAL_COMPUTE is not set +# CONFIG_TARGET_LS2080A_EMU is not set +# CONFIG_TARGET_LS1088AQDS is not set +# CONFIG_TARGET_LS2080AQDS is not set +# CONFIG_TARGET_LS2080ARDB is not set +# CONFIG_TARGET_LS2081ARDB is not set +# CONFIG_TARGET_LX2160ARDB is not set +# CONFIG_TARGET_LX2160AQDS is not set +# CONFIG_TARGET_LX2162AQDS is not set +# CONFIG_TARGET_HIKEY is not set +# CONFIG_TARGET_HIKEY960 is not set +# CONFIG_TARGET_POPLAR is not set +# CONFIG_TARGET_LS1012AQDS is not set +# CONFIG_TARGET_LS1012ARDB is not set +# CONFIG_TARGET_LS1012A2G5RDB is not set +# CONFIG_TARGET_LS1012AFRWY is not set +# CONFIG_T
[PATCH 3/3] corstone1000: enable PSCI reset
From: Emekcan Aras enable PSCI reset used for the system reset Even though Corstone-1000 does not implement the entire PSCI APIs, it relies on PSCI reset interface for the system reset. Signed-off-by: Emekcan Aras Signed-off-by: Abdellatif El Khlifi --- configs/corstone1000_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig index f25da79ec8..f8c48972cc 100644 --- a/configs/corstone1000_defconfig +++ b/configs/corstone1000_defconfig @@ -1330,7 +1330,7 @@ CONFIG_PL01X_SERIAL=y # CONFIG_SYSRESET=y CONFIG_SYSRESET_CMD_RESET=y -# CONFIG_SYSRESET_PSCI is not set +CONFIG_SYSRESET_PSCI=y # CONFIG_SYSRESET_SYSCON is not set # CONFIG_SYSRESET_WATCHDOG is not set # CONFIG_SYSRESET_RESETCTL is not set -- 2.25.1
[PATCH] corstone1000: update maintainers
From: Abdellatif El Khlifi Update MAINTAINERS of corstone1000 board. Signed-off-by: Xueliang Zhong Signed-off-by: Abdellatif El Khlifi --- board/armltd/corstone1000/MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/armltd/corstone1000/MAINTAINERS b/board/armltd/corstone1000/MAINTAINERS index 8c905686de..1cc9aaa29a 100644 --- a/board/armltd/corstone1000/MAINTAINERS +++ b/board/armltd/corstone1000/MAINTAINERS @@ -1,6 +1,6 @@ CORSTONE1000 BOARD -M: Rui Miguel Silva -M: Vishnu Banavath +M: Abdellatif El Khlifi +M: Xueliang Zhong S: Maintained F: board/armltd/corstone1000/ F: include/configs/corstone1000.h -- 2.25.1
[PATCH v1 2/6] sandbox64: fix: return unsigned long in readq()
From: Abdellatif El Khlifi make readq return unsigned long readq should return 64-bit data Signed-off-by: Abdellatif El Khlifi --- arch/sandbox/cpu/cpu.c| 2 +- arch/sandbox/include/asm/io.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 636d3545b9..248d17a85c 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -230,7 +230,7 @@ phys_addr_t map_to_sysmem(const void *ptr) return mentry->tag; } -unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size) +unsigned long sandbox_read(const void *addr, enum sandboxio_size_t size) { struct sandbox_state *state = state_get_current(); diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index ad6c29a4e2..31ab7289b4 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -45,7 +45,7 @@ static inline void unmap_sysmem(const void *vaddr) /* Map from a pointer to our RAM buffer */ phys_addr_t map_to_sysmem(const void *ptr); -unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size); +unsigned long sandbox_read(const void *addr, enum sandboxio_size_t size); void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size); #define readb(addr) sandbox_read((const void *)addr, SB_SIZE_8) -- 2.17.1
[PATCH v1 0/6] introduce NVM XIP block storage emulation
From: Abdellatif El Khlifi Adding block storage emulation for NVM XIP flash devices. Some paltforms such as Corstone-1000 need to see NVM XIP raw flash as a block storage device with read only capability. Here NVM flash devices are devices with addressable memory (e.g: QSPI NOR flash). The NVM XIP block storage emulation provides the following features: - Emulate NVM XIP raw flash as a block storage device with read only capability - Being generic by design and can be used by any platform - Device tree node - Platforms can use multiple NVM XIP devices at the same time by defining a DT node for each one of them - A generic NVMXIP block driver allowing to read from the XIP flash - A generic NVMXIP QSPI driver - Implemented on top of memory-mapped IO (using readq macro) - Enabling NVMXIP in sandbox64 - A sandbox test case - Enabling NVMXIP in Corstone1000 platform as a use case For more details please refer to the readme [A]. [A]: doc/develop/driver-model/nvmxip.rst Cheers, Abdellatif Cc: Tom Rini Cc: Simon Glass Cc: Drew Reed Cc: Xueliang Zhong Abdellatif El Khlifi (6): drivers/nvmxip: introduce NVM XIP block storage emulation sandbox64: fix: return unsigned long in readq() sandbox64: add support for NVMXIP QSPI corstone1000: add NVM XIP QSPI device tree node corstone1000: enable NVM XIP QSPI flash sandbox64: add a test case for UCLASS_NVMXIP MAINTAINERS| 8 ++ arch/arm/dts/corstone1000.dtsi | 9 +- arch/sandbox/cpu/cpu.c | 2 +- arch/sandbox/dts/sandbox64.dts | 13 ++ arch/sandbox/dts/test.dts | 14 +++ arch/sandbox/include/asm/io.h | 2 +- configs/corstone1000_defconfig | 1 + configs/sandbox64_defconfig| 1 + doc/develop/driver-model/index.rst | 1 + doc/develop/driver-model/nvmxip.rst| 70 +++ doc/device-tree-bindings/nvmxip/nvmxip.txt | 56 + drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/block/blk-uclass.c | 1 + drivers/nvmxip/Kconfig | 19 +++ drivers/nvmxip/Makefile| 8 ++ drivers/nvmxip/nvmxip-uclass.c | 15 +++ drivers/nvmxip/nvmxip.c| 133 + drivers/nvmxip/nvmxip.h| 51 drivers/nvmxip/nvmxip_qspi.c | 67 +++ include/dm/uclass-id.h | 1 + test/dm/Makefile | 5 + test/dm/nvmxip.c | 117 ++ 23 files changed, 594 insertions(+), 3 deletions(-) create mode 100644 doc/develop/driver-model/nvmxip.rst create mode 100644 doc/device-tree-bindings/nvmxip/nvmxip.txt create mode 100644 drivers/nvmxip/Kconfig create mode 100644 drivers/nvmxip/Makefile create mode 100644 drivers/nvmxip/nvmxip-uclass.c create mode 100644 drivers/nvmxip/nvmxip.c create mode 100644 drivers/nvmxip/nvmxip.h create mode 100644 drivers/nvmxip/nvmxip_qspi.c create mode 100644 test/dm/nvmxip.c -- 2.17.1
[PATCH v1 5/6] corstone1000: enable NVM XIP QSPI flash
From: Abdellatif El Khlifi add the QSPI flash device with block storage capability Signed-off-by: Abdellatif El Khlifi --- configs/corstone1000_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig index dddfa27507..815355a544 100644 --- a/configs/corstone1000_defconfig +++ b/configs/corstone1000_defconfig @@ -52,3 +52,4 @@ CONFIG_DM_SERIAL=y CONFIG_USB=y CONFIG_USB_ISP1760=y CONFIG_ERRNO_STR=y +CONFIG_NVMXIP_QSPI=y -- 2.17.1
[PATCH v1 3/6] sandbox64: add support for NVMXIP QSPI
From: Abdellatif El Khlifi enable NVMXIP QSPI for sandbox 64-bit Adding two NVM XIP QSPI storage devices. Signed-off-by: Abdellatif El Khlifi --- arch/sandbox/dts/sandbox64.dts | 13 + arch/sandbox/dts/test.dts | 14 ++ configs/sandbox64_defconfig| 1 + drivers/nvmxip/nvmxip.c| 4 drivers/nvmxip/nvmxip.h| 3 +++ 5 files changed, 35 insertions(+) diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts index a9cd7908f8..aed3801af8 100644 --- a/arch/sandbox/dts/sandbox64.dts +++ b/arch/sandbox/dts/sandbox64.dts @@ -89,6 +89,19 @@ cs-gpios = <0>, <&gpio_a 0>; }; + nvmxip-qspi1@0800 { + compatible = "nvmxip,qspi"; + reg = <0x0 0x0800 0x0 0x0020>; + lba_shift = <9>; + lba = <4096>; + }; + + nvmxip-qspi2@0820 { + compatible = "nvmxip,qspi"; + reg = <0x0 0x0820 0x0 0x0010>; + lba_shift = <9>; + lba = <2048>; + }; }; #include "sandbox.dtsi" diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index dffe10adbf..c3ba0a225e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1745,6 +1745,20 @@ compatible = "u-boot,fwu-mdata-gpt"; fwu-mdata-store = <&mmc0>; }; + + nvmxip-qspi1@0800 { + compatible = "nvmxip,qspi"; + reg = <0x0800 0x0020>; + lba_shift = <9>; + lba = <4096>; + }; + + nvmxip-qspi2@0820 { + compatible = "nvmxip,qspi"; + reg = <0x0820 0x0010>; + lba_shift = <9>; + lba = <2048>; + }; }; #include "sandbox_pmic.dtsi" diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index ba45ac0b71..cd4dadb190 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -259,3 +259,4 @@ CONFIG_FWU_MULTI_BANK_UPDATE=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_NVMXIP_QSPI=y \ No newline at end of file diff --git a/drivers/nvmxip/nvmxip.c b/drivers/nvmxip/nvmxip.c index c276fb147e..ea9b9bfa48 100644 --- a/drivers/nvmxip/nvmxip.c +++ b/drivers/nvmxip/nvmxip.c @@ -87,6 +87,10 @@ int nvmxip_init(struct udevice *udev) priv_data->udev = udev; priv_data->plat_data = plat_data; +#if CONFIG_IS_ENABLED(SANDBOX64) + sandbox_set_enable_memio(true); +#endif + nvmxip_bdev_max_devs++; snprintf(bdev_name, NVMXIP_BLKDEV_NAME_SZ, "nvmxip-blk#%d", nvmxip_bdev_max_devs); diff --git a/drivers/nvmxip/nvmxip.h b/drivers/nvmxip/nvmxip.h index 47ae3bd8ab..0cb8e511f0 100644 --- a/drivers/nvmxip/nvmxip.h +++ b/drivers/nvmxip/nvmxip.h @@ -10,6 +10,9 @@ #define __DRIVER_NVMXIP_H__ #include +#if CONFIG_IS_ENABLED(SANDBOX64) +#include +#endif #include #include #include -- 2.17.1
[PATCH v1 4/6] corstone1000: add NVM XIP QSPI device tree node
From: Abdellatif El Khlifi add QSPI flash device node for block storage access Signed-off-by: Abdellatif El Khlifi --- arch/arm/dts/corstone1000.dtsi | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/corstone1000.dtsi b/arch/arm/dts/corstone1000.dtsi index 4e46826f88..533dfdf8e1 100644 --- a/arch/arm/dts/corstone1000.dtsi +++ b/arch/arm/dts/corstone1000.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 or MIT /* - * Copyright (c) 2022, Arm Limited. All rights reserved. + * Copyright 2022-2023 Arm Limited and/or its affiliates * Copyright (c) 2022, Linaro Limited. All rights reserved. * */ @@ -38,6 +38,13 @@ reg = <0x8820 0x77e0>; }; + nvmxip-qspi@0800 { + compatible = "nvmxip,qspi"; + reg = <0x0800 0x200>; + lba_shift = <9>; + lba = <65536>; + }; + gic: interrupt-controller@1c00 { compatible = "arm,gic-400"; #interrupt-cells = <3>; -- 2.17.1
[PATCH v1 6/6] sandbox64: add a test case for UCLASS_NVMXIP
From: Abdellatif El Khlifi provide a test for NVM XIP devices The test case allows to make sure of the following: - The NVM XIP QSPI devices are probed - The DT entries are read correctly - the data read from the flash by the NVMXIP block driver is correct Signed-off-by: Abdellatif El Khlifi --- MAINTAINERS | 1 + test/dm/Makefile | 5 ++ test/dm/nvmxip.c | 117 +++ 3 files changed, 123 insertions(+) create mode 100644 test/dm/nvmxip.c diff --git a/MAINTAINERS b/MAINTAINERS index 539d01f68c..e92898e462 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1199,6 +1199,7 @@ S:Maintained F: doc/develop/driver-model/nvmxip.rst F: doc/device-tree-bindings/nvmxip/nvmxip.txt F: drivers/nvmxip/ +F: test/dm/nvmxip.c NVMEM M: Sean Anderson diff --git a/test/dm/Makefile b/test/dm/Makefile index 7a79b6e1a2..7f9d0b3c38 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2013 Google, Inc +# Copyright 2023 Arm Limited and/or its affiliates obj-$(CONFIG_UT_DM) += test-dm.o @@ -17,6 +18,10 @@ obj-$(CONFIG_UT_DM) += test-uclass.o obj-$(CONFIG_UT_DM) += core.o obj-$(CONFIG_UT_DM) += read.o obj-$(CONFIG_UT_DM) += phys2bus.o +ifeq ($(CONFIG_NVMXIP_QSPI)$(CONFIG_SANDBOX64),yy) +obj-y += nvmxip.o +endif + ifneq ($(CONFIG_SANDBOX),) ifeq ($(CONFIG_ACPIGEN),y) obj-y += acpi.o diff --git a/test/dm/nvmxip.c b/test/dm/nvmxip.c new file mode 100644 index 00..b65154d125 --- /dev/null +++ b/test/dm/nvmxip.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Functional tests for UCLASS_FFA class + * + * Copyright 2023 Arm Limited and/or its affiliates + * + * Authors: + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include +#include "../../drivers/nvmxip/nvmxip.h" +#include +#include + +/* NVMXIP devices described in the device tree */ +#define SANDBOX_NVMXIP_DEVICES 2 + +/* reference device tree data for the probed devices */ +static struct nvmxip_plat nvmqspi_refdata[SANDBOX_NVMXIP_DEVICES] = { + {0x0800, 9, 4096}, {0x0820, 9, 2048} +}; + +#define NVMXIP_BLK_START_PATTERN 0x1122334455667788ULL +#define NVMXIP_BLK_END_PATTERN 0xa1a2a3a4a5a6a7a8ULL + +static int dm_nvmxip_flash_sanity(u8 device_idx, void *buffer) +{ + int i; + u64 *ptr = NULL; + u8 *base = NULL; + unsigned long blksz; + + blksz = 1 << nvmqspi_refdata[device_idx].lba_shift; + + /* if buffer not NULL, init the flash with the pattern data*/ + if (!buffer) + base = map_sysmem(nvmqspi_refdata[device_idx].phys_base, 0); + else + base = buffer; + + for (i = 0; i < nvmqspi_refdata[device_idx].lba ; i++) { + ptr = (u64 *)(base + i * blksz); + + /* write an 8 bytes pattern at the start of the current block*/ + if (!buffer) + *ptr = NVMXIP_BLK_START_PATTERN; + else if (*ptr != NVMXIP_BLK_START_PATTERN) + return -EINVAL; + + ptr = (u64 *)((u8 *)ptr + blksz - sizeof(u64)); + + /* write an 8 bytes pattern at the end of the current block*/ + if (!buffer) + *ptr = NVMXIP_BLK_END_PATTERN; + else if (*ptr != NVMXIP_BLK_END_PATTERN) + return -EINVAL; + } + + if (!buffer) + unmap_sysmem(base); + + return 0; +} + +static int dm_test_nvmxip(struct unit_test_state *uts) +{ + struct nvmxip_plat *plat_data = NULL; + struct udevice *dev = NULL, *bdev = NULL; + u8 device_idx; + void *buffer = NULL; + unsigned long flashsz; + + /* set the flash content first for both devices */ + dm_nvmxip_flash_sanity(0, NULL); + dm_nvmxip_flash_sanity(1, NULL); + + /* probing all NVM XIP QSPI devices */ + for (device_idx = 0, uclass_first_device(UCLASS_NVMXIP, &dev); +dev; +uclass_next_device(&dev), device_idx++) { + plat_data = dev_get_plat(dev); + + /* device tree entries checks */ + ut_assertok(nvmqspi_refdata[device_idx].phys_base != plat_data->phys_base); + ut_assertok(nvmqspi_refdata[device_idx].lba_shift != plat_data->lba_shift); + ut_assertok(nvmqspi_refdata[device_idx].lba != plat_data->lba); + + /* before reading all the flash blocks, let's calculate the flash size */ + flashsz = plat_data->lba << plat_data->lba_shift; + + /* allocate the user buffer where to copy the blocks data to */ + buffer = calloc(flashsz, 1); + ut_assertok(!buffer); + + /* the block device is the child of the parent device probed with DT*/ + ut_assertok(device_find_first_child(dev, &bdev)); + + /* reading al
[PATCH v1 1/6] drivers/nvmxip: introduce NVM XIP block storage emulation
From: Abdellatif El Khlifi add block storage emulation for NVM XIP flash devices Some paltforms such as Corstone-1000 need to see NVM XIP raw flash as a block storage device with read only capability. Here NVM flash devices are devices with addressable memory (e.g: QSPI NOR flash). The implementation is generic and can be used by different platforms. Two drivers are provided as follows. nvmxip-blk : a generic block driver allowing to read from the XIP flash nvmxip_qspi : The driver probed with the DT and parent of the nvmxip-blk device. nvmxip_qspi can be reused by other platforms. If the platform has custom settings to apply before using the flash, then the platform can provide its own parent driver belonging to UCLASS_NVMXIP and reuse nvmxip-blk. The custom driver can be implmented like nvmxip_qspi in addition to the platform custom settings. Platforms can use multiple NVM XIP devices at the same time by defining a DT node for each one of them. For more details please refer to doc/develop/driver-model/nvmxip.rst Signed-off-by: Abdellatif El Khlifi --- MAINTAINERS| 7 ++ doc/develop/driver-model/index.rst | 1 + doc/develop/driver-model/nvmxip.rst| 70 +++ doc/device-tree-bindings/nvmxip/nvmxip.txt | 56 + drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/block/blk-uclass.c | 1 + drivers/nvmxip/Kconfig | 19 +++ drivers/nvmxip/Makefile| 8 ++ drivers/nvmxip/nvmxip-uclass.c | 15 +++ drivers/nvmxip/nvmxip.c| 129 + drivers/nvmxip/nvmxip.h| 48 drivers/nvmxip/nvmxip_qspi.c | 67 +++ include/dm/uclass-id.h | 1 + 14 files changed, 425 insertions(+) create mode 100644 doc/develop/driver-model/nvmxip.rst create mode 100644 doc/device-tree-bindings/nvmxip/nvmxip.txt create mode 100644 drivers/nvmxip/Kconfig create mode 100644 drivers/nvmxip/Makefile create mode 100644 drivers/nvmxip/nvmxip-uclass.c create mode 100644 drivers/nvmxip/nvmxip.c create mode 100644 drivers/nvmxip/nvmxip.h create mode 100644 drivers/nvmxip/nvmxip_qspi.c diff --git a/MAINTAINERS b/MAINTAINERS index b2de50ccfc..539d01f68c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1193,6 +1193,13 @@ F: cmd/nvme.c F: include/nvme.h F: doc/develop/driver-model/nvme.rst +NVMXIP +M: Abdellatif El Khlifi +S: Maintained +F: doc/develop/driver-model/nvmxip.rst +F: doc/device-tree-bindings/nvmxip/nvmxip.txt +F: drivers/nvmxip/ + NVMEM M: Sean Anderson S: Maintained diff --git a/doc/develop/driver-model/index.rst b/doc/develop/driver-model/index.rst index 7366ef818c..8e12bbd936 100644 --- a/doc/develop/driver-model/index.rst +++ b/doc/develop/driver-model/index.rst @@ -20,6 +20,7 @@ subsystems livetree migration nvme + nvmxip of-plat pci-info pmic-framework diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst new file mode 100644 index 00..91b24e4e50 --- /dev/null +++ b/doc/develop/driver-model/nvmxip.rst @@ -0,0 +1,70 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +NVM XIP Block Storage Emulation Driver +=== + +Summary +--- + +Non-Volatile Memory devices with addressable memory (e.g: QSPI NOR flash) could +be used for block storage needs (e.g: parsing a GPT layout in a raw QSPI NOR flash). + +The NVMXIP class provides this functionality and can be used for any 64-bit platform. + +The NVMXIP class provides the following drivers: + + nvmxip-blk : + +A generic block driver allowing to read from the XIP flash. + The driver belongs to UCLASS_BLK. + The driver implemented by drivers/nvmxip/nvmxip.c + + nvmxip_qspi : + +The driver probed with the DT and parent of the nvmxip-blk device. +nvmxip_qspi can be reused by other platforms. If the platform +has custom settings to apply before using the flash, then the platform +can provide its own parent driver belonging to UCLASS_NVMXIP and reuse +nvmxip-blk. The custom driver can be implmented like nvmxip_qspi in +addition to the platform custom settings. + The nvmxip_qspi driver belongs to UCLASS_NVMXIP. + The driver implemented by drivers/nvmxip/nvmxip_qspi.c + +The implementation is generic and can be used by different platforms. + +Supported hardware + + +Any 64-bit plaform. + +Configuration +-- + +config NVMXIP + This option allows the emulation of a block storage device + on top of a direct access non volatile memory XIP flash devices. + This support provides the read operation. + This option provides the block st
[PATCH v2 0/6] introduce Arm FF-A support
From: Abdellatif El Khlifi This patchset adds support for Arm FF-A (Arm Firmware Framework for Armv8-A v1.0). FF-A support is generic by design and can be used by any Arm platform. The features added are as follows: 1/ FF-A bus driver 2/ armffa command 3/ FF-A Sandbox driver 4/ FF-A Sandbox test cases 5/ FF-A MM communication The suggested design considers FF-A as a discoverable bus. The Secure World is considered as one entity to communicate with using the FF-A bus. 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. The Secure World firmware runs under TrustZone HW (such as Optee). The same approach was followed in the FF-A driver in Linux kernel (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/arm_ffa/bus.c?h=v5.15#n211)) Cc: Tom Rini Cc: Rob Herring Cc: Ilias Apalodimas Cc: Achin Gupta Cc: Simon Glass Cc: Vishnu Banavath Abdellatif El Khlifi (6): arm_ffa: introduce Arm FF-A low-level driver arm_ffa: introduce armffa command arm_ffa: introduce the FF-A Sandbox driver arm_ffa: introduce Sandbox test cases for UCLASS_FFA arm_ffa: introduce armffa command Sandbox test arm_ffa: introduce FF-A MM communication MAINTAINERS | 15 + arch/arm/cpu/armv8/cache.S| 16 + arch/arm/cpu/armv8/cache_v8.c |3 +- arch/arm/cpu/armv8/smccc-call.S | 27 + arch/arm/lib/asm-offsets.c|6 + cmd/Kconfig | 10 + cmd/Makefile |2 + cmd/armffa.c | 266 + common/board_r.c |7 + configs/sandbox64_defconfig |2 + configs/sandbox_defconfig |2 + doc/arch/sandbox.rst |1 + drivers/Kconfig |2 + drivers/Makefile |1 + drivers/arm-ffa/Kconfig | 34 + drivers/arm-ffa/Makefile |7 + drivers/arm-ffa/arm-ffa-uclass.c | 103 ++ drivers/arm-ffa/arm_ffa_prv.h | 193 drivers/arm-ffa/core.c| 1384 + drivers/arm-ffa/sandbox.c | 669 drivers/arm-ffa/sandbox_arm_ffa_prv.h | 131 +++ include/arm_ffa.h | 197 include/arm_ffa_helper.h | 45 + include/dm/uclass-id.h|1 + include/linux/arm-smccc.h | 28 +- include/mm_communication.h|4 +- include/sandbox_arm_ffa.h | 31 + include/sandbox_arm_ffa_helper.h | 26 + lib/Kconfig |1 + lib/Makefile |1 + lib/arm-ffa/Kconfig |6 + lib/arm-ffa/Makefile |9 + lib/arm-ffa/arm_ffa_helper.c | 188 lib/arm-ffa/sandbox_arm_ffa_helper.c | 23 + lib/efi_loader/Kconfig| 14 +- lib/efi_loader/efi_boottime.c | 17 + lib/efi_loader/efi_variable_tee.c | 281 - test/cmd/Makefile |1 + test/cmd/armffa.c | 33 + test/cmd/armffa.h | 13 + test/dm/Makefile |1 + test/dm/ffa.c | 418 test/dm/ffa.h | 22 + 43 files changed, 4230 insertions(+), 11 deletions(-) create mode 100644 cmd/armffa.c create mode 100644 drivers/arm-ffa/Kconfig create mode 100644 drivers/arm-ffa/Makefile create mode 100644 drivers/arm-ffa/arm-ffa-uclass.c create mode 100644 drivers/arm-ffa/arm_ffa_prv.h create mode 100644 drivers/arm-ffa/core.c create mode 100644 drivers/arm-ffa/sandbox.c create mode 100644 drivers/arm-ffa/sandbox_arm_ffa_prv.h create mode 100644 include/arm_ffa.h create mode 100644 include/arm_ffa_helper.h create mode 100644 include/sandbox_arm_ffa.h create mode 100644 include/sandbox_arm_ffa_helper.h create mode 100644 lib/arm-ffa/Kconfig create mode 100644 lib/arm-ffa/Makefile create mode 100644 lib/arm-ffa/arm_ffa_helper.c create mode 100644 lib/arm-ffa/sandbox_arm_ffa_helper.c create mode 100644 test/cmd/armffa.c create mode 100644 test/cmd/armffa.h create mode 100644 test/dm/ffa.c create mode 100644 test/dm/ffa.h -- 2.17.1
[PATCH v2 1/6] arm_ffa: introduce Arm FF-A low-level driver
From: Abdellatif El Khlifi Add the driver implementing Arm Firmware Framework for Armv8-A v1.0 The Firmware Framework for Arm A-profile processors (FF-A) describes interfaces (ABIs) that standardize communication between the Secure World and Normal World leveraging TrustZone technology. This driver uses SMC32 calling convention. In u-boot FF-A design, FF-A is considered as a discoverable bus. The Secure World is considered as one entity to communicate with using the FF-A bus. 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. The driver provides helper FF-A interfaces for user layers. These helper functions allow clients to pass data and select the FF-A function to use for the communication with secure world. Signed-off-by: Abdellatif El Khlifi --- MAINTAINERS |8 + arch/arm/cpu/armv8/smccc-call.S | 27 + arch/arm/lib/asm-offsets.c |6 + common/board_r.c |7 + drivers/Kconfig |2 + drivers/Makefile |1 + drivers/arm-ffa/Kconfig | 27 + drivers/arm-ffa/Makefile |6 + drivers/arm-ffa/arm-ffa-uclass.c | 64 ++ drivers/arm-ffa/arm_ffa_prv.h| 193 + drivers/arm-ffa/core.c | 1349 ++ include/arm_ffa.h| 190 + include/arm_ffa_helper.h | 45 + include/dm/uclass-id.h |1 + include/linux/arm-smccc.h| 28 +- lib/Kconfig |1 + lib/Makefile |1 + lib/arm-ffa/Kconfig |6 + lib/arm-ffa/Makefile |8 + lib/arm-ffa/arm_ffa_helper.c | 188 + lib/efi_loader/efi_boottime.c| 17 + 21 files changed, 2174 insertions(+), 1 deletion(-) create mode 100644 drivers/arm-ffa/Kconfig create mode 100644 drivers/arm-ffa/Makefile create mode 100644 drivers/arm-ffa/arm-ffa-uclass.c create mode 100644 drivers/arm-ffa/arm_ffa_prv.h create mode 100644 drivers/arm-ffa/core.c create mode 100644 include/arm_ffa.h create mode 100644 include/arm_ffa_helper.h create mode 100644 lib/arm-ffa/Kconfig create mode 100644 lib/arm-ffa/Makefile create mode 100644 lib/arm-ffa/arm_ffa_helper.c diff --git a/MAINTAINERS b/MAINTAINERS index aca97cd2a3..efa17206b8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -232,6 +232,14 @@ F: board/CZ.NIC/ F: configs/turris_*_defconfig F: include/configs/turris_*.h +ARM FF-A +M: Abdellatif El Khlifi +S: Maintained +F: drivers/arm-ffa/ +F: include/arm_ffa.h +F: include/arm_ffa_helper.h +F: lib/arm-ffa/ + ARM FREESCALE IMX M: Stefano Babic M: Fabio Estevam diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S index dc92b28777..9a6aebf194 100644 --- a/arch/arm/cpu/armv8/smccc-call.S +++ b/arch/arm/cpu/armv8/smccc-call.S @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015, Linaro Limited + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi */ #include #include @@ -45,3 +47,28 @@ ENDPROC(__arm_smccc_smc) ENTRY(__arm_smccc_hvc) SMCCC hvc ENDPROC(__arm_smccc_hvc) + +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT)) + + .macro FFASMCCC instr + .cfi_startproc + \instr #0 + ldr x9, [sp] + stp x0, x1, [x9, #ARM_SMCCC_RES_X0_OFFS] + stp x2, x3, [x9, #ARM_SMCCC_RES_X2_OFFS] + stp x4, x5, [x9, #ARM_SMCCC_RES_X4_OFFS] + stp x6, x7, [x9, #ARM_SMCCC_RES_X6_OFFS] + ret + .cfi_endproc + .endm + +/* + * void 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) + */ +ENTRY(__arm_ffa_smccc_smc) + FFASMCCCsmc +ENDPROC(__arm_ffa_smccc_smc) + +#endif diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c index 22fd541f9a..02a4a42fe6 100644 --- a/arch/arm/lib/asm-offsets.c +++ b/arch/arm/lib/asm-offsets.c @@ -9,6 +9,8 @@ * generate asm statements containing #defines, * compile this file to assembler, and then extract the * #defines from the assembly-language output. + * + * (C) Copyright 2022 ARM Limited */ #include @@ -115,6 +117,10 @@ int main(void) #ifdef CONFIG_ARM_SMCCC DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT)) + DEFINE(ARM_SMCCC_RES_X4_OFFS, offsetof(struct arm_smccc_res, a4)); + DEFINE(ARM_SMCCC_RES_X6_OFFS, offsetof(struct arm_smccc_res, a6)); +#endif DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); #endif
[PATCH v2 2/6] arm_ffa: introduce armffa command
From: Abdellatif El Khlifi Provide armffa command showcasing the use of the FF-A driver The armffa command allows to query secure partitions data from the secure world and exchanging messages with the partitions. Signed-off-by: Abdellatif El Khlifi --- MAINTAINERS | 1 + cmd/Kconfig | 10 ++ cmd/Makefile| 2 + cmd/armffa.c| 266 drivers/arm-ffa/Kconfig | 1 + 5 files changed, 280 insertions(+) create mode 100644 cmd/armffa.c diff --git a/MAINTAINERS b/MAINTAINERS index efa17206b8..ca2e13b9ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -235,6 +235,7 @@ F: include/configs/turris_*.h ARM FF-A M: Abdellatif El Khlifi S: Maintained +F: cmd/armffa.c F: drivers/arm-ffa/ F: include/arm_ffa.h F: include/arm_ffa_helper.h diff --git a/cmd/Kconfig b/cmd/Kconfig index 516c6bbe2d..0d16e8cb14 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -823,6 +823,16 @@ endmenu menu "Device access commands" +config CMD_ARMFFA + bool "Arm FF-A test command" + depends on ARM_FFA_TRANSPORT + help + Provides a test command for the Arm FF-A driver + supported options: + - Listing the partition(s) info + - Sending a data pattern to the specified partition + - Displaying the arm_ffa device info + config CMD_ARMFLASH #depends on FLASH_CFI_DRIVER bool "armflash" diff --git a/cmd/Makefile b/cmd/Makefile index ede634d731..2905ce63cf 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -12,6 +12,8 @@ obj-y += panic.o obj-y += version.o # command + +obj-$(CONFIG_CMD_ARMFFA) += armffa.o obj-$(CONFIG_CMD_ACPI) += acpi.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_AES) += aes.o diff --git a/cmd/armffa.c b/cmd/armffa.c new file mode 100644 index 00..4b74bf5f31 --- /dev/null +++ b/cmd/armffa.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * do_ffa_get_singular_partition_info - implementation of the getpart subcommand + * @cmdtp: Command Table + * @flag: flags + * @argc: number of arguments + * @argv: arguments + * + * This function queries the secure partition information which the UUID is provided + * as an argument. The function uses the arm_ffa driver helper function + * to retrieve the data. + * The input UUID string is expected to be in big endian format. + * + * Return: + * + * CMD_RET_SUCCESS: on success, otherwise failure + */ +static int do_ffa_get_singular_partition_info(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct ffa_interface_data func_data = {0}; + u32 count = 0; + int ret; + union ffa_partition_uuid service_uuid = {0}; + struct ffa_partition_info *parts_info; + u32 info_idx; + + if (argc != 1) + return -EINVAL; + + if (ffa_uuid_str_to_bin(argv[0], (unsigned char *)&service_uuid)) { + ffa_err("Invalid UUID"); + return -EINVAL; + } + + /* +* get from the driver the count of the SPs matching the UUID +*/ + func_data.data0_size = sizeof(service_uuid); + func_data.data0 = &service_uuid; + func_data.data1_size = sizeof(count); + func_data.data1 = &count; + + ret = ffa_helper_get_partitions_info(&func_data); + if (ret != FFA_ERR_STAT_SUCCESS) { + ffa_err("Failure in querying partitions count (error code: %d)", ret); + return ret; + } + + if (!count) { + ffa_info("No secure partition found"); + return ret; + } + + /* +* pre-allocate a buffer to be filled by the driver +* with ffa_partition_info structs +*/ + + parts_info = calloc(count, sizeof(struct ffa_partition_info)); + if (!parts_info) + return -EINVAL; + + ffa_info("Pre-allocating %d partition(s) info structures", count); + + func_data.data1_size = count * sizeof(struct ffa_partition_info); + func_data.data1 = parts_info; + + /* +* ask the driver to fill the buffer with the SPs info +*/ + ret = ffa_helper_get_partitions_info(&func_data); + if (ret != FFA_ERR_STAT_SUCCESS) { + ffa_err("Failure in querying partition(s) info (error code: %d)", ret); + free(parts_info); + return ret; + } + + /* +* SPs found , show the partition information +*/ + for (info_idx = 0; info_idx < count ; info_idx++) { + ffa_info("Partition: id = 0x%x , exec_ctxt 0x%x , properties 0x%x", +parts_info[info_idx].id, +
[PATCH v2 3/6] arm_ffa: introduce the FF-A Sandbox driver
From: Abdellatif El Khlifi 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 --- 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 #include +#if CONFIG_IS_ENABLED(SANDBOX_FFA) +#include +#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_ENAB
[PATCH v2 4/6] arm_ffa: introduce Sandbox test cases for UCLASS_FFA
From: Abdellatif El Khlifi Add functional test cases for the FF-A core driver These tests rely on the FF-A Sandbox driver which helps in inspecting the FF-A core driver. Signed-off-by: Abdellatif El Khlifi --- MAINTAINERS | 2 + test/dm/Makefile | 1 + test/dm/ffa.c| 418 +++ test/dm/ffa.h| 22 +++ 4 files changed, 443 insertions(+) create mode 100644 test/dm/ffa.c create mode 100644 test/dm/ffa.h diff --git a/MAINTAINERS b/MAINTAINERS index 7c439ed1fd..74b7ed9388 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -242,6 +242,8 @@ F: include/arm_ffa_helper.h F: include/sandbox_arm_ffa.h F: include/sandbox_arm_ffa_helper.h F: lib/arm-ffa/ +F: test/dm/ffa.c +F: test/dm/ffa.h ARM FREESCALE IMX M: Stefano Babic diff --git a/test/dm/Makefile b/test/dm/Makefile index d46552fbf3..48eab1b1ff 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_POWER_DOMAIN) += power-domain.o obj-$(CONFIG_ACPI_PMC) += pmc.o obj-$(CONFIG_DM_PMIC) += pmic.o obj-$(CONFIG_DM_PWM) += pwm.o +obj-$(CONFIG_SANDBOX_FFA) += ffa.o obj-$(CONFIG_QFW) += qfw.o obj-$(CONFIG_RAM) += ram.o obj-y += regmap.o diff --git a/test/dm/ffa.c b/test/dm/ffa.c new file mode 100644 index 00..85b71bd808 --- /dev/null +++ b/test/dm/ffa.c @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Functional tests for UCLASS_FFA class + * + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include "ffa.h" +#include +#include +#include +#include + +/* Functional tests for the UCLASS_FFA */ + +static int dm_test_ffa_log(struct unit_test_state *uts, char *msg) +{ + char cmd[LOG_CMD_SZ] = {0}; + + console_record_reset(); + + snprintf(cmd, LOG_CMD_SZ, "echo \"%s\"", msg); + run_command(cmd, 0); + + ut_assert_console_end(); + + return CMD_RET_SUCCESS; +} + +static int check_fwk_version(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (prvdata->fwk_version != SANDBOX_FWK_VERSION) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: prvdata->fwk_version = 0x%x", __func__, +prvdata->fwk_version); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_endpoint_id(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (prvdata->id) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: prvdata->id = 0x%x", __func__, prvdata->id); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_dev(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (!prvdata->dev) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: device = 0x%p", __func__, prvdata->dev); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_rxtxbuf(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (!prvdata->pair.rxbuf && prvdata->pair.txbuf) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: rxbuf = 0x%llx txbuf = 0x%llx", __func__, +prvdata->pair.rxbuf, +prvdata->pair.txbuf); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_features(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + u32 desc_idx; + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, +LOG_MSG_SZ, +"[%s]: Error: FFA_RXTX_MAP features not found", +__func__); + + for (desc_idx = 0; desc_idx < FFA_FEATURE_DESC_CNT ; desc_idx++) + if (prvdata->features[desc_idx].func_id == FFA_RXTX_MAP) { + if (prvdata->features[desc_idx].field1 != RXTX_4K && + prvdata->features[desc_idx].field1 != RXTX_16K && + prvdata->features[desc_idx].field1 != RXTX_64K) { + snprintf(msg, +LOG_MSG_SZ, +"[%s]: Error: FFA_RXTX_MAP features = 0x%x", +__func__, +prvdata->features[desc_idx].field1); + break; + } + return CMD_RET_SUCCESS; + } + + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; +} + +static int check_rxbuf_mapped_flag(u32 queried_fu
[PATCH v2 5/6] arm_ffa: introduce armffa command Sandbox test
From: Abdellatif El Khlifi Add Sandbox test for the armffa command Signed-off-by: Abdellatif El Khlifi --- MAINTAINERS | 2 ++ test/cmd/Makefile | 1 + test/cmd/armffa.c | 33 + test/cmd/armffa.h | 13 + 4 files changed, 49 insertions(+) create mode 100644 test/cmd/armffa.c create mode 100644 test/cmd/armffa.h diff --git a/MAINTAINERS b/MAINTAINERS index 74b7ed9388..eb9c3886e6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -242,6 +242,8 @@ F: include/arm_ffa_helper.h F: include/sandbox_arm_ffa.h F: include/sandbox_arm_ffa_helper.h F: lib/arm-ffa/ +F: test/cmd/armffa.c +F: test/cmd/armffa.h F: test/dm/ffa.c F: test/dm/ffa.h diff --git a/test/cmd/Makefile b/test/cmd/Makefile index a59adb1e6d..d9dc0809d6 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PWM) += pwm.o obj-$(CONFIG_CMD_SETEXPR) += setexpr.o +obj-$(CONFIG_SANDBOX_FFA) += armffa.o diff --git a/test/cmd/armffa.c b/test/cmd/armffa.c new file mode 100644 index 00..fc41571cf0 --- /dev/null +++ b/test/cmd/armffa.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for armffa command + * + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#include "armffa.h" +#include +#include +#include +#include +#include + +/* Basic test of 'armffa' command */ +static int dm_test_armffa_cmd(struct unit_test_state *uts) +{ + ut_assertok(ffa_helper_bus_discover()); + + /* armffa getpart */ + ut_assertok(run_command("armffa getpart " SE_PROXY_PARTITION_UUID, 0)); + + /* armffa ping */ + ut_assertok(run_command("armffa ping " SE_PROXY_PARTITION_ID, 0)); + + /* armffa devlist */ + ut_assertok(run_command("armffa devlist", 0)); + + return CMD_RET_SUCCESS; +} + +DM_TEST(dm_test_armffa_cmd, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); diff --git a/test/cmd/armffa.h b/test/cmd/armffa.h new file mode 100644 index 00..630dc75e25 --- /dev/null +++ b/test/cmd/armffa.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#ifndef __TEST_CMD_FFA_H +#define __TEST_CMD_FFA_H + +#define SE_PROXY_PARTITION_ID "0x1245" +#define SE_PROXY_PARTITION_UUID "33d532ed-e699-0942-c09c-a798d9cd722d" + +#endif /*__TEST_CMD_FFA_H */ -- 2.17.1
[PATCH v2 6/6] arm_ffa: introduce FF-A MM communication
From: Abdellatif El Khlifi Add MM communication support using FF-A transport FF-A MM communication allows exchanging data with StandAlonneMM or smm-gateway secure partitions which run in OP-TEE. An MM shared buffer and a door bell event are used to exchange this data. The data is used by EFI services such as GetVariable()/SetVariable() and copied from the communication buffer to the MM shared buffer. The secure partition is notified about availability of data in the MM shared buffer by an FF-A message (door bell). On such event, MM SP can read the data and updates the MM shared buffer with the response data. The response data is copied back to the communication buffer and consumed by the EFI subsystem. Signed-off-by: Abdellatif El Khlifi Signed-off-by: Gowtham Suresh Kumar --- arch/arm/cpu/armv8/cache.S| 16 ++ arch/arm/cpu/armv8/cache_v8.c | 3 +- include/mm_communication.h| 4 +- lib/efi_loader/Kconfig| 14 +- lib/efi_loader/efi_variable_tee.c | 281 +- 5 files changed, 308 insertions(+), 10 deletions(-) diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S index d1cee23437..bdbe89e0c5 100644 --- a/arch/arm/cpu/armv8/cache.S +++ b/arch/arm/cpu/armv8/cache.S @@ -21,7 +21,11 @@ * x1: 0 clean & invalidate, 1 invalidate only * x2~x9: clobbered */ +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_dcache_level, "ax" +#endif ENTRY(__asm_dcache_level) lsl x12, x0, #1 msr csselr_el1, x12 /* select cache level */ @@ -65,7 +69,11 @@ ENDPROC(__asm_dcache_level) * * flush or invalidate all data cache by SET/WAY. */ +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_dcache_all, "ax" +#endif ENTRY(__asm_dcache_all) mov x1, x0 dsb sy @@ -109,7 +117,11 @@ ENTRY(__asm_flush_dcache_all) ENDPROC(__asm_flush_dcache_all) .popsection +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_invalidate_dcache_all, "ax" +#endif ENTRY(__asm_invalidate_dcache_all) mov x0, #0x1 b __asm_dcache_all @@ -182,7 +194,11 @@ ENTRY(__asm_invalidate_icache_all) ENDPROC(__asm_invalidate_icache_all) .popsection +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_invalidate_l3_dcache, "ax" +#endif WEAK(__asm_invalidate_l3_dcache) mov x0, #0 /* return status as success */ ret diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 3de18c7675..187a4497a7 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -425,7 +426,7 @@ __weak void mmu_setup(void) /* * Performs a invalidation of the entire data cache at all levels */ -void invalidate_dcache_all(void) +void __efi_runtime invalidate_dcache_all(void) { __asm_invalidate_dcache_all(); __asm_invalidate_l3_dcache(); diff --git a/include/mm_communication.h b/include/mm_communication.h index e65fbde60d..bb99190956 100644 --- a/include/mm_communication.h +++ b/include/mm_communication.h @@ -123,7 +123,7 @@ struct __packed efi_mm_communicate_header { * * Defined in EDK2 as SMM_VARIABLE_COMMUNICATE_HEADER. */ -struct smm_variable_communicate_header { +struct __packed smm_variable_communicate_header { efi_uintn_t function; efi_status_t ret_status; u8 data[]; @@ -145,7 +145,7 @@ struct smm_variable_communicate_header { * Defined in EDK2 as SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE. * */ -struct smm_variable_access { +struct __packed smm_variable_access { efi_guid_t guid; efi_uintn_t data_size; efi_uintn_t name_size; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 28657f50c9..0d69133595 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -55,13 +55,23 @@ config EFI_VARIABLE_FILE_STORE stored as file /ubootefi.var on the EFI system partition. config EFI_MM_COMM_TEE - bool "UEFI variables storage service via OP-TEE" - depends on OPTEE + bool "UEFI variables storage service via the trusted world" + depends on OPTEE || ARM_FFA_TRANSPORT help + The MM SP (also called partition) can be StandAlonneMM or smm-gateway. + When using the u-boot OP-TEE driver, StandAlonneMM is supported. + When using the u-boot FF-A driver, StandAlonneMM and smm-gateway are supported. + If OP-TEE is present and running StandAloneMM, dispatch all UEFI variable related operations to that. The application will verify, authenticate and store the variables on an RPMB. + When ARM_FFA_TRANSPORT is used, dispatch all UEFI variable related
[PATCH 0/6] introduce Arm FF-A support
From: Abdellatif El Khlifi This patchset adds support for Arm FF-A (Arm Firmware Framework for Armv8-A v1.0). FF-A support is generic by design and can be used by any Arm platform. The features added are as follows: 1/ FF-A device driver 2/ armffa command 3/ FF-A Sandbox driver 4/ FF-A Sandbox test cases 5/ FF-A MM communication The suggested design sees FF-A as a data bus allowing data exchange with the firmware running under TrustZone HW (such as Optee). The same approach was followed in the FF-A driver in Linux kernel (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/arm_ffa/bus.c?h=v5.15#n211)) u-boot boards using FF-A can provide a device tree node in a -u-boot.dtsi file. Since the node can not be hosted in Linux device tree, we suggest using u-boot device tree. As a use case, we will send a commit enabling FF-A for the Corstone-1000 platform and providing the FF-A node in u-boot.dtsi files. Corstone-1000: https://lore.kernel.org/u-boot/20220322104118.573537-1-rui.si...@linaro.org/ Cc: Tom Rini Abdellatif El Khlifi (6): arm_ffa: introduce Arm FF-A low-level driver arm_ffa: introduce armffa command arm_ffa: introduce the FF-A Sandbox driver arm_ffa: introduce Sandbox test cases for UCLASS_FFA arm_ffa: introduce armffa command Sandbox test arm_ffa: introduce FF-A MM communication MAINTAINERS | 15 + arch/arm/cpu/armv8/cache.S| 16 + arch/arm/cpu/armv8/cache_v8.c |3 +- arch/arm/cpu/armv8/smccc-call.S | 27 + arch/arm/lib/asm-offsets.c|6 + arch/sandbox/dts/sandbox.dtsi | 10 + arch/sandbox/dts/test.dts | 10 + cmd/Kconfig | 10 + cmd/Makefile |2 + cmd/armffa.c | 266 + common/board_r.c |7 + configs/sandbox64_defconfig |2 + configs/sandbox_defconfig |2 + doc/arch/sandbox.rst |1 + drivers/Kconfig |2 + drivers/Makefile |1 + drivers/arm-ffa/Kconfig | 32 + drivers/arm-ffa/Makefile |7 + drivers/arm-ffa/arm-ffa-uclass.c | 102 ++ drivers/arm-ffa/arm_ffa_prv.h | 200 drivers/arm-ffa/core.c| 1463 + drivers/arm-ffa/sandbox.c | 735 + drivers/arm-ffa/sandbox_arm_ffa_prv.h | 128 +++ include/arm_ffa.h | 197 include/arm_ffa_helper.h | 45 + include/dm/uclass-id.h|1 + include/linux/arm-smccc.h | 28 +- include/mm_communication.h|4 +- include/sandbox_arm_ffa.h | 31 + include/sandbox_arm_ffa_helper.h | 26 + lib/Kconfig |1 + lib/Makefile |1 + lib/arm-ffa/Kconfig |6 + lib/arm-ffa/Makefile |9 + lib/arm-ffa/arm_ffa_helper.c | 188 lib/arm-ffa/sandbox_arm_ffa_helper.c | 23 + lib/efi_loader/Kconfig| 14 +- lib/efi_loader/efi_boottime.c | 17 + lib/efi_loader/efi_variable_tee.c | 294 - test/cmd/Makefile |1 + test/cmd/armffa.c | 33 + test/cmd/armffa.h | 13 + test/dm/Makefile |1 + test/dm/ffa.c | 424 +++ test/dm/ffa.h | 22 + 45 files changed, 4415 insertions(+), 11 deletions(-) create mode 100644 cmd/armffa.c create mode 100644 drivers/arm-ffa/Kconfig create mode 100644 drivers/arm-ffa/Makefile create mode 100644 drivers/arm-ffa/arm-ffa-uclass.c create mode 100644 drivers/arm-ffa/arm_ffa_prv.h create mode 100644 drivers/arm-ffa/core.c create mode 100644 drivers/arm-ffa/sandbox.c create mode 100644 drivers/arm-ffa/sandbox_arm_ffa_prv.h create mode 100644 include/arm_ffa.h create mode 100644 include/arm_ffa_helper.h create mode 100644 include/sandbox_arm_ffa.h create mode 100644 include/sandbox_arm_ffa_helper.h create mode 100644 lib/arm-ffa/Kconfig create mode 100644 lib/arm-ffa/Makefile create mode 100644 lib/arm-ffa/arm_ffa_helper.c create mode 100644 lib/arm-ffa/sandbox_arm_ffa_helper.c create mode 100644 test/cmd/armffa.c create mode 100644 test/cmd/armffa.h create mode 100644 test/dm/ffa.c create mode 100644 test/dm/ffa.h -- 2.17.1
[PATCH 2/6] arm_ffa: introduce armffa command
From: Abdellatif El Khlifi Provide armffa command showcasing the use of the FF-A driver The armffa command allows to query secure partitions data from the secure world and exchanging messages with the partitions. Signed-off-by: Abdellatif El Khlifi Cc: Tom Rini --- MAINTAINERS | 1 + cmd/Kconfig | 10 ++ cmd/Makefile| 2 + cmd/armffa.c| 266 drivers/arm-ffa/Kconfig | 1 + 5 files changed, 280 insertions(+) create mode 100644 cmd/armffa.c diff --git a/MAINTAINERS b/MAINTAINERS index c5b608eb60..50ccd6a7ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -235,6 +235,7 @@ F: include/configs/turris_*.h ARM FF-A M: Abdellatif El Khlifi S: Maintained +F: cmd/armffa.c F: drivers/arm-ffa/ F: include/arm_ffa.h F: include/arm_ffa_helper.h diff --git a/cmd/Kconfig b/cmd/Kconfig index 79219bcb74..de5bea1404 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -813,6 +813,16 @@ endmenu menu "Device access commands" +config CMD_ARMFFA + bool "Arm FF-A test command" + depends on ARM_FFA_TRANSPORT + help + Provides a test command for the Arm FF-A driver + supported options: + - Listing the partition(s) info + - Sending a data pattern to the specified partition + - Displaying the arm_ffa device info + config CMD_ARMFLASH #depends on FLASH_CFI_DRIVER bool "armflash" diff --git a/cmd/Makefile b/cmd/Makefile index ede634d731..2905ce63cf 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -12,6 +12,8 @@ obj-y += panic.o obj-y += version.o # command + +obj-$(CONFIG_CMD_ARMFFA) += armffa.o obj-$(CONFIG_CMD_ACPI) += acpi.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_AES) += aes.o diff --git a/cmd/armffa.c b/cmd/armffa.c new file mode 100644 index 00..fcfc3a06bd --- /dev/null +++ b/cmd/armffa.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * do_ffa_get_singular_partition_info - implementation of the getpart subcommand + * @cmdtp: Command Table + * @flag: flags + * @argc: number of arguments + * @argv: arguments + * + * This function queries the secure partition information which the UUID is provided + * as an argument. The function uses the arm_ffa driver helper function + * to retrieve the data. + * The input UUID string is expected to be in big endian format. + * + * Return: + * + * CMD_RET_SUCCESS: on success, otherwise failure + */ +static int do_ffa_get_singular_partition_info(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct ffa_interface_data func_data = {0}; + u32 count = 0; + int ret; + union ffa_partition_uuid service_uuid = {0}; + struct ffa_partition_info *parts_info; + u32 info_idx; + + if (argc != 1) + return -EINVAL; + + if (ffa_uuid_str_to_bin(argv[0], (unsigned char *)&service_uuid)) { + ffa_err("Invalid UUID"); + return -EINVAL; + } + + /* +* get from the driver the count of the SPs matching the UUID +*/ + func_data.data0_size = sizeof(service_uuid); + func_data.data0 = &service_uuid; + func_data.data1_size = sizeof(count); + func_data.data1 = &count; + + ret = ffa_helper_get_partitions_info(&func_data); + if (ret != FFA_ERR_STAT_SUCCESS) { + ffa_err("Failure in querying partitions count (error code: %d)", ret); + return ret; + } + + if (!count) { + ffa_info("No secure partition found"); + return ret; + } + + /* +* pre-allocate a buffer to be filled by the driver +* with ffa_partition_info structs +*/ + + parts_info = calloc(count, sizeof(struct ffa_partition_info)); + if (!parts_info) + return -EINVAL; + + ffa_info("Pre-allocating %d partition(s) info structures", count); + + func_data.data1_size = count * sizeof(struct ffa_partition_info); + func_data.data1 = parts_info; + + /* +* ask the driver to fill the buffer with the SPs info +*/ + ret = ffa_helper_get_partitions_info(&func_data); + if (ret != FFA_ERR_STAT_SUCCESS) { + ffa_err("Failure in querying partition(s) info (error code: %d)", ret); + free(parts_info); + return ret; + } + + /* +* SPs found , show the partition information +*/ + for (info_idx = 0; info_idx < count ; info_idx++) { + ffa_info("Partition: id = 0x%x , exec_ctxt 0x%x , properties 0x%x", +parts_info[info_idx].id,
[PATCH 5/6] arm_ffa: introduce armffa command Sandbox test
From: Abdellatif El Khlifi Add Sandbox test for the armffa command Signed-off-by: Abdellatif El Khlifi Cc: Tom Rini --- MAINTAINERS | 2 ++ test/cmd/Makefile | 1 + test/cmd/armffa.c | 33 + test/cmd/armffa.h | 13 + 4 files changed, 49 insertions(+) create mode 100644 test/cmd/armffa.c create mode 100644 test/cmd/armffa.h diff --git a/MAINTAINERS b/MAINTAINERS index 52274b2fac..9828095837 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -242,6 +242,8 @@ F: include/arm_ffa_helper.h F: include/sandbox_arm_ffa.h F: include/sandbox_arm_ffa_helper.h F: lib/arm-ffa/ +F: test/cmd/armffa.c +F: test/cmd/armffa.h F: test/dm/ffa.c F: test/dm/ffa.h diff --git a/test/cmd/Makefile b/test/cmd/Makefile index a59adb1e6d..d9dc0809d6 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PWM) += pwm.o obj-$(CONFIG_CMD_SETEXPR) += setexpr.o +obj-$(CONFIG_SANDBOX_FFA) += armffa.o diff --git a/test/cmd/armffa.c b/test/cmd/armffa.c new file mode 100644 index 00..d35032047b --- /dev/null +++ b/test/cmd/armffa.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for armffa command + * + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#include "armffa.h" +#include +#include +#include +#include +#include + +/* Basic test of 'armffa' command */ +static int dm_test_armffa_cmd(struct unit_test_state *uts) +{ + ut_assertok(ffa_helper_init_device()); + + /* armffa getpart */ + ut_assertok(run_command("armffa getpart " SE_PROXY_PARTITION_UUID, 0)); + + /* armffa ping */ + ut_assertok(run_command("armffa ping " SE_PROXY_PARTITION_ID, 0)); + + /* armffa devlist */ + ut_assertok(run_command("armffa devlist", 0)); + + return CMD_RET_SUCCESS; +} + +DM_TEST(dm_test_armffa_cmd, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); diff --git a/test/cmd/armffa.h b/test/cmd/armffa.h new file mode 100644 index 00..630dc75e25 --- /dev/null +++ b/test/cmd/armffa.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#ifndef __TEST_CMD_FFA_H +#define __TEST_CMD_FFA_H + +#define SE_PROXY_PARTITION_ID "0x1245" +#define SE_PROXY_PARTITION_UUID "33d532ed-e699-0942-c09c-a798d9cd722d" + +#endif /*__TEST_CMD_FFA_H */ -- 2.17.1
[PATCH 4/6] arm_ffa: introduce Sandbox test cases for UCLASS_FFA
From: Abdellatif El Khlifi Add functional test cases for the FF-A core driver These tests rely on the FF-A Sandbox driver which helps in inspecting the FF-A core driver. Signed-off-by: Abdellatif El Khlifi Cc: Tom Rini --- MAINTAINERS | 2 + test/dm/Makefile | 1 + test/dm/ffa.c| 424 +++ test/dm/ffa.h| 22 +++ 4 files changed, 449 insertions(+) create mode 100644 test/dm/ffa.c create mode 100644 test/dm/ffa.h diff --git a/MAINTAINERS b/MAINTAINERS index 84524d7caf..52274b2fac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -242,6 +242,8 @@ F: include/arm_ffa_helper.h F: include/sandbox_arm_ffa.h F: include/sandbox_arm_ffa_helper.h F: lib/arm-ffa/ +F: test/dm/ffa.c +F: test/dm/ffa.h ARM FREESCALE IMX M: Stefano Babic diff --git a/test/dm/Makefile b/test/dm/Makefile index d46552fbf3..48eab1b1ff 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_POWER_DOMAIN) += power-domain.o obj-$(CONFIG_ACPI_PMC) += pmc.o obj-$(CONFIG_DM_PMIC) += pmic.o obj-$(CONFIG_DM_PWM) += pwm.o +obj-$(CONFIG_SANDBOX_FFA) += ffa.o obj-$(CONFIG_QFW) += qfw.o obj-$(CONFIG_RAM) += ram.o obj-y += regmap.o diff --git a/test/dm/ffa.c b/test/dm/ffa.c new file mode 100644 index 00..82875705c6 --- /dev/null +++ b/test/dm/ffa.c @@ -0,0 +1,424 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Functional tests for UCLASS_FFA class + * + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include "ffa.h" +#include +#include +#include +#include + +/* Functional tests for the UCLASS_FFA */ + +int dm_test_ffa_log(struct unit_test_state *uts, char *msg) +{ + char cmd[LOG_CMD_SZ] = {0}; + + console_record_reset(); + + snprintf(cmd, LOG_CMD_SZ, "echo \"%s\"", msg); + run_command(cmd, 0); + + ut_assert_console_end(); + + return CMD_RET_SUCCESS; +} + +static int check_fwk_version(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (prvdata->fwk_version != SANDBOX_FWK_VERSION) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: prvdata->fwk_version = 0x%x", __func__, +prvdata->fwk_version); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_endpoint_id(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (prvdata->id) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: prvdata->id = 0x%x", __func__, prvdata->id); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_dev(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (!prvdata->dev) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: device = 0x%p", __func__, prvdata->dev); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_prvdata_null(struct ffa_prvdata *prvdata) +{ + u32 idx; + u8 *byte = (u8 *)prvdata; + + for (idx = 0 ; idx < sizeof(struct ffa_prvdata) ; idx++) + if (*(byte++)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static int check_rxtxbuf(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + if (!prvdata->pair.rxbuf && prvdata->pair.txbuf) { + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, LOG_MSG_SZ, "[%s]: Error: rxbuf = 0x%llx txbuf = 0x%llx", __func__, +prvdata->pair.rxbuf, +prvdata->pair.txbuf); + dm_test_ffa_log(uts, msg); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; +} + +static int check_features(struct ffa_prvdata *prvdata, struct unit_test_state *uts) +{ + u32 desc_idx; + char msg[LOG_MSG_SZ] = {0}; + + snprintf(msg, +LOG_MSG_SZ, +"[%s]: Error: FFA_RXTX_MAP features not found", +__func__); + + for (desc_idx = 0; desc_idx < FFA_FEATURE_DESC_CNT ; desc_idx++) + if (prvdata->features[desc_idx].func_id == FFA_RXTX_MAP) { + if (prvdata->features[desc_idx].field1 != RXTX_4K && + prvdata->features[desc_idx].field1 != RXTX_16K && + prvdata->features[desc_idx].field1 != RXTX_64K) { + snprintf(msg, +LOG_MSG_SZ, +"[%s]: Error: FFA_RXTX_MAP features = 0x%x", +__func__, +
[PATCH 1/6] arm_ffa: introduce Arm FF-A low-level driver
From: Abdellatif El Khlifi Add the driver implementing Arm Firmware Framework for Armv8-A v1.0 The Firmware Framework for Arm A-profile processors (FF-A) describes interfaces (ABIs) that standardize communication between the Secure World and Normal World leveraging TrustZone technology. This driver uses SMC32 calling convention. The driver provides helper FF-A interfaces for user layers. These helper functions allow clients to pass data and select the FF-A function to use for the communication with secure world. Signed-off-by: Abdellatif El Khlifi Cc: Tom Rini --- MAINTAINERS |8 + arch/arm/cpu/armv8/smccc-call.S | 27 + arch/arm/lib/asm-offsets.c |6 + common/board_r.c |7 + drivers/Kconfig |2 + drivers/Makefile |1 + drivers/arm-ffa/Kconfig | 25 + drivers/arm-ffa/Makefile |6 + drivers/arm-ffa/arm-ffa-uclass.c | 65 ++ drivers/arm-ffa/arm_ffa_prv.h| 200 + drivers/arm-ffa/core.c | 1427 ++ include/arm_ffa.h| 190 include/arm_ffa_helper.h | 45 + include/dm/uclass-id.h |1 + include/linux/arm-smccc.h| 28 +- lib/Kconfig |1 + lib/Makefile |1 + lib/arm-ffa/Kconfig |6 + lib/arm-ffa/Makefile |8 + lib/arm-ffa/arm_ffa_helper.c | 188 lib/efi_loader/efi_boottime.c| 17 + 21 files changed, 2258 insertions(+), 1 deletion(-) create mode 100644 drivers/arm-ffa/Kconfig create mode 100644 drivers/arm-ffa/Makefile create mode 100644 drivers/arm-ffa/arm-ffa-uclass.c create mode 100644 drivers/arm-ffa/arm_ffa_prv.h create mode 100644 drivers/arm-ffa/core.c create mode 100644 include/arm_ffa.h create mode 100644 include/arm_ffa_helper.h create mode 100644 lib/arm-ffa/Kconfig create mode 100644 lib/arm-ffa/Makefile create mode 100644 lib/arm-ffa/arm_ffa_helper.c diff --git a/MAINTAINERS b/MAINTAINERS index 74d5263fb1..c5b608eb60 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -232,6 +232,14 @@ F: board/CZ.NIC/ F: configs/turris_*_defconfig F: include/configs/turris_*.h +ARM FF-A +M: Abdellatif El Khlifi +S: Maintained +F: drivers/arm-ffa/ +F: include/arm_ffa.h +F: include/arm_ffa_helper.h +F: lib/arm-ffa/ + ARM FREESCALE IMX M: Stefano Babic M: Fabio Estevam diff --git a/arch/arm/cpu/armv8/smccc-call.S b/arch/arm/cpu/armv8/smccc-call.S index dc92b28777..9a6aebf194 100644 --- a/arch/arm/cpu/armv8/smccc-call.S +++ b/arch/arm/cpu/armv8/smccc-call.S @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015, Linaro Limited + * (C) Copyright 2022 ARM Limited + * Abdellatif El Khlifi */ #include #include @@ -45,3 +47,28 @@ ENDPROC(__arm_smccc_smc) ENTRY(__arm_smccc_hvc) SMCCC hvc ENDPROC(__arm_smccc_hvc) + +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT)) + + .macro FFASMCCC instr + .cfi_startproc + \instr #0 + ldr x9, [sp] + stp x0, x1, [x9, #ARM_SMCCC_RES_X0_OFFS] + stp x2, x3, [x9, #ARM_SMCCC_RES_X2_OFFS] + stp x4, x5, [x9, #ARM_SMCCC_RES_X4_OFFS] + stp x6, x7, [x9, #ARM_SMCCC_RES_X6_OFFS] + ret + .cfi_endproc + .endm + +/* + * void 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) + */ +ENTRY(__arm_ffa_smccc_smc) + FFASMCCCsmc +ENDPROC(__arm_ffa_smccc_smc) + +#endif diff --git a/arch/arm/lib/asm-offsets.c b/arch/arm/lib/asm-offsets.c index 22fd541f9a..02a4a42fe6 100644 --- a/arch/arm/lib/asm-offsets.c +++ b/arch/arm/lib/asm-offsets.c @@ -9,6 +9,8 @@ * generate asm statements containing #defines, * compile this file to assembler, and then extract the * #defines from the assembly-language output. + * + * (C) Copyright 2022 ARM Limited */ #include @@ -115,6 +117,10 @@ int main(void) #ifdef CONFIG_ARM_SMCCC DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); +#if (IS_ENABLED(CONFIG_ARM_FFA_TRANSPORT)) + DEFINE(ARM_SMCCC_RES_X4_OFFS, offsetof(struct arm_smccc_res, a4)); + DEFINE(ARM_SMCCC_RES_X6_OFFS, offsetof(struct arm_smccc_res, a6)); +#endif DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); #endif diff --git a/common/board_r.c b/common/board_r.c index b92c1bb0be..7866ec3ad5 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -62,6 +62,10 @@ #include #include +#ifdef CONFIG_ARM_FFA_TRANSPORT +#include +#endif + DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; @@ -771,6 +775,9 @@
[PATCH 6/6] arm_ffa: introduce FF-A MM communication
From: Abdellatif El Khlifi Add MM communication support using FF-A transport FF-A MM communication allows exchanging data with StandAlonneMM or smm-gateway secure partitions which run in OP-TEE. An MM shared buffer and a door bell event are used to exchange this data. The data is used by EFI services such as GetVariable()/SetVariable() and copied from the communication buffer to the MM shared buffer. The secure partition is notified about availability of data in the MM shared buffer by an FF-A message (door bell). On such event, MM SP can read the data and updates the MM shared buffer with the response data. The response data is copied back to the communication buffer and consumed by the EFI subsystem. Signed-off-by: Abdellatif El Khlifi Signed-off-by: Gowtham Suresh Kumar Cc: Tom Rini --- arch/arm/cpu/armv8/cache.S| 16 ++ arch/arm/cpu/armv8/cache_v8.c | 3 +- include/mm_communication.h| 4 +- lib/efi_loader/Kconfig| 14 +- lib/efi_loader/efi_variable_tee.c | 294 +- 5 files changed, 321 insertions(+), 10 deletions(-) diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S index d1cee23437..bdbe89e0c5 100644 --- a/arch/arm/cpu/armv8/cache.S +++ b/arch/arm/cpu/armv8/cache.S @@ -21,7 +21,11 @@ * x1: 0 clean & invalidate, 1 invalidate only * x2~x9: clobbered */ +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_dcache_level, "ax" +#endif ENTRY(__asm_dcache_level) lsl x12, x0, #1 msr csselr_el1, x12 /* select cache level */ @@ -65,7 +69,11 @@ ENDPROC(__asm_dcache_level) * * flush or invalidate all data cache by SET/WAY. */ +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_dcache_all, "ax" +#endif ENTRY(__asm_dcache_all) mov x1, x0 dsb sy @@ -109,7 +117,11 @@ ENTRY(__asm_flush_dcache_all) ENDPROC(__asm_flush_dcache_all) .popsection +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_invalidate_dcache_all, "ax" +#endif ENTRY(__asm_invalidate_dcache_all) mov x0, #0x1 b __asm_dcache_all @@ -182,7 +194,11 @@ ENTRY(__asm_invalidate_icache_all) ENDPROC(__asm_invalidate_icache_all) .popsection +#ifdef CONFIG_ARM_FFA_TRANSPORT +.pushsection .text.efi_runtime, "ax" +#else .pushsection .text.__asm_invalidate_l3_dcache, "ax" +#endif WEAK(__asm_invalidate_l3_dcache) mov x0, #0 /* return status as success */ ret diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 3de18c7675..187a4497a7 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -425,7 +426,7 @@ __weak void mmu_setup(void) /* * Performs a invalidation of the entire data cache at all levels */ -void invalidate_dcache_all(void) +void __efi_runtime invalidate_dcache_all(void) { __asm_invalidate_dcache_all(); __asm_invalidate_l3_dcache(); diff --git a/include/mm_communication.h b/include/mm_communication.h index e65fbde60d..bb99190956 100644 --- a/include/mm_communication.h +++ b/include/mm_communication.h @@ -123,7 +123,7 @@ struct __packed efi_mm_communicate_header { * * Defined in EDK2 as SMM_VARIABLE_COMMUNICATE_HEADER. */ -struct smm_variable_communicate_header { +struct __packed smm_variable_communicate_header { efi_uintn_t function; efi_status_t ret_status; u8 data[]; @@ -145,7 +145,7 @@ struct smm_variable_communicate_header { * Defined in EDK2 as SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE. * */ -struct smm_variable_access { +struct __packed smm_variable_access { efi_guid_t guid; efi_uintn_t data_size; efi_uintn_t name_size; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 28657f50c9..0d69133595 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -55,13 +55,23 @@ config EFI_VARIABLE_FILE_STORE stored as file /ubootefi.var on the EFI system partition. config EFI_MM_COMM_TEE - bool "UEFI variables storage service via OP-TEE" - depends on OPTEE + bool "UEFI variables storage service via the trusted world" + depends on OPTEE || ARM_FFA_TRANSPORT help + The MM SP (also called partition) can be StandAlonneMM or smm-gateway. + When using the u-boot OP-TEE driver, StandAlonneMM is supported. + When using the u-boot FF-A driver, StandAlonneMM and smm-gateway are supported. + If OP-TEE is present and running StandAloneMM, dispatch all UEFI variable related operations to that. The application will verify, authenticate and store the variables on an RPMB. + When ARM_FFA_TRANSPORT is used, dispatch all UEFI va
[PATCH 3/6] arm_ffa: introduce the FF-A Sandbox driver
From: Abdellatif El Khlifi 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 Cc: Tom Rini --- MAINTAINERS | 2 + arch/sandbox/dts/sandbox.dtsi | 10 + arch/sandbox/dts/test.dts | 10 + 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 | 51 +- drivers/arm-ffa/core.c| 94 +++- drivers/arm-ffa/sandbox.c | 735 ++ drivers/arm-ffa/sandbox_arm_ffa_prv.h | 128 + 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 | 6 +- lib/arm-ffa/sandbox_arm_ffa_helper.c | 23 + lib/efi_loader/efi_boottime.c | 4 +- 20 files changed, 1102 insertions(+), 44 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 50ccd6a7ba..84524d7caf 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/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 66b813faad..523ffcc27d 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -416,6 +416,16 @@ sandbox_tee { compatible = "sandbox,tee"; }; + + arm_ffa { + compatible = "arm,ffa"; + method = "smc"; + }; + + sandbox_arm_ffa { + compatible = "sandbox,ffa"; + method = "smc"; + }; }; &cros_ec { diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 3d206fdb3c..2c638af042 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1598,6 +1598,16 @@ compatible = "sandbox,regmap_test"; }; }; + + arm_ffa { + compatible = "arm,ffa"; + method = "smc"; + }; + + sandbox_arm_ffa { + compatible = "sandbox,ffa"; + method = "smc"; + }; }; #include "sandbox_pmic.dtsi" diff --git a/common/board_r.c b/common/board_r.c index 7866ec3ad5..3b82f74bb0 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_init_device, #endif #ifdef CONFIG_POST diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 40d1422a37..301c6f320f 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 0f43101ab5..a2f273056f 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -324,3 +324,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 7b7cfe26b1..61103daa42 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 @@ -24,3 +24,9 @@ config ARM_FFA_TRANSPORT entity to communicate with. FF-A commu
[PATCH 3/8] arm_ffa: Add FFA_MEM_RECLAIM support
From: Abdellatif El Khlifi Add to the FF-A bus FFA_MEM_RECLAIM ABI The FFA_MEM_RECLAIM is a memory management ABI described in the FF-A v1.0 specification [1]. This ABI restores exclusive access to a memory region back to its Owner. This work is based on the implementation in Linux [2]. [1]: https://developer.arm.com/documentation/den0077/a/?lang=en [2]: commit cc2195fe536c28e192df5d07e6dd277af36814b4 File: drivers/firmware/arm_ffa/driver.c Signed-off-by: Abdellatif El Khlifi --- doc/arch/arm64.ffa.rst| 2 + drivers/firmware/arm-ffa/arm-ffa-uclass.c | 70 +++ drivers/firmware/arm-ffa/arm-ffa.c| 1 + include/arm_ffa.h | 25 +++- include/arm_ffa_priv.h| 3 +- 5 files changed, 99 insertions(+), 2 deletions(-) diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst index 3eec735d741..d2c4fb49f79 100644 --- a/doc/arch/arm64.ffa.rst +++ b/doc/arch/arm64.ffa.rst @@ -186,6 +186,7 @@ The following features are provided: - FFA_MSG_SEND_DIRECT_REQ - FFA_MSG_SEND_DIRECT_RESP - FFA_MEM_SHARE +- FFA_MEM_RECLAIM - Support for the 64-bit version of the following ABIs: @@ -205,6 +206,7 @@ The following features are provided: - ffa_sync_send_receive - ffa_rxtx_unmap - ffa_memory_share +- ffa_memory_reclaim - FF-A bus discovery makes sure FF-A framework is responsive and compatible with the driver diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c index 8ff666c3757..5eae28386ae 100644 --- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c +++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c @@ -109,6 +109,18 @@ static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = { "DENIED: Memory region ownership, permission, access or attributes error", }, }, + [FFA_ID_TO_ERRMAP_ID(FFA_MEM_RECLAIM)] = { + { + [ABORTED] = + "ABORTED: ABI invocation failure", + [INVALID_PARAMETERS] = + "INVALID_PARAMETERS: Invalid handle or flags", + [NO_MEMORY] = + "NO_MEMORY: Failure to create the Owner's mapping", + [DENIED] = + "DENIED: Memory region state issue", + }, + }, }; /** @@ -1115,6 +1127,41 @@ int ffa_memory_share_hdlr(struct udevice *dev, struct ffa_mem_ops_args *args) return ffa_memory_ops(dev, FFA_MEM_SHARE, args); } +/** + * ffa_memory_reclaim_hdlr() - FFA_MEM_RECLAIM handler function + * @dev: The FF-A bus device + * @g_handle: The memory region globally unique Handle + * @flags: Zero memory and time slicing flags + * + * Implement FFA_MEM_RECLAIM FF-A function + * to restore exclusive access to a memory region back to its Owner. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +int ffa_memory_reclaim_hdlr(struct udevice *dev, u64 g_handle, u32 flags) +{ + ffa_value_t res; + int ffa_errno; + + invoke_ffa_fn((ffa_value_t){ + .a0 = FFA_SMC_32(FFA_MEM_RECLAIM), + .a1 = HANDLE_LOW(g_handle), .a2 = HANDLE_HIGH(g_handle), + .a3 = flags, + }, + &res + ); + + if (res.a0 != FFA_SMC_32(FFA_SUCCESS)) { + ffa_errno = res.a2; + ffa_print_error_log(FFA_MEM_RECLAIM, ffa_errno); + return ffa_to_std_errno(ffa_errno); + } + + return 0; +} + /* FF-A driver operations (used by clients for communicating with FF-A)*/ /** @@ -1214,6 +1261,29 @@ int ffa_memory_share(struct udevice *dev, struct ffa_mem_ops_args *args) return ops->memory_share(dev, args); } +/** + * ffa_memory_reclaim() - FFA_MEM_RECLAIM driver operation + * @dev: The FF-A bus device + * @g_handle: The memory region globally unique Handle + * @flags: Zero memory and time slicing flags + * + * Driver operation for FFA_MEM_RECLAIM. + * Please see ffa_memory_reclaim_hdlr() description for more details. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +int ffa_memory_reclaim(struct udevice *dev, u64 g_handle, u32 flags) +{ + struct ffa_bus_ops *ops = ffa_get_ops(dev); + + if (!ops || !ops->memory_reclaim) + return -ENOSYS; + + return ops->memory_reclaim(dev, g_handle, flags); +} + /** * ffa_do_probe() - probing FF-A framework * @dev: the FF-A bus device (arm_ffa) diff --git a/drivers/firmware/arm-ffa/arm-ffa.c b/drivers/firmware/arm-ffa/arm-ffa.c index c4211c953ef..b7e751e3821 100644 --- a/drivers/firmware/arm-ffa/arm-ffa.c +++ b/drivers/firmware/arm-ffa/arm-ffa.c @@ -85,6 +85,7 @@ static const struct ffa_bus_ops ffa_ops = { .sync_send_receive = ffa_msg_send_direct_req_hdlr, .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, .
[PATCH 6/8] arm_ffa: sandbox: Add FFA_MEM_SHARE tests
From: Abdellatif El Khlifi Add positive and negative test cases Signed-off-by: Abdellatif El Khlifi --- test/dm/ffa.c | 46 +- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/test/dm/ffa.c b/test/dm/ffa.c index 593b7177fce..4fd21ac3d72 100644 --- a/test/dm/ffa.c +++ b/test/dm/ffa.c @@ -2,7 +2,7 @@ /* * Functional tests for UCLASS_FFA class * - * Copyright 2022-2023 Arm Limited and/or its affiliates + * Copyright 2022-2024 Arm Limited and/or its affiliates * * Authors: * Abdellatif El Khlifi @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -141,6 +142,43 @@ static int test_partitions_and_comms(const char *service_uuid, return 0; } +static int test_ffa_memory_share(bool test_ack, struct unit_test_state *uts) +{ + struct ffa_mem_ops_args args = {0}; + struct ffa_mem_region_attributes attrs = {0}; + static u8 buf[SZ_4K]; + int ret; + struct udevice *dev; + + ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev)); + + args.attrs = &attrs; + args.nattrs = 1; + args.address = buf; + args.pg_cnt = 1; + + if (test_ack) { + args.use_txbuf = true; + + ut_assertok(ffa_memory_share(dev, &args)); + ut_asserteq(HANDLE_LOW(args.g_handle), SANDBOX_MEM_HANDLE); + ut_asserteq(HANDLE_HIGH(args.g_handle), SANDBOX_MEM_HANDLE); + } else { + /* Do not use the TX buffer as a transaction buffer */ + args.use_txbuf = false; + ret = ffa_memory_share(dev, &args); + ut_asserteq(-EPROTONOSUPPORT, ret); + + /* No memory region address given */ + args.use_txbuf = true; + args.address = NULL; + ret = ffa_memory_share(dev, &args); + ut_asserteq(-EINVAL, ret); + } + + return 0; +} + static int dm_test_ffa_ack(struct unit_test_state *uts) { struct ffa_priv *uc_priv; @@ -195,6 +233,9 @@ static int dm_test_ffa_ack(struct unit_test_state *uts) ut_assertok(sandbox_query_ffa_emul_state(FFA_RX_RELEASE, &func_data)); check_rxbuf_release_flag(rxbuf_flag, uts); + /* Test FFA_MEM_SHARE */ + test_ffa_memory_share(true, uts); + return 0; } DM_TEST(dm_test_ffa_ack, UTF_SCAN_FDT | UTF_CONSOLE); @@ -253,6 +294,9 @@ static int dm_test_ffa_nack(struct unit_test_state *uts) part_id = uc_priv->partitions.descs[0].info.id; ut_assertok(ffa_sync_send_receive(dev, part_id, &msg, 1)); + /* Test FFA_MEM_SHARE */ + test_ffa_memory_share(false, uts); + return 0; } DM_TEST(dm_test_ffa_nack, UTF_SCAN_FDT | UTF_CONSOLE); -- 2.25.1
[PATCH 8/8] arm_ffa: sandbox: Add FFA_MEM_RECLAIM tests
From: Abdellatif El Khlifi Add FFA_MEM_RECLAIM positive and negative test cases Signed-off-by: Abdellatif El Khlifi --- test/dm/ffa.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/test/dm/ffa.c b/test/dm/ffa.c index 4fd21ac3d72..c481964c758 100644 --- a/test/dm/ffa.c +++ b/test/dm/ffa.c @@ -179,6 +179,27 @@ static int test_ffa_memory_share(bool test_ack, struct unit_test_state *uts) return 0; } +static int test_ffa_memory_reclaim(bool test_ack, struct unit_test_state *uts) +{ + int ret; + u64 g_handle; + struct udevice *dev; + + ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev)); + + if (test_ack) { + g_handle = PACK_HANDLE(SANDBOX_MEM_HANDLE, SANDBOX_MEM_HANDLE); + ut_assertok(ffa_memory_reclaim(dev, g_handle, 0)); + } else { + /* Provide a wrong handle */ + g_handle = PACK_HANDLE(SANDBOX_MEM_HANDLE, 0); + ret = ffa_memory_reclaim(dev, g_handle, 0); + ut_asserteq(-EINVAL, ret); + } + + return 0; +} + static int dm_test_ffa_ack(struct unit_test_state *uts) { struct ffa_priv *uc_priv; @@ -236,6 +257,9 @@ static int dm_test_ffa_ack(struct unit_test_state *uts) /* Test FFA_MEM_SHARE */ test_ffa_memory_share(true, uts); + /* Test FFA_MEM_RECLAIM */ + test_ffa_memory_reclaim(true, uts); + return 0; } DM_TEST(dm_test_ffa_ack, UTF_SCAN_FDT | UTF_CONSOLE); @@ -297,6 +321,9 @@ static int dm_test_ffa_nack(struct unit_test_state *uts) /* Test FFA_MEM_SHARE */ test_ffa_memory_share(false, uts); + /* Test FFA_MEM_RECLAIM */ + test_ffa_memory_reclaim(false, uts); + return 0; } DM_TEST(dm_test_ffa_nack, UTF_SCAN_FDT | UTF_CONSOLE); -- 2.25.1
[PATCH 5/8] arm_ffa: sandbox: Add FFA_MEM_SHARE emulation
From: Abdellatif El Khlifi Add FFA_MEM_SHARE support to the FF-A emulator Signed-off-by: Abdellatif El Khlifi --- .../include/asm/sandbox_arm_ffa_priv.h| 5 ++- drivers/firmware/arm-ffa/ffa-emul-uclass.c| 44 +++ drivers/firmware/arm-ffa/sandbox_ffa.c| 3 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h b/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h index b0881822d78..8d04efc32d6 100644 --- a/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h +++ b/arch/sandbox/include/asm/sandbox_arm_ffa_priv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright 2022-2023 Arm Limited and/or its affiliates + * Copyright 2022-2024 Arm Limited and/or its affiliates * * Authors: * Abdellatif El Khlifi @@ -70,6 +70,9 @@ #define SANDBOX_SERVICE2_UUID_A3 0x9cc02d72 #define SANDBOX_SERVICE2_UUID_A4 0xcdd998a7 +/* Globally unique Handle to identify the shared memory region */ +#define SANDBOX_MEM_HANDLE 0x + /** * struct ffa_rxtxpair_info - structure hosting the RX/TX buffers flags * @rxbuf_owned: RX buffer ownership flag (the owner is non secure world) diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c index 3e8b5288d3b..a859d2e26cc 100644 --- a/drivers/firmware/arm-ffa/ffa-emul-uclass.c +++ b/drivers/firmware/arm-ffa/ffa-emul-uclass.c @@ -563,6 +563,47 @@ static int sandbox_ffa_get_parts(struct udevice *emul, struct ffa_sandbox_data * return 0; } +/** + * sandbox_ffa_memory_share() - Emulated FFA_MEM_SHARE handler + * @emul: The sandbox FF-A emulator device + * @pargs: The SMC call input arguments a0-a7 + * @res: The SMC return data + * + * Emulate FFA_MEM_SHARE FF-A function. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +static int sandbox_ffa_memory_share(struct udevice *emul, ffa_value_t *pargs, + ffa_value_t *res) +{ + int ret; + + res->a0 = FFA_SMC_32(FFA_ERROR); + res->a3 = 0; + + if (!pargs->a1 || (pargs->a1 > (RXTX_BUFFERS_MIN_PAGES * SZ_4K))) { + res->a2 = -INVALID_PARAMETERS; + ret = ffa_to_std_errmap[INVALID_PARAMETERS]; + goto feedback; + } + + res->a0 = FFA_SMC_32(FFA_SUCCESS); + res->a2 = SANDBOX_MEM_HANDLE; + res->a3 = SANDBOX_MEM_HANDLE; + ret = 0; + +feedback: + + res->a1 = 0; + + /* x4-x7 MBZ */ + memset(FFA_X4X7_MBZ_REG_START, 0, FFA_X4X7_MBZ_CNT * sizeof(ulong)); + + return ret; +} + /** * sandbox_query_ffa_emul_state() - Inspect the FF-A ABIs * @queried_func_id: The FF-A function to be queried @@ -653,6 +694,9 @@ void sandbox_arm_ffa_smccc_smc(ffa_value_t *args, ffa_value_t *res) case FFA_SMC_32(FFA_RX_RELEASE): ret = sandbox_ffa_rx_release(emul, args, res); break; + case FFA_SMC_32(FFA_MEM_SHARE): + ret = sandbox_ffa_memory_share(emul, args, res); + break; default: log_err("Undefined FF-A interface (%lx)\n", args->a0); diff --git a/drivers/firmware/arm-ffa/sandbox_ffa.c b/drivers/firmware/arm-ffa/sandbox_ffa.c index 44b32a829dd..a81455ce5ff 100644 --- a/drivers/firmware/arm-ffa/sandbox_ffa.c +++ b/drivers/firmware/arm-ffa/sandbox_ffa.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2022-2023 Arm Limited and/or its affiliates + * Copyright 2022-2024 Arm Limited and/or its affiliates * * Authors: * Abdellatif El Khlifi @@ -91,6 +91,7 @@ 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, + .memory_share = ffa_memory_share_hdlr, }; static const struct udevice_id sandbox_ffa_id[] = { -- 2.25.1
[PATCH 2/8] arm_ffa: Add FFA_MEM_SHARE support
From: Abdellatif El Khlifi Add to the FF-A bus FFA_MEM_SHARE ABI The FFA_MEM_SHARE is a memory management ABI described in the FF-A v1.0 specification [1]. This ABI starts a transaction to grant access to a memory region to one or more Borrowers (aka Secure Partitions or endpoints). This work is based on the implementation in Linux kernel [2]. [1]: https://developer.arm.com/documentation/den0077/a/?lang=en [2]: commit cc2195fe536c28e192df5d07e6dd277af36814b4 Files: drivers/firmware/arm_ffa/driver.c , include/linux/arm_ffa.h Signed-off-by: Abdellatif El Khlifi --- doc/arch/arm64.ffa.rst| 2 + drivers/firmware/arm-ffa/arm-ffa-uclass.c | 208 ++ drivers/firmware/arm-ffa/arm-ffa.c| 3 +- include/arm_ffa.h | 86 - include/arm_ffa_priv.h| 142 ++- 5 files changed, 437 insertions(+), 4 deletions(-) diff --git a/doc/arch/arm64.ffa.rst b/doc/arch/arm64.ffa.rst index f966f8ba6af..3eec735d741 100644 --- a/doc/arch/arm64.ffa.rst +++ b/doc/arch/arm64.ffa.rst @@ -185,6 +185,7 @@ The following features are provided: - FFA_INTERRUPT - FFA_MSG_SEND_DIRECT_REQ - FFA_MSG_SEND_DIRECT_RESP +- FFA_MEM_SHARE - Support for the 64-bit version of the following ABIs: @@ -203,6 +204,7 @@ The following features are provided: - ffa_partition_info_get - ffa_sync_send_receive - ffa_rxtx_unmap +- ffa_memory_share - FF-A bus discovery makes sure FF-A framework is responsive and compatible with the driver diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c index 5ec7654ed1c..8ff666c3757 100644 --- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c +++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c @@ -95,6 +95,20 @@ static struct ffa_abi_errmap err_msg_map[FFA_ERRMAP_COUNT] = { "DENIED: Buffer pair already registered", }, }, + [FFA_ID_TO_ERRMAP_ID(FFA_MEM_SHARE)] = { + { + [ABORTED] = + "ABORTED: Failure in the transmission of fragments or in time slicing", + [INVALID_PARAMETERS] = + "INVALID_PARAMETERS: Validation failed for the Memory Transaction or the Endpoint memory access descriptor", + [NO_MEMORY] = + "NO_MEMORY: Insufficient memory to complete this operation", + [BUSY] = + "BUSY: The TX buffer is busy", + [DENIED] = + "DENIED: Memory region ownership, permission, access or attributes error", + }, + }, }; /** @@ -929,6 +943,178 @@ int ffa_msg_send_direct_req_hdlr(struct udevice *dev, u16 dst_part_id, return ffa_to_std_errno(ffa_errno); } +/** + * ffa_mem_desc_offset() - helper for descriptors offset calculation + * @count: The number of Endpoint memory access descriptors + * + * Calculate the offset of the Endpoint memory access descriptor and + * the Composite memory region descriptor. + * + * Return: + * + * The descriptor offset. + */ +static inline u32 ffa_mem_desc_offset(int count) +{ + u32 offset = count * sizeof(struct ffa_mem_region_attributes); + + offset += sizeof(struct ffa_mem_region); + + return offset; +} + +/** + * ffa_setup_and_transmit() - setup the memory region and invoke the memory ABI + * @dev: The FF-A bus device + * @func_id: The FF-A memory ABI (currently we support FFA_MEM_SHARE only) + * @buffer: The TX buffer + * @args: The user arguments + * + * Setup the memory transaction related to the access to a specified + * memory region. + * + * Return: + * + * 0 on success. . Otherwise, failure + */ +static int ffa_setup_and_transmit(struct udevice *dev, u32 func_id, + void *buffer, struct ffa_mem_ops_args *args) +{ + ffa_value_t res = {0}; + int ffa_errno; + u32 composite_offset; + u32 total_length; + struct ffa_mem_region *mem_region = buffer; + struct ffa_composite_mem_region *composite; + struct ffa_mem_region_addr_range *constituent; + struct ffa_mem_region_attributes *ep_mem_access; + u32 idx; + struct ffa_priv *uc_priv; + + if (!buffer || !args->attrs || !args->address) + return -EINVAL; + + uc_priv = dev_get_uclass_priv(dev); + + mem_region->tag = args->tag; + mem_region->flags = args->flags; + mem_region->sender_id = uc_priv->id; + + /* +* These attributes are only valid for FFA_MEM_SHARE. +* They are not valid for FFA_MEM_LEND (no implemented). +*/ + if (func_id == FFA_MEM_SHARE) + mem_region->attributes = FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK +| FFA_MEM_INNER_SHAREABLE; + else + mem_region->attributes = 0; + +
[PATCH 4/8] arm_ffa: sandbox: Replace the emulator error log with debug log
From: Abdellatif El Khlifi Set the log to a debug log and reformulate the message The message is about showing what the emulated FF-A ABI decided based on the user arguments. The log is just for information purposes and helpful when debugging. Signed-off-by: Abdellatif El Khlifi --- drivers/firmware/arm-ffa/ffa-emul-uclass.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c index 1521d9b66ac..3e8b5288d3b 100644 --- a/drivers/firmware/arm-ffa/ffa-emul-uclass.c +++ b/drivers/firmware/arm-ffa/ffa-emul-uclass.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2022-2023 Arm Limited and/or its affiliates + * Copyright 2022-2024 Arm Limited and/or its affiliates * * Authors: * Abdellatif El Khlifi @@ -658,8 +658,7 @@ void sandbox_arm_ffa_smccc_smc(ffa_value_t *args, ffa_value_t *res) args->a0); } - if (ret != 0) - log_err("FF-A ABI internal failure (%d)\n", ret); + log_debug("Emulated FF-A ABI feedback (%d)\n", ret); } /** -- 2.25.1
[PATCH 0/8] arm_ffa: Add FFA_MEM_SHARE and FFA_MEM_RECLAIM support
From: Abdellatif El Khlifi Add to the FF-A bus FFA_MEM_SHARE and FFA_MEM_RECLAIM ABIs. These FF-A ABIs are for memory management. They are used for sharing memory between U-Boot and secure world. FFA_MEM_SHARE starts a transaction to grant access to a memory region to one or more Borrowers (aka Secure Partitions or endpoints). FFA_MEM_RECLAIM restores exclusive access to a memory region back to its Owner (U-Boot). For more details about these ABIs please refer to the FF-A v1.0 specification [1]. For more details about FF-A in U-Boot please refer to the readme [2]. This work is based on the implementation in Linux kernel [3]. This work is provided with sandbox support (emulation and test cases). [1]: https://developer.arm.com/documentation/den0077/a/?lang=en [2]: doc/arch/arm64.ffa.rst [3]: commit cc2195fe536c28e192df5d07e6dd277af36814b4 Files: drivers/firmware/arm_ffa/driver.c , include/linux/arm_ffa.h Cc: Tom Rini Cc: Simon Glass Cc: Ilias Apalodimas Cc: Jens Wiklander Cc: Achin Gupta Cc: Drew Reed Cc: Hugues Kamba Mpiana Cheers, Abdellatif Abdellatif El Khlifi (8): arm_ffa: Add NULL pointer check to the driver operations arm_ffa: Add FFA_MEM_SHARE support arm_ffa: Add FFA_MEM_RECLAIM support arm_ffa: sandbox: Replace the emulator error log with debug log arm_ffa: sandbox: Add FFA_MEM_SHARE emulation arm_ffa: sandbox: Add FFA_MEM_SHARE tests arm_ffa: sandbox: Add FFA_MEM_RECLAIM emulation arm_ffa: sandbox: Add FFA_MEM_RECLAIM tests .../include/asm/sandbox_arm_ffa_priv.h| 5 +- doc/arch/arm64.ffa.rst| 4 + drivers/firmware/arm-ffa/arm-ffa-uclass.c | 286 +- drivers/firmware/arm-ffa/arm-ffa.c| 4 +- drivers/firmware/arm-ffa/ffa-emul-uclass.c| 92 +- drivers/firmware/arm-ffa/sandbox_ffa.c| 4 +- include/arm_ffa.h | 111 ++- include/arm_ffa_priv.h| 143 - test/dm/ffa.c | 73 - 9 files changed, 707 insertions(+), 15 deletions(-) base-commit: 28dc47038edc4e93f32d75a357131bcf01a18d85 -- 2.25.1
[PATCH 1/8] arm_ffa: Add NULL pointer check to the driver operations
From: Abdellatif El Khlifi Add NULL pointer check for ops Signed-off-by: Abdellatif El Khlifi --- drivers/firmware/arm-ffa/arm-ffa-uclass.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/arm-ffa/arm-ffa-uclass.c b/drivers/firmware/arm-ffa/arm-ffa-uclass.c index 96c64964bb7..5ec7654ed1c 100644 --- a/drivers/firmware/arm-ffa/arm-ffa-uclass.c +++ b/drivers/firmware/arm-ffa/arm-ffa-uclass.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2022-2023 Arm Limited and/or its affiliates + * Copyright 2022-2024 Arm Limited and/or its affiliates * * Authors: * Abdellatif El Khlifi @@ -954,7 +954,7 @@ int ffa_partition_info_get(struct udevice *dev, const char *uuid_str, { struct ffa_bus_ops *ops = ffa_get_ops(dev); - if (!ops->partition_info_get) + if (!ops || !ops->partition_info_get) return -ENOSYS; return ops->partition_info_get(dev, uuid_str, sp_count, sp_descs); @@ -979,7 +979,7 @@ int ffa_sync_send_receive(struct udevice *dev, u16 dst_part_id, { struct ffa_bus_ops *ops = ffa_get_ops(dev); - if (!ops->sync_send_receive) + if (!ops || !ops->sync_send_receive) return -ENOSYS; return ops->sync_send_receive(dev, dst_part_id, msg, is_smc64); @@ -1000,7 +1000,7 @@ int ffa_rxtx_unmap(struct udevice *dev) { struct ffa_bus_ops *ops = ffa_get_ops(dev); - if (!ops->rxtx_unmap) + if (!ops || !ops->rxtx_unmap) return -ENOSYS; return ops->rxtx_unmap(dev); -- 2.25.1
[PATCH 7/8] arm_ffa: sandbox: Add FFA_MEM_RECLAIM emulation
From: Abdellatif El Khlifi Add FFA_MEM_RECLAIM support to the FF-A emulator Signed-off-by: Abdellatif El Khlifi --- drivers/firmware/arm-ffa/ffa-emul-uclass.c | 43 ++ drivers/firmware/arm-ffa/sandbox_ffa.c | 1 + 2 files changed, 44 insertions(+) diff --git a/drivers/firmware/arm-ffa/ffa-emul-uclass.c b/drivers/firmware/arm-ffa/ffa-emul-uclass.c index a859d2e26cc..b628e2c5c63 100644 --- a/drivers/firmware/arm-ffa/ffa-emul-uclass.c +++ b/drivers/firmware/arm-ffa/ffa-emul-uclass.c @@ -604,6 +604,46 @@ feedback: return ret; } +/** + * sandbox_ffa_memory_reclaim() - Emulated FFA_MEM_RECLAIM handler + * @emul: The sandbox FF-A emulator device + * @pargs: The SMC call input arguments a0-a7 + * @res: The SMC return data + * + * Emulate FFA_MEM_RECLAIM FF-A function. + * + * Return: + * + * 0 on success. Otherwise, failure + */ +static int sandbox_ffa_memory_reclaim(struct udevice *emul, ffa_value_t *pargs, + ffa_value_t *res) +{ + int ret; + + if (pargs->a1 != SANDBOX_MEM_HANDLE || + pargs->a2 != SANDBOX_MEM_HANDLE) { + res->a0 = FFA_SMC_32(FFA_ERROR); + res->a2 = -INVALID_PARAMETERS; + ret = ffa_to_std_errmap[INVALID_PARAMETERS]; + goto feedback; + } + + res->a0 = FFA_SMC_32(FFA_SUCCESS); + res->a2 = 0; + ret = 0; + +feedback: + + res->a1 = 0; + res->a3 = 0; + + /* x4-x7 MBZ */ + memset(FFA_X4X7_MBZ_REG_START, 0, FFA_X4X7_MBZ_CNT * sizeof(ulong)); + + return ret; +} + /** * sandbox_query_ffa_emul_state() - Inspect the FF-A ABIs * @queried_func_id: The FF-A function to be queried @@ -697,6 +737,9 @@ void sandbox_arm_ffa_smccc_smc(ffa_value_t *args, ffa_value_t *res) case FFA_SMC_32(FFA_MEM_SHARE): ret = sandbox_ffa_memory_share(emul, args, res); break; + case FFA_SMC_32(FFA_MEM_RECLAIM): + ret = sandbox_ffa_memory_reclaim(emul, args, res); + break; default: log_err("Undefined FF-A interface (%lx)\n", args->a0); diff --git a/drivers/firmware/arm-ffa/sandbox_ffa.c b/drivers/firmware/arm-ffa/sandbox_ffa.c index a81455ce5ff..8af9c8ac005 100644 --- a/drivers/firmware/arm-ffa/sandbox_ffa.c +++ b/drivers/firmware/arm-ffa/sandbox_ffa.c @@ -92,6 +92,7 @@ static const struct ffa_bus_ops sandbox_ffa_ops = { .sync_send_receive = ffa_msg_send_direct_req_hdlr, .rxtx_unmap = ffa_unmap_rxtx_buffers_hdlr, .memory_share = ffa_memory_share_hdlr, + .memory_reclaim = ffa_memory_reclaim_hdlr, }; static const struct udevice_id sandbox_ffa_id[] = { -- 2.25.1