Commit 72600226 authored by Yatharth Kochar's avatar Yatharth Kochar
Browse files

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
parent 131f7cd4
...@@ -115,7 +115,8 @@ ENABLE_PSCI_STAT := 0 ...@@ -115,7 +115,8 @@ ENABLE_PSCI_STAT := 0
# Whether code and read-only data should be put on separate memory pages. # Whether code and read-only data should be put on separate memory pages.
# The platform Makefile is free to override this value. # The platform Makefile is free to override this value.
SEPARATE_CODE_AND_RODATA := 0 SEPARATE_CODE_AND_RODATA := 0
# Flag to enable new version of image loading
LOAD_IMAGE_V2 := 0
################################################################################ ################################################################################
# Checkpatch script options # Checkpatch script options
...@@ -355,6 +356,13 @@ ifeq (${NEED_BL33},yes) ...@@ -355,6 +356,13 @@ ifeq (${NEED_BL33},yes)
endif endif
endif endif
# TRUSTED_BOARD_BOOT is currently not supported when LOAD_IMAGE_V2 is enabled.
ifeq (${LOAD_IMAGE_V2},1)
ifeq (${TRUSTED_BOARD_BOOT},1)
$(error "TRUSTED_BOARD_BOOT is currently not supported \
for LOAD_IMAGE_V2=1")
endif
endif
################################################################################ ################################################################################
# Process platform overrideable behaviour # Process platform overrideable behaviour
...@@ -445,6 +453,7 @@ $(eval $(call assert_boolean,PL011_GENERIC_UART)) ...@@ -445,6 +453,7 @@ $(eval $(call assert_boolean,PL011_GENERIC_UART))
$(eval $(call assert_boolean,ENABLE_PMF)) $(eval $(call assert_boolean,ENABLE_PMF))
$(eval $(call assert_boolean,ENABLE_PSCI_STAT)) $(eval $(call assert_boolean,ENABLE_PSCI_STAT))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
$(eval $(call assert_boolean,LOAD_IMAGE_V2))
################################################################################ ################################################################################
...@@ -475,6 +484,7 @@ $(eval $(call add_define,PL011_GENERIC_UART)) ...@@ -475,6 +484,7 @@ $(eval $(call add_define,PL011_GENERIC_UART))
$(eval $(call add_define,ENABLE_PMF)) $(eval $(call add_define,ENABLE_PMF))
$(eval $(call add_define,ENABLE_PSCI_STAT)) $(eval $(call add_define,ENABLE_PSCI_STAT))
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA)) $(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
$(eval $(call add_define,LOAD_IMAGE_V2))
# Define the EL3_PAYLOAD_BASE flag only if it is provided. # Define the EL3_PAYLOAD_BASE flag only if it is provided.
ifdef EL3_PAYLOAD_BASE ifdef EL3_PAYLOAD_BASE
$(eval $(call add_define,EL3_PAYLOAD_BASE)) $(eval $(call add_define,EL3_PAYLOAD_BASE))
......
...@@ -53,10 +53,7 @@ uintptr_t page_align(uintptr_t value, unsigned dir) ...@@ -53,10 +53,7 @@ uintptr_t page_align(uintptr_t value, unsigned dir)
return value; return value;
} }
static inline unsigned int is_page_aligned (uintptr_t addr) { #if !LOAD_IMAGE_V2
return (addr & (PAGE_SIZE - 1)) == 0;
}
/****************************************************************************** /******************************************************************************
* Determine whether the memory region delimited by 'addr' and 'size' is free, * Determine whether the memory region delimited by 'addr' and 'size' is free,
* given the extents of free memory. * given the extents of free memory.
...@@ -179,6 +176,7 @@ static void dump_load_info(uintptr_t image_load_addr, ...@@ -179,6 +176,7 @@ static void dump_load_info(uintptr_t image_load_addr,
INFO(" free region = [base = %p, size = 0x%zx]\n", INFO(" free region = [base = %p, size = 0x%zx]\n",
(void *) mem_layout->free_base, mem_layout->free_size); (void *) mem_layout->free_base, mem_layout->free_size);
} }
#endif /* LOAD_IMAGE_V2 */
/* Generic function to return the size of an image */ /* Generic function to return the size of an image */
size_t image_size(unsigned int image_id) size_t image_size(unsigned int image_id)
...@@ -223,6 +221,156 @@ size_t image_size(unsigned int image_id) ...@@ -223,6 +221,156 @@ size_t image_size(unsigned int image_id)
return image_size; return image_size;
} }
#if LOAD_IMAGE_V2
/*******************************************************************************
* Generic function to load an image at a specific address given
* an image ID and extents of free memory.
*
* If the load is successful then the image information is updated.
*
* Returns 0 on success, a negative error code otherwise.
******************************************************************************/
int load_image(unsigned int image_id, image_info_t *image_data)
{
uintptr_t dev_handle;
uintptr_t image_handle;
uintptr_t image_spec;
uintptr_t image_base;
size_t image_size;
size_t bytes_read;
int io_result;
assert(image_data != NULL);
assert(image_data->h.version >= VERSION_2);
image_base = image_data->image_base;
/* Obtain a reference to the image by querying the platform layer */
io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
if (io_result != 0) {
WARN("Failed to obtain reference to image id=%u (%i)\n",
image_id, io_result);
return io_result;
}
/* Attempt to access the image */
io_result = io_open(dev_handle, image_spec, &image_handle);
if (io_result != 0) {
WARN("Failed to access image id=%u (%i)\n",
image_id, io_result);
return io_result;
}
INFO("Loading image id=%u at address %p\n", image_id,
(void *) image_base);
/* Find the size of the image */
io_result = io_size(image_handle, &image_size);
if ((io_result != 0) || (image_size == 0)) {
WARN("Failed to determine the size of the image id=%u (%i)\n",
image_id, io_result);
goto exit;
}
/* Check that the image size to load is within limit */
if (image_size > image_data->image_max_size) {
WARN("Image id=%u size out of bounds\n", image_id);
io_result = -EFBIG;
goto exit;
}
image_data->image_size = image_size;
/* We have enough space so load the image now */
/* TODO: Consider whether to try to recover/retry a partially successful read */
io_result = io_read(image_handle, image_base, image_size, &bytes_read);
if ((io_result != 0) || (bytes_read < image_size)) {
WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
goto exit;
}
#if !TRUSTED_BOARD_BOOT
/*
* File has been successfully loaded.
* Flush the image to main memory so that it can be executed later by
* any CPU, regardless of cache and MMU state.
* When TBB is enabled the image is flushed later, after image
* authentication.
*/
flush_dcache_range(image_base, image_size);
#endif /* TRUSTED_BOARD_BOOT */
INFO("Image id=%u loaded: %p - %p\n", image_id, (void *) image_base,
(void *) (image_base + image_size));
exit:
io_close(image_handle);
/* Ignore improbable/unrecoverable error in 'close' */
/* TODO: Consider maintaining open device connection from this bootloader stage */
io_dev_close(dev_handle);
/* Ignore improbable/unrecoverable error in 'dev_close' */
return io_result;
}
/*******************************************************************************
* Generic function to load and authenticate an image. The image is actually
* loaded by calling the 'load_image()' function. Therefore, it returns the
* same error codes if the loading operation failed, or -EAUTH if the
* authentication failed. In addition, this function uses recursion to
* authenticate the parent images up to the root of trust.
******************************************************************************/
int load_auth_image(unsigned int image_id, image_info_t *image_data)
{
int rc;
#if TRUSTED_BOARD_BOOT
unsigned int parent_id;
/* Use recursion to authenticate parent images */
rc = auth_mod_get_parent_id(image_id, &parent_id);
if (rc == 0) {
rc = load_auth_image(parent_id, image_data);
if (rc != 0) {
return rc;
}
}
#endif /* TRUSTED_BOARD_BOOT */
/* Load the image */
rc = load_image(image_id, image_data);
if (rc != 0) {
return rc;
}
#if TRUSTED_BOARD_BOOT
/* Authenticate it */
rc = auth_mod_verify_img(image_id,
(void *)image_data->image_base,
image_data->image_size);
if (rc != 0) {
memset((void *)image_data->image_base, 0x00,
image_data->image_size);
flush_dcache_range(image_data->image_base,
image_data->image_size);
return -EAUTH;
}
/*
* File has been successfully loaded and authenticated.
* Flush the image to main memory so that it can be executed later by
* any CPU, regardless of cache and MMU state.
*/
flush_dcache_range(image_data->image_base, image_data->image_size);
#endif /* TRUSTED_BOARD_BOOT */
return 0;
}
#else /* LOAD_IMAGE_V2 */
/******************************************************************************* /*******************************************************************************
* Generic function to load an image at a specific address given an image ID and * Generic function to load an image at a specific address given an image ID and
* extents of free memory. * extents of free memory.
...@@ -255,7 +403,7 @@ int load_image(meminfo_t *mem_layout, ...@@ -255,7 +403,7 @@ int load_image(meminfo_t *mem_layout,
assert(mem_layout != NULL); assert(mem_layout != NULL);
assert(image_data != NULL); assert(image_data != NULL);
assert(image_data->h.version >= VERSION_1); assert(image_data->h.version == VERSION_1);
/* Obtain a reference to the image by querying the platform layer */ /* Obtain a reference to the image by querying the platform layer */
io_result = plat_get_image_source(image_id, &dev_handle, &image_spec); io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
...@@ -348,8 +496,10 @@ exit: ...@@ -348,8 +496,10 @@ exit:
/******************************************************************************* /*******************************************************************************
* Generic function to load and authenticate an image. The image is actually * Generic function to load and authenticate an image. The image is actually
* loaded by calling the 'load_image()' function. In addition, this function * loaded by calling the 'load_image()' function. Therefore, it returns the
* uses recursion to authenticate the parent images up to the root of trust. * same error codes if the loading operation failed, or -EAUTH if the
* authentication failed. In addition, this function uses recursion to
* authenticate the parent images up to the root of trust.
******************************************************************************/ ******************************************************************************/
int load_auth_image(meminfo_t *mem_layout, int load_auth_image(meminfo_t *mem_layout,
unsigned int image_id, unsigned int image_id,
...@@ -403,6 +553,8 @@ int load_auth_image(meminfo_t *mem_layout, ...@@ -403,6 +553,8 @@ int load_auth_image(meminfo_t *mem_layout,
return 0; return 0;
} }
#endif /* LOAD_IMAGE_V2 */
/******************************************************************************* /*******************************************************************************
* Print the content of an entry_point_info_t structure. * Print the content of an entry_point_info_t structure.
******************************************************************************/ ******************************************************************************/
......
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#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((unsigned long)bl_mem_params_desc_ptr,
sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
}
/*******************************************************************************
* 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);
/* Populate arg0 for the next BL image */
next_bl_params.head->ep_info->args.arg0 = (unsigned long)&next_bl_params;
/* Flush the parameters to be passed to the next BL image */
flush_dcache_range((unsigned long)&next_bl_params,
sizeof(next_bl_params));
return &next_bl_params;
}
...@@ -721,7 +721,6 @@ Firmware represents the power domain topology and how this relates to the ...@@ -721,7 +721,6 @@ Firmware represents the power domain topology and how this relates to the
linear CPU index, please refer [Power Domain Topology Design]. linear CPU index, please refer [Power Domain Topology Design].
2.4 Common optional modifications 2.4 Common optional modifications
--------------------------------- ---------------------------------
...@@ -841,10 +840,37 @@ and must be implemented in assembly because it may be called before the C ...@@ -841,10 +840,37 @@ and must be implemented in assembly because it may be called before the C
environment is initialized. environment is initialized.
Note: The address from where it was called is stored in x30 (Link Register). Note: The address from where it was called is stored in x30 (Link Register).
The default implementation simply spins. The default implementation simply spins.
### Function : plat_get_bl_image_load_info()
Argument : void
Return : bl_load_info_t *
This function returns pointer to the list of images that the platform has
populated to load. This function is currently invoked in BL2 to load the
BL3xx images, when LOAD_IMAGE_V2 is enabled.
### Function : plat_get_next_bl_params()
Argument : void
Return : bl_params_t *
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. This function is currently invoked in BL2 to pass this information to
the next BL image, when LOAD_IMAGE_V2 is enabled.
### Function : plat_flush_next_bl_params()
Argument : void
Return : void
This function flushes to main memory all the image params that are passed to
next image. This function is currently invoked in BL2 to flush this information
to the next BL image, when LOAD_IMAGE_V2 is enabled.
3. Modifications specific to a Boot Loader stage 3. Modifications specific to a Boot Loader stage
------------------------------------------------- -------------------------------------------------
...@@ -1175,6 +1201,20 @@ populated with the extents of secure RAM available for BL2 to use. See ...@@ -1175,6 +1201,20 @@ populated with the extents of secure RAM available for BL2 to use. See
`bl2_early_platform_setup()` above. `bl2_early_platform_setup()` above.
Following function is required only when LOAD_IMAGE_V2 is enabled.
### Function : bl2_plat_handle_post_image_load() [mandatory]
Argument : unsigned int
Return : int
This function can be used by the platforms to update/use image information
for given `image_id`. This function is currently invoked in BL2 to handle
BL image specific information based on the `image_id` passed, when
LOAD_IMAGE_V2 is enabled.
Following functions are required only when LOAD_IMAGE_V2 is disabled.
### Function : bl2_plat_get_scp_bl2_meminfo() [mandatory] ### Function : bl2_plat_get_scp_bl2_meminfo() [mandatory]
Argument : meminfo * Argument : meminfo *
......
...@@ -430,6 +430,12 @@ performed. ...@@ -430,6 +430,12 @@ performed.
pages" section in [Firmware Design]. This flag is disabled by default and pages" section in [Firmware Design]. This flag is disabled by default and
affects all BL images. affects all BL images.
* `LOAD_IMAGE_V2`: Boolean option to enable support for new version (v2) of
image loading, which provides more flexibility and scalability around what
images are loaded and executed during boot. Default is 0.
Note: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2`
is enabled.
#### ARM development platform specific build options #### ARM development platform specific build options
* `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options: * `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options:
......
...@@ -93,11 +93,22 @@ ...@@ -93,11 +93,22 @@
#define EP_GET_EXE(x) (x & EP_EXE_MASK) #define EP_GET_EXE(x) (x & EP_EXE_MASK)
#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee)) #define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee))
#define EP_FIRST_EXE_MASK 0x10
#define EP_FIRST_EXE 0x10
#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK)
#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee))
#define PARAM_EP 0x01 #define PARAM_EP 0x01
#define PARAM_IMAGE_BINARY 0x02 #define PARAM_IMAGE_BINARY 0x02
#define PARAM_BL31 0x03 #define PARAM_BL31 0x03
#define PARAM_BL_LOAD_INFO 0x04
#define PARAM_BL_PARAMS 0x05
#define IMAGE_ATTRIB_SKIP_LOADING 0x02
#define IMAGE_ATTRIB_PLAT_SETUP 0x04
#define VERSION_1 0x01 #define VERSION_1 0x01
#define VERSION_2 0x02
#define INVALID_IMAGE_ID (0xFFFFFFFF) #define INVALID_IMAGE_ID (0xFFFFFFFF)
...@@ -181,8 +192,10 @@ extern uintptr_t __COHERENT_RAM_END__; ...@@ -181,8 +192,10 @@ extern uintptr_t __COHERENT_RAM_END__;
typedef struct meminfo { typedef struct meminfo {
uintptr_t total_base; uintptr_t total_base;
size_t total_size; size_t total_size;
#if !LOAD_IMAGE_V2
uintptr_t free_base; uintptr_t free_base;
size_t free_size; size_t free_size;
#endif
} meminfo_t; } meminfo_t;
typedef struct aapcs64_params { typedef struct aapcs64_params {
...@@ -245,6 +258,9 @@ typedef struct image_info { ...@@ -245,6 +258,9 @@ typedef struct image_info {
param_header_t h; param_header_t h;
uintptr_t image_base; /* physical address of base of image */ uintptr_t image_base; /* physical address of base of image */
uint32_t image_size; /* bytes read from image file */ uint32_t image_size; /* bytes read from image file */
#if LOAD_IMAGE_V2
uint32_t image_max_size;
#endif
} image_info_t; } image_info_t;
/***************************************************************************** /*****************************************************************************
...@@ -263,6 +279,39 @@ typedef struct image_desc { ...@@ -263,6 +279,39 @@ typedef struct image_desc {
entry_point_info_t ep_info; entry_point_info_t ep_info;
} image_desc_t; } image_desc_t;
#if LOAD_IMAGE_V2
/* BL image node in the BL image loading sequence */
typedef struct bl_load_info_node {
unsigned int image_id;
image_info_t *image_info;
struct bl_load_info_node *next_load_info;
} bl_load_info_node_t;
/* BL image head node in the BL image loading sequence */
typedef struct bl_load_info {
param_header_t h;
bl_load_info_node_t *head;
} bl_load_info_t;
/* BL image node in the BL image execution sequence */
typedef struct bl_params_node {
unsigned int image_id;
image_info_t *image_info;
entry_point_info_t *ep_info;
struct bl_params_node *next_params_info;
} bl_params_node_t;
/*
* BL image head node in the BL image execution sequence
* It is also used to pass information to next BL image.
*/
typedef struct bl_params {
param_header_t h;
bl_params_node_t *head;
} bl_params_t;
#else /* LOAD_IMAGE_V2 */
/******************************************************************************* /*******************************************************************************
* This structure represents the superset of information that can be passed to * This structure represents the superset of information that can be passed to
* BL31 e.g. while passing control to it from BL2. The BL32 parameters will be * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
...@@ -286,6 +335,7 @@ typedef struct bl31_params { ...@@ -286,6 +335,7 @@ typedef struct bl31_params {
image_info_t *bl33_image_info; image_info_t *bl33_image_info;
} bl31_params_t; } bl31_params_t;
#endif /* LOAD_IMAGE_V2 */
/* /*
* Compile time assertions related to the 'entry_point_info' structure to * Compile time assertions related to the 'entry_point_info' structure to
...@@ -308,24 +358,34 @@ CASSERT(sizeof(uintptr_t) == ...@@ -308,24 +358,34 @@ CASSERT(sizeof(uintptr_t) ==
/******************************************************************************* /*******************************************************************************
* Function & variable prototypes * Function & variable prototypes
******************************************************************************/ ******************************************************************************/
uintptr_t page_align(uintptr_t, unsigned);
size_t image_size(unsigned int image_id); size_t image_size(unsigned int image_id);
#if LOAD_IMAGE_V2
int load_image(unsigned int image_id, image_info_t *image_data);
int load_auth_image(unsigned int image_id, image_info_t *image_data);
#else
uintptr_t page_align(uintptr_t, unsigned);
int load_image(meminfo_t *mem_layout, int load_image(meminfo_t *mem_layout,
unsigned int image_id, unsigned int image_id,
uintptr_t image_base, uintptr_t image_base,
image_info_t *image_data, image_info_t *image_data,
entry_point_info_t *entry_point_info); entry_point_info_t *entry_point_info);
int load_auth_image(meminfo_t *mem_layout, int load_auth_image(meminfo_t *mem_layout,
unsigned int image_name, unsigned int image_id,
uintptr_t image_base, uintptr_t image_base,
image_info_t *image_data, image_info_t *image_data,
entry_point_info_t *entry_point_info); entry_point_info_t *entry_point_info);
extern const char build_message[];
extern const char version_string[];
void reserve_mem(uintptr_t *free_base, size_t *free_size, void reserve_mem(uintptr_t *free_base, size_t *free_size,
uintptr_t addr, size_t size); uintptr_t addr, size_t size);
#endif /* LOAD_IMAGE_V2 */
extern const char build_message[];
extern const char version_string[];
void print_entry_point_info(const entry_point_info_t *ep_info); void print_entry_point_info(const entry_point_info_t *ep_info);
#endif /*__ASSEMBLY__*/ #endif /*__ASSEMBLY__*/
......
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __DESC_IMAGE_LOAD_H__
#define __DESC_IMAGE_LOAD_H__
#include <bl_common.h>
#if LOAD_IMAGE_V2
/* Following structure is used to store BL ep/image info. */
typedef struct bl_mem_params_node {
unsigned int image_id;
image_info_t image_info;
entry_point_info_t ep_info;
unsigned int next_handoff_image_id;
bl_load_info_node_t load_node_mem;
bl_params_node_t params_node_mem;
} bl_mem_params_node_t;
/*
* Macro to register list of BL image descriptors,
* defined as an array of bl_mem_params_node_t.
*/
#define REGISTER_BL_IMAGE_DESCS(_img_desc) \
bl_mem_params_node_t *bl_mem_params_desc_ptr = &_img_desc[0]; \
unsigned int bl_mem_params_desc_num = ARRAY_SIZE(_img_desc);
/* BL image loading utility functions */
void flush_bl_params_desc(void);
int get_bl_params_node_index(unsigned int image_id);
bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
bl_params_t *get_next_bl_params_from_mem_params_desc(void);
#endif /* LOAD_IMAGE_V2 */
#endif /* __DESC_IMAGE_LOAD_H__ */
...@@ -44,6 +44,8 @@ struct image_info; ...@@ -44,6 +44,8 @@ struct image_info;
struct entry_point_info; struct entry_point_info;
struct bl31_params; struct bl31_params;
struct image_desc; struct image_desc;
struct bl_load_info;
struct bl_params;
/******************************************************************************* /*******************************************************************************
* plat_get_rotpk_info() flags * plat_get_rotpk_info() flags
...@@ -138,6 +140,15 @@ void bl2_plat_arch_setup(void); ...@@ -138,6 +140,15 @@ void bl2_plat_arch_setup(void);
void bl2_platform_setup(void); void bl2_platform_setup(void);
struct meminfo *bl2_plat_sec_mem_layout(void); struct meminfo *bl2_plat_sec_mem_layout(void);
#if LOAD_IMAGE_V2
/*
* This function can be used by the platforms to update/use image
* information for given `image_id`.
*/
int bl2_plat_handle_post_image_load(unsigned int image_id);
#else /* LOAD_IMAGE_V2 */
/* /*
* This function returns a pointer to the shared memory that the platform has * This function returns a pointer to the shared memory that the platform has
* kept aside to pass trusted firmware related information that BL31 * kept aside to pass trusted firmware related information that BL31
...@@ -194,6 +205,8 @@ void bl2_plat_set_bl32_ep_info(struct image_info *image, ...@@ -194,6 +205,8 @@ void bl2_plat_set_bl32_ep_info(struct image_info *image,
/* Gets the memory layout for BL32 */ /* Gets the memory layout for BL32 */
void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info); void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
#endif /* LOAD_IMAGE_V2 */
/******************************************************************************* /*******************************************************************************
* Optional BL2 functions (may be overridden) * Optional BL2 functions (may be overridden)
******************************************************************************/ ******************************************************************************/
...@@ -218,8 +231,13 @@ int bl2u_plat_handle_scp_bl2u(void); ...@@ -218,8 +231,13 @@ int bl2u_plat_handle_scp_bl2u(void);
/******************************************************************************* /*******************************************************************************
* Mandatory BL31 functions * Mandatory BL31 functions
******************************************************************************/ ******************************************************************************/
#if LOAD_IMAGE_V2
void bl31_early_platform_setup(void *from_bl2,
void *plat_params_from_bl2);
#else
void bl31_early_platform_setup(struct bl31_params *from_bl2, void bl31_early_platform_setup(struct bl31_params *from_bl2,
void *plat_params_from_bl2); void *plat_params_from_bl2);
#endif
void bl31_plat_arch_setup(void); void bl31_plat_arch_setup(void);
void bl31_platform_setup(void); void bl31_platform_setup(void);
void bl31_plat_runtime_setup(void); void bl31_plat_runtime_setup(void);
...@@ -257,6 +275,31 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, ...@@ -257,6 +275,31 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr); int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr);
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr); int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
#if LOAD_IMAGE_V2
/*******************************************************************************
* Mandatory BL image load functions(may be overridden).
******************************************************************************/
/*
* This function returns pointer to the list of images that the
* platform has populated to load.
*/
struct bl_load_info *plat_get_bl_image_load_info(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 could need.
*/
struct bl_params *plat_get_next_bl_params(void);
/*
* This function flushes to main memory all the params that are
* passed to next image.
*/
void plat_flush_next_bl_params(void);
#endif /* LOAD_IMAGE_V2 */
#if ENABLE_PLAT_COMPAT #if ENABLE_PLAT_COMPAT
/* /*
* The below declarations are to enable compatibility for the platform ports * The below declarations are to enable compatibility for the platform ports
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment