aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-27 16:11:40 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-31 15:42:37 +1100
commit989d8b68b63ba21a58fb96cd0b0a82505e669046 (patch)
tree74388ed44bae1f00319108dba9aeed1927208242
parente162dbe49d12603ed9663a16f3040fbe6fddb9e9 (diff)
downloadskiboot-989d8b68b63ba21a58fb96cd0b0a82505e669046.zip
skiboot-989d8b68b63ba21a58fb96cd0b0a82505e669046.tar.gz
skiboot-989d8b68b63ba21a58fb96cd0b0a82505e669046.tar.bz2
exceptions: Catch exceptions at boot time
And print some informations about GPR state, backtrace, etc... Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--asm/asm-offsets.c2
-rw-r--r--asm/head.S91
-rw-r--r--core/exceptions.c22
-rw-r--r--include/stack.h2
4 files changed, 87 insertions, 30 deletions
diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c
index 74f3124..6278c5c 100644
--- a/asm/asm-offsets.c
+++ b/asm/asm-offsets.c
@@ -85,6 +85,8 @@ int main(void)
OFFSET(STACK_CFAR, stack_frame, cfar);
OFFSET(STACK_SRR0, stack_frame, srr0);
OFFSET(STACK_SRR1, stack_frame, srr1);
+ OFFSET(STACK_HSRR0, stack_frame, hsrr0);
+ OFFSET(STACK_HSRR1, stack_frame, hsrr1);
DEFINE(STACK_FRAMESIZE, sizeof(struct stack_frame));
return 0;
diff --git a/asm/head.S b/asm/head.S
index 8d754c1..a2a8a9f 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -28,13 +28,6 @@
#define PPC_INST_SLEEP .long 0x4c0003a4
#define PPC_INST_RVWINKLE .long 0x4c0003e4
-#define EXCEPTION(nr) \
- .= nr; \
- mtsprg0 %r3; \
- mfspr %r3,SPR_CFAR; \
- b . ;
-
-
#define GET_STACK(stack_reg,pir_reg) \
sldi stack_reg,pir_reg,STACK_SHIFT; \
addis stack_reg,stack_reg,CPU_STACKS_OFFSET@ha; \
@@ -113,6 +106,14 @@ hir_trigger:
li %r25,0
b boot_entry
+#define EXCEPTION(nr) \
+ .= nr ;\
+ mtsprg0 %r3 ;\
+ mfspr %r3,SPR_CFAR ;\
+ mtsprg1 %r4 ;\
+ li %r4,nr ;\
+ b _exception
+
/* More exception stubs */
EXCEPTION(0x200)
EXCEPTION(0x300)
@@ -132,7 +133,6 @@ hir_trigger:
EXCEPTION(0xe00)
EXCEPTION(0xe20)
EXCEPTION(0xe40)
- EXCEPTION(0xe50)
EXCEPTION(0xe60)
EXCEPTION(0xf00)
EXCEPTION(0xf20)
@@ -144,15 +144,72 @@ hir_trigger:
EXCEPTION(0x1400)
EXCEPTION(0x1500)
EXCEPTION(0x1600)
- EXCEPTION(0x1700)
- EXCEPTION(0x1800)
- EXCEPTION(0x1900)
- EXCEPTION(0x1a00)
- EXCEPTION(0x1b00)
- EXCEPTION(0x1c00)
- EXCEPTION(0x1d00)
- EXCEPTION(0x1e00)
- EXCEPTION(0x1f00)
+
+ .= 0x1e00
+_exception:
+ std %r4,16(%r1)
+ stdu %r1,-STACK_FRAMESIZE(%r1)
+ std %r3,STACK_CFAR(%r1)
+ std %r4,STACK_TYPE(%r1)
+ mfsprg0 %r3
+ mfsprg1 %r4
+ 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)
+ SAVE_GPR(8,%r1)
+ SAVE_GPR(9,%r1)
+ SAVE_GPR(10,%r1)
+ SAVE_GPR(11,%r1)
+ SAVE_GPR(12,%r1)
+ SAVE_GPR(13,%r1)
+ SAVE_GPR(14,%r1)
+ SAVE_GPR(15,%r1)
+ SAVE_GPR(16,%r1)
+ SAVE_GPR(17,%r1)
+ SAVE_GPR(18,%r1)
+ SAVE_GPR(19,%r1)
+ SAVE_GPR(20,%r1)
+ SAVE_GPR(21,%r1)
+ SAVE_GPR(22,%r1)
+ SAVE_GPR(23,%r1)
+ SAVE_GPR(24,%r1)
+ SAVE_GPR(25,%r1)
+ SAVE_GPR(26,%r1)
+ SAVE_GPR(27,%r1)
+ SAVE_GPR(28,%r1)
+ SAVE_GPR(29,%r1)
+ SAVE_GPR(30,%r1)
+ SAVE_GPR(31,%r1)
+ mfcr %r3
+ mfxer %r4
+ mfctr %r5
+ mflr %r6
+ stw %r3,STACK_CR(%r1)
+ stw %r4,STACK_XER(%r1)
+ stw %r5,STACK_CTR(%r1)
+ stw %r5,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)
+ mr %r3,%r1
+ LOAD_IMM64(%r4, SKIBOOT_BASE)
+ LOAD_IMM32(%r5, exception_entry_foo - __head)
+ add %r4,%r4,%r5
+ mtctr %r4
+ bctrl
+ b .
+exception_entry_foo:
+ b exception_entry
.= 0x2000
/* This is the OPAL branch table. It's populated at boot time
diff --git a/core/exceptions.c b/core/exceptions.c
index 83efa36..8416190 100644
--- a/core/exceptions.c
+++ b/core/exceptions.c
@@ -28,18 +28,14 @@ static void dump_regs(struct stack_frame *stack)
{
unsigned int i;
- printf("SRR0 : "REG" SRR1 : "REG"\n", stack->srr0, stack->srr1);
- printf("HSRR0: "REG" HSRR1: "REG"\n", stack->srr0, stack->srr1);
- printf("CFAR : "REG" LR : "REG" CTR: "REG"\n",
- stack->cfar, stack->lr, stack->ctr);
- printf(" CR: %08x XER: %08x\n", stack->cr, stack->xer);
-
- for (i = 0; i < 32; i++) {
- if ((i % REGS_PER_LINE) == 0)
- printf("\nGPR%02d: ", i);
- printf(REG " ", stack->gpr[i]);
- }
- printf("\n");
+ prerror("SRR0 : "REG" SRR1 : "REG"\n", stack->srr0, stack->srr1);
+ prerror("HSRR0: "REG" HSRR1: "REG"\n", stack->srr0, stack->srr1);
+ prerror("LR : "REG" CTR : "REG"\n", stack->lr, stack->ctr);
+ prerror("CFAR : "REG"\n", stack->cfar);
+ prerror("CR : %08x XER: %08x\n", stack->cr, stack->xer);
+ for (i = 0; i < 16; i++)
+ prerror("GPR%02d: "REG" GPR%02d: "REG"\n",
+ i, stack->gpr[i], i + 16, stack->gpr[i + 16]);
}
/* Called from head.S, thus no prototype */
@@ -47,9 +43,9 @@ void exception_entry(struct stack_frame *stack) __noreturn;
void exception_entry(struct stack_frame *stack)
{
+ prerror("***********************************************\n");
prerror("Unexpected exception %llx !\n", stack->type);
dump_regs(stack);
- backtrace();
_abort();
}
diff --git a/include/stack.h b/include/stack.h
index 2f27a7b..0009ea9 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -90,6 +90,8 @@ struct stack_frame {
uint64_t cfar;
uint64_t srr0;
uint64_t srr1;
+ uint64_t hsrr0;
+ uint64_t hsrr1;
} __attribute__((aligned(16)));
/* Backtrace */