Skip to content

Commit 30b122b

Browse files
ycsinnashif
authored andcommitted
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 <[email protected]>
1 parent 7e0a334 commit 30b122b

File tree

5 files changed

+74
-3
lines changed

5 files changed

+74
-3
lines changed

arch/riscv/core/fatal.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,21 @@ static void unwind_stack(const z_arch_esf_t *esf)
101101

102102
FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
103103
const z_arch_esf_t *esf)
104+
{
105+
z_riscv_fatal_error_csf(reason, esf, NULL);
106+
}
107+
108+
FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const z_arch_esf_t *esf,
109+
const _callee_saved_t *csf)
104110
{
105111
#ifdef CONFIG_EXCEPTION_DEBUG
106112
if (esf != NULL) {
113+
/*
114+
* Kernel stack pointer prior this exception i.e. before
115+
* storing the exception stack frame.
116+
*/
117+
uintptr_t sp = (uintptr_t)esf + sizeof(z_arch_esf_t);
118+
107119
LOG_ERR(" a0: " PR_REG " t0: " PR_REG, esf->a0, esf->t0);
108120
LOG_ERR(" a1: " PR_REG " t1: " PR_REG, esf->a1, esf->t1);
109121
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,
119131
LOG_ERR(" a7: " PR_REG, esf->a7);
120132
#endif /* CONFIG_RISCV_ISA_RV32E */
121133
#ifdef CONFIG_USERSPACE
122-
LOG_ERR(" sp: " PR_REG, esf->sp);
134+
if ((esf->mstatus & MSTATUS_MPP) == 0) {
135+
/*
136+
* Exception happened in user space:
137+
* consider the saved user stack instead.
138+
*/
139+
sp = esf->sp;
140+
}
123141
#endif
142+
LOG_ERR(" sp: " PR_REG, sp);
124143
LOG_ERR(" ra: " PR_REG, esf->ra);
125144
LOG_ERR(" mepc: " PR_REG, esf->mepc);
126145
LOG_ERR("mstatus: " PR_REG, esf->mstatus);
@@ -129,6 +148,21 @@ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
129148
unwind_stack(esf);
130149
#endif /* CONFIG_RISCV_EXCEPTION_STACK_TRACE */
131150
}
151+
152+
if (csf != NULL) {
153+
#if defined(CONFIG_RISCV_ISA_RV32E)
154+
LOG_ERR(" s0: " PR_REG, csf->s0);
155+
LOG_ERR(" s1: " PR_REG, csf->s1);
156+
#else
157+
LOG_ERR(" s0: " PR_REG " s6: " PR_REG, csf->s0, csf->s6);
158+
LOG_ERR(" s1: " PR_REG " s7: " PR_REG, csf->s1, csf->s7);
159+
LOG_ERR(" s2: " PR_REG " s8: " PR_REG, csf->s2, csf->s8);
160+
LOG_ERR(" s3: " PR_REG " s9: " PR_REG, csf->s3, csf->s9);
161+
LOG_ERR(" s4: " PR_REG " s10: " PR_REG, csf->s4, csf->s10);
162+
LOG_ERR(" s5: " PR_REG " s11: " PR_REG, csf->s5, csf->s11);
163+
#endif /* CONFIG_RISCV_ISA_RV32E */
164+
LOG_ERR("");
165+
}
132166
#endif /* CONFIG_EXCEPTION_DEBUG */
133167
z_fatal_error(reason, esf);
134168
CODE_UNREACHABLE;

arch/riscv/core/isr.S

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@
4141
RV_I( op a7, __z_arch_esf_t_a7_OFFSET(sp) );\
4242
RV_E( op ra, __z_arch_esf_t_ra_OFFSET(sp) )
4343

44+
#ifdef CONFIG_EXCEPTION_DEBUG
45+
/* Convenience macro for storing callee saved register [s0 - s11] states. */
46+
#define STORE_CALLEE_SAVED() \
47+
RV_E( sr s0, ___callee_saved_t_s0_OFFSET(sp) );\
48+
RV_E( sr s1, ___callee_saved_t_s1_OFFSET(sp) );\
49+
RV_I( sr s2, ___callee_saved_t_s2_OFFSET(sp) );\
50+
RV_I( sr s3, ___callee_saved_t_s3_OFFSET(sp) );\
51+
RV_I( sr s4, ___callee_saved_t_s4_OFFSET(sp) );\
52+
RV_I( sr s5, ___callee_saved_t_s5_OFFSET(sp) );\
53+
RV_I( sr s6, ___callee_saved_t_s6_OFFSET(sp) );\
54+
RV_I( sr s7, ___callee_saved_t_s7_OFFSET(sp) );\
55+
RV_I( sr s8, ___callee_saved_t_s8_OFFSET(sp) );\
56+
RV_I( sr s9, ___callee_saved_t_s9_OFFSET(sp) );\
57+
RV_I( sr s10, ___callee_saved_t_s10_OFFSET(sp) );\
58+
RV_I( sr s11, ___callee_saved_t_s11_OFFSET(sp) )
59+
#endif /* CONFIG_EXCEPTION_DEBUG */
60+
4461
.macro get_current_cpu dst
4562
#if defined(CONFIG_SMP) || defined(CONFIG_USERSPACE)
4663
csrr \dst, mscratch
@@ -61,7 +78,7 @@ GTEXT(__soc_save_context)
6178
GTEXT(__soc_restore_context)
6279
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
6380

64-
GTEXT(z_riscv_fatal_error)
81+
GTEXT(z_riscv_fatal_error_csf)
6582
GTEXT(z_get_next_switch_handle)
6683
GTEXT(z_riscv_switch)
6784
GTEXT(z_riscv_thread_start)
@@ -386,7 +403,17 @@ do_fault:
386403
/* Handle RV_ECALL_RUNTIME_EXCEPT. Retrieve reason in a0, esf in A1. */
387404
lr a0, __z_arch_esf_t_a0_OFFSET(sp)
388405
1: mv a1, sp
389-
tail z_riscv_fatal_error
406+
407+
#ifdef CONFIG_EXCEPTION_DEBUG
408+
/* Allocate space for caller-saved registers on current thread stack */
409+
addi sp, sp, -__callee_saved_t_SIZEOF
410+
411+
/* Save callee-saved registers to be passed as 3rd arg */
412+
STORE_CALLEE_SAVED() ;
413+
mv a2, sp
414+
#endif
415+
416+
tail z_riscv_fatal_error_csf
390417

391418
#if defined(CONFIG_IRQ_OFFLOAD)
392419
do_irq_offload:

arch/riscv/core/offsets/offsets.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ GEN_SOC_OFFSET_SYMS();
126126

127127
GEN_ABSOLUTE_SYM(__z_arch_esf_t_SIZEOF, sizeof(z_arch_esf_t));
128128

129+
#ifdef CONFIG_EXCEPTION_DEBUG
130+
GEN_ABSOLUTE_SYM(__callee_saved_t_SIZEOF, ROUND_UP(sizeof(_callee_saved_t), ARCH_STACK_PTR_ALIGN));
131+
#endif /* CONFIG_EXCEPTION_DEBUG */
132+
129133
#ifdef CONFIG_USERSPACE
130134
GEN_OFFSET_SYM(_cpu_arch_t, user_exc_sp);
131135
GEN_OFFSET_SYM(_cpu_arch_t, user_exc_tmp0);

arch/riscv/include/kernel_arch_func.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ arch_switch(void *switch_to, void **switched_from)
6969
#endif
7070
}
7171

72+
/* Thin wrapper around z_riscv_fatal_error_csf */
7273
FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason,
7374
const z_arch_esf_t *esf);
7475

76+
FUNC_NORETURN void z_riscv_fatal_error_csf(unsigned int reason, const z_arch_esf_t *esf,
77+
const _callee_saved_t *csf);
78+
7579
static inline bool arch_is_in_isr(void)
7680
{
7781
#ifdef CONFIG_SMP

doc/releases/release-notes-3.7.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ Architectures
6060

6161
* Implemented frame-pointer based stack unwinding.
6262

63+
* The fatal error message triggered from a fault now contains the callee-saved-registers states.
64+
6365
* Xtensa
6466

6567
Bluetooth

0 commit comments

Comments
 (0)