diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 647ae853b..2f065ec3c 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -167,6 +167,15 @@ typedef struct meminfo { size_t total_size; } meminfo_t; +/******************************************************************************* + * Structure used for conveying the location and size of the heap allocated for + * use by the cryptography library. + * *****************************************************************************/ +struct crypto_heap_info { + void *addr; + size_t size; +}; + /******************************************************************************* * Function & variable prototypes ******************************************************************************/ diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h index 1b5ec2d63..7b66a5e05 100644 --- a/include/lib/transfer_list.h +++ b/include/lib/transfer_list.h @@ -59,8 +59,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, + TL_TAG_MBEDTLS_HEAP_INFO = 0x105, }; enum transfer_list_ops { @@ -110,6 +110,7 @@ struct __attribute__((packed)) transfer_list_entry { CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size); void transfer_list_dump(struct transfer_list_header *tl); +struct transfer_list_header *transfer_list_ensure(void *addr, size_t size); entry_point_info_t * transfer_list_set_handoff_args(struct transfer_list_header *tl, entry_point_info_t *ep_info); diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index c3756bf5d..1d7a59df0 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -288,6 +288,11 @@ void arm_bl31_plat_arch_setup(void); 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); +void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl, + struct transfer_list_header *ns_tl); +struct transfer_list_entry * +arm_transfer_list_set_heap_info(struct transfer_list_header *tl); +void arm_transfer_list_get_heap_info(void **heap_addr, size_t *heap_size); /* TSP utility functions */ void arm_tsp_early_platform_setup(void); @@ -427,6 +432,7 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, extern plat_psci_ops_t plat_arm_psci_pm_ops; extern const mmap_region_t plat_arm_mmap[]; extern const unsigned int arm_pm_idle_states[]; +extern struct transfer_list_header *secure_tl; /* secure watchdog */ void plat_arm_secure_wdt_start(void); diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c index 8d82d259f..07614a684 100644 --- a/lib/transfer_list/transfer_list.c +++ b/lib/transfer_list/transfer_list.c @@ -168,30 +168,29 @@ transfer_list_check_header(const struct transfer_list_header *tl) } if (tl->signature != TRANSFER_LIST_SIGNATURE) { - ERROR("Bad transfer list signature %#" PRIx32 "\n", - tl->signature); + ERROR("Bad transfer list signature 0x%x\n", tl->signature); return TL_OPS_NON; } if (!tl->max_size) { - ERROR("Bad transfer list max size %#" PRIx32 "\n", + ERROR("Bad transfer list max size 0x%x\n", tl->max_size); return TL_OPS_NON; } if (tl->size > tl->max_size) { - ERROR("Bad transfer list size %#" PRIx32 "\n", tl->size); + ERROR("Bad transfer list size 0x%x\n", tl->size); return TL_OPS_NON; } if (tl->hdr_size != sizeof(struct transfer_list_header)) { - ERROR("Bad transfer list header size %#" PRIx32 "\n", + ERROR("Bad transfer list header size 0x%x\n", tl->hdr_size); return TL_OPS_NON; } if (!transfer_list_verify_checksum(tl)) { - ERROR("Bad transfer list checksum %#" PRIx32 "\n", + ERROR("Bad transfer list checksum 0x%x\n", tl->checksum); return TL_OPS_NON; } @@ -521,3 +520,22 @@ void *transfer_list_entry_data(struct transfer_list_entry *entry) } return (uint8_t *)entry + entry->hdr_size; } + +/******************************************************************************* + * Verifies that the transfer list has not already been initialized, then + * initializes it at the specified memory location. + * + * Return pointer to the transfer list or NULL on error + * *****************************************************************************/ +struct transfer_list_header *transfer_list_ensure(void *addr, size_t size) +{ + struct transfer_list_header *tl = NULL; + + if (transfer_list_check_header(addr) == TL_OPS_ALL) { + return (struct transfer_list_header *)addr; + } + + tl = transfer_list_init((void *)addr, size); + + return tl; +} diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index ebdd80d45..8dcdd62e5 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -48,8 +48,6 @@ 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 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 3b638e414..08fbfeef2 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -339,17 +339,12 @@ 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 +ifeq (${TRANSFER_LIST}, 0) FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ ${PLAT}_fw_config.dts \ ${PLAT}_tb_fw_config.dts \ @@ -357,6 +352,7 @@ FDT_SOURCES += $(addprefix plat/arm/board/fvp/fdts/, \ ${PLAT}_nt_fw_config.dts \ ) +FVP_TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb FVP_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_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 @@ -388,10 +384,10 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG})) $(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 - # 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})) +endif + # 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/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index f043f59dd..b8e502760 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -64,9 +64,7 @@ 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 transfer_list_header *secure_tl; struct meminfo *bl1_plat_sec_mem_layout(void) { @@ -90,6 +88,12 @@ void arm_bl1_early_platform_setup(void) /* Allow BL1 to see the whole Trusted RAM */ bl1_tzram_layout.total_base = ARM_BL_RAM_BASE; bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE; + +#if TRANSFER_LIST + secure_tl = transfer_list_ensure((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE, + PLAT_ARM_FW_HANDOFF_SIZE); + assert(secure_tl != NULL); +#endif } void bl1_early_platform_setup(void) @@ -158,7 +162,7 @@ void arm_bl1_platform_setup(void) image_desc_t *desc; - int err = -1; + int err __unused = 1; /* Initialise the IO layer and register platform IO devices */ plat_arm_io_setup(); @@ -171,35 +175,24 @@ void arm_bl1_platform_setup(void) } #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); +#if CRYPTO_SUPPORT + te = transfer_list_add(secure_tl, TL_TAG_MBEDTLS_HEAP_INFO, + sizeof(struct crypto_heap_info), NULL); assert(te != NULL); + struct crypto_heap_info *heap_info = + (struct crypto_heap_info *)transfer_list_entry_data(te); + arm_get_mbedtls_heap(&heap_info->addr, &heap_info->size); +#endif /* CRYPTO_SUPPORT */ + + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + /* - * Set the load address of TB_FW_CONFIG in the data section of the TE just - * allocated in the secure transfer list. + * The event log might have been updated prior to this, make sure we have an + * up to date tl before setting the handoff arguments. */ - 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)); + transfer_list_set_handoff_args(secure_tl, &desc->ep_info); #else /* Set global DTB info for fixed fw_config information */ fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; @@ -234,22 +227,18 @@ void arm_bl1_platform_setup(void) ERROR("Invalid FW_CONFIG address\n"); plat_error_handler(err); } -#endif /* TRANSFER_LIST */ 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 = config_info->config_addr; -#endif /* TRANSFER_LIST */ #if CRYPTO_SUPPORT /* Share the Mbed TLS heap info with other images */ arm_bl1_set_mbedtls_heap(); #endif /* CRYPTO_SUPPORT */ +#endif /* TRANSFER_LIST */ /* * Allow access to the System counter timer module and program diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 90ee70cc0..07b3b6203 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -66,8 +66,7 @@ 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; +struct transfer_list_header *secure_tl __unused; /******************************************************************************* * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 @@ -129,15 +128,14 @@ 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); + secure_tl = transfer_list_ensure((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 #if ARM_FW_CONFIG_LOAD_ENABLE @@ -232,11 +230,10 @@ void bl2_plat_arch_setup(void) 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)); +#if CRYPTO_SUPPORT + te = arm_transfer_list_set_heap_info(secure_tl); transfer_list_rem(secure_tl, te); +#endif /* CRYPTO_SUPPORT */ #else /* Fill the properties struct with the info from the config dtb */ fconf_populate("FW_CONFIG", config_base); @@ -246,7 +243,7 @@ void bl2_plat_arch_setup(void) assert(tb_fw_config_info != NULL); fconf_populate("TB_FW", tb_fw_config_info->config_addr); -#endif +#endif /* TRANSFER_LIST */ } int arm_bl2_handle_post_image_load(unsigned int image_id) diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 0a8dd372d..478799512 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -25,8 +25,8 @@ #include #include -static struct transfer_list_header *secure_tl __unused; -static struct transfer_list_header *ns_tl __unused; +struct transfer_list_header *secure_tl; +struct transfer_list_header *ns_tl __unused; /* * Placeholder variables for copying the arguments that have been passed to @@ -367,14 +367,13 @@ void arm_bl31_platform_setup(void) struct transfer_list_entry *te __unused; #if TRANSFER_LIST && !RESET_TO_BL31 - ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, - PLAT_ARM_FW_HANDOFF_SIZE); - + ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE, + PLAT_ARM_FW_HANDOFF_SIZE); if (ns_tl == NULL) { - ERROR("Non-secure transfer list initialisation failed!"); + ERROR("Non-secure transfer list initialisation failed!\n"); panic(); } - + /* BL31 may modify the HW_CONFIG so defer copying it until later. */ te = transfer_list_find(secure_tl, TL_TAG_FDT); assert(te != NULL); @@ -392,7 +391,7 @@ void arm_bl31_platform_setup(void) te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size, transfer_list_entry_data(te)); assert(te != NULL); -#endif /* TRANSFER_LIST */ +#endif /* TRANSFER_LIST && !RESET_TO_BL31 */ /* Initialize the GIC driver, cpu and distributor interfaces */ plat_arm_gic_driver_init(); @@ -447,7 +446,7 @@ void arm_bl31_plat_runtime_setup(void) * they can access the updated data even if caching is not enabled. */ flush_dcache_range((uintptr_t)ns_tl, ns_tl->size); -#endif /* TRANSFER_LIST && !(RESET_TO_BL2 || RESET_TO_BL31) */ +#endif /* TRANSFER_LIST && !RESET_TO_BL31 */ #if RECLAIM_INIT_CODE arm_free_init_memory(); diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 18ab5be80..a827f050c 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -23,7 +23,7 @@ #include #include -#if CRYPTO_SUPPORT +#if CRYPTO_SUPPORT && !TRANSFER_LIST static void *mbedtls_heap_addr; static size_t mbedtls_heap_size; @@ -118,7 +118,7 @@ void arm_bl1_set_mbedtls_heap(void) #endif /* !MEASURED_BOOT */ } } -#endif /* CRYPTO_SUPPORT */ +#endif /* CRYPTO_SUPPORT && !TRANSFER_LIST */ #if IMAGE_BL2 /* diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c index 59fb03984..6847591f3 100644 --- a/plat/arm/common/arm_transfer_list.c +++ b/plat/arm/common/arm_transfer_list.c @@ -4,10 +4,49 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#if CRYPTO_SUPPORT +#include +#endif /* CRYPTO_SUPPORT */ + #include #include -void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl) +#if CRYPTO_SUPPORT +#if defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) +static unsigned char heap[TF_MBEDTLS_HEAP_SIZE]; + +#define MBEDTLS_HEAP_ADDR heap +#define MBEDTLS_HEAP_SIZE sizeof(heap) +#else +static struct crypto_heap_info heap_info; + +#define MBEDTLS_HEAP_ADDR heap_info.addr +#define MBEDTLS_HEAP_SIZE heap_info.size + +struct transfer_list_entry * +arm_transfer_list_set_heap_info(struct transfer_list_header *tl) +{ + struct transfer_list_entry *te = + transfer_list_find(tl, TL_TAG_MBEDTLS_HEAP_INFO); + assert(te != NULL); + + heap_info = *(struct crypto_heap_info *)transfer_list_entry_data(te); + return te; +} +#endif /* defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) */ + +int __init arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) +{ + assert(heap_addr != NULL); + assert(heap_size != NULL); + *heap_addr = MBEDTLS_HEAP_ADDR; + *heap_size = MBEDTLS_HEAP_SIZE; + + return 0; +} +#endif /* CRYPTO_SUPPORT */ + +void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *tl) { struct transfer_list_entry *te; bl_mem_params_node_t *next_param_node = @@ -19,8 +58,7 @@ void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl) * 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); + te = transfer_list_add(tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, NULL); assert(te != NULL); next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; @@ -30,7 +68,7 @@ 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 *tl) { uint32_t next_exe_img_id; entry_point_info_t *ep; @@ -45,7 +83,7 @@ void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, next_exe_img_id)]; assert(next_param_node != NULL); - te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64, + te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO64, sizeof(entry_point_info_t), &next_param_node->ep_info); assert(te != NULL); @@ -72,5 +110,5 @@ void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, next_exe_img_id = next_param_node->next_handoff_image_id; } - flush_dcache_range((uintptr_t)secure_tl, secure_tl->size); + flush_dcache_range((uintptr_t)tl, tl->size); }