当然,由于GIC-400只支持8个CPU,因此CPU mask值只需要8bit,但是寄存器GIC_DIST_TARGETn返回32个bit的值,怎么对应?很简单,cpu mask重复四次就OK了。系统的概念了解了这些知识,回头看代码就很简单了。
(c)step (b)中获取了8个bit的cpu mask值,通过简单的copy,扩充为32个bit,每8个bit都是cpu mask的值,这么做是为了下一步设定所有IRQ(对于GIC而言就是SPI类型的中断)的CPU mask。
(d)设定每个SPI类型的中断都是只送达该CPU。
(e)配置GIC distributor的其他寄存器,代码如下:
void __init gic_dist_config(void __iomem *base, int gic_irqs, void (*sync_access)(void))
{
unsigned int i;
/* Set all global interrupts to be level triggered, active low. */
for (i = 32; i < gic_irqs; i += 16)
writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4);
/* Set priority on all global interrupts. */
for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i);
/* Disable all interrupts. Leave the PPI and SGIs alone as they are enabled by redistributor registers. */
for (i = 32; i < gic_irqs; i += 32)
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8);
if (sync_access)
sync_access();
}
程序的注释已经非常清楚了,这里就不细述了。需要注意的是:这里设定的都是缺省值,实际上,在各种driver的初始化过程中,还是有可能改动这些设置的(例如触发方式)。
(2)CPU interface初始化,代码如下:
static void gic_cpu_init(struct gic_chip_data *gic)
{
void __iomem *dist_base = gic_data_dist_base(gic);-------Distributor的基地址空间
void __iomem *base = gic_data_cpu_base(gic);-------CPU interface的基地址空间
unsigned int cpu_mask, cpu = smp_processor_id();------获取CPU的逻辑ID
int i;
cpu_mask = gic_get_cpumask(gic);-------------(a)
gic_cpu_map[cpu] = cpu_mask;
for (i = 0; i < NR_GIC_CPU_IF; i++)
if (i != cpu)
gic_cpu_map[i] &= ~cpu_mask; ------------(b)
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shumachanpin/article-76887-13.html
是人的基本需要
你也看球
口气小点不然要翻船谪