GIC 简介
GIC 的全称为 General Interrupt Controller,主要作用可以归结为:
接受硬件中断信号并进行简单处理,通过一定的设置策略,分给对应的CPU进行处理。
Terminology
IRI: Interrupt Routing Infrastructure. The Distributor, Redistributor and ITS are collectively known as an IRI.
The IRI performs interrupt grouping, interrupt prioritization, and controls the forwarding of interrupts
to the CPU interfaces.
ITS: Interrupt translation service, is an OPTIONAL hardware mechanism in the GICv3 architecture that routes
LPIs to the appropriate Redistributor, and the GICv4 implementations must include at least one ITS.
ARM 中断源分类
- SGI: Software Generated Interrupt,软件产生中断,中断号是
0-15
。通过向SGI寄存器写数触发,可用于CPU间的通信,比如时间同步,全局进程调度信息等。每个 PE 都有这么多 SGI 号。TheRedistributor
provides the configuration settings for PPIs and SGIs. - PPI: Private Peripheral Interrupt,私有外设中断,中断号是
16~31
。这些中断一般是发送给特定的CPU的,比如每个CPU有自己对应的Generic Timer
,产生的中断信号就发送给这个特定的CPU进行处理。每个 PE 都有这么多 PPI 号。TheRedistributor
provides the configuration settings for PPIs and SGIs. - SPI: Shared Peripheral Interrupt,共享外设中断,中断号是
32~1019
。比如按键触发一个中断,手机触摸屏触发的中断,共享的意思是说可以从多个 PE 中选择一个发送处理,当然也可以指定发送给某个 PE。TheDistributor
provides the routing configuration for SPIs, and holds all the associated routing and priority information. - 特殊中断号。
1020-1023
。这个在 GICv3 中用于指示特别的场景,例如给EL3
的软件使用。 - 保留中断号,
1024-8191
。 - LPI: Locality-specific Peripheral Interrupt,局部外设中断,中断号
>=8192
。LPI 没有 active or active and pending state,得到响应后由处理器自动转入 inactive 状态。LPIs are new in GICv3, and they are different to the other types of interruptin a number of ways . In particular, LPIs are alwaysmessage-based
interrupts,and their configuration isheld in tables in memory
rather than registers.NOTE: LPIs are only supported when GICD_CTLR.ARE_NS==1.
GIC V3 结构
- The Distributor provides the routing configuration for SPIs, and holds all the associated routing and priority.
- 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.
Distributor
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.
GICD_CTLR provides global settings for:
• Enabling affinity routing.
• Disabling security.
• Enabling Secure and Non-secure Group 1 interrupts.
• Enabling Group 0 interrupts.
For SPIs, the Distributor provides a programming interface for:
• 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.
The Distributor registers are identified by the GICD_ prefix.
对所有 CPU 都有效,主要控制 SPI 的相关属性。
Redistributor (GIC_v3, v4)
For each connected PE there is a Redistributor.
Redistributors provide a programming interface for:
• 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.
The Redistributor registers are identified by the GICR_ prefix.
对各个 CPU 有效,主要控制 SGI 和 PPI 的属性。
CPU interface
Each Redistributor is connected to a CPU interface.
The CPU interface provides a programming interface for:
• 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.
对各个 CPU 有效,控制中断是否上报,中断 ack,屏蔽,抢占等。
Interrupt Prioritization
数值越小优先级越高,即 0 优先级最高。优先级是 8-bit 无符号数,实际实现可以采用更少的 bits 来表示,此时相当于优先级分组,比如只用了高 4-bit 来表示,低 4-bit 将被忽略,那么原来的 256 个优先级变成了 16个优先级,原来 0-15 都映射到了 0 优先级上。
In a multiprocessor implementation,
ICC_CTLR_EL1.PRIbits
andICC_CTLR_EL3.PRIbits
indicate the number of priority bits implemented, independently for each target PE.
GICD_IPRIORITYR<n>
控制每个 SPI 的优先级。
GICR_IPRIORITYR<n>
控制每个 SGI 和 PPI 的优先级。
可以通过 BPR
寄存器控制中断的抢占,注意只比较 group priority
。
The Binary Point Registers split a priority value into two fields, the group priority and the subpriority. When
determining preemption, all interrupts with the same group priority are considered to have the same priority,
regardless of the subpriority.
Affinity Route
GICv3 uses affinity routing to identify connected PEs and to route interrupts to a specific PE or
group of PEs. The affinity of a PE is represented as four 8-bit fields:
<affinity level 3>.<affinity level 2>.<affinity level 1>.<affinity level 0>
可以把它类比成 IPv4 地址,只是个 PE 编码 :)。
每个 PE 的 affinity 放在寄存器 MPIDR_EL1
中。
SPIs are routed using an affinity address and the routing mode information that is held in `GICD_IROUTER<n>`.
SGIs are routed using the affinity address and routing mode information that is written by software when it
generates the SGI.
SGIs are generated using the following registers:
• ICC_SGI0R_EL1.
• ICC_SGI1R_EL1.
• ICC_ASGI1R_EL1.
Interrupt lifecycle
State | Details |
---|---|
inactive | An interrupt that is not active or pending. The interrupt source is not currently asserted. |
pending | An interrupt that is waiting to be serviced by a target processor. The interrupt source has been asserted, but the interrupt has not yet been acknowledged by a PE. |
active | An interrupt that has been acknowledged by a processor and is being serviced but has not completed |
active and pending | A processor is servicing the interrupt and the GIC has a pending interrupt from same source |
中断的生命周期和中断的触发方式息息相关。
电平触发
- Inactive to Pending
中断使能且优先级满足触发要求,cpu interface 向 PE asserts 该中断,等待 PE 处理。 - Pending to Active & Pending
中断处理程序中 PE ACK 了 pending 的中断。此时 cpu interface de-asserts 该中断。 - Active and Pending to Active
在 ACK 的基础上,中断源拉低了触发电平,这通常是中断处理程序往外设寄存器写东西,清除了该中断。 - Active to Inactive
中断处理程序表示中断处理完毕,EOI 了该中断。(End of Interrupt)
边沿触发
- Inactive to Pending
中断使能且优先级满足触发要求,cpu interface 向 PE asserts 该中断,等待 PE 处理。 - Pending to Active
中断处理程序中 PE ACK 了 pending 的中断。此时 cpu interface de-asserts 该中断。 - Active to Active and Pending
中断在处理时又再次触发。 - Active and Pending to Pending
PE 在处理完上一个中断后,EOI 该中断,之后 cpu interface re-asserts pending 的第二个中断。
主要描述 ack -> priority drop -> deactive
Activation
通过以下寄存器可以获取当前在PE上被触发的中断号,读操作会转移中断的状态到 active。
The interrupt handler reads ICC_IAR0_EL1
for Group 0 interrupts, and ICC_IAR1_EL1
for Group 1 interrupts.
This read acts as an acknowledge
for the interrupt. 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
.
Priority drop
After an interrupt has been acknowledged, a valid write to ICC_EOIR0_EL1
for Group 0 interrupts, or a valid write to ICC_EOIR1_EL1
for Group 1 interrupts, results in a priority drop. It 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.
值得注意的是,写 EOI
寄存器的顺序和读 IAR
寄存器的顺序必须是严格相反的。
Deactive
PPIs, SGIs, and SPIs have an active state in the IRI and must be deactivated.
SGIs and PPIs must be deactivated by the PE that activated the interrupt. SPIs can be deactivated by a different PE.
Interrupt deactivation is required to change the state of an interrupt either:
• From active and pending to pending.
• From active to inactive.