来自x86系统中的外部设备的中断。 第1部分。中断控制器的演变

在本文中,我将考虑用于从x86系统中的外部设备传递中断的机制,并尝试回答以下问题:

  • 什么是PIC?其用途是什么?
  • APIC是什么?它有什么用? LAPIC和I / O APIC有什么用途?
  • APIC,xAPIC和x2APIC之间有什么区别?
  • 什么是MSI? MSI和MSI-X有什么区别?
  • $ PIR,MPtable,ACPI表与此相关吗?

如果您有兴趣获得上述任何一个问题的答案,或者您只是想熟悉x86系统中中断控制器的发展,欢迎加入。

引言


我们都知道什么是中断。 对于那些不是的人,请引用维基百科:

中断(英文中断)-来自软件或硬件的信号,用于通知处理器任何需要立即注意的事件的发生。 中断通知处理器发生高优先级事件,要求中断由处理器执行的当前代码。 处理器通过挂起其当前活动,保存其状态并执行称为中断处理程序(或中断处理程序)的功能来进行响应,该功能对事件进行响应并为其提供服务,然后将控制权返回给被中断的代码。

根据中断信号的来源,它们分为:

  • 异步或外部(硬件)-来自外部硬件设备(例如外围设备)的事件,可以在任意时刻发生:来自计时器,网卡或磁盘驱动器的信号,击键,鼠标移动。 系统中发生此类中断的事实被解释为中断请求(IRQ)-设备报告它们需要OS给予注意;
  • 由于执行机器代码时违反某些条件,导致处理器本身发生同步或内部事件:被零除或堆栈溢出,访问无效的内存地址或无效的操作代码;
在本文中,我想讨论外部IRQ中断。

为什么需要它们? 假设我们要对到达的网卡输入数据包执行一些操作。 为了不不断询问网卡“您有新包装吗?” 并且不要为此浪费处理器资源;您可以使用IRQ中断。 设备中断线连接到处理器的INTR线,并且当接收到数据包时,网卡“拉”该线。 处理器了解到有信息并读取了数据包。

但是,如果有很多设备怎么办? 您无法充分利用处理器支脚的所有外部设备。



为了解决这个问题,他们提出了一个芯片-中断控制器。

图片


Wiki / osdev

第一个是Intel 8259 PIC芯片。 8条输入线(IRQ0-7)和1条输出将控制器与处理器的INTR线连接。 当发生来自设备的中断时,8259拉INTR线,处理器了解某些设备发出中断信号,并轮询PIC以了解是哪个IRQx支路引起了该中断。 此勘测还有一个额外的延迟,但是中断线的数量增加到8。



但是,很快发现8条线很小,为了增加数目,开始使用2个8259级联(双PIC)控制器(主从)。

IRQ 0至7由第一个Intel 8259 PIC(主设备)处理,IRQ 8至15由第二个8259 PIC(从设备)处理。 只有主机发出中断发生的信号。 如果在线8-15上发生中断,则第二个PIC(从站)通过IRQ 2向主机发出中断信号,而主机又向CPU发送信号。 该级联中断占用16条线之一,但最后为设备提供15条可用中断。



电路已经建立,这就是他们现在谈论PIC(程序中断控制器)时的意思。 随后,8259控制器进行了一些改进,并被称为8259A,并且该电路包含在芯片组中。 当用于连接外部设备的主要总线是ISA总线时,整个系统就足够了。 由于不共享ISA中断,因此仅需确保不同的设备未连接到同一IRQ线路即可避免冲突。

通常,设备的中断布局或多或少是标准的

示例( 从此处获取 ):
IRQ 0-系统计时器
IRQ 1-键盘控制器
IRQ 2-级联(从控制器中断)
IRQ 3-串行端口COM2
IRQ 4-串行端口COM1
IRQ 5-并行端口2和3或声卡
IRQ 6-软盘控制器
IRQ 7-并行端口1
IRQ 8-RTC计时器
IRQ 9-ACPI
IRQ 10-打开/ SCSI / NIC
IRQ 11-打开/ SCSI / NIC
IRQ 12-鼠标控制器
IRQ 13-数学协处理器
IRQ 14-ATA通道1
IRQ 15-ATA通道2

通过I / O端口进行8259微电路的配置和工作:
芯片报名I / O端口
大师级图片指挥部0x0020
大师级图片资料0x0021
从图片指挥部0x00A0
从图片资料0x00A1

→可以在此处找到8259A的文档

ISA总线已被PCI总线取代。 而且设备的数量显然开始超过数量15,而且,与静态ISA总线不同,在这种情况下,可以将设备动态添加到系统中。 但是幸运的是,在该总线中可以共享中断(即,可以将多个设备连接到同一IRQ线路)。 结果,为了解决IRQ线不足的问题,他们决定将来自所有PCI设备的中断分组为PIRQ线(可编程中断请求)。

假设我们在PIC控制器上有4条中断线,以及20个PCI设备。 我们将每条PIRQx线的5个设备的中断合并在一起,并将PIRQx线连接到控制器。 如果在PIRQx线路上发生中断,则处理器将必须询问与该线路相连的所有设备,以了解中断源是谁,但是总的来说,这可以解决问题。 在PIRQ线中绑定PCI中断线的设备通常称为PIR路由器。

在这种方法中,您需要确保PIRQx线未连接到已经开始ISA中断的IRQx线(因为这将导致冲突),并且PIRQx线是平衡的(毕竟,连接到同一PIRQ线的设备越多,所需的设备越多)将询问处理器以了解这些设备中的哪一个导致了中断)。



注意 :PCI设备-> PIR映射在图中抽象显示,因为实际上它有些复杂。 实际上,每个PCI设备都有4条中断线(INTA,INTB,INTC,INTD)。 每个PCI设备最多可以具有8个功能,现在每个功能都有一个INTx中断。 器件的每个功能将提取哪个INTx取决于芯片组的配置。

本质上,功能是单独的逻辑块。 例如,在一个PCI设备中,可能具有Smbus控制器功能,SATA控制器功能,LPC桥功能。 在操作系统方面,每个功能都是具有自己的PCI Config配置空间的单独设备。

BIOS使用$ PIR表并通过为每个功能填充PCI配置空间的3Ch(INT_LN中断线(R / W))和3Dh(INT_PN中断引脚(RO))寄存器将有关PIC上中断路由的信息传递给BIOS。 $ PIR表的规范以前在Microsoft网站上提供 ,但现在不再存在。 $ PIR表的行的内容可以从PCI BIOS规范 [4.2.2]中了解。 获取PCI中断路由选项]或在此处阅读

阿皮


Wikiosdev

前一种方法一直有效,直到出现多处理器系统。 事实是,PIC在其设备中只能将中断发送到一个主处理器。 但是我希望平衡来自中断处理的处理器负载。 解决此问题的方法是新的接口APIC(高级PIC)。

对于每个处理器,添加了一个特殊的LAPIC控制器(本地APIC),并添加了一个I / O APIC控制器来路由来自设备的中断。 所有这些控制器都组合在称为APIC的公共总线中(新系统现在通过标准系统总线连接)。

当来自设备的中断到达I / O APIC引脚时,控制器会将中断路由到其中一个处理器的LAPIC。 I / O APIC的存在使您能够平衡处理器之间来自外部设备的中断分配。

第一个APIC芯片是82489DX ,它是结合了LAPIC和I / O APIC的独立芯片。 为了创建一个包含2个处理器的系统,需要3个这样的微电路。 2个充当LAPIC,一个充当I / O APIC。 后来,LAPIC功能直接包含在处理器中,而I / O APIC功能则封装在82093AA芯片中。

I / O APIC 82093AA包含24个输入引脚,并且APIC架构最多可支持16个CPU。 为了保持与旧系统的兼容性,已将0〜15个中断分配给旧ISA中断。 PCI设备的中断开始在IRQ第16-23行显示。 现在有可能不考虑来自ISA和PCI设备的中断冲突。 同样,由于空闲中断线的数量增加,也有可能增加PIRQx线的数量。



I / O APIC和LAPIC编程是通过MMIO完成的。 LAPIC寄存器通常位于0xFEE00000,I / O APIC寄存器位于0xFE00000。 尽管原则上所有这些地址都可以重新配置。

与PIC一样,最初,单个芯片后来成为芯片集的一部分。

随后,APIC体系结构进行了现代化,新版本称为xAPIC(x-扩展)。 保持与先前版本的向后兼容性。 系统中可能的CPU数量增加到256。

下一轮架构开发称为x2APIC 。 系统中可能的CPU数量增加到2 ^ 32。 控制器可以在xAPIC兼容模式下工作,也可以在新的x2APIC模式下工作,在该模式下,LAPIC编程不是通过MMIO而是通过MSR寄存器(快得多)来进行的。 从此链接判断,此模式需要IOMMU支持。

应该注意的是,系统可能有几个I / O APIC控制器。 例如,一个中断在南桥中发生24次,另一个中断在北部中断32次。 在I / O上下文中,APIC中断通常称为GSI(全局系统中断)。 因此在这样的系统中将是GSI 0-55。

CPU中是否有内置的LAPIC,可以通过CPUID中的位标志理解哪种体系结构。
为了使系统能够检测到LAPIC和I / O APIC,BIOS必须通过MPtable(旧方法)或ACPI表(在这种情况下为MADT)向系统提供有关它们的信息。 除了一般信息外,MPtable和ACPI(这次在DSDT表中)都应包含有关中断路由的信息,即有关哪个设备位于哪条中断线上的信息($ PIR表的类似物)。

MPTable表可以在官方规范中找到。 以前,该规范位于英特尔网站上,但现在只能在存档中找到。 ACPI规范现在位于UEFI网站上(当前版本6.2 )。 应该注意的是,使用ACPI可以为没有APIC的系统指定中断路由(而不是使用$ PIR表)。

微星


维基

带有APIC的先前版本很好,但并非没有缺陷。 所有这些设备中断线都会使电路复杂化,并增加发生错误的可能性。 PCI总线被PCI Express所取代,在PCI Express中,中断线只是被确定为要移除。 为了保持兼容性,某些类型的消息会模拟中断信号(INTx#)。 在这种方案中,以前通常通过电线的物理连接完成的中断线的逻辑添加落在PCI桥的肩上。 但是,传统的INTx中断支持仅是与PCI总线向后兼容的支持。 实际上,PCI Express已经提出了一种用于传递中断消息的新方法-MSI(消息信号中断)。 在这种方法中,为了发出中断信号,设备只需写入分配给处理器LAPIC的MMIO区域。



以前,仅将4个中断分配给一个PCI设备(即所有功能),但是现在可以处理多达32个中断。

在MSI的情况下,线路没有共享,每个中断都与其设备相对应。

MSI中断还解决了另一个问题。 假设设备进行了存储器写事务,并希望通过中断报告其完成情况。 但是在传输过程中(设备完全不知道)总线上的写事务可能会延迟,并且中断信号将在处理器之前到达。 因此,CPU仍将读取无效数据。 如果使用MSI,则有关MSI的信息以及数据将被传输,并且将无法更早地出现。

应该注意的是,没有LAPIC,MSI中断将无法工作,但是使用MSI可以用I / O APIC(简化设计)代替我们。

随后,此方法收到了MSI-X扩展名。 现在,每个设备最多可以具有2048个中断。 这样就可以分别指示每个中断应在哪个处理器上执行。 这对于诸如网卡之类的重载设备非常有用。

MSI支持不需要其他BIOS表。 但是设备必须在其PCI Config中的功能之一中报告MSI支持,并且设备驱动程序必须支持使用MSI。

结论


在本文中,我们研究了中断控制器的发展,并从x86系统中的外部设备接收了有关中断传递的一般理论信息。

在下一部分中,我们将研究如何在Linux中实际使用每个描述的控制器。

参考文献:


Source: https://habr.com/ru/post/zh-CN430548/


All Articles