diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index d41a2e55fe9..052c1078481 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -77,6 +77,18 @@ 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 '__esf'. +config RISCV_SOC_HAS_CUSTOM_IRQ_LOCK_OPS + bool + help + Hidden option to allow SoC to overwrite arch_irq_lock(), + arch_irq_unlock() and arch_irq_unlocked() functions with + platform-specific versions named z_soc_irq_lock(), z_soc_irq_unlock() + and z_soc_irq_unlocked(). + + Enable this hidden option and specialize the z_soc_* functions when + the RISC-V SoC needs to do something different and more than reading and + writing the mstatus register to lock and unlock the IRQs. + config RISCV_SOC_CONTEXT_SAVE bool "SOC-based context saving in IRQ handlers" select RISCV_SOC_OFFSETS diff --git a/include/zephyr/arch/riscv/arch.h b/include/zephyr/arch/riscv/arch.h index e41efdee4f9..aafe6b00e5f 100644 --- a/include/zephyr/arch/riscv/arch.h +++ b/include/zephyr/arch/riscv/arch.h @@ -220,6 +220,9 @@ extern void z_irq_spurious(const void *unused); */ static ALWAYS_INLINE unsigned int arch_irq_lock(void) { +#ifdef CONFIG_RISCV_SOC_HAS_CUSTOM_IRQ_LOCK_OPS + return z_soc_irq_lock(); +#else unsigned int key; __asm__ volatile ("csrrc %0, mstatus, %1" @@ -228,6 +231,7 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) : "memory"); return key; +#endif } /* @@ -236,15 +240,23 @@ static ALWAYS_INLINE unsigned int arch_irq_lock(void) */ static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) { +#ifdef CONFIG_RISCV_SOC_HAS_CUSTOM_IRQ_LOCK_OPS + z_soc_irq_unlock(key); +#else __asm__ volatile ("csrs mstatus, %0" : : "r" (key & MSTATUS_IEN) : "memory"); +#endif } static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) { +#ifdef CONFIG_RISCV_SOC_HAS_CUSTOM_IRQ_LOCK_OPS + return z_soc_irq_unlocked(key); +#else return (key & MSTATUS_IEN) != 0; +#endif } static ALWAYS_INLINE void arch_nop(void)