概念

        PCI是一种高速的局部总线,连接周边设备,将低速的设备与高速的处理器连接起来,以满足对数据传输速率越来越高的要求。

从硬件结构上来看,PCI总线采用并行总线结构,使用点到点的连接方式;PCIe采用高速差分总线结构(串行),使用端到端的连接方式。

符合PCI总线标准的设备成为PCI设备。PCI设备分为主设备和目标设备(从设备),主设备是访问设备,目标设备是被访问设备。

PCI配置空间和内存空间是分离的。BDF(Bus Number、Device Number、Function Number)用来对所有的PCI设备进行编码,避免冲突。BDF码在BIOS进行PCI总线扫描和枚举的过程中确定,可用作查找PCI设备的索引。

        PCI桥是连接PCI总线的设备,用于PCI总线扩展。桥作用管理下游的PCI总线,并转发上下游总线之间的总线事务。PCI总线系统的组成包括:HOST主桥、PCI总线、PCI设备、HOST处理器、PCI总线的负载。

        HOST主桥用来隔离PCI总线域和CPU存储域,管理PCI总线域和存储域地址映射,并且完成处理器与PCI设备之间的数据交换。

        PCI总线由HOST主桥或者PCI桥管理,用来连接各类PCI设备,如是声卡、网卡、显卡等。

符合PCI总线标准的设备称为PCI设备。PCI设备分为主设备和目标设备(从设备),主设备是访问设备,目标设备是被访问设备。PCI从设备只能被动地接受来自HOST主桥或者其他PCI设备的读写请求;​ PCI主设备可以通过总线仲裁获得PCI总线的使用权,主动地向其他PCI设备或者主存储器发出读写请求。​

HOST处理器通过Host主桥发起PCI总线的配置请求总线事务,并对PCI总线上的设备和桥片进行配置。

PCI总线负载与总线频率相关,总线频率越高,能挂载的负载越少,但是整条总线能提供的带宽越大。

PCI总线树

一般的桌面系统只有一个PCI Host Bus(PCI主机总线),用于完成CPU与PCI设备之间的数据交换。一个PCI Root Bridge(PCI根桥),管理一个PCI局部总线,下挂一个PCI 总线树。PCI枚举所要访问的PCI设备是挂在在PCI总线树上的,这些设备属于同一总线空间。

PCI总线树上包含着PCI总线、PCI桥、PCI设备。 有32位和64位的,有多路地址线和数据线。典型的PCI总线树:

处理器、缓存、内存子系统通过PCI桥连接到PCI。PCI桥提供了一个低延迟路径,处理器可以通过该路径直接访问映射在内存或I/O地址空间中的任何位置的PCI设备。 PCI桥还提供了一个高带宽路径,允许PCI主机直接访问主存储器。

PCI设备的配置空间

PCI设备的基本配置空间由64字节组成,主要用来识别设备、定义主机访问PCI卡的方式。PCI设备通常将PCI配置信息存放在EEPROM中。在PCI设备上电初始化时,将EEPROM中的信息读取到PCI设备的配置空间中作为初始值,而这个过程是由硬件逻辑完成的。每个设备在出厂时,其配置空间中的值都有一些default值,枚举该设备时为每个设备分配BDS号和内存资源时,会再写入部分值。

PCI设备配置空间的代码实现(对应上图):

所有PCI兼容设备必须支持报头中的Vendor ID、Device ID、Command、Status、Revision ID、Class Code和Header Type字段。在Type 00h预定义报头中的其他寄存器的实现是可选的,这取决于设备的功能。

  • Vendor ID和Device ID用来表示设备自身;通过对比这两个ID可以判断所找的设备是否为目标设备。BIOS代码在枚举设备的时候,会去读每个设备的VID,如果读到的是不是FFFF,则表示此位置有设备存在,若为FFFF,则表示设备不存在。
  • Revision ID 记载着PCI设备的修订标识符(版本号),由供应商提供。
  • Class code(类代码寄存器)是一个24位只读的缓存器,它被分成三个字段:基本类别(Base Class)子类别(Sub Class)及程序界面(Programming Interface),较高的字节定义功能的基本类别,中间的字节定义在基本类别里的子类别,较低的字节定义程序界面。Class code记载设备的分类,用于供系统软件识别当前PCI设备的分类(识别设备)。
  • Header Type寄存器:第7位为1表示当前PCI设备时多功能设备,为0表示为单功能设备。第6~0位表示当前配置空间的类型,为0表示该设备使用PCI 设备的配置空间;为1表示使用PCI桥的配置空间;为2表示使用Cardbus桥片的配置空间。通过BAR寄存器,加上内部寄存器相对于BAR的偏移地址就可以访问PCI设备内的寄存器和其他资源。
  • Latency Timer:在PCI设备中,多个设备共享一条总线带宽。该寄存器用来控制PCI设备占用PCI总线的时间。
  • 基址寄存器BAR可以寻址IO地址空间和Memory地址空间。最低位是只读位,为0时表示寄存器是Memory地址译码,为1时表示寄存器是IO地址译码。通过BAR寄存器,加上内部寄存器相对于BAR的偏移地址访问PCI设备内的寄存器和其他资源。

  • Cache Line Size寄存器记录HOST处理器使用的Cache行长度。在PCI总线中和Cache相关的总线事务。
  • 地址0x10-0x24包含了6个基址寄存器(BAR),保存着PCI设备使用的地址空间的基地址,即设备在PCI总线域中的地址。每个PCI设备最多由6个基址空间(由BIOS分配)。
  • Subsystem ID 和 Subsystem Vendor ID寄存器也是记录PCI设备的生产厂商和设备名称。
  • Expansion ROM base address:有些PCI设备在处理器还没有运行操作系统之前,就需要完成基本的初始化设置。为了"预先执行"功能,PCI设备需要提供一段ROM,而处理器在初始化过程中将运行这段ROM程序,初始化这些PCI设备。这里记载了ROM程序运行的基地址。
  • Capabilities Pointer寄存器:在PCI 设备中,改寄存器是可选的,但是在PCI-X 和 PCIE设备汇总必须支持这个寄存器,这里存放了Capabilities寄存器组的基地址,存放一些与PCI设备相关的扩展配置信息。
  • Interrupt Line是系统软件对PCI设备进行配置时写入的,该寄存器记录当前PCI设备使用的中断向量号,设备驱动程序可以通过这个寄存器,判断当前PCI设备使用处理器系统中的哪个中断向量号。
  • Interrupt Pin寄存器告诉设备(或者设备功能)使用哪个中断引脚。PCI总线提供了四个中断引脚:INTA#,INTB#,INTC#和INTD。 为1时表示使用INTA#引脚,依次类推。

UEFI对PCI/PCIe的支持

UEFI对于PCI总线的支持包括:

1) 提供分配PCI设备资源的Protocol;

2) 提供访问PCI设备的Protocol(UEFI提供了两类访问PCI/PCIe设备的Protocol:EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL和EFI_PCI_IO_PROTOCOL);

3) 提供PCI枚举器,枚举PCI总线上的设备以及分配设备所需的资源;

4) 提供各种Lib,方便驱动程序访问PCI/PCIe配置空间或者MMIO/IO空间。

        MMIO(Memory mapping I/O)即内存映射I/O,它是PCI规范的一部分,I/O设备被放置在内存空间而不是I/O空间。从处理器的角度看,内存映射I/O后系统设备访问起来和内存一样。这样访问AGP/PCI-E显卡上的帧缓存,BIOS,PCI设备就可以使用读写内存一样的汇编指令完成,简化了程序设计的难度和接口的复杂性。简而言之,MMIO就是通过将外围设备映射到内存空间,便于CPU的访问。

EFI_PCI_IO_PROTOCOL

在PCI/PCIe设备驱动中,一般使用EFI_PCI_IO_PROTOCOL访问设备的内部资源。EFI_PCI_IO_PROTOCOL挂在在PCI/PCIe控制器上,运行在EFI启动环境中,对PCI/PCIe设备进行Memory空间和IO空间访问。函数接口代码清单:

EFI_PCI_IO_PROTOCOL在处理访问PCI/PCIe的Memory空间、IO空间和配置空间时,使用了两种类型。使用EFI_PCI_IO_PROTOCOL_ACCESS访问Memory空间和IO空间,而使用EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS访问配置空间。

访问Memory空间和IO空间的接口:

使用Io.Read()和Io.Write()函数访问IO空间,使用Memory.Read()和Memory.Write()函数访问Memory空间。BAR一共有6个,BarIndex取值范围为0~5。读写数据时,最终的访问地址由BarIndex所指向的BAR加上Offset共同决定,而地址的含义需要查看PCI/PCIe芯片厂商提供的手册说明。

访问配置空间的接口:

使用Pci.Read()和Pci.Write()函数访问PCI/PCIe设备的配置空间。参数Offset用于指定在配置空间内的偏移地址,如Offset = 0x10,表示BAR0寄存器。

PCI设备的基本配置空间由64字节组成(0x00~0x3F),PCI/PCIe设备扩展到0xFF。扩展的配置空间用来存放于MSI中断机制和电源管理相关的Capability结构。而PCIe设备扩展到0xFFF,用于存放PCIe设备独有的Capability。

EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL

        EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL为PCI根桥提供了抽象的IO功能,由PCI Host Bus Controller(PCI主总线驱动器)产生,一般由PCI/PCIe总线驱动枚举设备、获得Option ROM、分配PCI设备资源等。

EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL函数接口:

EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL提供了基本的访问接口,包括访问IO空间的接口Io、访问Memory空间的接口Mem和配置空间接口Pci。三种接口的参数类型都为EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS。接口代码清单:

​​​参数Address在访问IO空间、Memory空间和配置空间时,其含义是不同的。对于配置空间而言,Address由BDF地址Register偏移决定,即总线号、设备号、功能号和Register共同给出寻址。

对IO空间而言,参数Address是指PCI设备IO空间的IO地址;对Memory空间,Address是指PCI设备Memory空间的Memory地址。IO地址和Memory地址是由BAR和偏移决定的,每个地址的作用需要参考对应的芯片说明手册。

PCIe系统

        Root Complex(简称RC)是CPU和PCle总线之间的接口,可能包含几个组件(处理器接口、DRAM接口等),甚至可能包含几个芯片。

        Bridge提供了与其他总线(如PCI或PCI- x,甚至是另一个PCle总线)的接口。允许旧的PCI或PCIX卡插入新系统。

        Switch提供了扩展或聚合能力,并允许更多的设备连接到一个PCle端口。充当包路由器,根据地址或其他路由信息识别给定包需要走哪条路径。是一种PCIe转PCIe的桥。

        Endpoint处于PCIe总线系统拓扑结构中的最末端,一般作为总线操作的发起者或者终结者。Endpoint只能接受来自上级拓扑的数据包或者向上级拓扑发送数据包。

PCIe系统框图:

PCI驱动

UEFI提供了两种主要模块支持PCI总线:PCI Host Bridge控制器驱动PCI总线驱动。这两个模块是和特定的平台绑定的,在这种机制下,屏蔽了不同CPU的架构差异,提供了统一的Protocol接口。

        PCI HOST Bridge控制器驱动根据系统实际IO空间和Memory Map,为PCI设备指定IO空间和Memory空间的范围,并且产生PCI HOST Bridge Resource Allocation协议供PCI总线驱动使用。该驱动还对HostBridge控制器下所有RootBridge设备产生Handle(句柄),句柄安装了PCIRootBridgeProtocol。PCI总线驱动利用EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL枚举系统中所有PCI设备,发现并获取PCI设备的Option ROM,并且调用PCI HOST Bridge Resource Allocation协议分配PCI设备资源。

每一个PCI HOST Bridge Controller下面可以接一个或者多个PCI root Bridge,PCI Root Bridge会产生 PCI local Bus。PCI设备驱动不会使用PCI Root Bridge I/O协议访问PCI设备,而是会使用PCI总线驱动为PCI设备产生的PCI IO Protocol来访问PCI设备的IO/MEMORY空间和配置空间。PCI Root Bridge I/O协议(Protocol)是安装在Root Bridge设备的句柄上,同时在该handle上也会有表明Root Bridge设备的Device Path协议(Protocol)。

PCI标准的特点

PCI设备具有独立的地址空间——PCI总线地址空间。PCI总线地址空间与存储器地址空间通过Host Bridge 隔离,CPU访问PCI设备时,必须通过Host Bridge进行地址转换;PCI设备访问主存储器时,同样需要Host Bridge进行地址转换。Host Bridge使得PCI设备和处理器可以方便地共享主存储器资源。在Host Bridge 中有许多缓存,使得CPU总线与PCI总线可以工作在各自的时钟频率上。

PCI和PCIe的差异

1、 PCI是并行总线 ,而PCIe是串行的

PCI在一个时钟周期内有32bit的数据被同时传输。地址和数据在一个时钟周期内按照协议分别一次被传输。PCI引脚定义图:

PCI接口最少需要47个引脚用于目标设备,49个引脚用于主设备,用来处理数据和寻址、接口控制、仲裁和系统功能。必须的引脚有(图左边的引脚):  Address and Data、  Interface Control、  Error Reporting、  Arbitration(仲裁 master only)、  System(时钟、RST)。

2、 PCI采用总线结构,PCIe采用点对点的拓扑结构

PCI总线模型: 在传统的PCI总线模型中,一个设备通过在Bus上判断DEVSEL(设备选择,判断一个设备是否被选中)来认领一个请求。如果在一段时钟周期后没有设备认领一个请求,这个请求就被放弃。

PCIE点对点模型:PCI是一种点对点的传输模型,不像PCI总线那样,在总线上有平等认领请求的机制。所有的传送总是由一个Device发给Link上的另外一个Device。所以,对于所有接收方来说,接收方将会直接判断这个请请求是否要被认领。

3、PCIe支持4K字节的配置空间,而PCI只支持256字节的配置空间。

访问PCI/PCIe设备的过程

  1. 扫描整个系统空间,通过BDF获取PCI/PCIe设备的配置空间;
  2. 读取PCI/PCIe设备配置空间中的Vendor ID 和Device ID,确定是否为需要访问的设备;
  3. 找到PCI/PCIe设备后,获取其配置空间中的BAR,参照芯片手册,访问设备内部的寄存器和资源。

整个PCI枚举过程结束后,一个完整的资源分配的树建立完成。PCI设备的扫描是基于深度优先搜索算法的,下级分支最多的PCI桥将最先完成其子设备的扫描。

【本文主要参考UEFI Spec,部分内容来源作者罗冰的《UEFI编程实践》,编写粗糙,如有错误敬请谅解并欢迎指正】

UEFI——PCI/PCIe相关推荐

  1. 【UEFI】PCIE学习笔记

    本文是本人学习记录,不保证准确,如有错误请指出.如果侵犯请联系删除. PCIE一共支持256条bus(8个bit),32个device(5个bit),8个function(3个bit), 假设负载全满 ...

  2. KVM 介绍(4):I/O 设备直接分配和 SR-IOV [KVM PCI/PCIe Pass-Through SR-IOV]

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  3. linux禁用及启用pcie设备,KVM 介绍(4):I/O设备直接分配和 SRIOV [KVM PCI/PCIe PassThrough SRIOV]...

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  4. Linux(debian7)操作基础(三)之PCI/PCI-E设备配置空间

    ⑴ 概念 PCI和PCI Express,是计算机常使用的一种高速总线.操作系统中的PCI/PCI-E设备驱动以及操作系统内核,都需要访问PCI及PCI-E配置空间.PCI/PCI-E设备的正常运行, ...

  5. PCI/PCIe基础

    PCI/PCIe基础 处理器系统中的PCI PCI总线全称Peripheral Component Interconnect,它是处理器系统的一部分,属于局部总线,其主要功能是连接外部设备. PCI总 ...

  6. Remotely Controlling(远程控制) an Octeon through PCI, PCIe, or EJTAG

    Remotely Controlling(远程控制) an Octeon through PCI, PCIe, or EJTAG 1. Introduction In development, and ...

  7. 要实现八个串口怎么办(PCI/PCIE/USB方案)

    要同时使用8个互相独立的异步串口UART,可以采用PCI-Express转8串口.PCI转8串口,笔记本还可用USB转8串口.下面我们逐个来看: 一.PCIE(PCI-Express)转8串口 PCI ...

  8. KVM之I/O PCI/PCI-E设备直接分配和SR-IOV

    学习 KVM 的系列文章:  (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接 ...

  9. 嵌入式知识框架之六-接口与总线(SPI\I2C\ USB\PCI\PCI-E\SD\SDIO\以太网接口)

    接口是外设和主设备连接的方式/规则/协议的名称:XX总线是主设备连接某一类接口的名称 1.串口 串行数据接口标准(根据时间发展顺序介绍): RS-232:命名为EIA-232-E标准:通信距离短.速率 ...

  10. linux pci/pcie驱动

    /driver/pci/probe.c /arch/powerpc/kernel/pci_64.c 在pci驱动中pci调用pci_scan_device扫描每个设备的每个功能,当发现该功能存在时(通 ...

最新文章

  1. 给自己提个醒:关于document.getElementsByName无法获取非表单元素
  2. 转:[置顶] 从头到尾彻底理解KMP(2014年8月22日版)
  3. Promise-Polyfill源码解析(2)
  4. 【 .NET Core 3.0 】框架之二 || 后端项目搭建
  5. ASP.NET Core 2调用Azure云上的PowerBI报表展示
  6. tomee_一罐将其全部统治:Apache TomEE + Shrinkwrap == JavaEE引导
  7. 00004-括号匹配问题-牛客网-要考虑各种情况
  8. 牛客网--密码验证合格程序(Java)
  9. python默认数据转换_Python数据转换与答案
  10. html 计数器 样式,CSS3 计数器_html/css_WEB-ITnose
  11. bug引发的惨案,拼多多100元话费只需4毛钱,损失上千亿……
  12. How to install php evn on ubuntu
  13. windows7、10磁盘分区以及磁盘扩展(详细教程以及注意事项)
  14. 欢迎来到旁观,何必袖手的博客
  15. iOS GPUImage研究六:为视频添加图片水印
  16. css加载中,请稍后....demo示例(整理)
  17. 实现微信聊天界面的泡泡对话框效果(改进)
  18. 看看gps信息发布平台
  19. 看,那些在台风中挣扎的记者们
  20. 计算机专业 排名 国际,计算机专业世界大学排名ARWU

热门文章

  1. linux下使用ls命令时遇到的一个怪异现象
  2. 排列组合相关知识及组合数与杨辉三角形的关系(初学者篇)
  3. 翠贝卡VR 2017:把故事交到观众的手里
  4. 读coco数据集的代码接口了解segmentation的处理方法
  5. 计算机编码器的工作原理,优先级编码器74LS148的电路结构、工作原理及使用方法...
  6. vFORUM 2018,开启多云未来
  7. 腾讯云服务器硬盘价格,腾讯云服务器价格表(CPU/内存/带宽/云硬盘收费标准)...
  8. SAS中library是 excel引擎,LIBNAME STATEMENT
  9. 核磁为什么要做ROI分析?
  10. Mandriva 2007的下载地址以及安装中可能出现问题的解决办法