GIC的中断分类

这些中断都需要经过GIC的分发,才能发给指定的处理器(就算是处理器之间的SGI也一样)

PPI (Private Peripheral Interrupt)

GIC中只能通知特定的一个处理器的中断

SPI (Shared Peripheral Interrupt)

GIC中可以通知多个处理器的中断

SGI (Software Generated Interrupt)

用于处理器之间通信的中断,由处理器发给GIC,GIC再通知指定的处理器

interrupt子系统概述

interrupt子系统的核心是在于物理中断号和虚拟中断号之间的映射
其核心关系如下:
在这里插入图片描述
中断发生的时候是从叶子结点到GIC层层传递,然后由GIC传递给CPU,CPU再去跳转到中断向量表开始处理中断
中断处理的时候刚好和上面的过程是反过来的:

  • 首先GIC根据自己irq_domain中对32号物理中断在irq_desc数组映射好的虚拟中断号,在irq_desc数组中找到对应的handleA函数,该函数判断是谁的导致了该中断,然后再调用该子设备的虚拟中断号对应的irq_desc结构体中的handleB
  • handleB通过读取GPIO寄存器,得知是2号pin发生了中断,则根据自己irq_domain中的映射关系找到对应的虚拟终端号的irq_desc结构体,即102号,并调用其handle函数
  • 如此就找到了中断的叶子结点,即102号irq_desc结构体的action链表不为空,该action链表就是用户注册的中断函数,其挂在整个irq_domain嵌套体系的叶子结点上
  • 调用该叶子结点的handle函数,会逐个调用自己action链表中的中断处理函数(往往是上半部),来判断是否需要执行某些代码

通过上面的描述,提取几个关键信息:
1.每个interrupt-controller内部都会维护一个irq_domain,用于映射自己局部的物理中断号到全局的虚拟中断号之间的关系
2.用户申请和绑定中断都是绑定在interrupt-controller嵌套体系中的某个叶子结点下面(比如某个GPIO下面的pin口),即用户编写驱动只会添加action函数到该叶子结点中,其他的由BSP工程师编写

interrupt设备树规则

在这里插入图片描述
驱动工程师只需要在自己的设备节点指明interrupt-parentinterrupts这两个属性,即可使用对应interrupt-controller的中断
interrupts属性的变量个数,取决于父节点的interrupt-cells(若父节点未指定则继承自己父节点的)
其值的含义为用interrupt-parent的哪个中断,然后什么方式触发

接着在代码中,只需要在对应驱动中,使用通用的接口获取该中断对应的虚拟中断号

然后往该虚拟中断号对应的irq_desc结构体上面添加action函数即可

对于platform_device
使用platform_get_resource(*dev,IORESOURCE_IRQ,irq_num)即可获得虚拟中断号irq_num

对于I2C设备,SPI设备
使用of_irq_get(dev->of_node,0)获取虚拟中断号

对于GPIO
可以使用gpiod_to_irq()获取虚拟中断号

然后使用request_irq或者devm_request_irq,还有一些线程化处理函数的申请函数等等在虚拟中断号对应的irq_desc的action链表中添加对应中断处理函数即可

设备树解析过程

在这里插入图片描述
在现代linux内核中,是开启按需动态创建的
Interupt层级结构中除了特殊的节点,剩下的节点的虚拟中断号映射关系以及irq_desc都是在用到的时候才按照自己的规则去分配的
这就存在了分配时候的向上递归调用的关系
比如GPIO的某个pin申请中断号,GPIO自己也还没被映射和分配irq_desc,就得去找GIC来给GPIO分配,再给GPIO的pin分配,最后返回

虚拟中断号获取流程

以of_irq_get函数为例

在这里插入图片描述
其用于获取对应设备树节点中的第index个物理中断对应的虚拟中断号

406行,of_irq_parse_one()函数,如果能找到已经创建了的映射关系和irq_desc,则直接返回虚拟中断号

410行,irq_find_host最终调用irq_find_matching_fwspec函数,获取到当前的物理中断号应该对应的irq_domain

414行,在对应的irq_domain,创建物理中断号到虚拟中断号之间的映射(若父节点也没创建映射,则递归调用父节点的irq_create_of_mapping创建映射),并且在irq_descs数组中创建对应的irq_desc结构体

参考资料:韦东山驱动大全

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐