1 /* 2 * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <plat/arm/common/plat_arm.h> 8 #include <platform_def.h> 9 10 void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl) 11 { 12 struct transfer_list_entry *te; 13 bl_mem_params_node_t *next_param_node = 14 get_bl_mem_params_node(HW_CONFIG_ID); 15 assert(next_param_node != NULL); 16 17 /* 18 * The HW_CONFIG needs to be authenticated via the normal loading 19 * mechanism. Pre-allocate a TE for the configuration and update the 20 * load information so the configuration is loaded directly into the TE. 21 */ 22 te = transfer_list_add(secure_tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, 23 NULL); 24 assert(te != NULL); 25 26 next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; 27 next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE; 28 next_param_node->image_info.image_base = 29 (uintptr_t)transfer_list_entry_data(te); 30 } 31 32 void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node, 33 struct transfer_list_header *secure_tl, 34 struct transfer_list_header *ns_tl) 35 { 36 uint32_t next_exe_img_id; 37 entry_point_info_t *ep; 38 struct transfer_list_entry *te; 39 40 assert(next_param_node != NULL); 41 42 while ((next_exe_img_id = next_param_node->next_handoff_image_id) != 43 INVALID_IMAGE_ID) { 44 next_param_node = 45 &bl_mem_params_desc_ptr[get_bl_params_node_index( 46 next_exe_img_id)]; 47 assert(next_param_node != NULL); 48 49 te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64, 50 sizeof(entry_point_info_t), 51 &next_param_node->ep_info); 52 assert(te != NULL); 53 54 ep = transfer_list_entry_data(te); 55 56 if (next_exe_img_id == BL33_IMAGE_ID) { 57 ep = transfer_list_set_handoff_args(ns_tl, ep); 58 assert(ep != NULL); 59 } else if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) { 60 /* 61 * Populate the BL32 image base, size and max limit in 62 * the entry point information, since there is no 63 * platform function to retrieve them in generic 64 * code. We choose arg2, arg3 and arg4 since the generic 65 * code uses arg1 for stashing the SP manifest size. The 66 * SPMC setup uses these arguments to update SP manifest 67 * with actual SP's base address and it size. 68 */ 69 ep->args.arg2 = next_param_node->image_info.image_base; 70 ep->args.arg3 = next_param_node->image_info.image_size; 71 ep->args.arg4 = 72 next_param_node->image_info.image_base + 73 next_param_node->image_info.image_max_size; 74 } 75 76 next_exe_img_id = next_param_node->next_handoff_image_id; 77 } 78 79 flush_dcache_range((uintptr_t)secure_tl, secure_tl->size); 80 } 81 82 void arm_transfer_list_copy_hw_config(struct transfer_list_header *secure_tl, 83 struct transfer_list_header *ns_tl) 84 { 85 struct transfer_list_entry *te = 86 transfer_list_find(secure_tl, TL_TAG_FDT); 87 assert(te != NULL); 88 89 /* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */ 90 transfer_list_update_checksum(secure_tl); 91 92 /* Copy the hardware configuration to the non-secure TL. */ 93 te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size, 94 transfer_list_entry_data(te)); 95 assert(te != NULL); 96 } 97