Configuring the GIC
This section of the guide describes how to enable and configure a GICv3-compliant interrupt controller in a bare metal environment. For detailed register descriptions see the Arm Generic Interrupt Controller Architecture Specification GIC architecture version 3.0 and 4.
The configuration of Locality-specific Peripheral Interrupts (LPIs) is significantly different to the configuration of Shared Peripheral Interrupts (SPIs), Private Peripheral Interrupt (PPIs), and Software Generated Interrupts (SGIs), and is beyond the scope of this guide. To learn more, refer to our guide Arm CoreLink Generic Interrupt Controller v3 and v4: Locality-specific Peripheral Interrupts.
Most systems that use a GICv3 interrupt controller are multi-core systems, and possibly also multi-processor systems. Some settings are global, which means that affect all the connected PEs. Other settings are particular to a single PE.
Let’s look at the global settings, and then the settings for each PE.
The Distributor control register (
GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode as follows:
- Enable Affinity routing (
GICD_CTLRcontrol whether the GIC is operating in GICv3 mode or legacy mode. Legacy mode provides backwards compatibility with GICv2. This guide assumes that the
AREbits are set to
1, so that GICv3 mode is being used.
GICD_CTLRcontains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1:
EnableGrp1Senables distribution of Secure Group 1 interrupts.
EnableGrp1NSenables distribution of Non-secure Group 1 interrupts.
EnableGrp0enables distribution of Group 0 interrupts.
Note: Arm CoreLink GIC-600 does not support legacy operation, and the
ARE bits are permanently set to
This section covers settings that are specific to a single core or PE.
Each core has its own Redistributor, as shown here:
The Redistributor contains a register called
GICR_WAKER which is used to record whether the connected PE is online or offline. Interrupts are only forwarded to a PE that the GIC believes is online. At reset, all PEs are treated as being offline.
To mark the connected PE as being online, software must:
GICR_WAKER.ChildrenAsleepuntil it reads
It is important that software performs these steps before configuring the CPU interface, otherwise behavior can be UNPREDICTABLE.
While the PE is offline (
GICR_WAKER.ProcessorSleep==1), an interrupt that is targeting the PE will result in a wake-request signal being asserted. Typically, this signal will go to the power controller of the system. The power controller then turns on the PE. On waking, software on that PE would clear the
ProcessorSleep bit, allowing the interrupt that woke the PE to be forwarded.
CPU interface configuration
The CPU interface is responsible for delivering interrupt exceptions to the PE to which it is connected. To enable the CPU interface, software must configure the following:
- Enable System register access.
The CPU interfaces (
ICC_*_ELn) section describes the CPU interface registers, and how they are accessed as System registers in GICv3. Software must enable access to the CPU interface registers, by setting the
SREbit in the
Note: Many recent Arm Cortex processors do not support legacy operation, and the SRE bits are fixed as set. On these processors this step can be skipped.
- Set Priority Mask and Binary Point registers.
The CPU interface contains the Priority Mask register (
ICC_PMR_EL1) and the Binary Point registers (
ICC_BPRn_EL1). The Priority Mask sets the minimum priority that an interrupt must have in order to be forwarded to the PE. The Binary Point register is used for priority grouping and preemption. The use of both registers is described in more detail in Handling Interrupts.
- Set EOI mode.
ICC_CTLR_EL3in the CPU interface control how the completion of an interrupt is handled. This is described in more detail in End of interrupt.
- Enable signaling of each interrupt group.
The signaling of each interrupt group must be enabled before interrupts of that group will be forwarded by the CPU interface to the PE. To enable signaling, software must write to the
ICC_IGRPEN1_EL1register for Group 1 interrupts and
ICC_IGRPEN0_EL1registers for Group 0 interrupts.
ICC_IGRPEN1_EL1is banked by Security state. This means that
ICC_GRPEN1_EL1controls Group 1 for the current Security state. At EL3, software can access both Group 1 enables using
Some configuration of the PE is also required to allow it to receive and handle interrupts. A detailed description of this is outside of the scope of this guide. In this guide, we will describe the basic steps that are required for an Armv8-A compliant PE executing in AArch64 state.
- Routing controls
The routing controls for interrupts are in
HCR_EL2of the PE. The routing control bits determine the Exception level to which an interrupt is taken. The routing bits in these registers have an UNKNOWN value at reset, so they must be initialized by software.
- Interrupt masks
The PE also has exception mask bits in
PSTATE. When these bits are set, interrupts are masked. These bits are set at reset.
- Vector table
The location of the vector tables of the PE is set by the
VBAR_ELnregisters. Like with
VBAR_ELnregisters have an UNKNOWN value at reset. Software must set the
VBAR_ELnregisters to point to the appropriate vector tables in memory.
To learn more about these steps, see the Learn the Architecture: Exception model guide.
SPI, PPI, and SGI configuration
So far, we have looked at configuring the interrupt controller itself. We will now discuss the configuration of the individual interrupt sources.
Which registers are used to configure an interrupt depends on the type of interrupt:
- SPIs are configured through the Distributor, using the
- PPIs and SGIs are configured through the individual Redistributors, using the
These different configuration mechanisms are illustrated in the following diagram:
For each INTID, software must configure the following:
Each INTID has an associated priority, represented as an 8-bit unsigned value.
0x00is the highest possible priority, and
0xFFis the lowest possible priority. Running priority and preemption describes how the priority value in
GICR_IPRIORITYnmasks low priority interrupts, and how it controls preemption. An interrupt controller is not required to implement all 8 priority bits. A minimum of 5 bits must be implemented if the GIC supports two Security states. A minimum of 4 bits must be implemented if the GIC support only a single Security state.
As described in Security model, an interrupt can be configured to belong to one of the three interrupt groups. These interrupt groups are Group 0, Secure Group 1 and Non-secure Group 1.
- Edge-triggered or level-sensitive:
For PPIs and SPI, the software must specify whether the interrupt is edge-triggered or level-sensitive. SGIs are always treated as edge-triggered, and therefore
GICR_ICFGR0behaves as Read-As-One, Writes Ignored (RAO/WI) for these interrupts.
Each INTID has an enable bit. Set-enable registers and Clear-enable registers remove the requirement to perform read-modify-write routines. Arm recommends that the settings outlined in this section are configured before enabling the INTID.
For a bare metal environment, it is often unnecessary to change settings after initial configuration. However, if an interrupt must be reconfigured, for example to change the Group setting, you should first disable the interrupt before changing its configuration.
The reset values of most of the configuration registers are IMPLEMENTATION DEFINED. This means that the designer of the interrupt controller decides what the values are, and the values might vary between systems.
Arm CoreLink GICv3.1 and the extended INTID ranges
Arm CoreLink GICv3.1 added support for additional SPI and PPI INTIDs. The registers to configure these interrupts are the same as the original interrupt ranges, except that they have an
E suffix. For example:
GICR_ISENABLERn- Enable bits for the original PPI range
GICR_ISENABLERnE- Enable bits for the additional PPIs that are introduced in GICv3.1
For SPIs, the target of the interrupt must be configured. This is controlled by
GICD_IROUTERnE for the GICv3.1 extended SPIs. There is a
GICD_IROUTERn register for each SPI, and the
Interrupt_Routing_Mode bit controls the routing policy. The options are:
GICD_IROUTERn.Interrupt_Routing_Mode == 0
The SPI is delivered to the PE A.B.C.D, which are the affinity co-ordinates specified in the register.
GICD_IROUTERn.Interrupt_Routing_Mode == 1
The SPI can be delivered to any connected PE that is participating in distribution of the interrupt group. The Distributor, rather than software, selects the target PE. The target can therefore vary each time the interrupt is signaled. This type of routing is referred to as 1-of-N.
A PE can opt out of receiving 1-of-N interrupts. This is controlled by the
DPG0 bits in