diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2014-02-06 10:36:15 +0000 |
---|---|---|
committer | Dan Handley <dan.handley@arm.com> | 2014-02-17 18:51:44 +0000 |
commit | caa84939a4d8b1189dea8619ccc57bdb3026b125 (patch) | |
tree | a7eb5e977cc9971c051ef469877fc3d00cba24ad /bl31/bl31_main.c | |
parent | 07f4e078b6871e5c74f6cb38f2726a2cfcb2b746 (diff) |
Add support for handling runtime service requests
This patch uses the reworked exception handling support to handle
runtime service requests through SMCs following the SMC calling
convention. This is a giant commit since all the changes are
inter-related. It does the following:
1. Replace the old exception handling mechanism with the new one
2. Enforce that SP_EL0 is used C runtime stacks.
3. Ensures that the cold and warm boot paths use the 'cpu_context'
structure to program an ERET into the next lower EL.
4. Ensures that SP_EL3 always points to the next 'cpu_context'
structure prior to an ERET into the next lower EL
5. Introduces a PSCI SMC handler which completes the use of PSCI as a
runtime service
Change-Id: I661797f834c0803d2c674d20f504df1b04c2b852
Co-authored-by: Achin Gupta <achin.gupta@arm.com>
Diffstat (limited to 'bl31/bl31_main.c')
-rw-r--r-- | bl31/bl31_main.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index dc65b60..9d2dc29 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -48,15 +48,18 @@ void bl31_lib_init() cm_init(); } -void bl31_arch_next_el_setup(void); - /******************************************************************************* * BL31 is responsible for setting up the runtime services for the primary cpu - * before passing control to the bootloader (UEFI) or Linux. + * 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. ******************************************************************************/ void bl31_main(void) { - el_change_info *image_info; + el_change_info *next_image_info; + uint32_t scr; /* Perform remaining generic architectural setup from EL3 */ bl31_arch_setup(); @@ -76,10 +79,27 @@ void bl31_main(void) /* Clean caches before re-entering normal world */ dcsw_op_all(DCCSW); - image_info = bl31_get_next_image_info(); + /* + * Setup minimal architectural state of the next highest EL to + * allow execution in it immediately upon entering it. + */ bl31_arch_next_el_setup(); - change_el(image_info); - /* There is no valid reason for change_el() to return */ - assert(0); + /* Program EL3 registers to enable entry into the next EL */ + next_image_info = bl31_get_next_image_info(); + scr = read_scr(); + if (next_image_info->security_state == NON_SECURE) + scr |= SCR_NS_BIT; + + /* + * Tell the context mgmt. library to ensure that SP_EL3 points to + * the right context to exit from EL3 correctly. + */ + cm_set_el3_eret_context(next_image_info->security_state, + next_image_info->entrypoint, + next_image_info->spsr, + scr); + + /* Finally set the next context */ + cm_set_next_eret_context(next_image_info->security_state); } |