[Skiboot] [PATCH 3/3] core/exception: beautify exception handler, add MCE-involved registers

Nicholas Piggin npiggin at gmail.com
Fri Feb 2 16:34:10 AEDT 2018


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 at gmail.com>
---
 asm/asm-offsets.c |  2 ++
 asm/head.S        |  4 ++++
 core/exceptions.c | 39 ++++++++++++++++++++++++++++++++++++---
 include/stack.h   |  2 ++
 4 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c
index 060eb318b..71199503e 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;
diff --git a/asm/head.S b/asm/head.S
index e2ddc9151..fb4b95f73 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -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 c4acf85b2..4880fa242 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 e50b34f0d..df08ac13c 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 */
-- 
2.15.1



More information about the Skiboot mailing list