Software Generated Interrupts
Relevant source files
This document covers Software Generated Interrupts (SGIs) in the ARM GICv2 implementation, including their generation methods, register interface, and targeting mechanisms. SGIs are a critical component for inter-processor communication in multi-core systems.
For information about the overall interrupt classification system, see Interrupt Classification System. For details about the underlying register implementations, see GICD_SGIR Register Details.
SGI Overview and Characteristics
Software Generated Interrupts occupy interrupt IDs 0-15 and serve as the primary mechanism for inter-processor communication in ARM GICv2 systems. Unlike peripheral interrupts, SGIs are generated entirely through software writes to the GICD_SGIR
register.
Characteristic | Value |
---|---|
Interrupt ID Range | 0-15 |
Total Count | 16 SGIs |
Primary Use Case | Inter-processor communication |
Generation Method | Software write to GICD_SGIR |
Targeting | Flexible CPU targeting modes |
SGIs are defined by the SGI_RANGE
constant and classified through the InterruptType::SGI
enum variant. The translate_irq
function handles SGI ID validation, ensuring only IDs 0-15 are accepted for SGI operations.
SGI Generation Flow
flowchart TD A["Software Request"] B["GicDistributor::send_sgi*"] C["GICD_SGIR Register Write"] D["TargetListFilter Mode"] E["ForwardToCPUTargetList"] F["ForwardToAllExceptRequester"] G["ForwardToRequester"] H["CPUTargetList Field"] I["All CPUs Except Current"] J["Current CPU Only"] K["Target CPU Interfaces"] L["SGI Delivery"] A --> B B --> C C --> D D --> E D --> F D --> G E --> H F --> I G --> J H --> K I --> K J --> K K --> L
Sources: src/lib.rs(L14 - L18) src/lib.rs(L92 - L116) src/gic_v2.rs(L202 - L223)
SGI Generation Methods
The GicDistributor
struct provides three primary methods for generating SGIs, each corresponding to different targeting strategies. These methods abstract the complexity of GICD_SGIR
register programming.
send_sgi Method
The send_sgi
method targets a specific CPU interface using the ForwardToCPUTargetList
mode:
// Method signature from GicDistributor implementation
pub fn send_sgi(&mut self, dest_cpu_id: usize, sgi_num: usize)
This method constructs a GICD_SGIR
register write with:
TargetListFilter
=ForwardToCPUTargetList
(0b00)CPUTargetList
= destination CPU ID bitmaskSGIINTID
= SGI number (0-15)
send_sgi_all_except_self Method
The send_sgi_all_except_self
method broadcasts to all CPU interfaces except the requesting processor:
// Method signature from GicDistributor implementation
pub fn send_sgi_all_except_self(&mut self, sgi_num: usize)
This method uses TargetListFilter
= ForwardToAllExceptRequester
(0b01), eliminating the need to specify individual CPU targets.
send_sgi_to_self Method
The send_sgi_to_self
method targets only the requesting CPU interface:
// Method signature from GicDistributor implementation
pub fn send_sgi_to_self(&mut self, sgi_num: usize)
This method uses TargetListFilter
= ForwardToRequester
(0b10) for local SGI generation.
SGI Method Mapping
flowchart TD subgraph subGraph2["Hardware Behavior"] G["Target specific CPU interface"] H["Broadcast to all except sender"] I["Self-targeting only"] end subgraph subGraph1["GICD_SGIR TargetListFilter"] D["ForwardToCPUTargetList (0b00)"] E["ForwardToAllExceptRequester (0b01)"] F["ForwardToRequester (0b10)"] end subgraph subGraph0["GicDistributor Methods"] A["send_sgi(dest_cpu_id, sgi_num)"] B["send_sgi_all_except_self(sgi_num)"] C["send_sgi_to_self(sgi_num)"] end A --> D B --> E C --> F D --> G E --> H F --> I
Sources: src/gic_v2.rs(L202 - L208) src/gic_v2.rs(L211 - L216) src/gic_v2.rs(L219 - L223)
GICD_SGIR Register Interface
The GICD_SGIR
register controls SGI generation through a structured bit field layout. The register is implemented as a write-only interface using the tock-registers
abstraction.
Register Bit Fields
Bits | Field | Purpose |
---|---|---|
[31:26] | Reserved | Must be zero |
[25:24] | TargetListFilter | Determines targeting mode |
[23:16] | CPUTargetList | CPU interface bitmask (when TargetListFilter = 0b00) |
[15] | NSATT | Security attribute (Security Extensions only) |
[14:4] | Reserved | Should be zero |
[3:0] | SGIINTID | SGI interrupt ID (0-15) |
The TargetListFilter
field provides four targeting modes:
Value | Mode | Description |
---|---|---|
0b00 | ForwardToCPUTargetList | Use CPUTargetList bitmask |
0b01 | ForwardToAllExceptRequester | Broadcast except sender |
0b10 | ForwardToRequester | Self-targeting only |
0b11 | Reserved | Invalid mode |
GICD_SGIR Register Layout
flowchart TD subgraph subGraph0["GICD_SGIR Register (32 bits)"] A["[31:26]Reserved"] B["[25:24]TargetListFilter"] C["[23:16]CPUTargetList"] D["[15]NSATT"] E["[14:4]Reserved"] F["[3:0]SGIINTID"] end G["Targeting Mode0b00: CPUTargetList0b01: All except self0b10: Self only"] H["8-bit CPU maskEach bit = CPU interface"] I["SGI ID (0-15)4-bit value"] B --> G C --> H F --> I
Sources: src/regs/gicd_sgir.rs(L21 - L58) src/gic_v2.rs(L18)
SGI State Management
SGIs require special handling in the GIC distributor's state management functions due to their per-CPU nature. The set_pend
method implements SGI-specific logic using dedicated pending registers.
SGI Pending State Registers
SGIs use separate pending state registers compared to other interrupt types:
- SPENDSGIR: Set SGI pending registers (4 registers, 32 bits each)
- CPENDSGIR: Clear SGI pending registers (4 registers, 32 bits each)
Each register covers 4 SGIs with 8 bits per SGI (one bit per CPU interface).
SGI Pending State Implementation
The set_pend
method handles SGIs using a different code path:
// SGI range check and register access pattern
if SGI_RANGE.contains(&int_id) {
let reg_idx = int_id / 4; // SGI register index (0-3)
let offset = (int_id % 4) * 8; // Bit offset within register
// Set/clear pending state per CPU
}
SGI Pending State Flow
flowchart TD A["set_pend(int_id, is_pend, current_cpu_id)"] B["SGI_RANGE.contains(int_id)?"] C["SGI Pending Path"] D["Standard Pending Path"] E["reg_idx = int_id / 4"] F["offset = (int_id % 4) * 8"] G["is_pend?"] H["SPENDSGIR[reg_idx]Set bit at offset + current_cpu_id"] I["CPENDSGIR[reg_idx]Clear 8 bits at offset"] J["ISPENDR/ICPENDR registers"] A --> B B --> C B --> D C --> E C --> F D --> J E --> G F --> G G --> H G --> I
Sources: src/gic_v2.rs(L264 - L283) src/gic_v2.rs(L55 - L58) src/lib.rs(L14 - L18)
SGI Security and Access Control
When the GIC implements Security Extensions, the NSATT
bit in GICD_SGIR
controls SGI security attributes. This field determines whether SGIs are forwarded based on their Group 0 or Group 1 configuration.
Security Behavior
NSATT Value | SGI Forwarding Condition |
---|---|
0 | Forward only if SGI configured as Group 0 |
1 | Forward only if SGI configured as Group 1 |
Non-secure writes to GICD_SGIR
can only generate Group 1 SGIs, regardless of the NSATT
field value. This provides hardware-enforced security isolation between secure and non-secure SGI generation.
Sources: src/regs/gicd_sgir.rs(L42 - L49)