mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 01:24:27 +00:00
Merge changes from topic "hob_creation_in_tf_a" into integration
* changes: feat(el3_spmc): ffa error handling in direct msg feat(ff-a): support FFA_MSG_SEND_DIRECT_REQ2/RESP2 feat(ff-a): add FFA_MEM_PERM_GET/SET_SMC64 feat(el3-spmc): support Hob list to boot S-EL0 SP feat(synquacer): add support Hob creation fix(fvp): exclude extend memory map TZC regions feat(fvp): add StandaloneMm manifest in fvp feat(spm): use xfer list with Hob list in SPM_MM
This commit is contained in:
commit
ee990d5217
10 changed files with 655 additions and 58 deletions
|
@ -173,8 +173,8 @@
|
|||
#define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
|
||||
#define FFA_NORMAL_WORLD_RESUME FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
|
||||
#define FFA_EL3_INTR_HANDLE FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
|
||||
#define FFA_MEM_PERM_GET FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
|
||||
#define FFA_MEM_PERM_SET FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
|
||||
#define FFA_MEM_PERM_GET_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
|
||||
#define FFA_MEM_PERM_SET_SMC32 FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
|
||||
#define FFA_CONSOLE_LOG_SMC32 FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
|
||||
|
||||
/* FFA SMC64 FIDs */
|
||||
|
@ -201,6 +201,8 @@
|
|||
FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
|
||||
#define FFA_MSG_SEND_DIRECT_RESP2_SMC64 \
|
||||
FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP2)
|
||||
#define FFA_MEM_PERM_GET_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_PERM_GET)
|
||||
#define FFA_MEM_PERM_SET_SMC64 FFA_FID(SMC_64, FFA_FNUM_MEM_PERM_SET)
|
||||
|
||||
/*
|
||||
* FF-A partition properties values.
|
||||
|
@ -208,6 +210,8 @@
|
|||
#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)
|
||||
#define FFA_PARTITION_DIRECT_REQ2_RECV U(1 << 9)
|
||||
#define FFA_PARTITION_DIRECT_REQ2_SEND U(1 << 10)
|
||||
|
||||
/*
|
||||
* Reserve a special value for traffic targeted to the Hypervisor or SPM.
|
||||
|
|
146
plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts
Normal file
146
plat/arm/board/fvp/fdts/fvp_stmm_manifest.dts
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
/ {
|
||||
#define MODE_SEL0 (0x1)
|
||||
#define MODE_SEL1 (0x2)
|
||||
|
||||
#define SECURE_RO 0x1
|
||||
#define SECURE_RW 0x3
|
||||
#define SECURE_EXECUTE_RO 0x5
|
||||
#define SECURE_EXECUTE_RW 0x7
|
||||
#define NON_SECURE_RO 0x9
|
||||
#define NON_SECURE_RW 0xB
|
||||
#define NON_SECURE_EXECUTE_RO 0xD
|
||||
#define NON_SECURE_EXECUTE_RW 0xF
|
||||
/*
|
||||
* FF-A compatible Secure Partition Manager parses the
|
||||
* config file and fetch the following booting arguments to
|
||||
* pass on to the StandAloneMM(StMM) Secure Partition.
|
||||
*/
|
||||
compatible = "arm,ffa-manifest-1.0";
|
||||
|
||||
description = "FVP Base StandaloneMm";
|
||||
ffa-version = <0x00010002>; /* 31:16 - Major, 15:0 - Minor */
|
||||
uuid = <0xdcae8d37 0x46446bf0 0xab401483 0xa3873c93>;
|
||||
id = <0x8001>;
|
||||
execution-ctx-count = <PLATFORM_CORE_COUNT>;
|
||||
exception-level = <MODE_SEL0>; /* SEL0*/
|
||||
execution-state = <0>; /* AArch64*/
|
||||
load-address = <0x0 0xff200000>;
|
||||
image-size = <0x0 0x00300000>;
|
||||
xlat-granule = <0>; /* 4KiB */
|
||||
boot-order = <0>;
|
||||
messaging-method = <0x603>; /* Direct req/resp/req2/resp2 supported. */
|
||||
gp-register-num = <0>;
|
||||
|
||||
device-regions {
|
||||
compatible = "arm,ffa-manifest-device-regions";
|
||||
|
||||
/**
|
||||
* System registers, rtc, uart and etc regions for access from S-EL0.
|
||||
*/
|
||||
io_fpga {
|
||||
base-address = <0x0 0x1C000000>;
|
||||
pages-count = <0x3000>;
|
||||
attributes = <SECURE_RW>;
|
||||
};
|
||||
|
||||
system_reg_el0 {
|
||||
base-address = <0x0 0x1C010000>;
|
||||
pages-count = <0x10>;
|
||||
attributes = <SECURE_RW>;
|
||||
};
|
||||
|
||||
/**
|
||||
* ARM CSS SoC Peripherals area.
|
||||
* Similar to SOC_CSS_MAP_DEVICE.
|
||||
*/
|
||||
soc_components {
|
||||
base-address = <0x0 0x20000000>;
|
||||
pages-count = <0xc200>;
|
||||
attributes = <SECURE_RO>;
|
||||
};
|
||||
|
||||
/**
|
||||
* NOR0 Flash region, used for Firmware Image Update.
|
||||
*/
|
||||
nor_flash0 {
|
||||
base-address = <0x0 0x08000000>;
|
||||
pages-count = <0x4000>;
|
||||
attributes = <SECURE_RW>;
|
||||
};
|
||||
|
||||
/**
|
||||
* NOR1 Flash region, used for Secure booting.
|
||||
*/
|
||||
nor_flash1 {
|
||||
base-address = <0x0 0x0c000000>;
|
||||
pages-count = <0x4000>;
|
||||
attributes = <SECURE_RW>;
|
||||
};
|
||||
};
|
||||
|
||||
memory-regions {
|
||||
compatible = "arm,ffa-manifest-memory-regions";
|
||||
|
||||
/*
|
||||
* SPM Payload memory. Mapped as code region for S-EL0
|
||||
* Similar to ARM_SP_IMAGE_MMAP.
|
||||
*/
|
||||
stmm_region {
|
||||
description = "image";
|
||||
base-address = <0x0 0xff200000>;
|
||||
pages-count = <0x300>;
|
||||
/* StMM will remap the regions during runtime */
|
||||
attributes = <SECURE_EXECUTE_RO>;
|
||||
};
|
||||
|
||||
/*
|
||||
* Memory shared between EL3 and S-EL0.
|
||||
* Similar to ARM_SPM_BUF_EL0_MMAP.
|
||||
*/
|
||||
rx-tx-buffers {
|
||||
description = "shared-buff";
|
||||
base-address = <0x0 0xff500000>;
|
||||
pages-count = <0x100>;
|
||||
attributes = <SECURE_RW>;
|
||||
};
|
||||
|
||||
/*
|
||||
* Memory shared between Normal world and S-EL0.
|
||||
* Similar to ARM_SP_IMAGE_NS_BUF_MMAP.
|
||||
*/
|
||||
ns_comm_buffer {
|
||||
/*
|
||||
* Description is needed for StMM to identify
|
||||
* ns-communication buffer.
|
||||
*/
|
||||
description = "ns-comm";
|
||||
base-address = <0x0 0xff600000>;
|
||||
pages-count = <0x10>;
|
||||
attributes = <NON_SECURE_RW>;
|
||||
};
|
||||
|
||||
/*
|
||||
* Heap used by SP to allocate memory for DMA.
|
||||
*/
|
||||
heap {
|
||||
/*
|
||||
* Description is needed for StMM to identify
|
||||
* heap buffer.
|
||||
*/
|
||||
description = "heap";
|
||||
base-address = <0x0 0xFF610000>;
|
||||
pages-count = <0x7F0>;
|
||||
attributes = <SECURE_RW>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -24,7 +24,7 @@ void plat_arm_security_setup(void)
|
|||
|
||||
const arm_tzc_regions_info_t fvp_tzc_regions[] = {
|
||||
ARM_TZC_REGIONS_DEF,
|
||||
#if !SPM_MM && !ENABLE_RME
|
||||
#if !SPM_MM && !ENABLE_RME && !(SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
|
||||
{FVP_DRAM3_BASE, FVP_DRAM3_END,
|
||||
ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},
|
||||
{FVP_DRAM4_BASE, FVP_DRAM4_END,
|
||||
|
|
|
@ -170,6 +170,8 @@
|
|||
# elif SPMC_AT_EL3
|
||||
# define PLAT_ARM_MMAP_ENTRIES 13
|
||||
# define MAX_XLAT_TABLES 11
|
||||
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
|
||||
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
|
||||
# else
|
||||
# define PLAT_ARM_MMAP_ENTRIES 9
|
||||
# if USE_DEBUGFS
|
||||
|
@ -220,7 +222,8 @@ defined(IMAGE_BL2) && MEASURED_BOOT
|
|||
* In case of PSA Crypto API, few algorithms like ECDSA needs bigger BL1 RW
|
||||
* area.
|
||||
*/
|
||||
#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO
|
||||
#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO || \
|
||||
FVP_TRUSTED_SRAM_SIZE == 512
|
||||
#define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xC000)
|
||||
#else
|
||||
#define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xB000)
|
||||
|
|
|
@ -25,6 +25,14 @@ endif
|
|||
# Libraries
|
||||
include lib/xlat_tables_v2/xlat_tables.mk
|
||||
|
||||
ifeq (${TRANSFER_LIST}, 1)
|
||||
include lib/transfer_list/transfer_list.mk
|
||||
endif
|
||||
|
||||
ifeq (${HOB_LIST}, 1)
|
||||
include lib/hob/hob.mk
|
||||
endif
|
||||
|
||||
PLAT_PATH := plat/socionext/synquacer
|
||||
PLAT_INCLUDES := -I$(PLAT_PATH)/include \
|
||||
-I$(PLAT_PATH)/drivers/scpi \
|
||||
|
|
|
@ -134,6 +134,9 @@ struct sp_exec_ctx {
|
|||
|
||||
/* Track the source partition ID to validate a direct response. */
|
||||
uint16_t dir_req_origin_id;
|
||||
|
||||
/* Track direct message function id to validate a direct response. */
|
||||
uint16_t dir_req_funcid;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -304,6 +304,7 @@ static bool direct_msg_validate_lp_resp(uint16_t origin_id, uint16_t lp_id,
|
|||
void *handle)
|
||||
{
|
||||
/* Retrieve populated Direct Response Arguments. */
|
||||
uint64_t smc_fid = SMC_GET_GP(handle, CTX_GPREG_X0);
|
||||
uint64_t x1 = SMC_GET_GP(handle, CTX_GPREG_X1);
|
||||
uint64_t x2 = SMC_GET_GP(handle, CTX_GPREG_X2);
|
||||
uint16_t src_id = ffa_endpoint_source(x1);
|
||||
|
@ -323,13 +324,29 @@ static bool direct_msg_validate_lp_resp(uint16_t origin_id, uint16_t lp_id,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!direct_msg_validate_arg2(x2)) {
|
||||
if ((smc_fid != FFA_MSG_SEND_DIRECT_RESP2_SMC64) &&
|
||||
!direct_msg_validate_arg2(x2)) {
|
||||
ERROR("Invalid EL3 LP message encoding.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Helper function to check that partition can receive direct msg or not.
|
||||
******************************************************************************/
|
||||
static bool direct_msg_receivable(uint32_t properties, uint16_t dir_req_fnum)
|
||||
{
|
||||
if ((dir_req_fnum == FFA_FNUM_MSG_SEND_DIRECT_REQ &&
|
||||
((properties & FFA_PARTITION_DIRECT_REQ_RECV) == 0U)) ||
|
||||
(dir_req_fnum == FFA_FNUM_MSG_SEND_DIRECT_REQ2 &&
|
||||
((properties & FFA_PARTITION_DIRECT_REQ2_RECV) == 0U))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Handle direct request messages and route to the appropriate destination.
|
||||
******************************************************************************/
|
||||
|
@ -345,14 +362,21 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
|
|||
{
|
||||
uint16_t src_id = ffa_endpoint_source(x1);
|
||||
uint16_t dst_id = ffa_endpoint_destination(x1);
|
||||
uint16_t dir_req_funcid;
|
||||
struct el3_lp_desc *el3_lp_descs;
|
||||
struct secure_partition_desc *sp;
|
||||
unsigned int idx;
|
||||
|
||||
/* Check if arg2 has been populated correctly based on message type. */
|
||||
if (!direct_msg_validate_arg2(x2)) {
|
||||
return spmc_ffa_error_return(handle,
|
||||
FFA_ERROR_INVALID_PARAMETER);
|
||||
dir_req_funcid = (smc_fid != FFA_MSG_SEND_DIRECT_REQ2_SMC64) ?
|
||||
FFA_FNUM_MSG_SEND_DIRECT_REQ : FFA_FNUM_MSG_SEND_DIRECT_REQ2;
|
||||
|
||||
/*
|
||||
* Sanity check for DIRECT_REQ:
|
||||
* Check if arg2 has been populated correctly based on message type
|
||||
*/
|
||||
if ((dir_req_funcid == FFA_FNUM_MSG_SEND_DIRECT_REQ) &&
|
||||
!direct_msg_validate_arg2(x2)) {
|
||||
return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
/* Validate Sender is either the current SP or from the normal world. */
|
||||
|
@ -368,6 +392,10 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
|
|||
/* 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) {
|
||||
if (!direct_msg_receivable(el3_lp_descs[i].properties, dir_req_funcid)) {
|
||||
return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
|
||||
}
|
||||
|
||||
uint64_t ret = el3_lp_descs[i].direct_req(
|
||||
smc_fid, secure_origin, x1, x2,
|
||||
x3, x4, cookie, handle, flags);
|
||||
|
@ -402,6 +430,10 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
|
|||
FFA_ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
if (!direct_msg_receivable(sp->properties, dir_req_funcid)) {
|
||||
return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
|
||||
}
|
||||
|
||||
/* Protect the runtime state of a UP S-EL0 SP with a lock. */
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
spin_lock(&sp->rt_state_lock);
|
||||
|
@ -430,6 +462,7 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
|
|||
sp->ec[idx].rt_state = RT_STATE_RUNNING;
|
||||
sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
|
||||
sp->ec[idx].dir_req_origin_id = src_id;
|
||||
sp->ec[idx].dir_req_funcid = dir_req_funcid;
|
||||
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
spin_unlock(&sp->rt_state_lock);
|
||||
|
@ -453,9 +486,13 @@ static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
|
|||
uint64_t flags)
|
||||
{
|
||||
uint16_t dst_id = ffa_endpoint_destination(x1);
|
||||
uint16_t dir_req_funcid;
|
||||
struct secure_partition_desc *sp;
|
||||
unsigned int idx;
|
||||
|
||||
dir_req_funcid = (smc_fid != FFA_MSG_SEND_DIRECT_RESP2_SMC64) ?
|
||||
FFA_FNUM_MSG_SEND_DIRECT_REQ : FFA_FNUM_MSG_SEND_DIRECT_REQ2;
|
||||
|
||||
/* Check if arg2 has been populated correctly based on message type. */
|
||||
if (!direct_msg_validate_arg2(x2)) {
|
||||
return spmc_ffa_error_return(handle,
|
||||
|
@ -507,6 +544,15 @@ static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
|
|||
return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
|
||||
}
|
||||
|
||||
if (dir_req_funcid != sp->ec[idx].dir_req_funcid) {
|
||||
WARN("Unmatched direct req/resp func id. req:%x, resp:%x on core%u.\n",
|
||||
sp->ec[idx].dir_req_funcid, (smc_fid & FUNCID_NUM_MASK), idx);
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
spin_unlock(&sp->rt_state_lock);
|
||||
}
|
||||
return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
|
||||
}
|
||||
|
||||
if (sp->ec[idx].dir_req_origin_id != dst_id) {
|
||||
WARN("Invalid direct resp partition ID 0x%x != 0x%x on core%u.\n",
|
||||
dst_id, sp->ec[idx].dir_req_origin_id, idx);
|
||||
|
@ -522,6 +568,9 @@ static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
|
|||
/* Clear the ongoing direct request ID. */
|
||||
sp->ec[idx].dir_req_origin_id = INV_SP_ID;
|
||||
|
||||
/* Clear the ongoing direct request message version. */
|
||||
sp->ec[idx].dir_req_funcid = 0U;
|
||||
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
spin_unlock(&sp->rt_state_lock);
|
||||
}
|
||||
|
@ -647,6 +696,8 @@ static uint64_t ffa_error_handler(uint32_t smc_fid,
|
|||
{
|
||||
struct secure_partition_desc *sp;
|
||||
unsigned int idx;
|
||||
uint16_t dst_id = ffa_endpoint_destination(x1);
|
||||
bool cancel_dir_req = false;
|
||||
|
||||
/* Check that the response did not originate from the Normal world. */
|
||||
if (!secure_origin) {
|
||||
|
@ -674,6 +725,32 @@ static uint64_t ffa_error_handler(uint32_t smc_fid,
|
|||
panic();
|
||||
}
|
||||
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
spin_lock(&sp->rt_state_lock);
|
||||
}
|
||||
|
||||
if (sp->ec[idx].rt_state == RT_STATE_RUNNING &&
|
||||
sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
|
||||
sp->ec[idx].rt_state = RT_STATE_WAITING;
|
||||
sp->ec[idx].dir_req_origin_id = INV_SP_ID;
|
||||
sp->ec[idx].dir_req_funcid = 0x00;
|
||||
cancel_dir_req = true;
|
||||
}
|
||||
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
spin_unlock(&sp->rt_state_lock);
|
||||
}
|
||||
|
||||
if (cancel_dir_req) {
|
||||
if (dst_id == FFA_SPMC_ID) {
|
||||
spmc_sp_synchronous_exit(&sp->ec[idx], x4);
|
||||
/* Should not get here. */
|
||||
panic();
|
||||
} else
|
||||
return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
|
||||
handle, cookie, flags, dst_id);
|
||||
}
|
||||
|
||||
return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
@ -1267,6 +1344,7 @@ static uint64_t ffa_features_handler(uint32_t smc_fid,
|
|||
case FFA_RX_RELEASE:
|
||||
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
|
||||
case FFA_MSG_SEND_DIRECT_REQ_SMC64:
|
||||
case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
|
||||
case FFA_PARTITION_INFO_GET:
|
||||
case FFA_RXTX_MAP_SMC32:
|
||||
case FFA_RXTX_MAP_SMC64:
|
||||
|
@ -1289,6 +1367,7 @@ static uint64_t ffa_features_handler(uint32_t smc_fid,
|
|||
case FFA_SECONDARY_EP_REGISTER_SMC64:
|
||||
case FFA_MSG_SEND_DIRECT_RESP_SMC32:
|
||||
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
|
||||
case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
|
||||
case FFA_MEM_RELINQUISH:
|
||||
case FFA_MSG_WAIT:
|
||||
case FFA_CONSOLE_LOG_SMC32:
|
||||
|
@ -1909,7 +1988,9 @@ static int sp_manifest_parse(void *sp_manifest, int offset,
|
|||
|
||||
/* Validate this entry, we currently only support direct messaging. */
|
||||
if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV |
|
||||
FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) {
|
||||
FFA_PARTITION_DIRECT_REQ_SEND |
|
||||
FFA_PARTITION_DIRECT_REQ2_RECV |
|
||||
FFA_PARTITION_DIRECT_REQ2_SEND)) != 0U) {
|
||||
WARN("Invalid Secure Partition messaging method (0x%x)\n",
|
||||
config_32);
|
||||
return -EINVAL;
|
||||
|
@ -2077,39 +2158,34 @@ static int find_and_prepare_sp_context(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Check that the runtime EL in the manifest was correct. */
|
||||
if (sp->runtime_el != S_EL0 && sp->runtime_el != S_EL1) {
|
||||
ERROR("Unexpected runtime EL: %d\n", sp->runtime_el);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Perform any common initialisation. */
|
||||
spmc_sp_common_setup(sp, next_image_ep_info, boot_info_reg);
|
||||
|
||||
/* Perform any initialisation specific to S-EL1 SPs. */
|
||||
if (sp->runtime_el == S_EL1) {
|
||||
spmc_el1_sp_setup(sp, next_image_ep_info);
|
||||
spmc_sp_common_ep_commit(sp, next_image_ep_info);
|
||||
}
|
||||
|
||||
#if SPMC_AT_EL3_SEL0_SP
|
||||
/* Setup spsr in endpoint info for common context management routine. */
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
/* Perform any initialisation specific to S-EL0 SPs. */
|
||||
else if (sp->runtime_el == S_EL0) {
|
||||
/* Setup spsr in endpoint info for common context management routine. */
|
||||
spmc_el0_sp_spsr_setup(next_image_ep_info);
|
||||
}
|
||||
#endif /* SPMC_AT_EL3_SEL0_SP */
|
||||
|
||||
/* Initialize the SP context with the required ep info. */
|
||||
spmc_sp_common_ep_commit(sp, next_image_ep_info);
|
||||
spmc_sp_common_ep_commit(sp, next_image_ep_info);
|
||||
|
||||
#if SPMC_AT_EL3_SEL0_SP
|
||||
/*
|
||||
* Perform any initialisation specific to S-EL0 not set by common
|
||||
* context management routine.
|
||||
*/
|
||||
if (sp->runtime_el == S_EL0) {
|
||||
/*
|
||||
* Perform any initialisation specific to S-EL0 not set by common
|
||||
* context management routine.
|
||||
*/
|
||||
spmc_el0_sp_setup(sp, boot_info_reg, sp_manifest);
|
||||
}
|
||||
#endif /* SPMC_AT_EL3_SEL0_SP */
|
||||
else {
|
||||
ERROR("Unexpected runtime EL: %u\n", sp->runtime_el);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2356,11 +2432,13 @@ uint64_t spmc_smc_handler(uint32_t smc_fid,
|
|||
|
||||
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
|
||||
case FFA_MSG_SEND_DIRECT_REQ_SMC64:
|
||||
case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
|
||||
return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,
|
||||
x3, x4, cookie, handle, flags);
|
||||
|
||||
case FFA_MSG_SEND_DIRECT_RESP_SMC32:
|
||||
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
|
||||
case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
|
||||
return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2,
|
||||
x3, x4, cookie, handle, flags);
|
||||
|
||||
|
@ -2426,11 +2504,13 @@ uint64_t spmc_smc_handler(uint32_t smc_fid,
|
|||
return spmc_ffa_console_log(smc_fid, secure_origin, x1, x2, x3,
|
||||
x4, cookie, handle, flags);
|
||||
|
||||
case FFA_MEM_PERM_GET:
|
||||
case FFA_MEM_PERM_GET_SMC32:
|
||||
case FFA_MEM_PERM_GET_SMC64:
|
||||
return ffa_mem_perm_get_handler(smc_fid, secure_origin, x1, x2,
|
||||
x3, x4, cookie, handle, flags);
|
||||
|
||||
case FFA_MEM_PERM_SET:
|
||||
case FFA_MEM_PERM_SET_SMC32:
|
||||
case FFA_MEM_PERM_SET_SMC64:
|
||||
return ffa_mem_perm_set_handler(smc_fid, secure_origin, x1, x2,
|
||||
x3, x4, cookie, handle, flags);
|
||||
|
||||
|
|
|
@ -147,6 +147,8 @@ static int32_t spmc_send_pm_msg(uint8_t pm_msg_type,
|
|||
ec->rt_model = RT_MODEL_DIR_REQ;
|
||||
ec->rt_state = RT_STATE_RUNNING;
|
||||
ec->dir_req_origin_id = FFA_SPMC_ID;
|
||||
/* Expect a direct message response from the SP. */
|
||||
ec->dir_req_funcid = FFA_FNUM_MSG_SEND_DIRECT_REQ;
|
||||
|
||||
rc = spmc_sp_synchronous_entry(ec);
|
||||
if (rc != 0ULL) {
|
||||
|
|
|
@ -5,14 +5,22 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
|
||||
#include <context.h>
|
||||
#include <lib/el3_runtime/context_mgmt.h>
|
||||
#if HOB_LIST
|
||||
#include <lib/hob/hob.h>
|
||||
#include <lib/hob/hob_guid.h>
|
||||
#include <lib/hob/mmram.h>
|
||||
#include <lib/hob/mpinfo.h>
|
||||
#endif
|
||||
#include <lib/utils.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <libfdt.h>
|
||||
|
@ -51,6 +59,199 @@ enum sp_memory_region_type {
|
|||
SP_MEM_REGION_NOT_SPECIFIED
|
||||
};
|
||||
|
||||
|
||||
#if HOB_LIST
|
||||
static int get_memory_region_info(void *sp_manifest, int mem_region_node,
|
||||
const char *name, uint32_t granularity,
|
||||
uint64_t *base_address, uint32_t *size)
|
||||
{
|
||||
char *property;
|
||||
int node, ret;
|
||||
|
||||
if (name != NULL) {
|
||||
node = fdt_subnode_offset_namelen(sp_manifest, mem_region_node,
|
||||
name, strlen(name));
|
||||
if (node < 0) {
|
||||
ERROR("Not found '%s' region in memory regions configuration for SP.\n",
|
||||
name);
|
||||
return -ENOENT;
|
||||
}
|
||||
} else {
|
||||
node = mem_region_node;
|
||||
}
|
||||
|
||||
property = "base-address";
|
||||
ret = fdt_read_uint64(sp_manifest, node, property, base_address);
|
||||
if (ret < 0) {
|
||||
ERROR("Not found property(%s) in memory region(%s).\n",
|
||||
property, name);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
property = "pages-count";
|
||||
ret = fdt_read_uint32(sp_manifest, node, property, size);
|
||||
if (ret < 0) {
|
||||
ERROR("Not found property(%s) in memory region(%s).\n",
|
||||
property, name);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
*size = ((*size) << (PAGE_SIZE_SHIFT + (granularity << 1)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct efi_hob_handoff_info_table *build_sp_boot_hob_list(
|
||||
void *sp_manifest, uintptr_t hob_table_start, size_t *hob_table_size)
|
||||
{
|
||||
struct efi_hob_handoff_info_table *hob_table;
|
||||
uintptr_t base_address;
|
||||
int mem_region_node;
|
||||
int32_t node, ret;
|
||||
const char *name;
|
||||
uint32_t granularity, size;
|
||||
uint32_t mem_region_num;
|
||||
struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID;
|
||||
struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID;
|
||||
struct efi_mmram_descriptor *mmram_desc_data;
|
||||
struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data;
|
||||
|
||||
if (sp_manifest == NULL || hob_table_size == NULL || *hob_table_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = fdt_path_offset(sp_manifest, "/");
|
||||
if (node < 0) {
|
||||
ERROR("Failed to get root in sp_manifest.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = fdt_read_uint32(sp_manifest, node, "xlat-granule", &granularity);
|
||||
if (ret < 0) {
|
||||
ERROR("Not found property(xlat-granule) in sp_manifest.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (granularity > 0x02) {
|
||||
ERROR("Invalid granularity value: 0x%x\n", granularity);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem_region_node = fdt_subnode_offset_namelen(sp_manifest, 0, "memory-regions",
|
||||
sizeof("memory-regions") - 1);
|
||||
if (node < 0) {
|
||||
ERROR("Not found memory-region configuration for SP.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INFO("Generating PHIT_HOB...\n");
|
||||
|
||||
hob_table = create_hob_list(BL32_BASE, BL32_LIMIT,
|
||||
hob_table_start, *hob_table_size);
|
||||
if (hob_table == NULL) {
|
||||
ERROR("Failed to create Hob Table.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create fv hob.
|
||||
*/
|
||||
ret = get_memory_region_info(sp_manifest, mem_region_node,
|
||||
"stmm_region", granularity, &base_address, &size);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (base_address != BL32_BASE &&
|
||||
base_address + size > BL32_LIMIT) {
|
||||
ERROR("Image is ouf of bound(0x%lx/0x%x), should be in (0x%llx/0x%llx)\n",
|
||||
base_address, size, BL32_BASE, BL32_LIMIT - BL32_BASE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = create_fv_hob(hob_table, base_address, size);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to create fv hob... ret:%d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INFO("Success to create FV hob(0x%lx/0x%x).\n", base_address, size);
|
||||
|
||||
/*
|
||||
* Create Ns Buffer hob.
|
||||
*/
|
||||
ret = get_memory_region_info(sp_manifest, mem_region_node,
|
||||
"ns_comm_buffer", granularity, &base_address, &size);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = create_guid_hob(hob_table, &ns_buf_guid,
|
||||
sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to create ns buffer hob\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mmram_desc_data->physical_start = base_address;
|
||||
mmram_desc_data->physical_size = size;
|
||||
mmram_desc_data->cpu_start = base_address;
|
||||
mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
|
||||
|
||||
/*
|
||||
* Create mmram_resv hob.
|
||||
*/
|
||||
for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0;
|
||||
node >= 0;
|
||||
node = fdt_next_subnode(sp_manifest, node), mem_region_num++) {
|
||||
ret = get_memory_region_info(sp_manifest, node, NULL, granularity,
|
||||
&base_address, &size);
|
||||
if (ret < 0) {
|
||||
name = fdt_get_name(sp_manifest, node, NULL);
|
||||
ERROR("Invalid memory region(%s) found!\n", name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = create_guid_hob(hob_table, &mmram_resv_guid,
|
||||
(sizeof(struct efi_mmram_hob_descriptor_block) +
|
||||
(sizeof(struct efi_mmram_descriptor) * mem_region_num)),
|
||||
(void **) &mmram_hob_desc_data);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to create mmram_resv hob. ret: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mmram_hob_desc_data->number_of_mm_reserved_regions = mem_region_num;
|
||||
|
||||
for (node = fdt_first_subnode(sp_manifest, mem_region_node), mem_region_num = 0;
|
||||
node >= 0;
|
||||
node = fdt_next_subnode(sp_manifest, node), mem_region_num++) {
|
||||
get_memory_region_info(sp_manifest, node, NULL, granularity,
|
||||
&base_address, &size);
|
||||
name = fdt_get_name(sp_manifest, node, NULL);
|
||||
|
||||
mmram_desc_data = &mmram_hob_desc_data->descriptor[mem_region_num];
|
||||
mmram_desc_data->physical_start = base_address;
|
||||
mmram_desc_data->physical_size = size;
|
||||
mmram_desc_data->cpu_start = base_address;
|
||||
|
||||
if (!strcmp(name, "heap")) {
|
||||
mmram_desc_data->region_state = EFI_CACHEABLE;
|
||||
} else {
|
||||
mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
|
||||
}
|
||||
}
|
||||
|
||||
*hob_table_size = hob_table->efi_free_memory_bottom -
|
||||
(efi_physical_address_t) hob_table;
|
||||
|
||||
return hob_table;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function creates a initialization descriptor in the memory reserved
|
||||
* for passing boot information to an SP. It then copies the partition manifest
|
||||
|
@ -62,14 +263,13 @@ static void spmc_create_boot_info(entry_point_info_t *ep_info,
|
|||
{
|
||||
struct ffa_boot_info_header *boot_header;
|
||||
struct ffa_boot_info_desc *boot_descriptor;
|
||||
uintptr_t manifest_addr;
|
||||
uintptr_t content_addr;
|
||||
|
||||
/*
|
||||
* Calculate the maximum size of the manifest that can be accommodated
|
||||
* in the boot information memory region.
|
||||
*/
|
||||
const unsigned int
|
||||
max_manifest_sz = sizeof(ffa_boot_info_mem) -
|
||||
size_t max_sz = sizeof(ffa_boot_info_mem) -
|
||||
(sizeof(struct ffa_boot_info_header) +
|
||||
sizeof(struct ffa_boot_info_desc));
|
||||
|
||||
|
@ -83,17 +283,6 @@ static void spmc_create_boot_info(entry_point_info_t *ep_info,
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the manifest will fit into the boot info memory region else
|
||||
* bail.
|
||||
*/
|
||||
if (ep_info->args.arg1 > max_manifest_sz) {
|
||||
WARN("Unable to copy manifest into boot information. ");
|
||||
WARN("Max sz = %u bytes. Manifest sz = %lu bytes\n",
|
||||
max_manifest_sz, ep_info->args.arg1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Zero the memory region before populating. */
|
||||
memset(ffa_boot_info_mem, 0, PAGE_SIZE);
|
||||
|
||||
|
@ -125,29 +314,58 @@ static void spmc_create_boot_info(entry_point_info_t *ep_info,
|
|||
/* Set the count. Currently 1 since only the manifest is specified. */
|
||||
boot_header->count_boot_info_desc = 1;
|
||||
|
||||
boot_descriptor->flags =
|
||||
FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
|
||||
FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
|
||||
|
||||
content_addr = (uintptr_t) (ffa_boot_info_mem +
|
||||
boot_header->offset_boot_info_desc +
|
||||
boot_header->size_boot_info_desc);
|
||||
|
||||
#if HOB_LIST
|
||||
/* Populate the boot information descriptor for the hob_list. */
|
||||
boot_descriptor->type =
|
||||
FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
|
||||
FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_HOB);
|
||||
|
||||
content_addr = (uintptr_t) build_sp_boot_hob_list(
|
||||
(void *) ep_info->args.arg0, content_addr, &max_sz);
|
||||
if (content_addr == (uintptr_t) NULL) {
|
||||
WARN("Unable to create phit hob properly.");
|
||||
return;
|
||||
}
|
||||
|
||||
boot_descriptor->size_boot_info = max_sz;
|
||||
boot_descriptor->content = content_addr;
|
||||
#else
|
||||
/*
|
||||
* Check if the manifest will fit into the boot info memory region else
|
||||
* bail.
|
||||
*/
|
||||
if (ep_info->args.arg1 > max_sz) {
|
||||
WARN("Unable to copy manifest into boot information. ");
|
||||
WARN("Max sz = %lu bytes. Manifest sz = %lu bytes\n",
|
||||
max_sz, ep_info->args.arg1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Populate the boot information descriptor for the manifest. */
|
||||
boot_descriptor->type =
|
||||
FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
|
||||
FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_FDT);
|
||||
|
||||
boot_descriptor->flags =
|
||||
FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
|
||||
FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
|
||||
|
||||
/*
|
||||
* Copy the manifest into boot info region after the boot information
|
||||
* descriptor.
|
||||
*/
|
||||
boot_descriptor->size_boot_info = (uint32_t) ep_info->args.arg1;
|
||||
|
||||
manifest_addr = (uintptr_t) (ffa_boot_info_mem +
|
||||
boot_header->offset_boot_info_desc +
|
||||
boot_header->size_boot_info_desc);
|
||||
|
||||
memcpy((void *) manifest_addr, (void *) ep_info->args.arg0,
|
||||
memcpy((void *) content_addr, (void *) ep_info->args.arg0,
|
||||
boot_descriptor->size_boot_info);
|
||||
|
||||
boot_descriptor->content = manifest_addr;
|
||||
boot_descriptor->content = content_addr;
|
||||
#endif
|
||||
|
||||
/* Calculate the size of the total boot info blob. */
|
||||
boot_header->size_boot_info_blob = boot_header->offset_boot_info_desc +
|
||||
|
@ -158,7 +376,7 @@ static void spmc_create_boot_info(entry_point_info_t *ep_info,
|
|||
INFO("SP boot info @ 0x%lx, size: %u bytes.\n",
|
||||
(uintptr_t) ffa_boot_info_mem,
|
||||
boot_header->size_boot_info_blob);
|
||||
INFO("SP manifest @ 0x%lx, size: %u bytes.\n",
|
||||
INFO("SP content @ 0x%lx, size: %u bytes.\n",
|
||||
boot_descriptor->content,
|
||||
boot_descriptor->size_boot_info);
|
||||
}
|
||||
|
@ -194,6 +412,7 @@ static void read_optional_string(void *manifest, int32_t offset,
|
|||
out[0] = '\0';
|
||||
} else {
|
||||
memcpy(out, prop, MIN(lenp, (int)len));
|
||||
out[MIN(lenp, (int)len) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,10 +511,11 @@ static void populate_sp_regions(struct secure_partition_desc *sp,
|
|||
sp_mem_regions.base_va = base_address;
|
||||
sp_mem_regions.size = size;
|
||||
|
||||
INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n",
|
||||
INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx mem_attr: 0x%x, attr:0x%x\n",
|
||||
sp_mem_regions.base_pa,
|
||||
sp_mem_regions.base_va,
|
||||
sp_mem_regions.size,
|
||||
mem_attr,
|
||||
sp_mem_regions.attr);
|
||||
|
||||
if (type == SP_MEM_REGION_DEVICE) {
|
||||
|
@ -464,7 +684,6 @@ void spmc_el0_sp_setup(struct secure_partition_desc *sp,
|
|||
}
|
||||
|
||||
spmc_el0_sp_setup_system_registers(sp, ctx);
|
||||
|
||||
}
|
||||
#endif /* SPMC_AT_EL3_SEL0_SP */
|
||||
|
||||
|
|
|
@ -13,6 +13,15 @@
|
|||
#include <context.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/el3_runtime/context_mgmt.h>
|
||||
#if HOB_LIST
|
||||
#include <lib/hob/hob.h>
|
||||
#include <lib/hob/hob_guid.h>
|
||||
#include <lib/hob/mmram.h>
|
||||
#include <lib/hob/mpinfo.h>
|
||||
#endif
|
||||
#if TRANSFER_LIST
|
||||
#include <lib/transfer_list.h>
|
||||
#endif
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <platform_def.h>
|
||||
#include <plat/common/common_def.h>
|
||||
|
@ -23,6 +32,92 @@
|
|||
#include "spm_mm_private.h"
|
||||
#include "spm_shim_private.h"
|
||||
|
||||
#if HOB_LIST && TRANSFER_LIST
|
||||
static struct efi_hob_handoff_info_table *build_sp_boot_hob_list(
|
||||
const spm_mm_boot_info_t *sp_boot_info, uint16_t *hob_table_size)
|
||||
{
|
||||
int ret;
|
||||
struct efi_hob_handoff_info_table *hob_table;
|
||||
struct efi_guid ns_buf_guid = MM_NS_BUFFER_GUID;
|
||||
struct efi_guid mmram_resv_guid = MM_PEI_MMRAM_MEMORY_RESERVE_GUID;
|
||||
struct efi_mmram_descriptor *mmram_desc_data;
|
||||
uint16_t mmram_resv_data_size;
|
||||
struct efi_mmram_hob_descriptor_block *mmram_hob_desc_data;
|
||||
uint64_t hob_table_offset;
|
||||
|
||||
hob_table_offset = sizeof(struct transfer_list_header) +
|
||||
sizeof(struct transfer_list_entry);
|
||||
|
||||
*hob_table_size = 0U;
|
||||
|
||||
hob_table = create_hob_list(sp_boot_info->sp_mem_base,
|
||||
sp_boot_info->sp_mem_limit - sp_boot_info->sp_mem_base,
|
||||
sp_boot_info->sp_shared_buf_base + hob_table_offset,
|
||||
sp_boot_info->sp_shared_buf_size);
|
||||
if (hob_table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = create_fv_hob(hob_table, sp_boot_info->sp_image_base,
|
||||
sp_boot_info->sp_image_size);
|
||||
if (ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = create_guid_hob(hob_table, &ns_buf_guid,
|
||||
sizeof(struct efi_mmram_descriptor), (void **) &mmram_desc_data);
|
||||
if (ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mmram_desc_data->physical_start = sp_boot_info->sp_ns_comm_buf_base;
|
||||
mmram_desc_data->physical_size = sp_boot_info->sp_ns_comm_buf_size;
|
||||
mmram_desc_data->cpu_start = sp_boot_info->sp_ns_comm_buf_base;
|
||||
mmram_desc_data->region_state = EFI_CACHEABLE | EFI_ALLOCATED;
|
||||
|
||||
mmram_resv_data_size = sizeof(struct efi_mmram_hob_descriptor_block) +
|
||||
sizeof(struct efi_mmram_descriptor) * sp_boot_info->num_sp_mem_regions;
|
||||
|
||||
ret = create_guid_hob(hob_table, &mmram_resv_guid,
|
||||
mmram_resv_data_size, (void **) &mmram_hob_desc_data);
|
||||
if (ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*hob_table_size = hob_table->efi_free_memory_bottom -
|
||||
(efi_physical_address_t) hob_table;
|
||||
|
||||
mmram_hob_desc_data->number_of_mm_reserved_regions = 4U;
|
||||
mmram_desc_data = &mmram_hob_desc_data->descriptor[0];
|
||||
|
||||
/* First, should be image mm range. */
|
||||
mmram_desc_data[0].physical_start = sp_boot_info->sp_image_base;
|
||||
mmram_desc_data[0].physical_size = sp_boot_info->sp_image_size;
|
||||
mmram_desc_data[0].cpu_start = sp_boot_info->sp_image_base;
|
||||
mmram_desc_data[0].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
|
||||
|
||||
/* Second, should be shared buffer mm range. */
|
||||
mmram_desc_data[1].physical_start = sp_boot_info->sp_shared_buf_base;
|
||||
mmram_desc_data[1].physical_size = sp_boot_info->sp_shared_buf_size;
|
||||
mmram_desc_data[1].cpu_start = sp_boot_info->sp_shared_buf_base;
|
||||
mmram_desc_data[1].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
|
||||
|
||||
/* Ns Buffer mm range */
|
||||
mmram_desc_data[2].physical_start = sp_boot_info->sp_ns_comm_buf_base;
|
||||
mmram_desc_data[2].physical_size = sp_boot_info->sp_ns_comm_buf_size;
|
||||
mmram_desc_data[2].cpu_start = sp_boot_info->sp_ns_comm_buf_base;
|
||||
mmram_desc_data[2].region_state = EFI_CACHEABLE | EFI_ALLOCATED;
|
||||
|
||||
/* Heap mm range */
|
||||
mmram_desc_data[3].physical_start = sp_boot_info->sp_heap_base;
|
||||
mmram_desc_data[3].physical_size = sp_boot_info->sp_heap_size;
|
||||
mmram_desc_data[3].cpu_start = sp_boot_info->sp_heap_base;
|
||||
mmram_desc_data[3].region_state = EFI_CACHEABLE;
|
||||
|
||||
return hob_table;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup context of the Secure Partition */
|
||||
void spm_sp_setup(sp_context_t *sp_ctx)
|
||||
{
|
||||
|
@ -32,6 +127,15 @@ void spm_sp_setup(sp_context_t *sp_ctx)
|
|||
const spm_mm_boot_info_t *sp_boot_info =
|
||||
plat_get_secure_partition_boot_info(NULL);
|
||||
|
||||
#if HOB_LIST && TRANSFER_LIST
|
||||
struct efi_hob_handoff_info_table *hob_table;
|
||||
struct transfer_list_header *sp_boot_tl;
|
||||
struct transfer_list_entry *sp_boot_te;
|
||||
uint16_t hob_table_size;
|
||||
#endif
|
||||
|
||||
assert(sp_boot_info != NULL);
|
||||
|
||||
/*
|
||||
* Initialize CPU context
|
||||
* ----------------------
|
||||
|
@ -195,7 +299,35 @@ void spm_sp_setup(sp_context_t *sp_ctx)
|
|||
* Prepare information in buffer shared between EL3 and S-EL0
|
||||
* ----------------------------------------------------------
|
||||
*/
|
||||
#if HOB_LIST && TRANSFER_LIST
|
||||
sp_boot_tl = transfer_list_init((void *) sp_boot_info->sp_shared_buf_base,
|
||||
sp_boot_info->sp_shared_buf_size);
|
||||
assert(sp_boot_tl != NULL);
|
||||
|
||||
hob_table = build_sp_boot_hob_list(sp_boot_info, &hob_table_size);
|
||||
assert(hob_table != NULL);
|
||||
|
||||
transfer_list_update_checksum(sp_boot_tl);
|
||||
|
||||
sp_boot_te = transfer_list_add(sp_boot_tl, TL_TAG_HOB_LIST,
|
||||
hob_table_size, hob_table);
|
||||
if (sp_boot_te == NULL) {
|
||||
ERROR("Failed to add HOB list to xfer list\n");
|
||||
}
|
||||
|
||||
transfer_list_set_handoff_args(sp_boot_tl, &ep_info);
|
||||
|
||||
transfer_list_dump(sp_boot_tl);
|
||||
|
||||
write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0,
|
||||
ep_info.args.arg0);
|
||||
write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1,
|
||||
ep_info.args.arg1);
|
||||
write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2,
|
||||
ep_info.args.arg2);
|
||||
write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3,
|
||||
ep_info.args.arg3);
|
||||
#else
|
||||
void *shared_buf_ptr = (void *) sp_boot_info->sp_shared_buf_base;
|
||||
|
||||
/* Copy the boot information into the shared buffer with the SP. */
|
||||
|
@ -205,7 +337,6 @@ void spm_sp_setup(sp_context_t *sp_ctx)
|
|||
assert(sp_boot_info->sp_shared_buf_base <=
|
||||
(UINTPTR_MAX - sp_boot_info->sp_shared_buf_size + 1));
|
||||
|
||||
assert(sp_boot_info != NULL);
|
||||
|
||||
memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
|
||||
sizeof(spm_mm_boot_info_t));
|
||||
|
@ -256,4 +387,5 @@ void spm_sp_setup(sp_context_t *sp_ctx)
|
|||
if (plat_my_core_pos() == sp_mp_info[index].linear_id)
|
||||
sp_mp_info[index].flags |= MP_INFO_FLAG_PRIMARY_CPU;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue