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/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 */ /******************************************************************************* 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/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/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/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 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..0915d0b4c 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" /* @@ -68,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. @@ -118,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; }; @@ -142,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; }; @@ -184,4 +215,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..8067c74eb 100644 --- a/services/std_svc/spm/el3_spmc/spmc.mk +++ b/services/std_svc/spm/el3_spmc/spmc.mk @@ -10,8 +10,15 @@ endif SPMC_SOURCES := $(addprefix services/std_svc/spm/el3_spmc/, \ spmc_main.c \ - spmc_setup.c) + 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 diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index 3fd8c7836..35def25af 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"); @@ -479,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"); @@ -503,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. @@ -621,6 +681,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; @@ -684,6 +775,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; } } @@ -700,6 +794,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; } } @@ -725,6 +822,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) */