Interrupt Types and Ranges

Relevant source files

This document details the three interrupt types supported by the ARM GICv2 controller and their corresponding interrupt ID ranges as implemented in the arm_gicv2 crate. It covers the classification system that divides the 1024-interrupt address space into Software-Generated Interrupts (SGI), Private Peripheral Interrupts (PPI), and Shared Peripheral Interrupts (SPI), along with the translation mechanisms between logical and physical interrupt identifiers.

For information about trigger modes and the translate_irq function implementation details, see Trigger Modes and Translation. For the hardware interface implementations that use these interrupt types, see Hardware Interface Implementation.

Interrupt Classification Overview

The ARM GICv2 specification defines a structured interrupt ID space of 1024 interrupts (0-1023) divided into three distinct types, each serving different purposes in the system architecture.

GICv2 Interrupt ID Space Allocation

flowchart TD
subgraph subGraph0["GIC_MAX_IRQ [1024 total interrupts]"]
    SGI["SGI_RANGEIDs 0-15Software GeneratedInter-processor communication"]
    PPI["PPI_RANGEIDs 16-31Private PeripheralSingle CPU specific"]
    SPI["SPI_RANGEIDs 32-1019Shared PeripheralMulti-CPU routing"]
    Reserved["ReservedIDs 1020-1023Implementation specific"]
end
InterruptType_SGI["InterruptType::SGI"]
InterruptType_PPI["InterruptType::PPI"]
InterruptType_SPI["InterruptType::SPI"]
translate_irq["translate_irq()"]

InterruptType_PPI --> translate_irq
InterruptType_SGI --> translate_irq
InterruptType_SPI --> translate_irq
PPI --> InterruptType_PPI
SGI --> InterruptType_SGI
SPI --> InterruptType_SPI

Sources: src/lib.rs(L12 - L30) 

Software-Generated Interrupts (SGI)

Software-Generated Interrupts occupy interrupt IDs 0-15 and are primarily used for inter-processor communication in multi-core systems. These interrupts are triggered by software writing to the GIC Distributor's GICD_SGIR register.

PropertyValue
Range ConstantSGI_RANGE
ID Range0-15 (16 interrupts)
PurposeInter-processor communication
Trigger MethodSoftware write to GICD_SGIR
TargetSpecific CPU cores

SGI Characteristics and Usage

flowchart TD
subgraph subGraph0["Common SGI Use Cases"]
    IPC["Inter-processorcommunication"]
    TaskMigration["Task migrationrequests"]
    CacheOps["Cache maintenanceoperations"]
    Scheduling["Schedulernotifications"]
end
CPU0["CPU Core 0"]
GICD_SGIR["GICD_SGIR RegisterSGI Generation"]
CPU1["CPU Core 1"]
CPU2["CPU Core 2"]
CPU3["CPU Core 3"]
SGI_0_15["SGI IDs 0-15SGI_RANGE"]
CPU0_Interface["CPU 0 Interface"]
CPU1_Interface["CPU 1 Interface"]
CPU2_Interface["CPU 2 Interface"]
CPU3_Interface["CPU 3 Interface"]

CPU0 --> GICD_SGIR
CPU1 --> GICD_SGIR
CPU2 --> GICD_SGIR
CPU3 --> GICD_SGIR
GICD_SGIR --> SGI_0_15

Sources: src/lib.rs(L12 - L16) 

Private Peripheral Interrupts (PPI)

Private Peripheral Interrupts use interrupt IDs 16-31 and are generated by peripherals that are private to each individual processor core. Each CPU core has its own set of PPI interrupt sources.

PropertyValue
Range ConstantPPI_RANGE
ID Range16-31 (16 interrupts)
PurposePrivate peripheral interrupts
ScopeSingle CPU core
ExamplesPrivate timers, PMU, virtual timer

PPI Architecture and Core Association

flowchart TD
subgraph subGraph2["PPI_RANGE [16-31]"]
    PPI_16["PPI ID 16"]
    PPI_17["PPI ID 17"]
    PPI_18["PPI ID 18"]
    PPI_Dots["..."]
    PPI_31["PPI ID 31"]
end
subgraph subGraph1["CPU Core 1"]
    Core1_Timer["Private Timer"]
    Core1_PMU["Performance Monitor"]
    Core1_VTimer["Virtual Timer"]
    Core1_Interface["CPU Interface 1"]
end
subgraph subGraph0["CPU Core 0"]
    Core0_Timer["Private Timer"]
    Core0_PMU["Performance Monitor"]
    Core0_VTimer["Virtual Timer"]
    Core0_Interface["CPU Interface 0"]
end

Core0_PMU --> PPI_17
Core0_Timer --> PPI_16
Core0_VTimer --> PPI_18
Core1_PMU --> PPI_17
Core1_Timer --> PPI_16
Core1_VTimer --> PPI_18

Sources: src/lib.rs(L18 - L21) 

Shared Peripheral Interrupts (SPI)

Shared Peripheral Interrupts occupy the largest portion of the interrupt space, using IDs 32-1019. These interrupts can be routed to any CPU core and are typically generated by system-wide peripherals.

PropertyValue
Range ConstantSPI_RANGE
ID Range32-1019 (988 interrupts)
PurposeShared peripheral interrupts
RoutingConfigurable to any CPU core
ExamplesUART, GPIO, DMA, network controllers

SPI Routing and Distribution

flowchart TD
subgraph subGraph3["CPU Cores"]
    CPU_0["CPU Core 0"]
    CPU_1["CPU Core 1"]
    CPU_2["CPU Core 2"]
    CPU_3["CPU Core 3"]
end
subgraph subGraph2["GicDistributor Routing"]
    ITARGETSR["ITARGETSR RegistersCPU target configuration"]
    ICFGR["ICFGR RegistersTrigger mode config"]
end
subgraph subGraph1["SPI_RANGE [32-1019]"]
    SPI_32["SPI ID 32"]
    SPI_33["SPI ID 33"]
    SPI_Dots["..."]
    SPI_1019["SPI ID 1019"]
end
subgraph subGraph0["Shared Peripherals"]
    UART["UART Controllers"]
    GPIO["GPIO Controllers"]
    DMA["DMA Controllers"]
    Network["Network Interfaces"]
    Storage["Storage Controllers"]
end

DMA --> SPI_Dots
GPIO --> SPI_33
ITARGETSR --> CPU_0
ITARGETSR --> CPU_1
ITARGETSR --> CPU_2
ITARGETSR --> CPU_3
Network --> SPI_Dots
SPI_Dots --> ITARGETSR
Storage --> SPI_1019
UART --> SPI_32

Sources: src/lib.rs(L23 - L27) 

Interrupt ID Translation

The translate_irq function converts logical interrupt IDs (relative to each interrupt type) into physical GIC interrupt IDs (absolute addressing within the 1024-interrupt space).

Translation Logic and Mapping

flowchart TD
subgraph subGraph2["Physical GIC IDs [Output]"]
    GIC_SGI["GIC ID 0-15"]
    GIC_PPI["GIC ID 16-31"]
    GIC_SPI["GIC ID 32-1019"]
end
subgraph subGraph1["translate_irq Function"]
    InterruptType_SGI_Match["InterruptType::SGIid < SGI_RANGE.end"]
    InterruptType_PPI_Match["InterruptType::PPIid + PPI_RANGE.start"]
    InterruptType_SPI_Match["InterruptType::SPIid + SPI_RANGE.start"]
end
subgraph subGraph0["Logical IDs [Input]"]
    SGI_Logical["SGI Logical ID0..15"]
    PPI_Logical["PPI Logical ID0..15"]
    SPI_Logical["SPI Logical ID0..987"]
end

InterruptType_PPI_Match --> GIC_PPI
InterruptType_SGI_Match --> GIC_SGI
InterruptType_SPI_Match --> GIC_SPI
PPI_Logical --> InterruptType_PPI_Match
SGI_Logical --> InterruptType_SGI_Match
SPI_Logical --> InterruptType_SPI_Match

Translation Examples

InputInterrupt TypeCalculationOutput
id=5InterruptType::SGIid(direct mapping)Some(5)
id=3InterruptType::PPIid + 16Some(19)
id=10InterruptType::SPIid + 32Some(42)
id=20InterruptType::SGIInvalid (≥16)None

Range Validation

The translation function includes bounds checking to ensure logical IDs are valid for their respective interrupt types:

  • SGI: Logical ID must be < SGI_RANGE.end (16)
  • PPI: Logical ID must be < PPI_RANGE.end - PPI_RANGE.start (16)
  • SPI: Logical ID must be < SPI_RANGE.end - SPI_RANGE.start (988)

Sources: src/lib.rs(L65 - L90) 

Implementation Constants

The interrupt ranges and limits are defined as compile-time constants in the crate's public API:

ConstantValuePurpose
SGI_RANGE0..16Software-generated interrupt range
PPI_RANGE16..32Private peripheral interrupt range
SPI_RANGE32..1020Shared peripheral interrupt range
GIC_MAX_IRQ1024Maximum interrupt capacity

These constants are used throughout the crate for bounds checking, validation, and hardware register configuration.

Sources: src/lib.rs(L12 - L30)