linux 下ARC的中断机制
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
linux 下ARC的中断机制
一、Idu 中断控制器初始化
Idu 是arc 处理器内部中断控制模块 类似于arm 内部的gic 中断控制模块
首先Idu中断控制器在初始化时, 会解析DTS信息中定义了几个idu控制器每个Idu控制器注册一个struct irq_domain数据结构。
DTSarch/arc/boot/dts和中断相关的信息如下
struct irq_domain用于描述一个中断控制器 这个结构体很重要 dts 的信息会保存在这里面 另外这里面还会保存hwirq和virq 的对应关系。
初始化的流程如下
linux 正常流程会先进入Start_kernel 函数 然后进入Init_IRQ进行初始化后面会进入Irqchip_init函数
__irqchip_of_table 就是内核irq chip table的首地址这个table也就保存了kernel支持的所有的中断控制器的ID信息用于和device node的匹
配这些信息保存在.init.ramfs
section 中 of_irq_init 函数实际上就是根据DTS 的内容去进行搜索匹配一旦匹配到就调用该interrupt
controller的初始化函数并把该中断控制器的device node以及parent中断控制器的device node作为参数传递给irq chip driver。
__irqchip_of_table 的内容是通过IRQCHIP_DECLARE的宏来实现的如下图所示这个宏其实就是初始化了一个struct of_device_id的静态
常量并放置在__irqchip_of_table_end中。
idu_of_init 函数的功能如下
(a). 读取IDU的最大支持的中断数目
(b). 分配一个 irq_domain 的结构一个 irq_domain 代表了一个 IDU控制器
©. 在irq_default_domain中将hwirq和virq进行映射irq_create_mapping
中domain 参数是NULL 所以使用default domain, 所以virq 是等于 hwirq
的不做转换。然后设置中断响应函数入口为idu_cascade_isr
二、中断处理流程
处理器正常中断处理程序(handler)一般包含4个步骤
(1) 保存现场,保存各个寄存器的值
(2) 运行处理中断的需要的命令
(3) 恢复现场,恢复各个寄存器的值
(4) 返回到进行中断处理前的地方继续运行
以 arc 处理器为例 外部产生中断信号后的流程如下
首先 进入异常向量表vectors, 跳转到相应的异常中断arch/arc/kernel/entry-arcv2.S正常会跳转到handle_interrupt
函数 该函数会进行 保存现场处理中断和恢复现场 的工作具体如下
在arc中 vector table 如下图所示前面16个是异常向量表 后面开始是中断向量表 都会跳转到handle_interrupt 函数
主要工作分为三个部分
1、保护现场
将arc 的寄存器进行压栈处理需要注意的是arc 处理器会对大部分寄存器进行自动压栈但是仍然有少部分寄存器需要我们
手动压栈r12, r25, r30, sp, fp, gpACCL pair
2、中断处理
保存完现场后就会执行中断跳转函数 arch_do_IRQ
b.d arch_do_IRQ
arch_do_IRQ
函数会把硬件中断号传递给handle_domain_irq
函数 handle_domain_irq
函数内部调用__handle_domain_irq
函数
__handle_domain_irq
函数是中断处理的核心函数 内部需要关注的函数有四个, 分别如下
其中由于触发中断后不知道domain信息所以 irq_find_mapping中domain 的参数为NULL默认在irq_default_domain中根据hwirq找到
virq (Linux的irq), generic_handle_irq参数是irq号这个是linux 中断号irq_to_desc()根据irq号找到对应的struct irq_desc。
然后调用irq_desc->handle_irq处理对应的中断, 会先调用idu_cascade_isr的中断处理函数一级中断函数这是一个idu提供的标准中断
后面再调用具体中断函数。
三、初始化&处理具体中断
这里简单举一下pcie中断的例子