xref: /rk3399_ARM-atf/common/desc_image_load.c (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
172600226SYatharth Kochar /*
272600226SYatharth Kochar  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
372600226SYatharth Kochar  *
4*82cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
572600226SYatharth Kochar  */
672600226SYatharth Kochar 
772600226SYatharth Kochar #include <arch_helpers.h>
872600226SYatharth Kochar #include <assert.h>
972600226SYatharth Kochar #include <bl_common.h>
1072600226SYatharth Kochar #include <desc_image_load.h>
1172600226SYatharth Kochar 
1272600226SYatharth Kochar 
1372600226SYatharth Kochar extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
1472600226SYatharth Kochar extern unsigned int bl_mem_params_desc_num;
1572600226SYatharth Kochar 
1672600226SYatharth Kochar static bl_load_info_t bl_load_info;
1772600226SYatharth Kochar static bl_params_t next_bl_params;
1872600226SYatharth Kochar 
1972600226SYatharth Kochar 
2072600226SYatharth Kochar /*******************************************************************************
2172600226SYatharth Kochar  * This function flushes the data structures so that they are visible
2272600226SYatharth Kochar  * in memory for the next BL image.
2372600226SYatharth Kochar  ******************************************************************************/
2472600226SYatharth Kochar void flush_bl_params_desc(void)
2572600226SYatharth Kochar {
26c2a9ee63SDan Handley 	flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
2772600226SYatharth Kochar 			sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
28c2a9ee63SDan Handley 
29c2a9ee63SDan Handley 	flush_dcache_range((uintptr_t)&next_bl_params,
30c2a9ee63SDan Handley 			sizeof(next_bl_params));
3172600226SYatharth Kochar }
3272600226SYatharth Kochar 
3372600226SYatharth Kochar /*******************************************************************************
3472600226SYatharth Kochar  * This function returns the index for given image_id, within the
3572600226SYatharth Kochar  * image descriptor array provided by bl_image_info_descs_ptr, if the
3672600226SYatharth Kochar  * image is found else it returns -1.
3772600226SYatharth Kochar  ******************************************************************************/
3872600226SYatharth Kochar int get_bl_params_node_index(unsigned int image_id)
3972600226SYatharth Kochar {
4072600226SYatharth Kochar 	int index;
4172600226SYatharth Kochar 	assert(image_id != INVALID_IMAGE_ID);
4272600226SYatharth Kochar 
4372600226SYatharth Kochar 	for (index = 0; index < bl_mem_params_desc_num; index++) {
4472600226SYatharth Kochar 		if (bl_mem_params_desc_ptr[index].image_id == image_id)
4572600226SYatharth Kochar 			return index;
4672600226SYatharth Kochar 	}
4772600226SYatharth Kochar 
4872600226SYatharth Kochar 	return -1;
4972600226SYatharth Kochar }
5072600226SYatharth Kochar 
5172600226SYatharth Kochar /*******************************************************************************
5272600226SYatharth Kochar  * This function returns the pointer to `bl_mem_params_node_t` object for
5372600226SYatharth Kochar  * given image_id, within the image descriptor array provided by
5472600226SYatharth Kochar  * bl_mem_params_desc_ptr, if the image is found else it returns NULL.
5572600226SYatharth Kochar  ******************************************************************************/
5672600226SYatharth Kochar bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
5772600226SYatharth Kochar {
5872600226SYatharth Kochar 	int index;
5972600226SYatharth Kochar 	assert(image_id != INVALID_IMAGE_ID);
6072600226SYatharth Kochar 
6172600226SYatharth Kochar 	index = get_bl_params_node_index(image_id);
6272600226SYatharth Kochar 	if (index >= 0)
6372600226SYatharth Kochar 		return &bl_mem_params_desc_ptr[index];
6472600226SYatharth Kochar 	else
6572600226SYatharth Kochar 		return NULL;
6672600226SYatharth Kochar }
6772600226SYatharth Kochar 
6872600226SYatharth Kochar /*******************************************************************************
6972600226SYatharth Kochar  * This function creates the list of loadable images, by populating and
7072600226SYatharth Kochar  * linking each `bl_load_info_node_t` type node, using the internal array
7172600226SYatharth Kochar  * of image descriptor provided by bl_mem_params_desc_ptr. It also populates
7272600226SYatharth Kochar  * and returns `bl_load_info_t` type structure that contains head of the list
7372600226SYatharth Kochar  * of loadable images.
7472600226SYatharth Kochar  ******************************************************************************/
7572600226SYatharth Kochar bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
7672600226SYatharth Kochar {
7772600226SYatharth Kochar 	int index = 0;
7872600226SYatharth Kochar 
7972600226SYatharth Kochar 	/* If there is no image to start with, return NULL */
8072600226SYatharth Kochar 	if (!bl_mem_params_desc_num)
8172600226SYatharth Kochar 		return NULL;
8272600226SYatharth Kochar 
8372600226SYatharth Kochar 	/* Assign initial data structures */
8472600226SYatharth Kochar 	bl_load_info_node_t *bl_node_info =
8572600226SYatharth Kochar 		&bl_mem_params_desc_ptr[index].load_node_mem;
8672600226SYatharth Kochar 	bl_load_info.head = bl_node_info;
8772600226SYatharth Kochar 	SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0);
8872600226SYatharth Kochar 
8972600226SYatharth Kochar 	/* Go through the image descriptor array and create the list */
9072600226SYatharth Kochar 	for (; index < bl_mem_params_desc_num; index++) {
9172600226SYatharth Kochar 
9272600226SYatharth Kochar 		/* Populate the image information */
9372600226SYatharth Kochar 		bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
9472600226SYatharth Kochar 		bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
9572600226SYatharth Kochar 
9672600226SYatharth Kochar 		/* Link next image if present */
9772600226SYatharth Kochar 		if ((index + 1) < bl_mem_params_desc_num) {
9872600226SYatharth Kochar 			/* Get the memory and link the next node */
9972600226SYatharth Kochar 			bl_node_info->next_load_info =
10072600226SYatharth Kochar 				&bl_mem_params_desc_ptr[index + 1].load_node_mem;
10172600226SYatharth Kochar 			bl_node_info = bl_node_info->next_load_info;
10272600226SYatharth Kochar 		}
10372600226SYatharth Kochar 	}
10472600226SYatharth Kochar 
10572600226SYatharth Kochar 	return &bl_load_info;
10672600226SYatharth Kochar }
10772600226SYatharth Kochar 
10872600226SYatharth Kochar /*******************************************************************************
10972600226SYatharth Kochar  * This function creates the list of executable images, by populating and
11072600226SYatharth Kochar  * linking each `bl_params_node_t` type node, using the internal array of
11172600226SYatharth Kochar  * image descriptor provided by bl_mem_params_desc_ptr. It also populates
11272600226SYatharth Kochar  * and returns `bl_params_t` type structure that contains head of the list
11372600226SYatharth Kochar  * of executable images.
11472600226SYatharth Kochar  ******************************************************************************/
11572600226SYatharth Kochar bl_params_t *get_next_bl_params_from_mem_params_desc(void)
11672600226SYatharth Kochar {
11772600226SYatharth Kochar 	int count;
11872600226SYatharth Kochar 	unsigned int img_id = 0;
11972600226SYatharth Kochar 	int link_index = 0;
12072600226SYatharth Kochar 	bl_params_node_t *bl_current_exec_node = NULL;
12172600226SYatharth Kochar 	bl_params_node_t *bl_last_exec_node = NULL;
12272600226SYatharth Kochar 	bl_mem_params_node_t *desc_ptr;
12372600226SYatharth Kochar 
12472600226SYatharth Kochar 	/* If there is no image to start with, return NULL */
12572600226SYatharth Kochar 	if (!bl_mem_params_desc_num)
12672600226SYatharth Kochar 		return NULL;
12772600226SYatharth Kochar 
12872600226SYatharth Kochar 	/* Get the list HEAD */
12972600226SYatharth Kochar 	for (count = 0; count < bl_mem_params_desc_num; count++) {
13072600226SYatharth Kochar 
13172600226SYatharth Kochar 		desc_ptr = &bl_mem_params_desc_ptr[count];
13272600226SYatharth Kochar 
13372600226SYatharth Kochar 		if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
13472600226SYatharth Kochar 			(EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
13572600226SYatharth Kochar 			next_bl_params.head = &desc_ptr->params_node_mem;
13672600226SYatharth Kochar 			link_index = count;
13772600226SYatharth Kochar 			break;
13872600226SYatharth Kochar 		}
13972600226SYatharth Kochar 	}
14072600226SYatharth Kochar 
14172600226SYatharth Kochar 	/* Make sure we have a HEAD node */
14272600226SYatharth Kochar 	assert(next_bl_params.head != NULL);
14372600226SYatharth Kochar 
14472600226SYatharth Kochar 	/* Populate the HEAD information */
14572600226SYatharth Kochar 	SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0);
14672600226SYatharth Kochar 
14772600226SYatharth Kochar 	/*
14872600226SYatharth Kochar 	 * Go through the image descriptor array and create the list.
14972600226SYatharth Kochar 	 * This bounded loop is to make sure that we are not looping forever.
15072600226SYatharth Kochar 	 */
15172600226SYatharth Kochar 	for (count = 0 ; count < bl_mem_params_desc_num; count++) {
15272600226SYatharth Kochar 
15372600226SYatharth Kochar 		desc_ptr = &bl_mem_params_desc_ptr[link_index];
15472600226SYatharth Kochar 
15572600226SYatharth Kochar 		/* Make sure the image is executable */
15672600226SYatharth Kochar 		assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
15772600226SYatharth Kochar 
15872600226SYatharth Kochar 		/* Get the memory for current node */
15972600226SYatharth Kochar 		bl_current_exec_node = &desc_ptr->params_node_mem;
16072600226SYatharth Kochar 
16172600226SYatharth Kochar 		/* Populate the image information */
16272600226SYatharth Kochar 		bl_current_exec_node->image_id = desc_ptr->image_id;
16372600226SYatharth Kochar 		bl_current_exec_node->image_info = &desc_ptr->image_info;
16472600226SYatharth Kochar 		bl_current_exec_node->ep_info = &desc_ptr->ep_info;
16572600226SYatharth Kochar 
16672600226SYatharth Kochar 		if (bl_last_exec_node) {
16772600226SYatharth Kochar 			/* Assert if loop detected */
16872600226SYatharth Kochar 			assert(bl_last_exec_node->next_params_info == NULL);
16972600226SYatharth Kochar 
17072600226SYatharth Kochar 			/* Link the previous node to the current one */
17172600226SYatharth Kochar 			bl_last_exec_node->next_params_info = bl_current_exec_node;
17272600226SYatharth Kochar 		}
17372600226SYatharth Kochar 
17472600226SYatharth Kochar 		/* Update the last node */
17572600226SYatharth Kochar 		bl_last_exec_node = bl_current_exec_node;
17672600226SYatharth Kochar 
17772600226SYatharth Kochar 		/* If no next hand-off image then break out */
17872600226SYatharth Kochar 		img_id = desc_ptr->next_handoff_image_id;
17972600226SYatharth Kochar 		if (img_id == INVALID_IMAGE_ID)
18072600226SYatharth Kochar 			break;
18172600226SYatharth Kochar 
18272600226SYatharth Kochar 		/* Get the index for the next hand-off image */
18372600226SYatharth Kochar 		link_index = get_bl_params_node_index(img_id);
18472600226SYatharth Kochar 		assert((link_index > 0) &&
18572600226SYatharth Kochar 			(link_index < bl_mem_params_desc_num));
18672600226SYatharth Kochar 	}
18772600226SYatharth Kochar 
18872600226SYatharth Kochar 	/* Invalid image is expected to terminate the loop */
18972600226SYatharth Kochar 	assert(img_id == INVALID_IMAGE_ID);
19072600226SYatharth Kochar 
19172600226SYatharth Kochar 	return &next_bl_params;
19272600226SYatharth Kochar }
193