diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 7f4f57eb283..686576f2923 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -262,6 +262,15 @@ config RISCV_GENERIC_TOOLCHAIN Allow SOCs that have custom extended riscv ISA to still compile with generic riscv32 toolchain. +config USE_ISR_WRAPPER + bool "Use isr_wrapper to handle interrupt and/or exception/fault" + default y if GEN_SW_ISR_TABLE + default y if MULTITHREADING + help + This is helper config to be able to use exception handling + when GEN_SW_ISR_TABLE is not used but multithreading is, which + needs exception handling and thread entry/switch functions. + config GEN_ISR_TABLES default y diff --git a/arch/riscv/core/CMakeLists.txt b/arch/riscv/core/CMakeLists.txt index 52a748c3247..280df8a60bd 100644 --- a/arch/riscv/core/CMakeLists.txt +++ b/arch/riscv/core/CMakeLists.txt @@ -26,7 +26,7 @@ endif() zephyr_library_sources_ifdef(CONFIG_FPU_SHARING fpu.c fpu.S) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) -zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr.S) +zephyr_library_sources_ifdef(CONFIG_USE_ISR_WRAPPER isr.S) zephyr_library_sources_ifdef(CONFIG_RISCV_PMP pmp.c pmp.S) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index 8ba7b615b42..ddc1730039f 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_RISCV_HAS_PLIC #include @@ -75,3 +76,20 @@ int arch_irq_disconnect_dynamic(unsigned int irq, unsigned int priority, } #endif /* CONFIG_SHARED_INTERRUPTS */ #endif /* CONFIG_DYNAMIC_INTERRUPTS */ + +#ifdef CONFIG_PM +void _arch_isr_direct_pm(void) +{ + unsigned int key; + + /* irq_lock() does what we want for this CPU */ + key = irq_lock(); + + if (_kernel.idle) { + _kernel.idle = 0; + pm_system_resume(); + } + + irq_unlock(key); +} +#endif diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index dad96974dcc..82b4491994b 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -73,6 +73,7 @@ GTEXT(__soc_is_irq) #endif GTEXT(__soc_handle_irq) GTEXT(z_riscv_fault) +GTEXT(z_irq_spurious) #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE GTEXT(__soc_save_context) GTEXT(__soc_restore_context) @@ -331,6 +332,7 @@ no_fp: /* increment _current->arch.exception_depth */ * function (that needs to be implemented by each SOC). The result is * returned via register a0 (1: interrupt, 0 exception) */ + #ifdef CONFIG_RISCV_SOC_EXCEPTION_FROM_IRQ jal ra, __soc_is_irq bnez a0, is_interrupt @@ -646,6 +648,7 @@ on_irq_stack: */ jal ra, __soc_handle_irq +#if defined CONFIG_GEN_SW_ISR_TABLE /* * Call corresponding registered function in _sw_isr_table. * (table is 2-word wide, we should shift index accordingly) @@ -659,6 +662,12 @@ on_irq_stack: /* Load ISR function address in register t1 */ lr t1, RV_REGSIZE(t0) +#else + /* Load spurious interrupt function in case _sw_isr_table does not exist */ + la t1, z_irq_spurious + /* NULL as parameter */ + li a0, 0 +#endif /* Call ISR function */ jalr ra, t1, 0 diff --git a/drivers/timer/nrf_grtc_timer.c b/drivers/timer/nrf_grtc_timer.c index 2809d8b3d60..431f80d279f 100644 --- a/drivers/timer/nrf_grtc_timer.c +++ b/drivers/timer/nrf_grtc_timer.c @@ -455,12 +455,26 @@ uint32_t sys_clock_elapsed(void) return (uint32_t)(counter_sub(counter(), last_count) / CYC_PER_TICK); } +#if !defined(CONFIG_GEN_SW_ISR_TABLE) +ISR_DIRECT_DECLARE(nrfx_grtc_direct_irq_handler) +{ + nrfx_grtc_irq_handler(); + ISR_DIRECT_PM(); + return 1; +} +#endif + static int sys_clock_driver_init(void) { nrfx_err_t err_code; +#if defined(CONFIG_GEN_SW_ISR_TABLE) IRQ_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), nrfx_isr, nrfx_grtc_irq_handler, 0); +#else + IRQ_DIRECT_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), nrfx_grtc_direct_irq_handler, 0); + irq_enable(DT_IRQN(GRTC_NODE)); +#endif #if defined(CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) && NRF_GRTC_HAS_CLKSEL #if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC) diff --git a/include/zephyr/arch/riscv/irq.h b/include/zephyr/arch/riscv/irq.h index 8408912716a..70371dbd82a 100644 --- a/include/zephyr/arch/riscv/irq.h +++ b/include/zephyr/arch/riscv/irq.h @@ -83,6 +83,13 @@ extern void z_riscv_irq_vector_set(unsigned int irq); z_riscv_irq_vector_set(irq_p); \ } +#ifdef CONFIG_PM +extern void _arch_isr_direct_pm(void); +#define ARCH_ISR_DIRECT_PM() _arch_isr_direct_pm() +#else +#define ARCH_ISR_DIRECT_PM() do { } while (false) +#endif + #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header() #define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap) diff --git a/soc/common/riscv-privileged/vector.S b/soc/common/riscv-privileged/vector.S index 1cd5a18b07c..23747bdbc52 100644 --- a/soc/common/riscv-privileged/vector.S +++ b/soc/common/riscv-privileged/vector.S @@ -12,7 +12,7 @@ GTEXT(__start) /* imports */ GTEXT(__initialize) -#if defined(CONFIG_GEN_SW_ISR_TABLE) +#if defined(CONFIG_USE_ISR_WRAPPER) GTEXT(_isr_wrapper) #endif @@ -41,7 +41,7 @@ SECTION_FUNC(vectors, __start) * mtvec.base must be aligned to 64 bytes (this is done using * CONFIG_RISCV_TRAP_HANDLER_ALIGNMENT) */ -#if defined(CONFIG_GEN_SW_ISR_TABLE) +#if defined(CONFIG_USE_ISR_WRAPPER) la t0, _isr_wrapper #else add t0, zero, zero