summaryrefslogtreecommitdiffstats
path: root/bsps
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2022-11-11 13:58:24 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2022-11-11 16:38:25 +0100
commit77c8d822c363de32c5b38b972ec01962bf676a6f (patch)
tree17f814613f4d4494fbd980fb34c3dfffb7568559 /bsps
parentvalidation: Improve spurious interrupt test case (diff)
downloadrtems-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.h29
-rw-r--r--bsps/riscv/riscv/irq/irq.c6
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);
}