Hi Sean
> From: Sean Anderson [mailto:[email protected]]
> Sent: Wednesday, December 18, 2019 10:32 AM
> To: [email protected]
> Cc: Rick Jian-Zhi Chen(陳建志)
> Subject: [PATCH] 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 <[email protected]>
> ---
> arch/riscv/Kconfig | 3 +++
> arch/riscv/cpu/mtrap.S | 3 ++-
> arch/riscv/lib/interrupts.c | 50 +++++++++++++++++++++++++++++--------
> 3 files changed, 44 insertions(+), 12 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index
> 85e15ebffa..3338b788f8 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
> 407ecfa9c0..e40c7bd3f4 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
> 3b25c5b7a7..0f1e5123d2 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 <[email protected]>
> + *
> + * Copyright (C) 2019 Sean Anderson <[email protected]>
> */
>
> #include <common.h>
> @@ -13,7 +15,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",
> @@ -34,14 +63,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("PC: " REG_FMT " TVAL: " REG_FMT "\n", epc, tval);
Please modify PC as EPC.
LGTM.
Other than that,
Thanks
Rick
> + show_regs(regs);
> hang();
> }
>
> @@ -65,7 +93,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;
>
> @@ -83,11 +111,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;
> --
> 2.23.0
>