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 TypeRangePurposeCPU Scope
SGI (Software Generated)0-15Inter-processor communicationAll CPUs
PPI (Private Peripheral)16-31CPU-specific peripheralsSingle CPU
SPI (Shared Peripheral)32-1019System-wide peripheralsMultiple 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

MethodTargetUse Case
send_sgi(dest_cpu_id, sgi_num)Specific CPUDirect communication
send_sgi_all_except_self(sgi_num)All other CPUsBroadcast operations
send_sgi_to_self(sgi_num)Current CPUSelf-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.