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

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Jul 13 05:16:13 UTC 2021


On 13/07/2021 04:46, Kinsey Moore wrote:
>> 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).

Ok, on Qemu and the i.MX7D the SGI are always enabled. I would keep the 
attributes like this until we have a system which is different. I will 
remove the check in bsp_interrupt_vector_enable/disable(). So, in the 
worst case, the attributes are wrong.

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

I will remove this check here.

>>     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.

Yes, I will change this to

attributes->maybe_enable = true;

I would not do the probing here, since this would require to do it also 
in bsp_interrupt_vector_is_valid(). The probing could be done using 
bsp_interrupt_vector_enable() and bsp_interrupt_vector_is_enabled().

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber at embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


More information about the devel mailing list