[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