[rtems commit] bsps/riscv: Fix software interrupt dispatching

Sebastian Huber sebh at rtems.org
Fri Nov 11 15:33:13 UTC 2022


Module:    rtems
Branch:    master
Commit:    77c8d822c363de32c5b38b972ec01962bf676a6f
Changeset: http://git.rtems.org/rtems/commit/?id=77c8d822c363de32c5b38b972ec01962bf676a6f

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Nov 11 13:58:24 2022 +0100

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.

---

 bsps/include/bsp/irq-generic.h | 29 +++++++++++++++++++++++++++++
 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
@@ -457,6 +457,35 @@ static inline void bsp_interrupt_dispatch_entries(
   } while ( RTEMS_PREDICT_FALSE( entry != NULL ) );
 }
 
+/**
+ * @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.
+ *
+ * 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.
  *
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);
   }



More information about the vc mailing list