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.
Property | Value |
---|---|
Range Constant | SGI_RANGE |
ID Range | 0-15 (16 interrupts) |
Purpose | Inter-processor communication |
Trigger Method | Software write to GICD_SGIR |
Target | Specific 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.
Property | Value |
---|---|
Range Constant | PPI_RANGE |
ID Range | 16-31 (16 interrupts) |
Purpose | Private peripheral interrupts |
Scope | Single CPU core |
Examples | Private 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.
Property | Value |
---|---|
Range Constant | SPI_RANGE |
ID Range | 32-1019 (988 interrupts) |
Purpose | Shared peripheral interrupts |
Routing | Configurable to any CPU core |
Examples | UART, 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
Input | Interrupt Type | Calculation | Output |
---|---|---|---|
id=5 | InterruptType::SGI | id(direct mapping) | Some(5) |
id=3 | InterruptType::PPI | id + 16 | Some(19) |
id=10 | InterruptType::SPI | id + 32 | Some(42) |
id=20 | InterruptType::SGI | Invalid (≥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:
Constant | Value | Purpose |
---|---|---|
SGI_RANGE | 0..16 | Software-generated interrupt range |
PPI_RANGE | 16..32 | Private peripheral interrupt range |
SPI_RANGE | 32..1020 | Shared peripheral interrupt range |
GIC_MAX_IRQ | 1024 | Maximum interrupt capacity |
These constants are used throughout the crate for bounds checking, validation, and hardware register configuration.
Sources: src/lib.rs(L12 - L30)