arch: riscv: print callee-saved-registers in fatal error

Print callee-saved registers during fatal error
to help with debugging.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
Yong Cong Sin 2024-03-06 16:25:06 +08:00 committed by Anas Nashif
parent 7e0a334060
commit 30b122b3f0
5 changed files with 74 additions and 3 deletions

View file

@ -101,9 +101,21 @@ static void unwind_stack(const z_arch_esf_t *esf)
FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
const z_arch_esf_t *esf)
{
z_riscv_fatal_error_csf(reason, esf, NULL);
}
FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const z_arch_esf_t *esf,
const _callee_saved_t *csf)
{
#ifdef CONFIG_EXCEPTION_DEBUG
if (esf != NULL) {
/*
* Kernel stack pointer prior this exception i.e. before
* storing the exception stack frame.
*/
uintptr_t sp = (uintptr_t)esf + sizeof(z_arch_esf_t);
LOG_ERR(" a0: " PR_REG " t0: " PR_REG, esf->a0, esf->t0);
LOG_ERR(" a1: " PR_REG " t1: " PR_REG, esf->a1, esf->t1);
LOG_ERR(" a2: " PR_REG " t2: " PR_REG, esf->a2, esf->t2);
@ -119,8 +131,15 @@ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
LOG_ERR(" a7: " PR_REG, esf->a7);
#endif /* CONFIG_RISCV_ISA_RV32E */
#ifdef CONFIG_USERSPACE
LOG_ERR(" sp: " PR_REG, esf->sp);
if ((esf->mstatus & MSTATUS_MPP) == 0) {
/*
* Exception happened in user space:
* consider the saved user stack instead.
*/
sp = esf->sp;
}
#endif
LOG_ERR(" sp: " PR_REG, sp);
LOG_ERR(" ra: " PR_REG, esf->ra);
LOG_ERR(" mepc: " PR_REG, esf->mepc);
LOG_ERR("mstatus: " PR_REG, esf->mstatus);
@ -129,6 +148,21 @@ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
unwind_stack(esf);
#endif /* CONFIG_RISCV_EXCEPTION_STACK_TRACE */
}
if (csf != NULL) {
#if defined(CONFIG_RISCV_ISA_RV32E)
LOG_ERR(" s0: " PR_REG, csf->s0);
LOG_ERR(" s1: " PR_REG, csf->s1);
#else
LOG_ERR(" s0: " PR_REG " s6: " PR_REG, csf->s0, csf->s6);
LOG_ERR(" s1: " PR_REG " s7: " PR_REG, csf->s1, csf->s7);
LOG_ERR(" s2: " PR_REG " s8: " PR_REG, csf->s2, csf->s8);
LOG_ERR(" s3: " PR_REG " s9: " PR_REG, csf->s3, csf->s9);
LOG_ERR(" s4: " PR_REG " s10: " PR_REG, csf->s4, csf->s10);
LOG_ERR(" s5: " PR_REG " s11: " PR_REG, csf->s5, csf->s11);
#endif /* CONFIG_RISCV_ISA_RV32E */
LOG_ERR("");
}
#endif /* CONFIG_EXCEPTION_DEBUG */
z_fatal_error(reason, esf);
CODE_UNREACHABLE;

View file

@ -41,6 +41,23 @@
RV_I( op a7, __z_arch_esf_t_a7_OFFSET(sp) );\
RV_E( op ra, __z_arch_esf_t_ra_OFFSET(sp) )
#ifdef CONFIG_EXCEPTION_DEBUG
/* Convenience macro for storing callee saved register [s0 - s11] states. */
#define STORE_CALLEE_SAVED() \
RV_E( sr s0, ___callee_saved_t_s0_OFFSET(sp) );\
RV_E( sr s1, ___callee_saved_t_s1_OFFSET(sp) );\
RV_I( sr s2, ___callee_saved_t_s2_OFFSET(sp) );\
RV_I( sr s3, ___callee_saved_t_s3_OFFSET(sp) );\
RV_I( sr s4, ___callee_saved_t_s4_OFFSET(sp) );\
RV_I( sr s5, ___callee_saved_t_s5_OFFSET(sp) );\
RV_I( sr s6, ___callee_saved_t_s6_OFFSET(sp) );\
RV_I( sr s7, ___callee_saved_t_s7_OFFSET(sp) );\
RV_I( sr s8, ___callee_saved_t_s8_OFFSET(sp) );\
RV_I( sr s9, ___callee_saved_t_s9_OFFSET(sp) );\
RV_I( sr s10, ___callee_saved_t_s10_OFFSET(sp) );\
RV_I( sr s11, ___callee_saved_t_s11_OFFSET(sp) )
#endif /* CONFIG_EXCEPTION_DEBUG */
.macro get_current_cpu dst
#if defined(CONFIG_SMP) || defined(CONFIG_USERSPACE)
csrr \dst, mscratch
@ -61,7 +78,7 @@ GTEXT(__soc_save_context)
GTEXT(__soc_restore_context)
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
GTEXT(z_riscv_fatal_error)
GTEXT(z_riscv_fatal_error_csf)
GTEXT(z_get_next_switch_handle)
GTEXT(z_riscv_switch)
GTEXT(z_riscv_thread_start)
@ -386,7 +403,17 @@ do_fault:
/* Handle RV_ECALL_RUNTIME_EXCEPT. Retrieve reason in a0, esf in A1. */
lr a0, __z_arch_esf_t_a0_OFFSET(sp)
1: mv a1, sp
tail z_riscv_fatal_error
#ifdef CONFIG_EXCEPTION_DEBUG
/* Allocate space for caller-saved registers on current thread stack */
addi sp, sp, -__callee_saved_t_SIZEOF
/* Save callee-saved registers to be passed as 3rd arg */
STORE_CALLEE_SAVED() ;
mv a2, sp
#endif
tail z_riscv_fatal_error_csf
#if defined(CONFIG_IRQ_OFFLOAD)
do_irq_offload:

View file

@ -126,6 +126,10 @@ GEN_SOC_OFFSET_SYMS();
GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, sizeof(z_arch_esf_t));
#ifdef CONFIG_EXCEPTION_DEBUG
GEN_ABSOLUTE_SYM(__callee_saved_t_SIZEOF, ROUND_UP(sizeof(_callee_saved_t), ARCH_STACK_PTR_ALIGN));
#endif /* CONFIG_EXCEPTION_DEBUG */
#ifdef CONFIG_USERSPACE
GEN_OFFSET_SYM(_cpu_arch_t, user_exc_sp);
GEN_OFFSET_SYM(_cpu_arch_t, user_exc_tmp0);

View file

@ -69,9 +69,13 @@ arch_switch(void *switch_to, void **switched_from)
#endif
}
/* Thin wrapper around z_riscv_fatal_error_csf */
FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
const z_arch_esf_t *esf);
FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const z_arch_esf_t *esf,
const _callee_saved_t *csf);
static inline bool arch_is_in_isr(void)
{
#ifdef CONFIG_SMP

View file

@ -60,6 +60,8 @@ Architectures
* Implemented frame-pointer based stack unwinding.
* The fatal error message triggered from a fault now contains the callee-saved-registers states.
* Xtensa
Bluetooth