什么决定了中断是 IO-APIC-edge 还是 IO-APIC-level?

And*_*ner 5 linux pci hardware interrupt x86

查看/proc/interruptsx86 Linux 上的内容,我看到一些中断IO-APIC-edgeIO-APIC-level.

我想知道是什么决定了中断类型,是中断产生设备、中断控制器(APIC)、Linux内核还是BIOS?

(我想知道的原因是因为我将 PCI 卡从双处理器 Pentium III 系统IO-APIC-level移到了双处理器 Xeon 系统,在那里它被识别为IO-APIC-edge

And*_*ner 2

例如,82093AA IO-APIC具有 I/O 重定向表寄存器 (IOREDTBL),该寄存器具有指定触发模式(可以是电平或边沿敏感)的可写位。这些寄存器似乎反映struct IO_APIC_route_entry在内核源代码中。

深入研究 2.6.18 内核源代码,我们会发现一个函数setup_IO_APIC_irqs(..),该函数循环遍历找到的所有 IO-APIC 以及每个 IO-APIC 的所有 IRQ 线,并调用io_apic_write(..)写入 APIC 的寄存器。

触发器类型似乎是由函数MPBIOS_trigger(..)(由 调用irq_trigger(..))决定的,该函数又似乎参考了一个变量,mp_irqs而该变量又似乎被填充arch/x86_64/kernel/mpparse.c该文件似乎读取了符合Intel MultiProcessor 规范的MP 配置表。

从此规范中引用:

The BIOS constructs the MP configuration data structures, presenting the 
hardware in a known format to the standard device drivers or to the 
hardware abstraction layer of the operating system.
Run Code Online (Sandbox Code Playgroud)

所以我想说内核根据BIOS提供的信息配置中断触发类型。

旁注:维基百科关于中断的文章提到了这一点

The original PCI standard mandated shareable level-triggered interrupts.
Run Code Online (Sandbox Code Playgroud)

(这似乎来自于同一线路上多个设备同时发送的边沿触发中断会发生冲突)。对于 PCI 设备来说这IO-APIC-edge有点出乎意料。