在带有gicv3的soc架构中,其框图如下所示:
gicv3中的redistributor与core中的cpu interface通过AXI-Stream进行通信。
一、connection
当core上电之后,需要将core中cpu interface与gic中的redistributor进行connect,这样将来gic才可以将中断发送给core。
connection的流程如下所示:
描述如下:
◾ 执行在core的程序,将GICR_WAKER.ProcessorSleep位给置低,表示要connect redistributor
◾ redistributor在完成connect之后,将GICR_WAKER.ChildrenAsleep位给置低,表示connect完成
◾ 执行在core的程序,查询GICR_WAKER.ChildAsleep位是否为0,如果不是,表示redistributor还没有完成connect操作,就继续查询
◾ 如果查询到0,表示connect完成,接着做之后的初始化工作
其汇编代码如下:
波形如下:
首先写GICR_WAKER寄存器,将ProcessorSleep位给置低。
然后读取GICR_WAKER寄存器,判断ChildAsleep位是否为0。在波形中,有读取到0,表示connect成功。
connect成功后,gic600会给cpu interface发送downstream包,设置vINTID,pINTID,RSS,DS这几个域。
downstream包,对于identifier为0,length为1的解释如下:
二、disconnection
当core下电之后,需要将core中cpu interface与gic中的redistributor进行disconnect,这样将来gic才不会将中断发送给core。
disconnection的流程如下所示:
描述如下:
◾ 执行在core的程序,先将cpu interface的中断组使能给disable
◾ 执行在core的程序,将GICR_WAKER.ProcessorSleep位给置高,表示要disconnect redistributor
◾ redistributor给cpu interface发送 Quiesce包
◾ cpu interface清掉内部所有pending的中断
◾ 清除完毕后,cpu interface回发Quiesce Acknowledge包给redistibutor
◾ redistributor收到cpu interface回发的响应之后,将GICR_WAKER.ChildrenAsleep位给置高,表示disconnect完成
◾ 执行在core的程序,查询GICR_WAKER.ChildAsleep位是否为1,如果不是,表示redistributor还没有完成connect操作,就继续查询
◾ 如果查询到1,表示disconnect完成
其汇编代码如下:
其波形如下:
首先写GICR_WAKER寄存器,将ProcessorSleep位给置高,表示要disconect。
然后读取GICR_WAKER寄存器,判断ChildAsleep位是否为0。在波形中,有读取到0,表示disconnect不成功,需要再次读取判断。
gic600给cpu interface发送Quiesce包。
cpu interface收到该命令包,完成内部的操作后,回发quiesce acknowledge响应包。
至此,完成了disconnect操作,此时再读取GICR_WAKER寄存器,ChildAsleep位就为1了
三、中断唤醒core
当core下电之后,gic就不再会给core发送中断。如果此时有一个中断是唤醒core的,那么其处理流程应该如何了?
在gicv3,为每一个redistributor,提供了WakeRequest输出信号。当GICR_WAKER的ProcessorSleep为1,此时外部有唤醒该core的中断请求,那么WakeRequest信号会被置高。
WakeRequest信号,会被连接到SCP或者PMU,也就是下图中的红色连线。当SCP或者PMU接收到WakeReqeust请求,就会将对应core给上电,然后core再connect redistributor,gic在将中断发送给该core,core再响应中断。
系列其他篇
原文首发于骏的世界博客
作者:卢骏.
更多Arm技术相关的文章请关注Arm技术博客极术专栏,每日更新。