blob: 405bb83486efc863fa17ec216b8cbd15973fec6d [file] [log] [blame]
Yatharth Kochar3345a8d2016-09-12 16:08:41 +01001/*
Roberto Vargas484f6dd2018-02-12 12:36:17 +00002 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
Yatharth Kochar3345a8d2016-09-12 16:08:41 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Yatharth Kochar3345a8d2016-09-12 16:08:41 +01005 */
6
Yatharth Kochar3345a8d2016-09-12 16:08:41 +01007#include <assert.h>
Yatharth Kochar3345a8d2016-09-12 16:08:41 +01008
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <arch_helpers.h>
10#include <common/bl_common.h>
11#include <common/desc_image_load.h>
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010012
13static bl_load_info_t bl_load_info;
14static bl_params_t next_bl_params;
15
16
17/*******************************************************************************
18 * This function flushes the data structures so that they are visible
19 * in memory for the next BL image.
20 ******************************************************************************/
21void flush_bl_params_desc(void)
22{
Sathees Balya90950092018-11-15 14:22:30 +000023 flush_bl_params_desc_args(bl_mem_params_desc_ptr,
24 bl_mem_params_desc_num,
25 &next_bl_params);
26}
27
28/*******************************************************************************
29 * This function flushes the data structures specified as arguments so that they
30 * are visible in memory for the next BL image.
31 ******************************************************************************/
32void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
33 unsigned int mem_params_desc_num,
34 bl_params_t *next_bl_params_ptr)
35{
36 assert(mem_params_desc_ptr != NULL);
37 assert(mem_params_desc_num != 0U);
38 assert(next_bl_params_ptr != NULL);
39
40 flush_dcache_range((uintptr_t)mem_params_desc_ptr,
41 sizeof(*mem_params_desc_ptr) * mem_params_desc_num);
Dan Handley09c97c92017-04-18 14:46:23 +010042
Sathees Balya90950092018-11-15 14:22:30 +000043 flush_dcache_range((uintptr_t)next_bl_params_ptr,
44 sizeof(*next_bl_params_ptr));
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010045}
46
47/*******************************************************************************
48 * This function returns the index for given image_id, within the
49 * image descriptor array provided by bl_image_info_descs_ptr, if the
50 * image is found else it returns -1.
51 ******************************************************************************/
52int get_bl_params_node_index(unsigned int image_id)
53{
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +010054 unsigned int index;
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010055 assert(image_id != INVALID_IMAGE_ID);
56
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +010057 for (index = 0U; index < bl_mem_params_desc_num; index++) {
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010058 if (bl_mem_params_desc_ptr[index].image_id == image_id)
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +010059 return (int)index;
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010060 }
61
62 return -1;
63}
64
65/*******************************************************************************
66 * This function returns the pointer to `bl_mem_params_node_t` object for
67 * given image_id, within the image descriptor array provided by
68 * bl_mem_params_desc_ptr, if the image is found else it returns NULL.
69 ******************************************************************************/
70bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
71{
72 int index;
73 assert(image_id != INVALID_IMAGE_ID);
74
75 index = get_bl_params_node_index(image_id);
76 if (index >= 0)
77 return &bl_mem_params_desc_ptr[index];
78 else
79 return NULL;
80}
81
82/*******************************************************************************
83 * This function creates the list of loadable images, by populating and
84 * linking each `bl_load_info_node_t` type node, using the internal array
85 * of image descriptor provided by bl_mem_params_desc_ptr. It also populates
86 * and returns `bl_load_info_t` type structure that contains head of the list
87 * of loadable images.
88 ******************************************************************************/
89bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
90{
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +010091 unsigned int index = 0;
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010092
93 /* If there is no image to start with, return NULL */
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +010094 if (bl_mem_params_desc_num == 0U)
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010095 return NULL;
96
97 /* Assign initial data structures */
98 bl_load_info_node_t *bl_node_info =
99 &bl_mem_params_desc_ptr[index].load_node_mem;
100 bl_load_info.head = bl_node_info;
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100101 SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0U);
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100102
103 /* Go through the image descriptor array and create the list */
104 for (; index < bl_mem_params_desc_num; index++) {
105
106 /* Populate the image information */
107 bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
108 bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
109
110 /* Link next image if present */
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100111 if ((index + 1U) < bl_mem_params_desc_num) {
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100112 /* Get the memory and link the next node */
113 bl_node_info->next_load_info =
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100114 &bl_mem_params_desc_ptr[index + 1U].load_node_mem;
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100115 bl_node_info = bl_node_info->next_load_info;
116 }
117 }
118
119 return &bl_load_info;
120}
121
122/*******************************************************************************
123 * This function creates the list of executable images, by populating and
124 * linking each `bl_params_node_t` type node, using the internal array of
125 * image descriptor provided by bl_mem_params_desc_ptr. It also populates
126 * and returns `bl_params_t` type structure that contains head of the list
127 * of executable images.
128 ******************************************************************************/
129bl_params_t *get_next_bl_params_from_mem_params_desc(void)
130{
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100131 unsigned int count;
132 unsigned int img_id = 0U;
133 unsigned int link_index = 0U;
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100134 bl_params_node_t *bl_current_exec_node = NULL;
135 bl_params_node_t *bl_last_exec_node = NULL;
136 bl_mem_params_node_t *desc_ptr;
137
138 /* If there is no image to start with, return NULL */
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100139 if (bl_mem_params_desc_num == 0U)
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100140 return NULL;
141
142 /* Get the list HEAD */
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100143 for (count = 0U; count < bl_mem_params_desc_num; count++) {
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100144
145 desc_ptr = &bl_mem_params_desc_ptr[count];
146
147 if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
148 (EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
149 next_bl_params.head = &desc_ptr->params_node_mem;
150 link_index = count;
151 break;
152 }
153 }
154
155 /* Make sure we have a HEAD node */
156 assert(next_bl_params.head != NULL);
157
158 /* Populate the HEAD information */
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100159 SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0U);
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100160
161 /*
162 * Go through the image descriptor array and create the list.
163 * This bounded loop is to make sure that we are not looping forever.
164 */
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100165 for (count = 0U; count < bl_mem_params_desc_num; count++) {
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100166
167 desc_ptr = &bl_mem_params_desc_ptr[link_index];
168
169 /* Make sure the image is executable */
170 assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
171
172 /* Get the memory for current node */
173 bl_current_exec_node = &desc_ptr->params_node_mem;
174
175 /* Populate the image information */
176 bl_current_exec_node->image_id = desc_ptr->image_id;
177 bl_current_exec_node->image_info = &desc_ptr->image_info;
178 bl_current_exec_node->ep_info = &desc_ptr->ep_info;
179
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100180 if (bl_last_exec_node != NULL) {
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100181 /* Assert if loop detected */
182 assert(bl_last_exec_node->next_params_info == NULL);
183
184 /* Link the previous node to the current one */
185 bl_last_exec_node->next_params_info = bl_current_exec_node;
186 }
187
188 /* Update the last node */
189 bl_last_exec_node = bl_current_exec_node;
190
191 /* If no next hand-off image then break out */
192 img_id = desc_ptr->next_handoff_image_id;
193 if (img_id == INVALID_IMAGE_ID)
194 break;
195
196 /* Get the index for the next hand-off image */
197 link_index = get_bl_params_node_index(img_id);
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100198 assert((link_index > 0U) &&
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100199 (link_index < bl_mem_params_desc_num));
200 }
201
202 /* Invalid image is expected to terminate the loop */
203 assert(img_id == INVALID_IMAGE_ID);
204
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100205 return &next_bl_params;
206}
Soby Mathew96a1c6b2018-01-15 14:45:33 +0000207
208/*******************************************************************************
209 * This function populates the entry point information with the corresponding
210 * config file for all executable BL images described in bl_params.
211 ******************************************************************************/
212void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
213{
214 bl_params_node_t *params_node;
215 unsigned int fw_config_id;
216 uintptr_t hw_config_base = 0, fw_config_base;
217 bl_mem_params_node_t *mem_params;
218
Soby Mathewcc364842018-02-21 01:16:39 +0000219 assert(bl2_to_next_bl_params != NULL);
Soby Mathew96a1c6b2018-01-15 14:45:33 +0000220
221 /*
222 * Get the `bl_mem_params_node_t` corresponding to HW_CONFIG
223 * if available.
224 */
225 mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
226 if (mem_params != NULL)
227 hw_config_base = mem_params->image_info.image_base;
228
229 for (params_node = bl2_to_next_bl_params->head; params_node != NULL;
230 params_node = params_node->next_params_info) {
231
232 fw_config_base = 0;
233
234 switch (params_node->image_id) {
235 case BL31_IMAGE_ID:
236 fw_config_id = SOC_FW_CONFIG_ID;
237 break;
238 case BL32_IMAGE_ID:
239 fw_config_id = TOS_FW_CONFIG_ID;
240 break;
241 case BL33_IMAGE_ID:
242 fw_config_id = NT_FW_CONFIG_ID;
243 break;
244 default:
245 fw_config_id = INVALID_IMAGE_ID;
246 break;
247 }
248
249 if (fw_config_id != INVALID_IMAGE_ID) {
250 mem_params = get_bl_mem_params_node(fw_config_id);
251 if (mem_params != NULL)
252 fw_config_base = mem_params->image_info.image_base;
253 }
254
255 /*
256 * Pass hw and tb_fw config addresses to next images. NOTE - for
257 * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32),
Amit Daniel Kachhap4a3bc082018-03-02 18:47:55 +0530258 * arg0 is already used by generic code. Take care of not
259 * overwriting the previous initialisations.
Soby Mathew96a1c6b2018-01-15 14:45:33 +0000260 */
261 if (params_node == bl2_to_next_bl_params->head) {
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100262 if (params_node->ep_info->args.arg1 == 0U)
Amit Daniel Kachhap4a3bc082018-03-02 18:47:55 +0530263 params_node->ep_info->args.arg1 =
264 fw_config_base;
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100265 if (params_node->ep_info->args.arg2 == 0U)
Amit Daniel Kachhap4a3bc082018-03-02 18:47:55 +0530266 params_node->ep_info->args.arg2 =
267 hw_config_base;
Soby Mathew96a1c6b2018-01-15 14:45:33 +0000268 } else {
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100269 if (params_node->ep_info->args.arg0 == 0U)
Amit Daniel Kachhap4a3bc082018-03-02 18:47:55 +0530270 params_node->ep_info->args.arg0 =
271 fw_config_base;
Antonio Nino Diazf0b14cf2018-10-04 09:55:23 +0100272 if (params_node->ep_info->args.arg1 == 0U)
Amit Daniel Kachhap4a3bc082018-03-02 18:47:55 +0530273 params_node->ep_info->args.arg1 =
274 hw_config_base;
Soby Mathew96a1c6b2018-01-15 14:45:33 +0000275 }
276 }
277}