Commit 8f55dfb4 authored by Sandrine Bailleux's avatar Sandrine Bailleux
Browse files

Remove concept of top/bottom image loading

This concept is no longer required since we now support loading of
images at fixed addresses only.

The image loader now automatically detects the position of the image
inside the current memory layout and updates the layout such that
memory fragmentation is minimised.

The 'attr' field of the meminfo data structure, which used to hold
the bottom/top loading information, has been removed. Also the 'next'
field has been removed as it wasn't used anywhere.

The 'init_bl2_mem_layout()' function has been moved out of common
code and put in BL1-specific code. It has also been renamed into
'bl1_init_bl2_mem_layout'.

Fixes ARM-software/tf-issues#109

Change-Id: I3f54642ce7b763d5ee3b047ad0ab59eabbcf916d
parent 5e0f9bde
...@@ -65,6 +65,38 @@ static void __dead2 bl1_run_bl2(entry_point_info_t *bl2_ep) ...@@ -65,6 +65,38 @@ static void __dead2 bl1_run_bl2(entry_point_info_t *bl2_ep)
bl2_ep->args.arg7); bl2_ep->args.arg7);
} }
/*******************************************************************************
* The next function has a weak definition. Platform specific code can override
* it if it wishes to.
******************************************************************************/
#pragma weak bl1_init_bl2_mem_layout
/*******************************************************************************
* Function that takes a memory layout into which BL2 has been loaded and
* populates a new memory layout for BL2 that ensures that BL1's data sections
* resident in secure RAM are not visible to BL2.
******************************************************************************/
void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
meminfo_t *bl2_mem_layout)
{
const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
assert(bl1_mem_layout != NULL);
assert(bl2_mem_layout != NULL);
/* Check that BL1's memory is lying outside of the free memory */
assert((BL1_RAM_LIMIT <= bl1_mem_layout->free_base) ||
(BL1_RAM_BASE >= bl1_mem_layout->free_base + bl1_mem_layout->free_size));
/* Remove BL1 RW data from the scope of memory visible to BL2 */
*bl2_mem_layout = *bl1_mem_layout;
reserve_mem(&bl2_mem_layout->total_base,
&bl2_mem_layout->total_size,
BL1_RAM_BASE,
bl1_size);
flush_dcache_range((unsigned long)bl2_mem_layout, sizeof(meminfo_t));
}
/******************************************************************************* /*******************************************************************************
* Function to perform late architectural and platform specific initialization. * Function to perform late architectural and platform specific initialization.
...@@ -78,7 +110,6 @@ void bl1_main(void) ...@@ -78,7 +110,6 @@ void bl1_main(void)
#if DEBUG #if DEBUG
unsigned long sctlr_el3 = read_sctlr_el3(); unsigned long sctlr_el3 = read_sctlr_el3();
#endif #endif
unsigned int load_type = TOP_LOAD;
image_info_t bl2_image_info = { {0} }; image_info_t bl2_image_info = { {0} };
entry_point_info_t bl2_ep = { {0} }; entry_point_info_t bl2_ep = { {0} };
meminfo_t *bl1_tzram_layout; meminfo_t *bl1_tzram_layout;
...@@ -105,17 +136,15 @@ void bl1_main(void) ...@@ -105,17 +136,15 @@ void bl1_main(void)
SET_PARAM_HEAD(&bl2_image_info, PARAM_IMAGE_BINARY, VERSION_1, 0); SET_PARAM_HEAD(&bl2_image_info, PARAM_IMAGE_BINARY, VERSION_1, 0);
SET_PARAM_HEAD(&bl2_ep, PARAM_EP, VERSION_1, 0); SET_PARAM_HEAD(&bl2_ep, PARAM_EP, VERSION_1, 0);
/* /* Find out how much free trusted ram remains after BL1 load */
* Find out how much free trusted ram remains after BL1 load
* & load the BL2 image at its top
*/
bl1_tzram_layout = bl1_plat_sec_mem_layout(); bl1_tzram_layout = bl1_plat_sec_mem_layout();
/* Load the BL2 image */
err = load_image(bl1_tzram_layout, err = load_image(bl1_tzram_layout,
(const char *) BL2_IMAGE_NAME, BL2_IMAGE_NAME,
load_type, BL2_BASE,
BL2_BASE, &bl2_image_info,
&bl2_image_info, &bl2_ep);
&bl2_ep);
if (err) { if (err) {
/* /*
* TODO: print failure to load BL2 but also add a tzwdog timer * TODO: print failure to load BL2 but also add a tzwdog timer
...@@ -132,10 +161,7 @@ void bl1_main(void) ...@@ -132,10 +161,7 @@ void bl1_main(void)
* memory for other purposes. * memory for other purposes.
*/ */
bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->free_base; bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->free_base;
init_bl2_mem_layout(bl1_tzram_layout, bl1_init_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
bl2_tzram_layout,
load_type,
bl2_image_info.image_base);
bl1_plat_set_bl2_ep_info(&bl2_image_info, &bl2_ep); bl1_plat_set_bl2_ep_info(&bl2_image_info, &bl2_ep);
bl2_ep.args.arg1 = (unsigned long)bl2_tzram_layout; bl2_ep.args.arg1 = (unsigned long)bl2_tzram_layout;
......
...@@ -31,6 +31,15 @@ ...@@ -31,6 +31,15 @@
#ifndef __BL1_PRIVATE_H__ #ifndef __BL1_PRIVATE_H__
#define __BL1_PRIVATE_H__ #define __BL1_PRIVATE_H__
/*******************************************************************************
* Declarations of linker defined symbols which will tell us where BL1 lives
* in Trusted RAM
******************************************************************************/
extern uint64_t __BL1_RAM_START__;
extern uint64_t __BL1_RAM_END__;
#define BL1_RAM_BASE (uint64_t)(&__BL1_RAM_START__)
#define BL1_RAM_LIMIT (uint64_t)(&__BL1_RAM_END__)
/****************************************** /******************************************
* Function prototypes * Function prototypes
*****************************************/ *****************************************/
......
...@@ -41,15 +41,13 @@ ...@@ -41,15 +41,13 @@
/******************************************************************************* /*******************************************************************************
* The only thing to do in BL2 is to load further images and pass control to * The only thing to do in BL2 is to load further images and pass control to
* BL31. The memory occupied by BL2 will be reclaimed by BL3_x stages. BL2 runs * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs
* entirely in S-EL1. Since arm standard c libraries are not PIC, printf et al * entirely in S-EL1.
* are not available. We rely on assertions to signal error conditions
******************************************************************************/ ******************************************************************************/
void bl2_main(void) void bl2_main(void)
{ {
meminfo_t *bl2_tzram_layout; meminfo_t *bl2_tzram_layout;
bl31_params_t *bl2_to_bl31_params; bl31_params_t *bl2_to_bl31_params;
unsigned int bl2_load, bl31_load;
entry_point_info_t *bl31_ep_info; entry_point_info_t *bl31_ep_info;
meminfo_t bl32_mem_info; meminfo_t bl32_mem_info;
meminfo_t bl33_mem_info; meminfo_t bl33_mem_info;
...@@ -76,18 +74,9 @@ void bl2_main(void) ...@@ -76,18 +74,9 @@ void bl2_main(void)
/* Set the X0 parameter to bl31 */ /* Set the X0 parameter to bl31 */
bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
/* /* Load the BL3-1 image */
* Load BL31. BL1 tells BL2 whether it has been TOP or BOTTOM loaded.
* To avoid fragmentation of trusted SRAM memory, BL31 is always
* loaded opposite to BL2. This allows BL31 to reclaim BL2 memory
* while maintaining its free space in one contiguous chunk.
*/
bl2_load = bl2_tzram_layout->attr & LOAD_MASK;
assert((bl2_load == TOP_LOAD) || (bl2_load == BOT_LOAD));
bl31_load = (bl2_load == TOP_LOAD) ? BOT_LOAD : TOP_LOAD;
e = load_image(bl2_tzram_layout, e = load_image(bl2_tzram_layout,
BL31_IMAGE_NAME, BL31_IMAGE_NAME,
bl31_load,
BL31_BASE, BL31_BASE,
bl2_to_bl31_params->bl31_image_info, bl2_to_bl31_params->bl31_image_info,
bl31_ep_info); bl31_ep_info);
...@@ -106,7 +95,6 @@ void bl2_main(void) ...@@ -106,7 +95,6 @@ void bl2_main(void)
/* Load the BL33 image in non-secure memory provided by the platform */ /* Load the BL33 image in non-secure memory provided by the platform */
e = load_image(&bl33_mem_info, e = load_image(&bl33_mem_info,
BL33_IMAGE_NAME, BL33_IMAGE_NAME,
BOT_LOAD,
plat_get_ns_image_entrypoint(), plat_get_ns_image_entrypoint(),
bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_image_info,
bl2_to_bl31_params->bl33_ep_info); bl2_to_bl31_params->bl33_ep_info);
...@@ -133,7 +121,6 @@ void bl2_main(void) ...@@ -133,7 +121,6 @@ void bl2_main(void)
bl2_plat_get_bl32_meminfo(&bl32_mem_info); bl2_plat_get_bl32_meminfo(&bl32_mem_info);
e = load_image(&bl32_mem_info, e = load_image(&bl32_mem_info,
BL32_IMAGE_NAME, BL32_IMAGE_NAME,
bl32_mem_info.attr & LOAD_MASK,
BL32_BASE, BL32_BASE,
bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_image_info,
bl2_to_bl31_params->bl32_ep_info); bl2_to_bl31_params->bl32_ep_info);
......
...@@ -33,10 +33,9 @@ ...@@ -33,10 +33,9 @@
#include <assert.h> #include <assert.h>
#include <bl_common.h> #include <bl_common.h>
#include <debug.h> #include <debug.h>
#include <errno.h>
#include <io_storage.h> #include <io_storage.h>
#include <platform.h> #include <platform.h>
#include <errno.h>
#include <stdio.h>
unsigned long page_align(unsigned long value, unsigned dir) unsigned long page_align(unsigned long value, unsigned dir)
{ {
...@@ -72,43 +71,76 @@ void change_security_state(unsigned int target_security_state) ...@@ -72,43 +71,76 @@ void change_security_state(unsigned int target_security_state)
write_scr(scr); write_scr(scr);
} }
/******************************************************************************
* Determine whether the memory region delimited by 'addr' and 'size' is free,
* given the extents of free memory.
* Return 1 if it is free, 0 otherwise.
*****************************************************************************/
static int is_mem_free(uint64_t free_base, size_t free_size,
uint64_t addr, size_t size)
{
return (addr >= free_base) && (addr + size <= free_base + free_size);
}
/******************************************************************************* /******************************************************************************
* The next function has a weak definition. Platform specific code can override * Inside a given memory region, determine whether a sub-region of memory is
* it if it wishes to. * closer from the top or the bottom of the encompassing region. Return the
******************************************************************************/ * size of the smallest chunk of free memory surrounding the sub-region in
#pragma weak init_bl2_mem_layout * 'small_chunk_size'.
*****************************************************************************/
/******************************************************************************* static unsigned int choose_mem_pos(uint64_t mem_start, uint64_t mem_end,
* Function that takes a memory layout into which BL2 has been either top or uint64_t submem_start, uint64_t submem_end,
* bottom loaded along with the address where BL2 has been loaded in it. Using size_t *small_chunk_size)
* this information, it populates bl2_mem_layout to tell BL2 how much memory
* it has access to and how much is available for use.
******************************************************************************/
void init_bl2_mem_layout(meminfo_t *bl1_mem_layout,
meminfo_t *bl2_mem_layout,
unsigned int load_type,
unsigned long bl2_base)
{ {
unsigned tmp; size_t top_chunk_size, bottom_chunk_size;
if (load_type == BOT_LOAD) { assert(mem_start <= submem_start);
bl2_mem_layout->total_base = bl2_base; assert(submem_start <= submem_end);
tmp = bl1_mem_layout->free_base - bl2_base; assert(submem_end <= mem_end);
bl2_mem_layout->total_size = bl1_mem_layout->free_size + tmp; assert(small_chunk_size != NULL);
top_chunk_size = mem_end - submem_end;
bottom_chunk_size = submem_start - mem_start;
if (top_chunk_size < bottom_chunk_size) {
*small_chunk_size = top_chunk_size;
return TOP;
} else { } else {
bl2_mem_layout->total_base = bl1_mem_layout->free_base; *small_chunk_size = bottom_chunk_size;
tmp = bl1_mem_layout->total_base + bl1_mem_layout->total_size; return BOTTOM;
bl2_mem_layout->total_size = tmp - bl1_mem_layout->free_base;
} }
}
bl2_mem_layout->free_base = bl1_mem_layout->free_base; /******************************************************************************
bl2_mem_layout->free_size = bl1_mem_layout->free_size; * Reserve the memory region delimited by 'addr' and 'size'. The extents of free
bl2_mem_layout->attr = load_type; * memory are passed in 'free_base' and 'free_size' and they will be updated to
* reflect the memory usage.
* The caller must ensure the memory to reserve is free.
*****************************************************************************/
void reserve_mem(uint64_t *free_base, size_t *free_size,
uint64_t addr, size_t size)
{
size_t discard_size;
size_t reserved_size;
unsigned int pos;
flush_dcache_range((unsigned long) bl2_mem_layout, sizeof(meminfo_t)); assert(free_base != NULL);
return; assert(free_size != NULL);
assert(is_mem_free(*free_base, *free_size, addr, size));
pos = choose_mem_pos(*free_base, *free_base + *free_size,
addr, addr + size,
&discard_size);
reserved_size = size + discard_size;
*free_size -= reserved_size;
if (pos == BOTTOM)
*free_base = addr + size;
INFO("Reserved %u bytes (discarded %u bytes %s)\n",
reserved_size, discard_size,
pos == TOP ? "above" : "below");
} }
static void dump_load_info(unsigned long image_load_addr, static void dump_load_info(unsigned long image_load_addr,
...@@ -170,34 +202,32 @@ unsigned long image_size(const char *image_name) ...@@ -170,34 +202,32 @@ unsigned long image_size(const char *image_name)
return image_size; return image_size;
} }
/******************************************************************************* /*******************************************************************************
* Generic function to load an image into the trusted RAM, * Generic function to load an image at a specific address given a name and
* given a name, extents of free memory & whether the image should be loaded at * extents of free memory. It updates the memory layout if the load is
* the bottom or top of the free memory. It updates the memory layout if the * successful, as well as the image information and the entry point information.
* load is successful. It also updates the image information and the entry point * The caller might pass a NULL pointer for the entry point if it is not
* information in the params passed. The caller might pass a NULL pointer for * interested in this information, e.g. because the image just needs to be
* the entry point if it is not interested in this information, e.g. because * loaded in memory but won't ever be executed.
* the image just needs to be loaded in memory but won't ever be executed. * Returns 0 on success, a negative error code otherwise.
******************************************************************************/ ******************************************************************************/
int load_image(meminfo_t *mem_layout, int load_image(meminfo_t *mem_layout,
const char *image_name, const char *image_name,
unsigned int load_type, uint64_t image_base,
unsigned long fixed_addr, image_info_t *image_data,
image_info_t *image_data, entry_point_info_t *entry_point_info)
entry_point_info_t *entry_point_info)
{ {
uintptr_t dev_handle; uintptr_t dev_handle;
uintptr_t image_handle; uintptr_t image_handle;
uintptr_t image_spec; uintptr_t image_spec;
unsigned long temp_image_base = 0; size_t image_size;
unsigned long image_base = 0; size_t bytes_read;
long offset = 0;
size_t image_size = 0;
size_t bytes_read = 0;
int io_result = IO_FAIL; int io_result = IO_FAIL;
assert(mem_layout != NULL); assert(mem_layout != NULL);
assert(image_name != NULL); assert(image_name != 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 */
...@@ -216,6 +246,8 @@ int load_image(meminfo_t *mem_layout, ...@@ -216,6 +246,8 @@ int load_image(meminfo_t *mem_layout,
return io_result; return io_result;
} }
INFO("Loading file '%s' at address 0x%lx\n", image_name, image_base);
/* Find the size of the image */ /* Find the size of the image */
io_result = io_size(image_handle, &image_size); io_result = io_size(image_handle, &image_size);
if ((io_result != IO_SUCCESS) || (image_size == 0)) { if ((io_result != IO_SUCCESS) || (image_size == 0)) {
...@@ -224,170 +256,14 @@ int load_image(meminfo_t *mem_layout, ...@@ -224,170 +256,14 @@ int load_image(meminfo_t *mem_layout,
goto exit; goto exit;
} }
/* See if we have enough space */ /* Check that the memory where the image will be loaded is free */
if (image_size > mem_layout->free_size) { if (!is_mem_free(mem_layout->free_base, mem_layout->free_size,
WARN("Cannot load '%s' file: Not enough space.\n", image_base, image_size)) {
image_name); WARN("Failed to reserve memory: 0x%lx - 0x%lx\n",
dump_load_info(0, image_size, mem_layout); image_base, image_base + image_size);
goto exit;
}
switch (load_type) {
case TOP_LOAD:
/* Load the image in the top of free memory */
temp_image_base = mem_layout->free_base + mem_layout->free_size;
temp_image_base -= image_size;
/* Page align base address and check whether the image still fits */
image_base = page_align(temp_image_base, DOWN);
assert(image_base <= temp_image_base);
if (image_base < mem_layout->free_base) {
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout);
io_result = -ENOMEM;
goto exit;
}
/* Calculate the amount of extra memory used due to alignment */
offset = temp_image_base - image_base;
break;
case BOT_LOAD:
/* Load the BL2 image in the bottom of free memory */
temp_image_base = mem_layout->free_base;
image_base = page_align(temp_image_base, UP);
assert(image_base >= temp_image_base);
/* Page align base address and check whether the image still fits */
if (image_base + image_size >
mem_layout->free_base + mem_layout->free_size) {
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout); dump_load_info(image_base, image_size, mem_layout);
io_result = -ENOMEM; io_result = -ENOMEM;
goto exit; goto exit;
}
/* Calculate the amount of extra memory used due to alignment */
offset = image_base - temp_image_base;
break;
default:
assert(0);
}
/*
* Some images must be loaded at a fixed address, not a dynamic one.
*
* This has been implemented as a hack on top of the existing dynamic
* loading mechanism, for the time being. If the 'fixed_addr' function
* argument is different from zero, then it will force the load address.
* So we still have this principle of top/bottom loading but the code
* determining the load address is bypassed and the load address is
* forced to the fixed one.
*
* This can result in quite a lot of wasted space because we still use
* 1 sole meminfo structure to represent the extents of free memory,
* where we should use some sort of linked list.
*
* E.g. we want to load BL2 at address 0x04020000, the resulting memory
* layout should look as follows:
* ------------ 0x04040000
* | | <- Free space (1)
* |----------|
* | BL2 |
* |----------| 0x04020000
* | | <- Free space (2)
* |----------|
* | BL1 |
* ------------ 0x04000000
*
* But in the current hacky implementation, we'll need to specify
* whether BL2 is loaded at the top or bottom of the free memory.
* E.g. if BL2 is considered as top-loaded, the meminfo structure
* will give the following view of the memory, hiding the chunk of
* free memory above BL2:
* ------------ 0x04040000
* | |
* | |
* | BL2 |
* |----------| 0x04020000
* | | <- Free space (2)
* |----------|
* | BL1 |
* ------------ 0x04000000
*/
if (fixed_addr != 0) {
/* Load the image at the given address. */
image_base = fixed_addr;
/* Check whether the image fits. */
if ((image_base < mem_layout->free_base) ||
(image_base + image_size >
mem_layout->free_base + mem_layout->free_size)) {
WARN("Cannot load '%s' file: Not enough space.\n",
image_name);
dump_load_info(image_base, image_size, mem_layout);
io_result = -ENOMEM;
goto exit;
}
/* Check whether the fixed load address is page-aligned. */
if (!is_page_aligned(image_base)) {
WARN("Cannot load '%s' file at unaligned address 0x%lx\n",
image_name, fixed_addr);
io_result = -ENOMEM;
goto exit;
}
/*
* Calculate the amount of extra memory used due to fixed
* loading.
*/
if (load_type == TOP_LOAD) {
unsigned long max_addr, space_used;
/*
* ------------ max_addr
* | /wasted/ | | offset
* |..........|..............................
* | image | | image_flen
* |----------| fixed_addr
* | |
* | |
* ------------ total_base
*/
max_addr = mem_layout->total_base + mem_layout->total_size;
/*
* Compute the amount of memory used by the image.
* Corresponds to all space above the image load
* address.
*/
space_used = max_addr - fixed_addr;
/*
* Calculate the amount of wasted memory within the
* amount of memory used by the image.
*/
offset = space_used - image_size;
} else /* BOT_LOAD */
/*
* ------------
* | |
* | |
* |----------|
* | image |
* |..........| fixed_addr
* | /wasted/ | | offset
* ------------ total_base
*/
offset = fixed_addr - mem_layout->total_base;
} }
/* We have enough space so load the image now */ /* We have enough space so load the image now */
...@@ -398,6 +274,14 @@ int load_image(meminfo_t *mem_layout, ...@@ -398,6 +274,14 @@ int load_image(meminfo_t *mem_layout,
goto exit; goto exit;
} }
/*
* Update the memory usage info.
* This is done after the actual loading so that it is not updated when
* the load is unsuccessful.
*/
reserve_mem(&mem_layout->free_base, &mem_layout->free_size,
image_base, image_size);
image_data->image_base = image_base; image_data->image_base = image_base;
image_data->image_size = image_size; image_data->image_size = image_size;
...@@ -405,18 +289,13 @@ int load_image(meminfo_t *mem_layout, ...@@ -405,18 +289,13 @@ int load_image(meminfo_t *mem_layout,
entry_point_info->pc = image_base; entry_point_info->pc = image_base;
/* /*
* File has been successfully loaded. Update the free memory * File has been successfully loaded.
* data structure & flush the contents of the TZRAM so that * Flush the image in TZRAM so that the next EL can see it.
* the next EL can see it.
*/ */
/* Update the memory contents */
flush_dcache_range(image_base, image_size); flush_dcache_range(image_base, image_size);
mem_layout->free_size -= image_size + offset; INFO("File '%s' loaded: 0x%lx - 0x%lx\n", image_name, image_base,
image_base + image_size);
/* Update the base of free memory since its moved up */
if (load_type == BOT_LOAD)
mem_layout->free_base += offset + image_size;
exit: exit:
io_close(image_handle); io_close(image_handle);
......
...@@ -511,7 +511,7 @@ warm boot. For each CPU, BL1 is responsible for the following tasks: ...@@ -511,7 +511,7 @@ warm boot. For each CPU, BL1 is responsible for the following tasks:
the platform to decide where it wants to place the `meminfo` structure for the platform to decide where it wants to place the `meminfo` structure for
BL2. BL2.
BL1 implements the `init_bl2_mem_layout()` function to populate the BL1 implements the `bl1_init_bl2_mem_layout()` function to populate the
BL2 `meminfo` structure. The platform may override this implementation, for BL2 `meminfo` structure. The platform may override this implementation, for
example if the platform wants to restrict the amount of memory visible to example if the platform wants to restrict the amount of memory visible to
BL2. Details of how to do this are given below. BL2. Details of how to do this are given below.
...@@ -574,7 +574,7 @@ its own use. ...@@ -574,7 +574,7 @@ its own use.
This function helps fulfill requirement 3 above. This function helps fulfill requirement 3 above.
### Function : init_bl2_mem_layout() [optional] ### Function : bl1_init_bl2_mem_layout() [optional]
Argument : meminfo *, meminfo *, unsigned int, unsigned long Argument : meminfo *, meminfo *, unsigned int, unsigned long
Return : void Return : void
......
...@@ -38,15 +38,11 @@ ...@@ -38,15 +38,11 @@
#define DOWN 0 #define DOWN 0
/******************************************************************************* /*******************************************************************************
* Constants for loading images. When BLx wants to load BLy, it looks at a * Constants to identify the location of a memory region in a given memory
* meminfo structure to find the extents of free memory. Then depending upon * layout.
* how it has been configured, it can either load BLy at the top or bottom of ******************************************************************************/
* the free memory. These constants indicate the choice. #define TOP 0x1
* TODO: Make this configurable while building the trusted firmware. #define BOTTOM !TOP
******************************************************************************/
#define TOP_LOAD 0x1
#define BOT_LOAD !TOP_LOAD
#define LOAD_MASK (1 << 0)
/****************************************************************************** /******************************************************************************
* Opcode passed in x0 to tell next EL that we want to run an image. * Opcode passed in x0 to tell next EL that we want to run an image.
...@@ -97,18 +93,17 @@ ...@@ -97,18 +93,17 @@
#include <cdefs.h> /* For __dead2 */ #include <cdefs.h> /* For __dead2 */
#include <cassert.h> #include <cassert.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
/******************************************************************************* /*******************************************************************************
* Structure used for telling the next BL how much of a particular type of * Structure used for telling the next BL how much of a particular type of
* memory is available for its use and how much is already used. * memory is available for its use and how much is already used.
******************************************************************************/ ******************************************************************************/
typedef struct meminfo { typedef struct meminfo {
unsigned long total_base; uint64_t total_base;
long total_size; size_t total_size;
unsigned long free_base; uint64_t free_base;
long free_size; size_t free_size;
unsigned long attr;
unsigned long next;
} meminfo_t; } meminfo_t;
typedef struct aapcs64_params { typedef struct aapcs64_params {
...@@ -209,14 +204,16 @@ CASSERT(sizeof(unsigned long) == ...@@ -209,14 +204,16 @@ CASSERT(sizeof(unsigned long) ==
unsigned long page_align(unsigned long, unsigned); unsigned long page_align(unsigned long, unsigned);
void change_security_state(unsigned int); void change_security_state(unsigned int);
unsigned long image_size(const char *); unsigned long image_size(const char *);
int load_image(meminfo_t *, int load_image(meminfo_t *mem_layout,
const char *, const char *image_name,
unsigned int, uint64_t image_base,
unsigned long, image_info_t *image_data,
image_info_t *, entry_point_info_t *entry_point_info);
entry_point_info_t *);
extern const char build_message[]; extern const char build_message[];
void reserve_mem(uint64_t *free_base, size_t *free_size,
uint64_t addr, size_t size);
#endif /*__ASSEMBLY__*/ #endif /*__ASSEMBLY__*/
#endif /* __BL_COMMON_H__ */ #endif /* __BL_COMMON_H__ */
...@@ -90,10 +90,8 @@ void bl1_plat_set_bl2_ep_info(struct image_info *image, ...@@ -90,10 +90,8 @@ void bl1_plat_set_bl2_ep_info(struct image_info *image,
/******************************************************************************* /*******************************************************************************
* Optional BL1 functions (may be overridden) * Optional BL1 functions (may be overridden)
******************************************************************************/ ******************************************************************************/
void init_bl2_mem_layout(struct meminfo *, void bl1_init_bl2_mem_layout(const struct meminfo *bl1_mem_layout,
struct meminfo *, struct meminfo *bl2_mem_layout);
unsigned int,
unsigned long);
/******************************************************************************* /*******************************************************************************
* Mandatory BL2 functions * Mandatory BL2 functions
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <mmio.h> #include <mmio.h>
#include <platform.h> #include <platform.h>
#include <platform_def.h> #include <platform_def.h>
#include "../../bl1/bl1_private.h"
#include "fvp_def.h" #include "fvp_def.h"
#include "fvp_private.h" #include "fvp_private.h"
...@@ -45,9 +46,6 @@ ...@@ -45,9 +46,6 @@
extern unsigned long __COHERENT_RAM_START__; extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__; extern unsigned long __COHERENT_RAM_END__;
extern unsigned long __BL1_RAM_START__;
extern unsigned long __BL1_RAM_END__;
/* /*
* The next 2 constants identify the extents of the coherent memory region. * The next 2 constants identify the extents of the coherent memory region.
* These addresses are used by the MMU setup code and therefore they must be * These addresses are used by the MMU setup code and therefore they must be
...@@ -58,10 +56,6 @@ extern unsigned long __BL1_RAM_END__; ...@@ -58,10 +56,6 @@ extern unsigned long __BL1_RAM_END__;
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) #define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) #define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#define BL1_RAM_BASE (unsigned long)(&__BL1_RAM_START__)
#define BL1_RAM_LIMIT (unsigned long)(&__BL1_RAM_END__)
/* Data structure which holds the extents of the trusted SRAM for BL1*/ /* Data structure which holds the extents of the trusted SRAM for BL1*/
static meminfo_t bl1_tzram_layout; static meminfo_t bl1_tzram_layout;
......
...@@ -171,12 +171,7 @@ void bl2_early_platform_setup(meminfo_t *mem_layout) ...@@ -171,12 +171,7 @@ void bl2_early_platform_setup(meminfo_t *mem_layout)
console_init(PL011_UART0_BASE); console_init(PL011_UART0_BASE);
/* Setup the BL2 memory layout */ /* Setup the BL2 memory layout */
bl2_tzram_layout.total_base = mem_layout->total_base; bl2_tzram_layout = *mem_layout;
bl2_tzram_layout.total_size = mem_layout->total_size;
bl2_tzram_layout.free_base = mem_layout->free_base;
bl2_tzram_layout.free_size = mem_layout->free_size;
bl2_tzram_layout.attr = mem_layout->attr;
bl2_tzram_layout.next = 0;
/* Initialize the platform config for future decision making */ /* Initialize the platform config for future decision making */
fvp_config_setup(); fvp_config_setup();
...@@ -276,8 +271,6 @@ void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) ...@@ -276,8 +271,6 @@ void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
bl32_meminfo->free_size = bl32_meminfo->free_size =
(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
bl32_meminfo->attr = BOT_LOAD;
bl32_meminfo->next = 0;
} }
...@@ -290,6 +283,4 @@ void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) ...@@ -290,6 +283,4 @@ void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
bl33_meminfo->total_size = DRAM_SIZE - DRAM1_SEC_SIZE; bl33_meminfo->total_size = DRAM_SIZE - DRAM1_SEC_SIZE;
bl33_meminfo->free_base = DRAM_BASE; bl33_meminfo->free_base = DRAM_BASE;
bl33_meminfo->free_size = DRAM_SIZE - DRAM1_SEC_SIZE; bl33_meminfo->free_size = DRAM_SIZE - DRAM1_SEC_SIZE;
bl33_meminfo->attr = 0;
bl33_meminfo->attr = 0;
} }
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