Page MenuHomePhabricator

Bl1aarch64bl1 Exceptionssvsplatarmboardfvp Rfvp R Bl1 Exceptionss
Updated 1,222 Days AgoPublic

/*                                                            /*
 * Copyright (c) 2013-2021, ARM Limited and Contributors.  |   * Copyright (c) 2021, ARM Limited and Contributors. All r
 *                                                             *
 * SPDX-License-Identifier: BSD-3-Clause                       * SPDX-License-Identifier: BSD-3-Clause
 */                                                            */

#include <arch.h>                                             #include <arch.h>
#include <asm_macros.S>                                       #include <asm_macros.S>
#include <bl1/bl1.h>                                          #include <bl1/bl1.h>
#include <common/bl_common.h>                                 #include <common/bl_common.h>
#include <context.h>                                          #include <context.h>

/* -------------------------------------------------------    /* -------------------------------------------------------
                                                           >   * File contains an EL2 override of the EL3 vector table f
                                                           >   *      .../bl1/aarch64/bl1_exceptions.S
                                                           >   * -------------------------------------------------------
                                                           >   */
                                                           >
                                                           >  /* -------------------------------------------------------
 * Very simple stackless exception handlers used by BL1.       * Very simple stackless exception handlers used by BL1.
 * -------------------------------------------------------     * -------------------------------------------------------
 */                                                            */
        .globl  bl1_exceptions                                        .globl  bl1_exceptions

vector_base bl1_exceptions                                    vector_base bl1_exceptions

        /* -----------------------------------------------            /* -----------------------------------------------
         * Current EL with SP0 : 0x0 - 0x200                           * Current EL with SP0 : 0x0 - 0x200
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
vector_entry SynchronousExceptionSP0                          vector_entry SynchronousExceptionSP0
        mov     x0, #SYNC_EXCEPTION_SP_EL0                            mov     x0, #SYNC_EXCEPTION_SP_EL0
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry SynchronousExceptionSP0                      end_vector_entry SynchronousExceptionSP0

vector_entry IrqSP0                                           vector_entry IrqSP0
        mov     x0, #IRQ_SP_EL0                                       mov     x0, #IRQ_SP_EL0
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry IrqSP0                                       end_vector_entry IrqSP0

vector_entry FiqSP0                                           vector_entry FiqSP0
        mov     x0, #FIQ_SP_EL0                                       mov     x0, #FIQ_SP_EL0
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry FiqSP0                                       end_vector_entry FiqSP0

vector_entry SErrorSP0                                        vector_entry SErrorSP0
        mov     x0, #SERROR_SP_EL0                                    mov     x0, #SERROR_SP_EL0
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry SErrorSP0                                    end_vector_entry SErrorSP0

        /* -----------------------------------------------            /* -----------------------------------------------
         * Current EL with SPx: 0x200 - 0x400                          * Current EL with SPx: 0x200 - 0x400
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
vector_entry SynchronousExceptionSPx                          vector_entry SynchronousExceptionSPx
        mov     x0, #SYNC_EXCEPTION_SP_ELX                            mov     x0, #SYNC_EXCEPTION_SP_ELX
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry SynchronousExceptionSPx                      end_vector_entry SynchronousExceptionSPx

vector_entry IrqSPx                                           vector_entry IrqSPx
        mov     x0, #IRQ_SP_ELX                                       mov     x0, #IRQ_SP_ELX
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry IrqSPx                                       end_vector_entry IrqSPx

vector_entry FiqSPx                                           vector_entry FiqSPx
        mov     x0, #FIQ_SP_ELX                                       mov     x0, #FIQ_SP_ELX
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry FiqSPx                                       end_vector_entry FiqSPx

vector_entry SErrorSPx                                        vector_entry SErrorSPx
        mov     x0, #SERROR_SP_ELX                                    mov     x0, #SERROR_SP_ELX
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry SErrorSPx                                    end_vector_entry SErrorSPx

        /* -----------------------------------------------            /* -----------------------------------------------
         * Lower EL using AArch64 : 0x400 - 0x600                      * Lower EL using AArch64 : 0x400 - 0x600
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
vector_entry SynchronousExceptionA64                          vector_entry SynchronousExceptionA64
        /* Enable the SError interrupt */                             /* Enable the SError interrupt */
        msr     daifclr, #DAIF_ABT_BIT                                msr     daifclr, #DAIF_ABT_BIT

        str     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_L            str     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_L

        /* Expect only SMC exceptions */                              /* Expect only SMC exceptions */
        mrs     x30, esr_el3                               |          mrs     x30, esr_el2
        ubfx    x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH               ubfx    x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
        cmp     x30, #EC_AARCH64_SMC                                  cmp     x30, #EC_AARCH64_SMC
        b.ne    unexpected_sync_exception                             b.ne    unexpected_sync_exception

        b       smc_handler64                                         b       smc_handler64
end_vector_entry SynchronousExceptionA64                      end_vector_entry SynchronousExceptionA64

vector_entry IrqA64                                           vector_entry IrqA64
        mov     x0, #IRQ_AARCH64                                      mov     x0, #IRQ_AARCH64
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry IrqA64                                       end_vector_entry IrqA64

vector_entry FiqA64                                           vector_entry FiqA64
        mov     x0, #FIQ_AARCH64                                      mov     x0, #FIQ_AARCH64
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry FiqA64                                       end_vector_entry FiqA64

vector_entry SErrorA64                                        vector_entry SErrorA64
        mov     x0, #SERROR_AARCH64                                   mov     x0, #SERROR_AARCH64
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler
end_vector_entry SErrorA64                                    end_vector_entry SErrorA64

        /* ----------------------------------------------- <
         * Lower EL using AArch32 : 0x600 - 0x800          <
         * ----------------------------------------------- <
         */                                                <
vector_entry SynchronousExceptionA32                       <
        mov     x0, #SYNC_EXCEPTION_AARCH32                <
        bl      plat_report_exception                      <
        no_ret  plat_panic_handler                         <
end_vector_entry SynchronousExceptionA32                   <
                                                           <
vector_entry IrqA32                                        <
        mov     x0, #IRQ_AARCH32                           <
        bl      plat_report_exception                      <
        no_ret  plat_panic_handler                         <
end_vector_entry IrqA32                                    <
                                                           <
vector_entry FiqA32                                        <
        mov     x0, #FIQ_AARCH32                           <
        bl      plat_report_exception                      <
        no_ret  plat_panic_handler                         <
end_vector_entry FiqA32                                    <
                                                           <
vector_entry SErrorA32                                     <
        mov     x0, #SERROR_AARCH32                        <
        bl      plat_report_exception                      <
        no_ret  plat_panic_handler                         <
end_vector_entry SErrorA32                                 <


func smc_handler64                                            func smc_handler64

        /* ----------------------------------------------             /* ----------------------------------------------
         * Detect if this is a RUN_IMAGE or other SMC.                 * Detect if this is a RUN_IMAGE or other SMC.
         * ----------------------------------------------              * ----------------------------------------------
         */                                                            */
        mov     x30, #BL1_SMC_RUN_IMAGE                               mov     x30, #BL1_SMC_RUN_IMAGE
        cmp     x30, x0                                               cmp     x30, x0
        b.ne    smc_handler                                           b.ne    smc_handler

        /* -----------------------------------------------            /* -----------------------------------------------
         * Make sure only Secure world reaches here.                   * Make sure only Secure world reaches here.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        mrs     x30, scr_el3                                          mrs     x30, scr_el3
        tst     x30, #SCR_NS_BIT                                      tst     x30, #SCR_NS_BIT
        b.ne    unexpected_sync_exception                             b.ne    unexpected_sync_exception

        /* ----------------------------------------------             /* ----------------------------------------------
         * Handling RUN_IMAGE SMC. First switch back to                * Handling RUN_IMAGE SMC. First switch back to
         * SP_EL0 for the C runtime stack.                             * SP_EL0 for the C runtime stack.
         * ----------------------------------------------              * ----------------------------------------------
         */                                                            */
        ldr     x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTI            ldr     x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTI
        msr     spsel, #MODE_SP_EL0                                   msr     spsel, #MODE_SP_EL0
        mov     sp, x30                                               mov     sp, x30

        /* -----------------------------------------------            /* -----------------------------------------------
         * Pass EL3 control to next BL image.              |           * Pass EL2 control to next BL image.
         * Here it expects X1 with the address of a entry_             * Here it expects X1 with the address of a entry_
         * structure describing the next BL image entrypoi             * structure describing the next BL image entrypoi
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        mov     x20, x1                                               mov     x20, x1

        mov     x0, x20                                               mov     x0, x20
        bl      bl1_print_next_bl_ep_info                             bl      bl1_print_next_bl_ep_info

        ldp     x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]            ldp     x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
        msr     elr_el3, x0                                |          msr     elr_el2, x0
        msr     spsr_el3, x1                               |          msr     spsr_el2, x1
        ubfx    x0, x1, #MODE_EL_SHIFT, #2                            ubfx    x0, x1, #MODE_EL_SHIFT, #2
        cmp     x0, #MODE_EL3                              |          cmp     x0, #MODE_EL2
        b.ne    unexpected_sync_exception                             b.ne    unexpected_sync_exception

        bl      disable_mmu_icache_el3                     |          bl      disable_mpu_icache_el2
        tlbi    alle3                                                 tlbi    alle3
        dsb     ish /* ERET implies ISB, so it is not need            dsb     ish /* ERET implies ISB, so it is not need

#if SPIN_ON_BL1_EXIT                                          #if SPIN_ON_BL1_EXIT
        bl      print_debug_loop_message                              bl      print_debug_loop_message
debug_loop:                                                   debug_loop:
        b       debug_loop                                            b       debug_loop
#endif                                                        #endif

        mov     x0, x20                                               mov     x0, x20
        bl      bl1_plat_prepare_exit                                 bl      bl1_plat_prepare_exit

        ldp     x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS            ldp     x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS
        ldp     x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS            ldp     x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS
        ldp     x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS            ldp     x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS
        ldp     x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS            ldp     x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFS
        exception_return                                              exception_return
endfunc smc_handler64                                         endfunc smc_handler64

unexpected_sync_exception:                                    unexpected_sync_exception:
        mov     x0, #SYNC_EXCEPTION_AARCH64                           mov     x0, #SYNC_EXCEPTION_AARCH64
        bl      plat_report_exception                                 bl      plat_report_exception
        no_ret  plat_panic_handler                                    no_ret  plat_panic_handler

        /* -----------------------------------------------            /* -----------------------------------------------
         * Save Secure/Normal world context and jump to                * Save Secure/Normal world context and jump to
         * BL1 SMC handler.                                            * BL1 SMC handler.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
smc_handler:                                                  smc_handler:
        /* -----------------------------------------------            /* -----------------------------------------------
         * Save x0-x29 and ARMv8.3-PAuth (if enabled) regi             * Save x0-x29 and ARMv8.3-PAuth (if enabled) regi
         * If Secure Cycle Counter is not disabled in MDCR |           * If Secure Cycle Counter is not disabled in MDCR
         * when ARMv8.5-PMU is implemented, save PMCR_EL0              * when ARMv8.5-PMU is implemented, save PMCR_EL0 
         * disable Cycle Counter.                                      * disable Cycle Counter.
         * TODO: Revisit to store only SMCCC specified reg             * TODO: Revisit to store only SMCCC specified reg
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        bl      save_gp_pmcr_pauth_regs                               bl      save_gp_pmcr_pauth_regs

#if ENABLE_PAUTH                                              #if ENABLE_PAUTH
        /* -----------------------------------------------            /* -----------------------------------------------
         * Load and program stored APIAKey firmware key.               * Load and program stored APIAKey firmware key.
         * Re-enable pointer authentication in EL3, as it  |           * Re-enable pointer authentication in EL2, as it 
         * disabled before jumping to the next boot image.             * disabled before jumping to the next boot image.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        bl      pauth_load_bl1_apiakey_enable                         bl      pauth_load_bl1_apiakey_enable
#endif                                                        #endif
        /* -----------------------------------------------            /* -----------------------------------------------
         * Populate the parameters for the SMC handler. We             * Populate the parameters for the SMC handler. We
         * already have x0-x4 in place. x5 will point to a             * already have x0-x4 in place. x5 will point to a
         * cookie (not used now). x6 will point to the con             * cookie (not used now). x6 will point to the con
         * structure (SP_EL3) and x7 will contain flags we |           * structure (SP_EL2) and x7 will contain flags we
         * to pass to the handler.                                     * to pass to the handler.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        mov     x5, xzr                                               mov     x5, xzr
        mov     x6, sp                                                mov     x6, sp

        /* -----------------------------------------------            /* -----------------------------------------------
         * Restore the saved C runtime stack value which w             * Restore the saved C runtime stack value which w
         * become the new SP_EL0 i.e. EL3 runtime stack. I |           * become the new SP_EL0 i.e. EL2 runtime stack. I
         * saved in the 'cpu_context' structure prior to t             * saved in the 'cpu_context' structure prior to t
         * ERET from EL3.                                  |           * ERET from EL2.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        ldr     x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTI            ldr     x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTI

        /* ---------------------------------------------              /* ---------------------------------------------
         * Switch back to SP_EL0 for the C runtime stack.              * Switch back to SP_EL0 for the C runtime stack.
         * ---------------------------------------------               * ---------------------------------------------
         */                                                            */
        msr     spsel, #MODE_SP_EL0                                   msr     spsel, #MODE_SP_EL0
        mov     sp, x12                                               mov     sp, x12

        /* -----------------------------------------------            /* -----------------------------------------------
         * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case t |           * Save the SPSR_EL2, ELR_EL2, & SCR_EL2 in case t
         * is a world switch during SMC handling.                      * is a world switch during SMC handling.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        mrs     x16, spsr_el3                              |          mrs     x16, spsr_el2
        mrs     x17, elr_el3                               |          mrs     x17, elr_el2
        mrs     x18, scr_el3                                          mrs     x18, scr_el3
        stp     x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_            stp     x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_
        str     x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_E            str     x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_E

        /* Copy SCR_EL3.NS bit to the flag to indicate cal |          /* Copy SCR_EL2.NS bit to the flag to indicate cal
        bfi     x7, x18, #0, #1                                       bfi     x7, x18, #0, #1

        /* -----------------------------------------------            /* -----------------------------------------------
         * Go to BL1 SMC handler.                                      * Go to BL1 SMC handler.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        bl      bl1_smc_handler                                       bl      bl1_smc_handler

        /* -----------------------------------------------            /* -----------------------------------------------
         * Do the transition to next BL image.                         * Do the transition to next BL image.
         * -----------------------------------------------             * -----------------------------------------------
         */                                                            */
        b       el3_exit                                   |          b       el2_exit
Last Author
garymorrison-arm
Last Edited
Jul 2 2021, 11:07 PM