系统虚拟化学习笔记——PCI设备

时间:2021-07-09 02:45:00

内容摘自《系统虚拟化:原理与实现》

PCI 总线架构

  PCI总线是典型的树结构。把北桥中host-PCI桥看做根,总线中其他PCI-PCI桥,PCI-ISA桥(ISA总线转PCI总线桥)等桥设备和直接连PCI总线的设备看做节点,整个PCI架构可以概括成下图:

系统虚拟化学习笔记——PCI设备

  通过桥,PCI可以很容易被扩展,并且与其他总线相互挂接,构成整个系统的总线网络。与HOST-PCI桥相连的总线称为总线0,其他层次总线的编号,是在BIOS(或者操作系统)枚举设备时确定的。

设备标识符

  设备标识符可以看做设备在PCI总线上的地址,它的格式如下所示:

系统虚拟化学习笔记——PCI设备

其中8位的bus字段代表设备所在的总线号,故系统中最多有256条总线。Device字段表示设备号,代表在bus所表示总线上的一个设备。Function表示功能号,标识具体设备上的某个功能单元(逻辑设备)。举一个例子,一块PCI卡,它上面有两个独立的设备,这两个设备共享一些电子线路,那么这两个设备就是这块PCI卡的两个功能单元。如Function字段长度暗示的,一个独立的PCI设备最多有8个功能单元,Device和Function一般合起来用, 表示一条总线上一共最多能有256个设备。通常用设备标识符三个字段的缩写BDF来代表它。

PCI配置空间

对于程序员来说,不需要了解PCI设备电路上的实现细节,只需要了解它的接口即可。PCI配置空间就是这么一个接口,其结构如下图所示:

系统虚拟化学习笔记——PCI设备

  PCI设备规范规定,设备的配置空间最多为256个字节,其中前64个字节的格式i和用途是统一的,对程序员来说最重要的是Base Address Registers和Interrupt Pin,Interrupt Line。

(1) Base Address Registers: 基地址寄存器,也就是常说的PCI bar。它报告设备寄存器或者设备RAM在I/O端口地址空间(或物理地址空间)的地址。地址是由软件(BIOS或操作系统)动态配置的。通常枚举PCI设备的软件(BIOS或操作系统)会在获得平台所有PCI设备之后,根据设备数量,按照固定的算法为每个设备的PCI bar分配I/O端口(或物理地址)。设备的电子线路负责把这些端口(或地址)映射到自身的寄存器上,这样,CPU就可以通过端口号(port I/O方式),物理地址(MMIO方式)访问到设备了。使用哪种方式访问,由PCI bar的最后一个位表示,该位为1时,表示是I/O端口;该位是0时,表示是MMIO端口。

(2)Interrupt Pin: 中断针脚。 PCI中断线的标准设计是4条:INTA,INTB,INTC,INTD,分别对应值0~3。该寄存器的值表示设备连接的是哪个中断针脚。

(3)Interrupt Line: 设备的中断线。该寄存器只起一个保护作用,BIOS和操作系统可以*使用它。BIOS通常用它来保存设备所连的PIC/IOAPIC的管脚号。  x86架构把IO地址空间的0xCF8~0xCFF段预留给了PCI总线,用于访问设备的配置空间。其中前32位的寄存器为“地址寄存器”,后32位为“值寄存器”。软件把设备的BDF和要访问的配置空间的字节偏移写入“地址寄存器”中,就可以通过“值寄存器”读写该配置空间了。

PCI设备枚举过程

  PCI设备的枚举过程一般是由BIOS或者操作系统完成的。

  从前面的PCI总线概要图知道,PCI设备和总线一起构成了树结构,其中PCI-PCI桥是子树的根节点,设备枚举的过程就是要在内存中建立一颗和实际总线情况相符合的设备树。枚举过程中最重要的步骤是发现PCI-PCI桥。这个可以通过PCI配置空间的HeaderType字段判断,该字段为1时表示桥设备。PCI-PCI桥主要有三个属性:

  • Primary bus: 表示该桥所属的根总线
  • Secondary bus: 表示以该桥为根节点的子总线
  • Subordinate bus: 表示该桥为根的子树中,最大的总线号

系统虚拟化学习笔记——PCI设备

  下面以上图说明三者的关系。

  如上图所示,对于“PCI-PCI桥1”,其Primary bus为总线0,Secondary bus为总线1,而以它为根的总线中最大的总线号为2,所以其Subordinate bus为总线2。

  设备枚举从根节点HOST-PCI桥开始,首先探测总线0上的各个设备。当探测到第一个桥设备时,为其分配Primary bus号和Secondary bus号,其中Secondary bus号为1(即当前系统中最大总线号加1),Subordinate bus号暂时和Secondary bus号相同,当在子树中发现新总线后会自动调整该值。接着以该桥为根节点,继续探测其下属总线,其过程与前面相同,发现第一个桥设备后则以其为根继续往下探测,如此反复知道所有的子树都探测完毕。

  当PCI-PCI桥收到写入0xCF8中的BDF后,会将Bus字段与自身的Secondary Bus相比,相符则在下属总线上搜索设备;如果不相符,当Bus值落在Subordinate bus范围内,则将该地址传递给下属总线中各桥,否则不予理睬。

  通过这种方式,BIOS或者操作系统可以枚举出总线上所有设备并为之分配资源,一旦PCI配置空间设定好,软件就可以通过PCIbar直接访问设备了。

  PCI Express

  PCI Express 抛弃了PCI所采用的多个设备共享的并行的总线架构,转而使用了与网络协议类似的点对点的串行通信机制。多个PCI Express设备(Endpoint)通过交换器(Switch)相互连接。与PCI设备中的桥设备相似,通过交换器,可以搭建一个树形的PCI Express的拓扑结构。标准的PCI Express拓扑结构如下图所示。

  系统虚拟化学习笔记——PCI设备