欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

openEuler 内核技术说明 | 内核中断子系统介绍 - 硬件封装层

最编程 2024-06-08 18:09:36
...

硬件封装层包括 cpu 和中断控制器两部分。区分开 cpu 和中断控制器相当重要,希望大家能更明确 cpu 和中断控制器的概念。软件在 cpu 方面主要需要按架构实现中断向量的处理,可以看 arch/「/kernel/entry」.S 的汇编实现。另外还需要为通用的开关中断方法提供架构实现:

通用中断开关方法 具体架构中断开关实现
local_irq_enable arch_local_irq_enable
local_irq_disable arch_local_irq_disable

这个 local 指的是 local_cpu,表示的是当前 cpu 是否响应中断:当前 cpu 关中断的情况下,中断控制器不管怎么玩都是徒劳的。事实上 cpu 对中断开关的实现还包含着很多条件,类似特权态、非屏蔽中断 NMI 之类的,可以在后文找下具体分析。软件对中断控制器的抽象是 struct irq_chip,体现的是中断控制器所具体的行为。这里列举部分重要成员讲解:

起因 struct irq_chip 成员 说明
怎么控制中断控制器是否屏蔽某个中断事件? irq_enable/ irq_disable
中断控制器如何配置中断事件的触发方式 irq_set_type 控制各个中断的电气触发条件,例如边沿触发或者是电平触发。
中断控制器如何得知中断事件被 cpu 响应? irq_ack 中断控制器在实现中会根据中断事件被 cpu 开始响应或完成响应来决定该中断事件类型是否会再度通知 cpu 处理。
中断控制器如何得知 cpu 完成处理中断事件? irq_eoi 中断控制器在实现中会根据中断事件被 cpu 开始响应或完成响应来决定该中断事件类型是否会再度通知 cpu 处理。
在 smp 系统中,中断事件应该通知哪个 cpu? irq_set_affinity affinity 表示了中断事件在中断控制器中配置的目标 cpu,根据具体实现可以是 1 个或多个。

此外,当多个中断事件同时发生,中断控制器会根据其优先级的实现来决定中断事件通知给 cpu 的顺序,某些实现是可配置的。另一方面,考虑到系统中可能存在多个中断控制器,使得单一中断控制器的中断号不足以区分中断事件,所以引入了软件中断号的概念。加上硬件中断号映射中断号的软件抽象 struct irq_domain,再看中断控制器软件抽象到中断源软件抽象的流程:

##中断流控处理层 这一层主要是隐藏了中断控制器在具体中断事件处理函数调用前后的一些处理逻辑,包括:

  • 何时对中断控制器发出 ack 回应?
  • mask_irq 和 unmask_irq 的处理;
  • 中断控制器是否需要 eoi 回应?
  • 何时打开 cpu 的本地 irq 中断?以便允许 irq 的嵌套;

类似于在用洗衣机洗衣服的时候,我们不关心衣服可能要经历过的洗涤多久、脱水多久、漂洗多久诸如此类的步骤细节,只需要按衣服类型选择流程;内核引入中断流程的抽象类型 irq_flow_handler_t 屏蔽了中断事件相关的 cpu、中断控制器和中断源的属性的不同带来的处理流程差异。这里举例部分内核实现:

  • handle_simple_irq:用于简易流控处理。
  • handle_level_irq:用于电平触发中断的流控处理。
  • handle_edge_irq:用于边沿触发中断的流控处理。
  • handle_fasteoi_irq:用于需要响应 eoi 的中断控制器
  • handle_percpu_irq:用于只在单一 cpu 响应的中断。