aboutsummaryrefslogtreecommitdiff
path: root/asm
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2019-01-08 00:04:23 +1000
committerStewart Smith <stewart@linux.ibm.com>2019-02-13 14:36:43 +1100
commit75669cb37067b52f80f43858a2eb9fac69b451ee (patch)
treecececd1cfcd926c550d3ca644a3d2ba7d967b1c6 /asm
parentebb814a80369adee82a509d50d41d56674ea68e4 (diff)
downloadskiboot-75669cb37067b52f80f43858a2eb9fac69b451ee.zip
skiboot-75669cb37067b52f80f43858a2eb9fac69b451ee.tar.gz
skiboot-75669cb37067b52f80f43858a2eb9fac69b451ee.tar.bz2
asm/head: provide asm support for interrupts to be returned from
This adds the redzone to the interrupt stack, and code to restore registers. This can be used for a number of things. Initially it will be used to recover from system reset interrupts, it could later be used to handle recoverable machine checks, use the decrementer to implement a watchdog, handle HMI interrupts at boot, and to implement virtual memory. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'asm')
-rw-r--r--asm/asm-offsets.c6
-rw-r--r--asm/head.S89
2 files changed, 77 insertions, 18 deletions
diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c
index 45f4243..0aea93d 100644
--- a/asm/asm-offsets.c
+++ b/asm/asm-offsets.c
@@ -28,6 +28,11 @@
#define OFFSET(sym, str, mem) \
DEFINE(sym, offsetof(struct str, mem))
+/*
+ * 64-bit ELF ABI specifies 288 byte redzone size.
+ */
+#define REDZONE_SIZE 288
+
int main(void);
int main(void)
@@ -95,6 +100,7 @@ int main(void)
OFFSET(STACK_HSRR1, stack_frame, hsrr1);
OFFSET(STACK_DAR, stack_frame, dar);
DEFINE(STACK_FRAMESIZE, sizeof(struct stack_frame));
+ DEFINE(INT_FRAMESIZE, (sizeof(struct stack_frame) + REDZONE_SIZE));
return 0;
}
diff --git a/asm/head.S b/asm/head.S
index 8006025..16ebf93 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -162,9 +162,23 @@ hdat_entry:
.= 0x1e00
_exception:
- stdu %r1,-STACK_FRAMESIZE(%r1)
+ stdu %r1,-INT_FRAMESIZE(%r1)
std %r3,STACK_CFAR(%r1)
std %r4,STACK_TYPE(%r1)
+ mfspr %r3,SPR_SRR0
+ mfspr %r4,SPR_SRR1
+ std %r3,STACK_SRR0(%r1)
+ std %r4,STACK_SRR1(%r1)
+ mfspr %r3,SPR_DSISR
+ mfspr %r4,SPR_DAR
+ stw %r3,STACK_DSISR(%r1)
+ std %r4,STACK_DAR(%r1)
+ mfmsr %r3
+ std %r3,STACK_MSR(%r1)
+ mfspr %r3,SPR_HSRR0
+ mfspr %r4,SPR_HSRR1
+ std %r3,STACK_HSRR0(%r1)
+ std %r4,STACK_HSRR1(%r1)
mfsprg0 %r3
mfsprg1 %r4
SAVE_GPR(0,%r1)
@@ -207,29 +221,68 @@ _exception:
stw %r4,STACK_XER(%r1)
std %r5,STACK_CTR(%r1)
std %r6,STACK_LR(%r1)
- mfspr %r3,SPR_SRR0
- mfspr %r4,SPR_SRR1
- mfspr %r5,SPR_HSRR0
- mfspr %r6,SPR_HSRR1
- std %r3,STACK_SRR0(%r1)
- std %r4,STACK_SRR1(%r1)
- std %r5,STACK_HSRR0(%r1)
- std %r6,STACK_HSRR1(%r1)
- mfspr %r3,SPR_DSISR
- mfspr %r4,SPR_DAR
- mfmsr %r5
- stw %r3,STACK_DSISR(%r1)
- std %r4,STACK_DAR(%r1)
- std %r5,STACK_MSR(%r1)
mr %r3,%r1
LOAD_IMM64(%r4, SKIBOOT_BASE)
LOAD_IMM32(%r5, exception_entry_foo - __head)
add %r4,%r4,%r5
mtctr %r4
- bctrl
- b .
+ bctr
exception_entry_foo:
- b exception_entry
+ bl exception_entry
+ /* Restore HSRRs in case a NMI interrupted an HSRR-live section
+ * and the NMI uses HSRRs for something. Possibly does not happen
+ * in current skiboot code, but good to be careful.
+ */
+ ld %r3,STACK_HSRR0(%r1)
+ ld %r4,STACK_HSRR1(%r1)
+ mtspr SPR_HSRR0,%r3
+ mtspr SPR_HSRR1,%r4
+ lwz %r3,STACK_CR(%r1)
+ lwz %r4,STACK_XER(%r1)
+ ld %r5,STACK_CTR(%r1)
+ ld %r6,STACK_LR(%r1)
+ mtcr %r3
+ mtxer %r4
+ mtctr %r5
+ mtlr %r6
+ REST_GPR(0,%r1)
+ REST_GPR(2,%r1)
+ REST_GPR(4,%r1)
+ REST_GPR(5,%r1)
+ REST_GPR(6,%r1)
+ REST_GPR(7,%r1)
+ REST_GPR(8,%r1)
+ REST_GPR(9,%r1)
+ REST_GPR(10,%r1)
+ REST_GPR(11,%r1)
+ REST_GPR(12,%r1)
+ REST_GPR(13,%r1)
+ REST_GPR(14,%r1)
+ REST_GPR(15,%r1)
+ REST_GPR(16,%r1)
+ REST_GPR(17,%r1)
+ REST_GPR(18,%r1)
+ REST_GPR(19,%r1)
+ REST_GPR(20,%r1)
+ REST_GPR(21,%r1)
+ REST_GPR(22,%r1)
+ REST_GPR(23,%r1)
+ REST_GPR(24,%r1)
+ REST_GPR(25,%r1)
+ REST_GPR(26,%r1)
+ REST_GPR(27,%r1)
+ REST_GPR(28,%r1)
+ REST_GPR(29,%r1)
+ REST_GPR(30,%r1)
+ REST_GPR(31,%r1)
+ ld %r3,STACK_SRR0(%r1)
+ mtspr SPR_SRR0,%r3
+ ld %r3,STACK_SRR1(%r1)
+ mtspr SPR_SRR1,%r3
+ REST_GPR(3,%r1)
+ addi %r1,%r1,INT_FRAMESIZE
+ rfid
+ b .
.= EXCEPTION_VECTORS_END
/* This is the OPAL branch table. It's populated at boot time