aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
authorSean Anderson <seanga2@gmail.com>2019-12-25 00:27:44 -0500
committerAndes <uboot@andestech.com>2020-02-10 14:51:08 +0800
commitfd1f6e9a0bc7ba536c19478b2fd8619ecda6ec3b (patch)
treecf45bbb908850abc89bf9b23cba29ed561e3f547 /arch/riscv
parentd9f1cee286c8d039e290f624baeeb133b8d47a21 (diff)
downloadu-boot-fd1f6e9a0bc7ba536c19478b2fd8619ecda6ec3b.zip
u-boot-fd1f6e9a0bc7ba536c19478b2fd8619ecda6ec3b.tar.gz
u-boot-fd1f6e9a0bc7ba536c19478b2fd8619ecda6ec3b.tar.bz2
riscv: Add option to print registers on exception
When debugging, it can be helpful to see more information about an unhandled exception. This patch adds an option to view the registers at the time of the trap, similar to the linux output on a kernel panic. Signed-off-by: Sean Anderson <seanga2@gmail.com> Reviewed-by: Rick Chen <rick@andestech.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Tested-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/Kconfig3
-rw-r--r--arch/riscv/cpu/mtrap.S3
-rw-r--r--arch/riscv/lib/interrupts.c50
3 files changed, 44 insertions, 12 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 85e15eb..3338b78 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -222,6 +222,9 @@ config XIP
from a NOR flash memory without copying the code to ram.
Say yes here if U-Boot boots from flash directly.
+config SHOW_REGS
+ bool "Show registers on unhandled exception"
+
config STACK_SIZE_SHIFT
int
default 14
diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S
index 407ecfa..e40c7bd 100644
--- a/arch/riscv/cpu/mtrap.S
+++ b/arch/riscv/cpu/mtrap.S
@@ -64,7 +64,8 @@ trap_entry:
SREG x31, 31 * REGBYTES(sp)
csrr a0, MODE_PREFIX(cause)
csrr a1, MODE_PREFIX(epc)
- mv a2, sp
+ csrr a2, MODE_PREFIX(tval)
+ mv a3, sp
jal handle_trap
csrw MODE_PREFIX(epc), a0
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 512dce06..074c70e 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -5,6 +5,8 @@
*
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
*/
#include <common.h>
@@ -14,7 +16,34 @@
#include <asm/system.h>
#include <asm/encoding.h>
-static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
+static void show_regs(struct pt_regs *regs)
+{
+#ifdef CONFIG_SHOW_REGS
+ printf("RA: " REG_FMT " SP: " REG_FMT " GP: " REG_FMT "\n",
+ regs->ra, regs->sp, regs->gp);
+ printf("TP: " REG_FMT " T0: " REG_FMT " T1: " REG_FMT "\n",
+ regs->tp, regs->t0, regs->t1);
+ printf("T2: " REG_FMT " S0: " REG_FMT " S1: " REG_FMT "\n",
+ regs->t2, regs->s0, regs->s1);
+ printf("A0: " REG_FMT " A1: " REG_FMT " A2: " REG_FMT "\n",
+ regs->a0, regs->a1, regs->a2);
+ printf("A3: " REG_FMT " A4: " REG_FMT " A5: " REG_FMT "\n",
+ regs->a3, regs->a4, regs->a5);
+ printf("A6: " REG_FMT " A7: " REG_FMT " S2: " REG_FMT "\n",
+ regs->a6, regs->a7, regs->s2);
+ printf("S3: " REG_FMT " S4: " REG_FMT " S5: " REG_FMT "\n",
+ regs->s3, regs->s4, regs->s5);
+ printf("S6: " REG_FMT " S7: " REG_FMT " S8: " REG_FMT "\n",
+ regs->s6, regs->s7, regs->s8);
+ printf("S9: " REG_FMT " S10: " REG_FMT " S11: " REG_FMT "\n",
+ regs->s9, regs->s10, regs->s11);
+ printf("T3: " REG_FMT " T4: " REG_FMT " T5: " REG_FMT "\n",
+ regs->t3, regs->t4, regs->t5);
+ printf("T6: " REG_FMT "\n", regs->t6);
+#endif
+}
+
+static void _exit_trap(ulong code, ulong epc, ulong tval, struct pt_regs *regs)
{
static const char * const exception_code[] = {
"Instruction address misaligned",
@@ -35,14 +64,13 @@ static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
"Store/AMO page fault",
};
- if (code < ARRAY_SIZE(exception_code)) {
- printf("exception code: %ld , %s , epc %lx , ra %lx\n",
- code, exception_code[code], epc, regs->ra);
- } else {
- printf("reserved exception code: %ld , epc %lx , ra %lx\n",
- code, epc, regs->ra);
- }
+ if (code < ARRAY_SIZE(exception_code))
+ printf("Unhandled exception: %s\n", exception_code[code]);
+ else
+ printf("Unhandled exception code: %ld\n", code);
+ printf("EPC: " REG_FMT " TVAL: " REG_FMT "\n", epc, tval);
+ show_regs(regs);
hang();
}
@@ -66,7 +94,7 @@ int disable_interrupts(void)
return 0;
}
-ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
+ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs)
{
ulong is_irq, irq;
@@ -84,11 +112,11 @@ ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
timer_interrupt(0); /* handle timer interrupt */
break;
default:
- _exit_trap(cause, epc, regs);
+ _exit_trap(cause, epc, tval, regs);
break;
};
} else {
- _exit_trap(cause, epc, regs);
+ _exit_trap(cause, epc, tval, regs);
}
return epc;