diff --git a/bl1/aarch64/bl1_arch_setup.c b/bl1/aarch64/bl1_arch_setup.c index 6a3f06231..61c01e19a 100644 --- a/bl1/aarch64/bl1_arch_setup.c +++ b/bl1/aarch64/bl1_arch_setup.c @@ -38,7 +38,7 @@ void bl1_arch_setup(void) { /* Set the next EL to be AArch64 */ - write_scr_el3(SCR_RES1_BITS | SCR_RW_BIT); + write_scr_el3(read_scr_el3() | SCR_RW_BIT); } /******************************************************************************* diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c index edf10188d..0871b4195 100644 --- a/bl31/aarch64/bl31_arch_setup.c +++ b/bl31/aarch64/bl31_arch_setup.c @@ -43,9 +43,6 @@ ******************************************************************************/ void bl31_arch_setup(void) { - /* Set the RES1 bits in the SCR_EL3 */ - write_scr_el3(SCR_RES1_BITS); - /* Program the counter frequency */ write_cntfrq_el0(plat_get_syscnt_freq()); diff --git a/common/context_mgmt.c b/common/context_mgmt.c index 68ec89456..586d42a49 100644 --- a/common/context_mgmt.c +++ b/common/context_mgmt.c @@ -111,6 +111,11 @@ static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t if (EP_GET_ST(ep->h.attr)) scr_el3 |= SCR_ST_BIT; +#ifndef HANDLE_EA_EL3_FIRST + /* Explicitly stop to trap aborts from lower exception levels. */ + scr_el3 &= ~SCR_EA_BIT; +#endif + #if IMAGE_BL31 /* * IRQ/FIQ bits only need setting if interrupt routing diff --git a/docs/firmware-design.md b/docs/firmware-design.md index 54c506807..fe3c3f032 100644 --- a/docs/firmware-design.md +++ b/docs/firmware-design.md @@ -174,8 +174,9 @@ BL1 performs minimal architectural initialization as follows. `SCTLR_EL3.A` and `SCTLR_EL3.SA` bits. Exception endianness is set to little-endian by clearing the `SCTLR_EL3.EE` bit. - - `SCR_EL3`. The register width of the next lower exception level is set to - AArch64 by setting the `SCR.RW` bit. + - `SCR_EL3`. The register width of the next lower exception level is set + to AArch64 by setting the `SCR.RW` bit. The `SCR.EA` bit is set to trap + both External Aborts and SError Interrupts in EL3. - `CPTR_EL3`. Accesses to the `CPACR_EL1` register from EL1 or EL2, or the `CPTR_EL2` register from EL2 are configured to not trap to EL3 by diff --git a/docs/user-guide.md b/docs/user-guide.md index ea10a81ef..315e74689 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -439,6 +439,9 @@ performed. where applicable). Defaults to a string that contains the time and date of the compilation. +* `HANDLE_EA_EL3_FIRST`: When defined External Aborts and SError Interrupts + will be always trapped in EL3 i.e. in BL31 at runtime. + #### ARM development platform specific build options * `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options: diff --git a/include/common/el3_common_macros.S b/include/common/el3_common_macros.S index 0cd85c342..ba80d95d0 100644 --- a/include/common/el3_common_macros.S +++ b/include/common/el3_common_macros.S @@ -70,8 +70,15 @@ isb /* --------------------------------------------------------------------- - * Enable the SError interrupt now that the exception vectors have been - * setup. + * Early set RES1 bits in SCR_EL3. Set EA bit as well to catch both + * External Aborts and SError Interrupts in EL3. + * --------------------------------------------------------------------- + */ + mov x0, #(SCR_RES1_BITS | SCR_EA_BIT) + msr scr_el3, x0 + /* --------------------------------------------------------------------- + * Enable External Aborts and SError Interrupts now that the exception + * vectors have been setup. * --------------------------------------------------------------------- */ msr daifclr, #DAIF_ABT_BIT