Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
6a223156
Commit
6a223156
authored
Jul 10, 2014
by
danh-arm
Browse files
Merge pull request #157 from sandrine-bailleux/sb/tf-issue-109
TF issue 109
parents
3fc938b5
60633799
Changes
9
Hide whitespace changes
Inline
Side-by-side
bl1/bl1_main.c
View file @
6a223156
...
@@ -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
;
...
...
bl1/bl1_private.h
View file @
6a223156
...
@@ -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
*****************************************/
*****************************************/
...
...
bl2/bl2_main.c
View file @
6a223156
...
@@ -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
);
...
...
common/bl_common.c
View file @
6a223156
...
@@ -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 b
e load
ed at
* extents of free memory
. It updates the memory layout if th
e 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
* in
formation in the params passed. The caller might pass a NULL pointer for
* in
terested 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
);
...
...
docs/porting-guide.md
View file @
6a223156
...
@@ -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
...
...
include/common/bl_common.h
View file @
6a223156
...
@@ -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__ */
include/plat/common/platform.h
View file @
6a223156
...
@@ -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
...
...
plat/fvp/bl1_fvp_setup.c
View file @
6a223156
...
@@ -31,10 +31,12 @@
...
@@ -31,10 +31,12 @@
#include <arch_helpers.h>
#include <arch_helpers.h>
#include <assert.h>
#include <assert.h>
#include <bl_common.h>
#include <bl_common.h>
#include <debug.h>
#include <console.h>
#include <console.h>
#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 +47,6 @@
...
@@ -45,9 +47,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 +57,6 @@ extern unsigned long __BL1_RAM_END__;
...
@@ -58,10 +57,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
;
...
@@ -75,34 +70,25 @@ meminfo_t *bl1_plat_sec_mem_layout(void)
...
@@ -75,34 +70,25 @@ meminfo_t *bl1_plat_sec_mem_layout(void)
******************************************************************************/
******************************************************************************/
void
bl1_early_platform_setup
(
void
)
void
bl1_early_platform_setup
(
void
)
{
{
const
unsigned
long
bl1_ram_base
=
BL1_RAM_BASE
;
const
size_t
bl1_size
=
BL1_RAM_LIMIT
-
BL1_RAM_BASE
;
const
unsigned
long
bl1_ram_limit
=
BL1_RAM_LIMIT
;
const
unsigned
long
tzram_limit
=
TZRAM_BASE
+
TZRAM_SIZE
;
/* Initialize the console to provide early debug support */
/* Initialize the console to provide early debug support */
console_init
(
PL011_UART0_BASE
);
console_init
(
PL011_UART0_BASE
);
/*
/* Allow BL1 to see the whole Trusted RAM */
* Calculate how much ram is BL1 using & how much remains free.
* This also includes a rudimentary mechanism to detect whether
* the BL1 data is loaded at the top or bottom of memory.
* TODO: add support for discontigous chunks of free ram if
* needed. Might need dynamic memory allocation support
* et al.
*/
bl1_tzram_layout
.
total_base
=
TZRAM_BASE
;
bl1_tzram_layout
.
total_base
=
TZRAM_BASE
;
bl1_tzram_layout
.
total_size
=
TZRAM_SIZE
;
bl1_tzram_layout
.
total_size
=
TZRAM_SIZE
;
if
(
bl1_ram_limit
==
tzram_limit
)
{
/* Calculate how much RAM BL1 is using and how much remains free */
/* BL1 has been loaded at the top of memory. */
bl1_tzram_layout
.
free_base
=
TZRAM_BASE
;
bl1_tzram_layout
.
free_
bas
e
=
TZRAM_
BAS
E
;
bl1_tzram_layout
.
free_
siz
e
=
TZRAM_
SIZ
E
;
bl1_tzram_layout
.
free_
size
=
bl1_ram_base
-
TZRAM_BASE
;
reserve_mem
(
&
bl1_tzram_layout
.
free_
base
,
}
else
{
&
bl1_tzram_layout
.
free_size
,
/* BL1 has been loaded at the bottom of memory. */
BL1_RAM_BASE
,
bl1_tzram_layout
.
free_base
=
bl1_ram_limit
;
bl1_size
)
;
bl1_tzram_layout
.
free_size
=
tzram_limit
-
bl1_ram_limit
;
INFO
(
"BL1: 0x%lx - 0x%lx [size = %u]
\n
"
,
BL1_RAM_BASE
,
BL1_RAM_LIMIT
,
}
bl1_size
);
/* Initialize the platform config for future decision making */
/* Initialize the platform config for future decision making */
fvp_config_setup
();
fvp_config_setup
();
...
...
plat/fvp/bl2_fvp_setup.c
View file @
6a223156
...
@@ -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
();
...
@@ -278,8 +273,6 @@ void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
...
@@ -278,8 +273,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
;
}
}
...
@@ -292,6 +285,4 @@ void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
...
@@ -292,6 +285,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
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment