GIC 硬件原理
GIC,Generic Interrupt Controller。是ARM公司提供的通用中断控制器。主要功能是接收硬件中断信号,经过一定处理后分发给相应的CPU进行处理。
当前GIC 有四个版本,GIC v1~v4, 本文主要介绍GIC v3控制器。
GIC v3中断类别
GICv定义了以下中断类型:
(Software Generated Interrupt):软件触发的中断。软件可以写 GICD_SGIR 寄存器触发核间通信和内核中的中断事件 IPI:inter-processor interrupts 就是基于 SGI。
(Private Peripheral Interrupt):中断私有外设。这是每个核心私有的中断。PPI将送达指定CPU上,有应用场景CPU本地时钟。
(Shared Peripheral Interrupt):公共外部设备中断也被定义为共享中断。中断后,它可以分发到某个部分CPU上面。例如,按钮触发中断,手机触摸屏触发中断。
(Locality-specific Peripheral Interrupt):LPI 是 GICv3 它们在许多方面都不同于其他类型的中断。LPI 它们的配置总是基于信息的中断不是寄存器。 PCIe 的 MSI/MSI-x 中断。
中断类型 | 硬件中断号 |
---|---|
SGI | 0-15 |
PPI | 16-31 |
SPI | 32-1019 |
reserved | ... |
LPI | 8192-MAX |
GIC v3 组成

GICv3 控制器由以下三部分组成:
:SPI 中断管理将中断发送给 Redistributor
打开或关闭每个中断。Distributor控制中断分为两个层次。一是控制全局中断(GIC_DIST_CTRL)。一旦全局中断关闭,任何中断源产生的中断事件都不会传递到 CPU interface。另一个层次是控制每个中断源(GIC_DIST_ENABLE_CLEAR),关闭某一个中断源会导致该中断事件不会分发到 CPU interface,但不影响其他中断源中断事件的分配。
控制将当前优先级最高的中断事件分发到一个或者一组 CPU interface。当一个中断事件分发到多个 CPU interface 的时候,GIC 应保证只保证内部逻辑 assert 一个CPU。
优先控制。
interrupt属性设置。设置各外设中断的触发方法:电平触发和边缘触发;
interrupt group设置。设置每个中断 Group,其中 Group0 支持安全中断 FIQ 和 IRQ,Group1 只支持非安全中断 IRQ;
:SGI,PPI,LPI 中断管理将中断发送给 CPU interface
启用和禁用 SGI 和 PPI。
设置 SGI 和 PPI 的优先级。
将每个 PPI 设置为电平触发或边缘触发。
将每个 SGI 和 PPI 分配给中断组。
控制 SGI 和 PPI 的状态。
支持内存中数据结构的基址控制 LPI 相关中断属性和悬挂状态。
电源管理支持。
:传输中断给 Core
打开或关闭 CPU interface 向连接的 CPU assert 中断事件。对于 ARM,CPU interface 和 CPU 中断信号线之间是 nIRQCPU 和 nFIQCPU。如果中断被关闭,即使是 Distributor 中断事件分发到 CPU interface,也不会 assert 指定的 nIRQ 或者 nFIQ 通知 Core。
中断确认。Core 会向 CPU interface 响应中断(响应当前优先级最高的中断),一旦响应中断,Distributor 将中断状态从 pending 修改成 active 或者 pending and active(这与中断源的信号有关,例如,如果电平中断并保持它 asserted 那就是电平 pending and active)。ack 中断后,CPU interface 就会 deassert nIRQCPU 和 nFIQCPU 信号线。
中断处理后的通知。当 interrupt handler 处理中断后,会写 CPU interface 寄存器通知 GIC CPU 中断已经处理好了。做这个动作的一方面是通知 Distributor 修改中断状态 deactive,另一方面,另一方面,CPU interface 会 priority drop,允许其他的 pending 的中断向 CPU 提交。
为 CPU 设置中断优先级掩码。 priority mask,可以 mask 一些优先级相对较低的中断不会被通知 CPU。
设置 CPU 的中断抢占(preemption)策略。
当多个中断事件同时到来时,选择优先级最高的通知 CPU。
GICv3 控制器内部模块和各中断类型的关系如下图所示:
中断路由
GICv3 使用 hierarchy 来标识一个具体的 core, 下图为四层结构(aarch64):
用 <affinity level 3>.<affinity level 2>.<affinity level 1>.<affinity level 0> 一种形式 PE 的路由。每一个 core 的 affnity 值可以通过 MPDIR_EL1 获取寄存器, 每一个 affinity 占用8bit。配置对应 core 的 MPIDR 值,中断路由可以 core 上。
各个 affinity 定义是基础 SOC 自己的定义,比如:
<groupofgroups>.<groupofprocessors>.<processor>.<core> <groupofprocessors>.<processor>.<core>.<thread>
设置中断亲和力的通用函数是 irq_set_affinity,以后会详细介绍。
中断状态机
如下图所示:
Inactive:没有中断,也就是没有 Pending 也没有 Active。
Pending:通过硬件信号通知硬件或软件触发中断 GIC,等待 GIC 分配的那个 CPU 处理,在电平触发模式下保持中断 Pending 状态。
Active:CPU 已经应答(acknowledge)中断请求,正在处理中。
Active and pending:当处于中断源时 Active 在状态下,同一中断源触发中断,进入 pending 状态。
中断处理过程
https://dragonki先暂时略过.blog.这里的详细net/article/de相关内容详细分为/1058
外设发起中断,发送给 Distributor
Distributor 将中断分发给适当的 Redistributor
Redistributor 发送中断信息 CPU interface
li>
处理器接收该异常,并且软件处理该中断
CPU interface 产生合适的中断异常给处理器
5T技术资源大放送!包括但不限于:C/C++,Arm, Linux,Android,人工智能,单片机,树莓派,等等。在上面的【人人都是极客】公众号内回复「peter」,即可免费获取!!