aboutsummaryrefslogtreecommitdiff
path: root/plat/arm/common
diff options
context:
space:
mode:
Diffstat (limited to 'plat/arm/common')
-rw-r--r--plat/arm/common/aarch64/arm_bl2_mem_params_desc.c26
-rw-r--r--plat/arm/common/arm_bl1_fwu.c4
-rw-r--r--plat/arm/common/arm_bl1_setup.c13
-rw-r--r--plat/arm/common/arm_bl2_setup.c95
-rw-r--r--plat/arm/common/arm_bl31_setup.c78
-rw-r--r--plat/arm/common/arm_common.mk40
-rw-r--r--plat/arm/common/arm_dyn_cfg.c79
-rw-r--r--plat/arm/common/arm_dyn_cfg_helpers.c135
-rw-r--r--plat/arm/common/arm_image_load.c6
-rw-r--r--plat/arm/common/fconf/arm_fconf_io.c6
-rw-r--r--plat/arm/common/fconf/arm_fconf_sp.c17
-rw-r--r--plat/arm/common/fconf/fconf_ethosn_getter.c114
-rw-r--r--plat/arm/common/trp/arm_trp.mk10
-rw-r--r--plat/arm/common/trp/arm_trp_setup.c40
14 files changed, 436 insertions, 227 deletions
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index 6a8943d5d..0666e57fa 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -75,8 +75,10 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.image_info.image_base = BL31_BASE,
.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
-# ifdef BL32_BASE
+# if defined(BL32_BASE)
.next_handoff_image_id = BL32_IMAGE_ID,
+# elif ENABLE_RME
+ .next_handoff_image_id = RMM_IMAGE_ID,
# else
.next_handoff_image_id = BL33_IMAGE_ID,
# endif
@@ -99,6 +101,22 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
.next_handoff_image_id = INVALID_IMAGE_ID,
},
+
+# if ENABLE_RME
+ /* Fill RMM related information */
+ {
+ .image_id = RMM_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, EP_REALM | EXECUTABLE),
+ .ep_info.pc = RMM_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = RMM_BASE,
+ .image_info.image_max_size = RMM_LIMIT - RMM_BASE,
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+# endif
+
# ifdef BL32_BASE
/* Fill BL32 related information */
{
@@ -113,7 +131,11 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.image_info.image_base = BL32_BASE,
.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+# if ENABLE_RME
+ .next_handoff_image_id = RMM_IMAGE_ID,
+# else
.next_handoff_image_id = BL33_IMAGE_ID,
+# endif
},
/*
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
index 124c1af53..ce2c35699 100644
--- a/plat/arm/common/arm_bl1_fwu.c
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,8 @@
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#pragma weak bl1_plat_get_image_desc
+
/* Struct to keep track of usable memory */
typedef struct bl1_mem_info {
uintptr_t mem_base;
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 4b2a062f9..320bb8274 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,14 +22,17 @@
#pragma weak bl1_early_platform_setup
#pragma weak bl1_plat_arch_setup
#pragma weak bl1_plat_sec_mem_layout
+#pragma weak arm_bl1_early_platform_setup
#pragma weak bl1_plat_prepare_exit
#pragma weak bl1_plat_get_next_image_id
#pragma weak plat_arm_bl1_fwu_needed
+#pragma weak arm_bl1_plat_arch_setup
+#pragma weak arm_bl1_platform_setup
#define MAP_BL1_TOTAL MAP_REGION_FLAT( \
bl1_tzram_layout.total_base, \
bl1_tzram_layout.total_size, \
- MT_MEMORY | MT_RW | MT_SECURE)
+ MT_MEMORY | MT_RW | EL3_PAS)
/*
* If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
* otherwise one region is defined containing both
@@ -38,17 +41,17 @@
#define MAP_BL1_RO MAP_REGION_FLAT( \
BL_CODE_BASE, \
BL1_CODE_END - BL_CODE_BASE, \
- MT_CODE | MT_SECURE), \
+ MT_CODE | EL3_PAS), \
MAP_REGION_FLAT( \
BL1_RO_DATA_BASE, \
BL1_RO_DATA_END \
- BL_RO_DATA_BASE, \
- MT_RO_DATA | MT_SECURE)
+ MT_RO_DATA | EL3_PAS)
#else
#define MAP_BL1_RO MAP_REGION_FLAT( \
BL_CODE_BASE, \
BL1_CODE_END - BL_CODE_BASE, \
- MT_CODE | MT_SECURE)
+ MT_CODE | EL3_PAS)
#endif
/* Data structure which holds the extents of the trusted SRAM for BL1*/
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 26af38344..08c014d8e 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -9,6 +9,7 @@
#include <platform_def.h>
+#include <arch_features.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
@@ -17,10 +18,16 @@
#include <drivers/partition/partition.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#if ENABLE_RME
+#include <lib/gpt_rme/gpt_rme.h>
+#endif /* ENABLE_RME */
#ifdef SPD_opteed
#include <lib/optee_utils.h>
#endif
#include <lib/utils.h>
+#if ENABLE_RME
+#include <plat/arm/common/arm_pas_def.h>
+#endif /* ENABLE_RME */
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -41,15 +48,18 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
#pragma weak bl2_platform_setup
#pragma weak bl2_plat_arch_setup
#pragma weak bl2_plat_sec_mem_layout
-#if MEASURED_BOOT
-#pragma weak bl2_plat_get_hash
-#endif
+#if ENABLE_RME
+#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
+ bl2_tzram_layout.total_base, \
+ bl2_tzram_layout.total_size, \
+ MT_MEMORY | MT_RW | MT_ROOT)
+#else
#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
bl2_tzram_layout.total_base, \
bl2_tzram_layout.total_size, \
MT_MEMORY | MT_RW | MT_SECURE)
-
+#endif /* ENABLE_RME */
#pragma weak arm_bl2_plat_handle_post_image_load
@@ -105,8 +115,10 @@ void bl2_plat_preload_setup(void)
*/
void arm_bl2_platform_setup(void)
{
+#if !ENABLE_RME
/* Initialize the secure environment */
plat_arm_security_setup();
+#endif
#if defined(PLAT_ARM_MEM_PROT_ADDR)
arm_nor_psci_do_static_mem_protect();
@@ -118,9 +130,54 @@ void bl2_platform_setup(void)
arm_bl2_platform_setup();
}
+#if ENABLE_RME
+
+static void arm_bl2_plat_gpt_setup(void)
+{
+ /*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+ pas_region_t pas_regions[] = {
+ ARM_PAS_KERNEL,
+ ARM_PAS_SECURE,
+ ARM_PAS_REALM,
+ ARM_PAS_EL3_DRAM,
+ ARM_PAS_GPTS
+ };
+
+ /* Initialize entire protected space to GPT_GPI_ANY. */
+ if (gpt_init_l0_tables(GPCCR_PPS_4GB, ARM_L0_GPT_ADDR_BASE,
+ ARM_L0_GPT_SIZE) < 0) {
+ ERROR("gpt_init_l0_tables() failed!\n");
+ panic();
+ }
+
+ /* Carve out defined PAS ranges. */
+ if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
+ ARM_L1_GPT_ADDR_BASE,
+ ARM_L1_GPT_SIZE,
+ pas_regions,
+ (unsigned int)(sizeof(pas_regions) /
+ sizeof(pas_region_t))) < 0) {
+ ERROR("gpt_init_pas_l1_tables() failed!\n");
+ panic();
+ }
+
+ INFO("Enabling Granule Protection Checks\n");
+ if (gpt_enable() < 0) {
+ ERROR("gpt_enable() failed!\n");
+ panic();
+ }
+}
+
+#endif /* ENABLE_RME */
+
/*******************************************************************************
- * Perform the very early platform specific architectural setup here. At the
- * moment this is only initializes the mmu in a quick and dirty way.
+ * Perform the very early platform specific architectural setup here.
+ * When RME is enabled the secure environment is initialised before
+ * initialising and enabling Granule Protection.
+ * This function initialises the MMU in a quick and dirty way.
******************************************************************************/
void arm_bl2_plat_arch_setup(void)
{
@@ -143,13 +200,29 @@ void arm_bl2_plat_arch_setup(void)
ARM_MAP_BL_COHERENT_RAM,
#endif
ARM_MAP_BL_CONFIG_REGION,
+#if ENABLE_RME
+ ARM_MAP_L0_GPT_REGION,
+#endif
{0}
};
+#if ENABLE_RME
+ /* Initialise the secure environment */
+ plat_arm_security_setup();
+#endif
setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef __aarch64__
+#if ENABLE_RME
+ /* BL2 runs in EL3 when RME enabled. */
+ assert(get_armv9_2_feat_rme_support() != 0U);
+ enable_mmu_el3(0);
+
+ /* Initialise and enable granule protection after MMU. */
+ arm_bl2_plat_gpt_setup();
+#else
enable_mmu_el1(0);
+#endif
#else
enable_mmu_svc_mon(0);
#endif
@@ -233,7 +306,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id)
******************************************************************************/
int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
{
-#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD
/* For Secure Partitions we don't need post processing */
if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) &&
(image_id < MAX_NUMBER_IDS)) {
@@ -247,11 +320,3 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
{
return arm_bl2_plat_handle_post_image_load(image_id);
}
-
-#if MEASURED_BOOT
-/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */
-void bl2_plat_get_hash(void *data)
-{
- arm_bl2_get_hash(data);
-}
-#endif
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index b819888d3..a6f7df5f4 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,9 @@
#include <drivers/console.h>
#include <lib/debugfs.h>
#include <lib/extensions/ras.h>
+#if ENABLE_RME
+#include <lib/gpt_rme/gpt_rme.h>
+#endif
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@@ -25,6 +28,9 @@
*/
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
+#if ENABLE_RME
+static entry_point_info_t rmm_image_ep_info;
+#endif
#if !RESET_TO_BL31
/*
@@ -43,7 +49,7 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
#define MAP_BL31_TOTAL MAP_REGION_FLAT( \
BL31_START, \
BL31_END - BL31_START, \
- MT_MEMORY | MT_RW | MT_SECURE)
+ MT_MEMORY | MT_RW | EL3_PAS)
#if RECLAIM_INIT_CODE
IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
@@ -58,7 +64,7 @@ IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
BL_INIT_CODE_BASE, \
BL_INIT_CODE_END \
- BL_INIT_CODE_BASE, \
- MT_CODE | MT_SECURE)
+ MT_CODE | EL3_PAS)
#endif
#if SEPARATE_NOBITS_REGION
@@ -66,7 +72,7 @@ IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
BL31_NOBITS_BASE, \
BL31_NOBITS_LIMIT \
- BL31_NOBITS_BASE, \
- MT_MEMORY | MT_RW | MT_SECURE)
+ MT_MEMORY | MT_RW | EL3_PAS)
#endif
/*******************************************************************************
@@ -80,8 +86,18 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
entry_point_info_t *next_image_info;
assert(sec_state_is_valid(type));
- next_image_info = (type == NON_SECURE)
- ? &bl33_image_ep_info : &bl32_image_ep_info;
+ if (type == NON_SECURE) {
+ next_image_info = &bl33_image_ep_info;
+ }
+#if ENABLE_RME
+ else if (type == REALM) {
+ next_image_info = &rmm_image_ep_info;
+ }
+#endif
+ else {
+ next_image_info = &bl32_image_ep_info;
+ }
+
/*
* None of the images on the ARM development platforms can have 0x0
* as the entrypoint
@@ -169,21 +185,31 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
bl_params_node_t *bl_params = params_from_bl2->head;
/*
- * Copy BL33 and BL32 (if present), entry point information.
+ * Copy BL33, BL32 and RMM (if present), entry point information.
* They are stored in Secure RAM, in BL2's address space.
*/
while (bl_params != NULL) {
- if (bl_params->image_id == BL32_IMAGE_ID)
+ if (bl_params->image_id == BL32_IMAGE_ID) {
bl32_image_ep_info = *bl_params->ep_info;
-
- if (bl_params->image_id == BL33_IMAGE_ID)
+ }
+#if ENABLE_RME
+ else if (bl_params->image_id == RMM_IMAGE_ID) {
+ rmm_image_ep_info = *bl_params->ep_info;
+ }
+#endif
+ else if (bl_params->image_id == BL33_IMAGE_ID) {
bl33_image_ep_info = *bl_params->ep_info;
+ }
bl_params = bl_params->next_params_info;
}
if (bl33_image_ep_info.pc == 0U)
panic();
+#if ENABLE_RME
+ if (rmm_image_ep_info.pc == 0U)
+ panic();
+#endif
#endif /* RESET_TO_BL31 */
# if ARM_LINUX_KERNEL_AS_BL33
@@ -192,20 +218,20 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
* Linux kernel tree, Linux expects the physical address of the device
* tree blob (DTB) in x0, while x1-x3 are reserved for future use and
* must be 0.
+ * Repurpose the option to load Hafnium hypervisor in the normal world.
+ * It expects its manifest address in x0. This is essentially the linux
+ * dts (passed to the primary VM) by adding 'hypervisor' and chosen
+ * nodes specifying the Hypervisor configuration.
*/
+#if RESET_TO_BL31
bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+#else
+ bl33_image_ep_info.args.arg0 = (u_register_t)hw_config;
+#endif
bl33_image_ep_info.args.arg1 = 0U;
bl33_image_ep_info.args.arg2 = 0U;
bl33_image_ep_info.args.arg3 = 0U;
# endif
-
-#if defined(SPD_spmd)
- /*
- * Hafnium in normal world expects its manifest address in x0, In CI
- * configuration manifest is preloaded at 0x80000000(start of DRAM).
- */
- bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE;
-#endif
}
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
@@ -355,6 +381,9 @@ void __init arm_bl31_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
MAP_BL31_TOTAL,
+#if ENABLE_RME
+ ARM_MAP_L0_GPT_REGION,
+#endif
#if RECLAIM_INIT_CODE
MAP_BL_INIT_CODE,
#endif
@@ -376,6 +405,19 @@ void __init arm_bl31_plat_arch_setup(void)
enable_mmu_el3(0);
+#if ENABLE_RME
+ /*
+ * Initialise Granule Protection library and enable GPC for the primary
+ * processor. The tables have already been initialized by a previous BL
+ * stage, so there is no need to provide any PAS here. This function
+ * sets up pointers to those tables.
+ */
+ if (gpt_runtime_init() < 0) {
+ ERROR("gpt_runtime_init() failed!\n");
+ panic();
+ }
+#endif /* ENABLE_RME */
+
arm_setup_romlib();
}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 4d5e8b4b1..78efb0f90 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -4,6 +4,8 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+include common/fdt_wrappers.mk
+
ifeq (${ARCH}, aarch64)
# On ARM standard platorms, the TSP can execute from Trusted SRAM, Trusted
# DRAM (if available) or the TZC secured area of DRAM.
@@ -52,9 +54,10 @@ $(eval $(call assert_boolean,ARM_RECOM_STATE_ID_ENC))
$(eval $(call add_define,ARM_RECOM_STATE_ID_ENC))
# Process ARM_DISABLE_TRUSTED_WDOG flag
-# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
+# By default, Trusted Watchdog is always enabled unless
+# SPIN_ON_BL1_EXIT or ENABLE_RME is set
ARM_DISABLE_TRUSTED_WDOG := 0
-ifeq (${SPIN_ON_BL1_EXIT}, 1)
+ifneq ($(filter 1,${SPIN_ON_BL1_EXIT} ${ENABLE_RME}),)
ARM_DISABLE_TRUSTED_WDOG := 1
endif
$(eval $(call assert_boolean,ARM_DISABLE_TRUSTED_WDOG))
@@ -94,10 +97,13 @@ ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
ifndef PRELOADED_BL33_BASE
$(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
endif
- ifndef ARM_PRELOADED_DTB_BASE
- $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+ ifeq (${RESET_TO_BL31},1)
+ ifndef ARM_PRELOADED_DTB_BASE
+ $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is
+ used with RESET_TO_BL31.")
+ endif
+ $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
endif
- $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
endif
# Arm Ethos-N NPU SiP service
@@ -206,18 +212,22 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/${ARCH}/arm_helpers.S \
plat/arm/common/arm_console.c
ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
+PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/${ARCH}/xlat_tables.c
else
+ifeq (${XLAT_MPU_LIB_V1}, 1)
+include lib/xlat_mpu/xlat_mpu.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_MPU_LIB_V1_SRCS}
+else
include lib/xlat_tables_v2/xlat_tables.mk
-
-PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+endif
endif
ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \
plat/arm/common/fconf/arm_fconf_io.c
ifeq (${SPD},spmd)
- ifeq (${SPMD_SPM_AT_SEL2},1)
+ ifeq (${BL2_ENABLE_SP_LOAD},1)
ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c
endif
endif
@@ -248,14 +258,18 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
# Firmware Configuration Framework sources
include lib/fconf/fconf.mk
+BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
+BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
+
# Add `libfdt` and Arm common helpers required for Dynamic Config
include lib/libfdt/libfdt.mk
DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \
plat/arm/common/arm_dyn_cfg_helpers.c \
- common/fdt_wrappers.c \
common/uuid.c
+DYN_CFG_SOURCES += ${FDT_WRAPPERS_SOURCES}
+
BL1_SOURCES += ${DYN_CFG_SOURCES}
BL2_SOURCES += ${DYN_CFG_SOURCES}
@@ -335,10 +349,10 @@ endif
ifeq (${SPD},spmd)
BL31_SOURCES += plat/common/plat_spmd_manifest.c \
- common/fdt_wrappers.c \
common/uuid.c \
${LIBFDT_SRCS}
+BL31_SOURCES += ${FDT_WRAPPERS_SOURCES}
endif
ifneq (${TRUSTED_BOARD_BOOT},0)
@@ -351,7 +365,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
# Include the selected chain of trust sources.
ifeq (${COT},tbbr)
- BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
+ BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \
drivers/auth/tbbr/tbbr_cot_bl1.c
ifneq (${COT_DESC_IN_DTB},0)
BL2_SOURCES += lib/fconf/fconf_cot_getter.c
@@ -398,7 +412,7 @@ ifeq (${RECLAIM_INIT_CODE}, 1)
endif
ifeq (${MEASURED_BOOT},1)
- MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk
+ MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
$(info Including ${MEASURED_BOOT_MK})
include ${MEASURED_BOOT_MK}
endif
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 30473be31..6aae9ae59 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,10 +15,6 @@
#include <common/tbbr/tbbr_img_def.h>
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
-#if MEASURED_BOOT
-#include <drivers/auth/crypto_mod.h>
-#include <mbedtls/md.h>
-#endif
#endif
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
@@ -115,82 +111,13 @@ void arm_bl1_set_mbedtls_heap(void)
* images. It's critical because BL2 won't be able to proceed
* without the heap info.
*
- * In MEASURED_BOOT case flushing is done in
- * arm_bl1_set_bl2_hash() function which is called after heap
- * information is written in the DTB.
+ * In MEASURED_BOOT case flushing is done in a function which
+ * is called after heap information is written in the DTB.
*/
flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb));
#endif /* !MEASURED_BOOT */
}
}
-
-#if MEASURED_BOOT
-/*
- * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB.
- * Executed only from BL1.
- */
-void arm_bl1_set_bl2_hash(const image_desc_t *image_desc)
-{
- unsigned char hash_data[MBEDTLS_MD_MAX_SIZE];
- const image_info_t image_info = image_desc->image_info;
- uintptr_t tb_fw_cfg_dtb;
- int err;
- const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
-
- tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
- assert(tb_fw_config_info != NULL);
-
- tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
-
- /*
- * If tb_fw_cfg_dtb==NULL then DTB is not present for the current
- * platform. As such, we cannot write to the DTB at all and pass
- * measured data.
- */
- if (tb_fw_cfg_dtb == 0UL) {
- panic();
- }
-
- /* Calculate hash */
- err = crypto_mod_calc_hash(MBEDTLS_MD_ID,
- (void *)image_info.image_base,
- image_info.image_size, hash_data);
- if (err != 0) {
- ERROR("%scalculate%s\n", "BL1: unable to ",
- " BL2 hash");
- panic();
- }
-
- err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data);
- if (err < 0) {
- ERROR("%swrite%sdata%s\n", "BL1: unable to ",
- " BL2 hash ", "to DTB\n");
- panic();
- }
-
- /*
- * Ensure that the info written to the DTB is visible to other
- * images. It's critical because BL2 won't be able to proceed
- * without the heap info and its hash data.
- */
- flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize((void *)tb_fw_cfg_dtb));
-}
-
-/*
- * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB.
- * Executed only from BL2.
- */
-void arm_bl2_get_hash(void *data)
-{
- const void *bl2_hash;
-
- assert(data != NULL);
-
- /* Retrieve TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB */
- bl2_hash = FCONF_GET_PROPERTY(tbbr, dyn_config, bl2_hash_data);
- (void)memcpy(data, bl2_hash, TCG_DIGEST_SIZE);
-}
-#endif /* MEASURED_BOOT */
#endif /* TRUSTED_BOARD_BOOT */
/*
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 5f20c8d48..6a2a6f89a 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -11,6 +11,8 @@
#endif
#include <common/fdt_wrappers.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <libfdt.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
@@ -20,18 +22,15 @@
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
#if MEASURED_BOOT
-#define DTB_PROP_BL2_HASH_DATA "bl2_hash_data"
#ifdef SPD_opteed
/*
* Currently OP-TEE does not support reading DTBs from Secure memory
* and this property should be removed when this feature is supported.
*/
#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr"
-#endif
+#endif /* SPD_opteed */
#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr"
#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size"
-
-static int dtb_root = -1;
#endif /* MEASURED_BOOT */
/*******************************************************************************
@@ -81,9 +80,8 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
*/
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
{
-#if !MEASURED_BOOT
int dtb_root;
-#endif
+
/*
* Verify that the DTB is valid, before attempting to write to it,
* and get the DTB root node.
@@ -123,32 +121,8 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
#if MEASURED_BOOT
/*
- * This function writes the BL2 hash data in HW_FW_CONFIG DTB.
- * When it is called, it is guaranteed that a DTB is available.
- *
- * This function is supposed to be called only by BL1.
- *
- * Returns:
- * 0 = success
- * < 0 = error
- */
-int arm_set_bl2_hash_info(void *dtb, void *data)
-{
- assert(dtb_root >= 0);
-
- /*
- * Write the BL2 hash data in the DTB.
- */
- return fdtw_write_inplace_bytes(dtb, dtb_root,
- DTB_PROP_BL2_HASH_DATA,
- TCG_DIGEST_SIZE, data);
-}
-
-/*
* Write the Event Log address and its size in the DTB.
*
- * This function is supposed to be called only by BL2.
- *
* Returns:
* 0 = success
* < 0 = error
@@ -231,14 +205,20 @@ static int arm_set_event_log_info(uintptr_t config_base,
* 0 = success
* < 0 = error
*/
-int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
- size_t log_size)
+int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size)
{
+ uintptr_t config_base;
+ const bl_mem_params_node_t *cfg_mem_params;
int err;
- assert(config_base != 0UL);
assert(log_addr != 0UL);
+ /* Get the config load address and size of TOS_FW_CONFIG */
+ cfg_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+ assert(cfg_mem_params != NULL);
+
+ config_base = cfg_mem_params->image_info.image_base;
+
/* Write the Event Log address and its size in the DTB */
err = arm_set_event_log_info(config_base,
#ifdef SPD_opteed
@@ -263,23 +243,25 @@ int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
* 0 = success
* < 0 = error
*/
-int arm_set_nt_fw_info(uintptr_t config_base,
+int arm_set_nt_fw_info(
#ifdef SPD_opteed
uintptr_t log_addr,
#endif
size_t log_size, uintptr_t *ns_log_addr)
{
+ uintptr_t config_base;
uintptr_t ns_addr;
const bl_mem_params_node_t *cfg_mem_params;
int err;
- assert(config_base != 0UL);
assert(ns_log_addr != NULL);
/* Get the config load address and size from NT_FW_CONFIG */
cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
assert(cfg_mem_params != NULL);
+ config_base = cfg_mem_params->image_info.image_base;
+
/* Calculate Event Log address in Non-secure memory */
ns_addr = cfg_mem_params->image_info.image_base +
cfg_mem_params->image_info.image_max_size;
@@ -300,4 +282,87 @@ int arm_set_nt_fw_info(uintptr_t config_base,
*ns_log_addr = (err < 0) ? 0UL : ns_addr;
return err;
}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size)
+{
+ /*
+ * Read tb_fw_config device tree for Event Log properties
+ * and write the Event Log address and its size in the DTB
+ */
+ const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+ uintptr_t tb_fw_cfg_dtb;
+ int err;
+
+ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+ assert(tb_fw_config_info != NULL);
+
+ tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
+
+ err = arm_set_event_log_info(tb_fw_cfg_dtb,
+#ifdef SPD_opteed
+ 0UL,
+#endif
+ log_addr, log_size);
+ return err;
+}
+
+/*
+ * This function reads the Event Log address and its size
+ * properties present in TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ * Alongside returns Event Log address and its size.
+ */
+
+int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size)
+{
+ /* As libfdt uses void *, we can't avoid this cast */
+ const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+ int node, rc;
+
+ tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+ assert(tb_fw_config_info != NULL);
+
+ void *dtb = (void *)tb_fw_config_info->config_addr;
+ const char *compatible = "arm,tpm_event_log";
+
+ /* Assert the node offset point to compatible property */
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+ if (node < 0) {
+ WARN("The compatible property '%s'%s", compatible,
+ " not specified in TB_FW config.\n");
+ return node;
+ }
+
+ VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+ rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr);
+ if (rc != 0) {
+ ERROR("%s%s", DTB_PROP_HW_LOG_ADDR,
+ " not specified in TB_FW config.\n");
+ return rc;
+ }
+
+ rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size);
+ if (rc != 0) {
+ ERROR("%s%s", DTB_PROP_HW_LOG_SIZE,
+ " not specified in TB_FW config.\n");
+ }
+
+ return rc;
+}
#endif /* MEASURED_BOOT */
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index ebf6dfff8..c411c6cbb 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,7 +32,7 @@ void plat_flush_next_bl_params(void)
next_bl_params_cpy_ptr);
}
-#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD
/*******************************************************************************
* This function appends Secure Partitions to list of loadable images.
******************************************************************************/
@@ -76,7 +76,7 @@ static void plat_add_sp_images_load_info(struct bl_load_info *load_info)
******************************************************************************/
struct bl_load_info *plat_get_bl_image_load_info(void)
{
-#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD
bl_load_info_t *bl_load_info;
bl_load_info = get_bl_load_info_from_mem_params_desc();
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 86fd6d565..aea2f38d4 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -67,6 +67,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = {
[SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG},
[TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG},
[NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG},
+ [RMM_IMAGE_ID] = {UUID_REALM_MONITOR_MGMT_FIRMWARE},
#endif /* ARM_IO_IN_DTB */
#if TRUSTED_BOARD_BOOT
[TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
@@ -162,6 +163,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
(uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID],
open_fip
},
+ [RMM_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[RMM_IMAGE_ID],
+ open_fip
+ },
[HW_CONFIG_ID] = {
&fip_dev_handle,
(uintptr_t)&arm_uuid_spec[HW_CONFIG_ID],
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
index 552393c9b..95e08730c 100644
--- a/plat/arm/common/fconf/arm_fconf_sp.c
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -66,6 +66,15 @@ int fconf_populate_arm_sp(uintptr_t config)
}
arm_sp.uuids[index] = uuid_helper;
+
+ /* Read Load address */
+ err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
+ if (err < 0) {
+ ERROR("FCONF: cannot read SP load address\n");
+ return -1;
+ }
+ arm_sp.load_addr[index] = val32;
+
VERBOSE("FCONF: %s UUID"
" %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
" load_addr=%lx\n",
@@ -82,14 +91,6 @@ int fconf_populate_arm_sp(uintptr_t config)
uuid_helper.uuid_struct.node[4], uuid_helper.uuid_struct.node[5],
arm_sp.load_addr[index]);
- /* Read Load address */
- err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
- if (err < 0) {
- ERROR("FCONF: cannot read SP load address\n");
- return -1;
- }
- arm_sp.load_addr[index] = val32;
-
/* Read owner field only for dualroot CoT */
#if defined(ARM_COT_dualroot)
/* Owner is an optional field, no need to catch error */
diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 1ba9f3a23..0af1a20fb 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.c
@@ -12,7 +12,7 @@
#include <libfdt.h>
#include <plat/arm/common/fconf_ethosn_getter.h>
-struct ethosn_config_t ethosn_config;
+struct ethosn_config_t ethosn_config = {.num_cores = 0};
static uint8_t fdt_node_get_status(const void *fdt, int node)
{
@@ -33,74 +33,86 @@ static uint8_t fdt_node_get_status(const void *fdt, int node)
int fconf_populate_ethosn_config(uintptr_t config)
{
int ethosn_node;
- int sub_node;
- uint8_t ethosn_status;
- uint32_t core_count = 0U;
- uint32_t core_addr_idx = 0U;
const void *hw_conf_dtb = (const void *)config;
/* Find offset to node with 'ethosn' compatible property */
- ethosn_node = fdt_node_offset_by_compatible(hw_conf_dtb, -1, "ethosn");
- if (ethosn_node < 0) {
- ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n");
- return ethosn_node;
- }
-
- /* If the Arm Ethos-N NPU is disabled the core check can be skipped */
- ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
- if (ethosn_status == ETHOSN_STATUS_DISABLED) {
- return 0;
- }
+ INFO("Probing Arm Ethos-N NPU\n");
+ uint32_t total_core_count = 0U;
- fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
- int err;
- uintptr_t addr;
- uint8_t status;
+ fdt_for_each_compatible_node(hw_conf_dtb, ethosn_node, "ethosn") {
+ int sub_node;
+ uint8_t ethosn_status;
+ uint32_t device_core_count = 0U;
- /* Check that the sub node is "ethosn-core" compatible */
- if (fdt_node_check_compatible(hw_conf_dtb, sub_node,
- "ethosn-core") != 0) {
- /* Ignore incompatible sub node */
+ /* If the Arm Ethos-N NPU is disabled the core check can be skipped */
+ ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
+ if (ethosn_status == ETHOSN_STATUS_DISABLED) {
continue;
}
- /* Including disabled cores */
- if (core_addr_idx >= ETHOSN_CORE_NUM_MAX) {
- ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n");
- return -1;
+ fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
+ int err;
+ uintptr_t core_addr;
+ uint8_t core_status;
+
+ if (total_core_count >= ETHOSN_CORE_NUM_MAX) {
+ ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n");
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+
+ /* Check that the sub node is "ethosn-core" compatible */
+ if (fdt_node_check_compatible(hw_conf_dtb,
+ sub_node,
+ "ethosn-core") != 0) {
+ /* Ignore incompatible sub node */
+ continue;
+ }
+
+ core_status = fdt_node_get_status(hw_conf_dtb, sub_node);
+ if (core_status == ETHOSN_STATUS_DISABLED) {
+ continue;
+ }
+
+ err = fdt_get_reg_props_by_index(hw_conf_dtb,
+ ethosn_node,
+ device_core_count,
+ &core_addr,
+ NULL);
+ if (err < 0) {
+ ERROR(
+ "FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n",
+ device_core_count);
+ return err;
+ }
+
+ INFO("NPU core probed at address 0x%lx\n", core_addr);
+ ethosn_config.core[total_core_count].addr = core_addr;
+ total_core_count++;
+ device_core_count++;
}
- status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
- if (status == ETHOSN_STATUS_DISABLED) {
- ++core_addr_idx;
- continue;
+ if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
+ ERROR("FCONF: Failed to parse sub nodes\n");
+ return -FDT_ERR_BADSTRUCTURE;
}
- err = fdt_get_reg_props_by_index(hw_conf_dtb, ethosn_node,
- core_addr_idx, &addr, NULL);
- if (err < 0) {
- ERROR("FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n",
- core_addr_idx);
- return err;
+ if (device_core_count == 0U) {
+ ERROR(
+ "FCONF: Enabled Arm Ethos-N NPU device must have at least one enabled core\n");
+ return -FDT_ERR_BADSTRUCTURE;
}
-
- ethosn_config.core_addr[core_count++] = addr;
- ++core_addr_idx;
}
- if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
- ERROR("FCONF: Failed to parse sub nodes\n");
- return sub_node;
+ if (total_core_count == 0U) {
+ ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n");
+ return -FDT_ERR_BADSTRUCTURE;
}
- /* The Arm Ethos-N NPU can't be used if no cores were found */
- if (core_count == 0) {
- ERROR("FCONF: No Arm Ethos-N NPU cores found\n");
- return -1;
- }
+ ethosn_config.num_cores = total_core_count;
- ethosn_config.num_cores = core_count;
- ethosn_config.status = ethosn_status;
+ INFO("%d NPU core%s probed\n",
+ ethosn_config.num_cores,
+ ethosn_config.num_cores > 1 ? "s" : "");
return 0;
}
diff --git a/plat/arm/common/trp/arm_trp.mk b/plat/arm/common/trp/arm_trp.mk
new file mode 100644
index 000000000..997111f99
--- /dev/null
+++ b/plat/arm/common/trp/arm_trp.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TRP source files common to ARM standard platforms
+RMM_SOURCES += plat/arm/common/trp/arm_trp_setup.c \
+ plat/arm/common/arm_topology.c \
+ plat/common/aarch64/platform_mp_stack.S
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
new file mode 100644
index 000000000..8e4829344
--- /dev/null
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Initialize the UART
+ ******************************************************************************/
+static console_t arm_trp_runtime_console;
+
+void arm_trp_early_platform_setup(void)
+{
+ /*
+ * Initialize a different console than already in use to display
+ * messages from trp
+ */
+ int rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
+ PLAT_ARM_TRP_UART_CLK_IN_HZ,
+ ARM_CONSOLE_BAUDRATE,
+ &arm_trp_runtime_console);
+ if (rc == 0) {
+ panic();
+ }
+
+ console_set_scope(&arm_trp_runtime_console,
+ CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+}
+
+void trp_early_platform_setup(void)
+{
+ arm_trp_early_platform_setup();
+}