diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index b70eb0aca14..83e3ef86d07 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -124,6 +124,11 @@ config RISCV_SOC_HAS_ISR_STACKING saved on the stack by the hardware, and the registers saved by the software macros. The structure must be called 'struct arch_esf'. + - SOC_ISR_STACKING_ESR_INIT: macro guarded by !_ASMLANGUAGE. + Some hardware stacked registers should be initialized on init + stack with proper values. This prevents from incorrect behavior + on entry context switch when initial stack is restored. + config RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING bool help diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index b4999bda09a..896f8e5199d 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -106,6 +106,10 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, stack_init->soc_context = soc_esf_init; #endif +#ifdef CONFIG_RISCV_SOC_HAS_ISR_STACKING + SOC_ISR_STACKING_ESR_INIT; +#endif + thread->callee_saved.sp = (unsigned long)stack_init; /* where to go when returning from z_riscv_switch() */ diff --git a/soc/nordic/common/vpr/soc_isr_stacking.h b/soc/nordic/common/vpr/soc_isr_stacking.h index 014ae1296a0..c5f0e7b2762 100644 --- a/soc/nordic/common/vpr/soc_isr_stacking.h +++ b/soc/nordic/common/vpr/soc_isr_stacking.h @@ -60,6 +60,13 @@ #endif /* DT_PROP(VPR_CPU, nordic_bus_width) == 64 */ +/* + * VPR stacked mcause needs to have proper value on initial stack. + * Initial mret will restore this value. + */ +#define SOC_ISR_STACKING_ESR_INIT \ + stack_init->_mcause = 0; + #else /* _ASMLANGUAGE */ /*