资讯详情

linux kernel 中断子系统之(一)-- ARM GIC 硬件

中断是系统中非常重要的组成部分之一。有了中断,系统就不能一直轮流查询(polling)如果发生事件,系统效率可以提高,中断控制通常分散在不同的地方。不同的部分由不同功能的程序控制,使系统能够正常工作。在一般系统中,中断控制分为模块、中断控制器中断控制器、处理器、寄存器通常可以控制能量中断功能、中断触发条件等;中断控制器可以管理中断优先级,所有中断处理器都有寄存器设置是否响应中断。

1.全景

作为ARM系统中常用的中断控制器是GIC(Generic Interrupt Controller),目前有四个版本,V1~V4(V2最多支持8个ARM core,V3/V4支持更多的ARM core,主要用于ARM64系统结构)。目前在ARM官方网站只能下载Version 2的GIC architecture specification。其中GIC-500最多支持128个 cpu core,它要求ARM core必须是ARMV8指令集(例如Cortex-A57),符合GIC architecture specification version 3。本文的主要描述是GIC-400更适合嵌入式系统version 2的GIC architecture specification。GIC-400通过AMBA(Advanced Microcontroller Bus Architecture)这样的电影总线连接到一个或多个ARM processor上。先看一张GIC在系统中的作用全景图(overview)。

ee97437d33d9dfdd3e9661e027b87364.png

从这张图中可以看出,GIC是联系外设中断和CPU桥梁,也不相同CPU它负责检测、管理和分发中断互联通道(也具有管理功能),可以做到:

能量或禁止中断;

将中断分组到组中0或组1(安全系统使用)FIQ,Group0,Group1作为非安全系统连接IRQ);

将中断分配到多核系统的不同处理器上;

设置电平触发或边缘触发(不等于外设触发);

虚拟扩展;

ARMCPU对外连接只有两个中断,一个是IRQ,一个是FIQ,相应的处理模式是一般中断(IRQ)处理模式和快速中断(FIQ)所以GIC最后,将中断集成到两条线中CPU对接。

2.详细设计

在介绍了整体印象之后,下面将介绍详细的部分,在介绍之前,首先了解GIC中涉及的几个概念,GIC有三种类型的中断:SGI(Software-generatedinterrupt)、PPI(Privateperipheralinterrupt)、SPI(Sharedperipheralinterrupt)。

SGI:SGIsaregeneratedbywritingtotheSoftwareGeneratedInterruptRegister,GICD_SGIR.EachCPUinterfacecangenerateamaximumof16SGIs,ID0-ID15,foreachtargetprocessor.SGI为软件可以触发的中断,统一编号为0~15,用于各个core通信。

PPI:APPIisaninterruptthatisspecifictoasingleprocessor.AllPPIsignalsareactive-LOWlevel-sensitive.Table2-3showsthePPIsthatareavailableforeachprocessor.PPI为每个core中断私有外设,例如,每个统一编号为16-31,CPU的 local timer 即Arch Timer中断就是通过PPI发送给CPU的(安全为 29, 非安全为 30)。

SPI:SPIsaretriggeredbyeventsgeneratedonassociatedinterruptinputlines.TheGIC-400cansupportupto480SPIscorrespondingtotheexternalIRQS[479:0]signal.ThenumberofSPIsavailabledependsontheimplementedconfigurationoftheGIC-400.Thepermittedvaluesare0-480,instepsof32.SPIsstartatID32.YoucanconfigurewhethereachSPIisedge-triggeredonarisingedgeorisactive-HIGHlevel-sensitive.SPI是系统外设的中断,为各个core公共中断统一编号为32~1019,如globaltimer、uart、gpio中断。

还是先看图:

从图中可以看出,GIC可分为两部分:分发器( Distributor )和CPU接口(CPUInterface )。CPU interface有两种,一种是普通processor接口,另一个是虚拟机接口。Virtual CPU interface本文不会详细描述。其实分发器应该叫汇聚器,在IC在后端设计中,layout将各模块引入的中断线(即上述三种中断线)混合到GIC然后接收混合中断CPU的IRQ和FIQ线上,这样CPU有触觉。

其中Distribute只有一套,所以只有一个基地址,Interface因为每个,有很多套CPU都对应一套interface。所以严格来说,GIC最终输出线的数量应该是CPU的个数*2,但通常的设计保证了每一个CPU看到的interface基地址也一样,程序上看到的基地址也一样。

每个子中断使能,设置触发模式,优先排序,分发到哪个CPU这些功能由上Distribute负责,总的中断使能,状态维护由Interface负责。

Distributor 概述

Distributor检测功能是检测每一个interrupt source控制每种状态interrupt source分发各种行为interrupt source中断事件分发给指定的一个或多个CPU interface上。虽然Distributor多个可以管理interrupt source,但它总是优先级最高的那个interrupt请求送往CPU interface。Distributor控制中断包括:

(1)中断enable或者disable的控制。Distributor控制中断分为两个层次。一是控制全局中断(GIC_DIST_CTRL)。一旦disable如果全局中断,那么任何事情都会被打断interrupt source产生的interrupt event不会传递CPU interface。另一个层次是针对每个层次的interrupt source进行控制(GIC_DIST_ENABLE_CLEAR),disable某一个interrupt source会导致该interrupt event不会分发到CPU interface,但不影响其他interrupt source产生interrupt event的分发。

(2)控制将当前优先级最高的中断事件分发给一组或一组CPU interface。当一个中断事件分发到多个CPU interface的时候,GIC应保证只保证内部逻辑assert 一个CPU。

(3)优先控制。

(4)interrupt属性设置level-sensitive还是edge-triggered

(5)interrupt group的设定

Distributor几个可以管理interrupt source,这些interrupt source用ID我们称之为标识interrupt ID。

CPU interface

CPU interfce这个block主要用于和process进行接口。该block的主要功能包括:

(a)enable或者disable CPU interface向连接的CPU assert中断事件。对于ARM,CPU interface block和CPU之间的中断信号线是nIRQCPU和nFIQCPU。如果disable了中断,那么即便是Distributor分发了一个中断事件到CPU interface,但是也不会assert指定的nIRQ或者nFIQ通知processor。

(b)ackowledging中断。processor会向CPU interface block应答中断,中断一旦被应答,Distributor就会把该中断的状态从pending状态修改成active。如果没有后续pending的中断,那么CPU interface就会deassert nIRQCPU和nFIQCPU信号线。如果在这个过程中又产生了新的中断,那么Distributor就会把该中断的状态从pending状态修改成pending and active。这时候,CPU interface仍然会保持nIRQ或者nFIQ信号的asserted状态,也就是向processor signal下一个中断。

(c)中断处理完毕的通知。当interrupt handler处理完了一个中断的时候,会向写CPU interface的寄存器从而通知GIC CPU已经处理完该中断。做这个动作一方面是通知Distributor将中断状态修改为deactive,另外一方面,可以允许其他的pending的interrupt向CPU interface提交。

(d)设定priority mask。通过priority mask,可以mask掉一些优先级比较低的中断,这些中断不会通知到CPU。

(e)设定preemption的策略

(f)在多个中断事件同时到来的时候,选择一个优先级最高的通知processor

不同系统设置中断的亲和性是不同的,比如网络服务器中,总是希望尽快的响应网络请求,功耗不是很在乎,因此可以将不同中断分配到不同 CPU 上,以尽快响应中断,而嵌入式系统中,对功耗很在乎,通常要把中断绑定到 CPU0 上,这样其他 CPU 空闲时,可以进入 IDLE 状态,以节省功耗,ARM CPU 正常运行时,只使用 Arch Timer,不会使用 Global Timer ,即系统的 Timer 不会运行。但 CPU 电源被关闭后,此 CPU 的 Arch Timer 也会被关闭,因此, CPU 进入关电的 IDLE 状态时,要先将其 Timer 切换至 Global Timer ,这样在下一个 Timer 到来时,如果是非启动 CPU ,会有响应 Global Timer 中的 CPU 发送的 SGI 中断,有中断后,会有其他模块将其从断电状态中带出,如果是 CPU0 ,同样收到中断后,其他模块将其带出断电状态,不过此时的中断不再是 SGI ,而是 Global Timer 的中断。

通常 Distribute属于系统电源域,而interface属于CPU电源域,所以每次CPU断电重新上电(系统不断电)后,Interface都要恢复原值或重

新初始化。另外如果要让CPU一直在WFI状态,则需要设置Interface的GICC_CTLR寄存器为 0 ,否则CPU会从 WFI 状态中退出。

寄存器在安全和非安全模式读到值是不同的,这并不是说明安全和非安全状态下,同一个地址的寄存器存在备份(就像 IRQ和FIQ模式下,有些寄存器存在备份),而是因为寄存器的不同bit的属性不同,有些属于安全寄存器的bit在非安全状态下读到的为0,所以CPU复位后,在未切换到非安全系统前,要先设置GIC,否则安全系统不能响应中断,即安全系统不能使用,CPU就会停在哪里静静的休息,此时看到的现象是: CPU 在 WFI 状态,系统的时钟也是停止的, 因为 CPU 的 Arch-Timer 得不到响应, tick 计数不会改变。

3. 中断的处理流程

中断的处理流程是:distributor会把收集来的中断,先缓存一下,依次把优先级最高的那个interrupt请求送往CPU interface,CPU读取一个中断,其实就是读取interface的一个寄存器,只不过这个寄存器存放的是中断号,这时候中断的状态由pending转为active,cpu处理完了以后,将中断号写入GIC的interface,告诉GIC处理完了,可以将这个中断清理了。

查看系统上的中断是怎么分配在 CPU情况和响应次数的命令:

# cat /proc/interrupts

4. 寄存器

参考:

DDI0471B_gic400_r0p1_trm.pdf

IHI 0048B, ARM Generic Interrupt Controller Architecture Specification, Ver 2.0.pdf

标签: 连接器gic

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台