GICv3 Legacy Mode Configuration and Interrupt Delivery Failure
The ARM Cortex-A53 processor, when configured to use the Generic Interrupt Controller version 3 (GICv3) in legacy mode, can exhibit issues where Software Generated Interrupts (SGIs) fail to reach the target CPU interface. This problem is particularly prevalent when transitioning from EL3 to EL2 and attempting to handle interrupts in a manner consistent with GICv2 behavior. The GICv3 architecture introduces significant changes compared to GICv2, including the concept of redistributors and a more complex power management scheme. When operating in legacy mode, the system must ensure proper configuration of both the distributor and CPU interfaces while maintaining compatibility with the GICv2 programming model.
The core issue manifests when an SGI is triggered after configuring the interrupt groups and priorities. While the interrupt shows as pending in the distributor, the target CPU interface fails to acknowledge the interrupt. This behavior suggests a breakdown in the interrupt delivery path between the distributor and the CPU interface, which could be caused by several factors including incorrect power state management of the redistributor, improper legacy mode configuration, or missed steps in the initialization sequence.
Redistributor Power State and Legacy Mode Configuration
The GICv3 architecture introduces redistributors, which are responsible for managing the interrupt state for each connected processor. In legacy mode, these redistributors must be properly initialized and powered on to ensure interrupt delivery. The WAKER register within each redistributor controls the power state, with bit 2 (ProcessorSleep) indicating the sleep state and bit 3 (ChildrenAsleep) reflecting the state of downstream components. The reset value of 0x6 for the WAKER register indicates that both the redistributor and its children are in a sleep state.
When operating in legacy mode, software must explicitly wake up the redistributor by clearing the ProcessorSleep bit and waiting for the ChildrenAsleep bit to clear. This process is crucial because the legacy mode implementation assumes a GICv2-like behavior where these power management features were not present. Failure to properly handle the redistributor power state can result in interrupts being blocked at the redistributor level, even though they appear as pending in the distributor.
Another critical aspect is the configuration of the ICC_SRE_EL3.SRE bit, which controls whether the system registers for interrupt control are accessible at lower exception levels. When operating in legacy mode, this bit must be set appropriately to ensure compatibility with the GICv2 programming model. Additionally, the interrupt groups and priorities must be configured consistently across the distributor and CPU interfaces, with special attention to the Priority Mask Register (PMR) settings.
Implementing Redistributor Wake-up Sequence and Legacy Mode Validation
To resolve the interrupt delivery issues in GICv3 legacy mode, a comprehensive initialization sequence must be followed. The first step is to ensure that the redistributors are properly powered on. This involves writing to the WAKER register to clear the ProcessorSleep bit and then polling the ChildrenAsleep bit until it clears. The code sequence for this operation should be:
gicr.WAKER &= ~0x2; // Clear ProcessorSleep bit
while(gicr.WAKER & 0x4); // Wait for ChildrenAsleep bit to clear
This sequence must be executed for each redistributor associated with the processor cores. It is important to note that the WAKER register is banked per core, so the wake-up sequence must be performed on each core individually. The use of volatile pointers is essential to ensure that the compiler does not optimize out the polling loop.
After ensuring that the redistributors are powered on, the next step is to configure the distributor and CPU interfaces for legacy mode operation. This includes setting the appropriate interrupt groups, configuring the PMR, and enabling the interfaces. The following table summarizes the key registers and their required settings:
Register | Bit/Field | Value | Description |
---|---|---|---|
ICC_SRE_EL3 | SRE | 1 | Enable system register access for interrupt control |
GICD_CTLR | EnableGrp1 | 1 | Enable group 1 interrupts in the distributor |
GICR_WAKER | ProcessorSleep | 0 | Wake up the redistributor |
GICR_WAKER | ChildrenAsleep | 0 | Ensure downstream components are awake |
ICC_PMR_EL1 | Priority | 0xFF | Set lowest priority (highest value) to allow all interrupts |
GICR_IGROUPR0 | Group | 0x0 | Configure all interrupts as group 1 |
GICR_ISENABLER0 | Enable | 0x1 | Enable the SGI in the redistributor |
Once the initialization sequence is complete, the system should be validated to ensure proper interrupt delivery. This can be done by triggering an SGI and verifying that it reaches the target CPU interface. If the interrupt still fails to be acknowledged, additional debugging steps should be taken, including:
- Verifying the memory mapping of the GIC registers to ensure they are mapped as device memory (nGnRnE).
- Checking the ICC_SRE_EL3.SRE bit to confirm that system register access is enabled.
- Ensuring that the redistributors are properly powered on by re-checking the WAKER register.
- Confirming that the interrupt is properly enabled in both the distributor and redistributor.
For systems where software-based solutions prove insufficient, the use of model-specific options such as -C gic_distributor.wakeup-on-reset=true
can be considered. This option forces the redistributors to start in a woken-up state at reset, bypassing the need for explicit wake-up sequences in software. However, this approach should be used with caution, as it deviates from the GICv3 specification and may not be suitable for production code.
In conclusion, proper handling of GICv3 legacy mode requires careful attention to the redistributor power state and a thorough understanding of the initialization sequence. By following the outlined steps and validating each stage of the configuration, developers can ensure reliable interrupt delivery in systems using ARM Cortex-A53 processors with GICv3.