[rtems commit] Add interrupt vector set/get affinity

Sebastian Huber sebh at rtems.org
Wed Jul 12 06:02:48 UTC 2017


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Jul 11 11:54:30 2017 +0200

Add interrupt vector set/get affinity

Close #3071.

---

 c/src/lib/libbsp/arm/shared/arm-gic-irq.c          | 24 ++++++----
 c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h  |  9 +++-
 .../lib/libbsp/powerpc/qoriq/clock/clock-config.c  | 16 +++----
 c/src/lib/libbsp/powerpc/qoriq/include/irq.h       |  8 ++--
 c/src/lib/libbsp/powerpc/qoriq/irq/irq.c           | 24 ++++------
 c/src/lib/libbsp/shared/src/irq-generic.c          | 53 +++++++++++++++++++++-
 c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h     | 20 ++++++++
 c/src/lib/libbsp/sparc/leon3/clock/ckinit.c        | 11 +----
 c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h     | 10 ++++
 c/src/lib/libbsp/sparc/leon3/startup/eirq.c        | 41 +++++++++++++++++
 .../libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c  | 20 +-------
 cpukit/include/rtems/irq-extension.h               | 37 +++++++++++++++
 cpukit/score/include/rtems/score/processormask.h   | 25 ++++++++++
 13 files changed, 228 insertions(+), 70 deletions(-)

diff --git a/c/src/lib/libbsp/arm/shared/arm-gic-irq.c b/c/src/lib/libbsp/arm/shared/arm-gic-irq.c
index 5a4a998..7d36ce0 100644
--- a/c/src/lib/libbsp/arm/shared/arm-gic-irq.c
+++ b/c/src/lib/libbsp/arm/shared/arm-gic-irq.c
@@ -153,20 +153,24 @@ rtems_status_code arm_gic_irq_get_priority(
   return sc;
 }
 
-rtems_status_code arm_gic_irq_set_affinity(
+void bsp_interrupt_set_affinity(
   rtems_vector_number vector,
-  uint8_t targets
+  const Processor_mask *affinity
 )
 {
-  rtems_status_code sc = RTEMS_SUCCESSFUL;
+  volatile gic_dist *dist = ARM_GIC_DIST;
+  uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0);
 
-  if (bsp_interrupt_is_valid_vector(vector)) {
-    volatile gic_dist *dist = ARM_GIC_DIST;
+  gic_id_set_targets(dist, vector, targets);
+}
 
-    gic_id_set_targets(dist, vector, targets);
-  } else {
-    sc = RTEMS_INVALID_ID;
-  }
+void bsp_interrupt_get_affinity(
+  rtems_vector_number vector,
+  Processor_mask *affinity
+)
+{
+  volatile gic_dist *dist = ARM_GIC_DIST;
+  uint8_t targets = gic_id_get_targets(dist, vector);
 
-  return sc;
+  _Processor_mask_From_uint32_t(affinity, targets, 0);
 }
diff --git a/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h b/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h
index a8c29bb..1351cfb 100644
--- a/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h
+++ b/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h
@@ -58,9 +58,14 @@ rtems_status_code arm_gic_irq_get_priority(
   uint8_t *priority
 );
 
-rtems_status_code arm_gic_irq_set_affinity(
+void bsp_interrupt_set_affinity(
   rtems_vector_number vector,
-  uint8_t targets
+  const Processor_mask *affinity
+);
+
+void bsp_interrupt_get_affinity(
+  rtems_vector_number vector,
+  Processor_mask *affinity
 );
 
 typedef enum {
diff --git a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
index 42fdfda..99e9f97 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
@@ -56,12 +56,11 @@ static void qoriq_clock_handler_install(rtems_isr_entry *old_isr)
   *old_isr = NULL;
 
 #if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)
-  sc = qoriq_pic_set_affinity(
-    CLOCK_INTERRUPT,
-    ppc_processor_id()
-  );
-  if (sc != RTEMS_SUCCESSFUL) {
-    rtems_fatal_error_occurred(0xdeadbeef);
+  {
+    Processor_mask affinity;
+
+    _Processor_mask_From_index(&affinity, ppc_processor_id());
+    bsp_interrupt_set_affinity(CLOCK_INTERRUPT, &affinity);
   }
 #endif
 
@@ -133,10 +132,7 @@ static void qoriq_clock_cleanup(void)
   qoriq_clock_handler_install(&old_isr)
 
 #define Clock_driver_support_set_interrupt_affinity(online_processors) \
-  qoriq_pic_set_affinities( \
-    CLOCK_INTERRUPT, \
-    _Processor_mask_To_uint32_t(online_processors, 0) \
-  )
+  bsp_interrupt_set_affinity(CLOCK_INTERRUPT, online_processors)
 
 #define Clock_driver_support_shutdown_hardware() \
   qoriq_clock_cleanup()
diff --git a/c/src/lib/libbsp/powerpc/qoriq/include/irq.h b/c/src/lib/libbsp/powerpc/qoriq/include/irq.h
index edda658..feee951 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/include/irq.h
+++ b/c/src/lib/libbsp/powerpc/qoriq/include/irq.h
@@ -372,14 +372,14 @@ rtems_status_code qoriq_pic_set_priority(
   int *old_priority
 );
 
-rtems_status_code qoriq_pic_set_affinity(
+void bsp_interrupt_set_affinity(
   rtems_vector_number vector,
-  uint32_t processor_index
+  const Processor_mask *affinity
 );
 
-rtems_status_code qoriq_pic_set_affinities(
+void bsp_interrupt_get_affinity(
   rtems_vector_number vector,
-  uint32_t processor_affinities
+  Processor_mask *affinity
 );
 
 /** @} */
diff --git a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c
index ea08621..facb53b 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c
@@ -147,30 +147,24 @@ rtems_status_code qoriq_pic_set_priority(
 	return sc;
 }
 
-rtems_status_code qoriq_pic_set_affinities(
+void bsp_interrupt_set_affinity(
 	rtems_vector_number vector,
-	uint32_t processor_affinities
+	const Processor_mask *affinity
 )
 {
-	rtems_status_code sc = RTEMS_SUCCESSFUL;
-
-	if (bsp_interrupt_is_valid_vector(vector)) {
-		volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
-
-		src_cfg->dr = processor_affinities;
-	} else {
-		sc = RTEMS_INVALID_ID;
-	}
+	volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
 
-	return sc;
+	src_cfg->dr = _Processor_mask_To_uint32_t(affinity, 0);
 }
 
-rtems_status_code qoriq_pic_set_affinity(
+void bsp_interrupt_get_affinity(
 	rtems_vector_number vector,
-	uint32_t processor_index
+	Processor_mask *affinity
 )
 {
-	return qoriq_pic_set_affinities(vector, BSP_BIT32(processor_index));
+	volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
+
+	_Processor_mask_From_uint32_t(affinity, src_cfg->dr, 0);
 }
 
 static rtems_status_code pic_vector_enable(rtems_vector_number vector, uint32_t msk)
diff --git a/c/src/lib/libbsp/shared/src/irq-generic.c b/c/src/lib/libbsp/shared/src/irq-generic.c
index 7f943d9..a773644 100755
--- a/c/src/lib/libbsp/shared/src/irq-generic.c
+++ b/c/src/lib/libbsp/shared/src/irq-generic.c
@@ -9,7 +9,7 @@
 /*
  * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
  *
- * Copyright (c) 2008-2014 embedded brains GmbH.
+ * Copyright (c) 2008, 2017 embedded brains GmbH.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -573,3 +573,54 @@ bool bsp_interrupt_handler_is_empty(rtems_vector_number vector)
 
   return empty;
 }
+
+rtems_status_code rtems_interrupt_set_affinity(
+  rtems_vector_number  vector,
+  size_t               affinity_size,
+  const cpu_set_t     *affinity
+)
+{
+  Processor_mask             set;
+  Processor_mask_Copy_status status;
+
+  if (!bsp_interrupt_is_valid_vector(vector)) {
+    return RTEMS_INVALID_ID;
+  }
+
+  status = _Processor_mask_From_cpu_set_t(&set, affinity_size, affinity);
+  if (status != PROCESSOR_MASK_COPY_LOSSLESS) {
+    return RTEMS_INVALID_SIZE;
+  }
+
+#if defined(RTEMS_SMP)
+  bsp_interrupt_set_affinity(vector, &set);
+#endif
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_interrupt_get_affinity(
+  rtems_vector_number  vector,
+  size_t               affinity_size,
+  cpu_set_t           *affinity
+)
+{
+  Processor_mask             set;
+  Processor_mask_Copy_status status;
+
+  if (!bsp_interrupt_is_valid_vector(vector)) {
+    return RTEMS_INVALID_ID;
+  }
+
+#if defined(RTEMS_SMP)
+  bsp_interrupt_get_affinity(vector, &set);
+#else
+  _Processor_mask_From_index(&set, 0);
+#endif
+
+  status = _Processor_mask_To_cpu_set_t(&set, affinity_size, affinity);
+  if (status != PROCESSOR_MASK_COPY_LOSSLESS) {
+    return RTEMS_INVALID_SIZE;
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h b/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
index e0bc339..9860a7e 100644
--- a/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
+++ b/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
@@ -18,6 +18,8 @@
 #ifndef LIBBSP_ERC32_IRQ_CONFIG_H
 #define LIBBSP_ERC32_IRQ_CONFIG_H
 
+#include <rtems.h>
+
 #define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
 #define BSP_INTERRUPT_VECTOR_MIN 0
 #define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_STD
@@ -25,4 +27,22 @@
 /* No extra check is needed */
 #undef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
 
+RTEMS_INLINE_ROUTINE void bsp_interrupt_set_affinity(
+  rtems_vector_number   vector,
+  const Processor_mask *affinity
+)
+{
+  (void) vector;
+  (void) affinity;
+}
+
+RTEMS_INLINE_ROUTINE void bsp_interrupt_get_affinity(
+  rtems_vector_number  vector,
+  Processor_mask      *affinity
+)
+{
+  (void) vector;
+  _Processor_mask_From_index( affinity, 0 );
+}
+
 #endif /* LIBBSP_ERC32_IRQ_CONFIG_H */
diff --git a/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c b/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c
index f2372ec..2b0dbae 100644
--- a/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c
+++ b/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c
@@ -192,16 +192,7 @@ static void bsp_clock_handler_install(rtems_isr *new)
 }
 
 #define Clock_driver_support_set_interrupt_affinity(online_processors) \
-  do { \
-    uint32_t cpu_count = _SMP_Processor_count; \
-    uint32_t cpu_index; \
-    LEON_Enable_interrupt_broadcast(clkirq); \
-    for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { \
-      if (_Processor_mask_Is_set(online_processors, cpu_index)) { \
-        BSP_Cpu_Unmask_interrupt(clkirq, cpu_index); \
-      } \
-    } \
-  } while (0)
+  bsp_interrupt_set_affinity(clkirq, online_processors)
 
 static void leon3_clock_initialize(void)
 {
diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h b/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
index b429c86..964cc8c 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
@@ -41,4 +41,14 @@ static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
         LEON3_IrqCtrl_EIrq != 0));
 }
 
+void bsp_interrupt_set_affinity(
+  rtems_vector_number vector,
+  const Processor_mask *affinity
+);
+
+void bsp_interrupt_get_affinity(
+  rtems_vector_number vector,
+  Processor_mask *affinity
+);
+
 #endif /* LIBBSP_LEON3_IRQ_CONFIG_H */
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/eirq.c b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
index 7e8eb03..1f7be1b 100644
--- a/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
+++ b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
@@ -11,6 +11,7 @@
  */
 
 #include <leon.h>
+#include <bsp/irq.h>
 
 /* GRLIB extended IRQ controller IRQ number */
 int LEON3_IrqCtrl_EIrq = -1;
@@ -23,3 +24,43 @@ void leon3_ext_irq_init(void)
     LEON3_IrqCtrl_EIrq = (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf;
   }
 }
+
+void bsp_interrupt_set_affinity(
+  rtems_vector_number vector,
+  const Processor_mask *affinity
+)
+{
+  uint32_t unmasked = 0;
+  uint32_t cpu_count = rtems_get_processor_count();
+  uint32_t cpu_index;
+
+  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
+    if (_Processor_mask_Is_set(affinity, cpu_index)) {
+      BSP_Cpu_Unmask_interrupt(vector, cpu_index);
+      ++unmasked;
+    }
+  }
+
+  if (unmasked > 1) {
+    LEON_Enable_interrupt_broadcast(vector);
+  } else {
+    LEON_Disable_interrupt_broadcast(vector);
+  }
+}
+
+void bsp_interrupt_get_affinity(
+  rtems_vector_number vector,
+  Processor_mask *affinity
+)
+{
+  uint32_t cpu_count = rtems_get_processor_count();
+  uint32_t cpu_index;
+
+  _Processor_mask_Zero(affinity);
+
+  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
+    if (!BSP_Cpu_Is_interrupt_masked(vector, cpu_index)) {
+      _Processor_mask_Set(affinity, cpu_index);
+    }
+  }
+}
diff --git a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c
index f61d2a8..e299b10 100644
--- a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c
+++ b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_grlib.c
@@ -22,6 +22,7 @@
 #include <bsp/genirq.h>
 
 #include <bsp.h>
+#include <bsp/irq.h>
 
 #define DBG(args...)
 /*#define DBG(args...) printk(args)*/
@@ -236,24 +237,7 @@ int ambapp_grlib_int_set_affinity
 	const Processor_mask *cpus
 	)
 {
-	uint32_t cpu_count = rtems_get_processor_count();
-	uint32_t cpu_index;
-	int enabled_cnt = 0;
-
-	for (cpu_index = 0; cpu_index < cpu_count; cpu_index++) {
-		if (_Processor_mask_Is_set(cpus, cpu_index)) {
-			BSP_Cpu_Unmask_interrupt(irq, cpu_index);
-			enabled_cnt++;
-		}
-	}
-
-	/* Propagate the interrupt to all CPUs */
-	if (enabled_cnt > 1) {
-		LEON_Enable_interrupt_broadcast(irq);
-	} else {
-		LEON_Disable_interrupt_broadcast(irq);
-	}
-
+	bsp_interrupt_set_affinity(irq, cpus);
 	return DRVMGR_OK;
 }
 #endif
diff --git a/cpukit/include/rtems/irq-extension.h b/cpukit/include/rtems/irq-extension.h
index e3fb4c5..5dd3792 100644
--- a/cpukit/include/rtems/irq-extension.h
+++ b/cpukit/include/rtems/irq-extension.h
@@ -204,6 +204,43 @@ rtems_status_code rtems_interrupt_handler_iterate(
 );
 
 /**
+ * @brief Sets the processor affinity set of an interrupt vector.
+ *
+ * @param[in] vector The interrupt vector number.
+ * @param[in] affinity_size The storage size of the affinity set.
+ * @param[in] affinity_set The new processor affinity set for the interrupt
+ *   vector.  This pointer must not be @c NULL.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID The vector number is invalid.
+ * @retval RTEMS_INVALID_SIZE Invalid affinity set size.
+ * @retval RTEMS_INVALID_NUMBER Invalid processor affinity set.
+ */
+rtems_status_code rtems_interrupt_set_affinity(
+  rtems_vector_number  vector,
+  size_t               affinity_size,
+  const cpu_set_t     *affinity
+);
+
+/**
+ * @brief Gets the processor affinity set of an interrupt vector.
+ *
+ * @param[in] vector The interrupt vector number.
+ * @param[in] affinity_size The storage size of the affinity set.
+ * @param[out] affinity_set The current processor affinity set for the
+ *   interrupt vector.  This pointer must not be @c NULL.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID The vector number is invalid.
+ * @retval RTEMS_INVALID_SIZE Invalid affinity set size.
+ */
+rtems_status_code rtems_interrupt_get_affinity(
+  rtems_vector_number  vector,
+  size_t               affinity_size,
+  cpu_set_t           *affinity
+);
+
+/**
  * @brief An interrupt server action.
  *
  * This structure must be treated as an opaque data type.  Members must not be
diff --git a/cpukit/score/include/rtems/score/processormask.h b/cpukit/score/include/rtems/score/processormask.h
index ed79e63..fd256d2 100644
--- a/cpukit/score/include/rtems/score/processormask.h
+++ b/cpukit/score/include/rtems/score/processormask.h
@@ -203,6 +203,31 @@ RTEMS_INLINE_ROUTINE uint32_t _Processor_mask_To_uint32_t(
   return (uint32_t) (bits >> (32 * (index % _BITSET_BITS) / 32));
 }
 
+/**
+ * @brief Creates a processor set from an unsigned 32-bit integer relative to
+ * the specified index.
+ */
+RTEMS_INLINE_ROUTINE void _Processor_mask_From_uint32_t(
+  Processor_mask *mask,
+  uint32_t        bits,
+  uint32_t        index
+)
+{
+  _Processor_mask_Zero( mask );
+  mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32);
+}
+
+/**
+ * @brief Creates a processor set from the specified index.
+ */
+RTEMS_INLINE_ROUTINE void _Processor_mask_From_index(
+  Processor_mask *mask,
+  uint32_t        index
+)
+{
+  BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask );
+}
+
 typedef enum {
   PROCESSOR_MASK_COPY_LOSSLESS,
   PROCESSOR_MASK_COPY_PARTIAL_LOSS,




More information about the vc mailing list