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
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 @@
 	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 @@
 	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 @@
 	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 @@
 	 * 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 @@
 	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 @@
 
 *   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 @@
     -   `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 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 @@
 	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 @@
 	ret
 
 
+disable_debug_exceptions:
+	msr	daifset, #DAIF_DBG_BIT
+	ret
+
+
 read_daif:; .type read_daif, %function
 	mrs	x0, daif
 	ret