本文主要讲解了x86体系架构从外部设备接受中断的过程,本文是系列文章的第一部分,试图回答以下问题:

  • 什么是PIC以及它的用途是什么?
  • 什么是APIC以及它的用途是什么?LAPIC和I/O APIC的目的是什么?
  • APIC,xAPIC以及x2APIC之间的区别在哪儿?
  • 什么是MSI? MSI以及MSI-X之间的存在哪些区别?
  • $PIR, MPtable, 和 ACPI tables的用途是什么?

如果你想知道上述问题的答案,或者仅仅想简单了解一下中断控制器的发展过程,耐心看完本文,你一定会有收获。

原文地址:

本文是翻译的国外大佬的文章,根据自己的理解稍加修改了语序,由于自己也在学习阶段,翻译难免有纰漏,如果感觉有些地方读不懂,建议可以去看看原文,并向我提出翻译修改的建议,谢谢。

《External Interrupts in the x86 system. Part 1. Interrupt controller evolution》

Introduction

对于那些不了解中断(interrupt)是啥的同学,这里引用Wikipedia的内容进行简单的介绍:

在系统编程中,中断是由硬件或软件向CPU(处理器)发出的一种信号,提示CPU需要立即处理一些高优先级任务。 中断提醒CPU注意高优先级任务,同时停止CPU当前正在执行的代码。 随后CPU暂停当前运行的代码、保存程序状态、转而去执行一个中断处理程序(或中断服务程序,ISR)来响应中断事件。 中断是暂时的,在中断处理程序完成后,处理器恢复到之前运行的代码。

中断一般分为两类:硬件中断和软件中断。

  • 硬件中断:外设一般使用硬件中断向操作系统传递自身需要运行的信号,在计算机内部,外部设备通过向处理器发送电子警报信号实现硬件中断,例如磁盘控制器,或者外部设备,当按下键盘上的键或移动鼠标时会触发硬件中断,从而使处理器读取按键值或鼠标位置。启动硬件中断的行为被称为中断请求(IRQ)。
  • 软件中断:软件中断是由处理器本身的异常,或者是指令集中特殊指令在执行时引起的中断。 前者通常称为陷阱(trap)或异常(exception),用于处理程序执行期间发生的错误或事件,这些错误或事件无法在程序内处理。 例如,数字除以零,会引发除零异常,由此产生软件中断。

   本文主要讲解的是硬件中断IRQ。

       中断的目的是什么? 举个例子,在网卡传输数据包的过程中,我们希望数据包到达后立即对来自网卡的传入数据包执行操作,而不是cpu连续询问网卡«我的数据包到达了吗?»,轮询方式会浪费cpu处理的时间,在这个案例之下可以使用外部硬件中断 IRQ,网卡的中断线应该连接到 CPU 的 INTR 线,网卡每收到一个数据包,就通过中断线发出信号,通知cpu数据包已经收到,然后cpu停下手头的工作,去读取这个数据包。

但是如果有很多外部设备我们该怎么办?不可能将每个设备的中断线直接连接到CPU上,虽然通信效率高,但 在 CPU 上制作大量的 INTR 引脚是不现实的。

为了解决多个外设的中断线连接CPU的问题,一个特殊的芯片被设计出来,这就是中断控制器(an interrupt controller)。

PIC(可编程中断控制器 Programm Interrupt Controller)

第一个中断控制器芯片是 Intel 8259 PIC。 它有 8 条输入线(IRQ0-7)和 1 条输出线(连接中断控制器和 CPU 的 INTR 线)。 当其输入线上的任意一个设备发生中断时,8259 将通过 INTR 线发出中断信号。 于是CPU 知道某个设备请求了中断,处理器将询问 PIC的 8 条输入线(IRQx),并判断哪条是此中断的来源。 这个轮询有一些开销,但现在我们有 8 条中断线而不是 1 条。

很快 8 条输入线就不够用了。 为了增加中断线的总数,两个 8259 控制器(主控制器master和从控制器slave)以级联方式进行连接(Dual PIC)。

从 0 到 7 的 IRQ 由第一个 Intel 8259 PIC(主)处理,从 8 到 15 的 IRQ 由第二个 Intel 8259 PIC(从)处理。 只有主设备直接连接到 CPU 并可以发出中断信号。 如果第 8-15 行有中断,第二个 PIC(从机)将通过 IRQ2 线向主机发送中断信号,然后主机向 CPU 发送中断信号。 这种级联中断占用了 16 条线路中的 1 条,但对所有外部设备总共产生了 15 条中断线(8+7)。

上述中断控制器级联方案很快被开发社区采用,现在当有人谈论PIC(可编程中断控制器)时,通常是指Dual PIC system即双PIC级联系统。过了一段时间,8259改进为8259A。有了这个控制器,芯片组中就包含了双PIC系统。当外部设备连接的主总线是ISA时,这个系统就足够了。不同的设备需要连接到不同的IRQ线路,因为ISA总线的中断是不可共享的。       设备中断几乎都按照如下标准进行映射:

Example (from here):

IRQ 0 — system timer

IRQ 1 — keyboard controller

IRQ 2 — cascade (interrupt from slave controller)

IRQ 3 — serial port COM2

IRQ 4 — serial port COM1

IRQ 5 — parallel port 2 and 3 or sound card

IRQ 6 — floppy controller

IRQ 7 — parallel port 1

IRQ 8 — RTC timer

IRQ 9 — ACPI

IRQ 10 — open/SCSI/NIC

IRQ 11 — open/SCSI/NIC

IRQ 12 — mouse controller

IRQ 13 — math co-processor

IRQ 14 — ATA channel 1

IRQ 15 — ATA chanel2

Intel 8259芯片的配置和工作通过I如下I/O端口进行:

Chip

Register

I/O port

Master PIC

Command

0x0020

Master PIC

Data

0x0021

Slave PIC

Command

0x00A0

Slave PIC

Data

0x00A1

8259A更加完整的说明文档在此链接here

后来,外设数量超过了15台,PCI总线也逐渐替代了ISA总线,相比于静态的ISA总线,PCI总线上的设备可以动态的加入到系统中,同时总线上的中断可以共享,这样可以实现利用一条中断线IRQ连接多个设备。最后,为了解决中断线不足的问题,设计者决定将所有PCI设备的中断分配到PIRQ线(Programmable Interrupt Request 可编程中断请求)。

例如,假设我们在PIC控制器和20个PCI设备上有4条空闲的中断线。我们可以将来自5台设备的中断合并成一条PIRQx线,并将这些PIRQx线连接到PIC控制器。在这种情况下,如果一条PIRQx线路上出现中断,处理器必须询问与该线路相连的所有设备的中断情况,确定对哪个设备响应。由此将PCI中断线与PIRQx线连接的设备称为PIR路由器。使用这种方法必须要确保PIRQx线路没有连接到ISA总线中断上(这会产生冲突),同时要确保PIRQx线路分布是均衡的(我们连接到一条线路的设备越多,CPU在响应哪个设备的中断时需要轮询的次数就越多)。

        Note:上图展示了PCI设备->PIR的连接过程,在实际电路中,它们之间的连接更加复杂。实际上,每个PCI设备有4条中断线(INTA、INTB、INTC、INTD)和多达8个中断函数,其中每个函数只能有一个INTx中断。每个中断函数将使用哪条INTx线取决于芯片组配置。

从本质上讲,中断函数彼此间是独立的。例如,一个PCI设备可以具有Smbus控制器函数、SATA控制器函数和LPC桥接函数。从操作系统(OS)的角度来看,每个函数就像一个单独的设备,有自己的配置空间(PCI配置)。 PIC控制器的中断路由信息由BIOS发送给操作系统,BIOS主要通过$PIR 、3Ch寄存器、3Dh寄存器来对PCI 进行配置。

$PIR 表规范可以在微软提供的网站查询,或者从 PCI BIOS Specification获取相关信息。

APIC

最后一种方法主要用于多处理器系统。本质上,PIC只能向一个CPU发送中断,在多处理器系统中,需要均衡的向CPU通知中断。这个问题的解决方案是添加一种新的PIC接口----APIC(Advanced PIC)。

每一个处理器都添加一个特殊的控制器LAPIC(local APIC),以及提供外部设备中断路由的I/O APIC控制器。这些所有的控制器都连接在APIC 总线上,设备连接示意图如下。

当一个外部中断信号输入到 APIC的I/O口上,这个控制器会将该中断信号传送到系统中任意一个CPU上的LAPIC上,在上述传输方式中,APIC控制器可以均衡的将中断信号传入不同的处理器上。第一款APIC芯片是82489DX,它是一个单独的芯片,内部含有LAPIC和APIC,对于上图中的双处理器系统,需要三个这样的芯片:两个用于LAPIC,一个用于I/O APIC。后来,LAPIC功能直接包含在处理器中,APIC部分与82093AA芯片分离。

APIC 82093AA芯片有24个输入,APIC体系架构最多可支持16个CPU。中断0-15用于旧的ISA中断,以便与旧的系统兼容,中断16-23用于所有PCI设备。通过这种划分,ISA和PCI中断之间的所有冲突都可以轻松避免。随着空闲中断线数量的增加,也可以用来增加PIRQx线的数量。APIC和LAPIC编程可以通过MMIO完成。LAPIC寄存器通常放在地址0xFEE00000上,APIC寄存器放在地址0xFEС00000上,因此可以需要重新配置它们。与PIC的情况一样,最初独立的芯片后来会成为芯片组(处理器)的一部分。

APIC 体系结构的下一代是xAPIC (x -extended),可以完全向后兼容,并且系统支持的CPU个数增加到了256。xAPIC的下一代体系架构是x2APIC.该系统可以支持的CPUs数量增加到了  2^32。可以在xAPIC模式下运行,也可以在新的x2APIC模式下运行。在这种新模式下,控制器编程不是通过MMIO完成的,而是通过MSR寄存器(速度快得多)。根据该链接(this link,),IOMMU来支持该模式的编程。

值得一提的是,系统中可能有多个APIC控制器。例如,南桥中的APIC负责24次中断,北桥中的另一个APIC负责32次中断。在APIC系统中,中断通常被称为GSI(全局系统中断)。因此,上述南北桥系统整体的GSIs为0-55。我们如何确定CPU内部是否含有LAPIC,以及它支持哪种APIC体系结构?我们可以通过检查CPUID中的标志位来确定。

为了帮助OS 发现 LAPIC 和 APIC硬件的存在,以及使用它们。BIOS可以通过MPtable(旧方法)或ACPI表(在本例中是MADT表)来提供有关它们的信息,并加载到OS中。除了上述信息,MPtable和ACPI都应该包含具体的中断路由信息。这包含着哪个设备具体使用哪个中断线的信息(类似于$PIR表),以及相互映射关系。

我们可以通过查看官方文档(official specification)来了解MPtable,早些时候,该规范出现在英特尔网站上,但目前只能在存档版本中找到。ACPI规范可在UEFI网站上找到(当前版本为6.2)。

MSI

随着APIC的发展,所有设备的中断线导致系统变得异常复杂并且增加了错误概率。同时PCI express总线也取代了PCI总线,PCIe总线简化了中断系统,该总线中没有中断线,但是为了向下兼容,中断信号(INTx#)用一种单独的消息进行模拟。PCI总线中,中断的连接是通过物理布线实现的。而PCIe总线中的中断是逻辑连接的,并通过PCIe 桥接器进行传输。PCI express引入了一种全新的中断传递方法——MSI(消息信号中断)。在这种方式中,设备只需将数据写入CPU LAPIC的MMIO区域中的一个特殊位置,即可发出有关中断的信号。信号传输示意图如下:

早些时候,单个PCI设备只包含4个中断,但是现在可以提供多达32个中断。在MSI的情况下,没有共享的中断线:每个中断自然地对应于它的设备。 MSI中断还解决了另一个问题。例如,一个设备进行一个内存写入事务,并希望通过中断发出其完成的信号。但是,写入事务在传输过程中可能会在总线上延迟(设备无法知道)。在这种情况下,中断信号可能提前到达CPU,因此处理器将读取尚未生效的数据。如果使用MSI,MSI信息将以与数据消息相同的方式传输,因此不能提前发送,从而不会出现冲突的情况。

需要注意的是,没有LAPIC,MSI中断将无法工作,但是MSI可以取代APIC(正如上图所示,进一步简化了电路的设计)。随和一段时间的发展,MSI扩展到了MSI-X,现在每个设备最多可以处理2048个中断,并且可以指定哪一个CPU去处理哪一个中断,这对网卡等高负载设备都非常的有用。MSI不需要单独的BIOS表来支持,但外设需要指明它自身与哪一个MSI信号相对应,这些信息都需要包含在外设的驱动程序中。

Сonclusion

在本文中,我们学习了有关中断控制器演变的相关知识,并大致了解了x86中断外设的一些基本知识。

Part2部分中,我们将进行练习,了解如何在Linux中使用前面提到的每个中断控制器。

Part3部分,我们将研究coreboot代码,并查看芯片组中需要哪些设置才能实现正确的中断路由信息。

Links:

Acknowledgments

Special thanks to Jacob Garber from the coreboot community for helping me with this article translation.

Special thanks to Alex's suggestion for Computer architecture review

x86架构中的外部中断结构-Part 1:中断控制器的演化的更多相关文章

  1. 微服务架构中的BFF到底是啥?

    在<技术中台与业务中台都是啥玩意>一文中留下一个问题:BFF是啥?为啥在API网关和业务中台之间加入了一层BFF?考虑到在实际工作中,我的大部分同事都问过这个问题,这里我也总结一下进行答复 ...

  2. 向linux内核中添加外部中断驱动模块

    本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...

  3. x86架构:实模式下的中断

    https://www.cnblogs.com/Philip-Tell-Truth/p/5317983.html   这里有详细的过程说明.文字很多,为了方便阅读和理解,提炼了一些要点后归纳.整理了如 ...

  4. X86架构CPU常识(主频,外频,FSB,cpu位和字长,倍频系数,缓存,CPU扩展指令集,CPU内核和I/O工作电压,制造工艺,指令集,超流水线与超标量)

    1.主频 主频也叫时钟频率,单位是MHz,用来表示CPU的运算速度. CPU的主频=外频×倍频系数.很多人认为主频就决定着CPU的运行速度,这不仅是个片面的,而且对于服务器来讲,这个认识也出现了偏差. ...

  5. X86架构

    在接触BIOS的时候,都需要对PC架构有一定的认知.目前的PC架构绝大多数都是Intel的X86架构,貌似也是因为INTEL的这个X86架构早就了目前INTEL如日中天的地位. 废话不多说,X86架构 ...

  6. 分享一个CQRS/ES架构中基于写文件的EventStore的设计思路

    最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event Sourcing这种架构,我博客 ...

  7. X86 架构和 ARM 架构

    1.关于x86架构 X86是一个intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合,X86是由Intel推出的一种复杂指令集,用于控制芯片的运行的程序,现在X86已经广泛运用到了家 ...

  8. ARM架构和X86架构对比

    转载地址 我们就ARM架构的系统与X86架构系统的特性进行一个系统分析,方便用户在选择系统时进行理性.合理的比价分析. 一.性能: X86结构的电脑无论如何都比ARM结构的系统在性能方面要快得多.强得 ...

  9. Windows中进程的内存结构

    基础知识: 栈是一种简单的数据结构,是一种只允许在其一端进行插入或删除的线性表.允许插入或删除操作的一端称为栈顶,另一端称为栈底,对栈的插入和删除操作被称为入栈和出栈. 有一组CPU指令可以实现对进程 ...

随机推荐

  1. 谈谈 StringBuffer 和 StringBuilder 的历史故事

    1.前言 众所周知,StringBuffer 是线程安全的 ,而StringBuilder 不是线程安全的  ,但是 StringBuilder 速度会更快. 事实上 作为一个字符串拼接 方法 ,在线 ...

  2. Go语言系列之标准库path/filepath

    一.Path包 import "path" path实现了对斜杠分隔的路径进行操作的函数. func IsAbs(path string) bool // 判断是否是一个绝对路径 ...

  3. HBase文档学习顺序

    1.<HBase基础概念知识学习> https://www.toutiao.com/i6774215329498268164/ 2.<VM安装CentOS6.5> https: ...

  4. 对飞猪H5端API接口sign签名逆向实验

    免责声明 本文章所提到的技术仅用于学习用途,禁止使用本文章的任何技术进行发起网络攻击.非法利用等网络犯罪行为,一切信息禁止用于任何非法用途.若读者利用文章所提到的技术实施违法犯罪行为,其责任一概由读者 ...

  5. 超详细的编码实战,让你的springboot应用识别图片中的行人、汽车、狗子、喵星人(JavaCV+YOLO4)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. 扒一扒@Retryable注解,很优雅,有点意思!

    你好呀,我是歪歪. 前几天我 Review 代码的时候发现项目里面有一坨逻辑写的非常的不好,一眼望去简直就是丑陋之极. 我都不知道为什么会有这样的代码存在项目里面,于是我看了一眼提交记录准备叫对应的同 ...

  7. 【刷题-PAT】A1114 Family Property (25 分)

    1114 Family Property (25 分) This time, you are supposed to help us collect the data for family-owned ...

  8. Java 实现订单未支付超时自动取消

    在电商上购买商品后,如果在下单而又没有支付的情况下,一般提示30分钟完成支付,否则订单自动.比如在京东下单为完成支付: 超过24小时,就会自动取消订单,下面使用 Java 定时器实现超时取消订单功能. ...

  9. 源码分析axios(1)~源码分析、模拟axios的创建

    ■ 查看源码发现,起初axios[instance=bind(Axios.prototype.request, context);]是一个函数, 但后续[ utils.extend(instance, ...

  10. JVM专题2: JVM内存结构

    合集目录 JVM专题2: JVM内存结构 Java 内存分配 JVM 内存结构 The JVM is an abstract computing machine that enables a comp ...