From 3738274dc1b40ad846d41d7bfd6a597bcfba9e70 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Mon, 18 Nov 2013 17:26:59 +0000 Subject: [PATCH] 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 --- bl1/aarch64/bl1_arch_setup.c | 12 ++++++++++-- bl31/aarch64/bl31_arch_setup.c | 13 ++++++++++--- common/psci/psci_afflvl_suspend.c | 3 +++ common/psci/psci_private.h | 1 + docs/change-log.md | 3 +++ docs/user-guide.md | 4 +++- include/aarch64/arch_helpers.h | 2 ++ lib/arch/aarch64/misc_helpers.S | 13 +++++++++++++ 8 files changed, 45 insertions(+), 6 deletions(-) diff --git a/bl1/aarch64/bl1_arch_setup.c b/bl1/aarch64/bl1_arch_setup.c index d4be9d6b..7085f778 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 f6fa088f..238af7bd 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 030f15dd..9a2c0cfb 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 48d40d0f..6505adf3 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 1f2d12c4..61499c78 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 debda445..45e850b2 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 348d5452..b571a5db 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 8c1f7400..05e90f95 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 -- 2.30.2