diff options
Diffstat (limited to 'plat/arm/common')
-rw-r--r-- | plat/arm/common/aarch64/arm_bl2_mem_params_desc.c | 26 | ||||
-rw-r--r-- | plat/arm/common/arm_bl1_fwu.c | 4 | ||||
-rw-r--r-- | plat/arm/common/arm_bl1_setup.c | 13 | ||||
-rw-r--r-- | plat/arm/common/arm_bl2_setup.c | 95 | ||||
-rw-r--r-- | plat/arm/common/arm_bl31_setup.c | 78 | ||||
-rw-r--r-- | plat/arm/common/arm_common.mk | 40 | ||||
-rw-r--r-- | plat/arm/common/arm_dyn_cfg.c | 79 | ||||
-rw-r--r-- | plat/arm/common/arm_dyn_cfg_helpers.c | 135 | ||||
-rw-r--r-- | plat/arm/common/arm_image_load.c | 6 | ||||
-rw-r--r-- | plat/arm/common/fconf/arm_fconf_io.c | 6 | ||||
-rw-r--r-- | plat/arm/common/fconf/arm_fconf_sp.c | 17 | ||||
-rw-r--r-- | plat/arm/common/fconf/fconf_ethosn_getter.c | 114 | ||||
-rw-r--r-- | plat/arm/common/trp/arm_trp.mk | 10 | ||||
-rw-r--r-- | plat/arm/common/trp/arm_trp_setup.c | 40 |
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(); +} |