GIC中断 redistributor介绍

描述

跟distributor连接的部分就不说了。Cpu_active是指示cluster或core的状态,可以用于idle管理。ppi_id用于多核设计时,区分每个redistributor。PPIs就是PPI中断线

从上面可以看出来,所谓的“私有”是说这些中断信号是core专有的。对于PPI,ARMv8定义了三种规格,8,12和16。所以对于不同的core来说,可能PPI数量不一样。

cpu

上面是ARMv8-A的架构spec里,关于timer的图。我们可以看到,core的timer会发PPI,而中断控制器返回FIQ或者IRQ给core。细心的同学可能会问了,在redistributor上面没有FIQ和IRQ的信号啊?其实在第一篇文章里就说了,在现有的GICv3架构下,关于中断FIQ和IRQ,以及系统寄存器等放在cluster/core端,对外留出了一组接口,叫cpu interface(在GICv2中实现在中断控制器这一侧),也就是图1中最下面的接口。其实这是一组简化的AXI4-Stream。

cpu

stream协议接口由于是双向,所以是两组信号

cpu

redistributor到CPU的信号

cpu

CPU到redistributor的信号

既然是简化的总线协议,为了更便于CPU和redistributor通信,ARM又规定了具体的数据包格式。下图是CPU端发出的命令格式,具体的解释请查阅GICv3的文档,此处就不过多的贴图了。

cpu

interface命令至此,就剩下最复杂的ITS了,这一部分是为了实现基于消息的中断。前面介绍过,LPI是一种基于消息的中断。也就是中断信息不在通过中断线进行传递。ITS就是要将接收到的LPI中断进行解析。

cpu

GIC-600的ITS组件

既然是信息中断,就一定要有区分这些中断的方法,这样才能找到合适的中断处理对策。所以这里有两个概念。

• EventID,用来表示外设发送中断的事件类型

• DeviceID,用来表示哪一个外设发起LPI

而ITS需要将外设发送的DeviceID,eventID,通过一系列查表,得到LPI的中断号,再使用LPI中断号查表得到该中断的目标CPU。为此,ITS需要维护几张表,分别是device table,interrupt translation tableh和collection。

当外设写GITS_TRANSLATER寄存器,产生了LPI。这时ITS首先要拿着DeviceID,从device
table中选择索引为DeviceID的表项。从该表项中,得到interrupt translation table的位置;

然后再根据EventID,从interrupt translation table中选择索引为EventID的表项。

得到中断号,以及中断所属的collection号;

最后,使用collection号,从collection table中,选择索引为collection号的表项。得到redistributor的映射信息,最后根据collection表项的映射信息,将中断信息路由发送给对应的redistributor。

最后,提一句,GICv3中开始支持亲和性路由(affinity routing)。

CPU亲和性是一种调度属性(scheduler property),Linux调度器会根据affinity的设置让指定的进程运行在“绑定”的CPU上,而不会在别的CPU上运行。其中有一个好处是,可以提高cache的命中率。当一个进程在某个CPU上运行时,会在该CPU的缓存中维护许多状态。

下次该进程在相同的CPU上运行时,由于缓存中的数据而执行的更快。因此,多处理器的调度器应该考虑这种亲和性,尽可能的进程保持在同一个CPU上。同理,对于并发程序也是有好处的。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分