gic_cpu_config(dist_base, NULL); --------------(c)
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);-------(d)
writel_relaxed(1, base + GIC_CPU_CTRL);-----------(e)
}
(a)系统软件实际上是使用CPU 逻辑ID这个概念的,通过smp_processor_id可以获得本CPU的逻辑ID。gic_cpu_map这个全部lookup table就是用CPU 逻辑ID作为所以,去寻找其cpu mask,后续通过cpu mask值来控制中断是否送达该CPU。在gic_init_bases函数中,我们将该lookup table中的值都初始化为0xff,也就是说不进行mask,送达所有的CPU。这里,我们会进行重新修正。
(b)清除lookup table中其他entry中本cpu mask的那个bit。
(c)设定SGI和PPI的初始值。具体代码如下:
void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
{
int i;
/* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled. */
writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR);
writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET);
/* Set priority on PPI and SGI interrupts */
for (i = 0; i < 32; i += 4)
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
if (sync_access)
sync_access();
}
程序的注释已经非常清楚了,这里就不细述了。
(d)通过Distributor中的寄存器可以控制送达CPU interface,中断来到了GIC的CPU interface是否可以真正送达CPU呢?也不一定,还有一道关卡,也就是CPU interface中的Interrupt Priority Mask Register。这个寄存器设定了一个中断优先级的值,只有中断优先级高过该值的中断请求才会被送到CPU上去。我们在前面初始化的时候,给每个interrupt ID设定的缺省优先级是0xa0,这里设定的priority filter的优先级值是0xf0。数值越小,优先级越过。因此,这样的设定就是让所有的interrupt source都可以送达CPU,在CPU interface这里不做控制了。
(e)设定CPU interface的control register。enable了group 0的中断,disable了group 1的中断,group 0的interrupt source触发IRQ中断(而不是FIQ中断)。
(3)GIC电源管理初始化,代码如下:
static void __init gic_pm_init(struct gic_chip_data *gic)
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shumachanpin/article-76887-14.html
美军刚出发就有中军舰尾随
这有利于我们国土岛屿的收回和国家的发展建设