diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 575c9871c13..8f524c23fc1 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -83,6 +83,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 59adbc42e46..2fecc68a077 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 8d2f64ad729..55733733539 100644 --- a/soc/nordic/common/vpr/soc_isr_stacking.h +++ b/soc/nordic/common/vpr/soc_isr_stacking.h @@ -62,6 +62,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 */ /*