mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
feat(rmmd): add support for RMM Boot interface
This patch adds the infrastructure needed to pass boot arguments from EL3 to RMM and allocates a shared buffer between both worlds that can be used, among others, to pass a boot manifest to RMM. The buffer is composed a single memory page be used by a later EL3 <-> RMM interface by all CPUs. The RMM boot manifest is not implemented by this patch. In addition to that, this patch also enables support for RMM when RESET_TO_BL31 is enabled. Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com> Change-Id: I855cd4758ee3843eadd9fb482d70a6d18954d82a
This commit is contained in:
parent
caca0e57b8
commit
8c980a4a46
19 changed files with 336 additions and 75 deletions
|
@ -563,6 +563,9 @@ subsections:
|
|||
- title: TRP
|
||||
scope: trp
|
||||
|
||||
- title: RMMD
|
||||
scope: rmmd
|
||||
|
||||
- title: SPM
|
||||
scope: spm
|
||||
|
||||
|
|
|
@ -2017,7 +2017,7 @@ state. This function must return a pointer to the ``entry_point_info`` structure
|
|||
(that was copied during ``bl31_early_platform_setup()``) if the image exists. It
|
||||
should return NULL otherwise.
|
||||
|
||||
Function : plat_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
|
||||
Function : plat_rmmd_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
@ -2043,8 +2043,8 @@ The parameters of the function are:
|
|||
|
||||
The function returns 0 on success, -EINVAL on failure.
|
||||
|
||||
Function : plat_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
|
@ -2069,6 +2069,18 @@ The parameters of the function are:
|
|||
|
||||
The function returns 0 on success, -EINVAL on failure.
|
||||
|
||||
Function : plat_rmmd_get_el3_rmm_shared_mem() [when ENABLE_RME == 1]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
Argument : uintptr_t *
|
||||
Return : size_t
|
||||
|
||||
This function returns the size of the shared area between EL3 and RMM (or 0 on
|
||||
failure). A pointer to the shared area (or a NULL pointer on failure) is stored
|
||||
in the pointer passed as argument.
|
||||
|
||||
Function : bl31_plat_enable_mmu [optional]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
* - SCP TZC DRAM: If present, DRAM reserved for SCP use
|
||||
* - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
|
||||
* - REALM DRAM: Reserved for Realm world if RME is enabled
|
||||
* - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
|
||||
* - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use
|
||||
*
|
||||
* RME enabled(64MB) RME not enabled(16MB)
|
||||
|
@ -87,11 +88,16 @@
|
|||
* | AP TZC (~28MB) | | AP TZC (~14MB) |
|
||||
* -------------------- -------------------
|
||||
* | | | |
|
||||
* | REALM (32MB) | | EL3 TZC (2MB) |
|
||||
* -------------------- -------------------
|
||||
* | | | |
|
||||
* | EL3 TZC (3MB) | | SCP TZC |
|
||||
* -------------------- 0xFFFF_FFFF-------------------
|
||||
* | REALM (RMM) | | EL3 TZC (2MB) |
|
||||
* | (32MB - 4KB) | -------------------
|
||||
* -------------------- | |
|
||||
* | | | SCP TZC |
|
||||
* | TF-A <-> RMM | 0xFFFF_FFFF-------------------
|
||||
* | SHARED (4KB) |
|
||||
* --------------------
|
||||
* | |
|
||||
* | EL3 TZC (3MB) |
|
||||
* --------------------
|
||||
* | L1 GPT + SCP TZC |
|
||||
* | (~1MB) |
|
||||
* 0xFFFF_FFFF --------------------
|
||||
|
@ -106,12 +112,17 @@
|
|||
*/
|
||||
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00300000) /* 3MB */
|
||||
#define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */
|
||||
#define ARM_REALM_SIZE UL(0x02000000) /* 32MB */
|
||||
|
||||
/* 32MB - ARM_EL3_RMM_SHARED_SIZE */
|
||||
#define ARM_REALM_SIZE (UL(0x02000000) - \
|
||||
ARM_EL3_RMM_SHARED_SIZE)
|
||||
#define ARM_EL3_RMM_SHARED_SIZE (PAGE_SIZE) /* 4KB */
|
||||
#else
|
||||
#define ARM_TZC_DRAM1_SIZE UL(0x01000000) /* 16MB */
|
||||
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2MB */
|
||||
#define ARM_L1_GPT_SIZE UL(0)
|
||||
#define ARM_REALM_SIZE UL(0)
|
||||
#define ARM_EL3_RMM_SHARED_SIZE UL(0)
|
||||
#endif /* ENABLE_RME */
|
||||
|
||||
#define ARM_SCP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
|
||||
|
@ -128,13 +139,20 @@
|
|||
#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \
|
||||
ARM_L1_GPT_SIZE - 1U)
|
||||
|
||||
#define ARM_REALM_BASE (ARM_DRAM1_BASE + \
|
||||
ARM_DRAM1_SIZE - \
|
||||
(ARM_SCP_TZC_DRAM1_SIZE + \
|
||||
ARM_EL3_TZC_DRAM1_SIZE + \
|
||||
ARM_REALM_SIZE + \
|
||||
ARM_L1_GPT_SIZE))
|
||||
#define ARM_REALM_BASE (ARM_EL3_RMM_SHARED_BASE - \
|
||||
ARM_REALM_SIZE)
|
||||
|
||||
#define ARM_REALM_END (ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
|
||||
|
||||
#define ARM_EL3_RMM_SHARED_BASE (ARM_DRAM1_BASE + \
|
||||
ARM_DRAM1_SIZE - \
|
||||
(ARM_SCP_TZC_DRAM1_SIZE + \
|
||||
ARM_L1_GPT_SIZE + \
|
||||
ARM_EL3_RMM_SHARED_SIZE + \
|
||||
ARM_EL3_TZC_DRAM1_SIZE))
|
||||
|
||||
#define ARM_EL3_RMM_SHARED_END (ARM_EL3_RMM_SHARED_BASE + \
|
||||
ARM_EL3_RMM_SHARED_SIZE - 1U)
|
||||
#endif /* ENABLE_RME */
|
||||
|
||||
#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - \
|
||||
|
@ -148,6 +166,7 @@
|
|||
#define ARM_AP_TZC_DRAM1_SIZE (ARM_TZC_DRAM1_SIZE - \
|
||||
(ARM_SCP_TZC_DRAM1_SIZE + \
|
||||
ARM_EL3_TZC_DRAM1_SIZE + \
|
||||
ARM_EL3_RMM_SHARED_SIZE + \
|
||||
ARM_REALM_SIZE + \
|
||||
ARM_L1_GPT_SIZE))
|
||||
#define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \
|
||||
|
@ -197,6 +216,7 @@
|
|||
#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
|
||||
#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
|
||||
ARM_TZC_DRAM1_SIZE)
|
||||
|
||||
#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \
|
||||
ARM_NS_DRAM1_SIZE - 1U)
|
||||
#ifdef PLAT_ARM_DRAM1_BASE
|
||||
|
@ -301,6 +321,12 @@
|
|||
ARM_L1_GPT_SIZE, \
|
||||
MT_MEMORY | MT_RW | EL3_PAS)
|
||||
|
||||
#define ARM_MAP_EL3_RMM_SHARED_MEM \
|
||||
MAP_REGION_FLAT( \
|
||||
ARM_EL3_RMM_SHARED_BASE, \
|
||||
ARM_EL3_RMM_SHARED_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_REALM)
|
||||
|
||||
#endif /* ENABLE_RME */
|
||||
|
||||
/*
|
||||
|
@ -595,6 +621,8 @@
|
|||
#if ENABLE_RME
|
||||
#define RMM_BASE (ARM_REALM_BASE)
|
||||
#define RMM_LIMIT (RMM_BASE + ARM_REALM_SIZE)
|
||||
#define RMM_SHARED_BASE (ARM_EL3_RMM_SHARED_BASE)
|
||||
#define RMM_SHARED_SIZE (ARM_EL3_RMM_SHARED_SIZE)
|
||||
#endif
|
||||
|
||||
#if !defined(__aarch64__) || JUNO_AARCH32_EL3_RUNTIME
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -61,6 +61,10 @@
|
|||
#define ARM_PAS_2_BASE (ARM_PAS_1_BASE + ARM_PAS_1_SIZE)
|
||||
#define ARM_PAS_2_SIZE (ARM_NS_DRAM1_SIZE)
|
||||
|
||||
/* Shared area between EL3 and RMM */
|
||||
#define ARM_PAS_SHARED_BASE (ARM_EL3_RMM_SHARED_BASE)
|
||||
#define ARM_PAS_SHARED_SIZE (ARM_EL3_RMM_SHARED_SIZE)
|
||||
|
||||
/* Secure TZC region */
|
||||
#define ARM_PAS_3_BASE (ARM_AP_TZC_DRAM1_BASE)
|
||||
#define ARM_PAS_3_SIZE (ARM_AP_TZC_DRAM1_SIZE)
|
||||
|
@ -76,8 +80,13 @@
|
|||
ARM_PAS_3_SIZE, \
|
||||
GPT_GPI_SECURE)
|
||||
|
||||
/*
|
||||
* REALM and Shared area share the same PAS, so consider them a single
|
||||
* PAS region to configure in GPT.
|
||||
*/
|
||||
#define ARM_PAS_REALM GPT_MAP_REGION_GRANULE(ARM_REALM_BASE, \
|
||||
ARM_REALM_SIZE, \
|
||||
(ARM_PAS_SHARED_SIZE + \
|
||||
ARM_REALM_SIZE), \
|
||||
GPT_GPI_REALM)
|
||||
|
||||
#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -57,7 +57,8 @@ typedef struct arm_tzc_regions_info {
|
|||
{ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0}, \
|
||||
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
|
||||
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
|
||||
{ARM_REALM_BASE, ARM_REALM_END, ARM_TZC_NS_DRAM_S_ACCESS, \
|
||||
/* Realm and Shared area share the same PAS */ \
|
||||
{ARM_REALM_BASE, ARM_EL3_RMM_SHARED_END, ARM_TZC_NS_DRAM_S_ACCESS, \
|
||||
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
|
||||
{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \
|
||||
PLAT_ARM_TZC_NS_DEV_ACCESS}
|
||||
|
|
|
@ -305,11 +305,11 @@ plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
|
|||
/*******************************************************************************
|
||||
* Mandatory BL31 functions when ENABLE_RME=1
|
||||
******************************************************************************/
|
||||
int plat_get_cca_attest_token(uintptr_t buf, size_t *len,
|
||||
uintptr_t hash, size_t hash_size);
|
||||
int plat_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
|
||||
unsigned int type);
|
||||
|
||||
int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
|
||||
uintptr_t hash, size_t hash_size);
|
||||
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
|
||||
unsigned int type);
|
||||
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
|
||||
/*******************************************************************************
|
||||
* Optional BL31 functions (may be overridden)
|
||||
******************************************************************************/
|
||||
|
|
|
@ -40,7 +40,17 @@
|
|||
/* 0x18F */
|
||||
#define RMMD_RMI_REQ_COMPLETE SMC64_RMI_FID(U(0x3F))
|
||||
|
||||
/* The SMC in the range 0x8400 0190 - 0x8400 01AF are reserved for RSIs.*/
|
||||
/* RMM_BOOT_COMPLETE arg0 error codes */
|
||||
#define E_RMM_BOOT_SUCCESS (0)
|
||||
#define E_RMM_BOOT_UNKNOWN (-1)
|
||||
#define E_RMM_BOOT_VERSION_MISMATCH (-2)
|
||||
#define E_RMM_BOOT_CPUS_OUT_OF_RANGE (-3)
|
||||
#define E_RMM_BOOT_CPU_ID_OUT_OF_RANGE (-4)
|
||||
#define E_RMM_BOOT_INVALID_SHARED_BUFFER (-5)
|
||||
#define E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED (-6)
|
||||
#define E_RMM_BOOT_MANIFEST_DATA_ERROR (-7)
|
||||
|
||||
/* The SMC in the range 0x8400 0191 - 0x8400 01AF are reserved for RSIs.*/
|
||||
|
||||
/*
|
||||
* EL3 - RMM SMCs used for requesting RMMD services. These SMCs originate in Realm
|
||||
|
@ -121,6 +131,36 @@
|
|||
/* ECC Curve types for attest key generation */
|
||||
#define ATTEST_KEY_CURVE_ECC_SECP384R1 0
|
||||
|
||||
/*
|
||||
* RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
|
||||
* or warm boot). This is handled by the RMM-EL3 interface SMC handler.
|
||||
*
|
||||
* RMM_BOOT_COMPLETE FID is located at the end of the available range.
|
||||
*/
|
||||
/* 0x1CF */
|
||||
#define RMM_BOOT_COMPLETE SMC64_RMMD_EL3_FID(U(0x1F))
|
||||
|
||||
/*
|
||||
* The major version number of the RMM Boot Interface implementation.
|
||||
* Increase this whenever the semantics of the boot arguments change making it
|
||||
* backwards incompatible.
|
||||
*/
|
||||
#define RMM_EL3_IFC_VERSION_MAJOR (U(0))
|
||||
|
||||
/*
|
||||
* The minor version number of the RMM Boot Interface implementation.
|
||||
* Increase this when a bug is fixed, or a feature is added without
|
||||
* breaking compatibility.
|
||||
*/
|
||||
#define RMM_EL3_IFC_VERSION_MINOR (U(1))
|
||||
|
||||
#define RMM_EL3_INTERFACE_VERSION \
|
||||
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \
|
||||
RMM_EL3_IFC_VERSION_MINOR)
|
||||
|
||||
#define RMM_EL3_IFC_VERSION_GET_MAJOR(_version) (((_version) >> 16) \
|
||||
& 0x7FFF)
|
||||
#define RMM_EL3_IFC_VERSION_GET_MAJOR_MINOR(_version) ((_version) & 0xFFFF)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -169,6 +169,7 @@ const mmap_region_t plat_arm_mmap[] = {
|
|||
#endif
|
||||
#if ENABLE_RME
|
||||
ARM_MAP_GPT_L1_DRAM,
|
||||
ARM_MAP_EL3_RMM_SHARED_MEM,
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
@ -512,3 +513,18 @@ int32_t plat_get_soc_revision(void)
|
|||
return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
|
||||
V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
|
||||
}
|
||||
|
||||
#if ENABLE_RME
|
||||
/*
|
||||
* Get a pointer to the RMM-EL3 Shared buffer and return it
|
||||
* through the pointer passed as parameter.
|
||||
*
|
||||
* This function returns the size of the shared buffer.
|
||||
*/
|
||||
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
|
||||
{
|
||||
*shared = (uintptr_t)RMM_SHARED_BASE;
|
||||
|
||||
return (size_t)RMM_SHARED_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -300,8 +300,8 @@ static uint8_t platform_token[] = {
|
|||
0xB0, 0x3A
|
||||
};
|
||||
|
||||
int plat_get_cca_attest_token(uintptr_t buf, size_t *len,
|
||||
uintptr_t hash, size_t hash_size)
|
||||
int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
|
||||
uintptr_t hash, size_t hash_size)
|
||||
{
|
||||
(void)hash;
|
||||
(void)hash_size;
|
||||
|
|
|
@ -19,7 +19,8 @@ static uint8_t sample_attest_priv_key[] = {
|
|||
0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
|
||||
};
|
||||
|
||||
int plat_get_cca_realm_attest_key(uintptr_t buf, size_t *len, unsigned int type)
|
||||
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
|
||||
unsigned int type)
|
||||
{
|
||||
assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
|
||||
|
||||
|
|
|
@ -127,11 +127,7 @@
|
|||
#if defined(IMAGE_BL31)
|
||||
# if SPM_MM
|
||||
# define PLAT_ARM_MMAP_ENTRIES 10
|
||||
# if ENABLE_RME
|
||||
# define MAX_XLAT_TABLES 11
|
||||
# else
|
||||
# define MAX_XLAT_TABLES 9
|
||||
# endif
|
||||
# define MAX_XLAT_TABLES 9
|
||||
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
|
||||
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
|
||||
# elif SPMC_AT_EL3
|
||||
|
|
|
@ -341,10 +341,6 @@ ifeq ($(filter 1,${BL2_AT_EL3} ${ARM_XLAT_TABLES_LIB_V1}),)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq (${ENABLE_RME},1)
|
||||
BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
|
||||
endif
|
||||
|
||||
ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
|
||||
ifeq (${ARCH},aarch32)
|
||||
BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -164,6 +164,14 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
|
|||
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
|
||||
#if ENABLE_RME
|
||||
/*
|
||||
* Populate entry point information for RMM.
|
||||
* Only PC needs to be set as other fields are determined by RMMD.
|
||||
*/
|
||||
rmm_image_ep_info.pc = RMM_BASE;
|
||||
#endif /* ENABLE_RME */
|
||||
|
||||
#else /* RESET_TO_BL31 */
|
||||
|
||||
/*
|
||||
|
|
|
@ -101,7 +101,7 @@ int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len, uint64_t
|
|||
print_challenge((uint8_t *)temp_buf, challenge_hash_len);
|
||||
|
||||
/* Get the platform token. */
|
||||
err = plat_get_cca_attest_token(va,
|
||||
err = plat_rmmd_get_cca_attest_token(va,
|
||||
buf_len, (uintptr_t)temp_buf, challenge_hash_len);
|
||||
|
||||
if (err != 0) {
|
||||
|
@ -152,7 +152,7 @@ int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
|
|||
}
|
||||
|
||||
/* Get the Realm attestation key. */
|
||||
err = plat_get_cca_realm_attest_key(va, buf_len, (unsigned int)ecc_curve);
|
||||
err = plat_rmmd_get_cca_realm_attest_key(va, buf_len, (unsigned int)ecc_curve);
|
||||
if (err != 0) {
|
||||
ERROR("Failed to get attestation key: %d.\n", err);
|
||||
err = RMMD_ERR_UNK;
|
||||
|
|
|
@ -32,6 +32,17 @@
|
|||
#include "rmmd_initial_context.h"
|
||||
#include "rmmd_private.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* RMM <-> EL3 shared buffer information.
|
||||
******************************************************************************/
|
||||
static size_t shared_buf_size;
|
||||
static uintptr_t shared_buf_base;
|
||||
|
||||
/*******************************************************************************
|
||||
* RMM boot failure flag
|
||||
******************************************************************************/
|
||||
static bool rmm_boot_failed;
|
||||
|
||||
/*******************************************************************************
|
||||
* RMM context information.
|
||||
******************************************************************************/
|
||||
|
@ -132,13 +143,10 @@ static void manage_extensions_realm(cpu_context_t *ctx)
|
|||
******************************************************************************/
|
||||
static int32_t rmm_init(void)
|
||||
{
|
||||
|
||||
uint64_t rc;
|
||||
|
||||
long rc;
|
||||
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
|
||||
|
||||
INFO("RMM init start.\n");
|
||||
ctx->state = RMM_STATE_RESET;
|
||||
|
||||
/* Enable architecture extensions */
|
||||
manage_extensions_realm(&ctx->cpu_ctx);
|
||||
|
@ -147,12 +155,13 @@ static int32_t rmm_init(void)
|
|||
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
|
||||
|
||||
rc = rmmd_rmm_sync_entry(ctx);
|
||||
if (rc != 0ULL) {
|
||||
ERROR("RMM initialisation failed 0x%" PRIx64 "\n", rc);
|
||||
panic();
|
||||
if (rc != E_RMM_BOOT_SUCCESS) {
|
||||
ERROR("RMM init failed: %ld\n", rc);
|
||||
/* Mark the boot as failed for all the CPUs */
|
||||
rmm_boot_failed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->state = RMM_STATE_IDLE;
|
||||
INFO("RMM init end.\n");
|
||||
|
||||
return 1;
|
||||
|
@ -192,6 +201,25 @@ int rmmd_setup(void)
|
|||
MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
|
||||
shared_buf_size =
|
||||
plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
|
||||
|
||||
assert((shared_buf_size == SZ_4K) &&
|
||||
((void *)shared_buf_base != NULL));
|
||||
|
||||
/*
|
||||
* Prepare coldboot arguments for RMM:
|
||||
* arg0: This CPUID (primary processor).
|
||||
* arg1: Version for this Boot Interface.
|
||||
* arg2: PLATFORM_CORE_COUNT.
|
||||
* arg3: Base address for the EL3 <-> RMM shared area. The boot
|
||||
* manifest will be stored at the beginning of this area.
|
||||
*/
|
||||
rmm_ep_info->args.arg0 = linear_id;
|
||||
rmm_ep_info->args.arg1 = RMM_EL3_INTERFACE_VERSION;
|
||||
rmm_ep_info->args.arg2 = PLATFORM_CORE_COUNT;
|
||||
rmm_ep_info->args.arg3 = shared_buf_base;
|
||||
|
||||
/* Initialise RMM context with this entry point information */
|
||||
cm_setup_context(&rmm_ctx->cpu_ctx, rmm_ep_info);
|
||||
|
||||
|
@ -244,9 +272,14 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
|||
uint64_t x3, uint64_t x4, void *cookie,
|
||||
void *handle, uint64_t flags)
|
||||
{
|
||||
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
|
||||
uint32_t src_sec_state;
|
||||
|
||||
/* If RMM failed to boot, treat any RMI SMC as unknown */
|
||||
if (rmm_boot_failed) {
|
||||
WARN("RMMD: Failed to boot up RMM. Ignoring RMI call\n");
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
}
|
||||
|
||||
/* Determine which security state this SMC originated from */
|
||||
src_sec_state = caller_sec_state(flags);
|
||||
|
||||
|
@ -272,11 +305,6 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
|||
|
||||
switch (smc_fid) {
|
||||
case RMMD_RMI_REQ_COMPLETE:
|
||||
if (ctx->state == RMM_STATE_RESET) {
|
||||
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
|
||||
rmmd_rmm_sync_exit(x1);
|
||||
}
|
||||
|
||||
return rmmd_smc_forward(REALM, NON_SECURE, x1,
|
||||
x2, x3, x4, 0, handle);
|
||||
|
||||
|
@ -293,11 +321,26 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
|||
******************************************************************************/
|
||||
static void *rmmd_cpu_on_finish_handler(const void *arg)
|
||||
{
|
||||
int32_t rc;
|
||||
long rc;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
rmmd_rmm_context_t *ctx = &rmm_context[linear_id];
|
||||
|
||||
ctx->state = RMM_STATE_RESET;
|
||||
if (rmm_boot_failed) {
|
||||
/* RMM Boot failed on a previous CPU. Abort. */
|
||||
ERROR("RMM Failed to initialize. Ignoring for CPU%d\n",
|
||||
linear_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare warmboot arguments for RMM:
|
||||
* arg0: This CPUID.
|
||||
* arg1 to arg3: Not used.
|
||||
*/
|
||||
rmm_ep_info->args.arg0 = linear_id;
|
||||
rmm_ep_info->args.arg1 = 0ULL;
|
||||
rmm_ep_info->args.arg2 = 0ULL;
|
||||
rmm_ep_info->args.arg3 = 0ULL;
|
||||
|
||||
/* Initialise RMM context with this entry point information */
|
||||
cm_setup_context(&ctx->cpu_ctx, rmm_ep_info);
|
||||
|
@ -309,13 +352,13 @@ static void *rmmd_cpu_on_finish_handler(const void *arg)
|
|||
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
|
||||
|
||||
rc = rmmd_rmm_sync_entry(ctx);
|
||||
if (rc != 0) {
|
||||
ERROR("RMM initialisation failed (%d) on CPU%d\n", rc,
|
||||
linear_id);
|
||||
panic();
|
||||
|
||||
if (rc != E_RMM_BOOT_SUCCESS) {
|
||||
ERROR("RMM init failed on CPU%d: %ld\n", linear_id, rc);
|
||||
/* Mark the boot as failed for any other booting CPU */
|
||||
rmm_boot_failed = true;
|
||||
}
|
||||
|
||||
ctx->state = RMM_STATE_IDLE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -354,6 +397,12 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
|||
uint32_t src_sec_state;
|
||||
int ret;
|
||||
|
||||
/* If RMM failed to boot, treat any RMM-EL3 interface SMC as unknown */
|
||||
if (rmm_boot_failed) {
|
||||
WARN("RMMD: Failed to boot up RMM. Ignoring RMM-EL3 call\n");
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
}
|
||||
|
||||
/* Determine which security state this SMC originated from */
|
||||
src_sec_state = caller_sec_state(flags);
|
||||
|
||||
|
@ -375,6 +424,11 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
|||
case RMMD_ATTEST_GET_REALM_KEY:
|
||||
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
|
||||
SMC_RET2(handle, ret, x2);
|
||||
|
||||
case RMM_BOOT_COMPLETE:
|
||||
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
|
||||
rmmd_rmm_sync_exit(x1);
|
||||
|
||||
default:
|
||||
WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum rmm_state {
|
||||
RMM_STATE_RESET = 0,
|
||||
RMM_STATE_IDLE
|
||||
} rmm_state_t;
|
||||
|
||||
/*
|
||||
* Data structure used by the RMM dispatcher (RMMD) in EL3 to track context of
|
||||
* the RMM at R-EL2.
|
||||
|
@ -44,7 +39,6 @@ typedef enum rmm_state {
|
|||
typedef struct rmmd_rmm_context {
|
||||
uint64_t c_rt_ctx;
|
||||
cpu_context_t cpu_ctx;
|
||||
rmm_state_t state;
|
||||
} rmmd_rmm_context_t;
|
||||
|
||||
/* Functions used to enter/exit the RMM synchronously */
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <asm_macros.S>
|
||||
#include <services/rmmd_svc.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include "trp_private.h"
|
||||
|
||||
.global trp_head
|
||||
|
@ -31,6 +33,28 @@
|
|||
* ---------------------------------------------
|
||||
*/
|
||||
trp_head:
|
||||
/*
|
||||
* Stash arguments from previous boot stage
|
||||
*/
|
||||
mov x20, x0
|
||||
mov x21, x1
|
||||
mov x22, x2
|
||||
mov x23, x3
|
||||
|
||||
/*
|
||||
* Validate CPUId before allocating a stack.
|
||||
*/
|
||||
cmp x20, #PLATFORM_CORE_COUNT
|
||||
b.lo 1f
|
||||
|
||||
mov_imm x0, RMM_BOOT_COMPLETE
|
||||
mov_imm x1, E_RMM_BOOT_CPU_ID_OUT_OF_RANGE
|
||||
smc #0
|
||||
|
||||
/* EL3 should never return back here, so panic if it does */
|
||||
b trp_panic
|
||||
|
||||
1:
|
||||
bl plat_set_my_stack
|
||||
|
||||
/*
|
||||
|
@ -45,7 +69,6 @@ trp_head:
|
|||
adr x2, cold_boot_flag
|
||||
str xzr, [x2]
|
||||
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Zero out BSS section
|
||||
* ---------------------------------------------
|
||||
|
@ -54,15 +77,21 @@ trp_head:
|
|||
ldr x1, =__BSS_SIZE__
|
||||
bl zeromem
|
||||
|
||||
mov x0, x20
|
||||
mov x1, x21
|
||||
mov x2, x22
|
||||
mov x3, x23
|
||||
bl trp_setup
|
||||
|
||||
bl trp_main
|
||||
warm_boot:
|
||||
mov_imm x0, RMMD_RMI_REQ_COMPLETE
|
||||
mov x1, xzr
|
||||
mov_imm x0, RMM_BOOT_COMPLETE
|
||||
mov x1, xzr /* RMM_BOOT_SUCCESS */
|
||||
smc #0
|
||||
b trp_handler
|
||||
|
||||
trp_panic:
|
||||
no_ret plat_panic_handler
|
||||
|
||||
/*
|
||||
* Flag to mark if it is a cold boot.
|
||||
* 1: cold boot, 0: warmboot.
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include <platform_def.h>
|
||||
#include "trp_private.h"
|
||||
|
||||
/* Parameters received from the previous image */
|
||||
static unsigned int trp_boot_abi_version;
|
||||
static uintptr_t trp_shared_region_start;
|
||||
|
||||
/*******************************************************************************
|
||||
* Per cpu data structure to populate parameters for an SMC in C code and use
|
||||
* a pointer to this structure in assembler code to populate x0-x7
|
||||
|
@ -52,11 +56,55 @@ static trp_args_t *set_smc_args(uint64_t arg0,
|
|||
return pcpu_smc_args;
|
||||
}
|
||||
|
||||
/*
|
||||
* Abort the boot process with the reason given in err.
|
||||
*/
|
||||
__dead2 static void trp_boot_abort(uint64_t err)
|
||||
{
|
||||
(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
|
||||
panic();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Setup function for TRP.
|
||||
******************************************************************************/
|
||||
void trp_setup(void)
|
||||
void trp_setup(uint64_t x0,
|
||||
uint64_t x1,
|
||||
uint64_t x2,
|
||||
uint64_t x3)
|
||||
{
|
||||
/*
|
||||
* Validate boot parameters.
|
||||
*
|
||||
* According to the Boot Interface ABI v.0.1, the
|
||||
* parameters recived from EL3 are:
|
||||
* x0: CPUID (verified earlier so not used)
|
||||
* x1: Boot Interface version
|
||||
* x2: PLATFORM_CORE_COUNT
|
||||
* x3: Pointer to the shared memory area.
|
||||
*/
|
||||
|
||||
(void)x0;
|
||||
|
||||
if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
|
||||
trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
|
||||
}
|
||||
|
||||
if ((void *)x3 == NULL) {
|
||||
trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
|
||||
}
|
||||
|
||||
if (x2 > TRP_PLATFORM_CORE_COUNT) {
|
||||
trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
|
||||
}
|
||||
|
||||
trp_boot_abi_version = x1;
|
||||
trp_shared_region_start = x3;
|
||||
flush_dcache_range((uintptr_t)&trp_boot_abi_version,
|
||||
sizeof(trp_boot_abi_version));
|
||||
flush_dcache_range((uintptr_t)&trp_shared_region_start,
|
||||
sizeof(trp_shared_region_start));
|
||||
|
||||
/* Perform early platform-specific setup */
|
||||
trp_early_platform_setup();
|
||||
}
|
||||
|
@ -66,9 +114,16 @@ void trp_main(void)
|
|||
{
|
||||
NOTICE("TRP: %s\n", version_string);
|
||||
NOTICE("TRP: %s\n", build_message);
|
||||
NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
|
||||
TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
|
||||
INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
|
||||
INFO("TRP: Base address for the shared region : 0x%lx\n",
|
||||
(unsigned long)trp_shared_region_start);
|
||||
INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END
|
||||
- RMM_BASE));
|
||||
INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
|
||||
TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
|
||||
TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef TRP_PRIVATE_H
|
||||
#define TRP_PRIVATE_H
|
||||
|
||||
#include <services/rmmd_svc.h>
|
||||
|
||||
/* Definitions to help the assembler access the SMC/ERET args structure */
|
||||
#define TRP_ARGS_SIZE TRP_ARGS_END
|
||||
#define TRP_ARG0 0x0
|
||||
|
@ -19,6 +21,14 @@
|
|||
#define TRP_ARG7 0x38
|
||||
#define TRP_ARGS_END 0x40
|
||||
|
||||
/* Definitions for RMM-EL3 Interface ABI VERSION */
|
||||
#define TRP_RMM_EL3_ABI_VERS_MAJOR RMM_EL3_IFC_VERSION_MAJOR
|
||||
#define TRP_RMM_EL3_ABI_VERS_MINOR RMM_EL3_IFC_VERSION_MINOR
|
||||
#define TRP_RMM_EL3_ABI_VERS (((TRP_RMM_EL3_ABI_VERS_MAJOR & 0x7FFF) << 16) | \
|
||||
(TRP_RMM_EL3_ABI_VERS_MINOR & 0xFFFF))
|
||||
|
||||
#define TRP_PLATFORM_CORE_COUNT PLATFORM_CORE_COUNT
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -38,8 +48,14 @@ typedef struct trp_args {
|
|||
/* Definitions for RMI VERSION */
|
||||
#define RMI_ABI_VERSION_MAJOR U(0x0)
|
||||
#define RMI_ABI_VERSION_MINOR U(0x0)
|
||||
#define RMI_ABI_VERSION ((RMI_ABI_VERSION_MAJOR << 16) | \
|
||||
RMI_ABI_VERSION_MINOR)
|
||||
#define RMI_ABI_VERSION (((RMI_ABI_VERSION_MAJOR & 0x7FFF) \
|
||||
<< 16) | \
|
||||
(RMI_ABI_VERSION_MINOR & 0xFFFF))
|
||||
|
||||
#define TRP_RMM_EL3_VERSION_GET_MAJOR(x) \
|
||||
RMM_EL3_IFC_VERSION_GET_MAJOR((x))
|
||||
#define TRP_RMM_EL3_VERSION_GET_MINOR(x) \
|
||||
RMM_EL3_IFC_VERSION_GET_MAJOR_MINOR((x))
|
||||
|
||||
/* Helper to issue SMC calls to BL31 */
|
||||
uint64_t trp_smc(trp_args_t *);
|
||||
|
@ -48,7 +64,10 @@ uint64_t trp_smc(trp_args_t *);
|
|||
void trp_main(void);
|
||||
|
||||
/* Setup TRP. Executed only by Primary CPU */
|
||||
void trp_setup(void);
|
||||
void trp_setup(uint64_t x0,
|
||||
uint64_t x1,
|
||||
uint64_t x2,
|
||||
uint64_t x3);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* TRP_PRIVATE_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue