【原创】Linux中断子系统(一)-中断控制器及驱动分析 (4)

【原创】Linux中断子系统(一)-中断控制器及驱动分析

每个中断控制器都对应一个IRQ Domain;

中断控制器驱动通过irq_domain_add_*()接口来创建IRQ Domain;

IRQ Domain支持三种映射方式:linear map(线性映射),tree map(树映射),no map(不映射);

linear map:维护固定大小的表,索引是硬件中断号,如果硬件中断最大数量固定,并且数值不大,可以选择线性映射;

tree map:硬件中断号可能很大,可以选择树映射;

no map:硬件中断号直接就是Linux的中断号;

三种映射的方式如下图:

【原创】Linux中断子系统(一)-中断控制器及驱动分析

图中描述了三个中断控制器,对应到三种不同的映射方式;

各个控制器的硬件中断号可以一样,最终在Linux内核中映射的中断号是唯一的;

4. Arch-speicific代码分析

中断也是异常模式的一种,当外设触发中断时,处理器会切换到特定的异常模式进行处理,而这部分代码都是架构相关的;ARM64的代码位于arch/arm64/kernel/entry.S。

ARM64处理器有四个异常级别Exception Level:0~3,EL0级对应用户态程序,EL1级对应操作系统内核态,EL2级对应Hypervisor,EL3级对应Secure Monitor;

异常触发时,处理器进行切换,并且跳转到异常向量表开始执行,针对中断异常,最终会跳转到irq_handler中;

代码比较简单,如下:

/* * Interrupt handling. */ .macro irq_handler ldr_l x1, handle_arch_irq mov x0, sp irq_stack_entry blr x1 irq_stack_exit .endm

来张图:

【原创】Linux中断子系统(一)-中断控制器及驱动分析

中断触发,处理器去异常向量表找到对应的入口,比如EL0的中断跳转到el0_irq处,EL1则跳转到el1_irq处;

在GIC驱动中,会调用set_handle_irq接口来设置handle_arch_irq的函数指针,让它指向gic_handle_irq,因此中断触发的时候会跳转到gic_handle_irq处执行;

gic_handle_irq函数处理时,分为两种情况,一种是外设触发的中断,硬件中断号在16 ~ 1020之间,一种是软件触发的中断,用于处理器之间的交互,硬件中断号在16以内;

外设触发中断后,根据irq domain去查找对应的Linux IRQ中断号,进而得到中断描述符irq_desc,最终也就能调用到外设的中断处理函数了;

GIC和Arch相关的介绍就此打住,下一篇文章会接着介绍通用的中断处理框架,敬请期待。

参考

ARM Generic Interrupt Controller Architecture version 2.0

欢迎关注公众号,不定期更新Linux内核机制相关文章,谢谢。

【原创】Linux中断子系统(一)-中断控制器及驱动分析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppxjf.html