GIC Distributor
Relevant source files
The GIC Distributor provides system-wide interrupt configuration and routing capabilities for the ARM GICv2 interrupt controller. This component manages interrupt prioritization, distribution to CPU interfaces, and global interrupt settings across all processors in the system.
For per-CPU interrupt handling and acknowledgment, see GIC CPU Interface. For background on interrupt types and ranges, see Interrupt Types and Ranges.
Register Structure and Memory Layout
The GIC Distributor is accessed through a memory-mapped register interface defined by the GicDistributorRegs structure. This provides type-safe access to all distributor control registers.
Distributor Register Layout
Sources: src/gic_v2.rs(L12 - L48)
Core Implementation Structure
The GicDistributor struct provides the main interface for distributor operations, encapsulating the register base address and maximum interrupt count.
Distributor Component Architecture
flowchart TD
subgraph subGraph5["GicDistributor Implementation"]
Struct["GicDistributorbase: NonNull<GicDistributorRegs>max_irqs: usize"]
subgraph subGraph4["Register Access"]
Regs["regs()→ &GicDistributorRegs"]
end
subgraph Initialization["Initialization"]
Init["init()"]
end
subgraph subGraph2["Configuration Methods"]
ConfigureInterrupt["configure_interrupt(vector: usize,tm: TriggerMode)"]
SetEnable["set_enable(vector: usize,enable: bool)"]
end
subgraph subGraph1["Information Methods"]
CpuNum["cpu_num()→ usize"]
MaxIrqs["max_irqs()→ usize"]
end
subgraph subGraph0["Constructor Methods"]
New["new(base: *mut u8)→ Self"]
end
end
Regs --> ConfigureInterrupt
Regs --> CpuNum
Regs --> Init
Regs --> MaxIrqs
Regs --> SetEnable
Struct --> ConfigureInterrupt
Struct --> CpuNum
Struct --> Init
Struct --> MaxIrqs
Struct --> New
Struct --> Regs
Struct --> SetEnable
Sources: src/gic_v2.rs(L96 - L210)
Initialization Process
The distributor initialization follows a specific sequence to establish a known state and configure default interrupt routing.
Initialization Sequence
| Step | Operation | Register(s) | Purpose |
|---|---|---|---|
| 1 | Disable all interrupts | ICENABLER[*] | Clear existing enables |
| 2 | Clear pending interrupts | ICPENDR[*] | Reset pending state |
| 3 | Set SPI targets to CPU 0 | ITARGETSR[*] | Default routing |
| 4 | Configure SPIs as edge-triggered | ICFGR[*] | Set trigger mode |
| 5 | Enable distributor | CTLR | Activate GICD |
flowchart TD Start["init() called"] ReadMaxIrqs["Read max_irqs from TYPER registerAssert ≤ GIC_MAX_IRQ"] DisableAll["Disable all interruptsICENABLER[i] = 0xFFFFFFFFfor i in 0..max_irqs/32"] ClearPending["Clear pending interruptsICPENDR[i] = 0xFFFFFFFFfor i in 0..max_irqs/32"] CheckMultiCpu["cpu_num() > 1?"] SetTargets["Set SPI targets to CPU 0ITARGETSR[i] = 0x01010101for i in SPI_RANGE"] ConfigEdge["Configure SPIs as edge-triggeredconfigure_interrupt(i, TriggerMode::Edge)for i in SPI_RANGE"] EnableGICD["Enable distributorCTLR = 1"] End["Initialization complete"] CheckMultiCpu --> ConfigEdge CheckMultiCpu --> SetTargets ClearPending --> CheckMultiCpu ConfigEdge --> EnableGICD DisableAll --> ClearPending EnableGICD --> End ReadMaxIrqs --> DisableAll SetTargets --> ConfigEdge Start --> ReadMaxIrqs
Sources: src/gic_v2.rs(L186 - L209)
Interrupt Configuration
The distributor provides methods to configure interrupt properties including trigger modes and enable/disable states.
Trigger Mode Configuration
The configure_interrupt method sets the trigger mode for SPI interrupts using the ICFGR registers:
flowchart TD
subgraph subGraph0["configure_interrupt Method"]
Input["vector: usizetm: TriggerMode"]
Validate["Validate vector≥ SPI_RANGE.start< max_irqs"]
CalcReg["Calculate register indexreg_idx = vector >> 4bit_shift = ((vector & 0xf) << 1) + 1"]
ReadReg["Read ICFGR[reg_idx]"]
ModifyBit["Modify trigger bitEdge: set bitLevel: clear bit"]
WriteReg["Write ICFGR[reg_idx]"]
end
CalcReg --> ReadReg
Input --> Validate
ModifyBit --> WriteReg
ReadReg --> ModifyBit
Validate --> CalcReg
Enable/Disable Control
The set_enable method controls interrupt enable state using dedicated enable/disable registers:
| Operation | Register Used | Bit Effect |
|---|---|---|
| Enable | ISENABLER[reg] | Set bit atvector % 32 |
| Disable | ICENABLER[reg] | Set bit atvector % 32 |
Where reg = vector / 32.
Sources: src/gic_v2.rs(L147 - L178)
System Information Interface
The distributor provides methods to query system configuration determined by hardware implementation.
Hardware Detection Methods
flowchart TD
subgraph subGraph0["System Information"]
TYPER_Reg["TYPER Register"]
CpuNumCalc["cpu_num()((TYPER >> 5) & 0b111) + 1"]
MaxIrqsCalc["max_irqs()((TYPER & 0b11111) + 1) * 32"]
CpuCount["Number of CPU interfaces"]
IrqCount["Maximum interrupt count"]
end
CpuNumCalc --> CpuCount
MaxIrqsCalc --> IrqCount
TYPER_Reg --> CpuNumCalc
TYPER_Reg --> MaxIrqsCalc
Sources: src/gic_v2.rs(L138 - L145)
Thread Safety and Memory Access
The GicDistributor implements Send and Sync traits for safe concurrent access across threads, with register access performed through unsafe memory operations wrapped in safe interfaces.
The register access uses NonNull<GicDistributorRegs> to ensure the base pointer is always valid and uses the tock-registers crate for type-safe memory-mapped I/O operations.
Sources: src/gic_v2.rs(L5 - L135)