aboutsummaryrefslogtreecommitdiff
path: root/src/arch/arm64/transition_asm.S
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2019-12-03 22:47:01 -0800
committerPatrick Georgi <pgeorgi@google.com>2019-12-05 17:57:58 +0000
commitbb345abbfc999f70e3f0f9739f13e1f45d5a0fe9 (patch)
treef8b652805a320d188ea995bc88bca8837118cfe9 /src/arch/arm64/transition_asm.S
parent31a5ff5e36ea499f87a8947875a067c843a45532 (diff)
arm64: Correctly unmask asynchronous SError interrupts
Arm CPUs have always had an odd feature that allows you to mask not only true interrupts, but also "external aborts" (memory bus errors from outside the CPU). CPUs usually have all of these masked after reset, which we quickly learned was a bad idea back when bringing up the first arm32 systems in coreboot. Masking external aborts means that if any of your firmware code does an illegal memory access, you will only see it once the kernel comes up and unmasks the abort (not when it happens). Therefore, we always unmask everything in early bootblock assembly code. When arm64 came around, it had very similar masking bits and we did the same there, thinking the issue resolved. Unfortunately Arm, in their ceaseless struggle for more complexity, decided that having a single bit to control this masking behavior is no longer enough: on AArch64, in addition to the PSTATE.DAIF bits that are analogous to arm32's CPSR, there are additional bits in SCR_EL3 that can override the PSTATE setting for some but not all cases (makes perfect sense, I know...). When aborts are unmasked in PSTATE, but SCR.EA is not set, then synchronous external aborts will cause an exception while asynchronous external aborts will not. It turns out we never intialize SCR in coreboot and on RK3399 it comes up with all zeroes (even the reserved-1 bits, which is super weird). If you get an asynchronous external abort in coreboot it will silently hide in the CPU until BL31 enables SCR.EA before it has its own console handlers registered and silently hangs. This patch resolves the issue by also initializing SCR to a known good state early in the bootblock. It also cleans up some bit defintions and slightly reworks the DAIF unmasking... it doesn't actually make that much sense to unmask anything before our console and exception handlers are up. The new code will mask everything until the exception handler is installed and then unmask it, so that if there was a super early external abort we could still see it. (Of course there are still dozens of other processor exceptions that could happen which we have no way to mask.) Change-Id: I5266481a7aaf0b72aca8988accb671d92739af6f Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37463 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Diffstat (limited to 'src/arch/arm64/transition_asm.S')
-rw-r--r--src/arch/arm64/transition_asm.S5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/arch/arm64/transition_asm.S b/src/arch/arm64/transition_asm.S
index 718832b421..bdb412f36d 100644
--- a/src/arch/arm64/transition_asm.S
+++ b/src/arch/arm64/transition_asm.S
@@ -154,7 +154,7 @@ ENDPROC(exc_exit)
/*
* exception_init_asm: Initialize VBAR and point SP_EL3 to exception stack.
- * x0 = end of exception stack
+ * Also unmask aborts now that we can report them. x0 = end of exception stack
*/
ENTRY(exception_init_asm)
msr SPSel, #SPSR_USE_H
@@ -163,6 +163,9 @@ ENTRY(exception_init_asm)
adr x0, exc_vectors
msr vbar_el3, x0
+
+ msr DAIFClr, #0xf
+
dsb sy
isb
ret