diff mbox series

core/exceptions: save current MSR in exception frame

Message ID 20181017144901.12967-1-npiggin@gmail.com
State Superseded
Headers show
Series core/exceptions: save current MSR in exception frame | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied
snowpatch_ozlabs/make_check success Test make_check on branch master

Commit Message

Nicholas Piggin Oct. 17, 2018, 2:49 p.m. UTC
Save and print the MSR of the interrupt context. This can be derived
from the interrupt type, SRR1, and other system register settings. But
it can be useful to quickly verify what's happening.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 asm/asm-offsets.c |  1 +
 asm/head.S        |  2 ++
 core/exceptions.c | 57 ++++++++++++++++++++++++++---------------------
 include/stack.h   |  1 +
 4 files changed, 35 insertions(+), 26 deletions(-)
diff mbox series

Patch

diff --git a/asm/asm-offsets.c b/asm/asm-offsets.c
index 3eac592d..45f42436 100644
--- a/asm/asm-offsets.c
+++ b/asm/asm-offsets.c
@@ -87,6 +87,7 @@  int main(void)
 	OFFSET(STACK_CTR,	stack_frame, ctr);
 	OFFSET(STACK_LR,	stack_frame, lr);
 	OFFSET(STACK_PC,	stack_frame, pc);
+	OFFSET(STACK_MSR,	stack_frame, msr);
 	OFFSET(STACK_CFAR,	stack_frame, cfar);
 	OFFSET(STACK_SRR0,	stack_frame, srr0);
 	OFFSET(STACK_SRR1,	stack_frame, srr1);
diff --git a/asm/head.S b/asm/head.S
index b7569d24..7968bb69 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -210,8 +210,10 @@  _exception:
 	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)
diff --git a/core/exceptions.c b/core/exceptions.c
index 4880fa24..ed92edfb 100644
--- a/core/exceptions.c
+++ b/core/exceptions.c
@@ -28,7 +28,7 @@  static void dump_regs(struct stack_frame *stack)
 {
 	unsigned int i;
 
-	prerror("CFAR : "REG"\n", stack->cfar);
+	prerror("CFAR : "REG" MSR  : "REG"\n", stack->cfar, stack->msr);
 	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);
@@ -44,40 +44,45 @@  void exception_entry(struct stack_frame *stack) __noreturn;
 
 void exception_entry(struct stack_frame *stack)
 {
+	uint64_t nip;
+	uint64_t msr;
 	const size_t max = 320;
 	char buf[max];
 	size_t l;
 
+	switch (stack->type) {
+	case 0x500:
+	case 0x980:
+	case 0xe00:
+	case 0xe20:
+	case 0xe40:
+	case 0xe60:
+	case 0xe80:
+	case 0xea0:
+	case 0xf80:
+		nip = stack->hsrr0;
+		msr = stack->hsrr1;
+		break;
+	default:
+		nip = stack->srr0;
+		msr = stack->srr1;
+		break;
+	}
+
 	prerror("***********************************************\n");
+	l = 0;
 	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);
+		l += snprintf(buf + l, max - l,
+			"Fatal MCE at "REG"   ", nip);
 	} 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);
+		l += snprintf(buf + l, max - l,
+			"Fatal Exception 0x%llx at "REG"  ", stack->type, nip);
 	}
+	l += snprintf_symbol(buf + l, max - l, nip);
+	l += snprintf(buf + l, max - l, "  MSR "REG, msr);
+	prerror("%s\n", buf);
 	dump_regs(stack);
+
 	abort();
 }
 
diff --git a/include/stack.h b/include/stack.h
index a41a4a91..7578cc34 100644
--- a/include/stack.h
+++ b/include/stack.h
@@ -98,6 +98,7 @@  struct stack_frame {
 	uint64_t	ctr;
 	uint64_t	lr;
 	uint64_t	pc;
+	uint64_t	msr;
 	uint64_t	cfar;
 	uint64_t	srr0;
 	uint64_t	srr1;