xref: /rk3399_ARM-atf/common/desc_image_load.c (revision c2a9ee6383b71af2d0dae7b0c578e987bcf35695)
172600226SYatharth Kochar /*
272600226SYatharth Kochar  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
372600226SYatharth Kochar  *
472600226SYatharth Kochar  * Redistribution and use in source and binary forms, with or without
572600226SYatharth Kochar  * modification, are permitted provided that the following conditions are met:
672600226SYatharth Kochar  *
772600226SYatharth Kochar  * Redistributions of source code must retain the above copyright notice, this
872600226SYatharth Kochar  * list of conditions and the following disclaimer.
972600226SYatharth Kochar  *
1072600226SYatharth Kochar  * Redistributions in binary form must reproduce the above copyright notice,
1172600226SYatharth Kochar  * this list of conditions and the following disclaimer in the documentation
1272600226SYatharth Kochar  * and/or other materials provided with the distribution.
1372600226SYatharth Kochar  *
1472600226SYatharth Kochar  * Neither the name of ARM nor the names of its contributors may be used
1572600226SYatharth Kochar  * to endorse or promote products derived from this software without specific
1672600226SYatharth Kochar  * prior written permission.
1772600226SYatharth Kochar  *
1872600226SYatharth Kochar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1972600226SYatharth Kochar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2072600226SYatharth Kochar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2172600226SYatharth Kochar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2272600226SYatharth Kochar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2372600226SYatharth Kochar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2472600226SYatharth Kochar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2572600226SYatharth Kochar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2672600226SYatharth Kochar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2772600226SYatharth Kochar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2872600226SYatharth Kochar  * POSSIBILITY OF SUCH DAMAGE.
2972600226SYatharth Kochar  */
3072600226SYatharth Kochar 
3172600226SYatharth Kochar #include <arch_helpers.h>
3272600226SYatharth Kochar #include <assert.h>
3372600226SYatharth Kochar #include <bl_common.h>
3472600226SYatharth Kochar #include <desc_image_load.h>
3572600226SYatharth Kochar 
3672600226SYatharth Kochar 
3772600226SYatharth Kochar extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
3872600226SYatharth Kochar extern unsigned int bl_mem_params_desc_num;
3972600226SYatharth Kochar 
4072600226SYatharth Kochar static bl_load_info_t bl_load_info;
4172600226SYatharth Kochar static bl_params_t next_bl_params;
4272600226SYatharth Kochar 
4372600226SYatharth Kochar 
4472600226SYatharth Kochar /*******************************************************************************
4572600226SYatharth Kochar  * This function flushes the data structures so that they are visible
4672600226SYatharth Kochar  * in memory for the next BL image.
4772600226SYatharth Kochar  ******************************************************************************/
4872600226SYatharth Kochar void flush_bl_params_desc(void)
4972600226SYatharth Kochar {
50*c2a9ee63SDan Handley 	flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
5172600226SYatharth Kochar 			sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
52*c2a9ee63SDan Handley 
53*c2a9ee63SDan Handley 	flush_dcache_range((uintptr_t)&next_bl_params,
54*c2a9ee63SDan Handley 			sizeof(next_bl_params));
5572600226SYatharth Kochar }
5672600226SYatharth Kochar 
5772600226SYatharth Kochar /*******************************************************************************
5872600226SYatharth Kochar  * This function returns the index for given image_id, within the
5972600226SYatharth Kochar  * image descriptor array provided by bl_image_info_descs_ptr, if the
6072600226SYatharth Kochar  * image is found else it returns -1.
6172600226SYatharth Kochar  ******************************************************************************/
6272600226SYatharth Kochar int get_bl_params_node_index(unsigned int image_id)
6372600226SYatharth Kochar {
6472600226SYatharth Kochar 	int index;
6572600226SYatharth Kochar 	assert(image_id != INVALID_IMAGE_ID);
6672600226SYatharth Kochar 
6772600226SYatharth Kochar 	for (index = 0; index < bl_mem_params_desc_num; index++) {
6872600226SYatharth Kochar 		if (bl_mem_params_desc_ptr[index].image_id == image_id)
6972600226SYatharth Kochar 			return index;
7072600226SYatharth Kochar 	}
7172600226SYatharth Kochar 
7272600226SYatharth Kochar 	return -1;
7372600226SYatharth Kochar }
7472600226SYatharth Kochar 
7572600226SYatharth Kochar /*******************************************************************************
7672600226SYatharth Kochar  * This function returns the pointer to `bl_mem_params_node_t` object for
7772600226SYatharth Kochar  * given image_id, within the image descriptor array provided by
7872600226SYatharth Kochar  * bl_mem_params_desc_ptr, if the image is found else it returns NULL.
7972600226SYatharth Kochar  ******************************************************************************/
8072600226SYatharth Kochar bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
8172600226SYatharth Kochar {
8272600226SYatharth Kochar 	int index;
8372600226SYatharth Kochar 	assert(image_id != INVALID_IMAGE_ID);
8472600226SYatharth Kochar 
8572600226SYatharth Kochar 	index = get_bl_params_node_index(image_id);
8672600226SYatharth Kochar 	if (index >= 0)
8772600226SYatharth Kochar 		return &bl_mem_params_desc_ptr[index];
8872600226SYatharth Kochar 	else
8972600226SYatharth Kochar 		return NULL;
9072600226SYatharth Kochar }
9172600226SYatharth Kochar 
9272600226SYatharth Kochar /*******************************************************************************
9372600226SYatharth Kochar  * This function creates the list of loadable images, by populating and
9472600226SYatharth Kochar  * linking each `bl_load_info_node_t` type node, using the internal array
9572600226SYatharth Kochar  * of image descriptor provided by bl_mem_params_desc_ptr. It also populates
9672600226SYatharth Kochar  * and returns `bl_load_info_t` type structure that contains head of the list
9772600226SYatharth Kochar  * of loadable images.
9872600226SYatharth Kochar  ******************************************************************************/
9972600226SYatharth Kochar bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
10072600226SYatharth Kochar {
10172600226SYatharth Kochar 	int index = 0;
10272600226SYatharth Kochar 
10372600226SYatharth Kochar 	/* If there is no image to start with, return NULL */
10472600226SYatharth Kochar 	if (!bl_mem_params_desc_num)
10572600226SYatharth Kochar 		return NULL;
10672600226SYatharth Kochar 
10772600226SYatharth Kochar 	/* Assign initial data structures */
10872600226SYatharth Kochar 	bl_load_info_node_t *bl_node_info =
10972600226SYatharth Kochar 		&bl_mem_params_desc_ptr[index].load_node_mem;
11072600226SYatharth Kochar 	bl_load_info.head = bl_node_info;
11172600226SYatharth Kochar 	SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0);
11272600226SYatharth Kochar 
11372600226SYatharth Kochar 	/* Go through the image descriptor array and create the list */
11472600226SYatharth Kochar 	for (; index < bl_mem_params_desc_num; index++) {
11572600226SYatharth Kochar 
11672600226SYatharth Kochar 		/* Populate the image information */
11772600226SYatharth Kochar 		bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
11872600226SYatharth Kochar 		bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
11972600226SYatharth Kochar 
12072600226SYatharth Kochar 		/* Link next image if present */
12172600226SYatharth Kochar 		if ((index + 1) < bl_mem_params_desc_num) {
12272600226SYatharth Kochar 			/* Get the memory and link the next node */
12372600226SYatharth Kochar 			bl_node_info->next_load_info =
12472600226SYatharth Kochar 				&bl_mem_params_desc_ptr[index + 1].load_node_mem;
12572600226SYatharth Kochar 			bl_node_info = bl_node_info->next_load_info;
12672600226SYatharth Kochar 		}
12772600226SYatharth Kochar 	}
12872600226SYatharth Kochar 
12972600226SYatharth Kochar 	return &bl_load_info;
13072600226SYatharth Kochar }
13172600226SYatharth Kochar 
13272600226SYatharth Kochar /*******************************************************************************
13372600226SYatharth Kochar  * This function creates the list of executable images, by populating and
13472600226SYatharth Kochar  * linking each `bl_params_node_t` type node, using the internal array of
13572600226SYatharth Kochar  * image descriptor provided by bl_mem_params_desc_ptr. It also populates
13672600226SYatharth Kochar  * and returns `bl_params_t` type structure that contains head of the list
13772600226SYatharth Kochar  * of executable images.
13872600226SYatharth Kochar  ******************************************************************************/
13972600226SYatharth Kochar bl_params_t *get_next_bl_params_from_mem_params_desc(void)
14072600226SYatharth Kochar {
14172600226SYatharth Kochar 	int count;
14272600226SYatharth Kochar 	unsigned int img_id = 0;
14372600226SYatharth Kochar 	int link_index = 0;
14472600226SYatharth Kochar 	bl_params_node_t *bl_current_exec_node = NULL;
14572600226SYatharth Kochar 	bl_params_node_t *bl_last_exec_node = NULL;
14672600226SYatharth Kochar 	bl_mem_params_node_t *desc_ptr;
14772600226SYatharth Kochar 
14872600226SYatharth Kochar 	/* If there is no image to start with, return NULL */
14972600226SYatharth Kochar 	if (!bl_mem_params_desc_num)
15072600226SYatharth Kochar 		return NULL;
15172600226SYatharth Kochar 
15272600226SYatharth Kochar 	/* Get the list HEAD */
15372600226SYatharth Kochar 	for (count = 0; count < bl_mem_params_desc_num; count++) {
15472600226SYatharth Kochar 
15572600226SYatharth Kochar 		desc_ptr = &bl_mem_params_desc_ptr[count];
15672600226SYatharth Kochar 
15772600226SYatharth Kochar 		if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
15872600226SYatharth Kochar 			(EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
15972600226SYatharth Kochar 			next_bl_params.head = &desc_ptr->params_node_mem;
16072600226SYatharth Kochar 			link_index = count;
16172600226SYatharth Kochar 			break;
16272600226SYatharth Kochar 		}
16372600226SYatharth Kochar 	}
16472600226SYatharth Kochar 
16572600226SYatharth Kochar 	/* Make sure we have a HEAD node */
16672600226SYatharth Kochar 	assert(next_bl_params.head != NULL);
16772600226SYatharth Kochar 
16872600226SYatharth Kochar 	/* Populate the HEAD information */
16972600226SYatharth Kochar 	SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0);
17072600226SYatharth Kochar 
17172600226SYatharth Kochar 	/*
17272600226SYatharth Kochar 	 * Go through the image descriptor array and create the list.
17372600226SYatharth Kochar 	 * This bounded loop is to make sure that we are not looping forever.
17472600226SYatharth Kochar 	 */
17572600226SYatharth Kochar 	for (count = 0 ; count < bl_mem_params_desc_num; count++) {
17672600226SYatharth Kochar 
17772600226SYatharth Kochar 		desc_ptr = &bl_mem_params_desc_ptr[link_index];
17872600226SYatharth Kochar 
17972600226SYatharth Kochar 		/* Make sure the image is executable */
18072600226SYatharth Kochar 		assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
18172600226SYatharth Kochar 
18272600226SYatharth Kochar 		/* Get the memory for current node */
18372600226SYatharth Kochar 		bl_current_exec_node = &desc_ptr->params_node_mem;
18472600226SYatharth Kochar 
18572600226SYatharth Kochar 		/* Populate the image information */
18672600226SYatharth Kochar 		bl_current_exec_node->image_id = desc_ptr->image_id;
18772600226SYatharth Kochar 		bl_current_exec_node->image_info = &desc_ptr->image_info;
18872600226SYatharth Kochar 		bl_current_exec_node->ep_info = &desc_ptr->ep_info;
18972600226SYatharth Kochar 
19072600226SYatharth Kochar 		if (bl_last_exec_node) {
19172600226SYatharth Kochar 			/* Assert if loop detected */
19272600226SYatharth Kochar 			assert(bl_last_exec_node->next_params_info == NULL);
19372600226SYatharth Kochar 
19472600226SYatharth Kochar 			/* Link the previous node to the current one */
19572600226SYatharth Kochar 			bl_last_exec_node->next_params_info = bl_current_exec_node;
19672600226SYatharth Kochar 		}
19772600226SYatharth Kochar 
19872600226SYatharth Kochar 		/* Update the last node */
19972600226SYatharth Kochar 		bl_last_exec_node = bl_current_exec_node;
20072600226SYatharth Kochar 
20172600226SYatharth Kochar 		/* If no next hand-off image then break out */
20272600226SYatharth Kochar 		img_id = desc_ptr->next_handoff_image_id;
20372600226SYatharth Kochar 		if (img_id == INVALID_IMAGE_ID)
20472600226SYatharth Kochar 			break;
20572600226SYatharth Kochar 
20672600226SYatharth Kochar 		/* Get the index for the next hand-off image */
20772600226SYatharth Kochar 		link_index = get_bl_params_node_index(img_id);
20872600226SYatharth Kochar 		assert((link_index > 0) &&
20972600226SYatharth Kochar 			(link_index < bl_mem_params_desc_num));
21072600226SYatharth Kochar 	}
21172600226SYatharth Kochar 
21272600226SYatharth Kochar 	/* Invalid image is expected to terminate the loop */
21372600226SYatharth Kochar 	assert(img_id == INVALID_IMAGE_ID);
21472600226SYatharth Kochar 
21572600226SYatharth Kochar 	return &next_bl_params;
21672600226SYatharth Kochar }
217