QEMU源码全解析 —— PCI设备模拟(1)

发布时间:2024年01月10日

接前一篇文章:

1. PCI设备简介

PCI是用来连接外设的一种局部(local)总线,其主要功能是连接外部设备。PCI总线规范在20世纪90年代提出以后,其逐渐取代了其它各种总线,被各种处理器所支持。直到现在,PCI总线机器发展出来的PCIe总线都在PC上得到广泛使用。在Linux系统上,输入lspci命令,可以看到当前系统的PCI设备(笔者使用的是Ubuntu 22.04的虚拟机):

$ lspci
00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)
00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01)
00:07.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 08)
00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)
00:07.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)
00:07.7 System peripheral: VMware Virtual Machine Communication Interface (rev 10)
00:0f.0 VGA compatible controller: VMware SVGA II Adapter
00:10.0 SCSI storage controller: Broadcom / LSI 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)
00:11.0 PCI bridge: VMware PCI bridge (rev 02)
00:15.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:15.7 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:16.7 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:17.7 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.0 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.1 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.2 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.3 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.4 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.5 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.6 PCI bridge: VMware PCI Express Root Port (rev 01)
00:18.7 PCI bridge: VMware PCI Express Root Port (rev 01)
02:00.0 USB controller: VMware USB1.1 UHCI Controller
02:01.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
02:02.0 Multimedia audio controller: Ensoniq ES1371/ES1373 / Creative Labs CT2518 (rev 02)
02:03.0 USB controller: VMware USB2 EHCI Controller
02:04.0 SATA controller: VMware SATA AHCI controller

这里对于lspci命令进行一下知识补强。参考一下博文:

lspci 命令详解及常用命令-CSDN博客

一、说明

lspci是查看设备上PCIe设备信息的命令。该命令的不同参数配合,在查看PCIe设备和定位PCIe问题时很有用。包括查看PCIe设备中断号、查看配置空间内容、修改配置空间寄存器等操作。

二、参数说明

表1 基本参数

tag说明实例
-v显示设备上所以pcie设备的一些信息lspci -v
-vv显示更多的信息,几乎包含了所有有用的信息lspci -vv
-vvv显示相当详细的信息,所有能够解析出来的pcie信息都会显示出来lspci -vvv
-n显示设备上所有pcie设备的vendor id 和device idlspci -n
-x显示设备上所有pcie设备的配置空间的标准部分(前 64 字节或 CardBus 桥接器的 128 字节)lspci -x
-xxx显示设备上pcie设备的配置空间的所有内容lspci -xxx
-xxxx显示 PCI-X 2.0 和 PCI Express 总线上可用的扩展(4096 字节)PCI 配置空间内容lspci -xxxx
-b显示所有pcie设备的总线地址lspci -b
-t以树形结构显示pcie设备,能展示设备上所以pcie总线、桥、pcie设备之间的连接关系lspci -t

表二 限制参数

tag说明实例
-s [[[[domain]:]bus]:][slot][.[func]]根据domain bus号等信息,查看指定pcie设备的信息,可搭配表1任意参数使用lspci -vv -s 00:1f.3
-d []:[]查看指定device id和vendor id的pcie设备的信息,可搭配表1任意参数使用lspci -vv -d 8086:8c22

每一个PCI设备在系统中的位置由总线号(Bus Number)、设备号(Device Number)和功能号(Function Number)唯一确定。有的设备肯能有多个功能,从逻辑上来说是单独的设备。可以在PCI总线上挂一个桥设备,之后在该桥上在挂一个PCI总线或者其它总线。PCI设备结构如下图所示:

PCI设备有自己独立的地址空间,叫做PCI地址空间。也就是说从设备角度看到的地址跟从CPU角度看到的地址,本质上不在一个地址空间,这种隔离是由上图中的HOST-PCI(HOST/PCI)主桥完成的CPU需要通过主桥才能访问PCI设备,而PCI设备也需要通过主桥才能访问主存储器

主桥的一个重要作用就是将处理器访问的存储器地址转换为PCI总线地址。x86架构对于存储器地址空间和PCI地址空间区分得不是很清晰,因为本质上是两个不同的地址空间,但是其地址是相同且一一对应的。

每个PCI设备都有一个配置空间,该空间至少有256字节。其中,前面64个字节是标准化的,每个设备都是这个格式,后面的数据则由设备觉得。

PCI配置空间如下图所示:

下面对配置空间进行简单介绍(这一段可以对照笔者的文章《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(12)以及后续文章)。

Vendor ID、Device ID、Class Code用来表明设备的身份有时(有些场景下)还会设置Subsystem Vendor ID和Subsystem Device ID

6个Base Address表示的是PCI设备的IO地址空间(BAR寄存器保存PCI设备使用的地址空间的基地址,该基地址保存的是该设备在PCI总线域中的地址),虚拟机可以通过这些地址空间对设备进行读写配置控制。除了6个BAR,还可能有一个ROM的BAR(Expansion ROM base address寄存器,有些PCI设备在处理器还没有运行操作系统之前,就需要完成基本的初始化设置)。

有两个与中断设置有关的值,IRQ Line表示设备使用的是哪一个中断号。如传统的中断控制器由两个82599芯片看级联而成,有0~15号Line,IRQ Line表示的是使用哪一根线IRQ Pin表示的是PCI设备使用哪一条引脚连接中断控制器PCI总线上的设备可以通过4根中断引脚INTA~D#向中断控制器提交中断请求,这里的IRQ Pin即用来表示这个引脚编号。1~4分别表示INTA~INTD#的4个引脚大部分设备使用中断线INTA引脚如果设备不支持中断,则该域为0

PCI总线能够发送对应的INTA~INTD#4个信号,这4个信号会与中断控制器的IRQ_PIN引脚相连。PCI总线规范中并没有规定PCI设备的INTx信号与中断控制引脚的连接关系,因此系统软件需要使用中断路由表存放PCI设备的INTx信号与中断控制器的连接关系中断路由表通常是由BIOS等系统软件建立的

为了均衡PCI总线上的负载,通常PCI信号与终端信号的连接都是错开的。如下图所示:

插槽A上的设备与插槽B、C上的设备使用不同的信号线连接中断控制器的IRQY#引脚,其它类似。这种连接方式也让每个插槽的中断信号INTA连接到不同的中断设备引脚。

欲知后事如何,且看下回分解。

文章来源:https://blog.csdn.net/phmatthaus/article/details/135492646
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。