diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index 6fe551188..1dfdc459b 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -38,27 +38,6 @@ uint64_t bl1_apiakey[2]; BL_TOTAL_IDS, PMF_DUMP_ENABLE) #endif -/******************************************************************************* - * Helper utility to calculate the BL2 memory layout taking into consideration - * the BL1 RW data assuming that it is at the top of the memory layout. - ******************************************************************************/ -void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout, - meminfo_t *bl2_mem_layout) -{ - assert(bl1_mem_layout != NULL); - assert(bl2_mem_layout != NULL); - - /* - * Remove BL1 RW data from the scope of memory visible to BL2. - * This is assuming BL1 RW data is at the top of bl1_mem_layout. - */ - assert(BL1_RW_BASE > bl1_mem_layout->total_base); - bl2_mem_layout->total_base = bl1_mem_layout->total_base; - bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base; - - flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t)); -} - /******************************************************************************* * Setup function for BL1. ******************************************************************************/ diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index 7c66d1118..5d9840aab 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -1712,6 +1712,18 @@ This function can be used by the platforms to update/use image information corresponding to ``image_id``. This function is invoked in BL1, both in cold boot and FWU code path, before loading the image. +Function : bl1_plat_calc_bl2_layout() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : const meminfo_t *bl1_mem_layout, meminfo_t *bl2_mem_layout + Return : void + +This utility function calculates the memory layout of BL2, representing it in a +`meminfo_t` structure. The default implementation derives this layout from the +positioning of BL1’s RW data at the top of the memory layout. + Function : bl1_plat_handle_post_image_load() [optional] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h index 7cd7e727c..3ab88de96 100644 --- a/include/bl1/bl1.h +++ b/include/bl1/bl1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -94,9 +94,5 @@ CASSERT(FWU_NUM_SMC_CALLS == (FWU_SMC_FID_END - FWU_SMC_FID_START + 1), assert_FWU_NUM_SMC_CALLS_mismatch); -/* Utility functions */ -void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout, - meminfo_t *bl2_mem_layout); - #endif /* __ASSEMBLER__ */ #endif /* BL1_H */ diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h index c5df22bb2..5bea2705c 100644 --- a/include/lib/transfer_list.h +++ b/include/lib/transfer_list.h @@ -44,6 +44,8 @@ enum transfer_list_tag_id { TL_TAG_OPTEE_PAGABLE_PART = 0x100, TL_TAG_DT_SPMC_MANIFEST = 0x101, TL_TAG_EXEC_EP_INFO64 = 0x102, + TL_TAG_TB_FW_CONFIG = 0x103, + TL_TAG_SRAM_LAYOUT64 = 0x104, }; enum transfer_list_ops { diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index c3a88e7cb..ec5f90bf1 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -411,6 +411,8 @@ MEASURED_BOOT #define ARM_V2M_MAP_MEM_PROTECT MAP_REGION_FLAT(PLAT_ARM_MEM_PROT_ADDR, \ V2M_FLASH_BLOCK_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) + +#if !TRANSFER_LIST /* * Map the region for device tree configuration with read and write permissions */ @@ -418,6 +420,8 @@ MEASURED_BOOT (ARM_FW_CONFIGS_LIMIT \ - ARM_BL_RAM_BASE), \ MT_MEMORY | MT_RW | EL3_PAS) +#endif + /* * Map L0_GPT with read and write permissions */ @@ -505,6 +509,14 @@ MEASURED_BOOT */ #define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) +/* Define memory configuration for trusted boot device tree files. */ +#ifdef PLAT_ARM_TB_FW_CONFIG_SIZE +#define ARM_TB_FW_CONFIG_MAX_SIZE PLAT_ARM_TB_FW_CONFIG_SIZE +#else +#define ARM_TB_FW_CONFIG_MAX_SIZE U(0x400) +#endif + +#if !TRANSFER_LIST /* * To enable FW_CONFIG to be loaded by BL1, define the corresponding base * and limit. Leave enough space of BL2 meminfo. @@ -526,6 +538,7 @@ MEASURED_BOOT */ #define ARM_FW_CONFIGS_SIZE (PAGE_SIZE * 2) #define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE) +#endif #if ENABLE_RME /* diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index a43e13c82..48d70688f 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -9,12 +9,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -254,6 +256,7 @@ uint32_t arm_get_spsr_for_bl33_entry(void); int arm_bl2_plat_handle_post_image_load(unsigned int image_id); int arm_bl2_handle_post_image_load(unsigned int image_id); struct bl_params *arm_get_next_bl_params(void); +void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node); /* BL2 at EL3 functions */ void arm_bl2_el3_early_platform_setup(void); @@ -266,12 +269,25 @@ void arm_bl2u_platform_setup(void); void arm_bl2u_plat_arch_setup(void); /* BL31 utility functions */ +#if TRANSFER_LIST +void arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3); +#else void arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config, uintptr_t hw_config, void *plat_params_from_bl2); +#endif void arm_bl31_platform_setup(void); void arm_bl31_plat_runtime_setup(void); void arm_bl31_plat_arch_setup(void); +/* Firmware Handoff utility functions */ +void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl); +void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, + struct transfer_list_header *secure_tl, + struct transfer_list_header *ns_tl); +void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl, + struct transfer_list_header *ns_tl); + /* TSP utility functions */ void arm_tsp_early_platform_setup(void); diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 4fe362005..2af49a93e 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -243,7 +243,11 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved); int bl1_plat_handle_pre_image_load(unsigned int image_id); int bl1_plat_handle_post_image_load(unsigned int image_id); -#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT) +/* Utility functions */ +void bl1_plat_calc_bl2_layout(const meminfo_t *bl1_mem_layout, + meminfo_t *bl2_mem_layout); + +#if MEASURED_BOOT void bl1_plat_mboot_init(void); void bl1_plat_mboot_finish(void); #else diff --git a/lib/transfer_list/transfer_list.mk b/lib/transfer_list/transfer_list.mk index 42574e85d..3ec4df236 100644 --- a/lib/transfer_list/transfer_list.mk +++ b/lib/transfer_list/transfer_list.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -15,6 +15,7 @@ TRANSFER_LIST_SOURCES += $(addprefix lib/transfer_list/, \ BL31_SOURCES += $(TRANSFER_LIST_SOURCES) BL2_SOURCES += $(TRANSFER_LIST_SOURCES) +BL1_SOURCES += $(TRANSFER_LIST_SOURCES) endif # TRANSFER_LIST diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 97d000e7f..ebdd80d45 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -20,8 +20,6 @@ #include "fvp_private.h" -static struct transfer_list_header *ns_tl __unused; - #if ENABLE_RME /* * The GPT library might modify the gpt regions structure to optimize @@ -50,6 +48,11 @@ static const arm_gpt_info_t arm_gpt_info = { void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { + struct transfer_list_entry *te __unused; + +#if TRANSFER_LIST + arg0 = arg3; +#endif arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1); /* Initialize the platform config for future decision making */ @@ -60,10 +63,6 @@ void bl2_platform_setup(void) { arm_bl2_platform_setup(); -#if TRANSFER_LIST - ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE); - assert(ns_tl != NULL); -#endif /* Initialize System level generic or SP804 timer */ fvp_timer_init(); } @@ -81,16 +80,15 @@ const arm_gpt_info_t *plat_arm_get_gpt_info(void) struct bl_params *plat_get_next_bl_params(void) { struct bl_params *arm_bl_params; - const struct dyn_cfg_dtb_info_t *hw_config_info __unused; - struct transfer_list_entry *te __unused; bl_mem_params_node_t *param_node __unused; + const struct dyn_cfg_dtb_info_t *fw_config_info __unused; + const struct dyn_cfg_dtb_info_t *hw_config_info __unused; + entry_point_info_t *ep __unused; + uint32_t next_exe_img_id __unused; + uintptr_t fw_config_base __unused; arm_bl_params = arm_get_next_bl_params(); -#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE - const struct dyn_cfg_dtb_info_t *fw_config_info; - uintptr_t fw_config_base = 0UL; - #if __aarch64__ /* Get BL31 image node */ param_node = get_bl_mem_params_node(BL31_IMAGE_ID); @@ -100,6 +98,15 @@ struct bl_params *plat_get_next_bl_params(void) #endif /* __aarch64__ */ assert(param_node != NULL); +#if TRANSFER_LIST + arm_bl_params->head = ¶m_node->params_node_mem; + arm_bl_params->head->ep_info = ¶m_node->ep_info; + arm_bl_params->head->image_id = param_node->image_id; + + arm_bl2_setup_next_ep_info(param_node); +#elif !RESET_TO_BL2 && !EL3_PAYLOAD_BASE + fw_config_base = 0UL; + /* Update the next image's ep info with the FW config address */ fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); assert(fw_config_info != NULL); @@ -113,49 +120,29 @@ struct bl_params *plat_get_next_bl_params(void) param_node = get_bl_mem_params_node(BL33_IMAGE_ID); assert(param_node != NULL); -#if TRANSFER_LIST - /* Update BL33's ep info with NS HW config address */ - te = transfer_list_find(ns_tl, TL_TAG_FDT); - assert(te != NULL); - - param_node->ep_info.args.arg1 = TRANSFER_LIST_SIGNATURE | - REGISTER_CONVENTION_VERSION_MASK; - param_node->ep_info.args.arg2 = 0; - param_node->ep_info.args.arg3 = (uintptr_t)ns_tl; - param_node->ep_info.args.arg0 = - te ? (uintptr_t)transfer_list_entry_data(te) : 0; -#else hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID); assert(hw_config_info != NULL); param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr; #endif /* TRANSFER_LIST */ -#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */ return arm_bl_params; } int bl2_plat_handle_post_image_load(unsigned int image_id) { -#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE +#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE && !TRANSFER_LIST if (image_id == HW_CONFIG_ID) { - const struct dyn_cfg_dtb_info_t *hw_config_info; + const struct dyn_cfg_dtb_info_t *hw_config_info __unused; struct transfer_list_entry *te __unused; + bl_mem_params_node_t *param_node __unused; - const bl_mem_params_node_t *param_node = - get_bl_mem_params_node(image_id); + param_node = get_bl_mem_params_node(image_id); assert(param_node != NULL); hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID); assert(hw_config_info != NULL); -#if TRANSFER_LIST - /* Update BL33's ep info with NS HW config address */ - te = transfer_list_add(ns_tl, TL_TAG_FDT, - param_node->image_info.image_size, - (void *)hw_config_info->config_addr); - assert(te != NULL); -#else memcpy((void *)hw_config_info->secondary_config_addr, (void *)hw_config_info->config_addr, (size_t)param_node->image_info.image_size); @@ -166,9 +153,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) */ flush_dcache_range(hw_config_info->secondary_config_addr, param_node->image_info.image_size); -#endif /* TRANSFER_LIST */ } -#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */ +#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE && !TRANSFER_LIST*/ return arm_bl2_plat_handle_post_image_load(image_id); } diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 93289b6b5..e08756562 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -5,12 +5,15 @@ */ #include + +#include #include #include #include #include #include #include + #include #include #include @@ -25,6 +28,9 @@ void __init bl31_early_platform_setup2(u_register_t arg0, /* Initialize the console to provide early debug support */ arm_console_boot_init(); +#if TRANSFER_LIST + arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3); +#else #if !RESET_TO_BL31 && !RESET_TO_BL2 const struct dyn_cfg_dtb_info_t *soc_fw_config_info; @@ -48,8 +54,8 @@ void __init bl31_early_platform_setup2(u_register_t arg0, assert(hw_config_info->secondary_config_addr != 0UL); arg2 = hw_config_info->secondary_config_addr; #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */ - arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); +#endif /* TRANSFER_LIST */ /* Initialize the platform config for future decision making */ fvp_config_setup(); @@ -88,6 +94,7 @@ void __init bl31_early_platform_setup2(u_register_t arg0, } } +#if !TRANSFER_LIST void __init bl31_plat_arch_setup(void) { int rc __unused; @@ -142,6 +149,7 @@ void __init bl31_plat_arch_setup(void) } #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1 */ } +#endif /* TRANSFER_LIST */ unsigned int plat_get_syscnt_freq2(void) { diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 8cbf10eb1..5557d5991 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -81,9 +81,14 @@ arm_config_t arm_config; #if TRANSFER_LIST #ifdef FW_NS_HANDOFF_BASE -#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, \ - FW_HANDOFF_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) +#define MAP_FW_NS_HANDOFF \ + MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) +#endif +#ifdef PLAT_ARM_EL3_FW_HANDOFF_BASE +#define MAP_EL3_FW_HANDOFF \ + MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \ + PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS) #endif #endif @@ -165,7 +170,10 @@ defined(SPD_spmd)) ARM_MAP_OPTEE_CORE_MEM, ARM_OPTEE_PAGEABLE_LOAD_MEM, #endif - {0} +#ifdef MAP_EL3_FW_HANDOFF + MAP_EL3_FW_HANDOFF, +#endif + { 0 } }; #endif #ifdef IMAGE_BL2U @@ -202,7 +210,10 @@ const mmap_region_t plat_arm_mmap[] = { #ifdef MAP_FW_NS_HANDOFF MAP_FW_NS_HANDOFF, #endif - {0} +#ifdef MAP_EL3_FW_HANDOFF + MAP_EL3_FW_HANDOFF, +#endif + { 0 } }; #if defined(IMAGE_BL31) && SPM_MM diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index ab1b07f82..56de8b8ef 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -143,8 +143,14 @@ #define PLAT_ARM_NS_IMAGE_BASE (ARM_DRAM1_BASE + UL(0x8000000)) #if TRANSFER_LIST -#define FW_HANDOFF_SIZE 0x4000 -#define FW_NS_HANDOFF_BASE (PLAT_ARM_NS_IMAGE_BASE - FW_HANDOFF_SIZE) +#define PLAT_ARM_FW_HANDOFF_SIZE U(0x5000) + +#define FW_NS_HANDOFF_BASE (PLAT_ARM_NS_IMAGE_BASE - PLAT_ARM_FW_HANDOFF_SIZE) +#define PLAT_ARM_EL3_FW_HANDOFF_BASE ARM_BL_RAM_BASE +#define PLAT_ARM_EL3_FW_HANDOFF_LIMIT PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE + +#else +#define PLAT_ARM_FW_HANDOFF_SIZE U(0) #endif /* @@ -269,9 +275,15 @@ defined(IMAGE_BL2) && MEASURED_BOOT * BL2 and BL1-RW. * Size of the BL31 PROGBITS increases as the SRAM size increases. */ +#if TRANSFER_LIST +#define PLAT_ARM_MAX_BL31_SIZE \ + (PLAT_ARM_TRUSTED_SRAM_SIZE - ARM_SHARED_RAM_SIZE - \ + PLAT_ARM_FW_HANDOFF_SIZE - ARM_L0_GPT_SIZE) +#else #define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ ARM_SHARED_RAM_SIZE - \ ARM_FW_CONFIGS_SIZE - ARM_L0_GPT_SIZE) +#endif /* TRANSFER_LIST */ #endif /* RESET_TO_BL31 */ #ifndef __aarch64__ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 8fa01ffe5..07e69e69a 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -330,9 +330,23 @@ else BL31_SOURCES += drivers/delay_timer/generic_delay_timer.c endif +ifeq (${TRANSFER_LIST}, 1) +include lib/transfer_list/transfer_list.mk +endif + # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts + +FDT_SOURCES += ${FVP_HW_CONFIG_DTS} +$(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS))) + +ifeq (${TRANSFER_LIST}, 1) +FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ + ${PLAT}_tb_fw_config.dts \ + ) +else FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ ${PLAT}_fw_config.dts \ ${PLAT}_tb_fw_config.dts \ @@ -341,7 +355,6 @@ FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ ) FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb -FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_SOC_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb @@ -353,10 +366,6 @@ FVP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG})) endif -ifeq (${TRANSFER_LIST}, 1) -include lib/transfer_list/transfer_list.mk -endif - ifeq (${SPD},spmd) ifeq ($(ARM_SPMC_MANIFEST_DTS),) @@ -372,16 +381,14 @@ endif # Add the FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG})) -# Add the TB_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG})) # Add the SOC_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG})) # Add the NT_FW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG})) +endif -FDT_SOURCES += ${FVP_HW_CONFIG_DTS} -$(eval FVP_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS))) - +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG})) # Add the HW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG})) endif diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c index 252fc31fb..29495cfcb 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_main.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c @@ -91,27 +91,6 @@ void bl1_load_bl33(void) NOTICE("BL1: Booting BL33\n"); } -/******************************************************************************* - * Helper utility to calculate the BL2 memory layout taking into consideration - * the BL1 RW data assuming that it is at the top of the memory layout. - ******************************************************************************/ -void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout, - meminfo_t *bl2_mem_layout) -{ - assert(bl1_mem_layout != NULL); - assert(bl2_mem_layout != NULL); - - /* - * Remove BL1 RW data from the scope of memory visible to BL2. - * This is assuming BL1 RW data is at the top of bl1_mem_layout. - */ - assert(bl1_mem_layout->total_base < BL1_RW_BASE); - bl2_mem_layout->total_base = bl1_mem_layout->total_base; - bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base; - - flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t)); -} - /******************************************************************************* * This function prepares for entry to BL33 ******************************************************************************/ diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c index 6a7c0c808..dcf5e0465 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -235,7 +235,7 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) */ bl33_secram_layout = (meminfo_t *) bl1_secram_layout->total_base; - bl1_calc_bl2_mem_layout(bl1_secram_layout, bl33_secram_layout); + bl1_plat_calc_bl2_layout(bl1_secram_layout, bl33_secram_layout); ep_info->args.arg1 = (uintptr_t)bl33_secram_layout; diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index feff6913d..f043f59dd 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,9 @@ #include #include #include +#if TRANSFER_LIST +#include +#endif #include #include #include @@ -61,6 +64,10 @@ static meminfo_t bl1_tzram_layout; /* Boolean variable to hold condition whether firmware update needed or not */ static bool is_fwu_needed; +#if TRANSFER_LIST +static struct transfer_list_header *secure_tl; +#endif + struct meminfo *bl1_plat_sec_mem_layout(void) { return &bl1_tzram_layout; @@ -144,9 +151,13 @@ void bl1_plat_arch_setup(void) */ void arm_bl1_platform_setup(void) { - const struct dyn_cfg_dtb_info_t *fw_config_info; + const struct dyn_cfg_dtb_info_t *config_info __unused; + uint32_t fw_config_max_size __unused; + image_info_t config_image_info __unused; + struct transfer_list_entry *te __unused; + image_desc_t *desc; - uint32_t fw_config_max_size; + int err = -1; /* Initialise the IO layer and register platform IO devices */ @@ -159,6 +170,37 @@ void arm_bl1_platform_setup(void) return; } +#if TRANSFER_LIST + secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE, + PLAT_ARM_FW_HANDOFF_SIZE); + + if (secure_tl == NULL) { + ERROR("Secure transfer list initialisation failed!\n"); + panic(); + } + + te = transfer_list_add(secure_tl, TL_TAG_TB_FW_CONFIG, + ARM_TB_FW_CONFIG_MAX_SIZE, NULL); + assert(te != NULL); + + /* + * Set the load address of TB_FW_CONFIG in the data section of the TE just + * allocated in the secure transfer list. + */ + SET_PARAM_HEAD(&config_image_info, PARAM_IMAGE_BINARY, VERSION_2, 0); + config_image_info.image_base = (uintptr_t)transfer_list_entry_data(te); + config_image_info.image_max_size = te->data_size; + + VERBOSE("FCONF: Loading config with image ID: %u\n", TB_FW_CONFIG_ID); + err = load_auth_image(TB_FW_CONFIG_ID, &config_image_info); + if (err != 0) { + VERBOSE("Failed to load config %u\n", TB_FW_CONFIG_ID); + plat_error_handler(err); + } + + transfer_list_update_checksum(secure_tl); + fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te)); +#else /* 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, ~0UL, fw_config_max_size, FW_CONFIG_ID); @@ -174,13 +216,14 @@ void arm_bl1_platform_setup(void) * 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); + config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + if (config_info != NULL) { + err = fconf_populate_dtb_registry(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) { @@ -191,11 +234,17 @@ void arm_bl1_platform_setup(void) ERROR("Invalid FW_CONFIG address\n"); plat_error_handler(err); } +#endif /* TRANSFER_LIST */ - /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + +#if TRANSFER_LIST + transfer_list_set_handoff_args(secure_tl, &desc->ep_info); +#else + /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ assert(desc != NULL); - desc->ep_info.args.arg0 = fw_config_info->config_addr; + desc->ep_info.args.arg0 = config_info->config_addr; +#endif /* TRANSFER_LIST */ #if CRYPTO_SUPPORT /* Share the Mbed TLS heap info with other images */ @@ -250,3 +299,32 @@ unsigned int bl1_plat_get_next_image_id(void) { return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; } + +// Use the default implementation of this function when Firmware Handoff is +// disabled to avoid duplicating its logic. +#if TRANSFER_LIST +int bl1_plat_handle_post_image_load(unsigned int image_id) +{ + image_desc_t *image_desc __unused; + + assert(image_id == BL2_IMAGE_ID); + struct transfer_list_entry *te; + + /* Convey this information to BL2 via its TL. */ + te = transfer_list_add(secure_tl, TL_TAG_SRAM_LAYOUT64, + sizeof(meminfo_t), NULL); + assert(te != NULL); + + bl1_plat_calc_bl2_layout(&bl1_tzram_layout, + (meminfo_t *)transfer_list_entry_data(te)); + + transfer_list_update_checksum(secure_tl); + + /** + * Before exiting make sure the contents of the TL are flushed in case there's no + * support for hardware cache coherency. + */ + flush_dcache_range((uintptr_t)secure_tl, secure_tl->size); + return 0; +} +#endif /* TRANSFER_LIST*/ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 30d064791..877ae8f51 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -19,6 +19,9 @@ #include #include #include +#if TRANSFER_LIST +#include +#endif #ifdef SPD_opteed #include #endif @@ -30,13 +33,18 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); /* Base address of fw_config received from BL1 */ -static uintptr_t config_base; +static uintptr_t config_base __unused; /* * 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. */ +#if TRANSFER_LIST +CASSERT(BL2_BASE >= PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE, + assert_bl2_base_overflows); +#else CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); +#endif /* TRANSFER_LIST */ /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl2_early_platform_setup2 @@ -58,6 +66,9 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); #pragma weak arm_bl2_plat_handle_post_image_load +static struct transfer_list_header *secure_tl __unused; +static struct transfer_list_header *ns_tl __unused; + /******************************************************************************* * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 * in x0. This memory layout is sitting at the base of the free trusted SRAM. @@ -66,15 +77,27 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout) { + struct transfer_list_entry *te __unused; int __maybe_unused ret; /* Initialize the console to provide early debug support */ arm_console_boot_init(); +#if TRANSFER_LIST + // TODO: modify the prototype of this function fw_config != bl2_tl + secure_tl = (struct transfer_list_header *)fw_config; + + te = transfer_list_find(secure_tl, TL_TAG_SRAM_LAYOUT64); + assert(te != NULL); + + bl2_tzram_layout = *(meminfo_t *)transfer_list_entry_data(te); + transfer_list_rem(secure_tl, te); +#else + config_base = fw_config; + /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; - - config_base = fw_config; +#endif /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); @@ -103,7 +126,22 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_ */ void bl2_plat_preload_setup(void) { +#if TRANSFER_LIST +/* Assume the secure TL hasn't been initialised if BL2 is running at EL3. */ +#if RESET_TO_BL2 + secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE, + PLAT_ARM_FW_HANDOFF_SIZE); + + if (secure_tl == NULL) { + ERROR("Secure transfer list initialisation failed!\n"); + panic(); + } +#endif + + arm_transfer_list_dyn_cfg_init(secure_tl); +#else arm_bl2_dyn_cfg_init(); +#endif #if ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT /* Always use the FIP from bank 0 */ @@ -124,6 +162,16 @@ void arm_bl2_platform_setup(void) #if defined(PLAT_ARM_MEM_PROT_ADDR) arm_nor_psci_do_static_mem_protect(); #endif + +#if TRANSFER_LIST + ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, + PLAT_ARM_FW_HANDOFF_SIZE); + + if (ns_tl == NULL) { + ERROR("Non-secure transfer list initialisation failed!"); + panic(); + } +#endif } void bl2_platform_setup(void) @@ -151,11 +199,13 @@ void arm_bl2_plat_arch_setup(void) ARM_MAP_ROMLIB_CODE, ARM_MAP_ROMLIB_DATA, #endif +#if !TRANSFER_LIST ARM_MAP_BL_CONFIG_REGION, +#endif /* TRANSFER_LIST */ #if ENABLE_RME ARM_MAP_L0_GPT_REGION, #endif - {0} + { 0 } }; #if ENABLE_RME @@ -184,10 +234,17 @@ void arm_bl2_plat_arch_setup(void) void bl2_plat_arch_setup(void) { - const struct dyn_cfg_dtb_info_t *tb_fw_config_info; - + const struct dyn_cfg_dtb_info_t *tb_fw_config_info __unused; + struct transfer_list_entry *te __unused; arm_bl2_plat_arch_setup(); +#if TRANSFER_LIST + te = transfer_list_find(secure_tl, TL_TAG_TB_FW_CONFIG); + assert(te != NULL); + + fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te)); + transfer_list_rem(secure_tl, te); +#else /* Fill the properties struct with the info from the config dtb */ fconf_populate("FW_CONFIG", config_base); @@ -196,6 +253,7 @@ void bl2_plat_arch_setup(void) assert(tb_fw_config_info != NULL); fconf_populate("TB_FW", tb_fw_config_info->config_addr); +#endif } int arm_bl2_handle_post_image_load(unsigned int image_id) @@ -265,5 +323,20 @@ int arm_bl2_plat_handle_post_image_load(unsigned int image_id) return 0; } #endif + +#if TRANSFER_LIST + if (image_id == HW_CONFIG_ID) { + arm_transfer_list_copy_hw_config(secure_tl, ns_tl); + } +#endif /* TRANSFER_LIST */ + return arm_bl2_handle_post_image_load(image_id); } + +void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node) +{ + assert(transfer_list_set_handoff_args( + secure_tl, &next_param_node->ep_info) != NULL); + + arm_transfer_list_populate_ep_info(next_param_node, secure_tl, ns_tl); +} diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 33043b7b1..414ac40ca 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -13,13 +13,18 @@ #include #include #include +#include #include #include +#if TRANSFER_LIST +#include +#endif #include #include #include #include +static struct transfer_list_header *secure_tl __unused; /* * Placeholder variables for copying the arguments that have been passed to * BL31 from BL2. @@ -35,8 +40,12 @@ static entry_point_info_t rmm_image_ep_info; * 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. */ +#if TRANSFER_LIST +CASSERT(BL31_BASE >= PLAT_ARM_EL3_FW_HANDOFF_LIMIT, assert_bl31_base_overflows); +#else CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); -#endif +#endif /* TRANSFER_LIST */ +#endif /* RESET_TO_BL31 */ /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak bl31_early_platform_setup2 @@ -115,6 +124,44 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) * while creating page tables. BL2 has flushed this information to memory, so * we are guaranteed to pick up good data. ******************************************************************************/ +#if TRANSFER_LIST +void __init arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct transfer_list_entry *te = NULL; + struct entry_point_info *ep; + + secure_tl = (struct transfer_list_header *)arg3; + + /* + * Populate the global entry point structures used to execute subsequent + * images. + */ + while ((te = transfer_list_next(secure_tl, te)) != NULL) { + ep = transfer_list_entry_data(te); + + if (te->tag_id == TL_TAG_EXEC_EP_INFO64) { + switch (GET_SECURITY_STATE(ep->h.attr)) { + case NON_SECURE: + bl33_image_ep_info = *ep; + break; +#if ENABLE_RME + case REALM: + rmm_image_ep_info = *ep; + break; +#endif + case SECURE: + bl32_image_ep_info = *ep; + break; + default: + ERROR("Unrecognized Image Security State %lu\n", + GET_SECURITY_STATE(ep->h.attr)); + panic(); + } + } + } +} +#else void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config, uintptr_t hw_config, void *plat_params_from_bl2) { @@ -258,11 +305,16 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi bl33_image_ep_info.args.arg3 = 0U; # endif } +#endif void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { +#if TRANSFER_LIST + arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3); +#else arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); +#endif /* * Initialize Interconnect for this cluster during cold boot. @@ -448,5 +500,15 @@ void __init arm_bl31_plat_arch_setup(void) void __init bl31_plat_arch_setup(void) { + struct transfer_list_entry *te __unused; + arm_bl31_plat_arch_setup(); + +#if TRANSFER_LIST && !RESET_TO_BL2 + te = transfer_list_find(secure_tl, TL_TAG_FDT); + assert(te != NULL); + + /* Populate HW_CONFIG device tree with the mapped address */ + fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te)); +#endif } diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 5084ea95e..7ab39eb28 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -299,6 +299,10 @@ BL31_SOURCES += plat/arm/common/arm_bl31_setup.c \ plat/arm/common/arm_topology.c \ plat/common/plat_psci_common.c +ifeq (${TRANSFER_LIST}, 1) + TRANSFER_LIST_SOURCES += plat/arm/common/arm_transfer_list.c +endif + ifneq ($(filter 1,${ENABLE_PMF} ${ETHOSN_NPU_DRIVER}),) ARM_SVC_HANDLER_SRCS := diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index c411c6cbb..25252666f 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,7 +17,10 @@ #pragma weak plat_get_bl_image_load_info #pragma weak plat_get_next_bl_params -static bl_params_t *next_bl_params_cpy_ptr; +#if TRANSFER_LIST +static bl_params_t next_bl_params_cpy; +#endif +bl_params_t *next_bl_params_cpy_ptr; /******************************************************************************* * This function flushes the data structures so that they are visible @@ -96,9 +99,15 @@ struct bl_load_info *plat_get_bl_image_load_info(void) ******************************************************************************/ struct bl_params *arm_get_next_bl_params(void) { - bl_mem_params_node_t *bl2_mem_params_descs_cpy - = (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE; - const bl_params_t *next_bl_params; + bl_mem_params_node_t *bl2_mem_params_descs_cpy __unused; + const bl_params_t *next_bl_params __unused; + +#if TRANSFER_LIST + next_bl_params_cpy_ptr = &next_bl_params_cpy; + SET_PARAM_HEAD(next_bl_params_cpy_ptr, PARAM_BL_PARAMS, VERSION_2, 0U); +#else + bl2_mem_params_descs_cpy = + (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE; next_bl_params_cpy_ptr = (bl_params_t *)(ARM_BL2_MEM_DESC_BASE + @@ -127,6 +136,7 @@ struct bl_params *arm_get_next_bl_params(void) (sizeof(bl_params_t))); populate_next_bl_params_config(next_bl_params_cpy_ptr); +#endif /* TRANSFER_LIST */ return next_bl_params_cpy_ptr; } diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c new file mode 100644 index 000000000..d144bbb5b --- /dev/null +++ b/plat/arm/common/arm_transfer_list.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl) +{ + struct transfer_list_entry *te; + bl_mem_params_node_t *next_param_node = + get_bl_mem_params_node(HW_CONFIG_ID); + assert(next_param_node != NULL); + + /* + * The HW_CONFIG needs to be authenticated via the normal loading + * mechanism. Pre-allocate a TE for the configuration and update the + * load information so the configuration is loaded directly into the TE. + */ + te = transfer_list_add(secure_tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, + NULL); + assert(te != NULL); + + next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; + next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE; + next_param_node->image_info.image_base = + (uintptr_t)transfer_list_entry_data(te); +} + +void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, + struct transfer_list_header *secure_tl, + struct transfer_list_header *ns_tl) +{ + uint32_t next_exe_img_id; + entry_point_info_t *ep; + struct transfer_list_entry *te; + + assert(next_param_node != NULL); + + while ((next_exe_img_id = next_param_node->next_handoff_image_id) != + INVALID_IMAGE_ID) { + next_param_node = + &bl_mem_params_desc_ptr[get_bl_params_node_index( + next_exe_img_id)]; + assert(next_param_node != NULL); + + te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64, + sizeof(entry_point_info_t), + &next_param_node->ep_info); + assert(te != NULL); + + ep = transfer_list_entry_data(te); + + if (next_exe_img_id == BL33_IMAGE_ID) { + ep = transfer_list_set_handoff_args(ns_tl, ep); + assert(ep != NULL); + } else if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) { + /* + * Populate the BL32 image base, size and max limit in + * the entry point information, since there is no + * platform function to retrieve them in generic + * code. We choose arg2, arg3 and arg4 since the generic + * code uses arg1 for stashing the SP manifest size. The + * SPMC setup uses these arguments to update SP manifest + * with actual SP's base address and it size. + */ + ep->args.arg2 = next_param_node->image_info.image_base; + ep->args.arg3 = next_param_node->image_info.image_size; + ep->args.arg4 = + next_param_node->image_info.image_base + + next_param_node->image_info.image_max_size; + } + + next_exe_img_id = next_param_node->next_handoff_image_id; + } + + flush_dcache_range((uintptr_t)secure_tl, secure_tl->size); +} + +void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl, + struct transfer_list_header *ns_tl) +{ + struct transfer_list_entry *te = + transfer_list_find(secure_tl, TL_TAG_FDT); + assert(te != NULL); + + /* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */ + transfer_list_update_checksum(secure_tl); + + /* Copy the hardware configuration to the non-secure TL. */ + te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size, + transfer_list_entry_data(te)); + assert(te != NULL); +} diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c index bcf9f8956..ff0e0828c 100644 --- a/plat/common/plat_bl1_common.c +++ b/plat/common/plat_bl1_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -80,10 +80,8 @@ int bl1_plat_mem_check(uintptr_t mem_base, unsigned int mem_size, */ int bl1_plat_handle_post_image_load(unsigned int image_id) { - meminfo_t *bl2_secram_layout; - meminfo_t *bl1_secram_layout; + meminfo_t *bl1_tzram_layout; image_desc_t *image_desc; - entry_point_info_t *ep_info; if (image_id != BL2_IMAGE_ID) return 0; @@ -92,26 +90,41 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); assert(image_desc != NULL); - /* Get the entry point info */ - ep_info = &image_desc->ep_info; - /* Find out how much free trusted ram remains after BL1 load */ - bl1_secram_layout = bl1_plat_sec_mem_layout(); + bl1_tzram_layout = bl1_plat_sec_mem_layout(); /* - * Create a new layout of memory for BL2 as seen by BL1 i.e. - * tell it the amount of total and free memory available. - * This layout is created at the first free address visible - * to BL2. BL2 will read the memory layout before using its - * memory for other purposes. + * Convey this information to BL2 by storing the layout at the first free + * address visible to BL2. */ - bl2_secram_layout = (meminfo_t *) bl1_secram_layout->total_base; + bl1_plat_calc_bl2_layout(bl1_tzram_layout, + (meminfo_t *)bl1_tzram_layout->total_base); - bl1_calc_bl2_mem_layout(bl1_secram_layout, bl2_secram_layout); - - ep_info->args.arg1 = (uintptr_t)bl2_secram_layout; + image_desc->ep_info.args.arg1 = (uintptr_t)bl1_tzram_layout->total_base; VERBOSE("BL1: BL2 memory layout address = %p\n", - (void *) bl2_secram_layout); + (void *)image_desc->ep_info.args.arg1); + return 0; } + +/******************************************************************************* + * Helper utility to calculate the BL2 memory layout taking into consideration + * the BL1 RW data assuming that it is at the top of the memory layout. + ******************************************************************************/ +void bl1_plat_calc_bl2_layout(const meminfo_t *bl1_mem_layout, + meminfo_t *bl2_mem_layout) +{ + assert(bl1_mem_layout != NULL); + assert(bl2_mem_layout != NULL); + + /* + * Remove BL1 RW data from the scope of memory visible to BL2. + * This is assuming BL1 RW data is at the top of bl1_mem_layout. + */ + assert(BL1_RW_BASE > bl1_mem_layout->total_base); + bl2_mem_layout->total_base = bl1_mem_layout->total_base; + bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base; + + flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t)); +}