From 7affa25cad400101c016082be2d102be0f4fce80 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Mon, 14 Feb 2022 17:06:09 +0000 Subject: [PATCH 1/7] feat(spmc/lsp): add logical partition framework Introduce a framework to support running logical partitions alongside the SPMC in EL3 as per the v1.1 FF-A spec. The DECLARE_LOGICAL_PARTITION macro has been added to simplify the process to define a Logical Partition. The partitions themselves are statically allocated with the descriptors placed in RO memory. It is assumed that the MAX_EL3_LP_DESCS_COUNT will be defined by the platform. Change-Id: I1c2523e0ad2d9c5d36aeeef6b8bcb1e80db7c443 Signed-off-by: Marc Bonnici --- include/common/bl_common.h | 6 +- include/common/bl_common.ld.h | 13 ++- include/services/el3_spmc_logical_sp.h | 60 ++++++++++++ include/services/ffa_svc.h | 7 ++ services/std_svc/spm/el3_spmc/logical_sp.c | 107 +++++++++++++++++++++ services/std_svc/spm/el3_spmc/spmc.h | 7 ++ services/std_svc/spm/el3_spmc/spmc.mk | 4 +- services/std_svc/spm/el3_spmc/spmc_main.c | 80 ++++++++++++++- 8 files changed, 276 insertions(+), 8 deletions(-) create mode 100644 include/services/el3_spmc_logical_sp.h create mode 100644 services/std_svc/spm/el3_spmc/logical_sp.c diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 8cb4990f0..3a06cfbf9 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -81,6 +81,10 @@ #define __RODATA_END__ Load$$__RODATA_EPILOGUE__$$Base #define __RT_SVC_DESCS_START__ Load$$__RT_SVC_DESCS__$$Base #define __RT_SVC_DESCS_END__ Load$$__RT_SVC_DESCS__$$Limit +#if SPMC_AT_EL3 +#define __EL3_LP_DESCS_START__ Load$$__EL3_LP_DESCS__$$Base +#define __EL3_LP_DESCS_END__ Load$$__EL3_LP_DESCS__$$Limit +#endif #define __RW_START__ Load$$LR$$LR_RW_DATA$$Base #define __RW_END__ Load$$LR$$LR_END$$Base #define __SPM_SHIM_EXCEPTIONS_START__ Load$$__SPM_SHIM_EXCEPTIONS__$$Base diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h index 9888a3caf..080e331ed 100644 --- a/include/common/bl_common.ld.h +++ b/include/common/bl_common.ld.h @@ -39,6 +39,16 @@ KEEP(*(rt_svc_descs)) \ __RT_SVC_DESCS_END__ = .; +#if SPMC_AT_EL3 +#define EL3_LP_DESCS \ + . = ALIGN(STRUCT_ALIGN); \ + __EL3_LP_DESCS_START__ = .; \ + KEEP(*(el3_lp_descs)) \ + __EL3_LP_DESCS_END__ = .; +#else +#define EL3_LP_DESCS +#endif + #define PMF_SVC_DESCS \ . = ALIGN(STRUCT_ALIGN); \ __PMF_SVC_DESCS_START__ = .; \ @@ -89,7 +99,8 @@ PARSER_LIB_DESCS \ CPU_OPS \ GOT \ - BASE_XLAT_TABLE_RO + BASE_XLAT_TABLE_RO \ + EL3_LP_DESCS /* * .data must be placed at a lower address than the stacks if the stack diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h new file mode 100644 index 000000000..7ec9958d5 --- /dev/null +++ b/include/services/el3_spmc_logical_sp.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef EL3_SP_H +#define EL3_SP_H + +#include +#include + +/******************************************************************************* + * Structure definition, typedefs & constants for the Logical SPs. + ******************************************************************************/ + +typedef uint64_t (*direct_msg_handler)(uint32_t smc_fid, bool secure_origin, + uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, void *handle, + uint64_t flags); + +/* Prototype for logical partition initializing function. */ +typedef int32_t (*ffa_partition_init_t)(void); + +/* Logical Partition Descriptor. */ +struct el3_lp_desc { + ffa_partition_init_t init; + uint16_t sp_id; + uint32_t properties; + uint32_t uuid[4]; /* Little Endian. */ + direct_msg_handler direct_req; + const char *debug_name; +}; + +/* Convenience macro to declare a logical partition descriptor. */ +#define DECLARE_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties, \ + _direct_req) \ + static const struct el3_lp_desc __partition_desc_ ## _name \ + __section("el3_lp_descs") __used = { \ + .debug_name = #_name, \ + .init = (_init), \ + .sp_id = (_sp_id), \ + .uuid = _uuid, \ + .properties = (_properties), \ + .direct_req = (_direct_req), \ + } + + +/******************************************************************************* + * Function & variable prototypes. + ******************************************************************************/ +int el3_sp_desc_validate(void); +uintptr_t handle_el3_sp(uint32_t smc_fid, void *cookie, void *handle, + unsigned int flags); +IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_START__, EL3_LP_DESCS_START); +IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_END__, EL3_LP_DESCS_END); + +#define EL3_LP_DESCS_COUNT ((EL3_LP_DESCS_END - EL3_LP_DESCS_START) \ + / sizeof(struct el3_lp_desc)) + +#endif /* EL3_SP_H */ diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index d3fb01273..2b4a37741 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -163,6 +163,13 @@ #define FFA_NOTIFICATION_INFO_GET_SMC64 \ FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET) +/* + * FF-A partition properties values. + */ +#define FFA_PARTITION_DIRECT_REQ_RECV U(1 << 0) +#define FFA_PARTITION_DIRECT_REQ_SEND U(1 << 1) +#define FFA_PARTITION_INDIRECT_MSG U(1 << 2) + /* * Reserve a special value for traffic targeted to the Hypervisor or SPM. */ diff --git a/services/std_svc/spm/el3_spmc/logical_sp.c b/services/std_svc/spm/el3_spmc/logical_sp.c new file mode 100644 index 000000000..e080832af --- /dev/null +++ b/services/std_svc/spm/el3_spmc/logical_sp.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include "spmc.h" + +/******************************************************************************* + * Validate any logical partition descriptors before we initialise. + * Initialization of said partitions will be taken care of during SPMC boot. + ******************************************************************************/ +int el3_sp_desc_validate(void) +{ + struct el3_lp_desc *lp_array; + + /* + * Assert the number of descriptors is less than maximum allowed. + * This constant should be define on a per platform basis. + */ + assert(EL3_LP_DESCS_COUNT <= MAX_EL3_LP_DESCS_COUNT); + + /* Check the array bounds are valid. */ + assert(EL3_LP_DESCS_END >= EL3_LP_DESCS_START); + + /* If no logical partitions are implemented then simply bail out. */ + if (EL3_LP_DESCS_COUNT == 0U) { + return 0; + } + + lp_array = get_el3_lp_array(); + + for (unsigned int index = 0; index < EL3_LP_DESCS_COUNT; index++) { + struct el3_lp_desc *lp_desc = &lp_array[index]; + + /* Validate our logical partition descriptors. */ + if (lp_desc == NULL) { + ERROR("Invalid Logical SP Descriptor\n"); + return -EINVAL; + } + + /* + * Ensure the ID follows the convention to indidate it resides + * in the secure world. + */ + if (!ffa_is_secure_world_id(lp_desc->sp_id)) { + ERROR("Invalid Logical SP ID (0x%x)\n", + lp_desc->sp_id); + return -EINVAL; + } + + /* Ensure we don't conflict with the SPMC partition ID. */ + if (lp_desc->sp_id == FFA_SPMC_ID) { + ERROR("Logical SP ID clashes with SPMC ID(0x%x)\n", + lp_desc->sp_id); + return -EINVAL; + } + + /* Ensure the UUID is not the NULL UUID. */ + if (lp_desc->uuid[0] == 0 && lp_desc->uuid[1] == 0 && + lp_desc->uuid[2] == 0 && lp_desc->uuid[3] == 0) { + ERROR("Invalid UUID for Logical SP (0x%x)\n", + lp_desc->sp_id); + return -EINVAL; + } + + /* Ensure init function callback is registered. */ + if (lp_desc->init == NULL) { + ERROR("Missing init function for Logical SP(0x%x)\n", + lp_desc->sp_id); + return -EINVAL; + } + + /* Ensure that LP only supports receiving direct requests. */ + if (lp_desc->properties & + ~(FFA_PARTITION_DIRECT_REQ_RECV)) { + ERROR("Invalid partition properties (0x%x)\n", + lp_desc->properties); + return -EINVAL; + } + + /* Ensure direct request function callback is registered. */ + if (lp_desc->direct_req == NULL) { + ERROR("No Direct Req handler for Logical SP (0x%x)\n", + lp_desc->sp_id); + return -EINVAL; + } + + /* Ensure that all partition IDs are unique. */ + for (unsigned int inner_idx = index + 1; + inner_idx < EL3_LP_DESCS_COUNT; inner_idx++) { + if (lp_desc->sp_id == lp_array[inner_idx].sp_id) { + ERROR("Duplicate SP ID Detected (0x%x)\n", + lp_desc->sp_id); + return -EINVAL; + } + } + } + return 0; +} diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h index df0aa61ce..db29727ea 100644 --- a/services/std_svc/spm/el3_spmc/spmc.h +++ b/services/std_svc/spm/el3_spmc/spmc.h @@ -11,6 +11,7 @@ #include #include +#include #include "spm_common.h" /* @@ -184,4 +185,10 @@ uint64_t spmc_ffa_error_return(void *handle, int error_code); */ bool is_ffa_secure_id_valid(uint16_t partition_id); +/* + * Helper function to obtain the array storing the EL3 + * Logical Partition descriptors. + */ +struct el3_lp_desc *get_el3_lp_array(void); + #endif /* SPMC_H */ diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk index 2b154dd7d..182753652 100644 --- a/services/std_svc/spm/el3_spmc/spmc.mk +++ b/services/std_svc/spm/el3_spmc/spmc.mk @@ -10,8 +10,8 @@ endif SPMC_SOURCES := $(addprefix services/std_svc/spm/el3_spmc/, \ spmc_main.c \ - spmc_setup.c) - + spmc_setup.c \ + logical_sp.c) # Let the top-level Makefile know that we intend to include a BL32 image NEED_BL32 := yes diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index 3fd8c7836..450dd8cdd 100644 --- a/services/std_svc/spm/el3_spmc/spmc_main.c +++ b/services/std_svc/spm/el3_spmc/spmc_main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,15 @@ static struct secure_partition_desc sp_desc[SECURE_PARTITION_COUNT]; */ static struct ns_endpoint_desc ns_ep_desc[NS_PARTITION_COUNT]; +/* + * Helper function to obtain the array storing the EL3 + * Logical Partition descriptors. + */ +struct el3_lp_desc *get_el3_lp_array(void) +{ + return (struct el3_lp_desc *) EL3_LP_DESCS_START; +} + /* * Helper function to obtain the descriptor of the last SP to whom control was * handed to on this physical cpu. Currently, we assume there is only one SP. @@ -105,6 +115,8 @@ uint64_t spmc_ffa_error_return(void *handle, int error_code) ******************************************************************************/ bool is_ffa_secure_id_valid(uint16_t partition_id) { + struct el3_lp_desc *el3_lp_descs = get_el3_lp_array(); + /* Ensure the ID is not the invalid partition ID. */ if (partition_id == INV_SP_ID) { return false; @@ -133,12 +145,22 @@ bool is_ffa_secure_id_valid(uint16_t partition_id) return false; } + /* Ensure we don't clash with any Logical SP's. */ + for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) { + if (el3_lp_descs[i].sp_id == partition_id) { + return false; + } + } + return true; } /******************************************************************************* * This function either forwards the request to the other world or returns * with an ERET depending on the source of the call. + * We can assume that the destination is for an entity at a lower exception + * level as any messages destined for a logical SP resident in EL3 will have + * already been taken care of by the SPMC before entering this function. ******************************************************************************/ static uint64_t spmc_smc_return(uint32_t smc_fid, bool secure_origin, @@ -210,6 +232,7 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid, uint64_t flags) { uint16_t dst_id = ffa_endpoint_destination(x1); + struct el3_lp_desc *el3_lp_descs; struct secure_partition_desc *sp; unsigned int idx; @@ -219,11 +242,22 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid, FFA_ERROR_INVALID_PARAMETER); } + el3_lp_descs = get_el3_lp_array(); + + /* Check if the request is destined for a Logical Partition. */ + for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) { + if (el3_lp_descs[i].sp_id == dst_id) { + return el3_lp_descs[i].direct_req( + smc_fid, secure_origin, x1, x2, x3, x4, + cookie, handle, flags); + } + } + /* - * If called by the secure world it is an invalid call since a - * SP cannot call into the Normal world and there is no other SP to call - * into. If there are other SPs in future then the partition runtime - * model would need to be validated as well. + * If the request was not targeted to a LSP and from the secure world + * then it is invalid since a SP cannot call into the Normal world and + * there is no other SP to call into. If there are other SPs in future + * then the partition runtime model would need to be validated as well. */ if (secure_origin) { VERBOSE("Direct request not supported to the Normal World.\n"); @@ -621,6 +655,37 @@ static int find_and_prepare_sp_context(void) * This function takes an SP context pointer and performs a synchronous entry * into it. ******************************************************************************/ +static int32_t logical_sp_init(void) +{ + int32_t rc = 0; + struct el3_lp_desc *el3_lp_descs; + + /* Perform initial validation of the Logical Partitions. */ + rc = el3_sp_desc_validate(); + if (rc != 0) { + ERROR("Logical Partition validation failed!\n"); + return rc; + } + + el3_lp_descs = get_el3_lp_array(); + + INFO("Logical Secure Partition init start.\n"); + for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) { + rc = el3_lp_descs[i].init(); + if (rc != 0) { + ERROR("Logical SP (0x%x) Failed to Initialize\n", + el3_lp_descs[i].sp_id); + return rc; + } + VERBOSE("Logical SP (0x%x) Initialized\n", + el3_lp_descs[i].sp_id); + } + + INFO("Logical Secure Partition init completed.\n"); + + return rc; +} + uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec) { uint64_t rc; @@ -725,6 +790,13 @@ int32_t spmc_setup(void) initalize_sp_descs(); initalize_ns_ep_descs(); + /* Setup logical SPs. */ + ret = logical_sp_init(); + if (ret != 0) { + ERROR("Failed to initialize Logical Partitions.\n"); + return ret; + } + /* Perform physical SP setup. */ /* Disable MMU at EL1 (initialized by BL2) */ From a34ccd4c20e23f882e36b3d2b53ab5032aabc6d1 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Thu, 19 Aug 2021 14:42:19 +0100 Subject: [PATCH 2/7] test(plat/fvp/lsp): add example logical partition Add an example logical partition to the FVP platform that simply prints and echos the contents of a direct request with the appropriate direct response. Change-Id: Ib2052c9a63a74830e5e83bd8c128c5f9b0d94658 Signed-off-by: Marc Bonnici --- plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c | 61 ++++++++++++++++++++ services/std_svc/spm/el3_spmc/spmc.mk | 7 +++ 2 files changed, 68 insertions(+) create mode 100644 plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c diff --git a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c new file mode 100644 index 000000000..b9e4f864c --- /dev/null +++ b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#define LP_PARTITION_ID 0xC001 +#define LP_UUID {0x47a3bf57, 0xe98e43ad, 0xb7db524f, 0x1588f4e3} + +/* Our Logical SP currently only supports receipt of direct messaging. */ +#define PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_RECV + +static int32_t sp_init(void) +{ + INFO("LSP: Init function called.\n"); + return 0; +} + +static uint64_t handle_ffa_direct_request(uint32_t smc_fid, bool secure_origin, + uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, + void *handle, uint64_t flags) +{ + uint64_t ret; + + /* Determine if we have a 64 or 32 direct request. */ + if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) { + ret = FFA_MSG_SEND_DIRECT_RESP_SMC32; + } else if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC64) { + ret = FFA_MSG_SEND_DIRECT_RESP_SMC64; + } else { + panic(); /* Unknown SMC. */ + } + /* + * Handle the incoming request. For testing purposes we echo the + * incoming message. + */ + INFO("Logical Partition: Received Direct Request from %s world!\n", + secure_origin ? "Secure" : "Normal"); + + /* + * Logical SP's must always send a direct response so we can populate + * our response directly. + */ + SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0); +} + +/* Register logical partition */ +DECLARE_LOGICAL_PARTITION( + my_logical_partition, + sp_init, /* Init Function */ + LP_PARTITION_ID, /* FF-A Partition ID */ + LP_UUID, /* UUID */ + PARTITION_PROPERTIES, /* Partition Properties. */ + handle_ffa_direct_request /* Callback for direct requests. */ +); diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk index 182753652..8067c74eb 100644 --- a/services/std_svc/spm/el3_spmc/spmc.mk +++ b/services/std_svc/spm/el3_spmc/spmc.mk @@ -13,5 +13,12 @@ SPMC_SOURCES := $(addprefix services/std_svc/spm/el3_spmc/, \ spmc_setup.c \ logical_sp.c) +# Specify platform specific logical partition implementation. +SPMC_LP_SOURCES := $(addprefix ${PLAT_DIR}/, \ + ${PLAT}_el3_spmc_logical_sp.c) + + +SPMC_SOURCES += $(SPMC_LP_SOURCES) + # Let the top-level Makefile know that we intend to include a BL32 image NEED_BL32 := yes From 44639ab73e43e0b79da834dff8c85266d68e5066 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Mon, 29 Nov 2021 16:59:02 +0000 Subject: [PATCH 3/7] feat(plat/fvp): add EL3 SPMC #defines Introduce additional #defines for running with the EL3 SPMC on the FVP. The increase in xlat tables has been chosen to allow the test cases to complete successfully and may need adjusting depending on the desired usecase. Signed-off-by: Marc Bonnici Change-Id: I7f44344ff8b74ae8907d53ebb652ff8def2d2562 --- plat/arm/board/fvp/fvp_common.c | 2 +- plat/arm/board/fvp/include/platform_def.h | 43 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index e9f725c04..a7028f6cf 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -127,7 +127,7 @@ const mmap_region_t plat_arm_mmap[] = { */ ARM_MAP_BL1_RW, #endif /* CRYPTO_SUPPORT && !BL2_AT_EL3 */ -#if SPM_MM +#if SPM_MM || SPMC_AT_EL3 ARM_SP_IMAGE_MMAP, #endif #if ARM_BL31_IN_DRAM diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index e70114418..82bd7c8a5 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -86,6 +86,35 @@ #define FVP_DTB_DRAM_MAP_START ULL(0x82000000) #define FVP_DTB_DRAM_MAP_SIZE ULL(0x02000000) /* 32 MB */ +#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ + FVP_DTB_DRAM_MAP_START, \ + FVP_DTB_DRAM_MAP_SIZE, \ + MT_MEMORY | MT_RO | MT_NS) + +#if SPMC_AT_EL3 +/* + * Number of Secure Partitions supported. + * SPMC at EL3, uses this count to configure the maximum number of supported + * secure partitions. + */ +#define SECURE_PARTITION_COUNT 1 + +/* + * Number of Normal World Partitions supported. + * SPMC at EL3, uses this count to configure the maximum number of supported + * NWd partitions. + */ +#define NS_PARTITION_COUNT 1 + +/* + * Number of Logical Partitions supported. + * SPMC at EL3, uses this count to configure the maximum number of supported + * logical partitions. + */ +#define MAX_EL3_LP_DESCS_COUNT 1 + +#endif /* SPMC_AT_EL3 */ + /* * Load address of BL33 for this platform port */ @@ -102,9 +131,12 @@ # define MAX_XLAT_TABLES 11 # else # define MAX_XLAT_TABLES 9 -# endif +# endif # define PLAT_SP_IMAGE_MMAP_REGIONS 30 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 +# elif SPMC_AT_EL3 +# define PLAT_ARM_MMAP_ENTRIES 13 +# define MAX_XLAT_TABLES 11 # else # define PLAT_ARM_MMAP_ENTRIES 9 # if USE_DEBUGFS @@ -122,8 +154,13 @@ # endif # endif #elif defined(IMAGE_BL32) -# define PLAT_ARM_MMAP_ENTRIES 9 -# define MAX_XLAT_TABLES 6 +# if SPMC_AT_EL3 +# define PLAT_ARM_MMAP_ENTRIES 270 +# define MAX_XLAT_TABLES 10 +# else +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 6 +# endif #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 # define MAX_XLAT_TABLES 5 From 2d65ea1930d4ce26cc176a8c60e9401d0b4f862a Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Mon, 20 Dec 2021 10:53:52 +0000 Subject: [PATCH 4/7] feat(plat/arm): allow BL32 specific defines to be used by SPMC_AT_EL3 For EL3 SPMC configuration enabled platforms, allow the reuse of BL32 specific definitions. Signed-off-by: Marc Bonnici Change-Id: I37ffbbf680326c101fbb2f146085a96c138f07a1 --- include/plat/arm/common/arm_def.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 29edb4bc7..a8211bdc6 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -618,7 +618,7 @@ * Trusted DRAM (if available) or the DRAM region secured by the TrustZone * controller. */ -# if SPM_MM +# if SPM_MM || SPMC_AT_EL3 # define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) # define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000)) # define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) @@ -664,12 +664,13 @@ /* * BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no - * SPD and no SPM-MM, as they are the only ones that can be used as BL32. + * SPD and no SPM-MM and no SPMC-AT-EL3, as they are the only ones that can be + * used as BL32. */ #if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME -# if defined(SPD_none) && !SPM_MM +# if defined(SPD_none) && !SPM_MM && !SPMC_AT_EL3 # undef BL32_BASE -# endif /* defined(SPD_none) && !SPM_MM */ +# endif /* defined(SPD_none) && !SPM_MM || !SPMC_AT_EL3 */ #endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */ /******************************************************************************* From e1df6008d9b4a00da25ec08fbdcbd3a5967fdb54 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Thu, 2 Sep 2021 13:18:41 +0100 Subject: [PATCH 5/7] feat(spmc): add partition mailbox structs Add mailbox structs to the partition descriptors and ensure these are initialised correctly. Change-Id: Ie80166d19763c266b6a1d23e351d312dc31fb221 Signed-off-by: Marc Bonnici --- services/std_svc/spm/el3_spmc/spmc.h | 32 ++++++++++++++++++++++- services/std_svc/spm/el3_spmc/spmc_main.c | 6 +++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h index db29727ea..0915d0b4c 100644 --- a/services/std_svc/spm/el3_spmc/spmc.h +++ b/services/std_svc/spm/el3_spmc/spmc.h @@ -69,6 +69,28 @@ enum sp_execution_state { SP_STATE_AARCH32 }; +enum mailbox_state { + /* There is no message in the mailbox. */ + MAILBOX_STATE_EMPTY, + + /* There is a message that has been populated in the mailbox. */ + MAILBOX_STATE_FULL, +}; + +struct mailbox { + enum mailbox_state state; + + /* RX/TX Buffers. */ + void *rx_buffer; + const void *tx_buffer; + + /* Size of RX/TX Buffer. */ + uint32_t rxtx_page_count; + + /* Lock access to mailbox. */ + spinlock_t lock; +}; + /* * Execution context members for an SP. This is a bit like struct * vcpu in a hypervisor. @@ -119,6 +141,9 @@ struct secure_partition_desc { /* Execution State. */ enum sp_execution_state execution_state; + /* Mailbox tracking. */ + struct mailbox mailbox; + /* Secondary entrypoint. Only valid for a S-EL1 SP. */ uintptr_t secondary_ep; }; @@ -143,7 +168,12 @@ struct ns_endpoint_desc { uint16_t ns_ep_id; /* - * Supported FF-A Version. + * Mailbox tracking. + */ + struct mailbox mailbox; + + /* + * Supported FF-A Version */ uint32_t ffa_version; }; diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index 450dd8cdd..bce9f9fa1 100644 --- a/services/std_svc/spm/el3_spmc/spmc_main.c +++ b/services/std_svc/spm/el3_spmc/spmc_main.c @@ -749,6 +749,9 @@ static void initalize_sp_descs(void) for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) { sp = &sp_desc[i]; sp->sp_id = INV_SP_ID; + sp->mailbox.rx_buffer = NULL; + sp->mailbox.tx_buffer = NULL; + sp->mailbox.state = MAILBOX_STATE_EMPTY; sp->secondary_ep = 0; } } @@ -765,6 +768,9 @@ static void initalize_ns_ep_descs(void) */ ns_ep->ns_ep_id = 0; ns_ep->ffa_version = 0; + ns_ep->mailbox.rx_buffer = NULL; + ns_ep->mailbox.tx_buffer = NULL; + ns_ep->mailbox.state = MAILBOX_STATE_EMPTY; } } From 857f5790da3770a9ca52416274eec4e545c9be53 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Tue, 24 Aug 2021 11:31:52 +0100 Subject: [PATCH 6/7] feat(spmc): enable parsing of UUID from SP Manifest To align with other SPMC implementations parse the UUID from the SP manifest as 4 uint32 values and store this internally. Change-Id: I7de5d5ef8d98dc14bc7c76892133c2333358a379 Signed-off-by: Marc Bonnici --- services/std_svc/spm/el3_spmc/spmc_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index bce9f9fa1..29d7d7bc0 100644 --- a/services/std_svc/spm/el3_spmc/spmc_main.c +++ b/services/std_svc/spm/el3_spmc/spmc_main.c @@ -513,6 +513,13 @@ static int sp_manifest_parse(void *sp_manifest, int offset, return node; } + ret = fdt_read_uint32_array(sp_manifest, node, "uuid", + ARRAY_SIZE(sp->uuid), sp->uuid); + if (ret != 0) { + ERROR("Missing Secure Partition UUID.\n"); + return ret; + } + ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32); if (ret != 0) { ERROR("Missing SP Exception Level information.\n"); From 5b0219ddd5da42413f4c2be9302224b5b71295ff Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Thu, 9 Dec 2021 10:51:05 +0000 Subject: [PATCH 7/7] feat(spmc): enable checking of execution ctx count This is a mandatory entry in an SP's manifest however currently an S-EL1 partition running under the EL3 SPMC must have the same amount of execution contexts as physical cores therefore just check the entry matches this value. Signed-off-by: Marc Bonnici Change-Id: I4c2a85ccde7a7bb9b1232cf6389a8c532cbf3d41 --- services/std_svc/spm/el3_spmc/spmc_main.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index 29d7d7bc0..35def25af 100644 --- a/services/std_svc/spm/el3_spmc/spmc_main.c +++ b/services/std_svc/spm/el3_spmc/spmc_main.c @@ -544,6 +544,25 @@ static int sp_manifest_parse(void *sp_manifest, int offset, sp->execution_state = config_32; + ret = fdt_read_uint32(sp_manifest, node, + "execution-ctx-count", &config_32); + + if (ret != 0) { + ERROR("Missing SP Execution Context Count.\n"); + return ret; + } + + /* + * Ensure this field is set correctly in the manifest however + * since this is currently a hardcoded value for S-EL1 partitions + * we don't need to save it here, just validate. + */ + if (config_32 != PLATFORM_CORE_COUNT) { + ERROR("SP Execution Context Count (%u) must be %u.\n", + config_32, PLATFORM_CORE_COUNT); + return -EINVAL; + } + /* * Look for the optional fields that are expected to be present in * an SP manifest.