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
arm_transfer_list_dyn_cfg_init(struct transfer_list_header * secure_tl)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
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)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
arm_transfer_list_copy_hw_config(struct transfer_list_header * secure_tl,struct transfer_list_header * ns_tl)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