mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-29 16:48:59 +00:00
Merge changes from topic "ffa_el3_spmc" into integration
* changes: feat(spmc): enable checking of execution ctx count feat(spmc): enable parsing of UUID from SP Manifest feat(spmc): add partition mailbox structs feat(plat/arm): allow BL32 specific defines to be used by SPMC_AT_EL3 feat(plat/fvp): add EL3 SPMC #defines test(plat/fvp/lsp): add example logical partition feat(spmc/lsp): add logical partition framework
This commit is contained in:
commit
44b9d577c0
12 changed files with 452 additions and 16 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
60
include/services/el3_spmc_logical_sp.h
Normal file
60
include/services/el3_spmc_logical_sp.h
Normal file
|
@ -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 <common/bl_common.h>
|
||||
#include <lib/cassert.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* 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 */
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
61
plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
Normal file
61
plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <services/el3_spmc_logical_sp.h>
|
||||
#include <services/ffa_svc.h>
|
||||
#include <smccc_helpers.h>
|
||||
|
||||
#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. */
|
||||
);
|
|
@ -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
|
||||
|
|
107
services/std_svc/spm/el3_spmc/logical_sp.c
Normal file
107
services/std_svc/spm/el3_spmc/logical_sp.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <services/el3_spmc_logical_sp.h>
|
||||
#include <services/ffa_svc.h>
|
||||
#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;
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <lib/psci/psci.h>
|
||||
#include <lib/spinlock.h>
|
||||
#include <services/el3_spmc_logical_sp.h>
|
||||
#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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <libfdt.h>
|
||||
#include <plat/common/platform.h>
|
||||
#include <services/el3_spmc_logical_sp.h>
|
||||
#include <services/ffa_svc.h>
|
||||
#include <services/spmc_svc.h>
|
||||
#include <services/spmd_svc.h>
|
||||
|
@ -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) */
|
||||
|
|
Loading…
Add table
Reference in a new issue