PCIe 中的不同中断有什么作用?我指的是 MSI、MSI-X 和 INTx

电器工程 中断 pcie
2022-01-24 22:04:00

我们有以下中断:MSI、MSI-X 和 INTx。这些不同类型的中断在 PCIe 中有什么作用?我只需要一个简短的描述。我只知道在 PCIe 中,当它们被断言以及当它们被取消断言时,中断作为数据包生成,并且 MSI 和 MSI-X 存在用于传统支持。我可能是错的。是否有可能在这个论坛上得到这个非常具体的问题的答案?

3个回答

您询问过的三个流行语,INTx、MSI 和 MSI-x,是 x86 PC 架构上中断/IRQ 交付的漫长而曲折历史的一部分。其他计算机架构可能会分享这段历史的一部分,这取决于它们与 PC 世界及其总线有多少共同点。

我将尝试跳过一些丰富多彩的支线情节,实际上从中间开始解释。

如果我跳过 ISA,让我从并行 PCI 开始。沿着 AD0:31 信号(或具有 64 位宽口味的 AD0:64),中断有四个专用信号线(线),标记为 INTA..INTD。在沿总线的连续 PCI 插槽中,四根 INTx 物理线“旋转一圈”,编织式,从插槽到插槽。由于插槽中的设备通常会占用它们自己的每个插槽 INTA,而很少占用 INTB 或更高,因此逐个插槽的轮换将有助于将触发设备分布在四根中断线之间。每个插槽的四个 INTx 信号可以在内部(由外围板)用于多达八个“功能”,这些功能在 PCI 配置空间中单独可见(大多数操作系统将它们显示为单独的 PCI“设备图标”)。即,如果每个插槽有八个功能,它们将不得不共享一些 INTx 线。因此,每个 PCI bus:dev: func在其配置空间中都有一个 IRQ 寄存器。注意:PCI“设备”和“插槽”是同义词。

最初的 XT/AT PC 带有一个 i8259 可编程中断控制器芯片(或两个)来合并所有 ISA IRQ 线并以统一的方式将它们呈现给 CPU(通过单个上游 IRQ 信号和一组可编程向量寄存器) . 这些最初是独立的 DIL 芯片。当 PCI 出现时,最初它的 4 条中断线被塞进第二个 i8259 并与 ISA 总线共享。这并不好,因为 ISA IRQ 是边缘触发的并且难以共享,而 PCI IRQ 是电平触发的并且设计为相对容易共享。

在 i486 前后的某个时候,当双 CPU x86 机器出现在绘图板上(有些是实际构建的)并且外围设备变得过于丰富时,i8259 XT PIC 进行了改造:CPU 内核现在有一个“本地 APIC”中断片上控制器,并且需要主板上的配套“IO APIC”芯片,以收集不同的专用 IRQ 线并将中断事件传输到 CPU。IO APIC 带有 24 个 IRQ 输入,主板上可能有几个。IO APIC 输入的第一个候选者显然是 PCI 总线的 4 根 INTA..INTD 线。

最初,IO APIC 是独立的芯片,通过专用的“APIC 总线”与 CPU LAPIC 通信。后来 IO-APIC 移到了 PC 芯片组的南桥中,一些被包含在独立的 PCI 桥中。而且,APIC IRQ 事件的上游通信“带内”移动:从那时起,它通过系统总线树上的消息进行传输。请注意,除了上面提到的三个之外,APIC 中断消息是另一种“总线事务类型”(让我们在这里跳过它们)。

典型 Pentium 4 主板上的芯片组拓扑

然后是 PCI-e,它支持原生消息信号中断传递机制,更多内容见下文 - 但 PCI-e 还承诺与传统并行 PCI 向后兼容。那么...如何传输传统的 INTA...INTD 中断 = 专用线?毫不奇怪,它们是通过消息传输的。专用消息,其中八个用于这四根电线:

  • 断言 INTA
  • 置低 INTA
  • 断言 INTB
  • 置低 INTB
  • 断言INTC
  • 置低INC
  • 断言INTD
  • 置低 INTD

概括地说,它们仅称为 INTx 消息(对应于历史 INTx 线路)。每条 INTx 线有两条 INTx 消息,用于传达“电平触发”逻辑。

但是等等,这就是乐趣的开始。PCI-e 中 INTA..INTD 中断的这种电平触发逻辑是系统范围的。在典型的 PC 芯片组 + 外围卡中,您将有许多 INTA..INTD 中断源。而且,它们的电平触发逻辑需要合并在一起。在物理线路中,这是以“有线或方式”完成的,低电平有效,集电极开路和上拉。在 PCI-e 中,每个 INTx 虚拟线的状态必须“虚拟”合并。并且,合并由 PCI-e 桥(交换机)以级联方式处理。每个 PCI-e 桥接器/交换机都包含四个“存储单元”,它们将来自下游 PCI-e 端口的断言/取消断言消息合并到一个内部状态中,然后再向上游发出该内部聚合状态的变化信号。所以有级联的PCI-e交换机,让四个 INTx“电平触发”状态在总线树上浮动,直到到达 PCI-e 根复合体。根集线器是芯片组北桥的关键部分,它执行 INTx 级别合并的最后阶段,并且……并将该状态转发到 IO APIC!关闭“集线器链接”端口,远离 CPU!IO-APIC(实际上现在重新命名为 IO(x)APIC)将这四个聚合“虚拟线”与其在输入 A..D 处的潜在四个物理线合并,并且...最终将中断事件转发到 CPU LAPIC . 向上“集线器链路”,向上 FSB。该原理在现代 PC 平台中保持不变,其中北部复合体集成在 CPU 芯片上,或者南部现在也在同一个 SoC 封装中。直到它到达 PCI-e 根联合体。根集线器是芯片组北桥的关键部分,它执行 INTx 级别合并的最后阶段,并且……并将该状态转发到 IO APIC!关闭“集线器链接”端口,远离 CPU!IO-APIC(实际上现在重新命名为 IO(x)APIC)将这四个聚合“虚拟线”与其在输入 A..D 处的潜在四个物理线合并,并且...最终将中断事件转发到 CPU LAPIC . 向上“集线器链路”,向上 FSB。该原理在现代 PC 平台中保持不变,其中北部复合体集成在 CPU 芯片上,或者南部现在也在同一个 SoC 封装中。直到它到达 PCI-e 根联合体。根集线器是芯片组北桥的关键部分,它执行 INTx 级别合并的最后阶段,并且……并将该状态转发到 IO APIC!关闭“集线器链接”端口,远离 CPU!IO-APIC(实际上现在重新命名为 IO(x)APIC)将这四个聚合“虚拟线”与其在输入 A..D 处的潜在四个物理线合并,并且...最终将中断事件转发到 CPU LAPIC . 向上“集线器链路”,向上 FSB。该原理在现代 PC 平台中保持不变,其中北部复合体集成在 CPU 芯片上,或者南部现在也在同一个 SoC 封装中。

我最近在一些 StackExchange 论坛上注意到另一个关于此的问题,现在找不到它......但这意味着如果您将一些外围设备插入直接连接到 CPU 插槽的广泛 PCI-e 端口,并且外围设备运行“ legacy compatible”INTx 中断,中断必须通过 HubLink(现在称为 DMI)到南桥的 IO-APIC,并重新处理备份到 HubLink,最后到 CPU。更有趣的是,连接到南桥的外设,如果使用与传统 INTx 兼容的 PCI-e 中断,理论上会导致中断沿着集线器链路向上传播到根复合体(PCI-e INTx 合并的最终点),下降到SB 中的 IO(x)APIC(虚拟和有线 INTx 合并的最终点),然后再次通过集线器链接到 CPU :-D

我会大胆猜测,在 ICH(南)中集成外围设备时,英特尔“作弊”=通过提供到 IO(x)APIC 的直接有线 IRQ 链接进行优化,这样它们就不必在 HubLink 上上下移动. 不确定通过外部 PCI-e/PCI 桥连接的外部外围设备,通过 PCI-e 端口与南桥通信(因为现代 ICH/SB 不再具有物理并行 PCI 端口)。

而且,这不是乐趣结束的地方。由于传统 INTx 模式下的大多数 PCI-e 设备将默认使用本地 INTA“虚拟线路输出”,并且通过 PCI-e/PCI 桥连接的许多物理 PCI 设备也是如此,因此传统操作系统最终将共享 IO (x)APIC 在系统中所有外设之间的 INTA 输入。所有设备共享 IRQ16 - 你能想象破坏吗?

没有搅拌

为了解决这个问题,英特尔引入了“virtual wire INTx IRQ swizzling”。

有调酒的

这两张图片取自下面“参考资料”中列出的英特尔应用笔记。

现在……我们受够了所有 INTx 遗产吗?是的?然后你就可以为真正的信息信号做好心理准备了。

英特尔可能已经注意到并行 PCI 时代已经存在的 4 条专用 INTx 线的无效性。或者他们可能已经开始研究 PCI-e 并且正在准备一些基础?无论哪种方式,PCI 版本 2.2 引入了消息信号中断,“MSI”,作为消除所有有线 IRQ 废话的一种方式。毕竟,中断只是一个“事件”,需要传递给 CPU - 一个简单的消息,不受所有有线废话的影响,实现起来可能很简单。真正的 PCI-e MSI 是相当简单的内存写入事务- 指向一个众所周知的地址,由 CPU LAPIC 解码。LAPIC 中的一个分配的 MSI 插槽恰好对应一个 PCI-e 设备。外围 PCI-e 设备被编程为直接向 CPU 发送中断,无需共享,无需任何转换和合并,并在 CPU 内核的 LAPIC 中获得其专用插槽。这样,它还可以在软件(内核模式驱动程序)中获得专用的服务例程。ISR 确切地知道谁调用了 IRQ,这意味着需要更少的后续轮询访问(延迟缠身的总线活动)。

世界突然变美了不是吗?好吧,这不是那么直截了当。MSI 需要操作系统和驱动程序的支持。

硬件准备好后,Linux 就增加了对 MSI 的支持。它需要两个专用的内核 API 调用,尽管理论上可以无缝转换到 MSI,但它还需要对特定于硬件的驱动程序(以及外围设备的固件)进行一些进一步的修改。也许最早带有支持 MSI 的驱动程序的外围设备是 Intel 千兆系列 NIC,仍然是并行 PCI 化身。英特尔 PRO 1000 的 PCI-e 代当然紧随其后。另一个罕见的例子是 AIC-79xx SCSI HBA,如果内存服务(并行 PCI-X)。但是,多年来,许多其他设备驱动程序使用传统中断(有效地使用虚拟线 INTx 和 IO APIC 路由),即使它们的硬件已经基于 PCI-e,因此根据定义应该支持 MSI(根据标准是强制性的)。如,Adaptec AACRAID 系列 SCSI RAID 控制器,讽刺的是使用了 Intel IOP 处理器。在撰写本文时,情况几乎完美,大多数 NIC 和磁盘控制器以及图形适配器等都在 Linux 中使用 MSI 或 MSI-X。

在 Windows 世界中,Microsoft 没有在 Windows XP SP3(NT/WDM 驱动程序模型)中包含 MSI。相反,他们在新的 WDK 驱动程序编写框架中包含了 MSI 支持,该框架在 Vista 中首次亮相,但在 Windows 7 中真正起飞。因此,随着 Windows 7 的到来,IRQ 共享噩梦终于开始消失。

什么是微星-X?这是MSI的演变。

最初的 MSI 模仿了 INTx 中断(有线或虚拟)的传统功能,因为单个总线:设备:函数具有单个 IRQ 编号 = 最好是 CPU LAPIC 中的单个插槽,单个 IRQ 服务向量。实际上 Wikipedia 上说单个设备最多可以有 32 个 IRQ,但我从来没有见过,恰好 1 曾经是实际规则。

使用 MSI-X,单个 PCI-e 实体可以执行多个专用 IRQ 编号/通道/服务向量,从而进一步限制“轮询 IRQ 源映射”的需要。一个现代的 Intel NIC 可以分配 3 或 5 个 MSI-X 向量:一个全局,一个用于 TX 队列,一个用于 RX 队列,天知道其他是干什么用的。

请注意,CPU 中的传统 Local APIC 只有 255 个 IRQ 服务向量槽,这可能已经成为繁忙的高端服务器机器的瓶颈。对于 MSI/MSI-X,此限制有所增加。使用 MSI-X,单个设备(单独!)可以使用多达 2048 个不同的 IRQ 编号。

MSI 和 MSI-X 之间可能存在我不知道的进一步差异。

进一步阅读:

英特尔关于 PCI-e INTx 虚拟线中断调配的应用说明

英特尔 5000X MCH 数据表 - 附有 INTx 虚拟线路交付说明

编辑:关于 APIC 的另外两个链接:

OSDev 本地 APIC 说明

OSDev IO APIC 笔记

[您可能应该直接阅读 Frr 的答案,该答案更准确并提供更多背景和上下文]

所有中断都执行相同的功能:从一个 (PCIe) 代理发送到另一个代理的有关某个事件的通知。

为什么我们称这些通知为“中断”?好吧,一般情况下(尽管并非总是如此),被中断的微处理器会停止其当前活动,以某种方式保存此活动的状态,并将注意力转移到处理中断上(通过执行中断服务程序;简而言之-ISR)。我们说这个通知的到来打断了微处理器的正常流程,因此得名“中断”。

在早期,所有中断都只是线路:必须在代理之间通信的每个事件都由一条线路表示。然而,随着此类事件数量的增加,必须在芯片上布线的导线数量变得庞大。

硬件模块之间标准化互连(PCI、PCIe 等)的引入允许使用中断传递的新概念 - 消息信号中断 (MSI)。为什么 MSI 比电线更好?好吧,工程师们,如果无论如何都有一个允许在代理之间交换通用消息的互连,那么在其顶部添加不必要的电线将是浪费空间 - 您可以使用现有的互连来交换特殊消息,只需确保所有代理都将这些特殊消息视为中断。

PCI MSI 是在 PCI2.2 (Wiki) 中引入的,作为常规中断的替代方案,并且它们在 PCIe 中成为强制性的。

MSI-X 只是 PCIe 中 PCI MSI 的扩展——它们提供相同的功能,但可以携带更多信息并且更灵活。注意:PCIe 支持 MSI 和 MSI-X。

MSI 的概念非常方便,可以大大减少芯片上的布线,但它几乎没有缺点:

  1. 延迟 - MSI 消息不会立即传递。在 MSI 到达其目的地之前可能需要许多时钟周期。
  2. 电源 - 为了交付 MSI,必须为传播它的逻辑供电。今天,当市场转向移动设备时,这是一个巨大的劣势。

从事 PCIe 规范工作的工程师足够聪明,可以预见到上述问题在未来将变得非常重要。他们决定保留使用“传统”中断的选项 - 简单的电线。这些是 INTx 中断:在特殊情况下,可以将 PCIe 代理配置为使用简单线路而不是 MSI 来发出中断信号。PCIe 为每个代理定义了最多 4 条线路 - 这些被命名为 AD。INTx 是所有四个的通用名称(x = A 或 B 或 C 或 D)。

INTx 信号的主要用途是在主 PCIe 互连断电时发出中断信号:当代理需要通信时,它“断言”INTx 之一,这会导致 PCIe 互连上电。

“在特殊情况下,可以将 PCIe 代理配置为使用简单线路而不是 MSI 来发出中断信号。PCIe 为每个代理定义多达 4 条线路 - 这些被命名为 AD。INTx 是所有四个的通用名称(x = A or B or C or D)”——我不认为这是真的。虽然 PCIe 支持传统中断,即 INTx,但它们不是物理线路。而是通过消息的带内信号。在 PCIe 中,INTx 和 MSI 都在带内,一个 (INTx) 是通过消息,而另一个 (MSI) 是通过发布的内存写入。