/* * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #if CRYPTO_SUPPORT #include #endif /* CRYPTO_SUPPORT */ #include #include #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 = 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(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); #if SPMC_AT_EL3 && defined(PLAT_ARM_SPMC_SP_MANIFEST_SIZE) next_param_node = get_bl_mem_params_node(TOS_FW_CONFIG_ID); assert(next_param_node != NULL); te = transfer_list_add(tl, TL_TAG_DT_FFA_MANIFEST, PLAT_ARM_SPMC_SP_MANIFEST_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_SPMC_SP_MANIFEST_SIZE; next_param_node->image_info.image_base = (uintptr_t)transfer_list_entry_data(te); #endif /* SPMC_AT_EL3 */ } void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, struct transfer_list_header *tl) { uint32_t next_exe_img_id; entry_point_info_t *ep __unused; 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(tl, TL_TAG_EXEC_EP_INFO, sizeof(entry_point_info_t), &next_param_node->ep_info); assert(te != NULL); ep = transfer_list_entry_data(te); assert(ep != NULL); #if SPMC_AT_EL3 if (next_exe_img_id == BL32_IMAGE_ID) { /* * 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; } #endif /* SPMC_AT_EL3 */ next_exe_img_id = next_param_node->next_handoff_image_id; } flush_dcache_range((uintptr_t)tl, tl->size); }