[coreboot-gerrit] Patch set updated for coreboot: arch/riscv: Improve and refactor trap handling diagnostics

Jonathan Neuschäfer (j.neuschaefer@gmx.net) gerrit at coreboot.org
Sat Aug 13 04:27:11 CEST 2016


Jonathan Neuschäfer (j.neuschaefer at gmx.net) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16016

-gerrit

commit ee9489ec65bebf6d5be2d0bc0587edade956ac5f
Author: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
Date:   Sat Aug 13 04:20:09 2016 +0200

    arch/riscv: Improve and refactor trap handling diagnostics
    
    Change-Id: I57032f958c88ea83a420e93b459df4f620799d84
    Signed-off-by: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
---
 src/arch/riscv/trap_handler.c | 134 +++++++++++++++++++++++-------------------
 1 file changed, 72 insertions(+), 62 deletions(-)

diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index 193be61..9f3f07f 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -84,81 +84,91 @@ void handle_supervisor_call(trapframe *tf) {
 	asm volatile("j supervisor_call_return");
 }
 
-void trap_handler(trapframe *tf) {
-	write_csr(mscratch, tf);
-	uintptr_t cause;
-	void *epc;
-	void *badAddr;
+static const char *const exception_names[] = {
+	"Instruction address misaligned",
+	"Instruction access fault",
+	"Illegal instruction",
+	"Breakpoint",
+	"Load address misaligned",
+	"Load access fault",
+	"Store address misaligned",
+	"Store access fault",
+	"Environment call from U-mode",
+	"Environment call from S-mode",
+	"Environment call from H-mode",
+	"Environment call from M-mode"
+};
 
-	// extract cause
-	asm("csrr %0, mcause" : "=r"(cause));
+static const char *mstatus_to_previous_mode(uintptr_t ms)
+{
+	switch (ms & MSTATUS_MPP) {
+		case 0x00000000: return "user";
+		case 0x00000800: return "supervisor";
+		case 0x00001000: return "hypervisor";
+		case 0x00001800: return "machine";
+	}
 
-	// extract faulting Instruction pc
-	epc = (void*) tf->epc;
+	return "unknown";
+}
 
-	// extract bad address
-	asm("csrr %0, mbadaddr" : "=r"(badAddr));
+static void print_trap_information(const trapframe *tf)
+{
+	const char *previous_mode;
+	bool mprv = !!(tf->status & MSTATUS_MPRV);
 
-	switch(cause) {
-		case 0:
-			printk(BIOS_DEBUG, "Trap: Instruction address misaligned\n");
-			break;
-		case 1:
-			printk(BIOS_DEBUG, "Trap: Instruction access fault\n");
-			printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
-			printk(BIOS_DEBUG, "Address: %p\n", badAddr);
-			break;
-		case 2:
-			printk(BIOS_DEBUG, "Trap: Illegal instruction\n");
-			printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
-			printk(BIOS_DEBUG, "Address: %p\n", badAddr);
-			break;
-		case 3:
-			printk(BIOS_DEBUG, "Trap: Breakpoint\n");
-			break;
-		case 4:
-			printk(BIOS_DEBUG, "Trap: Load address misaligned\n");
+	/* Leave some space around the trap message */
+	printk(BIOS_DEBUG, "\n");
+
+	if (tf->cause < ARRAY_SIZE(exception_names))
+		printk(BIOS_DEBUG, "Exception:          %s\n",
+				exception_names[tf->cause]);
+	else
+		printk(BIOS_DEBUG, "Trap:               Unknown cause %p\n",
+				(void *)tf->cause);
+
+	previous_mode = mstatus_to_previous_mode(read_csr(mstatus));
+	printk(BIOS_DEBUG, "Previous mode:      %s%s\n",
+			previous_mode, mprv? " (MPRV)":"");
+	printk(BIOS_DEBUG, "Bad instruction pc: %p\n", (void *)tf->epc);
+	printk(BIOS_DEBUG, "Bad address:        %p\n", (void *)tf->badvaddr);
+	printk(BIOS_DEBUG, "Stored ra:          %p\n", (void*) tf->gpr[1]);
+	printk(BIOS_DEBUG, "Stored sp:          %p\n", (void*) tf->gpr[2]);
+}
+
+void trap_handler(trapframe *tf) {
+	write_csr(mscratch, tf);
+
+	switch(tf->cause) {
+		case CAUSE_MISALIGNED_FETCH:
+		case CAUSE_FAULT_FETCH:
+		case CAUSE_ILLEGAL_INSTRUCTION:
+		case CAUSE_BREAKPOINT:
+		case CAUSE_FAULT_LOAD:
+		case CAUSE_FAULT_STORE:
+		case CAUSE_USER_ECALL:
+		case CAUSE_HYPERVISOR_ECALL:
+		case CAUSE_MACHINE_ECALL:
+			print_trap_information(tf);
+			break;
+		case CAUSE_MISALIGNED_LOAD:
+			print_trap_information(tf);
 			handle_misaligned_load(tf);
 			break;
-		case 5:
-			printk(BIOS_DEBUG, "Trap: Load access fault\n");
-			printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
-			printk(BIOS_DEBUG, "Load Address: %p\n", badAddr);
-			break;
-		case 6:
-			printk(BIOS_DEBUG, "Trap: Store address misaligned\n");
-			printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
-			printk(BIOS_DEBUG, "Store Address: %p\n", badAddr);
+		case CAUSE_MISALIGNED_STORE:
+			print_trap_information(tf);
 			handle_misaligned_store(tf);
 			break;
-		case 7:
-			printk(BIOS_DEBUG, "Trap: Store access fault\n");
-			printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
-			printk(BIOS_DEBUG, "Store Address: %p\n", badAddr);
-			break;
-		case 8:
-			printk(BIOS_DEBUG, "Trap: Environment call from U-mode\n");
-			break;
-		case 9:
-			// Don't print so we make console putchar calls look the way they should
-			// printk(BIOS_DEBUG, "Trap: Environment call from S-mode\n");
+		case CAUSE_SUPERVISOR_ECALL:
+			/* Don't print so we make console putchar calls look
+			   the way they should */
 			handle_supervisor_call(tf);
 			break;
-		case 10:
-			printk(BIOS_DEBUG, "Trap: Environment call from H-mode\n");
-			break;
-		case 11:
-			printk(BIOS_DEBUG, "Trap: Environment call from M-mode\n");
-			break;
 		default:
-			printk(BIOS_DEBUG, "Trap: Unknown cause %p\n",
-			       (void *)cause);
+			print_trap_information(tf);
 			break;
 	}
-	printk(BIOS_DEBUG, "Stored ra: %p\n", (void*) tf->gpr[1]);
-	printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
-	printk(BIOS_DEBUG, "looping...\n");
-	while(1);
+
+	die("Can't recover from trap. Halting.\n");
 }
 
 void handle_misaligned_load(trapframe *tf) {



More information about the coreboot-gerrit mailing list