void __iomem *base = gic_data_dist_base(gic); ----获取该GIC对应的Distributor基地址
writel_relaxed(0, base + GIC_DIST_CTRL); -----------(a)
cpumask = gic_get_cpumask(gic);---------------(b)
cpumask |= cpumask << 8;
cpumask |= cpumask << 16;------------------(c)
for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); --(d)
gic_dist_config(base, gic_irqs, NULL); ---------------(e)
writel_relaxed(1, base + GIC_DIST_CTRL);-------------(f)
}
(a)Distributor Control Register用来控制全局的中断forward情况。写入0表示Distributor不向CPU interface发送中断请求信号,也就disable了全部的中断请求(group 0和group 1),CPU interace再也收不到中断请求信号了。在初始化的最后,step(f)那里会进行enable的动作(这里只是enable了group 0的中断)。在初始化代码中,并没有设定interrupt source的group(寄存器是GIC_DIST_IGROUP),我相信缺省值就是设定为group 0的。
(b)我们先看看gic_get_cpumask的代码:
static u8 gic_get_cpumask(struct gic_chip_data *gic)
{
void __iomem *base = gic_data_dist_base(gic);
u32 mask, i;
for (i = mask = 0; i < 32; i += 4) {
mask = readl_relaxed(base + GIC_DIST_TARGET + i);
mask |= mask >> 16;
mask |= mask >> 8;
if (mask)
break;
}
return mask;
}
这里操作的寄存器是Interrupt Processor Targets Registers,该寄存器组中,每个GIC上的interrupt ID都有8个bit来控制送达的target CPU。我们来看看下面的图片:

GIC_DIST_TARGETn(Interrupt Processor Targets Registers)位于Distributor HW block中,能控制送达的CPU interface,并不是具体的CPU,如果具体的实现中CPU interface和CPU是严格按照上图中那样一一对应,那么GIC_DIST_TARGET送达了CPU Interface n,也就是送达了CPU n。当然现实未必如你所愿,那么怎样来获取这个CPU的mask呢?我们知道SGI和PPI不需要使用GIC_DIST_TARGET控制target CPU。SGI送达目标CPU有自己特有的寄存器来控制(Software Generated Interrupt Register),对于PPI,其是CPU私有的,因此不需要控制target CPU。GIC_DIST_TARGET0~GIC_DIST_TARGET7是控制0~31这32个interrupt ID(SGI和PPI)的target CPU的,但是实际上SGI和PPI是不需要控制target CPU的,因此,这些寄存器是read only的,读取这些寄存器返回的就是cpu mask值。假设CPU0接在CPU interface 4上,那么运行在CPU 0上的程序在读GIC_DIST_TARGET0~GIC_DIST_TARGET7的时候,返回的就是0b00010000。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shumachanpin/article-76887-12.html
重要的事情说三遍