blob: 52ef362b3cb2ed3a1d15f9c9d3c55c38ca48c33c [file] [log] [blame]
Yatharth Kochar3345a8d2016-09-12 16:08:41 +01001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch_helpers.h>
32#include <assert.h>
33#include <bl_common.h>
34#include <desc_image_load.h>
35
36
37extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
38extern unsigned int bl_mem_params_desc_num;
39
40static bl_load_info_t bl_load_info;
41static bl_params_t next_bl_params;
42
43
44/*******************************************************************************
45 * This function flushes the data structures so that they are visible
46 * in memory for the next BL image.
47 ******************************************************************************/
48void flush_bl_params_desc(void)
49{
Dan Handley09c97c92017-04-18 14:46:23 +010050 flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010051 sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
Dan Handley09c97c92017-04-18 14:46:23 +010052
53 flush_dcache_range((uintptr_t)&next_bl_params,
54 sizeof(next_bl_params));
Yatharth Kochar3345a8d2016-09-12 16:08:41 +010055}
56
57/*******************************************************************************
58 * This function returns the index for given image_id, within the
59 * image descriptor array provided by bl_image_info_descs_ptr, if the
60 * image is found else it returns -1.
61 ******************************************************************************/
62int get_bl_params_node_index(unsigned int image_id)
63{
64 int index;
65 assert(image_id != INVALID_IMAGE_ID);
66
67 for (index = 0; index < bl_mem_params_desc_num; index++) {
68 if (bl_mem_params_desc_ptr[index].image_id == image_id)
69 return index;
70 }
71
72 return -1;
73}
74
75/*******************************************************************************
76 * This function returns the pointer to `bl_mem_params_node_t` object for
77 * given image_id, within the image descriptor array provided by
78 * bl_mem_params_desc_ptr, if the image is found else it returns NULL.
79 ******************************************************************************/
80bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
81{
82 int index;
83 assert(image_id != INVALID_IMAGE_ID);
84
85 index = get_bl_params_node_index(image_id);
86 if (index >= 0)
87 return &bl_mem_params_desc_ptr[index];
88 else
89 return NULL;
90}
91
92/*******************************************************************************
93 * This function creates the list of loadable images, by populating and
94 * linking each `bl_load_info_node_t` type node, using the internal array
95 * of image descriptor provided by bl_mem_params_desc_ptr. It also populates
96 * and returns `bl_load_info_t` type structure that contains head of the list
97 * of loadable images.
98 ******************************************************************************/
99bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
100{
101 int index = 0;
102
103 /* If there is no image to start with, return NULL */
104 if (!bl_mem_params_desc_num)
105 return NULL;
106
107 /* Assign initial data structures */
108 bl_load_info_node_t *bl_node_info =
109 &bl_mem_params_desc_ptr[index].load_node_mem;
110 bl_load_info.head = bl_node_info;
111 SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0);
112
113 /* Go through the image descriptor array and create the list */
114 for (; index < bl_mem_params_desc_num; index++) {
115
116 /* Populate the image information */
117 bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
118 bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
119
120 /* Link next image if present */
121 if ((index + 1) < bl_mem_params_desc_num) {
122 /* Get the memory and link the next node */
123 bl_node_info->next_load_info =
124 &bl_mem_params_desc_ptr[index + 1].load_node_mem;
125 bl_node_info = bl_node_info->next_load_info;
126 }
127 }
128
129 return &bl_load_info;
130}
131
132/*******************************************************************************
133 * This function creates the list of executable images, by populating and
134 * linking each `bl_params_node_t` type node, using the internal array of
135 * image descriptor provided by bl_mem_params_desc_ptr. It also populates
136 * and returns `bl_params_t` type structure that contains head of the list
137 * of executable images.
138 ******************************************************************************/
139bl_params_t *get_next_bl_params_from_mem_params_desc(void)
140{
141 int count;
142 unsigned int img_id = 0;
143 int link_index = 0;
144 bl_params_node_t *bl_current_exec_node = NULL;
145 bl_params_node_t *bl_last_exec_node = NULL;
146 bl_mem_params_node_t *desc_ptr;
147
148 /* If there is no image to start with, return NULL */
149 if (!bl_mem_params_desc_num)
150 return NULL;
151
152 /* Get the list HEAD */
153 for (count = 0; count < bl_mem_params_desc_num; count++) {
154
155 desc_ptr = &bl_mem_params_desc_ptr[count];
156
157 if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
158 (EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
159 next_bl_params.head = &desc_ptr->params_node_mem;
160 link_index = count;
161 break;
162 }
163 }
164
165 /* Make sure we have a HEAD node */
166 assert(next_bl_params.head != NULL);
167
168 /* Populate the HEAD information */
169 SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0);
170
171 /*
172 * Go through the image descriptor array and create the list.
173 * This bounded loop is to make sure that we are not looping forever.
174 */
175 for (count = 0 ; count < bl_mem_params_desc_num; count++) {
176
177 desc_ptr = &bl_mem_params_desc_ptr[link_index];
178
179 /* Make sure the image is executable */
180 assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
181
182 /* Get the memory for current node */
183 bl_current_exec_node = &desc_ptr->params_node_mem;
184
185 /* Populate the image information */
186 bl_current_exec_node->image_id = desc_ptr->image_id;
187 bl_current_exec_node->image_info = &desc_ptr->image_info;
188 bl_current_exec_node->ep_info = &desc_ptr->ep_info;
189
190 if (bl_last_exec_node) {
191 /* Assert if loop detected */
192 assert(bl_last_exec_node->next_params_info == NULL);
193
194 /* Link the previous node to the current one */
195 bl_last_exec_node->next_params_info = bl_current_exec_node;
196 }
197
198 /* Update the last node */
199 bl_last_exec_node = bl_current_exec_node;
200
201 /* If no next hand-off image then break out */
202 img_id = desc_ptr->next_handoff_image_id;
203 if (img_id == INVALID_IMAGE_ID)
204 break;
205
206 /* Get the index for the next hand-off image */
207 link_index = get_bl_params_node_index(img_id);
208 assert((link_index > 0) &&
209 (link_index < bl_mem_params_desc_num));
210 }
211
212 /* Invalid image is expected to terminate the loop */
213 assert(img_id == INVALID_IMAGE_ID);
214
Yatharth Kochar3345a8d2016-09-12 16:08:41 +0100215 return &next_bl_params;
216}