diff options
Diffstat (limited to 'plat/arm/common')
27 files changed, 1522 insertions, 653 deletions
diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c index 7aeeb2aed..78360b06c 100644 --- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include <common/bl_common.h> #include <common/desc_image_load.h> -#include <plat/common/platform.h> /******************************************************************************* * Following descriptor provides BL image/ep information that gets used diff --git a/plat/arm/common/aarch32/arm_helpers.S b/plat/arm/common/aarch32/arm_helpers.S index badddd3a9..1da2d4cad 100644 --- a/plat/arm/common/aarch32/arm_helpers.S +++ b/plat/arm/common/aarch32/arm_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -64,10 +64,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ 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 0514b3994..6a8943d5d 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-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,6 @@ #include <common/bl_common.h> #include <common/desc_image_load.h> -#include <plat/common/platform.h> /******************************************************************************* * Following descriptor provides BL image/ep information that gets used diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c deleted file mode 100644 index 69ebd798f..000000000 --- a/plat/arm/common/aarch64/arm_ehf.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <platform_def.h> - -#include <bl31/ehf.h> - -/* - * Enumeration of priority levels on ARM platforms. - */ -ehf_pri_desc_t arm_exceptions[] = { -#if RAS_EXTENSION - /* RAS Priority */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_RAS_PRI), -#endif - -#if SDEI_SUPPORT - /* Critical priority SDEI */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_CRITICAL_PRI), - - /* Normal priority SDEI */ - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI), -#endif -#if SPM_MM - EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI), -#endif -}; - -/* Plug in ARM exceptions to Exception Handling Framework. */ -EHF_REGISTER_PRIORITIES(arm_exceptions, ARRAY_SIZE(arm_exceptions), ARM_PRI_BITS); diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S index 06720589a..b47078173 100644 --- a/plat/arm/common/aarch64/arm_helpers.S +++ b/plat/arm/common/aarch64/arm_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -66,10 +66,10 @@ func plat_crash_console_putc endfunc plat_crash_console_putc /* --------------------------------------------- - * int plat_crash_console_flush() + * void plat_crash_console_flush() * Function to force a write of all buffered * data that hasn't been output. - * Out : return -1 on error else return 0. + * Out : void. * Clobber list : r0 * --------------------------------------------- */ diff --git a/plat/arm/common/aarch64/arm_sdei.c b/plat/arm/common/aarch64/arm_sdei.c index 493134b6a..3c74a465c 100644 --- a/plat/arm/common/aarch64/arm_sdei.c +++ b/plat/arm/common/aarch64/arm_sdei.c @@ -1,16 +1,51 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ /* SDEI configuration for ARM platforms */ -#include <platform_def.h> - #include <bl31/ehf.h> +#include <common/debug.h> #include <services/sdei.h> +#if SDEI_IN_FCONF +#include <plat/arm/common/fconf_sdei_getter.h> +#endif +#include <plat/common/platform.h> +#include <platform_def.h> + + +#if SDEI_IN_FCONF +/* Private event mappings */ +static sdei_ev_map_t arm_sdei_private[PLAT_SDEI_DP_EVENT_MAX_CNT + 1] = { 0 }; + +/* Shared event mappings */ +static sdei_ev_map_t arm_sdei_shared[PLAT_SDEI_DS_EVENT_MAX_CNT] = { 0 }; + +void plat_sdei_setup(void) +{ + uint32_t i; + + arm_sdei_private[0] = (sdei_ev_map_t)SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI); + + for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_cnt); i++) { + arm_sdei_private[i + 1] = (sdei_ev_map_t)SDEI_PRIVATE_EVENT( + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_nums[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_intrs[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, private_ev_flags[i])); + } + + for (i = 0; i < FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_cnt); i++) { + arm_sdei_shared[i] = (sdei_ev_map_t)SDEI_SHARED_EVENT( \ + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_nums[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_intrs[i]), + FCONF_GET_PROPERTY(sdei, dyn_config, shared_ev_flags[i])); + } + INFO("FCONF: SDEI platform setup\n"); +} +#else /* Private event mappings */ static sdei_ev_map_t arm_sdei_private[] = { PLAT_ARM_PRIVATE_SDEI_EVENTS @@ -21,5 +56,11 @@ static sdei_ev_map_t arm_sdei_shared[] = { PLAT_ARM_SHARED_SDEI_EVENTS }; +void plat_sdei_setup(void) +{ + INFO("SDEI platform setup\n"); +} +#endif /* SDEI_IN_FCONF */ + /* Export ARM SDEI events */ REGISTER_SDEI_MAP(arm_sdei_private, arm_sdei_shared); diff --git a/plat/arm/common/aarch64/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c index 8835fa135..bed929a9c 100644 --- a/plat/arm/common/aarch64/execution_state_switch.c +++ b/plat/arm/common/aarch64/execution_state_switch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,7 +12,6 @@ #include <lib/el3_runtime/context_mgmt.h> #include <lib/psci/psci.h> #include <lib/utils.h> -#include <plat/arm/common/arm_sip_svc.h> #include <plat/arm/common/plat_arm.h> #include <smccc_helpers.h> diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index b19a7c39c..4b2a062f9 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,8 @@ #include <arch.h> #include <bl1/bl1.h> #include <common/bl_common.h> +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #include <lib/utils.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/plat_arm.h> @@ -52,6 +54,9 @@ /* Data structure which holds the extents of the trusted SRAM for BL1*/ static meminfo_t bl1_tzram_layout; +/* Boolean variable to hold condition whether firmware update needed or not */ +static bool is_fwu_needed; + struct meminfo *bl1_plat_sec_mem_layout(void) { return &bl1_tzram_layout; @@ -141,9 +146,59 @@ void bl1_plat_arch_setup(void) */ void arm_bl1_platform_setup(void) { + const struct dyn_cfg_dtb_info_t *fw_config_info; + image_desc_t *desc; + uint32_t fw_config_max_size; + int err = -1; + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - arm_load_tb_fw_config(); + + /* Check if we need FWU before further processing */ + is_fwu_needed = plat_arm_bl1_fwu_needed(); + if (is_fwu_needed) { + ERROR("Skip platform setup as FWU detected\n"); + return; + } + + /* Set global DTB info for fixed fw_config information */ + fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; + set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID); + + /* Fill the device tree information struct with the info from the config dtb */ + err = fconf_load_config(FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + + /* + * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing + * is successful then load TB_FW_CONFIG device tree. + */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + if (fw_config_info != NULL) { + err = fconf_populate_dtb_registry(fw_config_info->config_addr); + if (err < 0) { + ERROR("Parsing of FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + /* load TB_FW_CONFIG */ + err = fconf_load_config(TB_FW_CONFIG_ID); + if (err < 0) { + ERROR("Loading of TB_FW_CONFIG failed %d\n", err); + plat_error_handler(err); + } + } else { + ERROR("Invalid FW_CONFIG address\n"); + plat_error_handler(err); + } + + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + desc->ep_info.args.arg0 = fw_config_info->config_addr; + #if TRUSTED_BOARD_BOOT /* Share the Mbed TLS heap info with other images */ arm_bl1_set_mbedtls_heap(); @@ -184,9 +239,9 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info) * On Arm platforms, the FWU process is triggered when the FIP image has * been tampered with. */ -int plat_arm_bl1_fwu_needed(void) +bool plat_arm_bl1_fwu_needed(void) { - return (arm_io_is_toc_valid() != 1); + return !arm_io_is_toc_valid(); } /******************************************************************************* @@ -195,8 +250,5 @@ int plat_arm_bl1_fwu_needed(void) ******************************************************************************/ unsigned int bl1_plat_get_next_image_id(void) { - if (plat_arm_bl1_fwu_needed() != 0) - return NS_BL1U_IMAGE_ID; - - return BL2_IMAGE_ID; + return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; } diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index cdf87ca55..c90e93cd8 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,8 @@ #include <common/debug.h> #include <common/desc_image_load.h> #include <drivers/generic_delay_timer.h> +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> #ifdef SPD_opteed #include <lib/optee_utils.h> #endif @@ -24,17 +26,23 @@ /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); +/* Base address of fw_config received from BL1 */ +static uintptr_t config_base; + /* - * Check that BL2_BASE is above ARM_TB_FW_CONFIG_LIMIT. This reserved page is + * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is * for `meminfo_t` data structure and fw_configs passed from BL1. */ -CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); +CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl2_early_platform_setup2 #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 #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ bl2_tzram_layout.total_base, \ @@ -49,7 +57,7 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows); * in x0. This memory layout is sitting at the base of the free trusted SRAM. * Copy it to a safe location before its reclaimed by later BL2 functionality. ******************************************************************************/ -void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, +void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { /* Initialize the console to provide early debug support */ @@ -58,11 +66,10 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; + config_base = fw_config; + /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); - - if (tb_fw_config != 0U) - arm_bl2_set_tb_cfg_addr((void *)tb_fw_config); } void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) @@ -123,6 +130,7 @@ void arm_bl2_plat_arch_setup(void) #if ARM_CRYPTOCELL_INTEG ARM_MAP_BL_COHERENT_RAM, #endif + ARM_MAP_BL_CONFIG_REGION, {0} }; @@ -139,7 +147,18 @@ void arm_bl2_plat_arch_setup(void) void bl2_plat_arch_setup(void) { + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + arm_bl2_plat_arch_setup(); + + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", config_base); + + /* TB_FW_CONFIG was also loaded by BL1 */ + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + fconf_populate("TB_FW", tb_fw_config_info->config_addr); } int arm_bl2_handle_post_image_load(unsigned int image_id) @@ -150,7 +169,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id) bl_mem_params_node_t *pager_mem_params = NULL; bl_mem_params_node_t *paged_mem_params = NULL; #endif - assert(bl_mem_params); + assert(bl_mem_params != NULL); switch (image_id) { #ifdef __aarch64__ @@ -202,6 +221,13 @@ 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 + /* For Secure Partitions we don't need post processing */ + if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) && + (image_id < MAX_NUMBER_IDS)) { + return 0; + } +#endif return arm_bl2_handle_post_image_load(image_id); } @@ -209,3 +235,11 @@ 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 939885f98..81ef6e7b2 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,7 +14,6 @@ #include <lib/debugfs.h> #include <lib/extensions/ras.h> #include <lib/mmio.h> -#include <lib/utils.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> @@ -29,10 +28,10 @@ static entry_point_info_t bl33_image_ep_info; #if !RESET_TO_BL31 /* - * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); +CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #endif /* Weak definitions may be overridden in specific ARM standard platform */ @@ -47,7 +46,13 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); MT_MEMORY | MT_RW | MT_SECURE) #if RECLAIM_INIT_CODE IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); -IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); +IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED); +IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED); + +#define BL_INIT_CODE_END ((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) +#define BL_STACKS_END ((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \ + ~(PAGE_SIZE - 1)) #define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ BL_INIT_CODE_BASE, \ @@ -56,6 +61,14 @@ IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); MT_CODE | MT_SECURE) #endif +#if SEPARATE_NOBITS_REGION +#define MAP_BL31_NOBITS MAP_REGION_FLAT( \ + BL31_NOBITS_BASE, \ + BL31_NOBITS_LIMIT \ + - BL31_NOBITS_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#endif /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the * security state specified. BL33 corresponds to the non-secure image type @@ -107,6 +120,18 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); bl32_image_ep_info.pc = BL32_BASE; bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry(); + +#if defined(SPD_spmd) + /* SPM (hafnium in secure world) expects SPM Core manifest base address + * in x0, which in !RESET_TO_BL31 case loaded after base of non shared + * SRAM(after 4KB offset of SRAM). But in RESET_TO_BL31 case all non + * shared SRAM is allocated to BL31, so to avoid overwriting of manifest + * keep it in the last page. + */ + bl32_image_ep_info.args.arg0 = ARM_TRUSTED_SRAM_BASE + + PLAT_ARM_TRUSTED_SRAM_SIZE - PAGE_SIZE; +#endif + # endif /* BL32_BASE */ /* Populate entry point information for BL33 */ @@ -123,6 +148,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 defined(SPD_spmd) && !(ARM_LINUX_KERNEL_AS_BL33) + /* + * Hafnium in normal world expects its manifest address in x0, which + * is loaded at base of DRAM. + */ + bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; +#endif + # if ARM_LINUX_KERNEL_AS_BL33 /* * According to the file ``Documentation/arm64/booting.txt`` of the @@ -249,21 +282,51 @@ void arm_bl31_plat_runtime_setup(void) /* Initialize the runtime console */ arm_console_runtime_init(); + #if RECLAIM_INIT_CODE arm_free_init_memory(); #endif + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } #if RECLAIM_INIT_CODE /* - * Zero out and make RW memory used to store image boot time code so it can - * be reclaimed during runtime + * Make memory for image boot time code RW to reclaim it as stack for the + * secondary cores, or RO where it cannot be reclaimed: + * + * |-------- INIT SECTION --------| + * ----------------------------------------- + * | CORE 0 | CORE 1 | CORE 2 | EXTRA | + * | STACK | STACK | STACK | SPACE | + * ----------------------------------------- + * <-------------------> <------> + * MAKE RW AND XN MAKE + * FOR STACKS RO AND XN */ void arm_free_init_memory(void) { - int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, + int ret = 0; + + if (BL_STACKS_END < BL_INIT_CODE_END) { + /* Reclaim some of the init section as stack if possible. */ + if (BL_INIT_CODE_BASE < BL_STACKS_END) { + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, + BL_STACKS_END - BL_INIT_CODE_BASE, + MT_RW_DATA); + } + /* Make the rest of the init section read-only. */ + ret |= xlat_change_mem_attributes(BL_STACKS_END, + BL_INIT_CODE_END - BL_STACKS_END, + MT_RO_DATA); + } else { + /* The stacks cover the init section, so reclaim it all. */ + ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE, BL_INIT_CODE_END - BL_INIT_CODE_BASE, MT_RW_DATA); + } if (ret != 0) { ERROR("Could not reclaim initialization code"); @@ -295,6 +358,9 @@ void __init arm_bl31_plat_arch_setup(void) #if RECLAIM_INIT_CODE MAP_BL_INIT_CODE, #endif +#if SEPARATE_NOBITS_REGION + MAP_BL31_NOBITS, +#endif ARM_MAP_BL_RO, #if USE_ROMLIB ARM_MAP_ROMLIB_CODE, diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 255e6b421..7d9fd6c72 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -13,10 +13,11 @@ #include <common/debug.h> #include <common/romlib.h> #include <lib/mmio.h> +#include <lib/smccc.h> #include <lib/xlat_tables/xlat_tables_compat.h> +#include <services/arm_arch_svc.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> -#include <services/spm_mm_partition.h> /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_get_ns_image_entrypoint @@ -26,6 +27,29 @@ * conflicts with the definition in plat/common. */ #pragma weak plat_get_syscnt_freq2 +/* Get ARM SOC-ID */ +#pragma weak plat_arm_get_soc_id + +/******************************************************************************* + * Changes the memory attributes for the region of mapped memory where the BL + * image's translation tables are located such that the tables will have + * read-only permissions. + ******************************************************************************/ +#if PLAT_RO_XLAT_TABLES +void arm_xlat_make_tables_readonly(void) +{ + int rc = xlat_make_tables_readonly(); + + if (rc != 0) { + ERROR("Failed to make translation tables read-only at EL%u.\n", + get_current_el()); + panic(); + } + + INFO("Translation tables are now read-only at EL%u.\n", + get_current_el()); +} +#endif void arm_setup_romlib(void) { @@ -73,7 +97,7 @@ uint32_t arm_get_spsr_for_bl33_entry(void) * the FIP ToC and allowing the platform to have a say as * well. */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); return spsr; } #else @@ -192,7 +216,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) * Translate entry point to Physical Address using the EL1&0 * translation regime, including stage 2. */ - ats12e1r(ep); + AT(ats12e1r, ep); } isb(); par = read_par_el1(); @@ -212,3 +236,4 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) return arm_validate_ns_entrypoint(pa); } #endif + diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index c8b7ab448..74afc53eb 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -121,10 +121,33 @@ endif ENABLE_PSCI_STAT := 1 ENABLE_PMF := 1 +# Override the standard libc with optimised libc_asm +OVERRIDE_LIBC := 1 +ifeq (${OVERRIDE_LIBC},1) + include lib/libc/libc_asm.mk +endif + # On ARM platforms, separate the code and read-only data sections to allow # mapping the former as executable and the latter as execute-never. SEPARATE_CODE_AND_RODATA := 1 +# On ARM platforms, disable SEPARATE_NOBITS_REGION by default. Both PROGBITS +# and NOBITS sections of BL31 image are adjacent to each other and loaded +# into Trusted SRAM. +SEPARATE_NOBITS_REGION := 0 + +# In order to support SEPARATE_NOBITS_REGION for Arm platforms, we need to load +# BL31 PROGBITS into secure DRAM space and BL31 NOBITS into SRAM. Hence mandate +# the build to require that ARM_BL31_IN_DRAM is enabled as well. +ifeq ($(SEPARATE_NOBITS_REGION),1) + ifneq ($(ARM_BL31_IN_DRAM),1) + $(error For SEPARATE_NOBITS_REGION, ARM_BL31_IN_DRAM must be enabled) + endif + ifneq ($(RECLAIM_INIT_CODE),0) + $(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported) + endif +endif + # Disable ARM Cryptocell by default ARM_CRYPTOCELL_INTEG := 0 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG)) @@ -160,12 +183,21 @@ include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} 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) + ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c + endif +endif + BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl1_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} + ifdef EL3_PAYLOAD_BASE # Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from # their holding pen @@ -179,7 +211,10 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_err.c \ - plat/arm/common/arm_io_storage.c + ${ARM_IO_SOURCES} + +# Firmware Configuration Framework sources +include lib/fconf/fconf.mk # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk @@ -229,11 +264,14 @@ endif endif ifeq (${EL3_EXCEPTION_HANDLING},1) -BL31_SOURCES += plat/arm/common/aarch64/arm_ehf.c +BL31_SOURCES += plat/common/aarch64/plat_ehf.c endif ifeq (${SDEI_SUPPORT},1) BL31_SOURCES += plat/arm/common/aarch64/arm_sdei.c +ifeq (${SDEI_IN_FCONF},1) +BL31_SOURCES += plat/arm/common/fconf/fconf_sdei_getter.c +endif endif # RAS sources @@ -248,16 +286,33 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \ lib/extensions/pauth/pauth_helpers.S endif +ifeq (${SPD},spmd) +BL31_SOURCES += plat/common/plat_spmd_manifest.c \ + common/fdt_wrappers.c \ + ${LIBFDT_SRCS} + +endif + ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ + lib/fconf/fconf_tbbr_getter.c # Include the selected chain of trust sources. ifeq (${COT},tbbr) - AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot.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 + else + BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c + endif + else ifeq (${COT},dualroot) + AUTH_SOURCES += drivers/auth/dualroot/cot.c else $(error Unknown chain of trust ${COT}) endif @@ -293,3 +348,9 @@ ifeq (${RECLAIM_INIT_CODE}, 1) $(error "To reclaim init code xlat tables v2 must be used") endif endif + +ifeq (${MEASURED_BOOT},1) + MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk + $(info Including ${MEASURED_BOOT_MK}) + include ${MEASURED_BOOT_MK} +endif diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c index 123811d71..af5f11e46 100644 --- a/plat/arm/common/arm_console.c +++ b/plat/arm/common/arm_console.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,11 +13,14 @@ #include <drivers/console.h> #include <plat/arm/common/plat_arm.h> +#pragma weak arm_console_runtime_init +#pragma weak arm_console_runtime_end + /******************************************************************************* * Functions that set up the console ******************************************************************************/ -static console_pl011_t arm_boot_console; -static console_pl011_t arm_runtime_console; +static console_t arm_boot_console; +static console_t arm_runtime_console; /* Initialize the console to provide early debug support */ void __init arm_console_boot_init(void) @@ -35,13 +38,13 @@ void __init arm_console_boot_init(void) panic(); } - console_set_scope(&arm_boot_console.console, CONSOLE_FLAG_BOOT); + console_set_scope(&arm_boot_console, CONSOLE_FLAG_BOOT); } void arm_console_boot_end(void) { - (void)console_flush(); - (void)console_unregister(&arm_boot_console.console); + console_flush(); + (void)console_unregister(&arm_boot_console); } /* Initialize the runtime console */ @@ -54,10 +57,10 @@ void arm_console_runtime_init(void) if (rc == 0) panic(); - console_set_scope(&arm_runtime_console.console, CONSOLE_FLAG_RUNTIME); + console_set_scope(&arm_runtime_console, CONSOLE_FLAG_RUNTIME); } void arm_console_runtime_end(void) { - (void)console_flush(); + console_flush(); } diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a7361..6b3a61180 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,13 +15,17 @@ #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> +#include <lib/fconf/fconf_tbbr_getter.h> + #include <plat/arm/common/arm_dyn_cfg_helpers.h> #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> - -/* Variable to store the address to TB_FW_CONFIG passed from BL1 */ -static void *tb_fw_cfg_dtb; #if TRUSTED_BOARD_BOOT @@ -57,20 +61,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) - int err; - /* If in BL2, retrieve the already allocated heap's info from DTB */ - if (tb_fw_cfg_dtb != NULL) { - err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr, - heap_size); - if (err < 0) { - ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n"); - panic(); - } - } else { - ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n"); - panic(); - } + *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); + *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); + #endif return 0; @@ -83,6 +77,8 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void arm_bl1_set_mbedtls_heap(void) { int err; + uintptr_t tb_fw_cfg_dtb; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -96,141 +92,150 @@ void arm_bl1_set_mbedtls_heap(void) * information, we would need to call plat_get_mbedtls_heap to retrieve * the default heap's address and size. */ - if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) { - err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, + + 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 != 0UL) && (mbedtls_heap_addr != NULL)) { + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)tb_fw_cfg_dtb; + + err = arm_set_dtb_mbedtls_heap_info(dtb, mbedtls_heap_addr, mbedtls_heap_size); if (err < 0) { - ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); + ERROR("%swrite shared Mbed TLS heap information%s", + "BL1: unable to ", " to DTB\n"); panic(); } +#if !MEASURED_BOOT /* * 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. + * + * 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. */ - flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, - fdt_totalsize(tb_fw_cfg_dtb)); + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); +#endif /* !MEASURED_BOOT */ } } -#endif /* TRUSTED_BOARD_BOOT */ - +#if MEASURED_BOOT /* - * Helper function to load TB_FW_CONFIG and populate the load information to - * arg0 of BL2 entrypoint info. + * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. + * Executed only from BL1. */ -void arm_load_tb_fw_config(void) +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; - uintptr_t config_base = 0UL; - image_desc_t *desc; - - image_desc_t arm_tb_fw_info = { - .image_id = TB_FW_CONFIG_ID, - SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), - .image_info.image_base = ARM_TB_FW_CONFIG_BASE, - .image_info.image_max_size = - ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE - }; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; - VERBOSE("BL1: Loading TB_FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info); - if (err != 0) { - /* Return if TB_FW_CONFIG is not loaded */ - VERBOSE("Failed to load TB_FW_CONFIG\n"); - return; - } - - /* At this point we know that a DTB is indeed available */ - config_base = arm_tb_fw_info.image_info.image_base; - tb_fw_cfg_dtb = (void *)config_base; + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); - /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = config_base; + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; - INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base); + /* + * 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(); + } -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - int tb_fw_node; - uint32_t disable_auth = 0; + /* 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_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node); + err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded\n"); + ERROR("%swrite%sdata%s\n", "BL1: unable to ", + " BL2 hash ", "to DTB\n"); panic(); } - err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif + /* + * 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)); } /* - * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. + * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB. + * Executed only from BL2. */ -void arm_bl2_set_tb_cfg_addr(void *dtb) +void arm_bl2_get_hash(void *data) { - assert(dtb != NULL); - tb_fw_cfg_dtb = dtb; + 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 */ /* * BL2 utility function to initialize dynamic configuration specified by - * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if - * specified in TB_FW_CONFIG. + * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if + * specified in FW_CONFIG. */ void arm_bl2_dyn_cfg_init(void) { - int err = 0, tb_fw_node; unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; - uint64_t image_base; + uintptr_t image_base; uint32_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, NT_FW_CONFIG_ID, -#ifdef SPD_tspd - /* Currently tos_fw_config is only present for TSP */ +#if defined(SPD_tspd) || defined(SPD_spmd) + /* tos_fw_config is only present for TSPD/SPMD */ TOS_FW_CONFIG_ID #endif }; - if (tb_fw_cfg_dtb == NULL) { - VERBOSE("No TB_FW_CONFIG specified\n"); - return; - } - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } + const struct dyn_cfg_dtb_info_t *dtb_info; /* Iterate through all the fw config IDs */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { /* Get the config load address and size from TB_FW_CONFIG */ cfg_mem_params = get_bl_mem_params_node(config_ids[i]); if (cfg_mem_params == NULL) { - VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n"); + VERBOSE("%sHW_CONFIG in bl_mem_params_node\n", + "Couldn't find "); continue; } - err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, - config_ids[i], &image_base, &image_size); - if (err < 0) { - VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", - config_ids[i]); + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); + if (dtb_info == NULL) { + VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n", + "Couldn't find ", config_ids[i]); continue; } + image_base = dtb_info->config_addr; + image_size = dtb_info->config_max_size; + /* * Do some runtime checks on the load addresses of soc_fw_config, * tos_fw_config, nt_fw_config. This is not a comprehensive check @@ -238,32 +243,34 @@ void arm_bl2_dyn_cfg_init(void) */ if (config_ids[i] != HW_CONFIG_ID) { - if (check_uptr_overflow(image_base, image_size)) + if (check_uptr_overflow(image_base, image_size)) { continue; - + } #ifdef BL31_BASE /* Ensure the configs don't overlap with BL31 */ if ((image_base >= BL31_BASE) && - (image_base <= BL31_LIMIT)) + (image_base <= BL31_LIMIT)) { continue; + } #endif /* Ensure the configs are loaded in a valid address */ - if (image_base < ARM_BL_RAM_BASE) + if (image_base < ARM_BL_RAM_BASE) { continue; + } #ifdef BL32_BASE /* * If BL32 is present, ensure that the configs don't * overlap with it. */ if ((image_base >= BL32_BASE) && - (image_base <= BL32_LIMIT)) + (image_base <= BL32_LIMIT)) { continue; + } #endif } - - cfg_mem_params->image_info.image_base = (uintptr_t)image_base; - cfg_mem_params->image_info.image_max_size = image_size; + cfg_mem_params->image_info.image_base = image_base; + cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; /* * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from @@ -271,16 +278,4 @@ void arm_bl2_dyn_cfg_init(void) */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - uint32_t disable_auth = 0; - - err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, - &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif } diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 36d37f8f6..5f20c8d48 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -1,142 +1,38 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> -#include <libfdt.h> - +#if MEASURED_BOOT #include <common/desc_image_load.h> +#endif #include <common/fdt_wrappers.h> + +#include <libfdt.h> + #include <plat/arm/common/arm_dyn_cfg_helpers.h> #include <plat/arm/common/plat_arm.h> #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr" #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" -typedef struct config_load_info_prop { - unsigned int config_id; - const char *config_addr; - const char *config_max_size; -} config_load_info_prop_t; - -static const config_load_info_prop_t prop_names[] = { - {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"}, - {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"}, - {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"}, - {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"} -}; - -/******************************************************************************* - * Helper to read the load information corresponding to the `config_id` in - * TB_FW_CONFIG. This function expects the following properties to be defined : - * <config>_addr size : 2 cells - * <config>_max_size size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * unsigned int config_id - The configuration id - * uint64_t *config_addr - Returns the `config` load address if read - * is successful. - * uint32_t *config_size - Returns the `config` size if read is - * successful. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id, - uint64_t *config_addr, uint32_t *config_size) -{ - int err; - unsigned int i; - - assert(dtb != NULL); - assert(config_addr != NULL); - assert(config_size != NULL); - - for (i = 0; i < ARRAY_SIZE(prop_names); i++) { - if (prop_names[i].config_id == config_id) - break; - } - - if (i == ARRAY_SIZE(prop_names)) { - WARN("Invalid config id %d\n", config_id); - return -1; - } - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2, - (void *) config_addr); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_addr); - return -1; - } - - err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1, - (void *) config_size); - if (err < 0) { - WARN("Read cell failed for %s\n", prop_names[i].config_max_size); - return -1; - } - - VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n", - config_id, (unsigned long long)*config_addr, *config_size); - - return 0; -} - -/******************************************************************************* - * Helper to read the `disable_auth` property in config DTB. This function - * expects the following properties to be present in the config DTB. - * name : disable_auth size : 1 cell - * - * Arguments: - * void *dtb - pointer to the TB_FW_CONFIG in memory - * int node - The node offset to appropriate node in the - * DTB. - * uint64_t *disable_auth - The value of `disable_auth` property on - * successful read. Must be 0 or 1. - * - * Returns 0 on success and -1 on error. - ******************************************************************************/ -int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth) -{ - int err; - - assert(dtb != NULL); - assert(disable_auth != NULL); - - /* Check if the pointer to DT is correct */ - assert(fdt_check_header(dtb) == 0); - - /* Assert the node offset point to "arm,tb_fw" compatible property */ - assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); - - /* Locate the disable_auth cell and read the value */ - err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth); - if (err < 0) { - WARN("Read cell failed for `disable_auth`\n"); - return -1; - } +#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 +#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr" +#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size" - /* Check if the value is boolean */ - if ((*disable_auth != 0U) && (*disable_auth != 1U)) { - WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth); - return -1; - } - - VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n", - *disable_auth); - return 0; -} +static int dtb_root = -1; +#endif /* MEASURED_BOOT */ /******************************************************************************* * Validate the tb_fw_config is a valid DTB file and returns the node offset @@ -154,62 +50,22 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) /* Check if the pointer to DT is correct */ if (fdt_check_header(dtb) != 0) { - WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); + WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG"); return -1; } /* Assert the node offset point to "arm,tb_fw" compatible property */ *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); if (*node < 0) { - WARN("The compatible property `arm,tb_fw` not found in the config\n"); - return -1; - } - - VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); - return 0; -} - -/* - * Reads and returns the Mbed TLS shared heap information from the DTB. - * This function is supposed to be called *only* when a DTB is present. - * This function is supposed to be called only by BL2. - * - * Returns: - * 0 = success - * -1 = error. In this case the values of heap_addr, heap_size should be - * considered as garbage by the caller. - */ -int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, - size_t *heap_size) -{ - int err, dtb_root; - - /* Verify the DTB is valid and get the root node */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n"); + WARN("The compatible property '%s' not%s", "arm,tb_fw", + " found in the config\n"); return -1; } - /* Retrieve the Mbed TLS heap details from the DTB */ - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); - return -1; - } - err = fdtw_read_cells(dtb, dtb_root, - DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size); - if (err < 0) { - ERROR("Error while reading %s from DTB\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); - return -1; - } + VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n"); return 0; } - /* * This function writes the Mbed TLS heap address and size in the DTB. When it * is called, it is guaranteed that a DTB is available. However it is not @@ -221,19 +77,21 @@ int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr, * * Returns: * 0 = success - * 1 = error + * -1 = error */ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) { - int err, dtb_root; - +#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. */ - err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); + int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n"); + ERROR("Invalid%s loaded. Unable to get root node\n", + " TB_FW_CONFIG"); return -1; } @@ -247,18 +105,199 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR); return -1; } err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE); return -1; } return 0; } + +#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 + */ +static int arm_set_event_log_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t sm_log_addr, +#endif + uintptr_t log_addr, size_t log_size) +{ + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)config_base; + const char *compatible = "arm,tpm_event_log"; + int err, node; + + /* + * Verify that the DTB is valid, before attempting to write to it, + * and get the DTB root node. + */ + + /* Check if the pointer to DT is correct */ + err = fdt_check_header(dtb); + if (err < 0) { + WARN("Invalid DTB file passed\n"); + return err; + } + + /* 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' not%s", compatible, + " found in the config\n"); + return node; + } + + VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n"); + +#ifdef SPD_opteed + if (sm_log_addr != 0UL) { + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_SM_LOG_ADDR); + return err; + } + } +#endif + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_ADDR, 2, &log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_ADDR); + return err; + } + + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_SIZE, 1, &log_size); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_SIZE); + } else { + /* + * Ensure that the info written to the DTB is visible + * to other images. + */ + flush_dcache_range(config_base, fdt_totalsize(dtb)); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the TOS_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, + size_t log_size) +{ + int err; + + assert(config_base != 0UL); + assert(log_addr != 0UL); + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + 0UL, +#endif + log_addr, log_size); + if (err < 0) { + ERROR("%sEvent Log data to TOS_FW_CONFIG\n", + "Unable to write "); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the NT_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_nt_fw_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t log_addr, +#endif + size_t log_size, uintptr_t *ns_log_addr) +{ + 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); + + /* 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; + + /* Check for memory space */ + if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) { + return -1; + } + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + log_addr, +#endif + ns_addr, log_size); + + /* Return Event Log address in Non-secure memory */ + *ns_log_addr = (err < 0) ? 0UL : ns_addr; + return err; +} +#endif /* MEASURED_BOOT */ diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index 2faaa76c4..ed7f1f5a5 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,9 @@ #include <assert.h> #include <common/bl_common.h> #include <common/desc_image_load.h> +#if defined(SPD_spmd) +#include <plat/arm/common/fconf_arm_sp_getter.h> +#endif #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> @@ -29,12 +32,62 @@ void plat_flush_next_bl_params(void) next_bl_params_cpy_ptr); } +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 +/******************************************************************************* + * This function appends Secure Partitions to list of loadable images. + ******************************************************************************/ +static void plat_add_sp_images_load_info(struct bl_load_info *load_info) +{ + bl_load_info_node_t *node_info = load_info->head; + unsigned int index = 0; + + if (sp_mem_params_descs[index].image_id == 0) { + ERROR("No Secure Partition Image available\n"); + return; + } + + /* Traverse through the bl images list */ + do { + node_info = node_info->next_load_info; + } while (node_info->next_load_info != NULL); + + for (; index < MAX_SP_IDS; index++) { + /* Populate the image information */ + node_info->image_id = sp_mem_params_descs[index].image_id; + node_info->image_info = &sp_mem_params_descs[index].image_info; + + if ((index + 1U) == MAX_SP_IDS) { + INFO("Reached Max number of SPs\n"); + return; + } + + if (sp_mem_params_descs[index + 1U].image_id == 0) { + return; + } + + node_info->next_load_info = + &sp_mem_params_descs[index + 1U].load_node_mem; + node_info = node_info->next_load_info; + + } +} +#endif + /******************************************************************************* * This function returns the list of loadable images. ******************************************************************************/ struct bl_load_info *plat_get_bl_image_load_info(void) { +#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 + bl_load_info_t *bl_load_info; + + bl_load_info = get_bl_load_info_from_mem_params_desc(); + plat_add_sp_images_load_info(bl_load_info); + + return bl_load_info; +#else return get_bl_load_info_from_mem_params_desc(); +#endif } /******************************************************************************* diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c index fc1eb490e..34b4101e1 100644 --- a/plat/arm/common/arm_io_storage.c +++ b/plat/arm/common/arm_io_storage.c @@ -1,263 +1,33 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include <assert.h> -#include <string.h> - -#include <platform_def.h> - #include <common/debug.h> #include <drivers/io/io_driver.h> #include <drivers/io/io_fip.h> #include <drivers/io/io_memmap.h> #include <drivers/io/io_storage.h> #include <lib/utils.h> + +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> -#include <tools_share/firmware_image_package.h> +#include <platform_def.h> /* IO devices */ static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; +uintptr_t fip_dev_handle; static const io_dev_connector_t *memmap_dev_con; -static uintptr_t memmap_dev_handle; - -static const io_block_spec_t fip_block_spec = { - .offset = PLAT_ARM_FIP_BASE, - .length = PLAT_ARM_FIP_MAX_SIZE -}; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t scp_bl2_uuid_spec = { - .uuid = UUID_SCP_FIRMWARE_SCP_BL2, -}; - -static const io_uuid_spec_t bl31_uuid_spec = { - .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, -}; - -static const io_uuid_spec_t bl32_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32, -}; - -static const io_uuid_spec_t bl32_extra1_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, -}; - -static const io_uuid_spec_t bl32_extra2_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, -}; - -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -static const io_uuid_spec_t tb_fw_config_uuid_spec = { - .uuid = UUID_TB_FW_CONFIG, -}; - -static const io_uuid_spec_t hw_config_uuid_spec = { - .uuid = UUID_HW_CONFIG, -}; - -static const io_uuid_spec_t soc_fw_config_uuid_spec = { - .uuid = UUID_SOC_FW_CONFIG, -}; - -static const io_uuid_spec_t tos_fw_config_uuid_spec = { - .uuid = UUID_TOS_FW_CONFIG, -}; - -static const io_uuid_spec_t nt_fw_config_uuid_spec = { - .uuid = UUID_NT_FW_CONFIG, -}; - -#if TRUSTED_BOARD_BOOT -static const io_uuid_spec_t tb_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FW_CERT, -}; - -static const io_uuid_spec_t trusted_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_KEY_CERT, -}; - -static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { - .uuid = UUID_SCP_FW_KEY_CERT, -}; - -static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { - .uuid = UUID_SOC_FW_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, -}; - -static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, -}; - -static const io_uuid_spec_t scp_fw_cert_uuid_spec = { - .uuid = UUID_SCP_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t soc_fw_cert_uuid_spec = { - .uuid = UUID_SOC_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t tos_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t nt_fw_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, -}; -#endif /* TRUSTED_BOARD_BOOT */ - - -static int open_fip(const uintptr_t spec); -static int open_memmap(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -/* By default, ARM platforms load images from the FIP */ -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - open_fip - }, - [SCP_BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_bl2_uuid_spec, - open_fip - }, - [BL31_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl31_uuid_spec, - open_fip - }, - [BL32_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_uuid_spec, - open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra1_uuid_spec, - open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra2_uuid_spec, - open_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, - [TB_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_config_uuid_spec, - open_fip - }, - [HW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&hw_config_uuid_spec, - open_fip - }, - [SOC_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_config_uuid_spec, - open_fip - }, - [TOS_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_config_uuid_spec, - open_fip - }, - [NT_FW_CONFIG_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_config_uuid_spec, - open_fip - }, -#if TRUSTED_BOARD_BOOT - [TRUSTED_BOOT_FW_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&trusted_key_cert_uuid_spec, - open_fip - }, - [SCP_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_fw_key_cert_uuid_spec, - open_fip - }, - [SOC_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_key_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_key_cert_uuid_spec, - open_fip - }, - [SCP_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&scp_fw_cert_uuid_spec, - open_fip - }, - [SOC_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_cert_uuid_spec, - open_fip - }, -#endif /* TRUSTED_BOARD_BOOT */ -}; - +uintptr_t memmap_dev_handle; /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_arm_io_setup #pragma weak plat_arm_get_alt_image_source - -static int open_fip(const uintptr_t spec) +int open_fip(const uintptr_t spec) { int result; uintptr_t local_image_handle; @@ -274,8 +44,7 @@ static int open_fip(const uintptr_t spec) return result; } - -static int open_memmap(const uintptr_t spec) +int open_memmap(const uintptr_t spec) { int result; uintptr_t local_image_handle; @@ -291,33 +60,41 @@ static int open_memmap(const uintptr_t spec) return result; } - -void arm_io_setup(void) +int arm_io_setup(void) { int io_result; io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } /* Open connections to devices and cache the handles */ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(io_result == 0); + if (io_result < 0) { + return io_result; + } io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, &memmap_dev_handle); - assert(io_result == 0); - /* Ignore improbable errors in release builds */ - (void)io_result; + return io_result; } void plat_arm_io_setup(void) { - arm_io_setup(); + int err; + + err = arm_io_setup(); + if (err < 0) { + panic(); + } } int plat_arm_get_alt_image_source( @@ -337,9 +114,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, int result; const struct plat_io_policy *policy; - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; + policy = FCONF_GET_PROPERTY(arm, io_policies, image_id); result = policy->check(policy->image_spec); if (result == 0) { *image_spec = policy->image_spec; @@ -357,12 +132,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, * See if a Firmware Image Package is available, * by checking if TOC is valid or not. */ -int arm_io_is_toc_valid(void) +bool arm_io_is_toc_valid(void) { - int result; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - - return (result == 0); + return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0); } - diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c index b9181eb4c..1fa234d79 100644 --- a/plat/arm/common/arm_nor_psci_mem_protect.c +++ b/plat/arm/common/arm_nor_psci_mem_protect.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,6 @@ #include <common/debug.h> #include <drivers/cfi/v2m_flash.h> #include <lib/psci/psci.h> -#include <lib/mmio.h> #include <lib/utils.h> #include <plat/arm/common/plat_arm.h> diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index c95f4523c..5434c9457 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -1,11 +1,10 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> -#include <errno.h> #include <platform_def.h> diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c index 34e650f19..370ef0a86 100644 --- a/plat/arm/common/arm_tzc400.c +++ b/plat/arm/common/arm_tzc400.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,8 @@ * When booting an EL3 payload, this is simplified: we configure region 0 with * secure access only and do not enable any other region. ******************************************************************************/ -void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) +void arm_tzc400_setup(uintptr_t tzc_base, + const arm_tzc_regions_info_t *tzc_regions) { #ifndef EL3_PAYLOAD_BASE unsigned int region_index = 1U; @@ -32,7 +33,7 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) INFO("Configuring TrustZone Controller\n"); - tzc400_init(PLAT_ARM_TZC_BASE); + tzc400_init(tzc_base); /* Disable filters. */ tzc400_disable_filters(); @@ -74,5 +75,5 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions) void plat_arm_security_setup(void) { - arm_tzc400_setup(NULL); + arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); } diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c new file mode 100644 index 000000000..48286c2f2 --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <drivers/io/io_storage.h> +#include <lib/object_pool.h> +#include <libfdt.h> +#include <tools_share/firmware_image_package.h> + +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> +#include <platform_def.h> + +const io_block_spec_t fip_block_spec = { + .offset = PLAT_ARM_FIP_BASE, + .length = PLAT_ARM_FIP_MAX_SIZE +}; + +const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { + [BL2_IMAGE_ID] = {UUID_TRUSTED_BOOT_FIRMWARE_BL2}, + [TB_FW_CONFIG_ID] = {UUID_TB_FW_CONFIG}, + [FW_CONFIG_ID] = {UUID_FW_CONFIG}, +#if !ARM_IO_IN_DTB + [SCP_BL2_IMAGE_ID] = {UUID_SCP_FIRMWARE_SCP_BL2}, + [BL31_IMAGE_ID] = {UUID_EL3_RUNTIME_FIRMWARE_BL31}, + [BL32_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32}, + [BL32_EXTRA1_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA1}, + [BL32_EXTRA2_IMAGE_ID] = {UUID_SECURE_PAYLOAD_BL32_EXTRA2}, + [BL33_IMAGE_ID] = {UUID_NON_TRUSTED_FIRMWARE_BL33}, + [HW_CONFIG_ID] = {UUID_HW_CONFIG}, + [SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG}, + [TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG}, + [NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG}, +#endif /* ARM_IO_IN_DTB */ +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, +#if !ARM_IO_IN_DTB + [TRUSTED_KEY_CERT_ID] = {UUID_TRUSTED_KEY_CERT}, + [SCP_FW_KEY_CERT_ID] = {UUID_SCP_FW_KEY_CERT}, + [SOC_FW_KEY_CERT_ID] = {UUID_SOC_FW_KEY_CERT}, + [TRUSTED_OS_FW_KEY_CERT_ID] = {UUID_TRUSTED_OS_FW_KEY_CERT}, + [NON_TRUSTED_FW_KEY_CERT_ID] = {UUID_NON_TRUSTED_FW_KEY_CERT}, + [SCP_FW_CONTENT_CERT_ID] = {UUID_SCP_FW_CONTENT_CERT}, + [SOC_FW_CONTENT_CERT_ID] = {UUID_SOC_FW_CONTENT_CERT}, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT}, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, + [PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT}, +#endif +#endif /* ARM_IO_IN_DTB */ +#endif /* TRUSTED_BOARD_BOOT */ +}; + +/* By default, ARM platforms load images from the FIP */ +struct plat_io_policy policies[MAX_NUMBER_IDS] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL2_IMAGE_ID], + open_fip + }, + [TB_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TB_FW_CONFIG_ID], + open_fip + }, + [FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[FW_CONFIG_ID], + open_fip + }, +#if !ARM_IO_IN_DTB + [SCP_BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_BL2_IMAGE_ID], + open_fip + }, + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL31_IMAGE_ID], + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_IMAGE_ID], + open_fip + }, + [BL32_EXTRA1_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_EXTRA1_IMAGE_ID], + open_fip + }, + [BL32_EXTRA2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL32_EXTRA2_IMAGE_ID], + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID], + open_fip + }, + [HW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[HW_CONFIG_ID], + open_fip + }, + [SOC_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_CONFIG_ID], + open_fip + }, + [TOS_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TOS_FW_CONFIG_ID], + open_fip + }, + [NT_FW_CONFIG_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID], + open_fip + }, +#endif /* ARM_IO_IN_DTB */ +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_BOOT_FW_CERT_ID], + open_fip + }, +#if !ARM_IO_IN_DTB + [TRUSTED_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_KEY_CERT_ID], + open_fip + }, + [SCP_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_FW_KEY_CERT_ID], + open_fip + }, + [SOC_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_KEY_CERT_ID], + open_fip + }, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_KEY_CERT_ID], + open_fip + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_KEY_CERT_ID], + open_fip + }, + [SCP_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SCP_FW_CONTENT_CERT_ID], + open_fip + }, + [SOC_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SOC_FW_CONTENT_CERT_ID], + open_fip + }, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[TRUSTED_OS_FW_CONTENT_CERT_ID], + open_fip + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_CONTENT_CERT_ID], + open_fip + }, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID], + open_fip + }, + [PLAT_SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID], + open_fip + }, +#endif +#endif /* ARM_IO_IN_DTB */ +#endif /* TRUSTED_BOARD_BOOT */ +}; + +#ifdef IMAGE_BL2 + +#if TRUSTED_BOARD_BOOT +#define FCONF_ARM_IO_UUID_NUMBER U(21) +#else +#define FCONF_ARM_IO_UUID_NUMBER U(10) +#endif + +static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; +static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids); + +struct policies_load_info { + unsigned int image_id; + const char *name; +}; + +/* image id to property name table */ +static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { + {SCP_BL2_IMAGE_ID, "scp_bl2_uuid"}, + {BL31_IMAGE_ID, "bl31_uuid"}, + {BL32_IMAGE_ID, "bl32_uuid"}, + {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, + {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, + {BL33_IMAGE_ID, "bl33_uuid"}, + {HW_CONFIG_ID, "hw_cfg_uuid"}, + {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"}, + {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, + {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +#if TRUSTED_BOARD_BOOT + {TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"}, + {SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"}, + {SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"}, + {TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"}, + {NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"}, + {SCP_FW_CONTENT_CERT_ID, "scp_fw_content_cert_uuid"}, + {SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"}, + {TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"}, + {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, +#if defined(SPD_spmd) + {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"}, + {PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"}, +#endif +#endif /* TRUSTED_BOARD_BOOT */ +}; + +int fconf_populate_arm_io_policies(uintptr_t config) +{ + int err, node; + unsigned int i; + unsigned int j; + + union uuid_helper_t uuid_helper; + io_uuid_spec_t *uuid_ptr; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,io-fip-handle" compatible property */ + const char *compatible_str = "arm,io-fip-handle"; + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + /* Locate the uuid cells and read the value for all the load info uuid */ + for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) { + uuid_ptr = pool_alloc(&fconf_arm_uuids_pool); + err = fdt_read_uint32_array(dtb, node, load_info[i].name, + 4, uuid_helper.word); + if (err < 0) { + WARN("FCONF: Read cell failed for %s\n", load_info[i].name); + return err; + } + + /* Convert uuid from big endian to little endian */ + for (j = 0U; j < 4U; j++) { + uuid_helper.word[j] = + ((uuid_helper.word[j] >> 24U) & 0xff) | + ((uuid_helper.word[j] << 8U) & 0xff0000) | + ((uuid_helper.word[j] >> 8U) & 0xff00) | + ((uuid_helper.word[j] << 24U) & 0xff000000); + } + + VERBOSE("FCONF: arm-io_policies.%s cell found with value = 0x%x 0x%x 0x%x 0x%x\n", + load_info[i].name, + uuid_helper.word[0], uuid_helper.word[1], + uuid_helper.word[2], uuid_helper.word[3]); + + uuid_ptr->uuid = uuid_helper.uuid_struct; + policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr; + policies[load_info[i].image_id].dev_handle = &fip_dev_handle; + policies[load_info[i].image_id].check = open_fip; + } + return 0; +} + +#if ARM_IO_IN_DTB +FCONF_REGISTER_POPULATOR(TB_FW, arm_io, fconf_populate_arm_io_policies); +#endif /* ARM_IO_IN_DTB */ + +#endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c new file mode 100644 index 000000000..7950e7f6d --- /dev/null +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <common/desc_image_load.h> +#include <common/fdt_wrappers.h> +#include <drivers/io/io_storage.h> +#include <lib/object_pool.h> +#include <libfdt.h> +#include <plat/arm/common/arm_fconf_getter.h> +#include <plat/arm/common/arm_fconf_io_storage.h> +#include <plat/arm/common/fconf_arm_sp_getter.h> +#include <platform_def.h> +#include <tools_share/firmware_image_package.h> + +#ifdef IMAGE_BL2 + +bl_mem_params_node_t sp_mem_params_descs[MAX_SP_IDS]; + +struct arm_sp_t arm_sp; + +int fconf_populate_arm_sp(uintptr_t config) +{ + int sp_node, node, err; + union uuid_helper_t uuid_helper; + unsigned int index = 0; + uint32_t val32; + bool is_plat_owned = false; + const unsigned int sip_start = SP_PKG1_ID; + unsigned int sip_index = sip_start; + const unsigned int sip_end = sip_start + MAX_SP_IDS / 2; + const unsigned int plat_start = SP_PKG5_ID; + unsigned int plat_index = plat_start; + const unsigned int plat_end = plat_start + MAX_SP_IDS / 2; + unsigned int j; + + /* As libfdt use void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "arm,sp" compatible property */ + const char *compatible_str = "arm,sp"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s in dtb\n", compatible_str); + return node; + } + + fdt_for_each_subnode(sp_node, dtb, node) { + if ((index == MAX_SP_IDS) || (sip_index == sip_end) + || (plat_index == plat_end)) { + ERROR("FCONF: Reached max number of SPs\n"); + return -1; + } + + /* Read UUID */ + err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, + uuid_helper.word); + if (err < 0) { + ERROR("FCONF: cannot read SP uuid\n"); + return -1; + } + + /* Convert uuid from big endian to little endian */ + for (j = 0U; j < 4U; j++) { + uuid_helper.word[j] = + ((uuid_helper.word[j] >> 24U) & 0xff) | + ((uuid_helper.word[j] << 8U) & 0xff0000) | + ((uuid_helper.word[j] >> 8U) & 0xff00) | + ((uuid_helper.word[j] << 24U) & 0xff000000); + } + + arm_sp.uuids[index] = uuid_helper; + VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", + __func__, + uuid_helper.word[0], + uuid_helper.word[1], + uuid_helper.word[2], + uuid_helper.word[3], + 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 */ + fdtw_read_string(dtb, sp_node, "owner", + arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN); +#endif + /* If owner is empty mark it as SiP owned */ + if ((strncmp(arm_sp.owner[index], "SiP", + ARM_SP_OWNER_NAME_LEN) == 0) || + (strncmp(arm_sp.owner[index], "", + ARM_SP_OWNER_NAME_LEN) == 0)) { + is_plat_owned = false; + } else if (strcmp(arm_sp.owner[index], "Plat") == 0) { + is_plat_owned = true; + } else { + ERROR("FCONF: %s is not a valid SP owner\n", + arm_sp.owner[index]); + return -1; + } + /* + * Add SP information in mem param descriptor and IO policies + * structure. + */ + if (is_plat_owned) { + sp_mem_params_descs[index].image_id = plat_index; + policies[plat_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[plat_index].dev_handle = &fip_dev_handle; + policies[plat_index].check = open_fip; + plat_index++; + } else { + sp_mem_params_descs[index].image_id = sip_index; + policies[sip_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[sip_index].dev_handle = &fip_dev_handle; + policies[sip_index].check = open_fip; + sip_index++; + } + SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info, + PARAM_IMAGE_BINARY, VERSION_2, 0); + sp_mem_params_descs[index].image_info.image_max_size = + ARM_SP_MAX_SIZE; + sp_mem_params_descs[index].next_handoff_image_id = + INVALID_IMAGE_ID; + sp_mem_params_descs[index].image_info.image_base = + arm_sp.load_addr[index]; + index++; + } + + if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { + ERROR("%u: fdt_for_each_subnode(): %d\n", __LINE__, node); + return sp_node; + } + + arm_sp.number_of_sp = index; + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, arm_sp, fconf_populate_arm_sp); + +#endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/fconf/fconf_nv_cntr_getter.c b/plat/arm/common/fconf/fconf_nv_cntr_getter.c new file mode 100644 index 000000000..8d645ef3d --- /dev/null +++ b/plat/arm/common/fconf/fconf_nv_cntr_getter.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> + +#include <libfdt.h> + +#include <plat/arm/common/fconf_nv_cntr_getter.h> + +/******************************************************************************* + * fconf_populate_cot_descs() - Populate available nv-counters and update global + * structure. + * @config[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int fconf_populate_nv_cntrs(uintptr_t config) +{ + int rc, node, child; + uint32_t id; + uintptr_t reg; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + const char *compatible_str = "arm, non-volatile-counter"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in node\n", + compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + + rc = fdt_read_uint32(dtb, child, "id", &id); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "id"); + return rc; + } + + assert(id < MAX_NV_CTR_IDS); + + rc = fdt_get_reg_props_by_index(dtb, child, 0, ®, NULL); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "reg"); + return rc; + } + + nv_cntr_base_addr[id] = reg; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs); diff --git a/plat/arm/common/fconf/fconf_sdei_getter.c b/plat/arm/common/fconf/fconf_sdei_getter.c new file mode 100644 index 000000000..c26e316a5 --- /dev/null +++ b/plat/arm/common/fconf/fconf_sdei_getter.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <libfdt.h> +#include <plat/arm/common/fconf_sdei_getter.h> + +#define PRIVATE_EVENT_NUM(i) private_events[3 * (i)] +#define PRIVATE_EVENT_INTR(i) private_events[3 * (i) + 1] +#define PRIVATE_EVENT_FLAGS(i) private_events[3 * (i) + 2] + +#define SHARED_EVENT_NUM(i) shared_events[3 * (i)] +#define SHARED_EVENT_INTR(i) shared_events[3 * (i) + 1] +#define SHARED_EVENT_FLAGS(i) shared_events[3 * (i) + 2] + +struct sdei_dyn_config_t sdei_dyn_config; + +int fconf_populate_sdei_dyn_config(uintptr_t config) +{ + uint32_t i; + int node, err; + uint32_t private_events[PLAT_SDEI_DP_EVENT_MAX_CNT * 3]; + uint32_t shared_events[PLAT_SDEI_DS_EVENT_MAX_CNT * 3]; + + const void *dtb = (void *)config; + + /* Check that the node offset points to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, "arm,sdei-1.0"); + if (node < 0) { + ERROR("FCONF: Can't find 'arm,sdei-1.0' compatible node in dtb\n"); + return node; + } + + /* Read number of private mappings */ + err = fdt_read_uint32(dtb, node, "private_event_count", + &sdei_dyn_config.private_ev_cnt); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'private_event_count': %u\n", + sdei_dyn_config.private_ev_cnt); + return err; + } + + /* Check if the value is in range */ + if (sdei_dyn_config.private_ev_cnt > PLAT_SDEI_DP_EVENT_MAX_CNT) { + ERROR("FCONF: Invalid value for 'private_event_count': %u\n", + sdei_dyn_config.private_ev_cnt); + return -1; + } + + /* Read private mappings */ + err = fdt_read_uint32_array(dtb, node, "private_events", + sdei_dyn_config.private_ev_cnt * 3, private_events); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'private_events': %d\n", err); + return err; + } + + /* Move data to fconf struct */ + for (i = 0; i < sdei_dyn_config.private_ev_cnt; i++) { + sdei_dyn_config.private_ev_nums[i] = PRIVATE_EVENT_NUM(i); + sdei_dyn_config.private_ev_intrs[i] = PRIVATE_EVENT_INTR(i); + sdei_dyn_config.private_ev_flags[i] = PRIVATE_EVENT_FLAGS(i); + } + + /* Read number of shared mappings */ + err = fdt_read_uint32(dtb, node, "shared_event_count", + &sdei_dyn_config.shared_ev_cnt); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'shared_event_count'\n"); + return err; + } + + /* Check if the value is in range */ + if (sdei_dyn_config.shared_ev_cnt > PLAT_SDEI_DS_EVENT_MAX_CNT) { + ERROR("FCONF: Invalid value for 'shared_event_count': %u\n", + sdei_dyn_config.shared_ev_cnt); + return -1; + } + + /* Read shared mappings */ + err = fdt_read_uint32_array(dtb, node, "shared_events", + sdei_dyn_config.shared_ev_cnt * 3, shared_events); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'shared_events': %d\n", err); + return err; + } + + /* Move data to fconf struct */ + for (i = 0; i < sdei_dyn_config.shared_ev_cnt; i++) { + sdei_dyn_config.shared_ev_nums[i] = SHARED_EVENT_NUM(i); + sdei_dyn_config.shared_ev_intrs[i] = SHARED_EVENT_INTR(i); + sdei_dyn_config.shared_ev_flags[i] = SHARED_EVENT_FLAGS(i); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, sdei, fconf_populate_sdei_dyn_config); diff --git a/plat/arm/common/fconf/fconf_sec_intr_config.c b/plat/arm/common/fconf/fconf_sec_intr_config.c new file mode 100644 index 000000000..f28be240e --- /dev/null +++ b/plat/arm/common/fconf/fconf_sec_intr_config.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <assert.h> + +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <libfdt.h> +#include <plat/arm/common/fconf_sec_intr_config.h> + +#define G0_INTR_NUM(i) g0_intr_prop[3U * (i)] +#define G0_INTR_PRIORITY(i) g0_intr_prop[3U * (i) + 1] +#define G0_INTR_CONFIG(i) g0_intr_prop[3U * (i) + 2] + +#define G1S_INTR_NUM(i) g1s_intr_prop[3U * (i)] +#define G1S_INTR_PRIORITY(i) g1s_intr_prop[3U * (i) + 1] +#define G1S_INTR_CONFIG(i) g1s_intr_prop[3U * (i) + 2] + +struct sec_intr_prop_t sec_intr_prop; + +static void print_intr_prop(interrupt_prop_t prop) +{ + VERBOSE("FCONF: Secure Interrupt NUM: %d, PRI: %d, TYPE: %d\n", + prop.intr_num, prop.intr_pri, prop.intr_cfg); +} + +int fconf_populate_sec_intr_config(uintptr_t config) +{ + int node, err; + uint32_t g0_intr_count, g1s_intr_count; + uint32_t g0_intr_prop[SEC_INT_COUNT_MAX * 3]; + uint32_t g1s_intr_prop[SEC_INT_COUNT_MAX * 3]; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, + "arm,secure_interrupt_desc"); + if (node < 0) { + ERROR("FCONF: Unable to locate node with %s compatible property\n", + "arm,secure_interrupt_desc"); + return node; + } + + /* Read number of Group 0 interrupts specified by platform */ + err = fdt_read_uint32(hw_config_dtb, node, "g0_intr_cnt", &g0_intr_count); + if (err < 0) { + ERROR("FCONF: Could not locate g0s_intr_cnt property\n"); + return err; + } + + /* At least 1 Group 0 interrupt description has to be provided*/ + if (g0_intr_count < 1U) { + ERROR("FCONF: Invalid number of Group 0 interrupts count specified\n"); + return -1; + } + + /* Read number of Group 1 secure interrupts specified by platform */ + err = fdt_read_uint32(hw_config_dtb, node, "g1s_intr_cnt", + &g1s_intr_count); + if (err < 0) { + ERROR("FCONF: Could not locate g1s_intr_cnt property\n"); + return err; + } + + /* At least one Group 1 interrupt description has to be provided*/ + if (g1s_intr_count < 1U) { + ERROR("FCONF: Invalid number of Group 1 secure interrupts count specified\n"); + return -1; + } + + /* + * Check if the total number of secure interrupts described are within + * the limit defined statically by the platform. + */ + if ((g0_intr_count + g1s_intr_count) > SEC_INT_COUNT_MAX) { + ERROR("FCONF: Total number of secure interrupts exceed limit the of %d\n", + SEC_INT_COUNT_MAX); + return -1; + } + + sec_intr_prop.count = g0_intr_count + g1s_intr_count; + + /* Read the Group 0 interrupt descriptors */ + err = fdt_read_uint32_array(hw_config_dtb, node, "g0_intr_desc", + g0_intr_count * 3, g0_intr_prop); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'g0s_intr_desc': %d\n", err); + return err; + } + + /* Read the Group 1 secure interrupt descriptors */ + err = fdt_read_uint32_array(hw_config_dtb, node, "g1s_intr_desc", + g1s_intr_count * 3, g1s_intr_prop); + if (err < 0) { + ERROR("FCONF: Read cell failed for 'g1s_intr_desc': %d\n", err); + return err; + } + + /* Populate Group 0 interrupt descriptors into fconf based C struct */ + for (uint32_t i = 0; i < g0_intr_count; i++) { + interrupt_prop_t sec_intr_property; + + /* Secure Interrupt Group: INTR_GROUP0 i.e., 0x1 */ + sec_intr_property.intr_grp = 1; + sec_intr_property.intr_num = G0_INTR_NUM(i); + sec_intr_property.intr_pri = G0_INTR_PRIORITY(i); + sec_intr_property.intr_cfg = G0_INTR_CONFIG(i); + sec_intr_prop.descriptor[i] = sec_intr_property; + print_intr_prop(sec_intr_property); + } + + /* Populate G1 secure interrupt descriptors into fconf based C struct */ + for (uint32_t i = 0; i < g1s_intr_count; i++) { + interrupt_prop_t sec_intr_property; + + /* Secure Interrupt Group: INTR_GROUP1S i.e., 0x0 */ + sec_intr_property.intr_grp = 0; + sec_intr_property.intr_num = G1S_INTR_NUM(i); + sec_intr_property.intr_pri = G1S_INTR_PRIORITY(i); + sec_intr_property.intr_cfg = G1S_INTR_CONFIG(i); + sec_intr_prop.descriptor[i + g0_intr_count] = sec_intr_property; + print_intr_prop(sec_intr_property); + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, sec_intr_prop, fconf_populate_sec_intr_config); diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index bb69914ae..270093c4e 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,6 @@ #include <bl32/sp_min/platform_sp_min.h> #include <common/bl_common.h> #include <common/debug.h> -#include <drivers/arm/pl011.h> #include <drivers/console.h> #include <lib/mmio.h> #include <plat/arm/common/plat_arm.h> @@ -30,10 +29,10 @@ static entry_point_info_t bl33_image_ep_info; MT_MEMORY | MT_RW | MT_SECURE) /* - * Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page + * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. */ -CASSERT(BL32_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl32_base_overflows); +CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows); /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the @@ -168,6 +167,10 @@ void arm_sp_min_plat_runtime_setup(void) { /* Initialize the runtime console */ arm_console_runtime_init(); + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } /******************************************************************************* @@ -183,7 +186,7 @@ void sp_min_platform_setup(void) * Do initial security configuration to allow DRAM/device access * (if earlier BL has not already done so). */ -#if RESET_TO_SP_MIN +#if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME plat_arm_security_setup(); #if defined(PLAT_ARM_MEM_PROT_ADDR) @@ -214,7 +217,7 @@ void sp_min_plat_runtime_setup(void) * Perform the very early platform specific architectural setup here. At the * moment this only initializes the MMU ******************************************************************************/ -void sp_min_plat_arch_setup(void) +void arm_sp_min_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { MAP_BL_SP_MIN_TOTAL, @@ -229,3 +232,8 @@ void sp_min_plat_arch_setup(void) enable_mmu_svc_mon(0); } + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); +} diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c index aefdf89c7..a4da8c35e 100644 --- a/plat/arm/common/tsp/arm_tsp_setup.c +++ b/plat/arm/common/tsp/arm_tsp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,7 +28,7 @@ /******************************************************************************* * Initialize the UART ******************************************************************************/ -static console_pl011_t arm_tsp_runtime_console; +static console_t arm_tsp_runtime_console; void arm_tsp_early_platform_setup(void) { @@ -43,7 +43,7 @@ void arm_tsp_early_platform_setup(void) if (rc == 0) panic(); - console_set_scope(&arm_tsp_runtime_console.console, + console_set_scope(&arm_tsp_runtime_console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); } @@ -79,4 +79,8 @@ void tsp_plat_arch_setup(void) setup_page_tables(bl_regions, plat_arm_get_mmap()); enable_mmu_el1(0); + +#if PLAT_RO_XLAT_TABLES + arm_xlat_make_tables_readonly(); +#endif } |