Update #3269. --- bsps/include/dev/irq/arm-gic-irq.h | 3 + bsps/shared/dev/irq/arm-gicv2.c | 93 +++++++++++++++++--- bsps/shared/dev/irq/arm-gicv3.c | 131 ++++++++++++++++++++++++----- 3 files changed, 194 insertions(+), 33 deletions(-)
diff --git a/bsps/include/dev/irq/arm-gic-irq.h b/bsps/include/dev/irq/arm-gic-irq.h index 68e0247fd8..398fd8bceb 100644 --- a/bsps/include/dev/irq/arm-gic-irq.h +++ b/bsps/include/dev/irq/arm-gic-irq.h @@ -46,6 +46,9 @@ extern "C" { #define ARM_GIC_IRQ_SGI_13 13 #define ARM_GIC_IRQ_SGI_14 14 #define ARM_GIC_IRQ_SGI_15 15 +#define ARM_GIC_IRQ_SGI_LAST 15 + +#define ARM_GIC_IRQ_PPI_LAST 31 #define ARM_GIC_DIST ((volatile gic_dist *) BSP_ARM_GIC_DIST_BASE) diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c index a1ba5e9112..6f5d4015e4 100644 --- a/bsps/shared/dev/irq/arm-gicv2.c +++ b/bsps/shared/dev/irq/arm-gicv2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -69,6 +69,28 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + attributes->is_maskable = true; + attributes->maybe_enable = true; + + if ( vector <= ARM_GIC_IRQ_SGI_LAST ) { + attributes->always_enabled = true; + attributes->can_enable = true; + attributes->can_cause = true; + attributes->can_cause_on = true; + attributes->cleared_by_acknowledge = true; + } else { + attributes->can_disable = true; + attributes->can_cause = true; + attributes->can_clear = true; + + if ( vector > ARM_GIC_IRQ_PPI_LAST ) { + /* SPI */ + attributes->can_enable = true; + attributes->can_get_affinity = true; + attributes->can_set_affinity = true; + } + } + return RTEMS_SUCCESSFUL; } @@ -77,16 +99,25 @@ rtems_status_code bsp_interrupt_is_pending( bool *pending ) { - bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - bsp_interrupt_assert(pending != NULL); - *pending = false; - return RTEMS_UNSATISFIED; + volatile gic_dist *dist = ARM_GIC_DIST; + + *pending = gic_id_is_pending(dist, vector); + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_cause(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + arm_gic_trigger_sgi(vector, 1U << _SMP_Get_current_processor()); + } else { + volatile gic_dist *dist = ARM_GIC_DIST; + + gic_id_set_pending(dist, vector); + } + + return RTEMS_SUCCESSFUL; } #if defined(RTEMS_SMP) @@ -95,15 +126,27 @@ rtems_status_code bsp_interrupt_cause_on( uint32_t cpu_index ) { - bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + if (vector >= 16) { + return RTEMS_UNSATISFIED; + } + + arm_gic_trigger_sgi(vector, 1U << cpu_index); + return RTEMS_SUCCESSFUL; } #endif rtems_status_code bsp_interrupt_clear(rtems_vector_number vector) { + volatile gic_dist *dist = ARM_GIC_DIST; + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + return RTEMS_UNSATISFIED; + } + + gic_id_clear_pending(dist, vector); + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_is_enabled( @@ -113,8 +156,16 @@ rtems_status_code bsp_interrupt_vector_is_enabled( { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); bsp_interrupt_assert(enabled != NULL); - *enabled = false; - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + *enabled = true; + } else { + volatile gic_dist *dist = ARM_GIC_DIST; + + *enabled = gic_id_is_enabled(dist, vector); + } + + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) @@ -133,6 +184,11 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + /* SGI cannot be disabled */ + return RTEMS_UNSATISFIED; + } + gic_id_disable(dist, vector); return RTEMS_SUCCESSFUL; } @@ -207,8 +263,8 @@ BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void) dist->icdigr[0] = 0xffffffff; #endif - /* Initialize Peripheral Private Interrupts (PPIs) */ - for (id = 0; id < 32; ++id) { + /* Initialize priority of SGIs and PPIs */ + for (id = 0; id <= ARM_GIC_IRQ_PPI_LAST; ++id) { gic_id_set_priority(dist, id, PRIORITY_DEFAULT); } @@ -300,6 +356,10 @@ rtems_status_code bsp_interrupt_set_affinity( volatile gic_dist *dist = ARM_GIC_DIST; uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0); + if ( vector <= ARM_GIC_IRQ_PPI_LAST ) { + return RTEMS_UNSATISFIED; + } + gic_id_set_targets(dist, vector, targets); return RTEMS_SUCCESSFUL; } @@ -310,8 +370,13 @@ rtems_status_code bsp_interrupt_get_affinity( ) { volatile gic_dist *dist = ARM_GIC_DIST; - uint8_t targets = gic_id_get_targets(dist, vector); + uint8_t targets; + + if ( vector <= ARM_GIC_IRQ_PPI_LAST ) { + return RTEMS_UNSATISFIED; + } + targets = gic_id_get_targets(dist, vector); _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c index 8db3053ffd..211f4d35c4 100644 --- a/bsps/shared/dev/irq/arm-gicv3.c +++ b/bsps/shared/dev/irq/arm-gicv3.c @@ -169,6 +169,25 @@ rtems_status_code bsp_interrupt_get_attributes( rtems_interrupt_attributes *attributes ) { + attributes->is_maskable = true; + attributes->can_enable = true; + + if ( vector <= ARM_GIC_IRQ_SGI_LAST ) { + attributes->can_cause = true; + attributes->can_cause_on = true; + attributes->cleared_by_acknowledge = true; + } else { + attributes->can_disable = true; + attributes->can_cause = true; + attributes->can_clear = true; + + if ( vector > ARM_GIC_IRQ_PPI_LAST ) { + /* SPI */ + attributes->can_get_affinity = true; + attributes->can_set_affinity = true; + } + } + return RTEMS_SUCCESSFUL; } @@ -179,14 +198,39 @@ rtems_status_code bsp_interrupt_is_pending( { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); bsp_interrupt_assert(pending != NULL); - *pending = false; - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_PPI_LAST) { + volatile gic_sgi_ppi *sgi_ppi = + gicv3_get_sgi_ppi(_SMP_Get_current_processor()); + + *pending = (sgi_ppi->icspispendr[0] & (1U << vector)) != 0; + } else { + volatile gic_dist *dist = ARM_GIC_DIST; + + *pending = gic_id_is_pending(dist, vector); + } + + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_cause(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + arm_gic_trigger_sgi(vector, 1U << _SMP_Get_current_processor()); + } else if (vector <= ARM_GIC_IRQ_PPI_LAST) { + volatile gic_sgi_ppi *sgi_ppi = + gicv3_get_sgi_ppi(_SMP_Get_current_processor()); + + sgi_ppi->icspispendr[0] = 1U << vector; + } else { + volatile gic_dist *dist = ARM_GIC_DIST; + + gic_id_set_pending(dist, vector); + } + + return RTEMS_SUCCESSFUL; } #if defined(RTEMS_SMP) @@ -195,15 +239,35 @@ rtems_status_code bsp_interrupt_cause_on( uint32_t cpu_index ) { - bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + if (vector >= 16) { + return RTEMS_UNSATISFIED; + } + + arm_gic_trigger_sgi(vector, 1U << cpu_index); + return RTEMS_SUCCESSFUL; } #endif rtems_status_code bsp_interrupt_clear(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + return RTEMS_UNSATISFIED; + } + + if ( vector <= ARM_GIC_IRQ_PPI_LAST ) { + volatile gic_sgi_ppi *sgi_ppi = + gicv3_get_sgi_ppi(_SMP_Get_current_processor()); + + sgi_ppi->icspicpendr[0] = 1U << vector; + } else { + volatile gic_dist *dist = ARM_GIC_DIST; + + gic_id_clear_pending(dist, vector); + } + + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_is_enabled( @@ -213,8 +277,21 @@ rtems_status_code bsp_interrupt_vector_is_enabled( { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); bsp_interrupt_assert(enabled != NULL); - *enabled = false; - return RTEMS_UNSATISFIED; + + if (vector <= ARM_GIC_IRQ_SGI_LAST) { + *enabled = true; + } else if ( vector <= ARM_GIC_IRQ_PPI_LAST ) { + volatile gic_sgi_ppi *sgi_ppi = + gicv3_get_sgi_ppi(_SMP_Get_current_processor()); + + *enabled = (sgi_ppi->icspiser[0] & (1U << vector)) != 0; + } else { + volatile gic_dist *dist = ARM_GIC_DIST; + + *enabled = gic_id_is_enabled(dist, vector); + } + + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) @@ -222,22 +299,24 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - if (vector >= 32) { + if (vector > ARM_GIC_IRQ_PPI_LAST) { volatile gic_dist *dist = ARM_GIC_DIST; + gic_id_enable(dist, vector); - } else { + } else if (vector > ARM_GIC_IRQ_SGI_LAST) { volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(_SMP_Get_current_processor()); + /* Set interrupt group to 1 in the current security mode */ #if defined(ARM_MULTILIB_ARCH_V4) || defined(AARCH64_IS_NONSECURE) - sgi_ppi->icspigrpr[0] |= 1 << (vector % 32); - sgi_ppi->icspigrpmodr[0] &= ~(1 << (vector % 32)); + sgi_ppi->icspigrpr[0] |= 1U << vector; + sgi_ppi->icspigrpmodr[0] &= ~(1U << vector); #else - sgi_ppi->icspigrpr[0] &= ~(1 << (vector % 32)); - sgi_ppi->icspigrpmodr[0] |= 1 << (vector % 32); + sgi_ppi->icspigrpr[0] &= ~(1U << vector); + sgi_ppi->icspigrpmodr[0] |= 1U << vector; #endif /* Set enable */ - sgi_ppi->icspiser[0] = 1 << (vector % 32); + sgi_ppi->icspiser[0] = 1U << vector; } return RTEMS_SUCCESSFUL; @@ -247,13 +326,18 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - if (vector >= 32) { + if (vector > ARM_GIC_IRQ_PPI_LAST) { volatile gic_dist *dist = ARM_GIC_DIST; + gic_id_disable(dist, vector); - } else { + } else if (vector > ARM_GIC_IRQ_SGI_LAST) { volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(_SMP_Get_current_processor()); - sgi_ppi->icspicer[0] = 1 << (vector % 32); + + sgi_ppi->icspicer[0] = 1U << vector; + } else { + /* SGI cannot be disabled */ + return RTEMS_UNSATISFIED; } return RTEMS_SUCCESSFUL; @@ -407,6 +491,10 @@ rtems_status_code bsp_interrupt_set_affinity( volatile gic_dist *dist = ARM_GIC_DIST; uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0); + if ( vector <= ARM_GIC_IRQ_PPI_LAST ) { + return RTEMS_UNSATISFIED; + } + gic_id_set_targets(dist, vector, targets); return RTEMS_SUCCESSFUL; } @@ -417,8 +505,13 @@ rtems_status_code bsp_interrupt_get_affinity( ) { volatile gic_dist *dist = ARM_GIC_DIST; - uint8_t targets = gic_id_get_targets(dist, vector); + uint8_t targets; + + if ( vector <= ARM_GIC_IRQ_PPI_LAST ) { + return RTEMS_UNSATISFIED; + } + targets = gic_id_get_targets(dist, vector); _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } -- 2.26.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel