由于不同的SOC厂商在集成GIC的时候可能会修改,也就是说,也有可能mask的代码要微调,这是通过gic_arch_extn这个全局变量实现的。在gic-irq.c中这个变量的全部成员都设定为NULL,各个厂商在初始中断控制器的时候可以设定其特定的操作函数。
(2)gic_unmask_irq函数
这个函数用来unmask一个interrupt source。代码如下:
static void gic_unmask_irq(struct irq_data *d)
{
u32 mask = 1 << (gic_irq(d) % 32);
raw_spin_lock(&irq_controller_lock);
if (gic_arch_extn.irq_unmask)
gic_arch_extn.irq_unmask(d);
writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
raw_spin_unlock(&irq_controller_lock);
}
GIC有若干个叫做Interrupt Set-Enable Registers的寄存器。这些寄存器的每个bit可以控制一个interrupt source。当写入1的时候,表示Distributor会forward该interrupt到CPU interface,也就是意味这unmask了该中断。特别需要注意的是:写入0无效,而不是mask的操作。
(3)gic_eoi_irq函数
当processor处理中断的时候就会调用这个函数用来结束中断处理。代码如下:
static void gic_eoi_irq(struct irq_data *d)
{
if (gic_arch_extn.irq_eoi) {
raw_spin_lock(&irq_controller_lock);
gic_arch_extn.irq_eoi(d);
raw_spin_unlock(&irq_controller_lock);
}
writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
}
对于GIC而言,其中断状态有四种:
processor ack了一个中断后,该中断会被设定为active。当处理完成后,仍然要通知GIC,中断已经处理完毕了。这时候,如果没有pending的中断,GIC就会将该interrupt设定为inactive状态。操作GIC中的End of Interrupt Register可以完成end of interrupt事件通知。
(4)gic_set_type函数
这个函数用来设定一个interrupt source的type,例如是level sensitive还是edge triggered。代码如下:
static int gic_set_type(struct irq_data *d, unsigned int type)
{
void __iomem *base = gic_dist_base(d);
unsigned int gicirq = gic_irq(d);
u32 enablemask = 1 << (gicirq % 32);
u32 enableoff = (gicirq / 32) * 4;
u32 confmask = 0x2 << ((gicirq % 16) * 2);
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shumachanpin/article-76887-17.html
不过这样的军事表演秀是不会起到任何作用的
任何工业品都有设计使用寿命
该废了直接开除