ARM通用中断控制器-GIC
GIC简介
GIC 是联系外设中断和 CPU 的桥梁,也是各 CPU 之间中断互联的通道(也带有管理功能),它负责检测、管理、分发中断。ARM CPU 对外的连接只有2 个中断: IRQ和FIQ ,相对应的处理模式分别是一般中断(IRQ )处理模式和快速中断(FIQ )处理模式。所以GIC 最后要把中断汇集成2 条线,与CPU 对接。
ARM GIC-v2支持三种类型的中断:
- SGI:软件触发中断(Software Generated Interrupt),通常用于多核间通讯,最多支持16个SGI中断,硬件中断号从ID0~ID15。SGI通常在Linux内核中被用作IPI中断(inter-processor interrupts),并会送达到系统指定的CPU上。
- PPI:私有外设中断(Private Peripheral Interrupt),是每个CPU私有的中断。最多支持16个PPI中断,硬件中断号从ID16~ID31。PPI通常会送达到指定的CPU上,应用场景有CPU本地时钟。
- SPI:公用外设中断(Shared Peripheral Interrupt),最多可以支持988个外设中断,硬件中断号从ID32~ID1019。
从GIC中断控制器结构中,我们可以把GIC划分成两个部分:分发器( Distributor )和 CPU 接口(CPU Interface ) - 分发器的主要的作用是检测各个中断源的状态,控制各个中断源的行为,分发各个中断源产生的中断事件到指定的一个或者多个CPU接口上。虽然分发器可以管理多个中断源,但是它总是把优先级最高的那个中断请求送往CPU接口。
- CPU接口主要用于和CPU进行对接
GIC中断处理流程
中断的处理流程是:
- 分发器把收集来的中断先缓存,依次把优先级最高的中断请求送往CPU接口。GIC中断控制器支持中断优先级抢占,一个高优先级中断可以抢占一个低优先级且处于active状态的中断,即GIC仲裁单元会记录和比较当前优先级最高的pending状态,然后去抢占当前中断,并且发送这个最高优先级的中断请求给CPU,CPU应答了高优先级中断,暂停低优先级中断服务,进而去处理高优先级中断。GIC会将pending状态优先级最高的中断请求发送给CPU。
- CPU读取一个中断,其实就是读取接口的一个寄存器,只不过这个寄存器存放的是中断号,此时中断的状态由pending转为active。
- CPU处理完了以后,将中断号写入GIC的接口,告诉GIC处理完了,可以将这个中断清理。
Linux对中断抢占处理
从GIC角度看,GIC会发送高优先级中断请求给CPU。但是目前CPU处于关中断状态,需要等低优先级中断处理完毕,直到发送EOI给GIC。然后CPU才会响应pending状态中优先级最高的中断进行处理。所以Linux下:
- 高优先级中断无法抢占正在执行的低优先级中断。
- 同处于pending状态的中断,优先响应高优先级中断进行处理。
参考文档:
https://blog.****.net/xiafeng1113/article/details/44998179