1 /* 2 * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <common/desc_image_load.h> 7 8 #if CRYPTO_SUPPORT 9 #include <mbedtls/version.h> 10 #endif /* CRYPTO_SUPPORT */ 11 12 #if BL2_ENABLE_SP_LOAD 13 #include <plat/arm/common/fconf_arm_sp_getter.h> 14 #endif /* BL2_ENABLE_SP_LOAD */ 15 #include <plat/arm/common/plat_arm.h> 16 #include <platform_def.h> 17 18 #if CRYPTO_SUPPORT 19 #if defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) 20 static unsigned char heap[TF_MBEDTLS_HEAP_SIZE]; 21 22 #define MBEDTLS_HEAP_ADDR heap 23 #define MBEDTLS_HEAP_SIZE sizeof(heap) 24 #else 25 static struct crypto_heap_info heap_info; 26 27 #define MBEDTLS_HEAP_ADDR heap_info.addr 28 #define MBEDTLS_HEAP_SIZE heap_info.size 29 30 struct transfer_list_entry * 31 arm_transfer_list_set_heap_info(struct transfer_list_header *tl) 32 { 33 struct transfer_list_entry *te = 34 transfer_list_find(tl, TL_TAG_MBEDTLS_HEAP_INFO); 35 assert(te != NULL); 36 37 heap_info = *(struct crypto_heap_info *)transfer_list_entry_data(te); 38 return te; 39 } 40 #endif /* defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) */ 41 42 int __init arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) 43 { 44 assert(heap_addr != NULL); 45 assert(heap_size != NULL); 46 *heap_addr = MBEDTLS_HEAP_ADDR; 47 *heap_size = MBEDTLS_HEAP_SIZE; 48 49 return 0; 50 } 51 #endif /* CRYPTO_SUPPORT */ 52 53 void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *tl) 54 { 55 int err __maybe_unused; 56 struct transfer_list_entry *te; 57 bl_mem_params_node_t *next_param_node = 58 get_bl_mem_params_node(HW_CONFIG_ID); 59 assert(next_param_node != NULL); 60 61 /* 62 * The HW_CONFIG needs to be authenticated via the normal loading 63 * mechanism. Pre-allocate a TE for the configuration and update the 64 * load information so the configuration is loaded directly into the TE. 65 */ 66 te = transfer_list_add(tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, NULL); 67 assert(te != NULL); 68 69 next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; 70 next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE; 71 next_param_node->image_info.image_base = 72 (uintptr_t)transfer_list_entry_data(te); 73 74 #if BL2_ENABLE_SP_LOAD && defined(PLAT_ARM_TB_FW_CONFIG_TL_TAG) 75 te = transfer_list_find(tl, PLAT_ARM_TB_FW_CONFIG_TL_TAG); 76 assert(te != NULL); 77 78 /* 79 * TB_FW_CONFIG is loaded in the TL_TAG_FDT entry at 80 * arm_bl31_platform_setup(). 81 * This data will be clear after loading SP_PKGs information. 82 * 83 * Later, TL_TAG_FDT data will be loaded with HW_CONFIG at 84 * arm_bl31_platform_setup(). 85 */ 86 err = fconf_populate_arm_sp((uintptr_t)transfer_list_entry_data(te)); 87 if (err) { 88 ERROR("Failed to populate SP information. err: %d\n", err); 89 } 90 #endif 91 92 #if defined(SPD_spmd) && defined(PLAT_ARM_SPMC_SP_MANIFEST_SIZE) 93 next_param_node = get_bl_mem_params_node(TOS_FW_CONFIG_ID); 94 if (next_param_node == NULL) { 95 return; 96 } 97 98 #if SPMC_AT_EL3 99 te = transfer_list_add(tl, TL_TAG_DT_FFA_MANIFEST, 100 PLAT_ARM_SPMC_SP_MANIFEST_SIZE, NULL); 101 #else 102 te = transfer_list_add(tl, TL_TAG_DT_SPMC_MANIFEST, 103 PLAT_ARM_SPMC_SP_MANIFEST_SIZE, NULL); 104 #endif 105 assert(te != NULL); 106 107 next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; 108 next_param_node->image_info.image_max_size = PLAT_ARM_SPMC_SP_MANIFEST_SIZE; 109 next_param_node->image_info.image_base = 110 (uintptr_t)transfer_list_entry_data(te); 111 #endif /* defined(SPD_spmd) && defined(PLAT_ARM_SPMC_SP_MANIFEST_SIZE) */ 112 } 113 114 void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, 115 struct transfer_list_header *tl) 116 { 117 uint32_t next_exe_img_id; 118 entry_point_info_t *ep __unused; 119 struct transfer_list_entry *te; 120 assert(next_param_node != NULL); 121 122 while ((next_exe_img_id = next_param_node->next_handoff_image_id) != 123 INVALID_IMAGE_ID) { 124 next_param_node = 125 &bl_mem_params_desc_ptr[get_bl_params_node_index( 126 next_exe_img_id)]; 127 assert(next_param_node != NULL); 128 129 te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO, 130 sizeof(entry_point_info_t), 131 &next_param_node->ep_info); 132 assert(te != NULL); 133 134 ep = transfer_list_entry_data(te); 135 assert(ep != NULL); 136 137 #if SPMC_AT_EL3 138 if (next_exe_img_id == BL32_IMAGE_ID) { 139 /* 140 * Populate the BL32 image base, size and max limit in 141 * the entry point information, since there is no 142 * platform function to retrieve them in generic 143 * code. We choose arg2, arg3 and arg4 since the generic 144 * code uses arg1 for stashing the SP manifest size. The 145 * SPMC setup uses these arguments to update SP manifest 146 * with actual SP's base address and it size. 147 */ 148 ep->args.arg2 = next_param_node->image_info.image_base; 149 ep->args.arg3 = next_param_node->image_info.image_size; 150 ep->args.arg4 = 151 next_param_node->image_info.image_base + 152 next_param_node->image_info.image_max_size; 153 } 154 #endif /* SPMC_AT_EL3 */ 155 156 next_exe_img_id = next_param_node->next_handoff_image_id; 157 } 158 159 flush_dcache_range((uintptr_t)tl, tl->size); 160 } 161