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;