summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Lejeune <gerald.lejeune@st.com>2016-03-22 09:29:23 +0100
committerGerald Lejeune <gerald.lejeune@st.com>2016-03-30 17:26:23 +0200
commitadb4fcfb4c515a9b9af68d386ed1350505480655 (patch)
tree9087d2aa75bc34f41290504025576434a1947786
parent6b1ca8f35802fddc530e1a5f2be7b82ddbab6917 (diff)
Enable asynchronous abort exceptions during boot
Asynchronous abort exceptions generated by the platform during cold boot are not taken in EL3 unless SCR_EL3.EA is set. Therefore EA bit is set along with RES1 bits in early BL1 and BL31 architecture initialisation. Further write accesses to SCR_EL3 preserve these bits during cold boot. A build flag controls SCR_EL3.EA value to keep asynchronous abort exceptions being trapped by EL3 after cold boot or not. For further reference SError Interrupts are also known as asynchronous external aborts. On Cortex-A53 revisions below r0p2, asynchronous abort exceptions are taken in EL3 whatever the SCR_EL3.EA value is. Fixes arm-software/tf-issues#368 Signed-off-by: Gerald Lejeune <gerald.lejeune@st.com>
-rw-r--r--bl1/aarch64/bl1_arch_setup.c2
-rw-r--r--bl31/aarch64/bl31_arch_setup.c3
-rw-r--r--common/context_mgmt.c5
-rw-r--r--docs/firmware-design.md5
-rw-r--r--docs/user-guide.md3
-rw-r--r--include/common/el3_common_macros.S11
6 files changed, 21 insertions, 8 deletions
diff --git a/bl1/aarch64/bl1_arch_setup.c b/bl1/aarch64/bl1_arch_setup.c
index 6a3f0623..61c01e19 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 edf10188..0871b419 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 68ec8945..586d42a4 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 54c50680..fe3c3f03 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 ea10a81e..315e7468 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 0cd85c34..ba80d95d 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