GIC与中断处理

本文详细解释了中断的初始化过程,硬件中断如何与内核交互,GIC中断管理器的结构及其在大规模SoC中的应用,以及Linux内核中断处理的流程,重点介绍了GIC(GenericInterruptController)在中断管理中的关键角色和中断状态转换机制。
摘要由CSDN通过智能技术生成

1.中断是怎么处理的

下文通过几个疑问 给出了硬件和软件是怎么交互并处理中断的

1.1 中断什么时候初始化?

中断初始化是伴随内核【就是操作系统】的初始化过程进行的。各硬件及外设的中断处理程序注册时间是不确定的,有的是在内核初始化过程中就完成注册,有的外设是在运行过程中后来接入的,时间就不可预知。

下面的链接详细区分了内核/os/进程

内核Kernel/操作系统OS/进程和程序-CSDN博客

1.2 中断是一个独立的进程吗?

中断的发生时刻是不可预知的,所以内核在初始化时完成中断初始化,这里的中断初始化主要是

  • 对中断控制器硬件的初始化,分配寄存器地址,配置寄存器等
  • 给中断向量表分配地址空间,并初始化【这个向量表会在后续有新的外设接入时更新】
  • 注册中断irq_domain

中断不是一个进程,进程是内核/操作系统为管理运行的各种用户程序而给出的概念。像管理硬件资源这种操作都是OS操作系统处理的。

而OS是和cpu core绑定的,可以理解为cpu core的驱动程序。cpu core上有中断的硬件连线,收到中断后,OS直接跳到中断处理流程,而无论当前执行的是什么进程。

中断的硬件连线又是来自于中断控制器的输出,输出是直接给了cpu core,也不是给哪个进程

1.3 硬件中断是各种各样的,cpu是如何正确执行对应的中断处理函数

硬件是各种各样的,但是当硬件运行起来后【初始化时候】,该硬件的驱动程序就会到内核中注册自己的中断处理函数,就建立了中断号到中断处理程序的对应关系,CPU获取到一个中断号后,查到对应的中断处理程序调用就好了。这两者的对应关系最后会抽象成了中断向量表, 现在叫 IDT中断描述符表

2.gic中断管理器

2.1 中断管理器的结构和组件

为了适应大规模的SoC设计,GIC-600被设计成分布式IP【和noc/nic一样可以分布在不同clk domain/power domain/harden】。所谓分布式,GIC-600由几种组件构成,每个组件可以跟其它相关模块在物理设计上摆放在一起,并与其拥有共同的电源域;组件之间通过片上网络(network on chip,简称NoC)通信,从而达到更好的时序。

2.1.1 gic组件

GIC-600的重要组件包括以下几种:

  • Distributor:GIC-600的核心部件,负责与其它组件通信,主要处理SPI和LPI
  • Redistributor:与cluster或core交互,主要处理PPI和SGI,同时将Distributor发送过来的SPI与直接传输过来的PPI、SGI进行优先级排序,然后输出给cpu core/cluster
  • ITS(Interrupt Translation Service):处理基于消息的中断,用于解析LPI
  • SPI collator:顾名思义,收集整理SPI
  • Wake request:组件的主要作用就是可以产生唤醒信号给core,如果SoC设计中没有做关于core功耗方面的设计,这个组件可以不需要;如果有功耗控制的需求,这些唤醒信号要给SCP(system control processor)或者相关的模块,再做进一步的设计,具体取决于设计需要了。

一个soc里只有一个Distributor,同时可以有若干redistributor,但是redistributor只与distributor通信,且需要双向传输,Redistributor是和cpu core或cluster一一对应的。

GIC与cpu通信的接口是cpu interface。cpu interface,将GICD[Distributor]发送的中断信息,通过IRQ,FIQ管脚,发送给连接到该cpu接口的core。有种说法有reDistributor的GIC只通过reD与core交互,也就是reD与core用cpu interface连接

2.1.2 中断类型

  • SGI (Software Generated Interrupt):软件触发的中断。软件可以通过写 GICD_SGIR 寄存器来触发一个中断事件,一般用于核间通信,内核中的 IPI:inter-processor interrupts 就是基于 SGI。
  • PPI (Private Peripheral Interrupt):私有外设中断。这是每个核心私有的中断。PPI会送达到指定的CPU上,应用场景有CPU本地时钟。
  • SPI (Shared Peripheral Interrupt):公用的外部设备中断,也定义为共享中断。中断产生后,可以分发到某一个CPU上。比如按键触发一个中断,手机触摸屏触发的中断。
  • LPI (Locality-specific Peripheral Interrupt):LPI 是 GICv3 中的新特性,它们在很多方面与其他类型的中断不同。LPI 始终是基于消息的中断,它们的配置保存在表中而不是寄存器。比如 PCIe 的 MSI/MSI-x 中断。

怎么理解PPI和SPI呢?这里的私有和共用是相对于cpu core/cluster而言的,比如说一个DMA的中断既可以上报给core0也可以上报给core1,那么它就是一个SPI。SPI最终上报给哪个core这就是Distributor的工作。而关于core0的clk的中断是只能给core0的,那么这个中断就属于core0的私有中断。无论PPI还是SPI都是外设产生的

SGI这类软件中断和PPI有一个共同点就是产生的时候已经确定要哪一个core处理,所以PPI和SGI都是不需要Distributor进行仲裁的,也就不需要经过Distributor,而是直接连接到reDistributor

LPI是一种新类型的中断,基于消息的中断,需要ITS[Interrupt Translation Service]来解析才能给core处理。

下图给出了PPI的一些中断示例。

2.1.3 gic的结构

gic既然是分布式组件,那么组件间就需要有互联。有两种典型的互联架构:

  1. 组件间通过私域互联
  2. 组件间通过支持AXI-stream接口的noc互联

上图就是私有桥接的方式,互联组件

上图是走系统的互联总线

第一种方法,适合规模较小的,全局时钟方案简单的SoC,GIC-600的组件不依赖于片上网络(因为没有可用接口,比如NIC等)。这种方法的弊端是,组件之间的走线可能会非常长,并且可能需要在别的IP中穿行。好处是,不占用任何NoC的带宽。

第二种方法,适合大规模的物理设计,尤其是全局时钟方案复杂的SoC。比如有很多的cluster,一般而言,一个redistributor对应一个cluster,这样redistributor可以和cluster一起做布局布线,redistributor和cluster之间的通信可以保持在一个比较高的频率,且timing容易实现。同样,对于有很多PCIe控制器的设计,ITS可以和PCIe控制器放在一起,实现LPI。对于SPI来说,一般多是给低速的外设准备的,所以SPI collator可以和distributor放在一起。
 

2.2 AXI stream接口

gic组件间无论采用私域互联还是总线互联,组件的互联接口都是AXI4-stream接口,该接口可参考

AXI4/AXI5-Stream协议介绍

相比于AXI4接口,AXI-stream接口只相当于只有AXI的aw/w/b/ar/r中的wch和rch,也就是只有读写两个方向的数据流,没有cmd和响应通道。

注意AXI5新增的一个TWAKEUP信号。

2.2.1 属性层次(affinity level)

AXI-stream用TDEST信号来寻址目的地,下面给出了GICv3的core层次结构,可根据层次结构来设置TDEST。

GICv3的一大变化,是对core的标识。对core不在使用单一数字来表示,而是使用属性层次来标识,和arm core,使用MPIDR_EL1系统寄存器来标识core一致。

每个core,根据属性层次的不同,使用不同的标号来识别。如下图所示,是一个4层结构,那么对于一个core来说,就可以用 xxx.xxx.xxx.xxx 来识别。

这种标识方式,和ARMv8架构的使用MPIDR_EL1寄存器,来标识core是一样的。

img

2.3 中断处理状态转换

下面一段摘自:

Linux 中断 —— ARM GIC 中断控制器_gic 中断抢占-CSDN博客

GIC仲裁单元:为每一个中断维护一个状态机,分别是:inactive、pending、active and pending、active。

下面是来自IHI0048B GIC-V2规格书3.2.4 Interrupt handling state machine截图:

GIC检测中断流程如下:

(1) 当GIC检测到一个中断发生时,会将该中断标记为pending状态(A1)。

(2) 对处于pending状态的中断,仲裁单元回确定目标CPU,将中断请求发送到这个CPU上。

(3) 对于每个CPU,仲裁单元会从众多pending状态的中断中选择一个优先级最高的中断,发送到目标CPU的CPU Interface模块上。

(4) CPU Interface会决定这个中断是否可以发送给CPU。如果该终端优先级满足要求,GIC会发生一个中断信号给该CPU。

(5) 当一个CPU进入中断异常后,会去读取GICC_IAR寄存器来响应该中断(一般是Linux内核的中断处理程序来读寄存器)。寄存器会返回硬件中断号(hardware interrupt ID),对于SGI中断来说是返回源CPU的ID。

     当GIC感知到软件读取了该寄存器后,又分为如下情况:

     * 如果该中断源是pending状态,那么转改将变成active。(C)    

     * 如果该中断又重新产生,那么pending状态变成active and pending。(D)

     * 如果该中断是active状态,现在变成active and pending。(A2)

(6) 当处理器完成中断服务,必须发送一个完成信号EOI(End Of Interrupt)给GIC控制器。软件写GICC_EOIR寄存器,状态变成inactive。(E1)

补充:

(7) 对于level triggered类型中断来说,当触发电平消失,状态从active and pending变成active。(B2)

常用路径是A1->D->B2->E1。

3.参考资料

吐血整理 | 肝翻 Linux 中断所有知识点 - 阅读清单 - 腾讯云开发者社区-腾讯云

上面链接从硬件和linux内核中断两方面介绍了中断的处理,更偏向于linux内核中断处理,从初始化到中断向量表,到检测到中断触发开始中断处理的过程。

Linux中断一网打尽(1) —— 中断及其初始化-腾讯云开发者社区-腾讯云

上面这一篇侧重于讲解内核中断初始化过程,比第一篇关于初始化的过程详细一些

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值