diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-11-11 13:58:24 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-11-11 16:38:25 +0100 |
commit | 77c8d822c363de32c5b38b972ec01962bf676a6f (patch) | |
tree | 17f814613f4d4494fbd980fb34c3dfffb7568559 /bsps | |
parent | validation: Improve spurious interrupt test case (diff) | |
download | rtems-77c8d822c363de32c5b38b972ec01962bf676a6f.tar.bz2 |
bsps/riscv: Fix software interrupt dispatching
In SMP configurations, there may be no software interrupt handler
installed when the software interrupt is processed. Add the new
interrupt handler dispatch variant
bsp_interrupt_handler_dispatch_unlikely() for this special case.
Diffstat (limited to 'bsps')
-rw-r--r-- | bsps/include/bsp/irq-generic.h | 29 | ||||
-rw-r--r-- | bsps/riscv/riscv/irq/irq.c | 6 |
2 files changed, 33 insertions, 2 deletions
diff --git a/bsps/include/bsp/irq-generic.h b/bsps/include/bsp/irq-generic.h index fa1343a990..f605da9803 100644 --- a/bsps/include/bsp/irq-generic.h +++ b/bsps/include/bsp/irq-generic.h @@ -463,6 +463,35 @@ static inline void bsp_interrupt_dispatch_entries( * This function does not validate the vector number. If the vector number is * out of range, then the behaviour is undefined. * + * The function assumes that no handlers are installed at the vector. In this + * case, no operation is performed. + * + * In uniprocessor configurations, you can call this function within every + * context which can be disabled via rtems_interrupt_local_disable(). + * + * In SMP configurations, you can call this function in every context. + * + * @param vector is the vector number. + */ +static inline void bsp_interrupt_handler_dispatch_unlikely( + rtems_vector_number vector +) +{ + const rtems_interrupt_entry *entry; + + entry = bsp_interrupt_entry_load_first( vector ); + + if ( RTEMS_PREDICT_FALSE( entry != NULL ) ) { + bsp_interrupt_dispatch_entries( entry ); + } +} + +/** + * @brief Sequentially calls all interrupt handlers installed at the vector. + * + * This function does not validate the vector number. If the vector number is + * out of range, then the behaviour is undefined. + * * In uniprocessor configurations, you can call this function within every * context which can be disabled via rtems_interrupt_local_disable(). * diff --git a/bsps/riscv/riscv/irq/irq.c b/bsps/riscv/riscv/irq/irq.c index 74d833eac8..6856b21165 100644 --- a/bsps/riscv/riscv/irq/irq.c +++ b/bsps/riscv/riscv/irq/irq.c @@ -78,7 +78,7 @@ void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self) mcause <<= 1; if (mcause == (RISCV_INTERRUPT_TIMER_MACHINE << 1)) { - bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_TIMER); + bsp_interrupt_handler_dispatch_unchecked(RISCV_INTERRUPT_VECTOR_TIMER); } else if (mcause == (RISCV_INTERRUPT_EXTERNAL_MACHINE << 1)) { volatile RISCV_PLIC_hart_regs *plic_hart_regs; uint32_t interrupt_index; @@ -109,8 +109,10 @@ void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self) #ifdef RTEMS_SMP _SMP_Inter_processor_interrupt_handler(cpu_self); + bsp_interrupt_handler_dispatch_unlikely(RISCV_INTERRUPT_VECTOR_SOFTWARE); +#else + bsp_interrupt_handler_dispatch_unchecked(RISCV_INTERRUPT_VECTOR_SOFTWARE); #endif - bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_SOFTWARE); } else { bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION); } |