From 7803a4e590a0fadece410bf3b0b43ff4522d4474 Mon Sep 17 00:00:00 2001 From: Mark Holden Date: Mon, 20 Dec 2021 09:49:33 -0800 Subject: [PATCH] arch: riscv: ARCH_EXCEPT macro Enable ARCH_EXCEPT macro for non-usermode scenario for RISC-V Macro will now raise an illegal instruction exception so that mepc will hold expected value in exception handler, and generated coredump can reconstruct the failing stack Coredump tests running on renode (for RISC-V) can now utilize fatal error path through k_panic Signed-off-by: Mark Holden --- arch/riscv/core/fatal.c | 10 +++++++++- include/arch/riscv/arch.h | 2 -- include/arch/riscv/error.h | 12 +++++++++++- tests/subsys/debug/coredump/src/main.c | 7 ++----- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index a6791d4b833..eaaca8639d2 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -119,7 +119,15 @@ void _Fault(z_arch_esf_t *esf) LOG_ERR(" mtval: %lx", mtval); #endif - z_riscv_fatal_error(K_ERR_CPU_EXCEPTION, esf); + unsigned int reason = K_ERR_CPU_EXCEPTION; + +#if !defined(CONFIG_USERSPACE) + if (esf->t5 == ARCH_EXCEPT_MARKER) { + reason = esf->t6; + } +#endif + + z_riscv_fatal_error(reason, esf); } #ifdef CONFIG_USERSPACE diff --git a/include/arch/riscv/arch.h b/include/arch/riscv/arch.h index 30272905832..7a889d13666 100644 --- a/include/arch/riscv/arch.h +++ b/include/arch/riscv/arch.h @@ -368,9 +368,7 @@ static inline uint64_t arch_k_cycle_get_64(void) return sys_clock_cycle_get_64(); } -#ifdef CONFIG_USERSPACE #include -#endif /* CONFIG_USERSPACE */ #ifdef __cplusplus } diff --git a/include/arch/riscv/error.h b/include/arch/riscv/error.h index 935f9f67403..eed3374df6f 100644 --- a/include/arch/riscv/error.h +++ b/include/arch/riscv/error.h @@ -46,8 +46,18 @@ extern "C" { CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ \ } while (false) #else +/* + * Raise an illegal instruction exception so that mepc will hold expected value in + * exception handler, and generated coredump can reconstruct the failing stack. + * Store reason_p in register t6, marker in t5 + */ +#define ARCH_EXCEPT_MARKER 0x00DEAD00 #define ARCH_EXCEPT(reason_p) do { \ - z_impl_user_fault(reason_p); \ + __asm__ volatile("addi t5, %[marker], 0" \ + : : [marker] "r" (ARCH_EXCEPT_MARKER)); \ + __asm__ volatile("addi t6, %[reason], 0" \ + : : [reason] "r" (reason_p)); \ + __asm__ volatile("unimp"); \ } while (false) #endif diff --git a/tests/subsys/debug/coredump/src/main.c b/tests/subsys/debug/coredump/src/main.c index 812b0d61420..9b01aae966e 100644 --- a/tests/subsys/debug/coredump/src/main.c +++ b/tests/subsys/debug/coredump/src/main.c @@ -15,11 +15,8 @@ void func_3(uint32_t *addr) defined(CONFIG_BOARD_LONGAN_NANO) || \ defined(CONFIG_BOARD_LONGAN_NANO_LITE) ARG_UNUSED(addr); - /* Call coredump() directly so Renode doesn't pause execution */ - z_arch_esf_t esf; - struct k_thread kthread; - - coredump(1, &esf, &kthread); + /* Call k_panic() directly so Renode doesn't pause execution */ + k_panic(); #elif !defined(CONFIG_CPU_CORTEX_M) /* For null pointer reference */ *addr = 0;