[PATCH 19/41] bsps/irq: Implement new directives for GICv2/3

Kinsey Moore kinsey.moore at oarcorp.com
Tue Jul 13 02:46:21 UTC 2021


Comments inline below.

On 7/12/2021 07:49, Sebastian Huber wrote:
> 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;

As far as I'm aware, SGIs can be enabled or disabled using 
GICD_ISENABLER0 just like

PPI or SPI interrupts for both GICv2 and GICv3. Section 3.1.2 of the 
GICv2 architecture

spec (IHI0048B) references this, though I have seen implementations 
where certain SGI

and PPI interrupts are hard-wired enabled or disabled and that state 
can't be changed

(which is also covered in this section).

> +    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 */

The actual number of SPI interrupts supported by GICv3 can vary 
depending on the configuration

of the IP. This should check that the provided vector is within that range.

> +      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;
>   }


More information about the devel mailing list