Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 2: Distribution and Routing of Interrupts

This chapter describes the distribution and routing of interrupts to a target PE using affinity routing, and the assignment of interrupt IDs. It contains the following sections:

  • The Distributor and Redistributors .

  • INTIDs .

  • Affinity routing .

2.1 The Distributor and Redistributors

The Distributor provides the routing configuration for SPIs, and holds all the associated routing and priority information.

The Redistributor provides the configuration settings for PPIs and SGIs.

A Redistributor always presents the pending interrupt with the highest priority to the CPU interface in finite time. For more information about interrupt prioritization, see Interrupt prioritization .

The highest priority pending interrupt might change because:

  • The previous highest priority interrupt has been acknowledged.

  • The previous highest priority interrupt has been preempted.

  • The previous highest priority interrupt is removed and no longer valid.

  • The group interrupt enable has been modified.

  • The PE is no longer a participating PE. See Participating nodes .

2.2 INTIDs

Interrupts are identified using ID numbers (INTIDs). The range of INTIDs supported by GICv3 is IMPLEMENTATION DEFINED, according to the following rules:

  • For the number of INTID bits supported in the Distributor and Redistributor:

  • If LPIs are not supported, the ID space in the Distributor is limited to 10 bits. This is the same as in earlier versions of the GIC architecture.

  • If LPIs are supported, the INTID field is IMPLEMENTATION DEFINED in the range of 14-24 bits, as described in the register description for GICD_TYPER.

Note

A Redistributor can be configured through GICR_PROPBASER to use fewer bits than specified by GICD_TYPER.

  • For the number of INTID bits supported in the ITS: — If LPIs are supported, the INTID field is IMPLEMENTATION DEFINED in the range of 14-24 bits.

  • The size of the INTID field is defined by GITS_TYPER.IDbits.

The ITS must be programmed so that interrupts that are forwarded to a Redistributor are in the range of interrupts that are supported by that Redistributor, otherwise the behavior is UNPREDICTABLE.

  • For the number of INTID bits supported in the CPU interface:

    • The GICv3 CPU interface supports either a 16-bit or a 24-bit INTID field, the choice being IMPLEMENTATION DEFINED. The number of physical interrupt identifier bits that are supported is indicated by ICC_CTLR_EL1.IDbits and ICC_CTLR_EL3.IDbits.

The valid INTID space is governed by the implemented size in the CPU interface and the Distributor. It is a programming error to forward an INTID that is greater than the supported size to a CPU interface.

Unused INTID bits are RAZ. This means that any affected bit field is zero-extended.

Table 2-1 shows how the INTID space is partitioned by interrupt type.

Table 2-1 INTIDs

INTIDInterrupt typeDetailsNotes
0 – 15SGIThese interrupts are local to a CPU interface.INTIDs 0-1023 are compatible with earlier versions of the GIC architecture.
16 – 31PPIThese interrupts are local to a CPU interface.(same as above)
32 – 1019SPIShared peripheral interrupts that the Distributor can route to either a specific PE, or to any one of the PEs in the system that is a participating node, see Participating nodes.
1020 – 1023Special interrupt numberInterrupt IDs that are reserved for special purposes, as Special INTIDs describes.
1024 – 1055-Reserved-
1056 – 1119PPIExtended PPI. The interrupts are local to a CPU interface.INTIDs 1056-1119 are not compatible with earlier versions of the GIC architecture. This range is supported by the GICv3.1 architecture.
1120 – 4095-Reserved-
4096 – 5119SPIExtended SPI.Supported by the GICv3.1 architecture.
5120 – 8191-Reserved
8192 – IMPLEMENTATION DEFINEDLPIPeripheral hardware interrupts that are routed to a specific PE.-

Note The Arm recommended PPI INTID assignments are provided by the Server Base System Architecture, see Arm[®] Server Base System Architecture (SBSA) .

The GICv4 architecture provides a unique INTID space for each VM by supporting a vPEID in addition to the INTID space. See About GIC support for virtualization for more information about VMs and The Interrupt Translation Service for more information about vPEIDs.

Arm strongly recommends that implemented interrupts are grouped to use the lowest INTID numbers and as small a range of INTIDs as possible. This reduces the size of the associated tables in memory that must be implemented, and that discovery routines must check.

Arm strongly recommends that software reserves:

  • INTID0 - INTID7 for Non-secure interrupts.

  • INTID8 - INTID15 for Secure interrupts.

2.2.1 Special INTIDs

The list of the INTIDs that the GIC architecture reserves for special purposes is as follows:

1020 The GIC returns this value in response to a read of ICC_IAR0_EL1 or ICC_HPPIR0_EL1 at EL3, to indicate that the interrupt being acknowledged is one which is expected to be handled at Secure EL1. This INTID is only returned when the PE is executing at EL3 using AArch64 state, or when the PE is executing in AArch32 state in Monitor mode.

This value can also be returned by reads of ICC_IAR1_EL1 or ICC_HPPIR1_EL1 at EL3 when ICC_CTLR_EL3.RM == 1, see Asymmetric operation and the use of ICC_CTLR_EL3.RM .

1021 The GIC returns this value in response to a read of ICC_IAR0_EL1 or ICC_HPPIR0_EL1 at EL3, to indicate that the interrupt being acknowledged is one which is expected to be handled at Non-secure EL1 or EL2. This INTID is only returned when the PE is executing at EL3 using AArch64 state, or when the PE is executing in AArch32 state in Monitor mode. This value can also be returned by reads of ICC_IAR1_EL1 or ICC_HPPIR1_EL1 at EL3 when ICC_CTLR_EL3.RM == 1, see Asymmetric operation and the use of ICC_CTLR_EL3.RM.

1022 This value applies to legacy operation only. For more information, see Use of the special INTID 1022.

1023 This value is returned in response to an interrupt acknowledge, if there is no pending interrupt with sufficient priority for it to be signaled to the PE, or if the highest priority pending interrupt is not appropriate for the:

  • Current Security state.
  • Interrupt group that is associated with the System register.

Note These INTIDs do not require an end of interrupt or deactivation.

For more information about the use of special INTIDs, see the descriptions for the following registers:

  • ICC_IAR0_EL1.

  • ICC_IAR1_EL1.

  • ICC_HPPIR0_EL1.

  • ICC_HPPIR1_EL1.

2.2.2 Implementations with mixed INTID sizes

Implementations might choose to implement different INTID sizes for different parts of the GIC, subject to the following rules:

  • PEs might implement either 16 or 24 bits of INTID.

    Note

    A system might include a mixture of PEs that support 16 bits of INTID and PEs that support 24 bits of INTID.

  • The Distributor and Redistributors must all implement the same number of INTID bits.

  • In systems that support LPIs, the Distributors and all Redistributors must implement at least 14 bits of INTID. The number of bits that is implemented in the Distributor and Redistributors must not exceed the minimum number that is implemented on any PE in the system.

Note Because interrupts might target any PE, each PE must be able to receive the maximum INTID that can be sent by a Redistributor. This means that the INTID size that is supported by the Redistributors cannot exceed the minimum INTID size that is supported by each PE in the system.

  • In systems that do not support LPIs, the Distributor and all Redistributors must implement at least 5 bits of INTID and cannot implement more than 10 bits of INTID. For GIC version 3.1, no more than 13 bits of INTID can be implemented.

  • In systems that include one or more ITSs, an ITS might implement any value up to and including the number of bits that are supported by the Distributor and the Redistributors down to a minimum of 14 bits, which is the minimum number that is required for LPI support.

2.2.3 Valid interrupt ID check pseudocode

The following pseudocode describes how the GIC checks whether an INTID for a physical interrupt is valid:

// InterruptIdentifierValid()
// ==========================

boolean InterruptIdentifierValid(bits(64) data, boolean lpiAllowed)

    // First check whether any out of range bits are set
    integer N = CPUInterfaceIDSize();

    if !IsZero(data<63:N>) then
        if GenerateLocalSError() then
            // Reporting of locally generated SEIs is supported
            IMPLEMENTATION_DEFINED "SError INVALID_INTERRUPT_IDENTIFIER";
            UNPREDICTABLE;

    intID = data<INTID_SIZE-1:0>;

    if !lpiAllowed && IsLPI(intID) then        // LPIs are not supported
        if GenerateLocalSError() then
            // Reporting of locally generated SEIs is supported
            IMPLEMENTATION_DEFINED "SError INVALID_INTERRUPT_IDENTIFIER";
        UNPREDICTABLE;

The following pseudocode describes how the GIC checks whether an INTID for a virtual interrupt is valid:

// VirtualIdentifierValid()
// ========================

boolean VirtualIdentifierValid(bits(64) data, boolean lpiAllowed)

    // First check whether any out of range bits are set
    integer N = VIDBits();

    if !IsZero(data<63:N>) then
        if ICH_VTR_EL2.SEIS == '1' then
            // Reporting of locally generated SEIs is supported
            IMPLEMENTATION_DEFINED "SError INVALID_INTERRUPT_IDENTIFIER";
        UNPREDICTABLE;

    intID = data<INTID_SIZE-1:0>;

    if !lpiAllowed && IsLPI(intID) then        // LPIs are not supported
        if ICH_VTR_EL2.SEIS == '1' then
            // Reporting of locally generated SEIs is supported
            IMPLEMENTATION_DEFINED "SError INVALID_INTERRUPT_IDENTIFIER";
        UNPREDICTABLE;

    // Now check for special identifiers
    if IsSpecial(intID) then
        return FALSE;                              // It is a special ID

    // All the checks pass so the identifier is valid
    return TRUE;

The following pseudocode describes CPU interface ID size function.

// CPUInterfaceIDSize()
// Returns TRUE if the value supplied has bits above the implemented range or
// if the value supplied exceeds the maximum configured size in the
// appropriate GITS_BASERn

boolean VCPUOutOfRange(bits(16) vcpu);

2.3 Affinity routing

Affinity routing is a hierarchical address-based scheme to identify specific PE nodes for interrupt routing.

For a PE, the affinity value is defined in MPIDR_EL1 for AArch64 state, and in MPIDR for AArch32 state:

  • Affinity routing is a 32-bit value that is composed of four 8-bit affinity fields. These fields are the nodes a , b , c , and d .

  • GICv3 using AArch64 state can support:

    • A four level routing hierarchy, a.b.c.d.

    • A three level routing hierarchy, 0.b.c.d.

  • GICv3 using AArch32 state only supports three affinity levels.

  • ICC_CTLR_EL3.A3V, ICC_CTLR_EL1.A3V, and GICD_TYPER.A3V indicate whether four levels or three levels of affinity are implemented.

Note An implementation that requires four levels of affinity must only support AArch64 state.

The enumeration notation for specifying nodes in an affinity hierarchy is of the following form, where Affx is Affinity level x:

Aff3.Aff2.Aff1.Aff0

Affinity routing for a Security state is enabled in the Distributor, using the Affinity Routing Enable (ARE) bits. Affinity routing is enabled:

  • For Secure interrupts, if GICD_CTLR.ARE_S is set to 1.

  • For Non-secure interrupts, if the GICD_CTLR.ARE_NS bit is set to 1.

GICD_CTLR.ARE_S and GICD_CTLR.ARE_NS are RAO/WI if affinity routing is permanently enabled.

For the handling of physical interrupts when affinity routing is enabled, System register access must also be enabled, see GIC System register access . For the other cases, see Chapter 14 Legacy Operation and Asymmetric Configurations .

2.3.1 Routing SPIs and SGIs by PE affinity

SPIs are routed using an affinity address and the routing mode information that is held in GICD_IROUTER. SGIs are routed using the affinity address and routing mode information that is written by software when it generates the SGI.

SGIs are generated using the following registers:

  • ICC_SGI0R_EL1.

  • ICC_SGI1R_EL1.

  • ICC_ASGI1R_EL1.

Arm strongly recommends that only values in the range 0-15 are used at affinity level 0 to align with the SGI target list capability. See Software Generated Interrupts .

SPIs and SGIs are routed using different registers:

  • SPIs are routed using GICD_IROUTER.Interrupt_Routing_Mode:

    • If GICD_IROUTER.Interrupt_Routing_Mode is cleared to 0, SPIs are routed to a single PE specified by a.b.c.d.

    • If GICD_IROUTER.Interrupt_Routing_Mode is set to 1, SPIs are routed to any PE defined as a participating node:

      • The mechanisms by which the IRI is selects the target PE is IMPLEMENTATION DEFINED.

      • When ICC_CTLR_EL3.PMHE == 1, or ICC_CTLR_EL1.PMHE == 1, the ICC_PMR_EL1 register associated with the PE might be used by the IRI to determine the target PE.

For more information about participating nodes, see Participating nodes .

  • SGIs are routed using ICC_SGI0R_EL1.IRM, and ICC_SGI1R_EL1.IRM:

    • If the IRM bit is set to 1, SGIs are routed to all participating PEs in the system, excluding the originating PE.

    • If the IRM bit is cleared to 0, SGIs are routed to a group of PEs, specified by a.b.c.targetlist.

2.3.2 Participating nodes

An enabled SPI configured to use the 1 of N distribution model can target a PE when:

  • GICR_WAKER.ProcessorSleep == 0 and the interrupt group of the interrupt is enabled on the PE.

  • GICD_CTLR.E1NWF == 1.

  • GICR_TYPER.DPGS == 1, and for the interrupt group of the interrupt, GICR_CTLR.{DPG1S, DPG1NS, DPG0} == 0.

For more information about whether a PE can be selected as the target when the 1 of N distribution model is used, see GICR_CTLR, Redistributor Control Register on page 12-621 .

For more information about enabling interrupts and interrupt groups, see Enabling the distribution of interrupts .

2.3.3 Changing affinity routing enables

This manual describes the GICv3 architecture in a system with affinity routing enabled. This means that:

  • GICD_CTLR.ARE_NS == 1.

  • GICD_CTLR.ARE_S == 1.

If the value of GICD_CTLR.ARE_NS or GICD_CTLR.ARE_S is changed from 1 to 0, the result is UNPREDICTABLE.

When GICD_CTLR. DS == 0, then:

  • Changing GICD_CTLR.ARE_S from 0 to 1 is unpredictable except when all of the following apply:

    • GICD_CTLR.EnableGrp0 == 0.

    • GICD_CTLR.EnableGrp1S == 0.

    • GICD_CTLR.EnableGrp1NS == 0.

  • Changing GICD_CTLR.ARE_NS from 0 to 1 is unpredictable except when GICD_CTLR. EnableGrp1NS == 0.

When GICD_CTLR.DS == 1, then:

  • Changing GICD_CTLR.ARE from 0 to 1 is unpredictable except when all of the following apply: — GICD_CTLR.EnableGrp0 == 0.

    • GICD_CTLR.EnableGrp1 == 0.

Note The effect of clearing GICD_CTLR.EnableGrp0, GICD_CTLR.EnableGrp1S, or GICD_CTLR.EnableGrp1NS, as appropriate, must be visible when changing GICD_CTLR.ARE_S or GICD_CTLR.ARE_NS from 0 to 1. Software can poll GICD_CTLR.RWP to check that writes that clear GICD_CTLR.EnableGrp0, GICD_CTLR.EnableGrp1S, or GICD_CTLR.EnableGrp1NS bits have completed.