中断基本概念

在现代嵌入式系统中,处理器上会挂接很多个外设,CPU在执行任务的时候,可能会同时由多个中断发生,那么中断必要要进行响应处理并维护一个队列一一运行,这样自然会影响CPU的效率,为了让CPU专注于实际运算,中断控制器孕育而生,各中断信号源都先交给中断控制器处理,由中断控制器进行管理,同时接受多个中断请求并进行优先级判断,然后选中一个最高优先级的请求送个CPU进行处理,在CPU响应处理中断时,中断控制器仍然可以响应外部中期的请求,在多核系统中,中断控制器还可以承担路由的作用,将某些中断送到指定CPU进行处理,以达到中断处理的负载均衡。在X86架构中断控制器称为APIC(Advanced Programmable Interrupt Controller),ARM架构的中断控制器则称为GIC(Generic Interrupt Controller),本文主要探讨的是GIC模块。
ARM架构的GIC目前已经发展了多个版本,不同的GIC IP使用于不同的ARM架构,下面是不同版本直接的关键features。

Version Key features Architecture Tpically used with
GICv1 Support for up to eight PEs.Support for up to 1020 interrupt IDs.Support for two Security states. A5/A9/R7
GICv2 All key features of GICv1.Support for virtualization. GIC400 A7/A15/A53/A57
GICv3 All key features of GICv2.Support for more than eight PEs.Support for message-based interrupts.Support for more than 1020 interrupt IDs.System register access to the CPU Interface registers.An enhanced security model, separating Secure and Non-secure Group 1 interrupts. GIC500 A72/A53/A57
GICv4 All key features of GICv3 and.Direct injection of virtual interrupts GIC600 A53/A57/A72

GICv2架构

GICv2将中断源类型进行分类。

类型 中断号范围 说明
SGI ID0~ID15 Software Generated Interrupt,软件触发中断,通常用于多核之间通信。
PPI ID16~ID31 Pivate Peripheral Interrupt,每个处理核私有中断,如timer,hw fault等。
SPI ID32~ID1019 Shared Peripheral Interrupt,公用外设中断,最多支持998个。

中断源类型的划分是输入给GIC的角度进行的,而GIC输出到CPU只有IRQ(Interrupt Request)和FIQ(Fast Interupt Request),FIQ主要用于安全OS,不适用于Linux内核本文也暂不讨论。
GIC在GICv2中,有两大模块组成,distributor和interface。

  • Distributor:实现中断的分发,从上图可以看出,SPIs Interrupt ID 32~1019中断是共享的,将会根据事先配置的寄存器GICD_xxx选择最高优先级的中断发往CPU核,PPI、SGI是各CPU独有的中断,不参与目的core的仲裁。distributor对中断主要提供全局中断使能、每个中断使能、中断优先级、中断分组、中断目的CPU核、中断触发方式、中断状态管理、可修改中断的Pending状态等。
  • Interface:将GICD发送的中断信息,通过IRQ/FIQ传输给CPU核。这里分为CPU interface和Virtual CPU interface,后者暂未接触先不讨论。interface提供将中断请求发送给CPU、CPU对中断进行确认、中断处理通知完成、设置中断优先级屏蔽等。

GICv3架构

类型 中断号范围 说明
SIGs ID0~ID15 Software Generated Interrupt,软件触发中断,通常用于多核之间通信。
PPIs ID16~ID31 Pivate Peripheral Interrupt,每个处理核私有中断,如timer,hw fault等。
SPIs ID32~ID1019 Shared Peripheral Interrupt,公用外设中断,最多支持998个。
ID1020~ID1023 Used to signal special cases
1024~8191 Reserved
LIPs 8192~ Locality-specific Peripheral Interrupt,外设不通过专用中断线向GIC发中断,而是基于消息的中断,配置信息存储在memmory中,通过ITS可以解析消息发送给Redistributor触发中断。

相对于GICv2架构GICv3多一个模块,Resdistributor。

  • Distributor:主要用来管理配置SPIs类型的中断。
  • Resdistributor:每个PE(process element,即cpu核)都对应一个,所以想要的配置是针对某个CPU核的,主要用来配置SGI和PPI类型中断。
  • CPU Interface:每个PE对应一个interface,与GICv2的interface一致。

引入LPIs后,对于中断源触发信号给中断控制器就可以分为两类,peripheral interrupt signal和Peripheral interrupt message。

在GICv3,SPIs类型也是可以配置成message 类型中断,但是LPIs只能是message类型中断。

GIC V3版本中寄存器如上图所示,提供了两种方式访问,memory-mapped和系统寄存器访问。

寄存器 说明(memory-mapped访问方式)
GICC CPU interface寄存器
GICD Distributor寄存器
GICR Redistributor寄存器
寄存器 说明(系统寄存器方式方式)
ICC 物理 CPU interface系统寄存器

中断处理过程

状态机

上图是中断控制器的状态机,四种状态适用于SPI,PPI和SGI类型的中断源,而LPIs没有active或active and pending状态。

  • Inactive:中断源没有触发信号。
  • Pending:中断源触发了信号,GIC会将IAR(Interrupt Acklowlege Register)中该中断源对应bit置1,然后通知了CPU,但CPU没有响应ACK给GIC。
  • Active:CPU读取了IAR寄存器置1的位,CPU通过interface读取IAR的寄存器表示确认了这个中断并开始处理,此时中断源进入Active状态。
  • Active and Pending:CPU ACK了这个中断请求后,中断控制器就解除了对该中断源的屏蔽,控制器可以继续响应中断,那么当CPU还在处理中断服务器程序时,此时中断源又触发了信号给中断控制器,此时的状态就处于Acitive and Pending,简称AP。

当CPU完成了中断程序处理,就会写中断控制器的EOI(End of Interrupt)寄存器,中断源的状态就会再次回到inactive状态。
CPU在处理中断程序期间是屏蔽掉IRQ的响应的,处理完成之后才会打开中断响应。这里要注意的是CPU的中断屏蔽和中断控制器的屏蔽是两回事,CPU屏蔽的是IRQ而中断控制器屏蔽的是SPIs/PPIs/SGIs/LPIs。

触发方式

电平触发

电平触发方式时序图如上,可以分为以下几个阶段变化:

  • Inactive to Pending:中断源触发了信号给到中断控制器,GIC收到信号后,如果CPU使能了该中断则触发信号给PE。上图Peripheral To GIC的信号被拉高,继而触发GIC To Core的信号被拉高。
  • Pending to AP:PE通过CPU interface读取了IARs寄存器,状态转为Active。由于CPU操作的是中断控制器,但并没有对设备进行处理,所以设备给中断控制器的触发信号高电平会一直维持,因此会再次触发中断控制器对应bit置位,表示中断又来了。
  • AP to Active:对应高电平的触发类型,通常需要CPU收到中断信号后再去响应外设,如写外设相关寄存器或读写外设的数据等,外设的中断源才会取消触发(高电平->低电平)。状态再次从AP转到Active。
  • Active to Inactive:CPU处理完了中断响应程序,然后写中断控制器EOIRs寄存器,表示中断处理完成。

边沿触发

  • Inactive to Pending:中断源触发了信号给到中断控制器,GIC收到信号后,如果CPU使能了该中断则触发信号给PE,在CPU没有ACK之前,GIC to Core的电平会被一直拉高,直到CPU做出ACK动作。
  • Pending to Active:与电平触发类似。
  • Active to A&P:Linux在处理中断过程中是不允许中断嵌套的,但此时如果有外设再次触发中断,但也不影响,因为中断控制器可以进行处理相当于锁存主第二个中断的到来,这样第二个中断也不会丢失。
  • A&P to Pending:边沿触发方式通常不需要CPU对外设进行中断信号清除,当cpu处理完了当前中断后,会转入准备处理第二个中断。
  • 边沿触发有丢中断的可能,一般情况下可靠性高的使用电平触发方式。

中断控制器的pengding位,在软件处理完成写eoi寄存器后硬件自己会清除,所以软件不需要清pending,但是对于外设是电平类型触发来说,需要清除外设的电平触发源(操作的不是中断控制器,是外设)。