0 总纲
The GIC is an architected
resource that supports and controls interrupts.
主要有三项大功能:
- Registers for managing interrupt sources
- interrupt behavior
- the routing of interrupts to one or more PEs
1 secure grouping
armv8架构的安全特性有如下结论:
- A PE requires EL3 to support both Secure and Non-secure state
- A PE requires EL2 to support virtualization
- If EL3 is not implemented, there is only a single Security state. This Security state is either Secure state or Non-secure state
gic作为一种架构级
资源,不可能不与PE的执行模型相匹配,PE有EL0-EL3四个级别,gic分为三种group:
- Group 0 physical interrupts are expected to be handled at the highest implemented Exception level
- Secure Group 1 physical interrupts are expected to be handled at Secure EL1 or EL2
- Non-secure Group 1 physical interrupts are excepted to be handled at Non-secure EL2 in systems using virtualization, or at Non-secure EL1 in systems not using virtualization
对于group 0,所谓的highest implemented Exception level
,有EL3实现时,就是EL3,EL1-EL3都有对应的group了,这里想5s为什么没有EL0对应的group
2 Models for handling interrupts
-
Targeted distribution model
这种模型应用于:
- LPI
- PPI
- 如果
GICD_IROUTER<n>.Interrupt_Routing_Mode == 0
,应用于non-legacy的SPI指定的PE处理中断
-
Targeted list model
这种模型只应用于SGI,多个PE收到独立的中断,每个PE也独立响应中断
-
1 of N model
这种模型只应用于SPI,中断被路由到一组PE,系统在一组PE里选一个响应中断
3 IRI
总体架构如下:
总体中断处理流向是:
-
Interrupts that are translated into LPIs are optionally routed via the ITS to the Redistributor and the CPU interface
-
PPIs are routed directly from the source to the local Redistributor *SPIs are routed from the source through the Distributor to the target Redistributor and the associated CPU interface
-
SGIs are generated by software through the CPU interface and Redistributor. They are then routed through the Distributor to one or more target Redistributors and the associated CPU interfaces
-
如果LPI是通过ITS转换生成的,则总体框架如下:
4 GICD
总体来说,GICD模块的主要功能是:
- The Distributor provides the routing configuration for SPIs, and holds all the associated routing and priority information.
- The Distributor performs interrupt prioritization and distribution of SPIs and SGIs to the Redistributors and CPU interfaces that are connected to the PEs in the system.
针对SPI中断,GICD干的事情主要是:
- Enabling or disabling SPIs
- Setting the priority level of each SPI
- Routing information for each SPI
- Setting each SPI to be level-sensitive or edge-triggered
- Generating message-based SPIs
- Assigning each SPI to an interrupt group
- Controlling the pending and active state of SPIs
5 GICR
总体来说,GICR模块的主要功能是:
- The Redistributor provides the configuration settings for PPIs and SGIs
- A Redistributor always presents the pending interrupt with the highest priority to the CPU interface in finite time
- The Redistributor holds the control, prioritization, and pending information for all physical LPIs using data structures that are held in memory
- In GICv4, the Redistributor also includes registers to handle virtual LPIs that are forwarded by an ITS to a Redistributor and directly to a VM, without involving the hypervisor
- In GICv4, the Redistributors collectively host the control, prioritization, and pending information for all virtual LPIs using data structures that are held in memory
- In an implementation that supports LPIs but does not include an ITS, the GICR_* registers contain a simple memory-mapped interface to signal and control physical LPIs
GICR提供的编程接口有:
- Identifying, controlling, and configuring supported features to enable interrupts and interrupt routing of the implementation
- Enabling or disabling SGIs and PPIs
- Setting the priority level of SGIs and PPIs
- Setting each PPI to be level-sensitive or edge-triggered
- Assigning each SGI and PPI to an interrupt group
- Controlling the pending state of SGIs and PPIs
- Controlling the active state of SGIs and PPIs
- Power management support for the connected PE
- Where LPIs are supported, base address control for the data structures in memory that support the associated interrupt properties and their pending status
- Where GICv4 is supported, base address control for the data structures in memory that support the associated virtual interrupt properties and their pending status
6 GITS
总体来说,GITS模块的主要功能是:
- The ITS is an OPTIONAL hardware mechanism in the GICv3 architecture that routes LPIs to the appropriate Redistributor
工作流程为:
-
The DeviceID selects a Device table entry (DTE) in the Device table that describes which Interrupt translation table (ITT) to use
-
The EventID selects an Interrupt translation entry (ITE) in the ITT that describes:
- For physical interrupts:
- The output physical INTID
- The Interrupt collection number, ICID
- For virtual interrupts, in GICv4:
- The output virtual INTID
- The vPEID
- A doorbell to use if the vPE is not scheduled
-
For physical interrupts, ICID selects a Collection table entry in the Collection table (CT) that describes the target Redistributor, and therefore the target PE, to which the interrupt is routed
-
For virtual interrupts, in GICv4, the vPEID selects a vPE table entry that describes the Redistributor that is currently hosting the target vPE to which the interrupt is routed
7 GICC
总体来说,GICC模块的主要功能是:
- General control and configuration to enable interrupt handling in accordance with the Security state and legacy support requirements of the implementation
- Acknowledging an interrupt
- Performing a priority drop
- Deactivation of an interrupt
- Setting an interrupt priority mask for the PE
- Defining the preemption policy for the PE
- Determining the highest priority pending interrupt for the PE
GICC包含的主要子模块有:
- A component that allows a supervisory level of software to control the handling of physical interrupts. The registers that are associated with this are identified by the ICC_prefix
- A component that allows a supervisory level of software to control the handling of virtual interrupts. The registers that are associated with this are identified by the ICV_prefix
- A component that allows a hypervisor to control the set of pending interrupts. The registers that are associated with this are identified by the ICH_prefix
8 INTID
The valid INTID space is governed by the implemented size in the CPU interface and the Distributor.
INTID | Interrupt type | Details | Notes |
---|---|---|---|
0 - 15 | SGI | These interrupts are local to a CPU interface. | INTIDs 0-1023 are compatible with earlier versions of the GIC architecture. |
16 – 31 | PPI | These interrupts are local to a CPU interface. | INTIDs 0-1023 are compatible with earlier versions of the GIC architecture. |
32 – 1019 | SPI | Shared peripheral interrupts that the Distributor can route to either a specific PE, or to any one of the PEs in the system that is a participating node | |
1020 – 1023 | Special interrupt number | Interrupt IDs that are reserved for special purposes | - |
1024 – 1055 | - | Reserved | - |
1056 – 1119 | PPI | Extended PPI. The interrupts are local to a CPU interface. | INTIDs 1056-1119 are not compatible with earlier versions of the GIC architecture. This range is supported by the GICv3.1 architecture. |
1120 – 4095 | - | Reserved | - |
4096 – 5119 | SPI | Extended SPI. | Supported by the GICv3.1 architecture. |
5120 – 8191 | - | Reserved | - |
8192 – IMPLEMENTATION DEFINED | LPI |
注意:
- PPI and SGI interrupt numbers are local to each PE
- SPIs and LPIs have global interrupt numbers for the physical domain
- The Distributor and Redistributors must all implement the same number of INTID bits
- The effects of reading ICC_IAR0_EL1 and ICC_IAR1_EL1 on the state of a returned INTID are not guaranteed to be visible until after the execution of a DSB
Arm strongly recommends that software reserves:
- INTID0 - INTID7 for Non-secure interrupts
- INTID8 - INTID15 for Secure interrupts
9 priority
The highest priority pending interrupt might change because:
- The previous highest priority interrupt has been acknowledged
- The previous highest priority interrupt has been preempted
- The previous highest priority interrupt is removed and no longer valid
- The group interrupt enable has been modified
- The PE is no longer a participating PE
对于支持两种安全态,需要实现至少32至多256级优先级,对于只支持一种安全态,需要实现至少16至多256级优先级,比如:
Implemented priority bits | Possible priority field values | Number of priority levels |
---|---|---|
[7:0] | 0x00-0xFF (0-255), all values | 256 |
[7:1] | 0x00-0xFE, (0-254), even values only | 128 |
[7:2] | 0x00-0xFC (0-252), in steps of 4 | 64 |
[7:3] | 0x00-0xF8 (0-248), in steps of 8 | 32 |
[7:4] | 0x00-0xF0 (0-240), in steps of 16 | 16 |
还支持group priority:
ICC_BPR1_EL1 Binary point value | Group priority field | Subpriority field | Field with binary point |
---|---|---|---|
0 | [7:0] | [0] | ggggggg.s |
1 | [7:2] | [1:0] | gggggg.ss |
2 | [7:3] | [2:0] | ggggg.sss |
3 | [7:4] | [3:0] | gggg.ssss |
4 | [7:5] | [4:0] | ggg.sssss |
5 | [7:6] | [5:0] | gg.ssssss |
6 | [7] | [6:0] | g.sssssss |
7 | No preemption | [7:0] | .ssssssss |
10 FIQ/IRQ
-
A Group 0 physical interrupt, when it is the highest priority pending interrupt and has sufficient priority, is always signaled as an FIQ
-
A Group 1 physical interrupt, when it is the highest priority pending interrupt and has sufficient priority, is signaled as an FIQ if either of the following conditions is true, otherwise it is signaled as an IRQ:
- It is an interrupt for the other Security state, that is, the Security state in which the PE is not executing.
- The PE is executing at EL3.
Current Exception level | Group 0 interrupts | Group 1 interrupts Secure | Group 1 interrupts Non-secure |
---|---|---|---|
Secure EL1or EL0 or EL2 | FIQ | IRQ | FIQ |
Non-secure EL1 or EL0, or Non-secure EL2 | FIQ | FIQ | IRQ |
EL3 | FIQ | FIQ | FIQ |
11 Affinity routing
特点有:
- 比如在EL3时,支持配置为secure state使能affinity routing,同时配置为non-secure state不使能affinity routing
12 LPI
The outputs of the Interrupt Translation Service (ITS) are always LPIs, which are a form of message-based interrupt.
特点是:
- 路由到指定的PE
- 在有两个安全态的系统中永远是Non-secure Group 1 interrupts
- edge-triggered
- 没有
active
状态,无需deactivation
- 永远是MSI中断
- LPI表地址位于None-secure物理地址空间
if GICD_CTLR.DS == 0 then
LPIs are always Non-secure Group 1 interrupts
else
LPIs are always Group 1 interrupts
endif
- 有ITS时,LPI通过MSI发给ITS产生LPI中断,再发送给GICR,总体结构如下:
- 没有ITS时,通过直接写GICR寄存器产生LPI中断,总体结构如下:
LPI tables主要分为两大类:
- configuration tables
- pending tables
每个GICR是否可以配置不同的LPI表基址要看具体实现:
It is IMPLEMENTATION DEFINED whether GICR_PROPBASER can be set to different values on different Redistributors.
GICR_TYPER.CommonLPIAff indicates which Redistributors must have GICR_PROPBASER set to the same value whenever GICR_CTLR.EnableLPIs == 1.
GICR可以实现一个小缓存,缓存LPI表,但不保证比如缓存一致性等行为
说明:
为啥要搞个LPI tables呢,原因是LPI中断可能暴多,不可能给每一个中断搞几个寄存器
13 SGI
主要用于核间通信,特点是:
- 可以是Group 0 interrupts, Secure Group 1 interrupts, or Non-secure Group 1 interrupts
- edge-triggered only
- 有
active
状态,需要明确的deactivation
需要注意的是,SGI的流向应该是

14 PPI
特点是:
- 路由到指定的单个PE,不同的PE可以用同一个PPI中断号
- 可以是Group 0 interrupts, Secure Group 1 interrupts, or Non-secure Group 1 interrupts
- 支持edge-triggered和level-sensitive
- 有
active
状态,需要明确的deactivation
15 SPI
特点是:
- 可以路由到单个PE或者多个PE
- 可以是Group 0 interrupts, Secure Group 1 interrupts, or Non-secure Group 1 interrupts
- 支持edge-triggered和level-sensitive
- 有
active
状态,需要明确的deactivation
16 MSI
GICv3 supports two mechanisms for message-based interrupts:
- A mechanism for communicating an SPI, where the assigned address is held in the Distributor. In this case the message-based interrupt can be either level-sensitive or edge-triggered
- A mechanism for communicating an LPI, where the assigned address is held in an ITS, if an ITS is implemented, or in the Redistributor
17 handling
-
When an LPI is acknowledged, the pending state for the interrupt changes to not pending in the Redistributor. The Redistributor does not maintain an active state for LPIs
-
When the PE acknowledges an SGI, a PPI, or an SPI at the CPU interface, the IRI changes the status of the interrupt to active if:
- It is an edge-triggered interrupt, and another edge has not been detected since the interrupt was acknowledged
- It is a level-sensitive interrupt, and the level has been deasserted since the interrupt was acknowledged
-
When the PE acknowledges an SGI, a PPI, or an SPI at the CPU interface, the IRI changes the status of the interrupt to active and pending if:
- It is an edge-triggered interrupt, and another edge has been detected since the interrupt was acknowledged
- It is a level-sensitive interrupt, and the level has not been deasserted since the interrupt was acknowledged
-
When the PE acknowledges an SGI, a PPI, or an SPI at the CPU interface, the CPU interface can signal another interrupt to the PE, to preempt interrupts that are active on the PE. If there is no pending interrupt with sufficient priority to be signaled to the PE, the interface deasserts the interrupt request signal to the PE
-
Deactivation可以配置为在EOI的同时进行,也可以配置为分别执行,先EIO,再deactivation
总体状态变迁图如下:
-
Transition A1 or A2, add pending state
This transition occurs when the interrupt becomes pending, either as a result of the peripheral generating the interrupt or as result of software generating the interrupt
-
Transition B1 or B2, remove pending state
This transition occurs when the interrupt has been deasserted by the peripheral, if the interrupt is a level-sensitive interrupt, or when software has changed the pending state For LPIs, it also occurs on acknowledgement of the
-
Transition C, pending to active
This transition occurs on acknowledgement of the interrupt by the PE for edge-triggered SPIs, SGIs, and PPIs For SPIs, SGIs, and PPIs, this transition occurs when software reads an INTID value from ICC_IAR0_EL1 or ICC_IAR1_EL1
-
Transition D, pending to active and pending
This transition occurs on acknowledgement of the interrupt by the PE for level-sensitive SPIs, SGIs, and PPIs
-
Transition E1 or E2, remove active state
This transition occurs when software deactivates an interrupt for SPIs, SGIs, and PPIs
注意:
-
A valid write to ICC_EOIR0_EL1 or ICC_EOIR1_EL1 to perform a priority drop is required for each acknowledged interrupt, even for LPIs which do not have an active state
-
A priority drop must be performed by the same PE that activated the interrupt
-
SGIs and PPIs must be deactivated by the PE that activated the interrupt
-
SPIs can be deactivated by a different PE
18 GICV
GICv4开始支持中断直接注入vPE,为了实现这一套逻辑,让vPE跑着的时候无感,需要实现一套vGIC的相关寄存器,即ICV_xx
,有两个难题要解决:
- 当一个中断发送到EL1处理时,系统需要明白这个EL1是实现了虚拟化的虚机内核级还是没有实现虚拟化的内核级
- 假设现在是实现了虚拟化的虚机内核级响应中断,但它访问的是
ICC_xx
样子的寄存器,系统需要能自动处理
对于第一个:
Accesses at EL1 to Group 0 registers are virtual when:
- The current Security state is Non-secure and HCR_EL2.FMO == 1
- The current Security state is Secure, HCR_EL2.FMO == 1 and SCR_EL3.EEL2 == 1
Accesses at EL1 to Group 1 registers are virtual when:
- The current Security state is Non-secure and HCR_EL2.IMO == 1
- The current Security state is Secure, HCR_EL2.IMO == 1 and SCR_EL3.EEL2 == 1
Accesses at EL1 to the common registers are virtual when:
- The current Security state is Non-secure and (HCR_EL2.FMO == 1 || HCR_EL2.IMO == 1)
- The current Security state is Secure, (HCR_EL2.FMO == 1 || HCR_EL2.IMO == 1) and SCR_EL3.EEL2 == 1
对于第二个:
Virtual accesses to the following Group 0 ICC_* registers access the ICV_* equivalents:
- Accesses to ICC_AP0R_EL1 access ICV_AP0R_EL1
- Accesses to ICC_BPR0_EL1 access ICV_BPR0_EL1
- Accesses to ICC_EOIR0_EL1 access ICV_EOIR0_EL1
- Accesses to ICC_HPPIR0_EL1 access ICV_HPPIR0_EL1
- Accesses to ICC_IAR0_EL1 access ICV_IAR0_EL1
- Accesses to ICC_IGRPEN0_EL1 access ICV_IGRPEN0_EL1
Virtual accesses to the following Group 1 ICC_* registers access the ICV_* equivalents:
- Accesses to ICC_AP1R_EL1 access ICV_AP1R_EL1
- Accesses to ICC_BPR1_EL1 access ICV_BPR1_EL1
- Accesses to ICC_EOIR1_EL1 access ICV_EOIR1_EL1
- Accesses to ICC_HPPIR1_EL1 access ICV_HPPIR1_EL1
- Accesses to ICC_IAR1_EL1 access ICV_IAR1_EL1
- Accesses to ICC_IGRPEN1_EL1 access ICV_IGRPEN1_EL1
Virtual accesses to the following Common ICC_* registers access the ICV_* equivalents:
- Accesses to ICC_RPR_EL1 access ICV_RPR_EL1
- Accesses to ICC_CTLR_EL1 access ICV_CTLR_EL1
- Accesses to ICC_DIR_EL1 access ICV_DIR_EL1
- Accesses to ICC_PMR_EL1 access ICV_PMR_EL1
A virtual write to ICC_SGI0R_EL1, ICC_SGI1R_EL1, or ICC_ASGI1R_EL1 traps to EL2