1、two secure state
gicv3中,引入了支持2种安全状态(secure state),也就是对于中断,根据secure状态,分为安全中断和非安全中断。当然也可以只支持一种安全状态。。
这里的2种安全状态和1种安全状态,主要是影响中断分组,所使用IRQ和FIQ管脚的映射,以及gic中的寄存器访问。
一、中断线的映射
当gic架构,使用gicv3后,中断的传递,和gicv2有所区别。
gicv3中,将cpu interface从gic中抽离,放入到了cpu中,cpu interface通过gic stream接口,与gic进行通信。
当gic要发送中断,gic通过gic stream接口,给cpu interface发送中断命令,cpu interface收到中断命令后,根据中断线映射配置,决定是通过IRQ还是FIQ管脚,向cpu发送中断。
而中断线映射配置,要根据中断的分组以及当前cpu所处的EL以及seucre状态,来决定。
二、2种安全状态中断线映射
当gic支持2种安全状态,EL3是AArch64和AArch32,映射情况不同
1、EL3是AArch64
当EL3是AArch64时,映射如下:
- 对于group0中断,中断线均映射到FIQ
- 对于group1安全中断,secure EL1或EL0,中断线映射到IRQ,其他EL映射到FIQ
- 对于group1非安全中断,secure EL1或EL0以及EL3,中断线映射到FIQ,其他EL映射到IRQ(脑子里一定要有)
(其实为什么要给安全使用FIQ,这是因为平时的操作还是都是运行在REE的环境之中的,希望安全的操作都是很快的,不只是中断的处理,包括cpu的时候,在进入到安全世界的环境中,运行操作的性能cpu都会全力以赴,尽快完成任务。至于这个具体在哪里看到的,我有点搞忘了。找到了的时候我就来这里补上!)
2、EL3是AArch32
当EL3是AArch32时,映射如下:
- 对于group0中断,中断线均映射到FIQ
- 对于group1安全中断,secure EL0和EL3,中断线映射到IRQ,其余EL映射到FIQ
- 对于group1非安全中断,secure EL0和EL3,中断线映射到FIQ,其余EL映射到IRQ
(其实造成这样的差异是因为32其实本身的安全等级和64的划分还是有点区别,专栏里有篇文章可以看一下,搜索32)
三、1种安全状态中断线映射
- group0中断线,直接映射到FIQ
- group1中断线,直接映射到IRQ
四、GICD寄存器
在GICD中的GICR_CTLR寄存器的DS bit,表示是否支持2种安全模式。
该bit描述如下,如果0,表示支持2种安全状态,为1,表示不支持。
1、支持2种安全模式下GICD_CTLR
在支持2种安全模式下,GICD中寄存器会进行备份成2份,一份提供给secure访问,。一份提供给non-secure访问。
比如对于GICD_CTLR寄存器,secure访问,寄存器描述如下:
而如果是non-secure访问,其寄存器描述如下:
2、支持1种安全模式下GICD_CTLR
在1种安全模式下,寄存器描述如下,此时不论是non-secure访问,还是secure访问,都访问的同一个寄存器。
(其实这里说安全状态不太合适,应该成为执行状态。安全状态应该是: secure security/non-secure security/ Root/Realm四个)
2、中断bypass
在GICv2架构中,GIC与core之间,是直接通过irq,fiq管脚,传递中断信号。
但是在GICv3架构中,GIC通过gic stream接口向cpu interface传递中断信息,然后由cpu interface向core传递中断信息,而且,cpu interface被设计在了core当中。
GICv3支持中断bypass功能,以下是我画的一个框图:
对于core而言,中断有2种(不考虑虚拟中断),分别是IRQ和FIQ。 在ICC_SRE_ELx寄存器,有DFB和DIB bit,分别控制FIQ,IRQ是否bypass。
对于DIB bit的描述:
对于DFB bit的描述:
这2个bit,复位值都是0,表示系统在复位后,中断bypass功能是开启的,此时外部的中断信号,是直接输入到core中的。 当软件,关闭中断bypass后,此时,才是由cpu interface给core发送中断,而忽略掉外部发送的中断。 在gicv3架构描述中,提到了中断bypass功能,会受到下面几个配置的影响: 一个是,是否运行系统寄存器访问icc寄存器,也就是ICC_CTLR.SRE bit是否为高,如果允许系统寄存器访问icc寄存器,那么中断bypass功能是禁止的。 一个是,ICC_SRE寄存器,由当前设计中支持的最高EL级的ICC_SRE寄存器的DFB和DIB bit来控制。
最后一个,就是中断分组使能,也就是ICC_IGPREN0_EL1和ICC_IGRPEN1_EL1的enable bit。 如果需要开启中断bypass功能,那么需要将中断分组使能给关掉。
以下是FIQ中断bypass的伪代码:
IRQ的处理,和FIQ是一致的。
(这个功能从gicv2上来理解是绕过gic控制的。当时的cpu interface还在gic中,现在集成到了core上。增加了系统寄存器,gic通过专门的stream axi线与core interface交互,不占用axi总线。在gic这个bypass还是直接发到core?一般来说不会开,但是既然留着,肯定是有用的!!!)
(bypass就是不走interface,猜测就是圈出来的地方,通过配置这个门的其它位,让这个生效。)(有错请大佬指出)