1、GIC的电源管理功能

从gic3开始,cpu interface放到了PE中,因此cpu interface和PE是同一个power domain。

而属于gic的其他组件,如redistributor,distributor,是另外一个power domain。

因此就有如下一种情况,PE和cpu interface的电源给断掉了,而gic的电源并没有断掉。此时gic给cpu interface发送数据,cpu interface是不会响应的。

在这种情况下,gic提供了power管理功能。

一、GICR_WAKER寄存器

gic中,提供了如下的 GICR_WAKER 寄存器,来支持power功能。

ARM架构 WinPE盘 arm版pe_架构


其寄存器描述如下:

ARM架构 WinPE盘 arm版pe_gic_02

二、断电cpu interface和PE

在cpu interface和PE要断电之前,软件要保证,通知redistributor,cpu interface和PE要进入low-power状态。

软件,要往GICR_WAKER寄存器的ProcessorSleep字段,写入1,表示PE要进入到low-power状态。cpu interface之后将自己置为low-power状态之后,就将ChildrenAseep字段,设置为1。

当GICR_WAKER.ChildrenAsleep为1之后,redistributor,不会在将中断,发送给cpu interfacedistributor在中断仲裁时,也不会考虑该PE。

三、唤醒cpu interface和PE

当gic要唤醒cpu interface和PE时,也是操作这个 GICR_WAKER寄存器。

将processorsleep,写入0,然后去唤醒该cpu,最后读取childrenasleep,判断PE是否唤醒成功,

ARM架构 WinPE盘 arm版pe_Arm_03

2、gicv3的中断分组

GICv3架构中,对中断进行了分组。分成了以下三个组:

  • group0,用于EL3处理的中断
  • secure group1:用于secure EL1处理的中断
  • non-secure group1:用于non-secure的EL2和non-secure的EL1。

对于redistributor的set命令,带有Mod和Grp参数。

ARM架构 WinPE盘 arm版pe_架构_04


Mod与Grp共同表示,中断所属的组。其组合如下图所示:

ARM架构 WinPE盘 arm版pe_Arm_05


对于每一组中断,有一个系统寄存器,来控制该组中断是否有效。

  • ICC_IGRPEN0_EL1:针对group0的中断
  • ICC_IGRPEN1_EL1:针对group1的中断,该寄存器分为non-secure和secure访问,不同的secure下,是访问当前(状态)secure下的寄存器

而每个中断的分组,由以下两个寄存器来决定:

  • GICR_IGROUPR: interrupt group registers
  • GICR_IGRPMODR:interrupt group modifier registers

每个中断,占寄存器中的1个bit,使用中断号进行索引。

当gic给cpu interface通过set命令发送中断,cpu能够响应该组中断,会回发activate命令,认可该中断。
如果cpu不能响应该组中断,会回发release响应。如下图所示:

ARM架构 WinPE盘 arm版pe_架构_06

gic给cpu interface通过set命令发送中断,中断号为93,优先级为0x40,Mod和Grp均为1,表示non-secure的group1。
cpu interface不能响应该中断,回发release响应。

3、GICv3软中断

软中断(software generated interrupts),用来多个核之间的通信(inter-processor communication)。软件通过写SGI寄存器来产生。(我觉得我的bug就是出现在这里的)

  • 软件写ICC_SGI1R_EL1产生对应当前secure状态的group1软中断
  • 软件写ICC_ASGI1R_EL1产生secure状态的group1软中断
  • 软件写ICC_SGI0R_EL1产生secure状态的group0软中断 这三个寄存器的位域是一样的,如下图:
  • ARM架构 WinPE盘 arm版pe_ARM架构 WinPE盘_07

  • Aff3.Aff2.Aff1:表示软中断目的CPU的属性层次。
  • TargetList:表示要发给哪些CPU。
  • INTID:表示软中断号
  • IRM:软中断发送,是按照属性层次发送,还是发起其他所有的cpu
  • RS:range selector,和TargetList结合,表示发送哪些CPU

例如,IRM为0,INTID为1,Aff3.Aff2.Aff1为0.0.0,TargetList为0xf,RS为0,就表示,软中断发送给属性层次为0.0.0.[0-3]的cpu。 GICv3对软中断的中断号,进行了规定,只能是0-15。(0xf和0结合了个寂寞)

ARM架构 WinPE盘 arm版pe_寄存器_08

一、cpu interface SGI命令

软件写SGI寄存器后,cpu interface会通过gic stream接口,发送SGI命令。

ARM架构 WinPE盘 arm版pe_ARM架构 WinPE盘_09

  • SGT:表示写的哪一个SGI寄存器 0b00: ICC_SGI0R_EL1 0b01: ICC_SGI1R_EL1 0b10: ICC_ASGI1R_EL1 0b11: Reserved
  • NS: 当前的secure状态,0表示secure,1表示non-secure
  • IRM: SGI寄存器的IRM bit
  • A3V: aff3是否有效,如果有效,需要发送A3数据。
  • RSV: range selector域是否有效
  • SGInum: 软中断中断号
  • A3,A2,A1: 对应Aff3.Aff2.Aff1
  • TargetList: 对应SGI寄存器中的TargetList
  • Range Selecto: 对应SGI寄存器中的RS域

比如,往ICC_SGI0R_EL1寄存器写0xffffef_ffffffff,那么cpu interface会发送如下波形:

ARM架构 WinPE盘 arm版pe_gic_10

二、A3V

GICv3中,使用属性层次对CPU进行编号,属性层次最多有4层,最高层为Aff3,这一层可以通过cpu interface系统寄存器来控制,是否使能。

ARM架构 WinPE盘 arm版pe_架构_11


ICC_CTLR_EL3和ICC_CTLR_EL1的A3V表示cpu interface是否支持Aff3,而GICD_TYPER.A3V表示gic ip是否支持Aff3。

三、关于range selector的理解。

gicv3的spec对range selector的解释如下:

ARM架构 WinPE盘 arm版pe_架构_12


gic3中,使用属性层次,来对CPU进行标识,这样可以精确的将中断发送指定的cpu。属性层次最高有4层,为aff3.aff2.aff1.aff0。每一个属性层次,用8bit来表示。如下图所示:

ARM架构 WinPE盘 arm版pe_ARM架构 WinPE盘_13


SGI中断,是可以同时发送给多个cpu的中断,通过TargetList来表示要发送给哪一些CPU。

而TargetList只有16个bit,也就是只能发送给16个cpu,但是Aff0最多可以表示256个cpu,那怎么发送给其他的cpu的了?

这个时候range selector就派上用场了,RS域共4个bit,可以表示16个范围,16×16=256,刚好表示256个cpu。所以spec里面,说TargetList[n]表示的aff0的值为RS*16 + n。 比如要给65-68号CPU发送软中断,首先判断这些cpu属于的range,为5,那么给这些CPU发送软中断,RS为5,TargetList为0x1E。

四、GIC的SGI认可响应

当GIC收到cpu interface发的SGI命令,需要回SGI认可响应。

ARM架构 WinPE盘 arm版pe_gic_14