diff options
author | Achin Gupta <achin.gupta@arm.com> | 2014-02-19 17:58:33 +0000 |
---|---|---|
committer | Dan Handley <dan.handley@arm.com> | 2014-02-20 19:06:34 +0000 |
commit | 35ca35119d9dc51f1665184ab6db5e2861c213b4 (patch) | |
tree | ad063c1d5bb7b529603570e53a17340d53d19c8b /bl31/bl31_main.c | |
parent | a3050ed521ec1fd6d34d7d8ba5105ac8bc024992 (diff) |
Add support for BL3-2 in BL3-1
This patch adds the following support to the BL3-1 stage:
1. BL3-1 allows runtime services to specify and determine the security
state of the next image after BL3-1. This has been done by adding
the `bl31_set_next_image_type()` & `bl31_get_next_image_type()`
apis. The default security state is non-secure. The platform api
`bl31_get_next_image_info()` has been modified to let the platform
decide which is the next image in the desired security state.
2. BL3-1 exports the `bl31_prepare_next_image_entry()` function to
program entry into the target security state. It uses the apis
introduced in 1. to do so.
3. BL3-1 reads the information populated by BL2 about the BL3-2 image
into its internal data structures.
4. BL3-1 introduces a weakly defined reference `bl32_init()` to allow
initialisation of a BL3-2 image. A runtime service like the Secure
payload dispatcher will define this function if present.
Change-Id: Icc46dcdb9e475ce6575dd3f9a5dc7a48a83d21d1
Diffstat (limited to 'bl31/bl31_main.c')
-rw-r--r-- | bl31/bl31_main.c | 92 |
1 files changed, 82 insertions, 10 deletions
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 9d2dc299..ea44871c 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -41,6 +41,12 @@ #include <context_mgmt.h> /******************************************************************************* + * Variable to indicate whether next image to execute after BL31 is BL33 + * (non-secure & default) or BL32 (secure). + ******************************************************************************/ +static uint32_t next_image_type = NON_SECURE; + +/******************************************************************************* * Simple function to initialise all BL31 helper libraries. ******************************************************************************/ void bl31_lib_init() @@ -50,16 +56,17 @@ void bl31_lib_init() /******************************************************************************* * BL31 is responsible for setting up the runtime services for the primary cpu - * before passing control to the bootloader (UEFI) or Linux. This function calls - * runtime_svc_init() which initializes all registered runtime services. The run - * time services would setup enough context for the core to swtich to the next - * exception level. When this function returns, the core will switch to the - * programmed exception level via. an ERET. + * before passing control to the bootloader or an Operating System. This + * function calls runtime_svc_init() which initializes all registered runtime + * services. The run time services would setup enough context for the core to + * swtich to the next exception level. When this function returns, the core will + * switch to the programmed exception level via. an ERET. ******************************************************************************/ void bl31_main(void) { - el_change_info *next_image_info; - uint32_t scr; +#if DEBUG + unsigned long mpidr = read_mpidr(); +#endif /* Perform remaining generic architectural setup from EL3 */ bl31_arch_setup(); @@ -80,15 +87,80 @@ void bl31_main(void) dcsw_op_all(DCCSW); /* + * Use the more complex exception vectors now that context + * management is setup. SP_EL3 should point to a 'cpu_context' + * structure which has an exception stack allocated. The PSCI + * service should have set the context. + */ + assert(cm_get_context(mpidr, NON_SECURE)); + cm_set_next_eret_context(NON_SECURE); + write_vbar_el3((uint64_t) runtime_exceptions); + + /* + * All the cold boot actions on the primary cpu are done. We + * now need to decide which is the next image (BL32 or BL33) + * and how to execute it. If the SPD runtime service is + * present, it would want to pass control to BL32 first in + * S-EL1. It will export the bl32_init() routine where it takes + * responsibility of entering S-EL1 and returning control back + * to bl31_main. Once this is done we can prepare entry into + * BL33 as normal. + */ + + /* Tell BL32 about it memory extents as well */ + if (bl32_init) + bl32_init(bl31_plat_get_bl32_mem_layout()); + + /* + * We are ready to enter the next EL. Prepare entry into the image + * corresponding to the desired security state after the next ERET. + */ + bl31_prepare_next_image_entry(); +} + +/******************************************************************************* + * Accessor functions to help runtime services decide which image should be + * executed after BL31. This is BL33 or the non-secure bootloader image by + * default but the Secure payload dispatcher could override this by requesting + * an entry into BL32 (Secure payload) first. If it does so then it should use + * the same API to program an entry into BL33 once BL32 initialisation is + * complete. + ******************************************************************************/ +void bl31_set_next_image_type(uint32_t security_state) +{ + assert(security_state == NON_SECURE || security_state == SECURE); + next_image_type = security_state; +} + +uint32_t bl31_get_next_image_type(void) +{ + return next_image_type; +} + +/******************************************************************************* + * This function programs EL3 registers and performs other setup to enable entry + * into the next image after BL31 at the next ERET. + ******************************************************************************/ +void bl31_prepare_next_image_entry() +{ + el_change_info *next_image_info; + uint32_t scr, image_type; + + /* Determine which image to execute next */ + image_type = bl31_get_next_image_type(); + + /* * Setup minimal architectural state of the next highest EL to * allow execution in it immediately upon entering it. */ - bl31_arch_next_el_setup(); + bl31_next_el_arch_setup(image_type); /* Program EL3 registers to enable entry into the next EL */ - next_image_info = bl31_get_next_image_info(); + next_image_info = bl31_get_next_image_info(image_type); + assert(next_image_info); + scr = read_scr(); - if (next_image_info->security_state == NON_SECURE) + if (image_type == NON_SECURE) scr |= SCR_NS_BIT; /* |