[rtems commit] LEON3 SMP: support static interrupt affinity

Daniel Hellstrom danielh at rtems.org
Thu Oct 9 11:12:15 UTC 2014


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

Author:    Daniel Hellstrom <daniel at gaisler.com>
Date:      Thu May 29 21:39:18 2014 +0200

LEON3 SMP: support static interrupt affinity

Changed LEON3_irq-mp to const also.

---

 c/src/lib/libbsp/sparc/leon3/include/bsp.h     |   13 +++++++-
 c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c  |    2 +-
 c/src/lib/libbsp/sparc/shared/irq/irq-shared.c |   39 ++++++++++++++++++++----
 3 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
index a4a4a6f..5cc6e02 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
@@ -220,7 +220,18 @@ extern void BSP_shared_interrupt_mask(int irq);
  * to override the BSP default.
  * See startup/bspsmp.c for the default value.
  */
-extern unsigned char LEON3_mp_irq;
+extern const unsigned char LEON3_mp_irq;
+
+#ifdef RTEMS_SMP
+/* Weak table used to implement static interrupt CPU affinity in a SMP
+ * configuration. The array index is the interrupt to be looked up, and
+ * the array[INTERRUPT] content is the CPU number relative to boot CPU
+ * index that will be servicing the interrupts from the IRQ source. The
+ * default is to let the first CPU (the boot cpu) to handle all
+ * interrupts (all zeros).
+ */
+extern const unsigned char LEON3_irq_to_cpu[32];
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c b/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c
index 567c971..45ac92b 100644
--- a/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c
+++ b/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c
@@ -24,7 +24,7 @@
 /* Irq used by shared memory driver and for inter-processor interrupts.
  * Can be overridden by being defined in the application.
  */
-unsigned char LEON3_mp_irq __attribute__((weak)) = 14;
+const unsigned char LEON3_mp_irq __attribute__((weak)) = 14;
 
 #if !defined(__leon__) || defined(RTEMS_PARAVIRT)
 uint32_t _CPU_SMP_Get_current_processor( void )
diff --git a/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
index b49621f..46c8307 100644
--- a/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
+++ b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
@@ -2,6 +2,31 @@
 #include <bsp.h>
 #include <bsp/irq-generic.h>
 
+#if defined(RTEMS_SMP) && defined(LEON3)
+/* Interrupt to CPU map. Default to CPU0 since in BSS. */
+const unsigned char LEON3_irq_to_cpu[32] __attribute__((weak));
+
+/* On SMP use map table above relative to SMP Boot CPU (normally CPU0) */
+static inline int bsp_irq_cpu(int irq)
+{
+  /* protect from bad user configuration, default to boot cpu */
+  if (rtems_configuration_get_maximum_processors() <= LEON3_irq_to_cpu[irq])
+    return LEON3_Cpu_Index;
+  else
+    return LEON3_Cpu_Index + LEON3_irq_to_cpu[irq];
+}
+#else
+/* when not SMP the local CPU is returned */
+static inline int bsp_irq_cpu(int irq)
+{
+#ifdef LEON3
+  return _LEON3_Get_current_processor();
+#else
+  return 0;
+#endif
+}
+#endif
+
 static inline void bsp_dispatch_irq(int irq)
 {
        bsp_interrupt_handler_entry *e =
@@ -54,26 +79,28 @@ rtems_status_code bsp_interrupt_facility_initialize(void)
 
 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
 {
-       BSP_Unmask_interrupt((int)vector);
+  int irq = (int)vector;
+  BSP_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq));
 
-       return RTEMS_SUCCESSFUL;
+  return RTEMS_SUCCESSFUL;
 }
 
 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
 {
-       BSP_Mask_interrupt((int)vector);
+  int irq = (int)vector;
+  BSP_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
 
-       return RTEMS_SUCCESSFUL;
+  return RTEMS_SUCCESSFUL;
 }
 
 void BSP_shared_interrupt_mask(int irq)
 {
-       BSP_Mask_interrupt(irq);
+  BSP_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
 }
 
 void BSP_shared_interrupt_unmask(int irq)
 {
-       BSP_Unmask_interrupt(irq);
+  BSP_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq));
 }
 
 void BSP_shared_interrupt_clear(int irq)



More information about the vc mailing list