[Skiboot] [RFC PATCH 6/7] asm/head: provide asm support for interrupts to be returned from
Nicholas Piggin
npiggin at gmail.com
Fri Sep 21 18:05:10 AEST 2018
This adds the redzone to the interrupt stack, and code to restore
registers.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
asm/asm-offsets.c | 6 ++++
asm/head.S | 83 +++++++++++++++++++++++++++++++++++------------
core/exceptions.c | 5 ++-
3 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c
index 45f42436..85ead488 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 BE 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 7968bb69..9c2162c1 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -155,16 +155,32 @@ hdat_entry:
.= 0x1e00
_exception:
- stdu %r1,-STACK_FRAMESIZE(%r1)
+ stdu %r1,-INT_FRAMESIZE(%r1)
std %r3,STACK_CFAR(%r1)
std %r4,STACK_TYPE(%r1)
mfsprg0 %r3
mfsprg1 %r4
+ SAVE_GPR(3,%r1)
+ SAVE_GPR(4,%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
+ ori %r4,%r3,MSR_RI
+ mtmsrd %r4,1
+ std %r3,STACK_MSR(%r1)
+ mfspr %r3,SPR_HSRR0
+ mfspr %r4,SPR_HSRR1
+ std %r3,STACK_HSRR0(%r1)
+ std %r4,STACK_HSRR1(%r1)
SAVE_GPR(0,%r1)
SAVE_GPR(1,%r1)
SAVE_GPR(2,%r1)
- SAVE_GPR(3,%r1)
- SAVE_GPR(4,%r1)
SAVE_GPR(5,%r1)
SAVE_GPR(6,%r1)
SAVE_GPR(7,%r1)
@@ -200,29 +216,56 @@ _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
+ 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(3,%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)
+ addi %r1,%r1,INT_FRAMESIZE
+ hrfid
+ b .
.= EXCEPTION_VECTORS_END
/* This is the OPAL branch table. It's populated at boot time
diff --git a/core/exceptions.c b/core/exceptions.c
index be701f0f..e205ac6e 100644
--- a/core/exceptions.c
+++ b/core/exceptions.c
@@ -40,7 +40,7 @@ static void dump_regs(struct stack_frame *stack)
}
/* Called from head.S, thus no prototype */
-void exception_entry(struct stack_frame *stack) __noreturn;
+void exception_entry(struct stack_frame *stack);
void exception_entry(struct stack_frame *stack)
{
@@ -66,6 +66,9 @@ void exception_entry(struct stack_frame *stack)
default:
nip = stack->srr0;
msr = stack->srr1;
+ /* Set up to allow hrfid return */
+ mtspr(SPR_HSRR0, nip);
+ mtspr(SPR_HSRR1, msr);
break;
}
--
2.18.0
More information about the Skiboot
mailing list