IRQ Number 软件虚拟的 标识外设中断
HW interrupt ID 硬件上的标识外设中断
1、irq domain干什么用的,为什么要使用它?
irq domain就是指中断领域,任何超出这个范围的定义就没有意义了。
IRQ domain来描述一个中断控制器(IRQ Controller)所管理的中断源。换句话说,每个中断控制器都有自己的domain。我们可以将IRQ Domain看作是IRQ Controller的软件抽象。
这里所说的“中断控制器”,不仅指硬件上实际存在的中断控制器,也可以是一个“虚拟”的中断控制器。例如,假设我们有一块CPU,它有多个GPIO Pin可以作为外部中断源使用(事实上大多数嵌入式CPU都有这样的GPIO)。
我们还假定所有的GPIO中断都复用到该CPU的同一个中断向量。在这样的情况下,这多个GPIO中断就可以抽象成一个虚拟的中断控制器,它连接到CPU的某个中断向量上。
这样做的好处在于,可以将“对中断控制器的中断响应”和“对产生中断的外部设备的中断响应”分离开来。我们还是看一个例子,假定我们有若干个GPIO,分别接了不同外设(如按键、外部以太网控制器等),
当这些外设产生中断的时候,CPU内部的GPIO控制器会置位相应的中断标志位,并向CPU提交中断请求。这样,对每一个外设中断,我们实际上要进行两级中断服务:第一级中断服务判断是哪个GPIO产生了中断,
并需要清除GPIO控制器内部某个寄存器中的某个标志位;第二级中断服务才是服务产生中断的那个外设的。显然,第一级中断服务代码对每个产生GPIO中断的外设是类似的。有了IRQ Domain的帮助,
第一级中断服务代码就可以统一,设备驱动程序只需要关心第二级中断服务就可以了。
2、如何注册一个irq domain,注册irq domain的动作到底是做什么了操作?
三种方法:
1、irq_domain_add_linear (线性映射)
2、irq_domain_add_tree (Radix Tree map)
3、irq_domain_add_nomap (no map)
根据自己的映射类型,初始化struct irq_domain中的各个成员,
调用__irq_domain_add将该irq domain挂入irq_domain_list的全局列表
3、为什么IRQ Number需要HW interrupt ID映射过来?
1、驱动工程师而言,我们和CPU视角是一样的,我们只希望得到一个IRQ number,而不关系具体是那个interrupt controller上的那个HW interrupt ID。
这样一个好处是在中断相关的硬件发生变化的时候,驱动软件不需要修改
2、interrupt controller级联的情况下,仅仅使用HW interrupt ID已经不能唯一标识一个外设中断,还需要知道HW interrupt ID所属的interrupt controller
因为HW interrupt ID在不同的interrupt controller上是会重复编码。
4、如何知道系统irq domain的当前采用哪种映射关系?
映射有三种:
1、线性映射
2、Radix Tree map (powerPC和MIPS硬件平台用到)
3、no map 即:hw interrupt id就是 irq number,寄存器配置HW interrupt ID而不是物理连接特性决定
因此arm架构使用 线性映射
5、如何获取HW interrupt ID?
interrupt controller会对连接其上的interrupt source(根据其在Interrupt controller中物理特性)进行编号(也就是HW interrupt ID了
int (*xlate)(struct irq_domain *d, struct device_node *node,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type);
软件上通过调用 irq domain的irq_domain_ops结构的xlate回调函数成员 将指定的设备(node参数)上若干个(intsize参数)中断属性(intspec参数)翻译成HW interrupt ID(out_hwirq参数)和trigger类型(out_type)。
6、HW interrput ID如何转换成IRQ number?
由IRQ domain负责,通过irq_create_mapping
7、什么是interrupt flow control?
中断流控制
软件上设定一些标志位和硬件上 mask或者unmask interrupt controller等,具体表现为调用中断描述符的irq chip driver进行mask,ack等callback函数。
8、每一个IRQ都有中断描述符吗?
系统中每一个连接外设的中断线(irq request line)用一个中断描述符来描述,每一个外设的interrupt request line分配一个中断号(irq number),
系统中有多少个中断线(或者叫做中断源)就有多少个中断描述符struct irq_desc
NR_IRQS定义了该硬件平台IRQ的最大数目
linux内核中有一个数据结构保存了所有中断描述符的信息,具体表现为以下两种:
(1)即一个静态定义的数组,irq number作为index, 有空洞,存在空间浪费
(2)打开CONFIG_SPARSE_IRQ 使用Radix tree保存,这时候,每一个中断描述符都是动态分配,然后插入到radix tree中
描述一个具体的中断 struct irq_desc,简称中断描述符
描述一个具体中断的底层相关数据结构 struct irq_data
描述一个具体中端底层若干和具体interrupt controller相关的callback函数 strcut irq_chip
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPR1UMFpWW6J1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2ADO5ITMzIjM1EzNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
9、GIC支持多少个中断号?
linux-4.9/drivers/irqchip/irq-gic.c
/*
* Find out how many interrupts are supported.
* The GIC only supports up to 1020 interrupt sources.
*/
gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f;
gic_irqs = (gic_irqs + 1) * 32;
if (gic_irqs > 1020)
gic_irqs = 1020;