Add directives to get and set the priority of an interrupt vector. Implement the directives for the following BSP families:
* arm/lpc24xx * arm/lpc32xx * powerpc/mpc55xxevb * powerpc/qoriq Implement the directives for the following interrupt controllers: * GICv2 and GICv3 (arm and aarch64) * NVIC (arm) * PLIC (riscv) Update #5002. --- v2: * Clarify documentation * Add implementations * Add validation tests bsps/arm/beagle/irq/irq.c | 19 + bsps/arm/csb336/irq/irq.c | 19 + bsps/arm/csb337/irq/irq.c | 19 + bsps/arm/edb7312/irq/irq.c | 19 + bsps/arm/gumstix/irq/irq.c | 19 + bsps/arm/lpc24xx/include/bsp/irq.h | 10 +- bsps/arm/lpc24xx/irq/irq.c | 58 +- bsps/arm/lpc32xx/include/bsp/irq.h | 4 - bsps/arm/lpc32xx/include/tm27.h | 10 +- bsps/arm/lpc32xx/irq/irq.c | 56 +- bsps/arm/raspberrypi/irq/irq.c | 19 + bsps/arm/rtl22xx/irq/irq.c | 19 + bsps/arm/shared/irq/irq-armv7m.c | 30 + bsps/arm/smdk2410/irq/irq.c | 19 + bsps/arm/tms570/irq/irq.c | 19 + bsps/i386/shared/irq/irq.c | 19 + bsps/include/bsp/irq-generic.h | 41 ++ bsps/include/dev/irq/arm-gic-irq.h | 10 - bsps/include/dev/irq/arm-gic-tm27.h | 4 +- bsps/include/dev/irq/arm-gicv3.h | 3 + bsps/lm32/shared/irq/irq.c | 19 + bsps/m68k/genmcf548x/irq/irq.c | 19 + bsps/microblaze/microblaze_fpga/irq/irq.c | 19 + bsps/mips/shared/irq/irq.c | 19 + bsps/powerpc/gen5200/irq/irq.c | 19 + bsps/powerpc/gen83xx/irq/irq.c | 19 + bsps/powerpc/mpc55xxevb/include/bsp/irq.h | 17 +- bsps/powerpc/mpc55xxevb/start/irq.c | 46 +- bsps/powerpc/mpc8260ads/irq/irq.c | 19 + bsps/powerpc/psim/irq/irq_init.c | 19 + bsps/powerpc/qemuppc/irq/irq_init.c | 19 + bsps/powerpc/qoriq/clock/clock-config.c | 5 +- bsps/powerpc/qoriq/include/bsp/irq.h | 23 +- bsps/powerpc/qoriq/include/tm27.h | 7 +- bsps/powerpc/qoriq/irq/irq.c | 56 +- bsps/powerpc/qoriq/mpci/intercom.c | 5 +- bsps/powerpc/shared/irq/ppc-irq-generic.c | 19 + bsps/powerpc/t32mppc/irq/irq.c | 19 + bsps/powerpc/tqm8xx/irq/irq.c | 19 + bsps/powerpc/virtex/irq/irq_init.c | 19 + bsps/riscv/griscv/irq/irq.c | 19 + bsps/riscv/riscv/irq/irq.c | 44 +- .../shared/dev/irq/arm-gicv2-get-attributes.c | 3 + bsps/shared/dev/irq/arm-gicv2-zynqmp.c | 3 + bsps/shared/dev/irq/arm-gicv2.c | 36 +- bsps/shared/dev/irq/arm-gicv3.c | 65 +- bsps/shared/irq/irq-default.c | 19 + bsps/shared/irq/irq-priority.c | 65 ++ bsps/sparc/leon3/start/eirq.c | 19 + bsps/sparc/shared/irq/irq-shared.c | 19 + bsps/x86_64/amd64/interrupts/idt.c | 19 + cpukit/include/rtems/rtems/intr.h | 166 ++++- spec/build/bsps/objirq.yml | 1 + spec/build/bsps/powerpc/ss555/bspss555.yml | 1 + .../testsuites/validation/validation-intr.yml | 2 + testsuites/validation/tc-intr-get-priority.c | 567 ++++++++++++++++++ testsuites/validation/tc-intr-set-priority.c | 504 ++++++++++++++++ 57 files changed, 2162 insertions(+), 212 deletions(-) create mode 100644 bsps/shared/irq/irq-priority.c create mode 100644 testsuites/validation/tc-intr-get-priority.c create mode 100644 testsuites/validation/tc-intr-set-priority.c diff --git a/bsps/arm/beagle/irq/irq.c b/bsps/arm/beagle/irq/irq.c index 0ae82aa95e..7cb37d86e4 100644 --- a/bsps/arm/beagle/irq/irq.c +++ b/bsps/arm/beagle/irq/irq.c @@ -163,6 +163,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { int i; diff --git a/bsps/arm/csb336/irq/irq.c b/bsps/arm/csb336/irq/irq.c index 2834eaf1f7..4ba8bd4ac4 100644 --- a/bsps/arm/csb336/irq/irq.c +++ b/bsps/arm/csb336/irq/irq.c @@ -88,6 +88,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL); diff --git a/bsps/arm/csb337/irq/irq.c b/bsps/arm/csb337/irq/irq.c index 8bb39f1c69..a3b1fb0e6e 100644 --- a/bsps/arm/csb337/irq/irq.c +++ b/bsps/arm/csb337/irq/irq.c @@ -83,6 +83,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { unsigned long i = 0; diff --git a/bsps/arm/edb7312/irq/irq.c b/bsps/arm/edb7312/irq/irq.c index 53f01eba65..7b0b342f89 100644 --- a/bsps/arm/edb7312/irq/irq.c +++ b/bsps/arm/edb7312/irq/irq.c @@ -125,6 +125,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { uint32_t int_stat = 0; diff --git a/bsps/arm/gumstix/irq/irq.c b/bsps/arm/gumstix/irq/irq.c index c90f2fe92e..b671bd0dcc 100644 --- a/bsps/arm/gumstix/irq/irq.c +++ b/bsps/arm/gumstix/irq/irq.c @@ -80,6 +80,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { /* disable all interrupts */ diff --git a/bsps/arm/lpc24xx/include/bsp/irq.h b/bsps/arm/lpc24xx/include/bsp/irq.h index 42f1c6b92a..0fe9c4cda3 100644 --- a/bsps/arm/lpc24xx/include/bsp/irq.h +++ b/bsps/arm/lpc24xx/include/bsp/irq.h @@ -132,20 +132,12 @@ #ifdef ARM_MULTILIB_ARCH_V4 #define LPC24XX_IRQ_PRIORITY_VALUE_MAX 15 #else - #define LPC24XX_IRQ_PRIORITY_VALUE_MAX 31 + #define LPC24XX_IRQ_PRIORITY_VALUE_MAX 255 #endif #define LPC24XX_IRQ_PRIORITY_COUNT (LPC24XX_IRQ_PRIORITY_VALUE_MAX + 1) #define LPC24XX_IRQ_PRIORITY_HIGHEST LPC24XX_IRQ_PRIORITY_VALUE_MIN #define LPC24XX_IRQ_PRIORITY_LOWEST LPC24XX_IRQ_PRIORITY_VALUE_MAX -#ifndef ASM - -void lpc24xx_irq_set_priority(rtems_vector_number vector, unsigned priority); - -unsigned lpc24xx_irq_get_priority(rtems_vector_number vector); - -#endif /* ASM */ - /** @} */ #endif /* LIBBSP_ARM_LPC24XX_IRQ_H */ diff --git a/bsps/arm/lpc24xx/irq/irq.c b/bsps/arm/lpc24xx/irq/irq.c index 560c5b810a..310e004479 100644 --- a/bsps/arm/lpc24xx/irq/irq.c +++ b/bsps/arm/lpc24xx/irq/irq.c @@ -47,34 +47,6 @@ static inline bool lpc24xx_irq_is_valid(rtems_vector_number vector) return vector < BSP_INTERRUPT_VECTOR_COUNT; } -void lpc24xx_irq_set_priority(rtems_vector_number vector, unsigned priority) -{ - if (lpc24xx_irq_is_valid(vector)) { - if (priority > LPC24XX_IRQ_PRIORITY_VALUE_MAX) { - priority = LPC24XX_IRQ_PRIORITY_VALUE_MAX; - } - - #ifdef ARM_MULTILIB_ARCH_V4 - VICVectPriorityBase [vector] = priority; - #else - _ARMV7M_NVIC_Set_priority((int) vector, (int) (priority << 3)); - #endif - } -} - -unsigned lpc24xx_irq_get_priority(rtems_vector_number vector) -{ - if (lpc24xx_irq_is_valid(vector)) { - #ifdef ARM_MULTILIB_ARCH_V4 - return VICVectPriorityBase [vector]; - #else - return (unsigned) (_ARMV7M_NVIC_Get_priority((int) vector) >> 3); - #endif - } else { - return LPC24XX_IRQ_PRIORITY_VALUE_MIN - 1U; - } -} - #ifdef ARM_MULTILIB_ARCH_V4 rtems_status_code bsp_interrupt_get_attributes( @@ -82,6 +54,9 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + attributes->maximum_priority = LPC24XX_IRQ_PRIORITY_VALUE_MAX; + attributes->can_get_priority = true; + attributes->can_set_priority = true; return RTEMS_SUCCESSFUL; } @@ -133,6 +108,33 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (priority > LPC24XX_IRQ_PRIORITY_VALUE_MAX) { + return RTEMS_INVALID_PRIORITY; + } + + VICVectPriorityBase [vector] = priority; + return RTEMS_SUCCESSFUL; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + + *priority = VICVectPriorityBase [vector]; + return RTEMS_SUCCESSFUL; +} + void bsp_interrupt_facility_initialize(void) { volatile uint32_t *addr = VICVectAddrBase; diff --git a/bsps/arm/lpc32xx/include/bsp/irq.h b/bsps/arm/lpc32xx/include/bsp/irq.h index 1571ea5e6b..7cef217263 100644 --- a/bsps/arm/lpc32xx/include/bsp/irq.h +++ b/bsps/arm/lpc32xx/include/bsp/irq.h @@ -161,10 +161,6 @@ extern "C" { bool bsp_interrupt_is_valid_vector(rtems_vector_number vector); -void lpc32xx_irq_set_priority(rtems_vector_number vector, unsigned priority); - -unsigned lpc32xx_irq_get_priority(rtems_vector_number vector); - typedef enum { LPC32XX_IRQ_ACTIVE_LOW_OR_FALLING_EDGE, LPC32XX_IRQ_ACTIVE_HIGH_OR_RISING_EDGE diff --git a/bsps/arm/lpc32xx/include/tm27.h b/bsps/arm/lpc32xx/include/tm27.h index bd06894354..2ad5606cd0 100644 --- a/bsps/arm/lpc32xx/include/tm27.h +++ b/bsps/arm/lpc32xx/include/tm27.h @@ -93,13 +93,19 @@ static inline void Clear_tm27_intr(void) volatile lpc_timer *timer = LPC32XX_TM27_TIMER; timer->ir = LPC_TIMER_IR_MR0; - lpc32xx_irq_set_priority(LPC32XX_TM27_IRQ, LPC32XX_IRQ_PRIORITY_LOWEST); + (void) rtems_interrupt_set_priority( + LPC32XX_TM27_IRQ, + LPC32XX_IRQ_PRIORITY_LOWEST + ); } static inline void Lower_tm27_intr(void) { bsp_interrupt_vector_enable(LPC32XX_TM27_IRQ); - lpc32xx_irq_set_priority(LPC32XX_TM27_IRQ, LPC32XX_IRQ_PRIORITY_HIGHEST); + (void) rtems_interrupt_set_priority( + LPC32XX_TM27_IRQ, + LPC32XX_IRQ_PRIORITY_HIGHEST + ); } #endif /* __tm27_h */ diff --git a/bsps/arm/lpc32xx/irq/irq.c b/bsps/arm/lpc32xx/irq/irq.c index 418798f8cb..67c08c80e5 100644 --- a/bsps/arm/lpc32xx/irq/irq.c +++ b/bsps/arm/lpc32xx/irq/irq.c @@ -160,39 +160,44 @@ static inline unsigned lpc32xx_irq_get_index(uint32_t val) return val; } -void lpc32xx_irq_set_priority(rtems_vector_number vector, unsigned priority) +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) { - if (bsp_interrupt_is_valid_vector(vector)) { - rtems_interrupt_level level; - unsigned i = 0; + rtems_interrupt_level level; + uint32_t i; - if (priority > LPC32XX_IRQ_PRIORITY_LOWEST) { - priority = LPC32XX_IRQ_PRIORITY_LOWEST; - } + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - lpc32xx_irq_priority_table [vector] = (uint8_t) priority; + if (priority > LPC32XX_IRQ_PRIORITY_VALUE_MAX) { + return RTEMS_INVALID_PRIORITY; + } - for (i = LPC32XX_IRQ_PRIORITY_HIGHEST; i <= priority; ++i) { - rtems_interrupt_disable(level); - lpc32xx_irq_clear_bit_in_field(vector, &lpc32xx_irq_priority_masks [i]); - rtems_interrupt_enable(level); - } + rtems_interrupt_disable(level); + lpc32xx_irq_priority_table [vector] = (uint8_t) priority; - for (i = priority + 1; i <= LPC32XX_IRQ_PRIORITY_LOWEST; ++i) { - rtems_interrupt_disable(level); - lpc32xx_irq_set_bit_in_field(vector, &lpc32xx_irq_priority_masks [i]); - rtems_interrupt_enable(level); - } + for (i = LPC32XX_IRQ_PRIORITY_HIGHEST; i <= priority; ++i) { + lpc32xx_irq_clear_bit_in_field(vector, &lpc32xx_irq_priority_masks [i]); } + + for (i = priority + 1; i <= LPC32XX_IRQ_PRIORITY_LOWEST; ++i) { + lpc32xx_irq_set_bit_in_field(vector, &lpc32xx_irq_priority_masks [i]); + } + + rtems_interrupt_enable(level); + return RTEMS_SUCCESSFUL; } -unsigned lpc32xx_irq_get_priority(rtems_vector_number vector) +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) { - if (bsp_interrupt_is_valid_vector(vector)) { - return lpc32xx_irq_priority_table [vector]; - } else { - return LPC32XX_IRQ_PRIORITY_LOWEST; - } + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + *priority lpc32xx_irq_priority_table [vector]; + return RTEMS_SUCCESSFUL; } void lpc32xx_irq_set_activation_polarity(rtems_vector_number vector, lpc32xx_irq_activation_polarity activation_polarity) @@ -326,6 +331,9 @@ rtems_status_code bsp_interrupt_get_attributes( attributes->can_clear = is_sw_irq; attributes->can_get_affinity = true; attributes->can_set_affinity = true; + attributes->maximum_priority = LPC32XX_IRQ_PRIORITY_VALUE_MAX; + attributes->can_get_priority = true; + attributes->can_set_priority = true; return RTEMS_SUCCESSFUL; } diff --git a/bsps/arm/raspberrypi/irq/irq.c b/bsps/arm/raspberrypi/irq/irq.c index 7177cd2c05..06ce90fbb3 100644 --- a/bsps/arm/raspberrypi/irq/irq.c +++ b/bsps/arm/raspberrypi/irq/irq.c @@ -206,6 +206,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + #if defined(RTEMS_SMP) rtems_status_code bsp_interrupt_get_affinity( rtems_vector_number vector, diff --git a/bsps/arm/rtl22xx/irq/irq.c b/bsps/arm/rtl22xx/irq/irq.c index e69b74d02a..eb522d9267 100644 --- a/bsps/arm/rtl22xx/irq/irq.c +++ b/bsps/arm/rtl22xx/irq/irq.c @@ -82,6 +82,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { volatile uint32_t *ctrl = (volatile uint32_t *) VICVectCntlBase; diff --git a/bsps/arm/shared/irq/irq-armv7m.c b/bsps/arm/shared/irq/irq-armv7m.c index 9e0c1f3a87..6606de8264 100644 --- a/bsps/arm/shared/irq/irq-armv7m.c +++ b/bsps/arm/shared/irq/irq-armv7m.c @@ -43,6 +43,9 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + attributes->maximum_priority = 255; + attributes->can_get_priority = true; + attributes->can_set_priority = true; return RTEMS_SUCCESSFUL; } @@ -94,6 +97,33 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (priority > 255) { + return RTEMS_INVALID_PRIORITY; + } + + _ARMV7M_NVIC_Set_priority((int) vector, (int) priority); + return RTEMS_SUCCESSFUL; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + + *priority = (uint32_t) _ARMV7M_NVIC_Get_priority((int) vector); + return RTEMS_SUCCESSFUL; +} + void bsp_interrupt_facility_initialize(void) { ARMV7M_Exception_handler *vector_table; diff --git a/bsps/arm/smdk2410/irq/irq.c b/bsps/arm/smdk2410/irq/irq.c index 3bc46aa6d7..9081dd25d4 100644 --- a/bsps/arm/smdk2410/irq/irq.c +++ b/bsps/arm/smdk2410/irq/irq.c @@ -81,6 +81,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, NULL); diff --git a/bsps/arm/tms570/irq/irq.c b/bsps/arm/tms570/irq/irq.c index 9a80e0e3d2..74e227f068 100644 --- a/bsps/arm/tms570/irq/irq.c +++ b/bsps/arm/tms570/irq/irq.c @@ -289,6 +289,25 @@ rtems_status_code bsp_interrupt_vector_disable( return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + /** * @brief Init function of interrupt module * diff --git a/bsps/i386/shared/irq/irq.c b/bsps/i386/shared/irq/irq.c index 57753c2f77..7ff3135781 100644 --- a/bsps/i386/shared/irq/irq.c +++ b/bsps/i386/shared/irq/irq.c @@ -337,6 +337,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + #if defined(RTEMS_SMP) rtems_status_code bsp_interrupt_get_affinity( rtems_vector_number vector, diff --git a/bsps/include/bsp/irq-generic.h b/bsps/include/bsp/irq-generic.h index bd557df9dc..ee7d6850e4 100644 --- a/bsps/include/bsp/irq-generic.h +++ b/bsps/include/bsp/irq-generic.h @@ -373,6 +373,47 @@ rtems_status_code bsp_interrupt_raise_on( */ rtems_status_code bsp_interrupt_clear( rtems_vector_number vector ); +/** + * @brief Gets the priority of the interrupt vector. + * + * @param vector is the interrupt vector number. The vector number shall be + * less than BSP_INTERRUPT_VECTOR_COUNT. + * + * @param[out] priority is the pointer to an uint32_t object. When the + * directive call is successful, the priority of the interrupt vector will be + * stored in this object. The pointer shall be valid. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_UNSATISFIED There is no priority associated with the + * interrupt vector. + */ +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +); + +/** + * @brief Sets the priority of the interrupt vector. + * + * @param vector is the interrupt vector number. The vector number shall be + * less than BSP_INTERRUPT_VECTOR_COUNT. + * + * @param priority is the new priority for the interrupt vector. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_INVALID_PRIORITY The priority specified by ``priority`` was + * not a valid new priority for the interrupt vector. + * + * @retval ::RTEMS_UNSATISFIED The request to set the priority of the interrupt + * vector has not been satisfied. + */ +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +); + /** * @brief Gets the processor affinity set of the interrupt vector. * diff --git a/bsps/include/dev/irq/arm-gic-irq.h b/bsps/include/dev/irq/arm-gic-irq.h index 1fcf594360..518256ad2b 100644 --- a/bsps/include/dev/irq/arm-gic-irq.h +++ b/bsps/include/dev/irq/arm-gic-irq.h @@ -64,16 +64,6 @@ extern "C" { #define ARM_GIC_DIST ((volatile gic_dist *) BSP_ARM_GIC_DIST_BASE) -rtems_status_code arm_gic_irq_set_priority( - rtems_vector_number vector, - uint8_t priority -); - -rtems_status_code arm_gic_irq_get_priority( - rtems_vector_number vector, - uint8_t *priority -); - rtems_status_code arm_gic_irq_set_group( rtems_vector_number vector, gic_group group diff --git a/bsps/include/dev/irq/arm-gic-tm27.h b/bsps/include/dev/irq/arm-gic-tm27.h index f2a16afae3..6baab7a45c 100644 --- a/bsps/include/dev/irq/arm-gic-tm27.h +++ b/bsps/include/dev/irq/arm-gic-tm27.h @@ -80,7 +80,7 @@ static inline void Install_tm27_vector( rtems_interrupt_handler handler ) ); _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL ); - sc = arm_gic_irq_set_priority( + sc = rtems_interrupt_set_priority( ARM_GIC_TM27_IRQ_LOW, ARM_GIC_TM27_PRIO_LOW ); @@ -99,7 +99,7 @@ static inline void Install_tm27_vector( rtems_interrupt_handler handler ) ); _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL ); - sc = arm_gic_irq_set_priority( + sc = rtems_interrupt_set_priority( ARM_GIC_TM27_IRQ_HIGH, ARM_GIC_TM27_PRIO_HIGH ); diff --git a/bsps/include/dev/irq/arm-gicv3.h b/bsps/include/dev/irq/arm-gicv3.h index 09d1b50422..74e29057b0 100644 --- a/bsps/include/dev/irq/arm-gicv3.h +++ b/bsps/include/dev/irq/arm-gicv3.h @@ -364,6 +364,9 @@ static inline void gicv3_get_attributes( attributes->maybe_enable = true; attributes->maybe_disable = true; attributes->can_raise = true; + attributes->can_get_priority = true; + attributes->can_set_priority = true; + attributes->maximum_priority = 255; if ( vector <= ARM_GIC_IRQ_SGI_LAST ) { /* diff --git a/bsps/lm32/shared/irq/irq.c b/bsps/lm32/shared/irq/irq.c index 4a7f9bd444..a7c1af6587 100644 --- a/bsps/lm32/shared/irq/irq.c +++ b/bsps/lm32/shared/irq/irq.c @@ -72,3 +72,22 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) lm32_interrupt_mask(1 << vector); return RTEMS_SUCCESSFUL; } + +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} diff --git a/bsps/m68k/genmcf548x/irq/irq.c b/bsps/m68k/genmcf548x/irq/irq.c index 0a1f8794e0..5624cd2aa1 100644 --- a/bsps/m68k/genmcf548x/irq/irq.c +++ b/bsps/m68k/genmcf548x/irq/irq.c @@ -136,6 +136,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + static void set_exception_handler(rtems_vector_number vector, void_func handler) { void **vbr; diff --git a/bsps/microblaze/microblaze_fpga/irq/irq.c b/bsps/microblaze/microblaze_fpga/irq/irq.c index f14eddc799..662eaf6ac6 100644 --- a/bsps/microblaze/microblaze_fpga/irq/irq.c +++ b/bsps/microblaze/microblaze_fpga/irq/irq.c @@ -122,6 +122,25 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector ) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize( void ) { /* diff --git a/bsps/mips/shared/irq/irq.c b/bsps/mips/shared/irq/irq.c index 460da7a3f8..83c998ae3c 100644 --- a/bsps/mips/shared/irq/irq.c +++ b/bsps/mips/shared/irq/irq.c @@ -121,6 +121,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { mips_install_isr_entries(); diff --git a/bsps/powerpc/gen5200/irq/irq.c b/bsps/powerpc/gen5200/irq/irq.c index 3dee82d566..9f771576a3 100644 --- a/bsps/powerpc/gen5200/irq/irq.c +++ b/bsps/powerpc/gen5200/irq/irq.c @@ -414,6 +414,25 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + #if (BENCHMARK_IRQ_PROCESSING == 0) void BSP_IRQ_Benchmarking_Reset( void) { diff --git a/bsps/powerpc/gen83xx/irq/irq.c b/bsps/powerpc/gen83xx/irq/irq.c index f81fae2848..f82d9a352e 100644 --- a/bsps/powerpc/gen83xx/irq/irq.c +++ b/bsps/powerpc/gen83xx/irq/irq.c @@ -476,6 +476,25 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + /* * IRQ Handler: this is called from the primary exception dispatcher */ diff --git a/bsps/powerpc/mpc55xxevb/include/bsp/irq.h b/bsps/powerpc/mpc55xxevb/include/bsp/irq.h index 0df805791e..940b9f9288 100644 --- a/bsps/powerpc/mpc55xxevb/include/bsp/irq.h +++ b/bsps/powerpc/mpc55xxevb/include/bsp/irq.h @@ -453,13 +453,16 @@ extern "C" { * Interrupt controller */ -#define MPC55XX_INTC_MIN_PRIORITY 1U -#define MPC55XX_INTC_MAX_PRIORITY 15U -#define MPC55XX_INTC_DISABLED_PRIORITY 0U -#define MPC55XX_INTC_INVALID_PRIORITY (MPC55XX_INTC_MAX_PRIORITY + 1) -#define MPC55XX_INTC_DEFAULT_PRIORITY (MPC55XX_INTC_MIN_PRIORITY + 1) -#define MPC55XX_INTC_IS_VALID_PRIORITY(p) \ - ((p) >= MPC55XX_INTC_DISABLED_PRIORITY && (p) <= MPC55XX_INTC_MAX_PRIORITY) +/* + * These are RTEMS API priority values, not INTC priority values. We have: + * 15 - API-priority == INTC-priority + */ +#define MPC55XX_INTC_MIN_PRIORITY 14U +#define MPC55XX_INTC_MAX_PRIORITY 0U +#define MPC55XX_INTC_DISABLED_PRIORITY 15U +#define MPC55XX_INTC_INVALID_PRIORITY 16U +#define MPC55XX_INTC_DEFAULT_PRIORITY 13U +#define MPC55XX_INTC_IS_VALID_PRIORITY(p) (((uint32_t) (p)) <= 15U) rtems_status_code mpc55xx_interrupt_handler_install( rtems_vector_number vector, diff --git a/bsps/powerpc/mpc55xxevb/start/irq.c b/bsps/powerpc/mpc55xxevb/start/irq.c index 05397ee7b1..ce05ea80a3 100644 --- a/bsps/powerpc/mpc55xxevb/start/irq.c +++ b/bsps/powerpc/mpc55xxevb/start/irq.c @@ -45,35 +45,30 @@ #include <rtems/status-checks.h> -/** - * @brief Returns the priority @a priority of IRQ @a vector from the INTC. - */ -rtems_status_code mpc55xx_intc_get_priority( rtems_vector_number vector, unsigned *priority) +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) { - if (MPC55XX_IRQ_IS_VALID( vector)) { - *priority = INTC.PSR [vector].B.PRI; - return RTEMS_SUCCESSFUL; - } else { - *priority = MPC55XX_INTC_INVALID_PRIORITY; - return RTEMS_INVALID_NUMBER; - } + bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector)); + bsp_interrupt_assert( priority != NULL); + *priority = INTC.PSR [vector].B.PRI; + return RTEMS_SUCCESSFUL; } -/** - * @brief Sets the priority of IRQ @a vector to @a priority at the INTC. - */ -rtems_status_code mpc55xx_intc_set_priority( rtems_vector_number vector, unsigned priority) +rtems_status_code rtems_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) { - if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) { - INTC.PSR [vector].B.PRI = priority; - if (INTC.PSR [vector].B.PRI == priority) { - return RTEMS_SUCCESSFUL; - } else { - return RTEMS_IO_ERROR; - } - } else { - return RTEMS_INVALID_NUMBER; + bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector)); + + if (!MPC55XX_INTC_IS_VALID_PRIORITY( priority)) { + return RTEMS_INVALID_PRIORITY; } + + INTC.PSR [vector].B.PRI = priority; + return RTEMS_SUCCESSFUL; } /** @@ -168,6 +163,9 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + attributes->maximum_priority = 15; + attributes->can_get_priority = true; + attributes->can_set_priority = true; return RTEMS_SUCCESSFUL; } diff --git a/bsps/powerpc/mpc8260ads/irq/irq.c b/bsps/powerpc/mpc8260ads/irq/irq.c index 70cb5acf9b..2980f8d2f8 100644 --- a/bsps/powerpc/mpc8260ads/irq/irq.c +++ b/bsps/powerpc/mpc8260ads/irq/irq.c @@ -398,6 +398,25 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize() { rtems_status_code sc; diff --git a/bsps/powerpc/psim/irq/irq_init.c b/bsps/powerpc/psim/irq/irq_init.c index 16c30e714d..36d9527484 100644 --- a/bsps/powerpc/psim/irq/irq_init.c +++ b/bsps/powerpc/psim/irq/irq_init.c @@ -158,6 +158,25 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { rtems_status_code sc; diff --git a/bsps/powerpc/qemuppc/irq/irq_init.c b/bsps/powerpc/qemuppc/irq/irq_init.c index 972a8456cc..d3120ade78 100644 --- a/bsps/powerpc/qemuppc/irq/irq_init.c +++ b/bsps/powerpc/qemuppc/irq/irq_init.c @@ -108,6 +108,25 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { rtems_status_code sc; diff --git a/bsps/powerpc/qoriq/clock/clock-config.c b/bsps/powerpc/qoriq/clock/clock-config.c index 17347278f3..40a7daa353 100644 --- a/bsps/powerpc/qoriq/clock/clock-config.c +++ b/bsps/powerpc/qoriq/clock/clock-config.c @@ -115,10 +115,9 @@ static void qoriq_clock_handler_install(rtems_interrupt_handler handler) } #endif - sc = qoriq_pic_set_priority( + sc = rtems_interrupt_set_priority( CLOCK_INTERRUPT, - QORIQ_PIC_PRIORITY_LOWEST, - NULL + QORIQ_PIC_PRIORITY_LOWEST ); if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(QORIQ_FATAL_CLOCK_INTERRUPT_SET_PRIORITY); diff --git a/bsps/powerpc/qoriq/include/bsp/irq.h b/bsps/powerpc/qoriq/include/bsp/irq.h index 5eaf36ba4c..56b75e3d1c 100644 --- a/bsps/powerpc/qoriq/include/bsp/irq.h +++ b/bsps/powerpc/qoriq/include/bsp/irq.h @@ -394,19 +394,16 @@ extern "C" { * @{ */ -#define QORIQ_PIC_PRIORITY_LOWEST 1 -#define QORIQ_PIC_PRIORITY_HIGHEST 15 -#define QORIQ_PIC_PRIORITY_DISABLED 0 -#define QORIQ_PIC_PRIORITY_INVALID (QORIQ_PIC_PRIORITY_HIGHEST + 1) -#define QORIQ_PIC_PRIORITY_DEFAULT (QORIQ_PIC_PRIORITY_LOWEST + 1) -#define QORIQ_PIC_PRIORITY_IS_VALID(p) \ - ((p) >= QORIQ_PIC_PRIORITY_DISABLED && (p) <= QORIQ_PIC_PRIORITY_HIGHEST) - -rtems_status_code qoriq_pic_set_priority( - rtems_vector_number vector, - int new_priority, - int *old_priority -); +/* + * These are RTEMS API priority values, not PIC priority values. We have: + * 15 - API-priority == PIC-priority + */ +#define QORIQ_PIC_PRIORITY_LOWEST 14 +#define QORIQ_PIC_PRIORITY_HIGHEST 0 +#define QORIQ_PIC_PRIORITY_DISABLED 15 +#define QORIQ_PIC_PRIORITY_INVALID 16 +#define QORIQ_PIC_PRIORITY_DEFAULT 13 +#define QORIQ_PIC_PRIORITY_IS_VALID(p) (((uint32_t) (p)) <= 15) rtems_status_code qoriq_pic_msi_allocate(rtems_vector_number *vector); diff --git a/bsps/powerpc/qoriq/include/tm27.h b/bsps/powerpc/qoriq/include/tm27.h index 0c43823f0e..7e8c78e54b 100644 --- a/bsps/powerpc/qoriq/include/tm27.h +++ b/bsps/powerpc/qoriq/include/tm27.h @@ -58,6 +58,9 @@ static inline void Install_tm27_vector( rtems_interrupt_handler handler ) rtems_vector_number low = QORIQ_IRQ_IPI_0 + IPI_INDEX_LOW; rtems_vector_number high = QORIQ_IRQ_IPI_0 + IPI_INDEX_HIGH; + (void) rtems_interrupt_set_priority(low, 14); + (void) rtems_interrupt_set_priority(high, 13); + rtems_interrupt_entry_initialize( &entry_low, handler, @@ -70,8 +73,6 @@ static inline void Install_tm27_vector( rtems_interrupt_handler handler ) &entry_low ); - (void) qoriq_pic_set_priority(low, 1, NULL); - rtems_interrupt_entry_initialize( &entry_high, handler, @@ -83,8 +84,6 @@ static inline void Install_tm27_vector( rtems_interrupt_handler handler ) RTEMS_INTERRUPT_UNIQUE, &entry_high ); - - (void) qoriq_pic_set_priority(high, 2, NULL); } static inline void qoriq_tm27_cause(uint32_t ipi_index) diff --git a/bsps/powerpc/qoriq/irq/irq.c b/bsps/powerpc/qoriq/irq/irq.c index 2a5e3e9a75..76e3e8ba0f 100644 --- a/bsps/powerpc/qoriq/irq/irq.c +++ b/bsps/powerpc/qoriq/irq/irq.c @@ -298,43 +298,50 @@ static bool pic_is_ipi(rtems_vector_number vector) return (vector - QORIQ_IRQ_IPI_BASE) < 4; } -rtems_status_code qoriq_pic_set_priority( +rtems_status_code bsp_interrupt_get_priority( rtems_vector_number vector, - int new_priority, - int *old_priority + uint32_t *priority ) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - uint32_t old_vpr = 0; + volatile qoriq_pic_src_cfg *src_cfg; + + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); if (QORIQ_IRQ_IS_MSI(vector)) { return RTEMS_UNSATISFIED; } - if (bsp_interrupt_is_valid_vector(vector)) { - volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector); + src_cfg = get_src_cfg(vector); + *priority = UINT32_C(15) - VPR_PRIORITY_GET(src_cfg->vpr); + return RTEMS_SUCCESSFUL; +} - if (QORIQ_PIC_PRIORITY_IS_VALID(new_priority)) { - rtems_interrupt_lock_context lock_context; +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + volatile qoriq_pic_src_cfg *src_cfg; + rtems_interrupt_lock_context lock_context; + uint32_t vpr; - rtems_interrupt_lock_acquire(&lock, &lock_context); - old_vpr = src_cfg->vpr; - src_cfg->vpr = VPR_PRIORITY_SET(old_vpr, (uint32_t) new_priority); - rtems_interrupt_lock_release(&lock, &lock_context); - } else if (new_priority < 0) { - old_vpr = src_cfg->vpr; - } else { - sc = RTEMS_INVALID_PRIORITY; - } - } else { - sc = RTEMS_INVALID_ID; + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (QORIQ_IRQ_IS_MSI(vector)) { + return RTEMS_UNSATISFIED; } - if (old_priority != NULL) { - *old_priority = (int) VPR_PRIORITY_GET(old_vpr); + if (!QORIQ_PIC_PRIORITY_IS_VALID(priority)) { + return RTEMS_INVALID_PRIORITY; } - return sc; + src_cfg = get_src_cfg(vector); + rtems_interrupt_lock_acquire(&lock, &lock_context); + vpr = src_cfg->vpr; + src_cfg->vpr = VPR_PRIORITY_SET(vpr, UINT32_C(15) - priority); + rtems_interrupt_lock_release(&lock, &lock_context); + return RTEMS_SUCCESSFUL; } rtems_status_code qoriq_pic_set_sense_and_polarity( @@ -472,6 +479,9 @@ rtems_status_code bsp_interrupt_get_attributes( attributes->can_set_affinity = !(is_ipi || is_msi); attributes->can_raise = is_ipi; attributes->can_raise_on = is_ipi; + attributes->maximum_priority = 15; + attributes->can_get_priority = !is_msi; + attributes->can_set_priority = !is_msi; if (is_msi) { attributes->can_be_triggered_by_message = true; diff --git a/bsps/powerpc/qoriq/mpci/intercom.c b/bsps/powerpc/qoriq/mpci/intercom.c index ae3c2d92e9..a27647c22e 100644 --- a/bsps/powerpc/qoriq/mpci/intercom.c +++ b/bsps/powerpc/qoriq/mpci/intercom.c @@ -313,10 +313,9 @@ void qoriq_intercom_init(void) ); assert(sc == RTEMS_SUCCESSFUL); - sc = qoriq_pic_set_priority( + sc = rtems_interrupt_set_priority( QORIQ_IRQ_IPI_0, - QORIQ_PIC_PRIORITY_LOWEST, - NULL + QORIQ_PIC_PRIORITY_LOWEST ); assert(sc == RTEMS_SUCCESSFUL); diff --git a/bsps/powerpc/shared/irq/ppc-irq-generic.c b/bsps/powerpc/shared/irq/ppc-irq-generic.c index f4b85f7bc0..d706c081c1 100644 --- a/bsps/powerpc/shared/irq/ppc-irq-generic.c +++ b/bsps/powerpc/shared/irq/ppc-irq-generic.c @@ -151,6 +151,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { /* diff --git a/bsps/powerpc/t32mppc/irq/irq.c b/bsps/powerpc/t32mppc/irq/irq.c index a3f2504443..250a7021a0 100644 --- a/bsps/powerpc/t32mppc/irq/irq.c +++ b/bsps/powerpc/t32mppc/irq/irq.c @@ -92,6 +92,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + #if defined(RTEMS_SMP) rtems_status_code bsp_interrupt_get_affinity( rtems_vector_number vector, diff --git a/bsps/powerpc/tqm8xx/irq/irq.c b/bsps/powerpc/tqm8xx/irq/irq.c index 2e8e229427..aeee5b2a35 100644 --- a/bsps/powerpc/tqm8xx/irq/irq.c +++ b/bsps/powerpc/tqm8xx/irq/irq.c @@ -143,6 +143,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + /* * IRQ Handler: this is called from the primary exception dispatcher */ diff --git a/bsps/powerpc/virtex/irq/irq_init.c b/bsps/powerpc/virtex/irq/irq_init.c index 320053e3a2..74e3b2ff7d 100644 --- a/bsps/powerpc/virtex/irq/irq_init.c +++ b/bsps/powerpc/virtex/irq/irq_init.c @@ -182,6 +182,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned int excNum) { BSP_irq_handle_at_opbintc(); diff --git a/bsps/riscv/griscv/irq/irq.c b/bsps/riscv/griscv/irq/irq.c index 12af7d7b3d..7b2f386f01 100644 --- a/bsps/riscv/griscv/irq/irq.c +++ b/bsps/riscv/griscv/irq/irq.c @@ -153,6 +153,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + rtems_status_code bsp_interrupt_get_affinity( rtems_vector_number vector, Processor_mask *affinity diff --git a/bsps/riscv/riscv/irq/irq.c b/bsps/riscv/riscv/irq/irq.c index ada418b7fb..f3aea1203a 100644 --- a/bsps/riscv/riscv/irq/irq.c +++ b/bsps/riscv/riscv/irq/irq.c @@ -356,6 +356,8 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + bool is_external = RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector); + attributes->is_maskable = true; attributes->can_enable = true; attributes->maybe_enable = true; @@ -364,8 +366,13 @@ rtems_status_code bsp_interrupt_get_attributes( attributes->can_raise = (vector == RISCV_INTERRUPT_VECTOR_SOFTWARE); attributes->can_raise_on = attributes->can_raise; attributes->cleared_by_acknowledge = true; - attributes->can_get_affinity = RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector); - attributes->can_set_affinity = attributes->can_get_affinity; + attributes->can_get_affinity = is_external; + attributes->can_set_affinity = is_external; + + /* The PLIC priority is defined by a 32-bit WARL register */ + attributes->maximum_priority = UINT32_MAX; + attributes->can_get_priority = is_external; + attributes->can_set_priority = is_external; if (vector == RISCV_INTERRUPT_VECTOR_SOFTWARE) { attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL; @@ -619,6 +626,39 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (!RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) { + return RTEMS_UNSATISFIED; + } + + riscv_plic->priority[RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector)] = + UINT32_MAX - priority; + return RTEMS_SUCCESSFUL; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + + if (!RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) { + return RTEMS_UNSATISFIED; + } + + *priority = UINT32_MAX - + riscv_plic->priority[RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector)]; + return RTEMS_SUCCESSFUL; +} + #ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, diff --git a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c index 3280671ab6..4bff328d55 100644 --- a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c +++ b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c @@ -45,6 +45,9 @@ rtems_status_code bsp_interrupt_get_attributes( attributes->maybe_enable = true; attributes->maybe_disable = true; attributes->can_raise = true; + attributes->can_get_priority = true; + attributes->can_set_priority = true; + attributes->maximum_priority = 255; if ( vector <= ARM_GIC_IRQ_SGI_LAST ) { /* diff --git a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c index ee4479155a..051764f731 100644 --- a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c +++ b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c @@ -46,6 +46,9 @@ rtems_status_code bsp_interrupt_get_attributes( attributes->maybe_enable = true; attributes->maybe_disable = true; attributes->can_raise = true; + attributes->can_get_priority = true; + attributes->can_set_priority = true; + attributes->maximum_priority = 255; if ( vector <= ARM_GIC_IRQ_SGI_LAST ) { /* diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c index 3cd27b2fa6..b76d263631 100644 --- a/bsps/shared/dev/irq/arm-gicv2.c +++ b/bsps/shared/dev/irq/arm-gicv2.c @@ -255,40 +255,36 @@ BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void) } #endif -rtems_status_code arm_gic_irq_set_priority( +rtems_status_code bsp_interrupt_set_priority( rtems_vector_number vector, - uint8_t priority + uint32_t priority ) { - rtems_status_code sc = RTEMS_SUCCESSFUL; + volatile gic_dist *dist = ARM_GIC_DIST; + uint8_t gic_priority = (uint8_t) priority; - if (bsp_interrupt_is_valid_vector(vector)) { - volatile gic_dist *dist = ARM_GIC_DIST; + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - gic_id_set_priority(dist, vector, priority); - } else { - sc = RTEMS_INVALID_ID; + if (gic_priority != priority) { + return RTEMS_INVALID_PRIORITY; } - return sc; + gic_id_set_priority(dist, vector, gic_priority); + return RTEMS_SUCCESSFUL; } -rtems_status_code arm_gic_irq_get_priority( +rtems_status_code bsp_interrupt_get_priority( rtems_vector_number vector, - uint8_t *priority + uint32_t *priority ) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - - if (bsp_interrupt_is_valid_vector(vector)) { - volatile gic_dist *dist = ARM_GIC_DIST; + volatile gic_dist *dist = ARM_GIC_DIST; - *priority = gic_id_get_priority(dist, vector); - } else { - sc = RTEMS_INVALID_ID; - } + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); - return sc; + *priority = gic_id_get_priority(dist, vector); + return RTEMS_SUCCESSFUL; } rtems_status_code arm_gic_irq_set_group( diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c index f85582ccff..bd5f684678 100644 --- a/bsps/shared/dev/irq/arm-gicv3.c +++ b/bsps/shared/dev/irq/arm-gicv3.c @@ -192,53 +192,52 @@ BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void) } #endif -rtems_status_code arm_gic_irq_set_priority( +rtems_status_code bsp_interrupt_set_priority( rtems_vector_number vector, - uint8_t priority + uint32_t priority ) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - - if (bsp_interrupt_is_valid_vector(vector)) { - if (vector >= 32) { - volatile gic_dist *dist = ARM_GIC_DIST; - gic_id_set_priority(dist, vector, priority); - } else { - gicv3_sgi_ppi_set_priority( - vector, - priority, - _SMP_Get_current_processor() - ); - } + uint8_t gic_priority = (uint8_t) priority; + + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (gic_priority != priority) { + return RTEMS_INVALID_PRIORITY; + } + + if (vector >= 32) { + volatile gic_dist *dist = ARM_GIC_DIST; + gic_id_set_priority(dist, vector, priority); } else { - sc = RTEMS_INVALID_ID; + gicv3_sgi_ppi_set_priority( + vector, + priority, + _SMP_Get_current_processor() + ); } - return sc; + return RTEMS_SUCCESSFUL; } -rtems_status_code arm_gic_irq_get_priority( +rtems_status_code bsp_interrupt_get_priority( rtems_vector_number vector, - uint8_t *priority + uint32_t *priority ) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - - if (bsp_interrupt_is_valid_vector(vector)) { - if (vector >= 32) { - volatile gic_dist *dist = ARM_GIC_DIST; - *priority = gic_id_get_priority(dist, vector); - } else { - *priority = gicv3_sgi_ppi_get_priority( - vector, - _SMP_Get_current_processor() - ); - } + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + + if (vector >= 32) { + volatile gic_dist *dist = ARM_GIC_DIST; + *priority = gic_id_get_priority(dist, vector); } else { - sc = RTEMS_INVALID_ID; + *priority = gicv3_sgi_ppi_get_priority( + vector, + _SMP_Get_current_processor() + ); } - return sc; + return RTEMS_SUCCESSFUL; } #ifdef RTEMS_SMP diff --git a/bsps/shared/irq/irq-default.c b/bsps/shared/irq/irq-default.c index 7210235aa6..d3eff19648 100644 --- a/bsps/shared/irq/irq-default.c +++ b/bsps/shared/irq/irq-default.c @@ -93,6 +93,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_UNSATISFIED; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + void bsp_interrupt_facility_initialize(void) { /* Nothing to do */ diff --git a/bsps/shared/irq/irq-priority.c b/bsps/shared/irq/irq-priority.c new file mode 100644 index 0000000000..f3eb5a880a --- /dev/null +++ b/bsps/shared/irq/irq-priority.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSImplClassicIntr + * + * @brief This source file contains the implementation of + * rtems_interrupt_get_priority() and rtems_interrupt_set_priority(). + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <bsp/irq-generic.h> + +rtems_status_code rtems_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + if (!bsp_interrupt_is_valid_vector(vector)) { + return RTEMS_INVALID_ID; + } + + return bsp_interrupt_set_priority(vector, priority); +} + +rtems_status_code rtems_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + if (priority == NULL) { + return RTEMS_INVALID_ADDRESS; + } + + if (!bsp_interrupt_is_valid_vector(vector)) { + return RTEMS_INVALID_ID; + } + + return bsp_interrupt_get_priority(vector, priority); +} diff --git a/bsps/sparc/leon3/start/eirq.c b/bsps/sparc/leon3/start/eirq.c index a0934a7848..b6e106c587 100644 --- a/bsps/sparc/leon3/start/eirq.c +++ b/bsps/sparc/leon3/start/eirq.c @@ -353,6 +353,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + #if defined(RTEMS_SMP) rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, diff --git a/bsps/sparc/shared/irq/irq-shared.c b/bsps/sparc/shared/irq/irq-shared.c index 18360b2b8e..c4190d860b 100644 --- a/bsps/sparc/shared/irq/irq-shared.c +++ b/bsps/sparc/shared/irq/irq-shared.c @@ -141,6 +141,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + #if defined(RTEMS_SMP) rtems_status_code bsp_interrupt_get_affinity( rtems_vector_number vector, diff --git a/bsps/x86_64/amd64/interrupts/idt.c b/bsps/x86_64/amd64/interrupts/idt.c index 4a2949450a..cc6eb77e8b 100644 --- a/bsps/x86_64/amd64/interrupts/idt.c +++ b/bsps/x86_64/amd64/interrupts/idt.c @@ -145,6 +145,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +rtems_status_code bsp_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + bsp_interrupt_assert(priority != NULL); + return RTEMS_UNSATISFIED; +} + rtems_status_code bsp_interrupt_get_attributes( rtems_vector_number vector, rtems_interrupt_attributes *attributes diff --git a/cpukit/include/rtems/rtems/intr.h b/cpukit/include/rtems/rtems/intr.h index f682112bf5..b40c640534 100644 --- a/cpukit/include/rtems/rtems/intr.h +++ b/cpukit/include/rtems/rtems/intr.h @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2008, 2022 embedded brains GmbH & Co. KG + * Copyright (C) 2008, 2024 embedded brains GmbH & Co. KG * Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without @@ -1688,6 +1688,147 @@ rtems_status_code rtems_interrupt_raise_on( */ rtems_status_code rtems_interrupt_clear( rtems_vector_number vector ); +/* Generated from spec:/rtems/intr/if/get-priority */ + +/** + * @ingroup RTEMSAPIClassicIntr + * + * @brief Gets the priority of the interrupt vector. + * + * @param vector is the interrupt vector number. + * + * @param[out] priority is the pointer to an uint32_t object. When the + * directive call is successful, the priority of the interrupt vector will be + * stored in this object. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_INVALID_ADDRESS The ``priority`` parameter was NULL. + * + * @retval ::RTEMS_INVALID_ID There was no interrupt vector associated with the + * number specified by ``vector``. + * + * @retval ::RTEMS_UNSATISFIED There is no priority associated with the + * interrupt vector. + * + * @par Notes + * The rtems_interrupt_set_priority() directive may be used to set the priority + * associated with an interrupt vector. + * + * @par Constraints + * @parblock + * The following constraints apply to this directive: + * + * * The directive may be called from within interrupt context. + * + * * The directive may be called from within device driver initialization + * context. + * + * * The directive may be called from within task context. + * + * * The directive will not cause the calling task to be preempted. + * @endparblock + */ +rtems_status_code rtems_interrupt_get_priority( + rtems_vector_number vector, + uint32_t *priority +); + +/* Generated from spec:/rtems/intr/if/set-priority */ + +/** + * @ingroup RTEMSAPIClassicIntr + * + * @brief Sets the priority of the interrupt vector. + * + * @param vector is the interrupt vector number. + * + * @param priority is the new priority for the interrupt vector. + * + * This directive sets the priority of the interrupt specified by ``vector`` to + * the priority specified by ``priority``. + * + * For processor-specific interrupts, the priority of the interrupt specific to + * a processor executing the directive call will be set. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_INVALID_ID There was no interrupt vector associated with the + * number specified by ``vector``. + * + * @retval ::RTEMS_INVALID_PRIORITY The priority specified by ``priority`` was + * not a valid new priority for the interrupt vector. + * + * @retval ::RTEMS_UNSATISFIED The request to set the priority of the interrupt + * vector has not been satisfied. + * + * @par Notes + * @parblock + * The rtems_interrupt_get_priority() directive may be used to get the priority + * associated with an interrupt vector. + * + * The interrupt prioritization support depends on the interrupt controller of + * the target. It is strongly recommended to read the relevant hardware + * documentation. What happens when the priority of a pending or active + * interrupt is changed, depends on the interrupt controller. In general, you + * should set the interrupt priority of an interrupt vector before a handler is + * installed. On some interrupt controllers, setting the priority to the + * maximum value (lowest importance) effectively disables the interrupt. On + * some architectures, a range of interrupt priority values may be not disabled + * by the interrupt disable directives. Handlers of such interrupts shall not + * use operating system services. + * + * For the ARM Generic Interrupt Controller (GIC), an 8-bit priority value is + * supported. The granularity of the priority levels depends on the interrupt + * controller configuration. Some low-order bits of a priority value may be + * read-as-zero (RAZ) and writes are ignored (WI). Where group 0 (FIQ) and + * group 1 (IRQ) interrupts are used, it is recommended to use the lower half + * of the supported priority value range for the group 0 interrupts and the + * upper half for group 1 interrupts. This ensures that group 1 interrupts + * cannot preempt group 0 interrupts. + * + * For the Armv7-M Nested Vector Interrupt Controller (NVIC), an 8-bit priority + * value is supported. The granularity of the priority levels depends on the + * interrupt controller configuration. Some lower bits of a priority value may + * be read-as-zero (RAZ) and writes are ignored (WI). Interrupts with a + * priority value less than 128 are not disabled by the RTEMS interrupt disable + * directives. Handlers of such interrupts shall not use operating system + * services. + * + * For the RISC-V Platform-Level Interrupt Controller (PLIC), all priority + * values from 0 up to and including the 0xffffffff are supported since the + * priority for the PLIC is defined by a write-any-read-legal (WARL) register. + * Please note that for this directive in contrast to the PLIC, a higher + * priority value is associated with a lower importance. The maximum priority + * value (mapped to the value 0 for the PLIC) is reserved to mean "never + * interrupt" and effectively disables the interrupt. + * + * For the QorIQ Multicore Programmable Interrupt Controller (MPIC), a 4-bit + * priority value is supported. Please note that for this directive in + * contrast to the MPIC, a higher priority value is associated with a lower + * importance. The maximum priority value of 15 (mapped to the value 0 for the + * MPIC) inhibits signalling of this interrupt. + * @endparblock + * + * @par Constraints + * @parblock + * The following constraints apply to this directive: + * + * * The directive may be called from within interrupt context. + * + * * The directive may be called from within device driver initialization + * context. + * + * * The directive may be called from within task context. + * + * * The directive will not cause the calling task to be preempted. + * @endparblock + */ +rtems_status_code rtems_interrupt_set_priority( + rtems_vector_number vector, + uint32_t priority +); + /* Generated from spec:/rtems/intr/if/get-affinity */ /** @@ -1965,6 +2106,29 @@ typedef struct { * rtems_interrupt_raise(), or rtems_interrupt_raise_on(). */ rtems_interrupt_signal_variant trigger_signal; + + /** + * @brief This member is true, if the priority of the interrupt vector can be + * obtained by rtems_interrupt_get_priority(), otherwise it is false. + */ + bool can_get_priority; + + /** + * @brief This member is true, if the priority of the interrupt vector can be + * set by rtems_interrupt_set_priority(), otherwise it is false. + */ + bool can_set_priority; + + /** + * @brief This member represents the maximum priority value of the interrupt + * vector. By convention, the minimum priority value is zero. Lower + * priority values shall be associated with a higher importance. The higher + * the priority value, the less important is the service of the associated + * interrupt vector. Where nested interrupts are supported, interrupts with + * a lower priority value may preempt other interrupts having a higher + * priority value. + */ + uint32_t maximum_priority; } rtems_interrupt_attributes; /* Generated from spec:/rtems/intr/if/get-attributes */ diff --git a/spec/build/bsps/objirq.yml b/spec/build/bsps/objirq.yml index 2a817649d3..916cd1de12 100644 --- a/spec/build/bsps/objirq.yml +++ b/spec/build/bsps/objirq.yml @@ -21,6 +21,7 @@ source: - bsps/shared/irq/irq-info.c - bsps/shared/irq/irq-legacy.c - bsps/shared/irq/irq-lock.c +- bsps/shared/irq/irq-priority.c - bsps/shared/irq/irq-record.c - bsps/shared/irq/irq-server.c - bsps/shared/irq/irq-shell.c diff --git a/spec/build/bsps/powerpc/ss555/bspss555.yml b/spec/build/bsps/powerpc/ss555/bspss555.yml index c97bbedf9f..d496aa4c20 100644 --- a/spec/build/bsps/powerpc/ss555/bspss555.yml +++ b/spec/build/bsps/powerpc/ss555/bspss555.yml @@ -80,6 +80,7 @@ source: - bsps/shared/irq/irq-handler-remove.c - bsps/shared/irq/irq-info.c - bsps/shared/irq/irq-lock.c +- bsps/shared/irq/irq-priority.c - bsps/shared/irq/irq-record.c - bsps/shared/irq/irq-server.c - bsps/shared/irq/irq-shell.c diff --git a/spec/build/testsuites/validation/validation-intr.yml b/spec/build/testsuites/validation/validation-intr.yml index bd3e888fce..eaf37da8d5 100644 --- a/spec/build/testsuites/validation/validation-intr.yml +++ b/spec/build/testsuites/validation/validation-intr.yml @@ -22,11 +22,13 @@ source: - testsuites/validation/tc-intr-entry-remove.c - testsuites/validation/tc-intr-get-affinity.c - testsuites/validation/tc-intr-get-attributes.c +- testsuites/validation/tc-intr-get-priority.c - testsuites/validation/tc-intr-handler-iterate.c - testsuites/validation/tc-intr-is-pending.c - testsuites/validation/tc-intr-raise.c - testsuites/validation/tc-intr-raise-on.c - testsuites/validation/tc-intr-set-affinity.c +- testsuites/validation/tc-intr-set-priority.c - testsuites/validation/tc-intr-vector-disable.c - testsuites/validation/tc-intr-vector-enable.c - testsuites/validation/tc-intr-vector-is-enabled.c diff --git a/testsuites/validation/tc-intr-get-priority.c b/testsuites/validation/tc-intr-get-priority.c new file mode 100644 index 0000000000..8975acddb5 --- /dev/null +++ b/testsuites/validation/tc-intr-get-priority.c @@ -0,0 +1,567 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RtemsIntrReqGetPriority + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <bsp/irq-generic.h> + +#include "tx-support.h" + +#include <rtems/test.h> + +/** + * @defgroup RtemsIntrReqGetPriority spec:/rtems/intr/req/get-priority + * + * @ingroup TestsuitesValidationIntr + * + * @{ + */ + +typedef enum { + RtemsIntrReqGetPriority_Pre_Vector_Valid, + RtemsIntrReqGetPriority_Pre_Vector_Invalid, + RtemsIntrReqGetPriority_Pre_Vector_NA +} RtemsIntrReqGetPriority_Pre_Vector; + +typedef enum { + RtemsIntrReqGetPriority_Pre_Priority_Valid, + RtemsIntrReqGetPriority_Pre_Priority_Null, + RtemsIntrReqGetPriority_Pre_Priority_NA +} RtemsIntrReqGetPriority_Pre_Priority; + +typedef enum { + RtemsIntrReqGetPriority_Pre_CanGetPriority_Yes, + RtemsIntrReqGetPriority_Pre_CanGetPriority_No, + RtemsIntrReqGetPriority_Pre_CanGetPriority_NA +} RtemsIntrReqGetPriority_Pre_CanGetPriority; + +typedef enum { + RtemsIntrReqGetPriority_Post_Status_Ok, + RtemsIntrReqGetPriority_Post_Status_InvAddr, + RtemsIntrReqGetPriority_Post_Status_InvId, + RtemsIntrReqGetPriority_Post_Status_Unsat, + RtemsIntrReqGetPriority_Post_Status_NA +} RtemsIntrReqGetPriority_Post_Status; + +typedef enum { + RtemsIntrReqGetPriority_Post_PriorityObj_Set, + RtemsIntrReqGetPriority_Post_PriorityObj_Nop, + RtemsIntrReqGetPriority_Post_PriorityObj_NA +} RtemsIntrReqGetPriority_Post_PriorityObj; + +typedef struct { + uint16_t Skip : 1; + uint16_t Pre_Vector_NA : 1; + uint16_t Pre_Priority_NA : 1; + uint16_t Pre_CanGetPriority_NA : 1; + uint16_t Post_Status : 3; + uint16_t Post_PriorityObj : 2; +} RtemsIntrReqGetPriority_Entry; + +/** + * @brief Test context for spec:/rtems/intr/req/get-priority test case. + */ +typedef struct { + /** + * @brief This member provides the object referenced by the ``priority`` + * parameter. + */ + uint32_t priority_obj; + + /** + * @brief If this member is true, then the ``vector`` parameter shall be + * valid. + */ + bool valid_vector; + + /** + * @brief If this member is true, then getting the priority shall be + * supported. + */ + bool can_get_priority; + + /** + * @brief This member specifies the ``priority`` parameter value. + */ + uint32_t *priority; + + /** + * @brief This member specifies the expected status. + */ + rtems_status_code expected_status; + + /** + * @brief This member specifies the expected value of the priority object. + */ + void (*expected_priority)(uint32_t); + + struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + + /** + * @brief This member defines the pre-condition states for the next action. + */ + size_t pcs[ 3 ]; + + /** + * @brief If this member is true, then the test action loop is executed. + */ + bool in_action_loop; + + /** + * @brief This member contains the next transition map index. + */ + size_t index; + + /** + * @brief This member contains the current transition map entry. + */ + RtemsIntrReqGetPriority_Entry entry; + + /** + * @brief If this member is true, then the current transition variant + * should be skipped. + */ + bool skip; + } Map; +} RtemsIntrReqGetPriority_Context; + +static RtemsIntrReqGetPriority_Context + RtemsIntrReqGetPriority_Instance; + +static const char * const RtemsIntrReqGetPriority_PreDesc_Vector[] = { + "Valid", + "Invalid", + "NA" +}; + +static const char * const RtemsIntrReqGetPriority_PreDesc_Priority[] = { + "Valid", + "Null", + "NA" +}; + +static const char * const RtemsIntrReqGetPriority_PreDesc_CanGetPriority[] = { + "Yes", + "No", + "NA" +}; + +static const char * const * const RtemsIntrReqGetPriority_PreDesc[] = { + RtemsIntrReqGetPriority_PreDesc_Vector, + RtemsIntrReqGetPriority_PreDesc_Priority, + RtemsIntrReqGetPriority_PreDesc_CanGetPriority, + NULL +}; + +typedef RtemsIntrReqGetPriority_Context Context; + +#define PRIORITY_UNSET (UINT32_MAX - 1234) + +static void PriorityIsSet( uint32_t priority ) +{ + T_lt_u32( priority, PRIORITY_UNSET ); +} + +static void PriorityIsNotSet( uint32_t priority ) +{ + T_eq_u32( priority, PRIORITY_UNSET ); +} + +static void CheckGetPriority( Context *ctx, rtems_vector_number vector ) +{ + rtems_status_code sc; + + ctx->priority_obj = PRIORITY_UNSET; + sc = rtems_interrupt_get_priority( vector, ctx->priority ); + T_rsc( sc, ctx->expected_status ); + (*ctx->expected_priority)( ctx->priority_obj ); +} + +static void RtemsIntrReqGetPriority_Pre_Vector_Prepare( + RtemsIntrReqGetPriority_Context *ctx, + RtemsIntrReqGetPriority_Pre_Vector state +) +{ + switch ( state ) { + case RtemsIntrReqGetPriority_Pre_Vector_Valid: { + /* + * While the ``vector`` parameter is associated with an interrupt vector. + */ + ctx->valid_vector = true; + break; + } + + case RtemsIntrReqGetPriority_Pre_Vector_Invalid: { + /* + * While the ``vector`` parameter is not associated with an interrupt + * vector. + */ + ctx->valid_vector = false; + break; + } + + case RtemsIntrReqGetPriority_Pre_Vector_NA: + break; + } +} + +static void RtemsIntrReqGetPriority_Pre_Priority_Prepare( + RtemsIntrReqGetPriority_Context *ctx, + RtemsIntrReqGetPriority_Pre_Priority state +) +{ + switch ( state ) { + case RtemsIntrReqGetPriority_Pre_Priority_Valid: { + /* + * While the ``priority`` parameter references an object of type + * uint32_t. + */ + ctx->priority = &ctx->priority_obj; + break; + } + + case RtemsIntrReqGetPriority_Pre_Priority_Null: { + /* + * While the ``priority`` parameter is equal to NULL. + */ + ctx->priority = NULL; + break; + } + + case RtemsIntrReqGetPriority_Pre_Priority_NA: + break; + } +} + +static void RtemsIntrReqGetPriority_Pre_CanGetPriority_Prepare( + RtemsIntrReqGetPriority_Context *ctx, + RtemsIntrReqGetPriority_Pre_CanGetPriority state +) +{ + switch ( state ) { + case RtemsIntrReqGetPriority_Pre_CanGetPriority_Yes: { + /* + * While getting the priority for the interrupt vector specified by + * ``vector`` parameter is supported. + */ + ctx->can_get_priority = true; + break; + } + + case RtemsIntrReqGetPriority_Pre_CanGetPriority_No: { + /* + * While getting the priority for the interrupt vector specified by + * ``vector`` parameter is not supported. + */ + ctx->can_get_priority = false; + break; + } + + case RtemsIntrReqGetPriority_Pre_CanGetPriority_NA: + break; + } +} + +static void RtemsIntrReqGetPriority_Post_Status_Check( + RtemsIntrReqGetPriority_Context *ctx, + RtemsIntrReqGetPriority_Post_Status state +) +{ + switch ( state ) { + case RtemsIntrReqGetPriority_Post_Status_Ok: { + /* + * The return status of rtems_interrupt_get_priority() shall be + * RTEMS_SUCCESSFUL. + */ + ctx->expected_status = RTEMS_SUCCESSFUL; + break; + } + + case RtemsIntrReqGetPriority_Post_Status_InvAddr: { + /* + * The return status of rtems_interrupt_get_priority() shall be + * RTEMS_INVALID_ADDRESS. + */ + ctx->expected_status = RTEMS_INVALID_ADDRESS; + break; + } + + case RtemsIntrReqGetPriority_Post_Status_InvId: { + /* + * The return status of rtems_interrupt_get_priority() shall be + * RTEMS_INVALID_ID. + */ + ctx->expected_status = RTEMS_INVALID_ID; + break; + } + + case RtemsIntrReqGetPriority_Post_Status_Unsat: { + /* + * The return status of rtems_interrupt_get_priority() shall be + * RTEMS_UNSATISFIED. + */ + ctx->expected_status = RTEMS_UNSATISFIED; + break; + } + + case RtemsIntrReqGetPriority_Post_Status_NA: + break; + } +} + +static void RtemsIntrReqGetPriority_Post_PriorityObj_Check( + RtemsIntrReqGetPriority_Context *ctx, + RtemsIntrReqGetPriority_Post_PriorityObj state +) +{ + ctx->expected_priority = PriorityIsNotSet; + + switch ( state ) { + case RtemsIntrReqGetPriority_Post_PriorityObj_Set: { + /* + * The value of the object referenced by the ``priority`` parameter shall + * be set by the directive call to a priority which the interrupt + * specified by the ``vector`` parameter had at some time point during + * the directive call. + */ + ctx->expected_priority = PriorityIsSet; + break; + } + + case RtemsIntrReqGetPriority_Post_PriorityObj_Nop: { + /* + * The value of the object referenced by the ``priority`` parameter shall + * not be changed by the directive call. + */ + ctx->expected_priority = PriorityIsNotSet; + break; + } + + case RtemsIntrReqGetPriority_Post_PriorityObj_NA: + break; + } +} + +static void RtemsIntrReqGetPriority_Action( + RtemsIntrReqGetPriority_Context *ctx +) +{ + /* Action carried out by CheckGetPriority() */ +} + +static void RtemsIntrReqGetPriority_Cleanup( + RtemsIntrReqGetPriority_Context *ctx +) +{ + if ( ctx->valid_vector ) { + rtems_vector_number vector; + + for ( + vector = 0; + vector < BSP_INTERRUPT_VECTOR_COUNT; + ++vector + ) { + rtems_interrupt_attributes attr; + rtems_status_code sc; + + memset( &attr, 0, sizeof( attr ) ); + sc = rtems_interrupt_get_attributes( vector, &attr ); + + if ( sc == RTEMS_INVALID_ID ) { + continue; + } + + T_rsc_success( sc ); + + if ( attr.can_get_priority != ctx->can_get_priority ) { + continue; + } + + CheckGetPriority( ctx, vector ); + } + } else { + CheckGetPriority( ctx, BSP_INTERRUPT_VECTOR_COUNT ); + } +} + +static const RtemsIntrReqGetPriority_Entry +RtemsIntrReqGetPriority_Entries[] = { + { 0, 0, 0, 0, RtemsIntrReqGetPriority_Post_Status_InvAddr, + RtemsIntrReqGetPriority_Post_PriorityObj_NA }, + { 0, 0, 0, 1, RtemsIntrReqGetPriority_Post_Status_InvId, + RtemsIntrReqGetPriority_Post_PriorityObj_Nop }, + { 0, 0, 0, 1, RtemsIntrReqGetPriority_Post_Status_InvAddr, + RtemsIntrReqGetPriority_Post_PriorityObj_NA }, + { 0, 0, 0, 0, RtemsIntrReqGetPriority_Post_Status_Ok, + RtemsIntrReqGetPriority_Post_PriorityObj_Set }, + { 0, 0, 0, 0, RtemsIntrReqGetPriority_Post_Status_Unsat, + RtemsIntrReqGetPriority_Post_PriorityObj_Nop } +}; + +static const uint8_t +RtemsIntrReqGetPriority_Map[] = { + 3, 4, 0, 0, 1, 1, 2, 2 +}; + +static size_t RtemsIntrReqGetPriority_Scope( void *arg, char *buf, size_t n ) +{ + RtemsIntrReqGetPriority_Context *ctx; + + ctx = arg; + + if ( ctx->Map.in_action_loop ) { + return T_get_scope( + RtemsIntrReqGetPriority_PreDesc, + buf, + n, + ctx->Map.pcs + ); + } + + return 0; +} + +static T_fixture RtemsIntrReqGetPriority_Fixture = { + .setup = NULL, + .stop = NULL, + .teardown = NULL, + .scope = RtemsIntrReqGetPriority_Scope, + .initial_context = &RtemsIntrReqGetPriority_Instance +}; + +static inline RtemsIntrReqGetPriority_Entry RtemsIntrReqGetPriority_PopEntry( + RtemsIntrReqGetPriority_Context *ctx +) +{ + size_t index; + + index = ctx->Map.index; + ctx->Map.index = index + 1; + return RtemsIntrReqGetPriority_Entries[ + RtemsIntrReqGetPriority_Map[ index ] + ]; +} + +static void RtemsIntrReqGetPriority_SetPreConditionStates( + RtemsIntrReqGetPriority_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + + if ( ctx->Map.entry.Pre_CanGetPriority_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqGetPriority_Pre_CanGetPriority_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + +static void RtemsIntrReqGetPriority_TestVariant( + RtemsIntrReqGetPriority_Context *ctx +) +{ + RtemsIntrReqGetPriority_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); + RtemsIntrReqGetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 1 ] ); + RtemsIntrReqGetPriority_Pre_CanGetPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] ); + RtemsIntrReqGetPriority_Action( ctx ); + RtemsIntrReqGetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); + RtemsIntrReqGetPriority_Post_PriorityObj_Check( + ctx, + ctx->Map.entry.Post_PriorityObj + ); +} + +/** + * @fn void T_case_body_RtemsIntrReqGetPriority( void ) + */ +T_TEST_CASE_FIXTURE( + RtemsIntrReqGetPriority, + &RtemsIntrReqGetPriority_Fixture +) +{ + RtemsIntrReqGetPriority_Context *ctx; + + ctx = T_fixture_context(); + ctx->Map.in_action_loop = true; + ctx->Map.index = 0; + + for ( + ctx->Map.pci[ 0 ] = RtemsIntrReqGetPriority_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqGetPriority_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] + ) { + for ( + ctx->Map.pci[ 1 ] = RtemsIntrReqGetPriority_Pre_Priority_Valid; + ctx->Map.pci[ 1 ] < RtemsIntrReqGetPriority_Pre_Priority_NA; + ++ctx->Map.pci[ 1 ] + ) { + for ( + ctx->Map.pci[ 2 ] = RtemsIntrReqGetPriority_Pre_CanGetPriority_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqGetPriority_Pre_CanGetPriority_NA; + ++ctx->Map.pci[ 2 ] + ) { + ctx->Map.entry = RtemsIntrReqGetPriority_PopEntry( ctx ); + RtemsIntrReqGetPriority_SetPreConditionStates( ctx ); + RtemsIntrReqGetPriority_TestVariant( ctx ); + RtemsIntrReqGetPriority_Cleanup( ctx ); + } + } + } +} + +/** @} */ diff --git a/testsuites/validation/tc-intr-set-priority.c b/testsuites/validation/tc-intr-set-priority.c new file mode 100644 index 0000000000..3742f2162d --- /dev/null +++ b/testsuites/validation/tc-intr-set-priority.c @@ -0,0 +1,504 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RtemsIntrReqSetPriority + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <bsp/irq-generic.h> + +#include "tx-support.h" + +#include <rtems/test.h> + +/** + * @defgroup RtemsIntrReqSetPriority spec:/rtems/intr/req/set-priority + * + * @ingroup TestsuitesValidationIntr + * + * @{ + */ + +typedef enum { + RtemsIntrReqSetPriority_Pre_Vector_Valid, + RtemsIntrReqSetPriority_Pre_Vector_Invalid, + RtemsIntrReqSetPriority_Pre_Vector_NA +} RtemsIntrReqSetPriority_Pre_Vector; + +typedef enum { + RtemsIntrReqSetPriority_Pre_Priority_Valid, + RtemsIntrReqSetPriority_Pre_Priority_Invalid, + RtemsIntrReqSetPriority_Pre_Priority_NA +} RtemsIntrReqSetPriority_Pre_Priority; + +typedef enum { + RtemsIntrReqSetPriority_Pre_CanSetPriority_Yes, + RtemsIntrReqSetPriority_Pre_CanSetPriority_No, + RtemsIntrReqSetPriority_Pre_CanSetPriority_NA +} RtemsIntrReqSetPriority_Pre_CanSetPriority; + +typedef enum { + RtemsIntrReqSetPriority_Post_Status_Ok, + RtemsIntrReqSetPriority_Post_Status_InvId, + RtemsIntrReqSetPriority_Post_Status_InvPrio, + RtemsIntrReqSetPriority_Post_Status_Unsat, + RtemsIntrReqSetPriority_Post_Status_NA +} RtemsIntrReqSetPriority_Post_Status; + +typedef struct { + uint8_t Skip : 1; + uint8_t Pre_Vector_NA : 1; + uint8_t Pre_Priority_NA : 1; + uint8_t Pre_CanSetPriority_NA : 1; + uint8_t Post_Status : 3; +} RtemsIntrReqSetPriority_Entry; + +/** + * @brief Test context for spec:/rtems/intr/req/set-priority test case. + */ +typedef struct { + /** + * @brief If this member is true, then the ``vector`` parameter shall be + * valid. + */ + bool valid_vector; + + /** + * @brief If this member is true, then the ``priority`` parameter shall be + * valid. + */ + bool valid_priority; + + /** + * @brief If this member is true, then setting the priority shall be + * supported. + */ + bool can_set_priority; + + /** + * @brief This member specifies the expected status. + */ + rtems_status_code expected_status; + + struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + + /** + * @brief This member defines the pre-condition states for the next action. + */ + size_t pcs[ 3 ]; + + /** + * @brief If this member is true, then the test action loop is executed. + */ + bool in_action_loop; + + /** + * @brief This member contains the next transition map index. + */ + size_t index; + + /** + * @brief This member contains the current transition map entry. + */ + RtemsIntrReqSetPriority_Entry entry; + + /** + * @brief If this member is true, then the current transition variant + * should be skipped. + */ + bool skip; + } Map; +} RtemsIntrReqSetPriority_Context; + +static RtemsIntrReqSetPriority_Context + RtemsIntrReqSetPriority_Instance; + +static const char * const RtemsIntrReqSetPriority_PreDesc_Vector[] = { + "Valid", + "Invalid", + "NA" +}; + +static const char * const RtemsIntrReqSetPriority_PreDesc_Priority[] = { + "Valid", + "Invalid", + "NA" +}; + +static const char * const RtemsIntrReqSetPriority_PreDesc_CanSetPriority[] = { + "Yes", + "No", + "NA" +}; + +static const char * const * const RtemsIntrReqSetPriority_PreDesc[] = { + RtemsIntrReqSetPriority_PreDesc_Vector, + RtemsIntrReqSetPriority_PreDesc_Priority, + RtemsIntrReqSetPriority_PreDesc_CanSetPriority, + NULL +}; + +typedef RtemsIntrReqSetPriority_Context Context; + +static void CheckSetPriority( Context *ctx, rtems_vector_number vector ) +{ + rtems_status_code sc; + uint32_t priority; + + if ( ctx->valid_priority ) { + (void) rtems_interrupt_get_priority( vector, &priority ); + } else { + priority = UINT32_MAX; + } + + sc = rtems_interrupt_set_priority( vector, priority ); + T_rsc( sc, ctx->expected_status ); +} + +static void RtemsIntrReqSetPriority_Pre_Vector_Prepare( + RtemsIntrReqSetPriority_Context *ctx, + RtemsIntrReqSetPriority_Pre_Vector state +) +{ + switch ( state ) { + case RtemsIntrReqSetPriority_Pre_Vector_Valid: { + /* + * While the ``vector`` parameter is associated with an interrupt vector. + */ + ctx->valid_vector = true; + break; + } + + case RtemsIntrReqSetPriority_Pre_Vector_Invalid: { + /* + * While the ``vector`` parameter is not associated with an interrupt + * vector. + */ + ctx->valid_vector = false; + break; + } + + case RtemsIntrReqSetPriority_Pre_Vector_NA: + break; + } +} + +static void RtemsIntrReqSetPriority_Pre_Priority_Prepare( + RtemsIntrReqSetPriority_Context *ctx, + RtemsIntrReqSetPriority_Pre_Priority state +) +{ + switch ( state ) { + case RtemsIntrReqSetPriority_Pre_Priority_Valid: { + /* + * While the ``priority`` parameter is a valid priority value. + */ + ctx->valid_priority = true; + break; + } + + case RtemsIntrReqSetPriority_Pre_Priority_Invalid: { + /* + * While the ``priority`` parameter is an invalid priority value. + */ + ctx->valid_priority = false; + break; + } + + case RtemsIntrReqSetPriority_Pre_Priority_NA: + break; + } +} + +static void RtemsIntrReqSetPriority_Pre_CanSetPriority_Prepare( + RtemsIntrReqSetPriority_Context *ctx, + RtemsIntrReqSetPriority_Pre_CanSetPriority state +) +{ + switch ( state ) { + case RtemsIntrReqSetPriority_Pre_CanSetPriority_Yes: { + /* + * While setting the priority for the interrupt vector specified by + * ``vector`` parameter is supported. + */ + ctx->can_set_priority = true; + break; + } + + case RtemsIntrReqSetPriority_Pre_CanSetPriority_No: { + /* + * While setting the priority for the interrupt vector specified by + * ``vector`` parameter is not supported. + */ + ctx->can_set_priority = false; + break; + } + + case RtemsIntrReqSetPriority_Pre_CanSetPriority_NA: + break; + } +} + +static void RtemsIntrReqSetPriority_Post_Status_Check( + RtemsIntrReqSetPriority_Context *ctx, + RtemsIntrReqSetPriority_Post_Status state +) +{ + switch ( state ) { + case RtemsIntrReqSetPriority_Post_Status_Ok: { + /* + * The return status of rtems_interrupt_set_priority() shall be + * RTEMS_SUCCESSFUL. + */ + ctx->expected_status = RTEMS_SUCCESSFUL; + break; + } + + case RtemsIntrReqSetPriority_Post_Status_InvId: { + /* + * The return status of rtems_interrupt_set_priority() shall be + * RTEMS_INVALID_ID. + */ + ctx->expected_status = RTEMS_INVALID_ID; + break; + } + + case RtemsIntrReqSetPriority_Post_Status_InvPrio: { + /* + * The return status of rtems_interrupt_set_priority() shall be + * RTEMS_INVALID_PRIORITY. + */ + ctx->expected_status = RTEMS_INVALID_PRIORITY; + break; + } + + case RtemsIntrReqSetPriority_Post_Status_Unsat: { + /* + * The return status of rtems_interrupt_set_priority() shall be + * RTEMS_UNSATISFIED. + */ + ctx->expected_status = RTEMS_UNSATISFIED; + break; + } + + case RtemsIntrReqSetPriority_Post_Status_NA: + break; + } +} + +static void RtemsIntrReqSetPriority_Action( + RtemsIntrReqSetPriority_Context *ctx +) +{ + /* Action carried out by CheckSetPriority() */ +} + +static void RtemsIntrReqSetPriority_Cleanup( + RtemsIntrReqSetPriority_Context *ctx +) +{ + if ( ctx->valid_vector ) { + rtems_vector_number vector; + + for ( + vector = 0; + vector < BSP_INTERRUPT_VECTOR_COUNT; + ++vector + ) { + rtems_interrupt_attributes attr; + rtems_status_code sc; + + memset( &attr, 0, sizeof( attr ) ); + sc = rtems_interrupt_get_attributes( vector, &attr ); + + if ( sc == RTEMS_INVALID_ID ) { + continue; + } + + T_rsc_success( sc ); + + if ( attr.can_set_priority != ctx->can_set_priority ) { + continue; + } + + CheckSetPriority( ctx, vector ); + } + } else { + CheckSetPriority( ctx, BSP_INTERRUPT_VECTOR_COUNT ); + } +} + +static const RtemsIntrReqSetPriority_Entry +RtemsIntrReqSetPriority_Entries[] = { + { 0, 0, 1, 1, RtemsIntrReqSetPriority_Post_Status_InvId }, + { 0, 0, 1, 0, RtemsIntrReqSetPriority_Post_Status_Unsat }, + { 0, 0, 0, 0, RtemsIntrReqSetPriority_Post_Status_Ok }, + { 0, 0, 0, 0, RtemsIntrReqSetPriority_Post_Status_InvPrio } +}; + +static const uint8_t +RtemsIntrReqSetPriority_Map[] = { + 2, 1, 3, 1, 0, 0, 0, 0 +}; + +static size_t RtemsIntrReqSetPriority_Scope( void *arg, char *buf, size_t n ) +{ + RtemsIntrReqSetPriority_Context *ctx; + + ctx = arg; + + if ( ctx->Map.in_action_loop ) { + return T_get_scope( + RtemsIntrReqSetPriority_PreDesc, + buf, + n, + ctx->Map.pcs + ); + } + + return 0; +} + +static T_fixture RtemsIntrReqSetPriority_Fixture = { + .setup = NULL, + .stop = NULL, + .teardown = NULL, + .scope = RtemsIntrReqSetPriority_Scope, + .initial_context = &RtemsIntrReqSetPriority_Instance +}; + +static inline RtemsIntrReqSetPriority_Entry RtemsIntrReqSetPriority_PopEntry( + RtemsIntrReqSetPriority_Context *ctx +) +{ + size_t index; + + index = ctx->Map.index; + ctx->Map.index = index + 1; + return RtemsIntrReqSetPriority_Entries[ + RtemsIntrReqSetPriority_Map[ index ] + ]; +} + +static void RtemsIntrReqSetPriority_SetPreConditionStates( + RtemsIntrReqSetPriority_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + + if ( ctx->Map.entry.Pre_Priority_NA ) { + ctx->Map.pcs[ 1 ] = RtemsIntrReqSetPriority_Pre_Priority_NA; + } else { + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + } + + if ( ctx->Map.entry.Pre_CanSetPriority_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqSetPriority_Pre_CanSetPriority_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + +static void RtemsIntrReqSetPriority_TestVariant( + RtemsIntrReqSetPriority_Context *ctx +) +{ + RtemsIntrReqSetPriority_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); + RtemsIntrReqSetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 1 ] ); + RtemsIntrReqSetPriority_Pre_CanSetPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] ); + RtemsIntrReqSetPriority_Action( ctx ); + RtemsIntrReqSetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); +} + +/** + * @fn void T_case_body_RtemsIntrReqSetPriority( void ) + */ +T_TEST_CASE_FIXTURE( + RtemsIntrReqSetPriority, + &RtemsIntrReqSetPriority_Fixture +) +{ + RtemsIntrReqSetPriority_Context *ctx; + + ctx = T_fixture_context(); + ctx->Map.in_action_loop = true; + ctx->Map.index = 0; + + for ( + ctx->Map.pci[ 0 ] = RtemsIntrReqSetPriority_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqSetPriority_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] + ) { + for ( + ctx->Map.pci[ 1 ] = RtemsIntrReqSetPriority_Pre_Priority_Valid; + ctx->Map.pci[ 1 ] < RtemsIntrReqSetPriority_Pre_Priority_NA; + ++ctx->Map.pci[ 1 ] + ) { + for ( + ctx->Map.pci[ 2 ] = RtemsIntrReqSetPriority_Pre_CanSetPriority_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqSetPriority_Pre_CanSetPriority_NA; + ++ctx->Map.pci[ 2 ] + ) { + ctx->Map.entry = RtemsIntrReqSetPriority_PopEntry( ctx ); + RtemsIntrReqSetPriority_SetPreConditionStates( ctx ); + RtemsIntrReqSetPriority_TestVariant( ctx ); + RtemsIntrReqSetPriority_Cleanup( ctx ); + } + } + } +} + +/** @} */ -- 2.35.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel