xref: /rk3399_ARM-atf/plat/arm/common/arm_transfer_list.c (revision 30a60389204f9ec44c890854e62ec1e0506cb9b9)
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