--- 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 +++++++++++++++++ cpukit/include/rtems/irq-extension.h | 37 +++++++++++++++ cpukit/score/include/rtems/score/processormask.h | 25 ++++++++++ 12 files changed, 226 insertions(+), 52 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 5a4a998bfb..7d36ce0930 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 a8c29bb7c5..1351cfb683 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 42fdfda77c..99e9f973e9 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 edda658ba9..feee951794 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 ea086215fc..facb53b347 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 7f943d96cb..a773644eae 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 e0bc3393d8..9860a7e19b 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 f2372ec363..2b0dbae8e7 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 b429c864b5..964cc8c1e5 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 7e8eb03762..1f7be1ba74 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/cpukit/include/rtems/irq-extension.h b/cpukit/include/rtems/irq-extension.h index e3fb4c5fea..5dd3792e22 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 ed79e63d6f..fd256d2342 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, -- 2.12.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel