diff options
Diffstat (limited to 'bl1/aarch64/bl1_exceptions.S')
-rw-r--r-- | bl1/aarch64/bl1_exceptions.S | 100 |
1 files changed, 89 insertions, 11 deletions
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S index 8802301e..9ff6a57b 100644 --- a/bl1/aarch64/bl1_exceptions.S +++ b/bl1/aarch64/bl1_exceptions.S @@ -31,6 +31,7 @@ #include <arch.h> #include <asm_macros.S> #include <bl_common.h> +#include <bl1.h> #include <context.h> .globl bl1_exceptions @@ -181,8 +182,26 @@ SErrorA32: func smc_handler64 + /* ---------------------------------------------- - * Switch back to SP_EL0 for the C runtime stack. + * Detect if this is a RUN_IMAGE or other SMC. + * ---------------------------------------------- + */ + mov x30, #BL1_SMC_RUN_IMAGE + cmp x30, x0 + b.ne smc_handler + + /* ------------------------------------------------ + * Make sure only Secure world reaches here. + * ------------------------------------------------ + */ + mrs x30, scr_el3 + tst x30, #SCR_NS_BIT + b.ne unexpected_sync_exception + + /* ---------------------------------------------- + * Handling RUN_IMAGE SMC. First switch back to + * SP_EL0 for the C runtime stack. * ---------------------------------------------- */ ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] @@ -190,20 +209,13 @@ func smc_handler64 mov sp, x30 /* --------------------------------------------------------------------- - * Only a single SMC exception from BL2 to ask BL1 to pass EL3 control - * to BL31 is expected here. It expects: - * - X0 with RUN_IMAGE SMC function ID; - * - X1 with the address of a entry_point_info_t structure describing - * the BL31 entrypoint. + * Pass EL3 control to BL31. + * Here it expects X1 with the address of a entry_point_info_t + * structure describing the BL31 entrypoint. * --------------------------------------------------------------------- */ - mov x19, x0 mov x20, x1 - mov x0, #RUN_IMAGE - cmp x19, x0 - b.ne unexpected_sync_exception - mov x0, x20 bl bl1_print_bl31_ep_info @@ -238,3 +250,69 @@ unexpected_sync_exception: bl plat_report_exception wfi b unexpected_sync_exception + + /* ----------------------------------------------------- + * Save Secure/Normal world context and jump to + * BL1 SMC handler. + * ----------------------------------------------------- + */ +smc_handler: + /* ----------------------------------------------------- + * Save the GP registers x0-x29. + * TODO: Revisit to store only SMCC specified registers. + * ----------------------------------------------------- + */ + bl save_gp_registers + + /* ----------------------------------------------------- + * Populate the parameters for the SMC handler. We + * already have x0-x4 in place. x5 will point to a + * cookie (not used now). x6 will point to the context + * structure (SP_EL3) and x7 will contain flags we need + * to pass to the handler. + * ----------------------------------------------------- + */ + mov x5, xzr + mov x6, sp + + /* ----------------------------------------------------- + * Restore the saved C runtime stack value which will + * become the new SP_EL0 i.e. EL3 runtime stack. It was + * saved in the 'cpu_context' structure prior to the last + * ERET from EL3. + * ----------------------------------------------------- + */ + ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] + + /* --------------------------------------------- + * Switch back to SP_EL0 for the C runtime stack. + * --------------------------------------------- + */ + msr spsel, #0 + mov sp, x12 + + /* ----------------------------------------------------- + * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there + * is a world switch during SMC handling. + * ----------------------------------------------------- + */ + mrs x16, spsr_el3 + mrs x17, elr_el3 + mrs x18, scr_el3 + stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] + str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] + + /* Copy SCR_EL3.NS bit to the flag to indicate caller's security */ + bfi x7, x18, #0, #1 + + /* ----------------------------------------------------- + * Go to BL1 SMC handler. + * ----------------------------------------------------- + */ + bl bl1_smc_handler + + /* ----------------------------------------------------- + * Do the transition to next BL image. + * ----------------------------------------------------- + */ + b el3_exit |