diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2018-02-02 15:34:10 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2018-02-08 18:21:42 -0600 |
commit | d5378d2a0d54793ee59cd460e465fd0471bdd703 (patch) | |
tree | 800467f2c73b98f79c3e3ec25f10a2d61b78dfb1 | |
parent | 92777d335ab3fe8e364014584b454ac48883993b (diff) | |
download | skiboot-d5378d2a0d54793ee59cd460e465fd0471bdd703.zip skiboot-d5378d2a0d54793ee59cd460e465fd0471bdd703.tar.gz skiboot-d5378d2a0d54793ee59cd460e465fd0471bdd703.tar.bz2 |
core/exception: beautify exception handler, add MCE-involved registers
Print DSISR and DAR, to help with deciphering machine check exceptions,
and improve the output a bit, decode NIP symbol, improve alignment, etc.
Also print a specific header for machine check, because we do expect to
see these if there is a hardware failure.
Before:
[ 0.005968779,3] ***********************************************
[ 0.005974102,3] Unexpected exception 200 !
[ 0.005978696,3] SRR0 : 000000003002ad80 SRR1 : 9000000000001000
[ 0.005985239,3] HSRR0: 00000000300027b4 HSRR1: 9000000030001000
[ 0.005991782,3] LR : 000000003002ad80 CTR : 0000000000000000
[ 0.005998130,3] CFAR : 00000000300b58bc
[ 0.006002769,3] CR : 40000004 XER: 20000000
[ 0.006008069,3] GPR00: 000000003002ad80 GPR16: 0000000000000000
[ 0.006015170,3] GPR01: 0000000031c03bd0 GPR17: 0000000000000000
[...]
After:
[ 0.003287941,3] ***********************************************
[ 0.003561769,3] Fatal MCE at 000000003002ad80 .nvram_init+0x24
[ 0.003579628,3] CFAR : 00000000300b5964
[ 0.003584268,3] SRR0 : 000000003002ad80 SRR1 : 9000000000001000
[ 0.003590812,3] HSRR0: 00000000300027b4 HSRR1: 9000000030001000
[ 0.003597355,3] DSISR: 00000000 DAR : 0000000000000000
[ 0.003603480,3] LR : 000000003002ad68 CTR : 0000000030093d80
[ 0.003609930,3] CR : 40000004 XER : 20000000
[ 0.003615698,3] GPR00: 00000000300149e8 GPR16: 0000000000000000
[ 0.003622799,3] GPR01: 0000000031c03bc0 GPR17: 0000000000000000
[...]
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | asm/asm-offsets.c | 2 | ||||
-rw-r--r-- | asm/head.S | 4 | ||||
-rw-r--r-- | core/exceptions.c | 39 | ||||
-rw-r--r-- | include/stack.h | 2 |
4 files changed, 44 insertions, 3 deletions
diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c index 060eb31..7119950 100644 --- a/asm/asm-offsets.c +++ b/asm/asm-offsets.c @@ -81,6 +81,7 @@ int main(void) OFFSET(STACK_CR, stack_frame, cr); OFFSET(STACK_XER, stack_frame, xer); + OFFSET(STACK_DSISR, stack_frame, dsisr); OFFSET(STACK_CTR, stack_frame, ctr); OFFSET(STACK_LR, stack_frame, lr); OFFSET(STACK_PC, stack_frame, pc); @@ -89,6 +90,7 @@ int main(void) OFFSET(STACK_SRR1, stack_frame, srr1); OFFSET(STACK_HSRR0, stack_frame, hsrr0); OFFSET(STACK_HSRR1, stack_frame, hsrr1); + OFFSET(STACK_DAR, stack_frame, dar); DEFINE(STACK_FRAMESIZE, sizeof(struct stack_frame)); return 0; @@ -210,6 +210,10 @@ _exception: std %r4,STACK_SRR1(%r1) std %r5,STACK_HSRR0(%r1) std %r6,STACK_HSRR1(%r1) + mfspr %r3,SPR_DSISR + mfspr %r4,SPR_DAR + stw %r3,STACK_DSISR(%r1) + std %r4,STACK_DAR(%r1) mr %r3,%r1 LOAD_IMM64(%r4, SKIBOOT_BASE) LOAD_IMM32(%r5, exception_entry_foo - __head) diff --git a/core/exceptions.c b/core/exceptions.c index c4acf85..4880fa2 100644 --- a/core/exceptions.c +++ b/core/exceptions.c @@ -21,17 +21,19 @@ #include <cpu.h> #define REG "%016llx" +#define REG32 "%08x" #define REGS_PER_LINE 4 static void dump_regs(struct stack_frame *stack) { unsigned int i; + prerror("CFAR : "REG"\n", stack->cfar); prerror("SRR0 : "REG" SRR1 : "REG"\n", stack->srr0, stack->srr1); prerror("HSRR0: "REG" HSRR1: "REG"\n", stack->hsrr0, stack->hsrr1); + prerror("DSISR: "REG32" DAR : "REG"\n", stack->dsisr, stack->dar); 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); + prerror("CR : "REG32" XER : "REG32"\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]); @@ -42,8 +44,39 @@ void exception_entry(struct stack_frame *stack) __noreturn; void exception_entry(struct stack_frame *stack) { + const size_t max = 320; + char buf[max]; + size_t l; + prerror("***********************************************\n"); - prerror("Unexpected exception %llx !\n", stack->type); + if (stack->type == 0x200) { + l = 0; + l += snprintf(buf + l, max - l, "Fatal MCE at "REG" ", stack->srr0); + l += snprintf_symbol(buf + l, max - l, stack->srr0); + prerror("%s\n", buf); + } else { + uint64_t nip; + switch (stack->type) { + case 0x500: + case 0x980: + case 0xe00: + case 0xe20: + case 0xe40: + case 0xe60: + case 0xe80: + case 0xea0: + case 0xf80: + nip = stack->hsrr0; + break; + default: + nip = stack->srr0; + break; + } + l = 0; + l += snprintf(buf + l, max - l, "Fatal Exception 0x%llx at "REG" ", stack->type, nip); + l += snprintf_symbol(buf + l, max - l, nip); + prerror("%s\n", buf); + } dump_regs(stack); abort(); } diff --git a/include/stack.h b/include/stack.h index e50b34f..df08ac1 100644 --- a/include/stack.h +++ b/include/stack.h @@ -86,6 +86,7 @@ struct stack_frame { */ uint32_t cr; uint32_t xer; + uint32_t dsisr; uint64_t ctr; uint64_t lr; uint64_t pc; @@ -94,6 +95,7 @@ struct stack_frame { uint64_t srr1; uint64_t hsrr0; uint64_t hsrr1; + uint64_t dar; } __attribute__((aligned(16))); /* Backtrace */ |