mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-15 09:04:17 +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_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",
|
||||
(unsigned long long) bl2_tzram_layout);
|
||||
#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)
|
||||
{
|
||||
meminfo *bl2_tzram_layout;
|
||||
meminfo *bl31_tzram_layout;
|
||||
meminfo *bl33_ns_layout;
|
||||
el_change_info *ns_image_info;
|
||||
bl31_args *bl2_to_bl31_args;
|
||||
unsigned long bl31_base, bl33_base, el_status;
|
||||
unsigned int bl2_load, bl31_load, mode;
|
||||
|
||||
|
@ -60,7 +58,7 @@ void bl2_main(void)
|
|||
/* Perform platform setup in BL1 */
|
||||
bl2_platform_setup();
|
||||
|
||||
#if defined (__GNUC__)
|
||||
#if defined(__GNUC__)
|
||||
printf("BL2 Built : %s, %s\n\r", __TIME__, __DATE__);
|
||||
#endif
|
||||
|
||||
|
@ -80,19 +78,30 @@ void bl2_main(void)
|
|||
bl31_load, BL31_BASE);
|
||||
|
||||
/* 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
|
||||
* will gobble up all the BL2 memory.
|
||||
*/
|
||||
bl31_tzram_layout = (meminfo *) get_el_change_mem_ptr();
|
||||
init_bl31_mem_layout(bl2_tzram_layout, bl31_tzram_layout, bl31_load);
|
||||
init_bl31_mem_layout(bl2_tzram_layout,
|
||||
&bl2_to_bl31_args->bl31_meminfo,
|
||||
bl31_load);
|
||||
|
||||
/* Find out where the BL3-3 normal world firmware should go. */
|
||||
bl33_ns_layout = bl2_get_ns_mem_layout();
|
||||
bl33_base = load_image(bl33_ns_layout, BL33_IMAGE_NAME,
|
||||
BOT_LOAD, plat_get_ns_image_entrypoint());
|
||||
/* Load the BL33 image in non-secure memory provided by the platform */
|
||||
bl33_base = load_image(&bl2_to_bl31_args->bl33_meminfo,
|
||||
BL33_IMAGE_NAME,
|
||||
BOT_LOAD,
|
||||
plat_get_ns_image_entrypoint());
|
||||
/* Halt if failed to load normal world firmware. */
|
||||
if (bl33_base == 0) {
|
||||
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
|
||||
* 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
|
||||
+ sizeof(meminfo));
|
||||
ns_image_info->entrypoint = bl33_base;
|
||||
bl2_to_bl31_args->bl33_image_info.entrypoint = bl33_base;
|
||||
|
||||
/* Figure out what mode we enter the non-secure world in */
|
||||
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
|
||||
|
@ -116,22 +123,27 @@ void bl2_main(void)
|
|||
else
|
||||
mode = MODE_EL1;
|
||||
|
||||
ns_image_info->spsr = make_spsr(mode, MODE_SP_ELX, MODE_RW_64);
|
||||
ns_image_info->security_state = NON_SECURE;
|
||||
flush_dcache_range((unsigned long) ns_image_info,
|
||||
sizeof(el_change_info));
|
||||
/*
|
||||
* TODO: Consider the possibility of specifying the SPSR in
|
||||
* the FIP ToC and allowing the platform to have a say as
|
||||
* 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
|
||||
* 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,
|
||||
make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64),
|
||||
SECURE,
|
||||
bl31_tzram_layout,
|
||||
(void *) ns_image_info);
|
||||
|
||||
/* There is no valid reason for run_image() to return */
|
||||
assert(0);
|
||||
run_image(bl31_base,
|
||||
make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64),
|
||||
SECURE,
|
||||
(void *) bl2_to_bl31_args,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -47,11 +47,10 @@
|
|||
|
||||
bl31_entrypoint: ; .type bl31_entrypoint, %function
|
||||
/* ---------------------------------------------
|
||||
* BL2 has populated x0,x3,x4 with the opcode
|
||||
* indicating BL31 should be run, memory layout
|
||||
* of the trusted SRAM available to BL31 and
|
||||
* information about running the non-trusted
|
||||
* software already loaded by BL2.
|
||||
* BL2 has populated x0 with the opcode
|
||||
* indicating BL31 should be run, x3 with
|
||||
* a pointer to a 'bl31_args' structure & x4
|
||||
* with any other optional information
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
|
@ -40,17 +40,6 @@
|
|||
#include "io_storage.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_size = 1 << FOUR_KB_SHIFT;
|
||||
|
@ -85,9 +74,9 @@ void change_security_state(unsigned int target_security_state)
|
|||
write_scr(scr);
|
||||
}
|
||||
|
||||
int drop_el(aapcs64_params *args,
|
||||
unsigned long spsr,
|
||||
unsigned long entrypoint)
|
||||
void __dead2 drop_el(aapcs64_params *args,
|
||||
unsigned long spsr,
|
||||
unsigned long entrypoint)
|
||||
{
|
||||
write_spsr(spsr);
|
||||
write_elr(entrypoint);
|
||||
|
@ -99,19 +88,18 @@ int drop_el(aapcs64_params *args,
|
|||
args->arg5,
|
||||
args->arg6,
|
||||
args->arg7);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
long raise_el(aapcs64_params *args)
|
||||
void __dead2 raise_el(aapcs64_params *args)
|
||||
{
|
||||
return smc(args->arg0,
|
||||
args->arg1,
|
||||
args->arg2,
|
||||
args->arg3,
|
||||
args->arg4,
|
||||
args->arg5,
|
||||
args->arg6,
|
||||
args->arg7);
|
||||
smc(args->arg0,
|
||||
args->arg1,
|
||||
args->arg2,
|
||||
args->arg3,
|
||||
args->arg4,
|
||||
args->arg5,
|
||||
args->arg6,
|
||||
args->arg7);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -119,7 +107,7 @@ long raise_el(aapcs64_params *args)
|
|||
* Add support for dropping into EL0 etc. Consider adding support
|
||||
* 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();
|
||||
|
||||
|
@ -134,9 +122,9 @@ long change_el(el_change_info *info)
|
|||
if (info->security_state == NON_SECURE)
|
||||
change_security_state(info->security_state);
|
||||
|
||||
return drop_el(&info->args, info->spsr, info->entrypoint);
|
||||
drop_el(&info->args, info->spsr, info->entrypoint);
|
||||
} else
|
||||
return raise_el(&info->args);
|
||||
raise_el(&info->args);
|
||||
}
|
||||
|
||||
/* 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
|
||||
* parameters for the EL change request correctly.
|
||||
******************************************************************************/
|
||||
int run_image(unsigned long entrypoint,
|
||||
unsigned long spsr,
|
||||
unsigned long target_security_state,
|
||||
meminfo *mem_layout,
|
||||
void *data)
|
||||
void __dead2 run_image(unsigned long entrypoint,
|
||||
unsigned long spsr,
|
||||
unsigned long target_security_state,
|
||||
void *first_arg,
|
||||
void *second_arg)
|
||||
{
|
||||
el_change_info run_image_info;
|
||||
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.spsr = spsr;
|
||||
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
|
||||
|
@ -538,14 +525,14 @@ int run_image(unsigned long entrypoint,
|
|||
* will go into the general purpose register xY e.g. arg0->x0
|
||||
*/
|
||||
if (GET_EL(current_el) == MODE_EL3) {
|
||||
run_image_info.args.arg1 = (unsigned long) mem_layout;
|
||||
run_image_info.args.arg2 = (unsigned long) data;
|
||||
run_image_info.args.arg1 = (unsigned long) first_arg;
|
||||
run_image_info.args.arg2 = (unsigned long) second_arg;
|
||||
} else {
|
||||
run_image_info.args.arg1 = entrypoint;
|
||||
run_image_info.args.arg2 = spsr;
|
||||
run_image_info.args.arg3 = (unsigned long) mem_layout;
|
||||
run_image_info.args.arg4 = (unsigned long) data;
|
||||
run_image_info.args.arg3 = (unsigned long) first_arg;
|
||||
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
|
||||
BL3-1
|
||||
|
||||
BL2 places this `meminfo` structure in memory provided by the
|
||||
platform (`bl2_el_change_mem_ptr`). BL2 implements the
|
||||
BL2 populates this information in the `bl31_meminfo` field of the pointer
|
||||
returned by the `bl2_get_bl31_args_ptr() function. BL2 implements the
|
||||
`init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
|
||||
described above. The platform may override this implementation, for example
|
||||
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
|
||||
variable as the original memory may be subsequently overwritten by BL2. 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
|
||||
loading BL3-3 is also initialized in this function. Access to this information
|
||||
is provided by the `bl2_get_ns_mem_layout()` function.
|
||||
`bl2_plat_sec_mem_layout()` function.
|
||||
|
||||
|
||||
### 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
|
||||
called by the primary CPU.
|
||||
|
||||
The purpose of this function is to perform any platform initialization specific
|
||||
to BL2. This function must initialize a pointer to memory
|
||||
(`bl2_el_change_mem_ptr`), which can then be used to populate an
|
||||
`el_change_info` structure. The underlying requirement is that the platform must
|
||||
initialize this pointer before the `get_el_change_mem_ptr()` function
|
||||
accesses it in `bl2_main()`.
|
||||
The purpose of this function is to perform any platform initialization
|
||||
specific to BL2. For example on the ARM FVP port this function initialises a
|
||||
internal pointer (`bl2_to_bl31_args`) to a `bl31_args` which will be used by
|
||||
BL2 to pass information to BL3_1. The pointer is initialized to the base
|
||||
address of Secure DRAM (`0x06000000`).
|
||||
|
||||
The ARM FVP port initializes this pointer to the base address of Secure DRAM
|
||||
(`0x06000000`).
|
||||
The non-secure memory extents used for loading BL3-3 are also initialized in
|
||||
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
|
||||
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]
|
||||
|
||||
Argument : void
|
||||
|
@ -616,18 +607,20 @@ populated with the extents of secure RAM available for BL2 to use. See
|
|||
`bl2_early_platform_setup()` above.
|
||||
|
||||
|
||||
### Function : bl2_get_ns_mem_layout() [mandatory]
|
||||
### Function : bl2_get_bl31_args_ptr() [mandatory]
|
||||
|
||||
Argument : void
|
||||
Return : meminfo *
|
||||
Return : bl31_args *
|
||||
|
||||
This function should only be called on the cold boot path. It 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 called by the primary CPU.
|
||||
|
||||
The purpose of this function is to return a pointer to a `meminfo` structure
|
||||
populated with the extents of non-secure DRAM available for BL2 to use. See
|
||||
`bl2_early_platform_setup()` above.
|
||||
BL2 platform code needs to return a pointer to a `bl31_args` structure it will
|
||||
use for passing information to BL3-1. The `bl31_args` structure carries the
|
||||
following information. This information is used by the `bl2_main()` function to
|
||||
load the BL3-2 (if present) and BL3-3 images.
|
||||
- Extents of memory available to the BL3-1 image in the `bl31_meminfo` field
|
||||
- Extents of memory available to the BL3-2 image in the `bl32_meminfo` field
|
||||
- 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]
|
||||
|
@ -699,11 +692,16 @@ by the primary CPU. The arguments to this function are:
|
|||
* An opaque pointer that the platform may use as needed.
|
||||
* The `MPIDR` of the primary CPU.
|
||||
|
||||
The platform must copy the contents of the `meminfo` structure into a private
|
||||
variable as the original memory may be subsequently overwritten by BL3-1. The
|
||||
copied structure is made available to all BL3-1 code through the
|
||||
The platform can copy the contents of the `meminfo` structure into a private
|
||||
variable if the original memory may be subsequently overwritten by BL3-1. The
|
||||
reference to this structure is made available to all BL3-1 code through the
|
||||
`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]
|
||||
|
||||
|
|
|
@ -796,7 +796,7 @@ bits.
|
|||
BL2 does not perform any platform initialization that affects subsequent
|
||||
stages of the ARM Trusted Firmware or normal world software. It copies the
|
||||
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
|
||||
images. A platform defined base address is used to specify the load address for
|
||||
the BL3-1 image.
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <arch.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <stdio.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* TLB maintenance accessor prototypes
|
||||
|
@ -108,14 +109,14 @@ extern void isb(void);
|
|||
extern unsigned int get_afflvl_shift(unsigned int);
|
||||
extern unsigned int mpidr_mask_lower_afflvls(unsigned long, unsigned int);
|
||||
|
||||
extern void eret(unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned long, unsigned long);
|
||||
extern void __dead2 eret(unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned long, unsigned long);
|
||||
|
||||
extern unsigned long smc(unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
extern void __dead2 smc(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 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__ */
|
||||
|
|
|
@ -48,21 +48,6 @@
|
|||
#define BOT_LOAD !TOP_LOAD
|
||||
#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
|
||||
* an invalid C construct if 'cond' evaluates to false.
|
||||
|
@ -81,6 +66,8 @@
|
|||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <stdio.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
|
@ -108,27 +95,36 @@ typedef struct {
|
|||
/*******************************************************************************
|
||||
* 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
|
||||
* SMC all members apart from 'aapcs64_params' will be ignored. The 'next'
|
||||
* 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.
|
||||
* SMC all members apart from 'aapcs64_params' will be ignored.
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
unsigned long entrypoint;
|
||||
unsigned long spsr;
|
||||
unsigned long security_state;
|
||||
aapcs64_params args;
|
||||
unsigned long next;
|
||||
} 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
|
||||
******************************************************************************/
|
||||
extern unsigned long page_align(unsigned long, unsigned);
|
||||
extern void change_security_state(unsigned int);
|
||||
extern int drop_el(aapcs64_params *, unsigned long, unsigned long);
|
||||
extern long raise_el(aapcs64_params *);
|
||||
extern long change_el(el_change_info *);
|
||||
extern void __dead2 drop_el(aapcs64_params *, unsigned long, unsigned long);
|
||||
extern void __dead2 raise_el(aapcs64_params *);
|
||||
extern void __dead2 change_el(el_change_info *);
|
||||
extern unsigned long make_spsr(unsigned long, unsigned long, unsigned long);
|
||||
extern void init_bl2_mem_layout(meminfo *,
|
||||
meminfo *,
|
||||
|
@ -138,11 +134,11 @@ extern void init_bl31_mem_layout(const meminfo *,
|
|||
meminfo *,
|
||||
unsigned int) __attribute__((weak));
|
||||
extern unsigned long load_image(meminfo *, const char *, unsigned int, unsigned long);
|
||||
extern int run_image(unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
meminfo *,
|
||||
void *);
|
||||
extern void __dead2 run_image(unsigned long entrypoint,
|
||||
unsigned long spsr,
|
||||
unsigned long security_state,
|
||||
void *first_arg,
|
||||
void *second_arg);
|
||||
extern unsigned long *get_el_change_mem_ptr(void);
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
|
|
|
@ -70,19 +70,25 @@ extern unsigned char **bl2_el_change_mem_ptr;
|
|||
static meminfo bl2_tzram_layout
|
||||
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
||||
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),
|
||||
section("tzfw_coherent_mem")));
|
||||
|
||||
/*******************************************************************************
|
||||
* Reference to structure which holds the arguments which need to be passed
|
||||
* to BL31
|
||||
******************************************************************************/
|
||||
static bl31_args *bl2_to_bl31_args;
|
||||
|
||||
meminfo *bl2_plat_sec_mem_layout(void)
|
||||
{
|
||||
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.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 */
|
||||
platform_config_setup();
|
||||
|
||||
|
@ -127,7 +123,15 @@ void bl2_platform_setup()
|
|||
io_setup();
|
||||
|
||||
/* 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 <fvp_pwrc.h>
|
||||
#include <bl_common.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* 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__)
|
||||
|
||||
/*******************************************************************************
|
||||
* This data structure holds information copied by BL31 from BL2 to pass
|
||||
* control to the normal world software images.
|
||||
* TODO: Can this be moved out of device memory.
|
||||
* Reference to structure which holds the arguments that have been passed to
|
||||
* BL31 from BL2.
|
||||
******************************************************************************/
|
||||
static el_change_info ns_entry_info
|
||||
__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")));
|
||||
static bl31_args *bl2_to_bl31_args;
|
||||
|
||||
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)
|
||||
{
|
||||
return &ns_entry_info;
|
||||
return &bl2_to_bl31_args->bl33_image_info;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform any BL31 specific platform actions. Here we copy parameters passed
|
||||
* by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they are lost
|
||||
* (potentially). This is done before the MMU is initialized so that the memory
|
||||
* layout can be used while creating page tables.
|
||||
* Perform any BL31 specific platform actions. Here is an opportunity to copy
|
||||
* parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
|
||||
* are lost (potentially). This needs to be done before the MMU is initialized
|
||||
* 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)
|
||||
{
|
||||
el_change_info *image_info = (el_change_info *) data;
|
||||
|
||||
/* 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;
|
||||
bl2_to_bl31_args = from_bl2;
|
||||
|
||||
/* Initialize the platform config for future decision making */
|
||||
platform_config_setup();
|
||||
|
@ -163,7 +146,7 @@ void bl31_platform_setup()
|
|||
******************************************************************************/
|
||||
void bl31_plat_arch_setup()
|
||||
{
|
||||
configure_mmu(&bl31_tzram_layout,
|
||||
configure_mmu(&bl2_to_bl31_args->bl31_meminfo,
|
||||
BL31_RO_BASE,
|
||||
BL31_RO_LIMIT,
|
||||
BL31_COHERENT_RAM_BASE,
|
||||
|
|
|
@ -53,17 +53,20 @@
|
|||
|
||||
/* Trusted Boot Firmware BL2 */
|
||||
#define BL2_IMAGE_NAME "bl2.bin"
|
||||
|
||||
/* EL3 Runtime Firmware BL31 */
|
||||
#define BL31_IMAGE_NAME "bl31.bin"
|
||||
#define BL31_IMAGE_NAME "bl31.bin"
|
||||
|
||||
/* 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 */
|
||||
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
|
||||
#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */
|
||||
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
|
||||
#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */
|
||||
|
||||
/* Firmware Image Package */
|
||||
#define FIP_IMAGE_NAME "fip.bin"
|
||||
|
||||
|
||||
#define PLATFORM_CACHE_LINE_SIZE 64
|
||||
#define PLATFORM_CLUSTER_COUNT 2ull
|
||||
#define PLATFORM_CLUSTER0_CORE_COUNT 4
|
||||
|
|
Loading…
Add table
Reference in a new issue