[Skiboot] [PATCH 2/2] exceptions: Catch exceptions at boot time

Benjamin Herrenschmidt benh at kernel.crashing.org
Fri Mar 27 16:11:40 AEDT 2015


And print some informations about GPR state, backtrace, etc...

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 asm/asm-offsets.c |  2 ++
 asm/head.S        | 91 ++++++++++++++++++++++++++++++++++++++++++++-----------
 core/exceptions.c | 22 ++++++--------
 include/stack.h   |  2 ++
 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 740adbf..651c8fb 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 at ha;	\
@@ -110,6 +103,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)
@@ -129,7 +130,6 @@ hir_trigger:
 	EXCEPTION(0xe00)
 	EXCEPTION(0xe20)
 	EXCEPTION(0xe40)
-	EXCEPTION(0xe50)
 	EXCEPTION(0xe60)
 	EXCEPTION(0xf00)
 	EXCEPTION(0xf20)
@@ -141,15 +141,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 */




More information about the Skiboot mailing list