mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 02:54:24 +00:00
Rework BL2 to BL3-1 hand over interface
This patch reworks BL2 to BL3-1 hand over interface by introducing a composite structure (bl31_args) that holds the superset of information that needs to be passed from BL2 to BL3-1. - The extents of secure memory available to BL3-1 - The extents of memory available to BL3-2 (not yet implemented) and BL3-3 - Information to execute BL3-2 (not yet implemented) and BL3-3 images This patch also introduces a new platform API (bl2_get_bl31_args_ptr) that needs to be implemented by the platform code to export reference to bl31_args structure which has been allocated in platform-defined memory. The platform will initialize the extents of memory available to BL3-3 during early platform setup in bl31_args structure. This obviates the need for bl2_get_ns_mem_layout platform API. BL2 calls the bl2_get_bl31_args_ptr function to get a reference to bl31_args structure. It uses the 'bl33_meminfo' field of this structure to load the BL3-3 image. It sets the entry point information for the BL3-3 image in the 'bl33_image_info' field of this structure. The reference to this structure is passed to the BL3-1 image. Also fixes issue ARM-software/tf-issues#25 Change-Id: Ic36426196dd5ebf89e60ff42643bed01b3500517
This commit is contained in:
parent
a7934d6950
commit
e4d084ea96
13 changed files with 187 additions and 200 deletions
|
@ -116,5 +116,5 @@ SECTIONS
|
||||||
__COHERENT_RAM_UNALIGNED_SIZE__ =
|
__COHERENT_RAM_UNALIGNED_SIZE__ =
|
||||||
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
|
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
|
||||||
|
|
||||||
ASSERT(. <= BL31_BASE, "BL31 image overlaps BL1 image.")
|
ASSERT(. <= BL31_BASE, "BL1 image overlaps BL31 image.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,11 @@ void bl1_main(void)
|
||||||
printf("BL2 memory layout address = 0x%llx \n\r",
|
printf("BL2 memory layout address = 0x%llx \n\r",
|
||||||
(unsigned long long) bl2_tzram_layout);
|
(unsigned long long) bl2_tzram_layout);
|
||||||
#endif
|
#endif
|
||||||
run_image(bl2_base, spsr, SECURE, bl2_tzram_layout, 0);
|
run_image(bl2_base,
|
||||||
|
spsr,
|
||||||
|
SECURE,
|
||||||
|
(void *) bl2_tzram_layout,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -48,9 +48,7 @@
|
||||||
void bl2_main(void)
|
void bl2_main(void)
|
||||||
{
|
{
|
||||||
meminfo *bl2_tzram_layout;
|
meminfo *bl2_tzram_layout;
|
||||||
meminfo *bl31_tzram_layout;
|
bl31_args *bl2_to_bl31_args;
|
||||||
meminfo *bl33_ns_layout;
|
|
||||||
el_change_info *ns_image_info;
|
|
||||||
unsigned long bl31_base, bl33_base, el_status;
|
unsigned long bl31_base, bl33_base, el_status;
|
||||||
unsigned int bl2_load, bl31_load, mode;
|
unsigned int bl2_load, bl31_load, mode;
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ void bl2_main(void)
|
||||||
/* Perform platform setup in BL1 */
|
/* Perform platform setup in BL1 */
|
||||||
bl2_platform_setup();
|
bl2_platform_setup();
|
||||||
|
|
||||||
#if defined (__GNUC__)
|
#if defined(__GNUC__)
|
||||||
printf("BL2 Built : %s, %s\n\r", __TIME__, __DATE__);
|
printf("BL2 Built : %s, %s\n\r", __TIME__, __DATE__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -80,19 +78,30 @@ void bl2_main(void)
|
||||||
bl31_load, BL31_BASE);
|
bl31_load, BL31_BASE);
|
||||||
|
|
||||||
/* Assert if it has not been possible to load BL31 */
|
/* Assert if it has not been possible to load BL31 */
|
||||||
assert(bl31_base != 0);
|
if (bl31_base == 0) {
|
||||||
|
ERROR("Failed to load BL3-1.\n");
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a pointer to the memory the platform has set aside to pass
|
||||||
|
* information to BL31.
|
||||||
|
*/
|
||||||
|
bl2_to_bl31_args = bl2_get_bl31_args_ptr();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new layout of memory for BL31 as seen by BL2. This
|
* Create a new layout of memory for BL31 as seen by BL2. This
|
||||||
* will gobble up all the BL2 memory.
|
* will gobble up all the BL2 memory.
|
||||||
*/
|
*/
|
||||||
bl31_tzram_layout = (meminfo *) get_el_change_mem_ptr();
|
init_bl31_mem_layout(bl2_tzram_layout,
|
||||||
init_bl31_mem_layout(bl2_tzram_layout, bl31_tzram_layout, bl31_load);
|
&bl2_to_bl31_args->bl31_meminfo,
|
||||||
|
bl31_load);
|
||||||
|
|
||||||
/* Find out where the BL3-3 normal world firmware should go. */
|
/* Load the BL33 image in non-secure memory provided by the platform */
|
||||||
bl33_ns_layout = bl2_get_ns_mem_layout();
|
bl33_base = load_image(&bl2_to_bl31_args->bl33_meminfo,
|
||||||
bl33_base = load_image(bl33_ns_layout, BL33_IMAGE_NAME,
|
BL33_IMAGE_NAME,
|
||||||
BOT_LOAD, plat_get_ns_image_entrypoint());
|
BOT_LOAD,
|
||||||
|
plat_get_ns_image_entrypoint());
|
||||||
/* Halt if failed to load normal world firmware. */
|
/* Halt if failed to load normal world firmware. */
|
||||||
if (bl33_base == 0) {
|
if (bl33_base == 0) {
|
||||||
ERROR("Failed to load BL3-3.\n");
|
ERROR("Failed to load BL3-3.\n");
|
||||||
|
@ -101,11 +110,9 @@ void bl2_main(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BL2 also needs to tell BL31 where the non-trusted software image
|
* BL2 also needs to tell BL31 where the non-trusted software image
|
||||||
* has been loaded. Place this info right after the BL31 memory layout
|
* is located.
|
||||||
*/
|
*/
|
||||||
ns_image_info = (el_change_info *) ((unsigned char *) bl31_tzram_layout
|
bl2_to_bl31_args->bl33_image_info.entrypoint = bl33_base;
|
||||||
+ sizeof(meminfo));
|
|
||||||
ns_image_info->entrypoint = bl33_base;
|
|
||||||
|
|
||||||
/* Figure out what mode we enter the non-secure world in */
|
/* Figure out what mode we enter the non-secure world in */
|
||||||
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
|
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
|
||||||
|
@ -116,22 +123,27 @@ void bl2_main(void)
|
||||||
else
|
else
|
||||||
mode = MODE_EL1;
|
mode = MODE_EL1;
|
||||||
|
|
||||||
ns_image_info->spsr = make_spsr(mode, MODE_SP_ELX, MODE_RW_64);
|
/*
|
||||||
ns_image_info->security_state = NON_SECURE;
|
* TODO: Consider the possibility of specifying the SPSR in
|
||||||
flush_dcache_range((unsigned long) ns_image_info,
|
* the FIP ToC and allowing the platform to have a say as
|
||||||
sizeof(el_change_info));
|
* well.
|
||||||
|
*/
|
||||||
|
bl2_to_bl31_args->bl33_image_info.spsr =
|
||||||
|
make_spsr(mode, MODE_SP_ELX, MODE_RW_64);
|
||||||
|
bl2_to_bl31_args->bl33_image_info.security_state = NON_SECURE;
|
||||||
|
|
||||||
|
/* Flush the entire BL31 args buffer */
|
||||||
|
flush_dcache_range((unsigned long) bl2_to_bl31_args,
|
||||||
|
sizeof(*bl2_to_bl31_args));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run BL31 via an SMC to BL1. Information on how to pass control to
|
* Run BL31 via an SMC to BL1. Information on how to pass control to
|
||||||
* the non-trusted software image will be passed to BL31 in x2.
|
* the BL32 (if present) and BL33 software images will be passed to
|
||||||
|
* BL31 as an argument.
|
||||||
*/
|
*/
|
||||||
if (bl31_base)
|
|
||||||
run_image(bl31_base,
|
run_image(bl31_base,
|
||||||
make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64),
|
make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64),
|
||||||
SECURE,
|
SECURE,
|
||||||
bl31_tzram_layout,
|
(void *) bl2_to_bl31_args,
|
||||||
(void *) ns_image_info);
|
NULL);
|
||||||
|
|
||||||
/* There is no valid reason for run_image() to return */
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,10 @@
|
||||||
|
|
||||||
bl31_entrypoint: ; .type bl31_entrypoint, %function
|
bl31_entrypoint: ; .type bl31_entrypoint, %function
|
||||||
/* ---------------------------------------------
|
/* ---------------------------------------------
|
||||||
* BL2 has populated x0,x3,x4 with the opcode
|
* BL2 has populated x0 with the opcode
|
||||||
* indicating BL31 should be run, memory layout
|
* indicating BL31 should be run, x3 with
|
||||||
* of the trusted SRAM available to BL31 and
|
* a pointer to a 'bl31_args' structure & x4
|
||||||
* information about running the non-trusted
|
* with any other optional information
|
||||||
* software already loaded by BL2.
|
|
||||||
* ---------------------------------------------
|
* ---------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -40,17 +40,6 @@
|
||||||
#include "io_storage.h"
|
#include "io_storage.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
* Memory for sharing data while changing exception levels.
|
|
||||||
* Only used by the primary core.
|
|
||||||
**********************************************************/
|
|
||||||
unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE];
|
|
||||||
|
|
||||||
unsigned long *get_el_change_mem_ptr(void)
|
|
||||||
{
|
|
||||||
return (unsigned long *) bl2_el_change_mem_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long page_align(unsigned long value, unsigned dir)
|
unsigned long page_align(unsigned long value, unsigned dir)
|
||||||
{
|
{
|
||||||
unsigned long page_size = 1 << FOUR_KB_SHIFT;
|
unsigned long page_size = 1 << FOUR_KB_SHIFT;
|
||||||
|
@ -85,7 +74,7 @@ void change_security_state(unsigned int target_security_state)
|
||||||
write_scr(scr);
|
write_scr(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int drop_el(aapcs64_params *args,
|
void __dead2 drop_el(aapcs64_params *args,
|
||||||
unsigned long spsr,
|
unsigned long spsr,
|
||||||
unsigned long entrypoint)
|
unsigned long entrypoint)
|
||||||
{
|
{
|
||||||
|
@ -99,12 +88,11 @@ int drop_el(aapcs64_params *args,
|
||||||
args->arg5,
|
args->arg5,
|
||||||
args->arg6,
|
args->arg6,
|
||||||
args->arg7);
|
args->arg7);
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long raise_el(aapcs64_params *args)
|
void __dead2 raise_el(aapcs64_params *args)
|
||||||
{
|
{
|
||||||
return smc(args->arg0,
|
smc(args->arg0,
|
||||||
args->arg1,
|
args->arg1,
|
||||||
args->arg2,
|
args->arg2,
|
||||||
args->arg3,
|
args->arg3,
|
||||||
|
@ -119,7 +107,7 @@ long raise_el(aapcs64_params *args)
|
||||||
* Add support for dropping into EL0 etc. Consider adding support
|
* Add support for dropping into EL0 etc. Consider adding support
|
||||||
* for switching from S-EL1 to S-EL0/1 etc.
|
* for switching from S-EL1 to S-EL0/1 etc.
|
||||||
*/
|
*/
|
||||||
long change_el(el_change_info *info)
|
void __dead2 change_el(el_change_info *info)
|
||||||
{
|
{
|
||||||
unsigned long current_el = read_current_el();
|
unsigned long current_el = read_current_el();
|
||||||
|
|
||||||
|
@ -134,9 +122,9 @@ long change_el(el_change_info *info)
|
||||||
if (info->security_state == NON_SECURE)
|
if (info->security_state == NON_SECURE)
|
||||||
change_security_state(info->security_state);
|
change_security_state(info->security_state);
|
||||||
|
|
||||||
return drop_el(&info->args, info->spsr, info->entrypoint);
|
drop_el(&info->args, info->spsr, info->entrypoint);
|
||||||
} else
|
} else
|
||||||
return raise_el(&info->args);
|
raise_el(&info->args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: add a parameter for DAIF. not needed right now */
|
/* TODO: add a parameter for DAIF. not needed right now */
|
||||||
|
@ -515,11 +503,11 @@ fail: image_base = 0;
|
||||||
* The only way of doing the latter is through an SMC. In either case, setup the
|
* The only way of doing the latter is through an SMC. In either case, setup the
|
||||||
* parameters for the EL change request correctly.
|
* parameters for the EL change request correctly.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int run_image(unsigned long entrypoint,
|
void __dead2 run_image(unsigned long entrypoint,
|
||||||
unsigned long spsr,
|
unsigned long spsr,
|
||||||
unsigned long target_security_state,
|
unsigned long target_security_state,
|
||||||
meminfo *mem_layout,
|
void *first_arg,
|
||||||
void *data)
|
void *second_arg)
|
||||||
{
|
{
|
||||||
el_change_info run_image_info;
|
el_change_info run_image_info;
|
||||||
unsigned long current_el = read_current_el();
|
unsigned long current_el = read_current_el();
|
||||||
|
@ -529,7 +517,6 @@ int run_image(unsigned long entrypoint,
|
||||||
run_image_info.entrypoint = entrypoint;
|
run_image_info.entrypoint = entrypoint;
|
||||||
run_image_info.spsr = spsr;
|
run_image_info.spsr = spsr;
|
||||||
run_image_info.security_state = target_security_state;
|
run_image_info.security_state = target_security_state;
|
||||||
run_image_info.next = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are EL3 then only an eret can take us to the desired
|
* If we are EL3 then only an eret can take us to the desired
|
||||||
|
@ -538,14 +525,14 @@ int run_image(unsigned long entrypoint,
|
||||||
* will go into the general purpose register xY e.g. arg0->x0
|
* will go into the general purpose register xY e.g. arg0->x0
|
||||||
*/
|
*/
|
||||||
if (GET_EL(current_el) == MODE_EL3) {
|
if (GET_EL(current_el) == MODE_EL3) {
|
||||||
run_image_info.args.arg1 = (unsigned long) mem_layout;
|
run_image_info.args.arg1 = (unsigned long) first_arg;
|
||||||
run_image_info.args.arg2 = (unsigned long) data;
|
run_image_info.args.arg2 = (unsigned long) second_arg;
|
||||||
} else {
|
} else {
|
||||||
run_image_info.args.arg1 = entrypoint;
|
run_image_info.args.arg1 = entrypoint;
|
||||||
run_image_info.args.arg2 = spsr;
|
run_image_info.args.arg2 = spsr;
|
||||||
run_image_info.args.arg3 = (unsigned long) mem_layout;
|
run_image_info.args.arg3 = (unsigned long) first_arg;
|
||||||
run_image_info.args.arg4 = (unsigned long) data;
|
run_image_info.args.arg4 = (unsigned long) second_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return change_el(&run_image_info);
|
change_el(&run_image_info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -529,8 +529,8 @@ using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
|
||||||
meminfo.free_size = Size of secure RAM available for allocation to
|
meminfo.free_size = Size of secure RAM available for allocation to
|
||||||
BL3-1
|
BL3-1
|
||||||
|
|
||||||
BL2 places this `meminfo` structure in memory provided by the
|
BL2 populates this information in the `bl31_meminfo` field of the pointer
|
||||||
platform (`bl2_el_change_mem_ptr`). BL2 implements the
|
returned by the `bl2_get_bl31_args_ptr() function. BL2 implements the
|
||||||
`init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
|
`init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
|
||||||
described above. The platform may override this implementation, for example
|
described above. The platform may override this implementation, for example
|
||||||
if the platform wants to restrict the amount of memory visible to BL3-1.
|
if the platform wants to restrict the amount of memory visible to BL3-1.
|
||||||
|
@ -554,9 +554,7 @@ by the primary CPU. The arguments to this function are:
|
||||||
The platform must copy the contents of the `meminfo` structure into a private
|
The platform must copy the contents of the `meminfo` structure into a private
|
||||||
variable as the original memory may be subsequently overwritten by BL2. The
|
variable as the original memory may be subsequently overwritten by BL2. The
|
||||||
copied structure is made available to all BL2 code through the
|
copied structure is made available to all BL2 code through the
|
||||||
`bl2_plat_sec_mem_layout()` function. The non-secure memory extents used for
|
`bl2_plat_sec_mem_layout()` function.
|
||||||
loading BL3-3 is also initialized in this function. Access to this information
|
|
||||||
is provided by the `bl2_get_ns_mem_layout()` function.
|
|
||||||
|
|
||||||
|
|
||||||
### Function : bl2_plat_arch_setup() [mandatory]
|
### Function : bl2_plat_arch_setup() [mandatory]
|
||||||
|
@ -581,27 +579,20 @@ This function may execute with the MMU and data caches enabled if the platform
|
||||||
port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
|
port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
|
||||||
called by the primary CPU.
|
called by the primary CPU.
|
||||||
|
|
||||||
The purpose of this function is to perform any platform initialization specific
|
The purpose of this function is to perform any platform initialization
|
||||||
to BL2. This function must initialize a pointer to memory
|
specific to BL2. For example on the ARM FVP port this function initialises a
|
||||||
(`bl2_el_change_mem_ptr`), which can then be used to populate an
|
internal pointer (`bl2_to_bl31_args`) to a `bl31_args` which will be used by
|
||||||
`el_change_info` structure. The underlying requirement is that the platform must
|
BL2 to pass information to BL3_1. The pointer is initialized to the base
|
||||||
initialize this pointer before the `get_el_change_mem_ptr()` function
|
address of Secure DRAM (`0x06000000`).
|
||||||
accesses it in `bl2_main()`.
|
|
||||||
|
|
||||||
The ARM FVP port initializes this pointer to the base address of Secure DRAM
|
The non-secure memory extents used for loading BL3-3 are also initialized in
|
||||||
(`0x06000000`).
|
this function. This information is accessible in the `bl33_meminfo` field in
|
||||||
|
the `bl31_args` structure pointed to by `bl2_to_bl31_args`.
|
||||||
|
|
||||||
This function is also responsible for initializing the storage abstraction layer
|
This function is also responsible for initializing the storage abstraction layer
|
||||||
which is used to load further bootloader images.
|
which is used to load further bootloader images.
|
||||||
|
|
||||||
|
|
||||||
### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory]
|
|
||||||
|
|
||||||
As mentioned in the description of `bl2_platform_setup()`, this pointer is
|
|
||||||
initialized by the platform to point to memory where an `el_change_info`
|
|
||||||
structure can be populated.
|
|
||||||
|
|
||||||
|
|
||||||
### Function : bl2_plat_sec_mem_layout() [mandatory]
|
### Function : bl2_plat_sec_mem_layout() [mandatory]
|
||||||
|
|
||||||
Argument : void
|
Argument : void
|
||||||
|
@ -616,18 +607,20 @@ populated with the extents of secure RAM available for BL2 to use. See
|
||||||
`bl2_early_platform_setup()` above.
|
`bl2_early_platform_setup()` above.
|
||||||
|
|
||||||
|
|
||||||
### Function : bl2_get_ns_mem_layout() [mandatory]
|
### Function : bl2_get_bl31_args_ptr() [mandatory]
|
||||||
|
|
||||||
Argument : void
|
Argument : void
|
||||||
Return : meminfo *
|
Return : bl31_args *
|
||||||
|
|
||||||
This function should only be called on the cold boot path. It may execute with
|
BL2 platform code needs to return a pointer to a `bl31_args` structure it will
|
||||||
the MMU and data caches enabled if the platform port does the necessary
|
use for passing information to BL3-1. The `bl31_args` structure carries the
|
||||||
initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU.
|
following information. This information is used by the `bl2_main()` function to
|
||||||
|
load the BL3-2 (if present) and BL3-3 images.
|
||||||
The purpose of this function is to return a pointer to a `meminfo` structure
|
- Extents of memory available to the BL3-1 image in the `bl31_meminfo` field
|
||||||
populated with the extents of non-secure DRAM available for BL2 to use. See
|
- Extents of memory available to the BL3-2 image in the `bl32_meminfo` field
|
||||||
`bl2_early_platform_setup()` above.
|
- Extents of memory available to the BL3-3 image in the `bl33_meminfo` field
|
||||||
|
- Information about executing the BL3-3 image in the `bl33_image_info` field
|
||||||
|
- Information about executing the BL3-2 image in the `bl32_image_info` field
|
||||||
|
|
||||||
|
|
||||||
### Function : init_bl31_mem_layout() [optional]
|
### Function : init_bl31_mem_layout() [optional]
|
||||||
|
@ -699,11 +692,16 @@ by the primary CPU. The arguments to this function are:
|
||||||
* An opaque pointer that the platform may use as needed.
|
* An opaque pointer that the platform may use as needed.
|
||||||
* The `MPIDR` of the primary CPU.
|
* The `MPIDR` of the primary CPU.
|
||||||
|
|
||||||
The platform must copy the contents of the `meminfo` structure into a private
|
The platform can copy the contents of the `meminfo` structure into a private
|
||||||
variable as the original memory may be subsequently overwritten by BL3-1. The
|
variable if the original memory may be subsequently overwritten by BL3-1. The
|
||||||
copied structure is made available to all BL3-1 code through the
|
reference to this structure is made available to all BL3-1 code through the
|
||||||
`bl31_plat_sec_mem_layout()` function.
|
`bl31_plat_sec_mem_layout()` function.
|
||||||
|
|
||||||
|
On the ARM FVP port, BL2 passes a pointer to a `bl31_args` structure populated
|
||||||
|
in the secure DRAM at address `0x6000000` in the opaque pointer mentioned
|
||||||
|
earlier. BL3-1 does not copy this information to internal data structures as it
|
||||||
|
guarantees that the secure DRAM memory will not be overwritten. It maintains an
|
||||||
|
internal reference to this information in the `bl2_to_bl31_args` variable.
|
||||||
|
|
||||||
### Function : bl31_plat_arch_setup() [mandatory]
|
### Function : bl31_plat_arch_setup() [mandatory]
|
||||||
|
|
||||||
|
|
|
@ -796,7 +796,7 @@ bits.
|
||||||
BL2 does not perform any platform initialization that affects subsequent
|
BL2 does not perform any platform initialization that affects subsequent
|
||||||
stages of the ARM Trusted Firmware or normal world software. It copies the
|
stages of the ARM Trusted Firmware or normal world software. It copies the
|
||||||
information regarding the trusted SRAM populated by BL1 using a
|
information regarding the trusted SRAM populated by BL1 using a
|
||||||
platform-specific mechanism. It also calculates the limits of DRAM (main memory)
|
platform-specific mechanism. It calculates the limits of DRAM (main memory)
|
||||||
to determine whether there is enough space to load the normal world software
|
to determine whether there is enough space to load the normal world software
|
||||||
images. A platform defined base address is used to specify the load address for
|
images. A platform defined base address is used to specify the load address for
|
||||||
the BL3-1 image.
|
the BL3-1 image.
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <arch.h>
|
#include <arch.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* TLB maintenance accessor prototypes
|
* TLB maintenance accessor prototypes
|
||||||
|
@ -108,12 +109,12 @@ extern void isb(void);
|
||||||
extern unsigned int get_afflvl_shift(unsigned int);
|
extern unsigned int get_afflvl_shift(unsigned int);
|
||||||
extern unsigned int mpidr_mask_lower_afflvls(unsigned long, unsigned int);
|
extern unsigned int mpidr_mask_lower_afflvls(unsigned long, unsigned int);
|
||||||
|
|
||||||
extern void eret(unsigned long, unsigned long,
|
extern void __dead2 eret(unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long,
|
unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long,
|
unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long);
|
unsigned long, unsigned long);
|
||||||
|
|
||||||
extern unsigned long smc(unsigned long, unsigned long,
|
extern void __dead2 smc(unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long,
|
unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long,
|
unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long);
|
unsigned long, unsigned long);
|
||||||
|
|
|
@ -43,6 +43,6 @@ extern unsigned long long bl2_entrypoint;
|
||||||
*****************************************/
|
*****************************************/
|
||||||
extern void bl2_platform_setup(void);
|
extern void bl2_platform_setup(void);
|
||||||
extern meminfo *bl2_plat_sec_mem_layout(void);
|
extern meminfo *bl2_plat_sec_mem_layout(void);
|
||||||
extern meminfo *bl2_get_ns_mem_layout(void);
|
extern bl31_args *bl2_get_bl31_args_ptr(void);
|
||||||
|
|
||||||
#endif /* __BL2_H__ */
|
#endif /* __BL2_H__ */
|
||||||
|
|
|
@ -48,21 +48,6 @@
|
||||||
#define BOT_LOAD !TOP_LOAD
|
#define BOT_LOAD !TOP_LOAD
|
||||||
#define LOAD_MASK (1 << 0)
|
#define LOAD_MASK (1 << 0)
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Size of memory for sharing data while changing exception levels.
|
|
||||||
*
|
|
||||||
* There are 2 cases where this memory buffer is used:
|
|
||||||
*
|
|
||||||
* - when BL1 (running in EL3) passes control to BL2 (running in S-EL1).
|
|
||||||
* BL1 needs to pass the memory layout to BL2, to allow BL2 to find out
|
|
||||||
* how much free trusted ram remains;
|
|
||||||
*
|
|
||||||
* - when BL2 (running in S-EL1) passes control back to BL1 (running in EL3)
|
|
||||||
* to make it run BL31. BL2 needs to pass the memory layout, as well as
|
|
||||||
* information on how to pass control to the non-trusted software image.
|
|
||||||
******************************************************************************/
|
|
||||||
#define EL_CHANGE_MEM_SIZE (sizeof(meminfo) + sizeof(el_change_info))
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Macro to flag a compile time assertion. It uses the preprocessor to generate
|
* Macro to flag a compile time assertion. It uses the preprocessor to generate
|
||||||
* an invalid C construct if 'cond' evaluates to false.
|
* an invalid C construct if 'cond' evaluates to false.
|
||||||
|
@ -81,6 +66,8 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <stdio.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.
|
||||||
|
@ -108,27 +95,36 @@ typedef struct {
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This structure represents the superset of information needed while switching
|
* This structure represents the superset of information needed while switching
|
||||||
* exception levels. The only two mechanisms to do so are ERET & SMC. In case of
|
* exception levels. The only two mechanisms to do so are ERET & SMC. In case of
|
||||||
* SMC all members apart from 'aapcs64_params' will be ignored. The 'next'
|
* SMC all members apart from 'aapcs64_params' will be ignored.
|
||||||
* member is a placeholder for a complicated case in the distant future when BL2
|
|
||||||
* will load multiple BL3x images as well as a non-secure image. So multiple
|
|
||||||
* such structures will have to be passed to BL31 in S-EL3.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long entrypoint;
|
unsigned long entrypoint;
|
||||||
unsigned long spsr;
|
unsigned long spsr;
|
||||||
unsigned long security_state;
|
unsigned long security_state;
|
||||||
aapcs64_params args;
|
aapcs64_params args;
|
||||||
unsigned long next;
|
|
||||||
} el_change_info;
|
} el_change_info;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
* populated only if BL2 detects its presence.
|
||||||
|
******************************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
meminfo bl31_meminfo;
|
||||||
|
el_change_info bl32_image_info;
|
||||||
|
meminfo bl32_meminfo;
|
||||||
|
el_change_info bl33_image_info;
|
||||||
|
meminfo bl33_meminfo;
|
||||||
|
} bl31_args;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Function & variable prototypes
|
* Function & variable prototypes
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
extern unsigned long page_align(unsigned long, unsigned);
|
extern unsigned long page_align(unsigned long, unsigned);
|
||||||
extern void change_security_state(unsigned int);
|
extern void change_security_state(unsigned int);
|
||||||
extern int drop_el(aapcs64_params *, unsigned long, unsigned long);
|
extern void __dead2 drop_el(aapcs64_params *, unsigned long, unsigned long);
|
||||||
extern long raise_el(aapcs64_params *);
|
extern void __dead2 raise_el(aapcs64_params *);
|
||||||
extern long change_el(el_change_info *);
|
extern void __dead2 change_el(el_change_info *);
|
||||||
extern unsigned long make_spsr(unsigned long, unsigned long, unsigned long);
|
extern unsigned long make_spsr(unsigned long, unsigned long, unsigned long);
|
||||||
extern void init_bl2_mem_layout(meminfo *,
|
extern void init_bl2_mem_layout(meminfo *,
|
||||||
meminfo *,
|
meminfo *,
|
||||||
|
@ -138,11 +134,11 @@ extern void init_bl31_mem_layout(const meminfo *,
|
||||||
meminfo *,
|
meminfo *,
|
||||||
unsigned int) __attribute__((weak));
|
unsigned int) __attribute__((weak));
|
||||||
extern unsigned long load_image(meminfo *, const char *, unsigned int, unsigned long);
|
extern unsigned long load_image(meminfo *, const char *, unsigned int, unsigned long);
|
||||||
extern int run_image(unsigned long,
|
extern void __dead2 run_image(unsigned long entrypoint,
|
||||||
unsigned long,
|
unsigned long spsr,
|
||||||
unsigned long,
|
unsigned long security_state,
|
||||||
meminfo *,
|
void *first_arg,
|
||||||
void *);
|
void *second_arg);
|
||||||
extern unsigned long *get_el_change_mem_ptr(void);
|
extern unsigned long *get_el_change_mem_ptr(void);
|
||||||
|
|
||||||
#endif /*__ASSEMBLY__*/
|
#endif /*__ASSEMBLY__*/
|
||||||
|
|
|
@ -70,19 +70,25 @@ extern unsigned char **bl2_el_change_mem_ptr;
|
||||||
static meminfo bl2_tzram_layout
|
static meminfo bl2_tzram_layout
|
||||||
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
||||||
section("tzfw_coherent_mem")));
|
section("tzfw_coherent_mem")));
|
||||||
/* Data structure which holds the extents of the Non-Secure DRAM for BL33 */
|
|
||||||
static meminfo bl33_dram_layout
|
/*******************************************************************************
|
||||||
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
* Reference to structure which holds the arguments which need to be passed
|
||||||
section("tzfw_coherent_mem")));
|
* to BL31
|
||||||
|
******************************************************************************/
|
||||||
|
static bl31_args *bl2_to_bl31_args;
|
||||||
|
|
||||||
meminfo *bl2_plat_sec_mem_layout(void)
|
meminfo *bl2_plat_sec_mem_layout(void)
|
||||||
{
|
{
|
||||||
return &bl2_tzram_layout;
|
return &bl2_tzram_layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
meminfo *bl2_get_ns_mem_layout(void)
|
/*******************************************************************************
|
||||||
|
* This function returns a pointer to the memory that the platform has kept
|
||||||
|
* aside to pass all the information that BL31 could need.
|
||||||
|
******************************************************************************/
|
||||||
|
bl31_args *bl2_get_bl31_args_ptr(void)
|
||||||
{
|
{
|
||||||
return &bl33_dram_layout;
|
return bl2_to_bl31_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -101,16 +107,6 @@ void bl2_early_platform_setup(meminfo *mem_layout,
|
||||||
bl2_tzram_layout.attr = mem_layout->attr;
|
bl2_tzram_layout.attr = mem_layout->attr;
|
||||||
bl2_tzram_layout.next = 0;
|
bl2_tzram_layout.next = 0;
|
||||||
|
|
||||||
/* Setup the BL3-3 memory layout.
|
|
||||||
* Normal World Firmware loaded into main DRAM.
|
|
||||||
*/
|
|
||||||
bl33_dram_layout.total_base = DRAM_BASE;
|
|
||||||
bl33_dram_layout.total_size = DRAM_SIZE;
|
|
||||||
bl33_dram_layout.free_base = DRAM_BASE;
|
|
||||||
bl33_dram_layout.free_size = DRAM_SIZE;
|
|
||||||
bl33_dram_layout.attr = 0;
|
|
||||||
bl33_dram_layout.next = 0;
|
|
||||||
|
|
||||||
/* Initialize the platform config for future decision making */
|
/* Initialize the platform config for future decision making */
|
||||||
platform_config_setup();
|
platform_config_setup();
|
||||||
|
|
||||||
|
@ -127,7 +123,15 @@ void bl2_platform_setup()
|
||||||
io_setup();
|
io_setup();
|
||||||
|
|
||||||
/* Use the Trusted DRAM for passing args to BL31 */
|
/* Use the Trusted DRAM for passing args to BL31 */
|
||||||
bl2_el_change_mem_ptr = (unsigned char **) TZDRAM_BASE;
|
bl2_to_bl31_args = (bl31_args *) TZDRAM_BASE;
|
||||||
|
|
||||||
|
/* Populate the extents of memory available for loading BL33 */
|
||||||
|
bl2_to_bl31_args->bl33_meminfo.total_base = DRAM_BASE;
|
||||||
|
bl2_to_bl31_args->bl33_meminfo.total_size = DRAM_SIZE;
|
||||||
|
bl2_to_bl31_args->bl33_meminfo.free_base = DRAM_BASE;
|
||||||
|
bl2_to_bl31_args->bl33_meminfo.free_size = DRAM_SIZE;
|
||||||
|
bl2_to_bl31_args->bl33_meminfo.attr = 0;
|
||||||
|
bl2_to_bl31_args->bl33_meminfo.next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <fvp_pwrc.h>
|
#include <fvp_pwrc.h>
|
||||||
|
#include <bl_common.h>
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Declarations of linker defined symbols which will help us find the layout
|
* Declarations of linker defined symbols which will help us find the layout
|
||||||
|
@ -61,22 +62,14 @@ extern unsigned long __COHERENT_RAM_END__;
|
||||||
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This data structure holds information copied by BL31 from BL2 to pass
|
* Reference to structure which holds the arguments that have been passed to
|
||||||
* control to the normal world software images.
|
* BL31 from BL2.
|
||||||
* TODO: Can this be moved out of device memory.
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static el_change_info ns_entry_info
|
static bl31_args *bl2_to_bl31_args;
|
||||||
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
|
||||||
section("tzfw_coherent_mem")));
|
|
||||||
|
|
||||||
/* Data structure which holds the extents of the trusted SRAM for BL31 */
|
|
||||||
static meminfo bl31_tzram_layout
|
|
||||||
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
|
||||||
section("tzfw_coherent_mem")));
|
|
||||||
|
|
||||||
meminfo *bl31_plat_sec_mem_layout(void)
|
meminfo *bl31_plat_sec_mem_layout(void)
|
||||||
{
|
{
|
||||||
return &bl31_tzram_layout;
|
return &bl2_to_bl31_args->bl31_meminfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -87,34 +80,24 @@ meminfo *bl31_plat_sec_mem_layout(void)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
el_change_info *bl31_get_next_image_info(void)
|
el_change_info *bl31_get_next_image_info(void)
|
||||||
{
|
{
|
||||||
return &ns_entry_info;
|
return &bl2_to_bl31_args->bl33_image_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Perform any BL31 specific platform actions. Here we copy parameters passed
|
* Perform any BL31 specific platform actions. Here is an opportunity to copy
|
||||||
* by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they are lost
|
* parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
|
||||||
* (potentially). This is done before the MMU is initialized so that the memory
|
* are lost (potentially). This needs to be done before the MMU is initialized
|
||||||
* layout can be used while creating page tables.
|
* so that the memory layout can be used while creating page tables. On the FVP
|
||||||
|
* we know that BL2 has populated the parameters in secure DRAM. So we just use
|
||||||
|
* the reference passed in 'from_bl2' instead of copying. The 'data' parameter
|
||||||
|
* is not used since all the information is contained in 'from_bl2'. Also, BL2
|
||||||
|
* has flushed this information to memory, so we are guaranteed to pick up good
|
||||||
|
* data
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void bl31_early_platform_setup(meminfo *mem_layout,
|
void bl31_early_platform_setup(bl31_args *from_bl2,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
el_change_info *image_info = (el_change_info *) data;
|
bl2_to_bl31_args = from_bl2;
|
||||||
|
|
||||||
/* Setup the BL31 memory layout */
|
|
||||||
bl31_tzram_layout.total_base = mem_layout->total_base;
|
|
||||||
bl31_tzram_layout.total_size = mem_layout->total_size;
|
|
||||||
bl31_tzram_layout.free_base = mem_layout->free_base;
|
|
||||||
bl31_tzram_layout.free_size = mem_layout->free_size;
|
|
||||||
bl31_tzram_layout.attr = mem_layout->attr;
|
|
||||||
bl31_tzram_layout.next = 0;
|
|
||||||
|
|
||||||
/* Save information about jumping into the normal world */
|
|
||||||
ns_entry_info.entrypoint = image_info->entrypoint;
|
|
||||||
ns_entry_info.spsr = image_info->spsr;
|
|
||||||
ns_entry_info.args = image_info->args;
|
|
||||||
ns_entry_info.security_state = image_info->security_state;
|
|
||||||
ns_entry_info.next = image_info->next;
|
|
||||||
|
|
||||||
/* Initialize the platform config for future decision making */
|
/* Initialize the platform config for future decision making */
|
||||||
platform_config_setup();
|
platform_config_setup();
|
||||||
|
@ -163,7 +146,7 @@ void bl31_platform_setup()
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void bl31_plat_arch_setup()
|
void bl31_plat_arch_setup()
|
||||||
{
|
{
|
||||||
configure_mmu(&bl31_tzram_layout,
|
configure_mmu(&bl2_to_bl31_args->bl31_meminfo,
|
||||||
BL31_RO_BASE,
|
BL31_RO_BASE,
|
||||||
BL31_RO_LIMIT,
|
BL31_RO_LIMIT,
|
||||||
BL31_COHERENT_RAM_BASE,
|
BL31_COHERENT_RAM_BASE,
|
||||||
|
|
|
@ -53,17 +53,20 @@
|
||||||
|
|
||||||
/* Trusted Boot Firmware BL2 */
|
/* Trusted Boot Firmware BL2 */
|
||||||
#define BL2_IMAGE_NAME "bl2.bin"
|
#define BL2_IMAGE_NAME "bl2.bin"
|
||||||
|
|
||||||
/* EL3 Runtime Firmware BL31 */
|
/* EL3 Runtime Firmware BL31 */
|
||||||
#define BL31_IMAGE_NAME "bl31.bin"
|
#define BL31_IMAGE_NAME "bl31.bin"
|
||||||
|
|
||||||
/* Secure Payload BL32 (Trusted OS) */
|
/* Secure Payload BL32 (Trusted OS) */
|
||||||
#define BL32_IMAGE_NAME "bl32.bin"
|
#define BL32_IMAGE_NAME "bl32.bin"
|
||||||
|
|
||||||
/* Non-Trusted Firmware BL33 and its load address */
|
/* Non-Trusted Firmware BL33 and its load address */
|
||||||
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
|
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
|
||||||
#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */
|
#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */
|
||||||
|
|
||||||
/* Firmware Image Package */
|
/* Firmware Image Package */
|
||||||
#define FIP_IMAGE_NAME "fip.bin"
|
#define FIP_IMAGE_NAME "fip.bin"
|
||||||
|
|
||||||
|
|
||||||
#define PLATFORM_CACHE_LINE_SIZE 64
|
#define PLATFORM_CACHE_LINE_SIZE 64
|
||||||
#define PLATFORM_CLUSTER_COUNT 2ull
|
#define PLATFORM_CLUSTER_COUNT 2ull
|
||||||
#define PLATFORM_CLUSTER0_CORE_COUNT 4
|
#define PLATFORM_CLUSTER0_CORE_COUNT 4
|
||||||
|
|
Loading…
Add table
Reference in a new issue