aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2013-11-18 17:26:59 +0000
committerDan Handley <dan.handley@arm.com>2013-11-27 15:31:06 +0000
commit3738274dc1b40ad846d41d7bfd6a597bcfba9e70 (patch)
tree136c4d81d7b4f285ee37f1fdf674df5332a238d4
parent204aa03da7d8a34d5e06fba3ccc9e565ed01d305 (diff)
downloadarm-trusted-firmware-3738274dc1b40ad846d41d7bfd6a597bcfba9e70.tar.gz
Unmask SError and Debug exceptions.
Any asynchronous exception caused by the firmware should be handled in the firmware itself. For this reason, unmask SError exceptions (and Debug ones as well) on all boot paths. Also route external abort and SError interrupts to EL3, otherwise they will target EL1. Change-Id: I9c191d2d0dcfef85f265641c8460dfbb4d112092
-rw-r--r--bl1/aarch64/bl1_arch_setup.c12
-rw-r--r--bl31/aarch64/bl31_arch_setup.c13
-rw-r--r--common/psci/psci_afflvl_suspend.c3
-rw-r--r--common/psci/psci_private.h1
-rw-r--r--docs/change-log.md3
-rw-r--r--docs/user-guide.md4
-rw-r--r--include/aarch64/arch_helpers.h2
-rw-r--r--lib/arch/aarch64/misc_helpers.S13
8 files changed, 45 insertions, 6 deletions
diff --git a/bl1/aarch64/bl1_arch_setup.c b/bl1/aarch64/bl1_arch_setup.c
index d4be9d6..7085f77 100644
--- a/bl1/aarch64/bl1_arch_setup.c
+++ b/bl1/aarch64/bl1_arch_setup.c
@@ -48,11 +48,19 @@ void bl1_arch_setup(void)
write_sctlr(tmp_reg);
/*
- * Enable HVCs, route FIQs to EL3, set the next EL to be aarch64
+ * Enable HVCs, route FIQs to EL3, set the next EL to be AArch64, route
+ * external abort and SError interrupts to EL3
*/
- tmp_reg = SCR_RES1_BITS | SCR_RW_BIT | SCR_HCE_BIT | SCR_FIQ_BIT;
+ tmp_reg = SCR_RES1_BITS | SCR_RW_BIT | SCR_HCE_BIT | SCR_EA_BIT |
+ SCR_FIQ_BIT;
write_scr(tmp_reg);
+ /*
+ * Enable SError and Debug exceptions
+ */
+ enable_serror();
+ enable_debug_exceptions();
+
/* Do not trap coprocessor accesses from lower ELs to EL3 */
write_cptr_el3(0);
diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c
index f6fa088..238af7b 100644
--- a/bl31/aarch64/bl31_arch_setup.c
+++ b/bl31/aarch64/bl31_arch_setup.c
@@ -49,12 +49,19 @@ void bl31_arch_setup(void)
write_sctlr(tmp_reg);
/*
- * Enable HVCs, allow NS to mask CPSR.A, route FIQs to EL3, set the
- * next EL to be aarch64
+ * Enable HVCs, route FIQs to EL3, set the next EL to be AArch64, route
+ * external abort and SError interrupts to EL3
*/
- tmp_reg = SCR_RES1_BITS | SCR_RW_BIT | SCR_HCE_BIT | SCR_FIQ_BIT;
+ tmp_reg = SCR_RES1_BITS | SCR_RW_BIT | SCR_HCE_BIT | SCR_EA_BIT |
+ SCR_FIQ_BIT;
write_scr(tmp_reg);
+ /*
+ * Enable SError and Debug exceptions
+ */
+ enable_serror();
+ enable_debug_exceptions();
+
/* Do not trap coprocessor accesses from lower ELs to EL3 */
write_cptr_el3(0);
diff --git a/common/psci/psci_afflvl_suspend.c b/common/psci/psci_afflvl_suspend.c
index 030f15d..9a2c0cf 100644
--- a/common/psci/psci_afflvl_suspend.c
+++ b/common/psci/psci_afflvl_suspend.c
@@ -82,6 +82,8 @@ static int psci_afflvl0_suspend(unsigned long mpidr,
psci_secure_context[index].tcr = read_tcr();
psci_secure_context[index].ttbr = read_ttbr0();
psci_secure_context[index].vbar = read_vbar();
+ psci_secure_context[index].pstate =
+ read_daif() & (DAIF_ABT_BIT | DAIF_DBG_BIT);
/* Set the secure world (EL3) re-entry point after BL1 */
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
@@ -370,6 +372,7 @@ static unsigned int psci_afflvl0_suspend_finish(unsigned long mpidr,
* context in the right order.
*/
write_vbar(psci_secure_context[index].vbar);
+ write_daif(read_daif() | psci_secure_context[index].pstate);
write_mair(psci_secure_context[index].mair);
write_tcr(psci_secure_context[index].tcr);
write_ttbr0(psci_secure_context[index].ttbr);
diff --git a/common/psci/psci_private.h b/common/psci/psci_private.h
index 48d40d0..6505adf 100644
--- a/common/psci/psci_private.h
+++ b/common/psci/psci_private.h
@@ -64,6 +64,7 @@ typedef struct {
unsigned long tcr;
unsigned long ttbr;
unsigned long vbar;
+ unsigned long pstate;
} secure_context;
/*******************************************************************************
diff --git a/docs/change-log.md b/docs/change-log.md
index 1f2d12c..61499c7 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -17,6 +17,9 @@ Detailed changes since last release
* Fixed various GCC compiler warnings.
+* Unmask SError and Debug exceptions in the trusted firmware.
+ Also route external abort and SError interrupts to EL3.
+
ARM Trusted Firmware - version 0.2
==================================
diff --git a/docs/user-guide.md b/docs/user-guide.md
index debda44..45e850b 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -661,7 +661,9 @@ BL1 performs minimal architectural initialization as follows.
- `SCR`. Use of the HVC instruction from EL1 is enabled by setting the
`SCR.HCE` bit. FIQ exceptions are configured to be taken in EL3 by
setting the `SCR.FIQ` bit. The register width of the next lower
- exception level is set to AArch64 by setting the `SCR.RW` bit.
+ exception level is set to AArch64 by setting the `SCR.RW` bit. External
+ Aborts and SError Interrupts are configured to be taken in EL3 by
+ setting the `SCR.EA` bit.
- `CPTR_EL3`. Accesses to the `CPACR` from EL1 or EL2, or the `CPTR_EL2`
from EL2 are configured to not trap to EL3 by clearing the
diff --git a/include/aarch64/arch_helpers.h b/include/aarch64/arch_helpers.h
index 348d545..b571a5d 100644
--- a/include/aarch64/arch_helpers.h
+++ b/include/aarch64/arch_helpers.h
@@ -80,10 +80,12 @@ extern void dcsw_op_all(unsigned int);
extern void enable_irq(void);
extern void enable_fiq(void);
extern void enable_serror(void);
+extern void enable_debug_exceptions(void);
extern void disable_irq(void);
extern void disable_fiq(void);
extern void disable_serror(void);
+extern void disable_debug_exceptions(void);
extern unsigned long read_id_pfr1_el1(void);
extern unsigned long read_id_aa64pfr0_el1(void);
diff --git a/lib/arch/aarch64/misc_helpers.S b/lib/arch/aarch64/misc_helpers.S
index 8c1f740..05e90f9 100644
--- a/lib/arch/aarch64/misc_helpers.S
+++ b/lib/arch/aarch64/misc_helpers.S
@@ -39,6 +39,9 @@
.globl enable_serror
.globl disable_serror
+ .globl enable_debug_exceptions
+ .globl disable_debug_exceptions
+
.globl read_daif
.globl write_daif
@@ -110,6 +113,11 @@ enable_serror:; .type enable_serror, %function
ret
+enable_debug_exceptions:
+ msr daifclr, #DAIF_DBG_BIT
+ ret
+
+
disable_irq:; .type disable_irq, %function
msr daifset, #DAIF_IRQ_BIT
ret
@@ -125,6 +133,11 @@ disable_serror:; .type disable_serror, %function
ret
+disable_debug_exceptions:
+ msr daifset, #DAIF_DBG_BIT
+ ret
+
+
read_daif:; .type read_daif, %function
mrs x0, daif
ret