本文是 ARM GICv3 学习笔记系列的第一篇,系统梳理 GICv3 的中断类型、硬件架构、状态机模型、亲和性路由、安全模型以及中断处理流程。内容基于 ARM 官方文档《Learn the architecture - Generic Interrupt Controller v3 and v4, Overview》《Arm Generic Interrupt Controller Architecture Specification》以及《GICv3 and GICv4 Software Overview》整理,侧重于建立 GICv3 的整体认知框架。
1、中断类型与 INTID
GIC(Generic Interrupt Controller)是 ARM 平台上的通用中断控制器,负责管理系统中所有中断的优先级、分发和路由。GICv3 支持四种中断类型,按 INTID(Interrupt ID)范围划分:
| INTID 范围 | 中断类型 | 说明 |
|---|---|---|
| 0--15 | SGI(Software Generated Interrupt) | 软件生成中断,用于处理器间通信(IPI),通过写 GIC 的 SGI 寄存器产生 |
| 16--31 | PPI(Private Peripheral Interrupt) | 私有外设中断,仅属于单个核心,例如 Generic Timer 中断 |
| 32--1019 | SPI(Shared Peripheral Interrupt) | 共享外设中断,可路由到任意已连接的核心 |
| 1020--8191 | 保留 | --- |
| 8192-- | LPI(Locality-specific Peripheral Interrupt) | GICv3 新增,基于 ITS(Interrupt Translation Service)和内存表,编程模型与上述三种截然不同 |

Learn the architecture - Generic Interrupt Controller v3 and v4, Overview
2、硬件连接方式:专用信号线与 MSI
传统中断控制器通过专用硬件信号线从外设连接到中断控制器:

GICv3 在此基础上增加了**消息信号中断(MSI, Message-Signaled Interrupts)**机制:外设通过向中断控制器的寄存器地址发起写操作来触发中断,无需专用物理信号线。

对大型 SoC 而言,MSI 消除了为数百个中断源逐一布设物理信号线的需求,显著简化了后端设计。从软件视角看,无论是专用信号线还是 MSI,中断处理流程基本一致------差异仅在于外设侧的配置方式(例如需要指定中断控制器的地址)。
在 GICv3 中,SPI 可以配置为 MSI,而 LPI 始终是 MSI。不同中断类型的寄存器使用方式如下:

3、中断状态机
3.1 四种基本状态
GIC 为每个 SPI、PPI 和 SGI 维护一个状态机,包含四种状态:
| 状态 | 含义 |
|---|---|
| Inactive | 中断源未触发 |
| Pending | 中断源已触发,但尚未被 PE(Processing Element,即 CPU 核心)确认 |
| Active | PE 已通过读取 ICC_IAR1_EL1 确认该中断 |
| Active and Pending | 当前中断实例处于 Active,同时外设又产生了新的中断请求 |

Learn the architecture - Generic Interrupt Controller v3 and v4, Overview
3.2 电平触发下的状态转换
中断的触发方式(电平/边沿)决定了状态转换路径的差异。
对于 电平敏感(Level-sensitive) 中断,外设拉高中断线后信号会持续保持有效,直到软件清除外设的中断源:

- Inactive → Pending:当中断源被 assert 时,中断从 Inactive 转换为 Pending。此时,如果该中断已使能且优先级足够高,GIC 会向处理器单元 (PE) assert(拉高)中断信号。
- Pending → Active and Pending:当 PE 读取中断确认寄存器 (IAR) 确认中断时,状态本应转为 Active。但由于是电平触发,且外设信号仍然保持 assert(高电平),GIC 检测到输入端依然有效,因此状态立即变为(或保持在) Active and Pending。此时 GIC 会暂时撤销发给 Core 的信号(图中第二个波形中间的凹陷)。
- Active and Pending → Active :软件在中断处理过程中,清除了外设的中断源,导致外设撤销(de-asserts)了中断信号。此时 GIC 检测到输入变低,状态从 Active and Pending 跌落为单纯的 Active。
- Active → Inactive:软件中断处理结束,PE 向中断结束寄存器 (EOIR) 写入。由于此时外设信号已经撤销(处于非挂起状态),GIC 将状态从 Active 转换为 Inactive,完成整个生命周期。
3.3 边沿触发下的状态转换
对于**边沿敏感(Edge-sensitive)**中断,外设发送的是一个脉冲,不会持续保持有效电平:

- Inactive → Pending:当外设发送一个上升沿脉冲时,GIC 捕获到这个边沿,中断从 Inactive 转换为 Pending。GIC 随即向处理器单元 (PE) 发送中断信号。
- Pending → Active:当 PE 读取中断确认寄存器 (IAR) 确认中断时,状态从 Pending 转换为 Active。此时 GIC 会撤销发给 PE 的中断信号(拉低),告诉 PE "你可以开始干活了"。
- Active → Active and Pending:在 PE 还在处理(状态仍为 Active)的时候,外设又发送了第二个脉冲(上升沿)。GIC 再次捕获到这个边沿,因为当前状态已经是 Active,所以它标记一个新的挂起,状态变为 Active and Pending。
- Active and Pending → Pending:当 PE 处理完第一次中断,向中断结束寄存器 (EOIR) 写入时,GIC 认为当前的 Active 实例结束了。但由于刚才捕获了第二个脉冲(处于 Pending 状态),所以状态机从 A&P 回落到 Pending。此时,GIC 会再次向 PE 发送中断信号,通知还有第二次中断需要处理。
4、中断亲和性
4.1 MPIDR_EL1:多核拓扑标识
在多核 ARM 系统中,每个 PE 通过 MPIDR_EL1(Multiprocessor Affinity Register)获得唯一硬件标识。该寄存器使用四个层级字段描述 PE 在拓扑中的位置:
<Aff3>.<Aff2>.<Aff1>.<Aff0>


ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile
不同微架构对这四个字段的使用方式有所差异。以 Cortex-A57 为例:
- Aff3 不支持;
- Aff2 + Aff1 组合标识 Cluster;
- Aff0 的低 2 位标识 Cluster 内的 Core ID(单簇最多 4 核心)。

ARM® Cortex®-A57 MPCore™ Processor Revision: r1p1 Technical Reference Manual
以 cortex-A55 为例:
- Aff0:标识同一核心内的线程 ID(SMT);
- Aff1:标识 Cluster 内的 CPU Core;
- Aff2 + Aff3 组合标识 Cluster。


ARM® Cortex®-A55 Core Revision: r1p0 Technical Reference Manual
关键认知 :
MPIDR_EL1提供了统一的寻址格式,但具体的字段有效位宽和含义取决于微架构实现。配置 GIC 中断路由时,必须确认目标平台的 MPIDR 编码方式。
4.2 GICD_IROUTER:SPI 路由寄存器
GICv3 的中断亲和性建立在 MPIDR_EL1 的拓扑抽象之上。对于每个 SPI,GIC 分配器都有一个对应的 GICD_IROUTER 寄存器(64 位),用于指定该 SPI 的目标 PE。

Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4
字段说明:
| 字段 | 含义 |
|---|---|
| Aff3--Aff0 | 路由目标 PE 的亲和值,直接映射到 MPIDR_EL1 的对应层级 |
| Interrupt_Routing_Mode(bit 31) | 0:精确路由到 Aff3--Aff0 指定的唯一核心;1:由 GIC 从当前参与中断分发的核心中任选一个 |
中断亲和性路由仅适用于 SPI。PPI 是每个核心私有的,无需路由;SGI 通过 SGI 寄存器中的目标字段指定接收方;LPI 的路由由 ITS 管理。
5. 安全模型与中断分组
GICv3 与 ARM TrustZone 深度集成。软件必须为每个 INTID 分配一个组(Group),该组决定了中断的安全属性:
| 组 | 安全状态 | 信号方式 |
|---|---|---|
| Group 0 | Secure | 始终以 FIQ 发出 |
| Secure Group 1 | Secure | 以 IRQ 发出(当前为 Secure 状态时) |
| Non-secure Group 1 | Non-secure | 以 IRQ 发出(当前为 Non-secure 状态时) |

Group 1 中断的具体信号类型(IRQ 还是 FIQ)取决于当前 PE 的安全状态和异常等级:

关键 :IRQ 和 FIQ 是 CPU Interface 与 PE 之间的物理信号线。由 CPU Interface 根据中断的 Group 属性及 PE 当前的安全状态,决定通过哪条信号线向 PE 发出通知。
只有运行在 Secure 状态下的软件才有权分配 INTID 到各个 Group。Non-secure 状态下是否允许访问安全中断的配置/状态,可通过 GICD_NSACRn 和 GICR_NSACR 寄存器逐 INTID 控制。
5.2 双重安全状态与单一安全状态
TrustZone 是可选特性。GICD_CTLR.DS 位控制 GIC 的安全状态模式:

DS == 0:支持双重安全状态(Secure + Non-secure),三种中断组全部可用。DS == 1:仅单一安全状态,只支持 Group 0(FIQ)和 Group 1(IRQ):


6. 中断异常等级路由
在 ARMv8 安全架构中,物理 IRQ 和 FIQ 的异常等级路由由 EL3 的 SCR_EL3 寄存器中两个关键位控制,这是中断进入安全世界的"总开关"。

FIQ 路由控制:


FIQ == 0:EL3 以下产生的物理 FIQ 不进 EL3,由当前异常等级处理。FIQ == 1:所有 FIQ 强制路由到 EL3。
IRQ 路由控制:

IRQ == 0:EL3 以下(EL0/EL1/EL2)产生的物理 IRQ 不进 EL3;即使当前在 EL3,也不接收物理 IRQ。IRQ == 1:所有物理 IRQ 强制路由到 EL3。
将安全模型(第 5 节)与异常等级路由结合来看,典型的配置是:IRQ 路由到 EL1 处理当前安全状态的 Group 1 中断,FIQ 路由到 EL3 处理跨安全状态的中断转发(Secure Monitor 执行上下文切换)。
下图展示了当前执行于 EL0、IRQ 路由到 EL1 且 FIQ 路由到 EL3 时的处理流程:

7. GICv3 架构组件
GICv3 的寄存器接口分为三个层次:
- 分发器(Distributor)接口
- 重分发器(Redistributor)接口
- CPU 接口(CPU interface)
这些接口的关系如下图所示:

Learn the architecture - Generic Interrupt Controller v3 and v4, Overview
7.1 Distributor(分发器)
内存映射寄存器,对系统中所有核心共享,主要负责 SPI 的全局配置:
- SPI 的使能、禁用与优先级设置
- 为每个 SPI 配置路由信息(
GICD_IROUTER) - 将每个 SPI 设置为电平敏感或边沿触发
- 生成消息信号中断(Message-signaled SPIs)
- 控制 SPI 的激活(Active)和挂起(Pending)状态
- 确定每种安全状态(Security state)下使用的编程模型:亲和性路由(Affinity routing)或传统模型(Legacy)。
7.2 Redistributor(重分发器)
每个 PE 私有一组 Redistributor 寄存器,负责该核心的本地中断管理:
- SGI 和 PPI 的使能、禁用与优先级设置
- PPI 的触发方式配置
- SGI 和 PPI 的中断组分配
- 控制 SGI 和 PPI 的状态
- 配置 LPI 的 pending 表和配置表基地址
- 为已连接的 PE 提供电源管理支持
SGI 的生成由本地 PE 写系统寄存器发起,但跨核转发本质上依赖 Distributor 的全局仲裁------Distributor 根据写入的亲和性路由信息,将 SGI 分发到目标 PE 对应的 Redistributor,再由 Redistributor 提交给目标 CPU Interface。
7.3 CPU Interface(CPU 接口)
每个 PE 内部的一组系统寄存器 (ICC_*_ELn),通过 MRS/MSR 指令访问:
- 通用中断控制与使能配置
- 中断确认(Acknowledge)
- 优先级降级(Priority Drop)与停用(Deactivation)
- 设置 PE 的中断优先级掩码
- 定义抢占策略
- 查询当前最高优先级的 Pending 中断
使用 CPU Interface 寄存器之前,必须通过 ICC_SRE_ELn.SRE 位启用系统寄存器接口:


Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4
8、中断处理流程与 Priority 机制
8.1 完整处理流程
一个物理中断在 GIC 中的生命周期包含六个阶段:

Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4
-
Generate interrupt
interrupt 可以由 peripheral(外设)触发,也可以由 software(软件)主动生成。
-
Distribute
IRI(Interrupt Routing Infrastructure)负责进行 interrupt grouping(中断分组)、interrupt prioritization(中断优先级仲裁),并控制将 interrupt forwarding(中断转发)到各个 CPU interface。
-
Deliver
physical CPU interface 会将 interrupt deliver 给对应的 PE(Processing Element,处理单元/CPU 核)。
-
Activate
当运行在 PE 上的软件对某个 interrupt 执行 acknowledge 后(读取 IAR),GIC 会将 Highest Active Priority 更新为该 interrupt 的优先级。
对于 SPI、SGI 和 PPI 类型的 interrupt,此时该 interrupt 会进入 Active 状态。
-
Priority drop
运行在 PE 上的软件通知 GIC:当前最高优先级 interrupt 已经被处理到允许降低 running priority 的阶段。
随后,running priority 会恢复为该 interrupt 被 acknowledge 之前的值。
这一阶段通常表示 interrupt handler 已经执行完 "EOI(End Of Interrupt)" 的语义。
-
Deactivation
Deactivation 会清除 interrupt 的 Active state,从而使该 interrupt 在再次 pending 时,能够重新被 CPU 接收和处理。
对于 LPI(Locality-specific Peripheral Interrupt),不要求执行 deactivation。
8.2 Priority 概念辨析
GIC 中存在多个容易混淆的优先级概念:
| 名称 | 含义 |
|---|---|
| interrupt priority | 中断本身的优先级(寄存器中配置的静态值) |
| highest pending priority | 当前所有 Pending 中断中的最高优先级 |
| active priority | 当前 Active 中断的优先级 |
| running priority | CPU 当前的抢占门槛(Preemption Threshold) |
其中最关键的是 Running Priority ------它不表示"CPU 当前运行什么中断",而是定义哪些中断可以抢占当前执行。GIC 中优先级数值越小表示优先级越高。
举例:CPU 正在处理优先级 0x40 的中断------优先级 0x10 的中断可以抢占,优先级 0x80 的中断则只能保持 Pending。
8.3 Priority Drop 与 Deactivation 分离
传统中断控制器中,EOI 同时完成"降低优先级"和"结束中断"两个动作。GICv3 将它们拆分为两个独立阶段:
| 阶段 | 作用 |
|---|---|
| Priority Drop | 降低 Running Priority,允许其他中断进入 |
| Deactivation | 清除 Active 状态,结束当前中断实例 |


分离设计的优势:
- 更早恢复中断响应能力(Priority Drop 后即可响应更高优先级中断);
- 避免低优先级中断被长时间阻塞;
- 同时防止同一中断重复进入(Deactivation 前该中断仍视为 Active)。
8.4 EOImode
Priority Drop 与 Deactivation 是否同时发生,由 ICC_CTLR_EL1.EOImode 控制:



| 模式 | 写 ICC_EOIR1_EL1 的效果 |
额外操作 |
|---|---|---|
| EOImode = 0(默认) | 同时完成 Priority Drop + Deactivation | 无需 |
| EOImode = 1(Split EOI) | 仅执行 Priority Drop | 需显式写 ICC_DIR_EL1 完成 Deactivation |
Split EOI 模式下,写 EOIR 后 Running Priority 恢复,CPU 可以立即响应其他中断,但当前中断仍保持 Active 状态------这也是 Pending + Active 状态产生的核心场景之一。


8.5 Pending + Active 状态的设计价值
Split EOI 模式下,Pending + Active 状态解决了一个关键问题:
以 UART 电平触发中断为例:
- CPU 已确认(Acknowledge)该中断,进入 Active 状态;
- 软件执行 Priority Drop(写 EOIR),恢复 Running Priority;
- 设备侧中断线仍保持有效(外设尚未清除中断源)。
此时外设信号持续有效,中断可能再次进入 Pending。但由于该中断仍处于 Active,GIC 不会再次激活同一个中断实例,而是进入 Pending + Active 状态。
这一机制的核心价值是:
允许其他中断继续响应(高优先级抢占),同时避免当前中断处理函数递归重入。
这也是 ARM GIC 将中断抢占与中断完成解耦的设计思想所在。
9. SGI 的发送与接收
9.1 SGI 寄存器
SGI 通过写 CPU Interface 中的系统寄存器生成。GICv3 提供三个 SGI 寄存器,分别对应不同的安全属性:

| 寄存器 | 用途 | 访问条件 |
|---|---|---|
ICC_SGI0R_EL1 |
生成 Group 0 中断(最高优先级 Secure 任务) | Secure 状态 |
ICC_SGI1R_EL1 |
生成 Group 1 中断,目标为当前安全状态 | Secure 或 Non-secure |
ICC_ASGI1R_EL1 |
生成 Group 1 中断,目标为对侧安全状态 | 仅 Secure 状态(通常 EL3) |
ICC_SGI1R_EL1 的行为取决于写寄存器时 PE 的安全状态:
- 当前在 Secure 世界 → 发送的是 Secure Group 1 中断(SGI)
- 当前在 Non-secure 世界 → 发送的是 Non-secure Group 1 中断(NSGI)
ICC_ASGI1R_EL1 用于 Secure 世界主动向 Non-secure 世界发送中断。

9.2 目标路由控制
SGI 寄存器中的 IRM(Interrupt Routing Mode)字段决定路由策略:
模式一:精确投递(IRM = 0)
中断发送到 <Aff3>.<Aff2>.<Aff1>.<Target List> 指定的核心。其中 <Target List> 是一个位图(bitmap),每一位对应 <Aff1> 层级下的一个核心(实际上替代了 Aff0 的作用)。一次 SGI 最多可同时发送给 16 个 PE,且可以包含发起者自身。
模式二:广播(IRM = 1)
中断发送给系统中所有已连接的核心,但排除发起者自身。适用于需要通知全局但无需自扰的场景。
9.3 安全状态与分组的转发规则
SGI 的安全属性和分组由三个因素共同决定:
- 发起方 PE 的安全状态
- 写入的 SGI 寄存器(SGI0R / SGI1R / ASGI1R)
- 目标 PE 的本地配置 (
GICR_IGROUPR0和GICR_IGRPMODR0)
GIC 在转发前会综合检查上述条件。目标 PE 的 GICR_IGROUPR0 和 GICR_IGRPMODR0 配置必须与中断实际携带的 Group 属性一致,否则不予转发。

注:此表假设 GICD_CTLR.DS == 0。当 GICD_CTLR.DS == 1,标记为(*)的 SGI 也被转发。
10. 关键寄存器速查
10.1 Distributor
Distributor 寄存器为内存映射(Memory-mapped),对系统所有核心全局可见,主要负责 SPI 的配置与分发。关键寄存器如下:
| 寄存器 | 功能 |
|---|---|
GICD_CTLR |
全局控制:使能 Group 0/1、亲和性路由、安全状态模式(DS)、ARE 等 |
GICD_TYPER |
类型信息:系统支持的 SPI 数量、LPI 是否支持、ITS 数量等 |
GICD_IIDR |
实现者标识:产品 ID 与版本号 |
GICD_IGROUPRn/GICD_IGRPMODRn |
中断分组:为每个 INTID 分配 Secure Group 0/Non-secure Group 1/Secure Group 1 |
GICD_ISENABLERn |
中断使能(Set):置位对应 bit 使能该 SPI |
GICD_ICENABLERn |
中断使能(Clear):置位对应 bit 禁用该 SPI |
GICD_ISPENDRn / GICD_ICPENDRn |
Pending 状态控制(Set/Clear):手动置位或清除 SPI 的 Pending 状态 |
GICD_ISACTIVERn / GICD_ICACTIVERn |
Active 状态控制(Set/Clear):手动置位或清除 SPI 的 Active 状态 |
GICD_IPRIORITYRn |
优先级配置:为每个 SPI 设置 8-bit 优先级值 |
GICD_ICFGRn |
触发方式配置:将每个 SPI 设置为电平敏感或边沿触发 |
GICD_IROUTERn |
中断路由:为每个 SPI 指定目标 PE 的亲和性地址(对应 MPIDR_EL1)及路由模式 |
GICD_NSACRn |
非安全态访问控制:控制 Non-secure 状态下能否访问各 INTID 的安全中断配置 |
GICD_SGIR |
传统 SGI 生成(Legacy 模式下使用) |



10.2 Redistributors
Redistributor 寄存器为每个 PE 私有(内存映射),负责该核心的 SGI/PPI 管理及 LPI 基地址配置。关键寄存器如下:
| 寄存器 | 功能 |
|---|---|
GICR_CTLR |
Redistributor 控制:使能当前 PE 的中断转发、电源管理等 |
GICR_TYPER |
类型信息:当前 PE 的亲和性值、LPI 支持情况 |
GICR_WAKER |
唤醒控制:控制 Redistributor 的睡眠/唤醒状态转换 |
GICR_IGROUPR0 |
中断分组:为当前 PE 的 SGI/PPI 分配 Group 0 或 Group 1 |
GICR_IGRPMODR0 |
Group 1 安全属性:为当前 PE 的每个 Group 1 INTID 指定 Secure 或 Non-secure |
GICR_ISENABLER0 / GICR_ICENABLER0 |
中断使能(Set/Clear):使能或禁用当前 PE 的 SGI/PPI |
GICR_ISPENDR0 / GICR_ICPENDR0 |
Pending 状态控制(Set/Clear):手动管理 SGI/PPI 的 Pending 状态 |
GICR_ISACTIVER0 / GICR_ICACTIVER0 |
Active 状态控制(Set/Clear):手动管理 SGI/PPI 的 Active 状态 |
GICR_IPRIORITYRn |
优先级配置:为 SGI/PPI 设置优先级 |
GICR_ICFGR0 / GICR_ICFGR1 |
触发方式配置:将 PPI 设置为电平敏感或边沿触发(SGI 固定为边沿) |
GICR_NSACR |
非安全态访问控制:控制 Non-secure 软件能否生成 Secure SGI |
GICR_PROPBASER |
LPI 配置表基地址:指向内存中 LPI 属性表的物理地址 |
GICR_PENDBASER |
LPI Pending 表基地址:指向内存中 LPI Pending 状态表的物理地址 |
GICR_IGROUPR0:该寄存器用于划分当前 PE 上每个 INTID 的中断组别(是属于 Group 0 还是 Group 1)


GICR_IGRPMODR0:该寄存器用于界定属于 Group 1 的每个 INTID 的安全状态(是属于 Secure 还是 Non-secure)


10.3 CPU Interface
CPU Interface 寄存器以系统寄存器形式(ICC_*_ELn)访问,通过 MRS/MSR 指令读写。关键寄存器如下:
| 寄存器 | 功能 |
|---|---|
ICC_SRE_ELn |
系统寄存器接口使能:控制 CPU Interface 是否通过系统寄存器访问(SRE 位) |
ICC_CTLR_EL1 |
CPU Interface 控制:含 EOImode、优先级丢弃模式等全局配置 |
ICC_PMR_EL1 |
优先级掩码:屏蔽优先级低于设定值的中断,实现中断屏蔽与抢占控制 |
ICC_IAR1_EL1 |
中断确认:读取当前最高优先级 Pending 中断的 INTID,同时使该中断进入 Active 状态 |
ICC_EOIR1_EL1 |
中断结束:执行 Priority Drop / Deactivation(具体行为取决于 EOImode) |
ICC_DIR_EL1 |
中断停用:在 Split EOI 模式下显式清除 Active 状态(Deactivation) |
ICC_RPR_EL1 |
Running Priority:只读,反映当前 CPU 的抢占门槛 |
ICC_HPPIR1_EL1 |
最高 Pending 优先级:只读,查询当前最高优先级 Pending 中断的 INTID |
ICC_SGI0R_EL1 |
SGI 生成(Group 0):生成 Secure Group 0 中断,仅 Secure 态可用 |
ICC_SGI1R_EL1 |
SGI 生成(Group 1, 当前安全态):生成 Group 1 中断,目标为当前安全状态 |
ICC_ASGI1R_EL1 |
SGI 生成(Group 1, 对侧安全态):生成 Group 1 中断,目标为对侧安全状态,仅 EL3 可用 |
参考
- Learn the architecture - Generic Interrupt Controller v3 and v4, Overview Version 3.2
- Arm Generic Interrupt Controller Architecture Specification --- GIC architecture version 3 and version 4
- GICv3 and GICv4 Software Overview