概述

        PCI的含义是外设部件互连,PCI局部总线是1991年由intel定义的,现在PCI局部总线已经成为PC机中不可缺少的外围设备总线,几乎所有的外部设备都连接到PCI局部总线上,我们说的PCI设备,实际上就是指连接在PCI局部总线上的设备,比如:显卡,网卡等。

        PCIE是PCI的扩充升级,早期的PCI时期,系统为每个PCI设备分配的内存大小仅有256B。后来的PCIE时期,随着设备性能增强,PCIE设备的配置空间扩展至4KB。

       PCIE是一种点对点连接的总线,而不像PCI那样的共享总线。但PCIe总线系统可以通过Switch连接多个PCIe设备,也可以通过PCIe桥连接传统的PCI和PCI-X设备。

配置空间 

        每个PCIE设备都有自己的独立的一段配置空间,该部分空间是这个设备的,系统会给这个设备分配一段内存空间,CPU访问这段内存空间即访问此设备的配置空间。设备在出厂时,配置空间是有默认初始值的。

        PCI设备(type0)配置空间头和PCI桥(type1)配置空间头如下图:

怎么知道pcie switch虚拟化 怎么分辨pci和pcie_运维

    在PCI桥配置空间中,有+0x18B,+0x19B,+0x1AB三个位置分别存放了Primary Bus Number(主总线号),Secondary Bus Number(所接的下一个总线号),Subordinate Bus Number(在该支路中最大总线号)。

地址映射方式

        在X86系统中,对PCIE设备配置空间的地址映射一般有两种方式:内存映射和IO映射。

  (1)内存映射       

        PCIE增强的配置访问机制在系统存储器空间里划出一片256MB的区域,将总容量为256MB的全部配置寄存器一对一地映射于这片存储器空间。

        访问特定的内存空间可以得到PCI设备的配置空间:

怎么知道pcie switch虚拟化 怎么分辨pci和pcie_运维_02

        一般的基地址,由BIOS分配,且指向PCI的第一个设备。0xC000000。

        然后配置完BDF后,其他默认为0 ,将地址直接在内容中访问,即可得出配置空间内容:

怎么知道pcie switch虚拟化 怎么分辨pci和pcie_寄存器_03

 (2)IO映射     

        PCIE设备的访问离不开Bus,Dev,Fun的编号方式,如下图寄存器所示,Bit[23:16]用来存放Bus号,共8Bit,所以一共有256条Bus,Bit[15:11]存放Dev,共5bit可存放32个Dev,Bit[10:8]存放Fun,共3Bit可存8个Fun。

怎么知道pcie switch虚拟化 怎么分辨pci和pcie_怎么知道pcie switch虚拟化_04

         根据协议,X86上使用了两个I/O端口寄存器CONFIG_ADDRESS(物理地址0CF8H)和CONFIG_DATA(0CFCH),来访问PCI配置空间。将上图寄存器的各位配置好以后,写入CONFIG_ADDRESS即可,从CONFIG_DATA中读出的值,就是配置空间中的内容。其中Bit31位是使能位,写1。在配置BDF的值,其他默认位0即可。

怎么知道pcie switch虚拟化 怎么分辨pci和pcie_运维_05

注:IO访问仅能读取到前256Byte,在256B后的空间需要用内存访问。当向 0xCF8 写入地址后,从 0xCFC 读出该地址的数据,若该数据不等于0xFFFF,说明 这是有个有效的地址,因此也可以利用此原理来枚举PCI设备。