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