Interrupt Types and Management
Relevant source files
This document covers the interrupt classification system and management operations provided by the arm_gicv2
crate. It details the three interrupt types supported by ARM GICv2 (SGI, PPI, SPI), their characteristics, and how they are managed through the distributor and CPU interface components.
For information about the core GIC architecture and components, see Core Architecture. For detailed register-level operations, see Register Interface.
Interrupt Classification System
The ARM GICv2 specification defines three distinct interrupt types, each serving different purposes and having specific characteristics. The crate implements this classification through constants, enums, and a translation function.
Interrupt Type Definitions
flowchart TD subgraph subGraph2["Range Constants"] SGI_RANGE_CONST["SGI_RANGE: 0..16"] PPI_RANGE_CONST["PPI_RANGE: 16..32"] SPI_RANGE_CONST["SPI_RANGE: 32..1020"] end subgraph subGraph1["InterruptType Enum"] SGI_TYPE["InterruptType::SGI"] PPI_TYPE["InterruptType::PPI"] SPI_TYPE["InterruptType::SPI"] end subgraph subGraph0["Interrupt ID Space (0-1019)"] SGI_SPACE["SGI Range0-15Software Generated"] PPI_SPACE["PPI Range16-31Private Peripheral"] SPI_SPACE["SPI Range32-1019Shared Peripheral"] end PPI_RANGE_CONST --> PPI_SPACE PPI_TYPE --> PPI_SPACE SGI_RANGE_CONST --> SGI_SPACE SGI_TYPE --> SGI_SPACE SPI_RANGE_CONST --> SPI_SPACE SPI_TYPE --> SPI_SPACE
Sources: src/lib.rs(L14 - L29) src/lib.rs(L74 - L89)
Interrupt Type | Range | Purpose | CPU Scope |
---|---|---|---|
SGI (Software Generated) | 0-15 | Inter-processor communication | All CPUs |
PPI (Private Peripheral) | 16-31 | CPU-specific peripherals | Single CPU |
SPI (Shared Peripheral) | 32-1019 | System-wide peripherals | Multiple CPUs |
Interrupt Translation System
The translate_irq
function provides a safe way to convert logical interrupt IDs within each type to absolute GIC interrupt IDs.
flowchart TD INPUT["Logical ID + InterruptType"] TRANSLATE_IRQ["translate_irq()"] SGI_CHECK["id < 16?"] PPI_CHECK["id < 16?"] SPI_CHECK["id < 988?"] SGI_RESULT["Some(id)"] SGI_NONE["None"] PPI_RESULT["Some(id + 16)"] PPI_NONE["None"] SPI_RESULT["Some(id + 32)"] SPI_NONE["None"] GIC_INTID["GIC INTID"] INPUT --> TRANSLATE_IRQ PPI_CHECK --> PPI_NONE PPI_CHECK --> PPI_RESULT PPI_RESULT --> GIC_INTID SGI_CHECK --> SGI_NONE SGI_CHECK --> SGI_RESULT SGI_RESULT --> GIC_INTID SPI_CHECK --> SPI_NONE SPI_CHECK --> SPI_RESULT SPI_RESULT --> GIC_INTID TRANSLATE_IRQ --> PPI_CHECK TRANSLATE_IRQ --> SGI_CHECK TRANSLATE_IRQ --> SPI_CHECK
Sources: src/lib.rs(L91 - L116)
Interrupt Management Operations
The GIC provides different management capabilities depending on the interrupt type. These operations are primarily handled through the GicDistributor
component.
Core Management Functions
flowchart TD subgraph subGraph1["Interrupt Type Applicability"] SGI_OPS["SGI Operations• send_sgi()• send_sgi_all_except_self()• send_sgi_to_self()• set_pend() (special)"] PPI_OPS["PPI Operations• set_enable()• set_priority()• set_state()"] SPI_OPS["SPI Operations• configure_interrupt()• set_enable()• set_priority()• set_target_cpu()• set_state()"] end subgraph subGraph0["GicDistributor Management Methods"] CONFIGURE["configure_interrupt()"] ENABLE["set_enable() / get_enable()"] PRIORITY["set_priority() / get_priority()"] TARGET["set_target_cpu() / get_target_cpu()"] STATE["set_state() / get_state()"] PEND["set_pend()"] end CONFIGURE --> SPI_OPS ENABLE --> PPI_OPS ENABLE --> SPI_OPS PEND --> SGI_OPS PRIORITY --> PPI_OPS PRIORITY --> SPI_OPS STATE --> PPI_OPS STATE --> SGI_OPS STATE --> SPI_OPS TARGET --> SPI_OPS
Sources: src/gic_v2.rs(L161 - L283) src/gic_v2.rs(L201 - L223)
Trigger Mode Configuration
Only SPI interrupts support configurable trigger modes. The system restricts trigger mode configuration to the SPI range.
flowchart TD CONFIG_REQ["configure_interrupt(vector, trigger_mode)"] RANGE_CHECK["vector >= 32?"] EARLY_RETURN["return (invalid)"] MAX_CHECK["vector < max_irqs?"] CALCULATE["Calculate ICFGR register"] REG_ACCESS["Access ICFGR[reg_idx]"] MODE_CHECK["TriggerMode?"] SET_EDGE["Set bit (Edge)"] CLEAR_BIT["Clear bit (Level)"] WRITE_REG["Write ICFGR register"] CALCULATE --> REG_ACCESS CLEAR_BIT --> WRITE_REG CONFIG_REQ --> RANGE_CHECK MAX_CHECK --> CALCULATE MAX_CHECK --> EARLY_RETURN MODE_CHECK --> CLEAR_BIT MODE_CHECK --> SET_EDGE RANGE_CHECK --> EARLY_RETURN RANGE_CHECK --> MAX_CHECK REG_ACCESS --> MODE_CHECK SET_EDGE --> WRITE_REG
Sources: src/gic_v2.rs(L161 - L178)
Software Generated Interrupt Management
SGIs have special handling due to their role in inter-processor communication. They use dedicated register interfaces and targeting mechanisms.
SGI Generation Methods
Method | Target | Use Case |
---|---|---|
send_sgi(dest_cpu_id, sgi_num) | Specific CPU | Direct communication |
send_sgi_all_except_self(sgi_num) | All other CPUs | Broadcast operations |
send_sgi_to_self(sgi_num) | Current CPU | Self-signaling |
flowchart TD subgraph subGraph1["GICD_SGIR Register Fields"] TARGET_FILTER["TargetListFilter"] CPU_LIST["CPUTargetList"] SGI_ID["SGIINTID"] end subgraph subGraph0["SGI Targeting Modes"] SPECIFIC["ForwardToCPUTargetList+ CPUTargetList"] BROADCAST["ForwardToAllExceptRequester"] SELF["ForwardToRequester"] end GICD_SGIR_REG["GICD_SGIR Register"] BROADCAST --> TARGET_FILTER CPU_LIST --> GICD_SGIR_REG SELF --> TARGET_FILTER SGI_ID --> GICD_SGIR_REG SPECIFIC --> CPU_LIST SPECIFIC --> TARGET_FILTER TARGET_FILTER --> GICD_SGIR_REG
Sources: src/gic_v2.rs(L201 - L223) src/regs/gicd_sgir.rs
SGI Pending State Management
SGIs require special handling for pending state management due to their per-CPU nature:
flowchart TD SET_PEND["set_pend(int_id, is_pend, current_cpu_id)"] SGI_CHECK["int_id in SGI_RANGE?"] SGI_CALC["Calculate register offset"] NORMAL_PEND["Use ISPENDR/ICPENDR"] PEND_CHECK["is_pend?"] SET_SPENDSGIR["Set SPENDSGIR bit"] CLEAR_CPENDSGIR["Clear CPENDSGIR bits"] CPU_SPECIFIC["Target specific CPU"] ALL_CPUS["Clear for all CPUs"] CLEAR_CPENDSGIR --> ALL_CPUS PEND_CHECK --> CLEAR_CPENDSGIR PEND_CHECK --> SET_SPENDSGIR SET_PEND --> SGI_CHECK SET_SPENDSGIR --> CPU_SPECIFIC SGI_CALC --> PEND_CHECK SGI_CHECK --> NORMAL_PEND SGI_CHECK --> SGI_CALC
Sources: src/gic_v2.rs(L264 - L283)
Integration with GIC Components
Interrupt management operations interface with both the distributor and CPU interface components, with different responsibilities for each type.
Distributor vs CPU Interface Responsibilities
flowchart TD subgraph subGraph2["Interrupt Flow"] PERIPHERAL["Peripheral Device"] HANDLER["Interrupt Handler"] end subgraph subGraph1["GicCpuInterface Responsibilities"] CPU_ACK["Acknowledgment• iar() register read• Interrupt priority"] CPU_EOI["Completion• eoi() priority drop• dir() deactivation"] CPU_MASK["Priority Masking• PMR register• Preemption control"] end subgraph subGraph0["GicDistributor Responsibilities"] DIST_CONFIG["Configuration• Trigger modes• Priority levels• CPU targeting"] DIST_ENABLE["Enable/Disable• Per-interrupt control• Group assignment"] DIST_SGI["SGI Generation• Inter-processor signals• Targeting modes"] DIST_STATE["State Management• Pending state• Active state"] end CPU_ACK --> HANDLER DIST_CONFIG --> CPU_ACK HANDLER --> CPU_EOI PERIPHERAL --> DIST_CONFIG
Sources: src/gic_v2.rs(L92 - L131) src/gic_v2.rs(L376 - L479)
The interrupt management system provides a complete abstraction over ARM GICv2 hardware while maintaining type safety and proper encapsulation of interrupt-type-specific behaviors.