arm-trusted-firmware/common/desc_image_load.c

193 lines
6.2 KiB
C
Raw Normal View History

Add new version of image loading. This patch adds capability to load BL images based on image descriptors instead of hard coded way of loading BL images. This framework is designed such that it can be readily adapted by any BL stage that needs to load images. In order to provide the above capability the following new platform functions are introduced: bl_load_info_t *plat_get_bl_image_load_info(void); This function returns pointer to the list of images that the platform has populated to load. bl_params_t *plat_get_next_bl_params(void); This function returns a pointer to the shared memory that the platform has kept aside to pass trusted firmware related information that next BL image needs. void plat_flush_next_bl_params(void); This function flushes to main memory all the params that are passed to next image. int bl2_plat_handle_post_image_load(unsigned int image_id) This function can be used by the platforms to update/use image information for given `image_id`. `desc_image_load.c` contains utility functions which can be used by the platforms to generate, load and executable, image list based on the registered image descriptors. This patch also adds new version of `load_image/load_auth_image` functions in-order to achieve the above capability. Following are the changes for the new version as compared to old: - Refactor the signature and only keep image_id and image_info_t arguments. Removed image_base argument as it is already passed through image_info_t. Given that the BL image base addresses and limit/size are already provided by the platforms, the meminfo_t and entry_point_info arguments are not needed to provide/reserve the extent of free memory for the given BL image. - Added check for the image size against the defined max size. This is needed because the image size could come from an unauthenticated source (e.g. the FIP header). To make this check, new member is added to the image_info_t struct for identifying the image maximum size. New flag `LOAD_IMAGE_V2` is added in the Makefile. Default value is 0. NOTE: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2` is enabled. Change-Id: Ia7b643f4817a170d5a2fbf479b9bc12e63112e79
2016-09-12 16:08:41 +01:00
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
Add new version of image loading. This patch adds capability to load BL images based on image descriptors instead of hard coded way of loading BL images. This framework is designed such that it can be readily adapted by any BL stage that needs to load images. In order to provide the above capability the following new platform functions are introduced: bl_load_info_t *plat_get_bl_image_load_info(void); This function returns pointer to the list of images that the platform has populated to load. bl_params_t *plat_get_next_bl_params(void); This function returns a pointer to the shared memory that the platform has kept aside to pass trusted firmware related information that next BL image needs. void plat_flush_next_bl_params(void); This function flushes to main memory all the params that are passed to next image. int bl2_plat_handle_post_image_load(unsigned int image_id) This function can be used by the platforms to update/use image information for given `image_id`. `desc_image_load.c` contains utility functions which can be used by the platforms to generate, load and executable, image list based on the registered image descriptors. This patch also adds new version of `load_image/load_auth_image` functions in-order to achieve the above capability. Following are the changes for the new version as compared to old: - Refactor the signature and only keep image_id and image_info_t arguments. Removed image_base argument as it is already passed through image_info_t. Given that the BL image base addresses and limit/size are already provided by the platforms, the meminfo_t and entry_point_info arguments are not needed to provide/reserve the extent of free memory for the given BL image. - Added check for the image size against the defined max size. This is needed because the image size could come from an unauthenticated source (e.g. the FIP header). To make this check, new member is added to the image_info_t struct for identifying the image maximum size. New flag `LOAD_IMAGE_V2` is added in the Makefile. Default value is 0. NOTE: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2` is enabled. Change-Id: Ia7b643f4817a170d5a2fbf479b9bc12e63112e79
2016-09-12 16:08:41 +01:00
*/
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <desc_image_load.h>
extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
extern unsigned int bl_mem_params_desc_num;
static bl_load_info_t bl_load_info;
static bl_params_t next_bl_params;
/*******************************************************************************
* This function flushes the data structures so that they are visible
* in memory for the next BL image.
******************************************************************************/
void flush_bl_params_desc(void)
{
flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
Add new version of image loading. This patch adds capability to load BL images based on image descriptors instead of hard coded way of loading BL images. This framework is designed such that it can be readily adapted by any BL stage that needs to load images. In order to provide the above capability the following new platform functions are introduced: bl_load_info_t *plat_get_bl_image_load_info(void); This function returns pointer to the list of images that the platform has populated to load. bl_params_t *plat_get_next_bl_params(void); This function returns a pointer to the shared memory that the platform has kept aside to pass trusted firmware related information that next BL image needs. void plat_flush_next_bl_params(void); This function flushes to main memory all the params that are passed to next image. int bl2_plat_handle_post_image_load(unsigned int image_id) This function can be used by the platforms to update/use image information for given `image_id`. `desc_image_load.c` contains utility functions which can be used by the platforms to generate, load and executable, image list based on the registered image descriptors. This patch also adds new version of `load_image/load_auth_image` functions in-order to achieve the above capability. Following are the changes for the new version as compared to old: - Refactor the signature and only keep image_id and image_info_t arguments. Removed image_base argument as it is already passed through image_info_t. Given that the BL image base addresses and limit/size are already provided by the platforms, the meminfo_t and entry_point_info arguments are not needed to provide/reserve the extent of free memory for the given BL image. - Added check for the image size against the defined max size. This is needed because the image size could come from an unauthenticated source (e.g. the FIP header). To make this check, new member is added to the image_info_t struct for identifying the image maximum size. New flag `LOAD_IMAGE_V2` is added in the Makefile. Default value is 0. NOTE: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2` is enabled. Change-Id: Ia7b643f4817a170d5a2fbf479b9bc12e63112e79
2016-09-12 16:08:41 +01:00
sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
flush_dcache_range((uintptr_t)&next_bl_params,
sizeof(next_bl_params));
Add new version of image loading. This patch adds capability to load BL images based on image descriptors instead of hard coded way of loading BL images. This framework is designed such that it can be readily adapted by any BL stage that needs to load images. In order to provide the above capability the following new platform functions are introduced: bl_load_info_t *plat_get_bl_image_load_info(void); This function returns pointer to the list of images that the platform has populated to load. bl_params_t *plat_get_next_bl_params(void); This function returns a pointer to the shared memory that the platform has kept aside to pass trusted firmware related information that next BL image needs. void plat_flush_next_bl_params(void); This function flushes to main memory all the params that are passed to next image. int bl2_plat_handle_post_image_load(unsigned int image_id) This function can be used by the platforms to update/use image information for given `image_id`. `desc_image_load.c` contains utility functions which can be used by the platforms to generate, load and executable, image list based on the registered image descriptors. This patch also adds new version of `load_image/load_auth_image` functions in-order to achieve the above capability. Following are the changes for the new version as compared to old: - Refactor the signature and only keep image_id and image_info_t arguments. Removed image_base argument as it is already passed through image_info_t. Given that the BL image base addresses and limit/size are already provided by the platforms, the meminfo_t and entry_point_info arguments are not needed to provide/reserve the extent of free memory for the given BL image. - Added check for the image size against the defined max size. This is needed because the image size could come from an unauthenticated source (e.g. the FIP header). To make this check, new member is added to the image_info_t struct for identifying the image maximum size. New flag `LOAD_IMAGE_V2` is added in the Makefile. Default value is 0. NOTE: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2` is enabled. Change-Id: Ia7b643f4817a170d5a2fbf479b9bc12e63112e79
2016-09-12 16:08:41 +01:00
}
/*******************************************************************************
* This function returns the index for given image_id, within the
* image descriptor array provided by bl_image_info_descs_ptr, if the
* image is found else it returns -1.
******************************************************************************/
int get_bl_params_node_index(unsigned int image_id)
{
int index;
assert(image_id != INVALID_IMAGE_ID);
for (index = 0; index < bl_mem_params_desc_num; index++) {
if (bl_mem_params_desc_ptr[index].image_id == image_id)
return index;
}
return -1;
}
/*******************************************************************************
* This function returns the pointer to `bl_mem_params_node_t` object for
* given image_id, within the image descriptor array provided by
* bl_mem_params_desc_ptr, if the image is found else it returns NULL.
******************************************************************************/
bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
{
int index;
assert(image_id != INVALID_IMAGE_ID);
index = get_bl_params_node_index(image_id);
if (index >= 0)
return &bl_mem_params_desc_ptr[index];
else
return NULL;
}
/*******************************************************************************
* This function creates the list of loadable images, by populating and
* linking each `bl_load_info_node_t` type node, using the internal array
* of image descriptor provided by bl_mem_params_desc_ptr. It also populates
* and returns `bl_load_info_t` type structure that contains head of the list
* of loadable images.
******************************************************************************/
bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
{
int index = 0;
/* If there is no image to start with, return NULL */
if (!bl_mem_params_desc_num)
return NULL;
/* Assign initial data structures */
bl_load_info_node_t *bl_node_info =
&bl_mem_params_desc_ptr[index].load_node_mem;
bl_load_info.head = bl_node_info;
SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0);
/* Go through the image descriptor array and create the list */
for (; index < bl_mem_params_desc_num; index++) {
/* Populate the image information */
bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
/* Link next image if present */
if ((index + 1) < bl_mem_params_desc_num) {
/* Get the memory and link the next node */
bl_node_info->next_load_info =
&bl_mem_params_desc_ptr[index + 1].load_node_mem;
bl_node_info = bl_node_info->next_load_info;
}
}
return &bl_load_info;
}
/*******************************************************************************
* This function creates the list of executable images, by populating and
* linking each `bl_params_node_t` type node, using the internal array of
* image descriptor provided by bl_mem_params_desc_ptr. It also populates
* and returns `bl_params_t` type structure that contains head of the list
* of executable images.
******************************************************************************/
bl_params_t *get_next_bl_params_from_mem_params_desc(void)
{
int count;
unsigned int img_id = 0;
int link_index = 0;
bl_params_node_t *bl_current_exec_node = NULL;
bl_params_node_t *bl_last_exec_node = NULL;
bl_mem_params_node_t *desc_ptr;
/* If there is no image to start with, return NULL */
if (!bl_mem_params_desc_num)
return NULL;
/* Get the list HEAD */
for (count = 0; count < bl_mem_params_desc_num; count++) {
desc_ptr = &bl_mem_params_desc_ptr[count];
if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
(EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
next_bl_params.head = &desc_ptr->params_node_mem;
link_index = count;
break;
}
}
/* Make sure we have a HEAD node */
assert(next_bl_params.head != NULL);
/* Populate the HEAD information */
SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0);
/*
* Go through the image descriptor array and create the list.
* This bounded loop is to make sure that we are not looping forever.
*/
for (count = 0 ; count < bl_mem_params_desc_num; count++) {
desc_ptr = &bl_mem_params_desc_ptr[link_index];
/* Make sure the image is executable */
assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
/* Get the memory for current node */
bl_current_exec_node = &desc_ptr->params_node_mem;
/* Populate the image information */
bl_current_exec_node->image_id = desc_ptr->image_id;
bl_current_exec_node->image_info = &desc_ptr->image_info;
bl_current_exec_node->ep_info = &desc_ptr->ep_info;
if (bl_last_exec_node) {
/* Assert if loop detected */
assert(bl_last_exec_node->next_params_info == NULL);
/* Link the previous node to the current one */
bl_last_exec_node->next_params_info = bl_current_exec_node;
}
/* Update the last node */
bl_last_exec_node = bl_current_exec_node;
/* If no next hand-off image then break out */
img_id = desc_ptr->next_handoff_image_id;
if (img_id == INVALID_IMAGE_ID)
break;
/* Get the index for the next hand-off image */
link_index = get_bl_params_node_index(img_id);
assert((link_index > 0) &&
(link_index < bl_mem_params_desc_num));
}
/* Invalid image is expected to terminate the loop */
assert(img_id == INVALID_IMAGE_ID);
return &next_bl_params;
}