free website counter

PCI基本概念

1. PCI体系结构:

  • PCI为局部总线,系统总线的延伸,用于连接外设;
  • PCI Express总线:PCIe总线;PCI-to-PCI桥:PCI桥;PCI Express-to-PCI桥:PCIe桥;Host-to-PCI主桥:HOST桥,也称为PCI主桥或者PCI总线控制器;

2. HOST主桥(PCI控制器):

  • PCI总线与处理器地址空间隔离:PCI设备的独立地址空间,即PCI总线地址空间,通过HOST主桥和处理器地址空间隔离,处理器通过HOST主桥访问PCI设备,PCI设备通过HOST主桥访问主存储器;
  • HOST主桥的多极缓冲,确保处理器总线和PCI总线工作在各自的时钟频率不干扰,设备和处理器共享主存储器资源;
  • HOST主桥的一个重要作用就是对存储器地址与PCI总线地址进行转换;PCI总线域地址空间和存储器域地址空间是不一样的;
  • 通过HOST主桥直接推出的PCI总线,可以通过PCI桥扩展出一系列PCI总线,HOST主桥为根节点,一棵PCI总线树,最多挂载256个PCI设备;
  • 每个PCI设备都有独立的配置空间,含有设备在PCI总线中使用的基地址,系统软件可以动态配置,保证每个PCI设备的物理地址不同;
  • PCI总线可以使用MSI中断机制,通过存储器读写总线事务传递中断请求;
  • HOST主桥与主存储器在处理器系统的同一级总线上,PCI设备可以方便通过HOST主桥访问主存储器,即DMA操作;
  • HOST主桥还完成处理器和设备之前的数据交换,即处理器访问PCI设备地址空间和PCI设备使用DMA机制访问主存储器;
  • 由于PCI总线是一个以HOST主桥为根的树形主从架构,不易于实现多处理器系统之间的对等互联;
  • HOST主桥中设置了许多寄存器,HOST处理器可以通过操作这些寄存器管理PCI设备,可以通过寄存器或者存储器映像寻址方式访问PCI设备寄存器空间;

3. PCI总线的存储器读写事务:

  • 地址译码方式进行数据传递,即采用地址信号;
  • ID译码方式进行配置信息传递,使用PCI设备的ID号,包括Bus Number、Device Number、Founction Number和Register Number;
  • PCI设备在系统软件初始化配置空间后,设备在PCI总线树上有一个独立PCI总线地址空间,即BAR寄存器描述的空间,才能由其他设备访问;
  • HOST处理器使用PCI总线的存储器读写事务和I/O读写事务对PCI设备的BAR空间进行数据读写,BAR空间可以用存储器或者I/O译码方式;
  • PCI设备对主存储器进行读写,即DMA操作,读写操作结束后伴随着中断产生,可以使用MSI机制提交中断请求;
  • 数据传送方式:Posted-数据请求通过PCI总线之后,将逐级释放总线资源,因此PCI总线利用率较高;Non-Posted-请求通过PCI总线时,并不及时释放总线资源,必须在当前总线事务结束后,才能释放;

4. HOST设备访问PCI设备:

  • HOST处理器对PCI设备的数据访问:发起存储器和I/O读写请求;对PC设备进行配置读写;
  • PCI设备配置空间,共6个BAR寄存器,每一个BAR寄存器都与PCI设备使用的一组PCI总线地址空间对应,BAR寄存器记录这组地址空间基地址;BAR寄存器对应的PCI总线空间为BAR空间,可以存放I/O地址空间,或存储器地址空间;存放的是“PCI总线域”而不是“存储器域”的物理地址;
  • x86处理器中,存储器域的I/O地址和PCI总线域的I/O地址相同,可以通过访问存储器域的I/O地址空间进行PCI设备的I/O地址空间访问;
  • 存储器读写事务:HOST处理器初始化时,先将PCI设备使用的BAR空间映射到“存储器域”的地址空间,处理器通过存储器的读写指令访问“存储器域”的地址空间,HOST主桥将读写请求转换为PCI总线的存储器读写事务,发送给目标设备;
  • 需要再次强调的是:处理器能够直接使用的是存储器域的地址;PCI设备能够直接使用的是PCI总线域的地址;许多处理器中,存储器地址与PCI总线地址完全相等,但含义完全不同;

5. PCI设备读写主存储器:

  • PCI设备与主存储器直接进行数据交换(DMA)时,需要获得数据传送的目的地址和传送大小;支持DMA传递的PCI设备可以在BAR空间设置两个寄存器,分别保存目的地址和传送大小,这两个寄存器也是PCI设备DMA控制器的组成部件;
  • PCI设备进行DMA操作,目的地址为PCI总线域的物理地址,HOST主桥负责其到存储器域地址的转换;HOST主桥需要合理设置,将存储器地址空间映射到PCI总线,PCI设备才能对这段存储器空间进行DMA操作;
  • 许多处理器允许PCI设备访问所有存储器域地址空间,但是有些处理器设置PCI设备所能访问的存储器地址空间;只有在PCI总线域中有映像的存储器空间才能被PCI设备访问;

6. 存储器域与PCI总线域:

  • CPU访问主存储器时,将读写指令放入读写指令缓冲中,然后发送到DRAM控制器或者HOST主桥,再转换为DRAM或者PCI总线地址,分别进入DRAM域或者PCI总线域,再访问相应地址空间;
  • DRAM域地址空间指DRAM控制器可以访问的地址空间集合,目前处理器系统的DRAM一般由DDR-SDRAM组成,也称为主存储器;
  • 多数时候,DRAM域空间是CPU区域空间的一部分,也有例外:显卡控制器可能借用一部分主存储器空间,被借用的空间不能被CPU访问,只能被显卡控制器通过DRAM控制器访问,这段空间不属于CPU域,而是外部设备域;
  • 存储器域包括CPU内部通用寄存器、存储器映像寻址的寄存器、主存储器空间、外部设备空间;x86,外部设备空间与PCI总线域地址空间等效,因为使用PCI总线统一管理全部外部设备;
  • 处理器系统中,CPU能访问的PCI总线地址一定在存储器域中有地址映射,而PCI设备能够访问的存储器域地址也一定在PCI总线域有映射;
  • PCI设备使用的地址空间保存在各自的PCI配置寄存器中(BAR),这些PCI总线地址空间需要在初始化时映射成存储器域的地址空间,之后处理器才能访问,x86处理器中,HOST主桥的硬件逻辑中存在这个地址转换的概念;而PowerPC处理器通过独立的寄存器保存这个地址映射规则;

7. PCI设备配置空间访问机制:

  • PCI总线规定了配置空间的访问事务,使用ID号进行寻址,ID号由总线号(Bus Number)、设备号(Device Number)、功能号(Function)组成;
  • 总线号在HOST主桥遍历PCI总线树时确定,总线号由系统软件决定;系统软件使用DFS算法扫描PCI总线树,并编号;与主桥直接相连的PCI总线为PCI总线0;与HOST主桥连接的PCI总线都为0,当有多个HOST主桥时,存在多个编号0的总线,但属于不同PCI总线域;
  • PCI总线的设备号由PCI设备的IDSEL信号与PCI总线地址线的连接关系确定;
  • 功能号与PCI设备的设计相关,最多可以有8个功能设备,每个功能设备有自己的配置空间,但绝大多数设备只有一个功能设备;
  • x86使用南北桥结构连接CPU和PCI设备,北桥连接快速设备,如显卡、内存,并推出PCI总线,HOST主桥位于北桥中;
  • x86处理器定义了两个I/O端口寄存器,分别为CONFIG_ADDRESS和CONFIG_DATA寄存器,地址为0xCF8和0xCFC,x86处理器使用这两个I/O端口访问PCI设备的配置空间,其中CONFIG_ADDRESS存放PCI设备的ID号,CONFIG_DATA存放进行配置读写的数据;
  • CONFIG_ADDRESS寄存器各个字段: Enable位:第31位,为1时,对CONFIG_DATA寄存器进行读写将引发PCI总线的配置周期; Bus Number:第23~16位,记录PCI设备的总线号; Device Number:第15~11位,记录PCI设备的设备号; Function Number:第10~8位,记录PCI设备的功能号; Register Number:第7~2位,记录PCI设备的寄存器号;
  • x86处理器对CONFIG_DATA寄存器进行I/O读写访问,且CONFIG_DATA的Enable位为1时,HOST主桥将这个I/O读写访问转换为PCI配置读写总线事务,发到PCI总线,PCI总线根据保存在CONFIG_DATA寄存器的ID号,将PCI配置读写请求发送到指定PCI设备的指定配置寄存器;

8. PCI桥:

  • PCI桥的配置空间对其下PCI设备进行管理,系统软件不需要专门的驱动程序设置PCI桥,因此PCI桥称为透明桥;
  • 有一种非透明桥,在PCI总线挂接另一个处理器系统时有用,即连接两个不同的PCI总线域(看起来当使用PCIe连接不同tail时需要使用非透明桥)
  • 通过PCI桥连接的PCI总线属于同一个总线域,不需要进行地址转换;PCI桥可以扩展出新的PCI总线,但不能扩展PCI总线域,如果系统使用32位PCI总线地址,则系统的PCI总线域地址空间为4GB,总线域上的所有设备共享4GB的空间;

9. PCI设备的配置空间:

  • 具体处理器应用时,PCI设备常将PCI配置信息存放在EEPROM中,PCI设备上电初始化时,将其读到PCI设备配置空间作为初始值,该过程由硬件逻辑完成(目测我们的芯片不采用这种方式,而是软件进行初始化);
  • PCI设备的配置空间包含很多寄存器,决定了该设备在PCI总线中的使用方法,即常见的那个寄存器图(包括Device ID和Vender ID等);PCI Agent设备配置空间包含的寄存器如下;
  • Device ID和Vender ID寄存器:由PCISIG组织分配,只读,其中Vender ID代表PCI设备生产厂商,Device ID代表厂商生产的具体设备;设备的识别,对于PCIe软核来说,完全由PCIe控制器来决定;
  • Revision ID和Class Code寄存器:只读,前者记载PCI设备的版本号,即Device ID的扩展;
  • Header Type寄存器:只读,8位组成,第7位为1表示该设备是多功能设备,为0表示为单功能设备;第6~0位表示当前配置空间类型,为0表示PCI Agent设备的配置空间,系统软件需要使用其区分不容类型的PCI配置空间,必须与设备实际情况对应(由此可见这些由硬件写入);
  • Cache Line Size寄存器:记录HOST处理器使用的Cache行长度,该寄存器由系统软件设置,但PCI设备的运行过程中,只有硬件逻辑使用该寄存器;对于PCIe设备,该寄存器的值无意义,PCIe的报文中含有一次数据传送的大小,设备可以使用来判断数据区域与Cache的对应关系;
  • Subsystem ID和Subsystem Vender ID:也是记录PCI设备的生产厂商和设备名称,但与Vender ID和Device ID略有不同;
  • Expansion ROM base address:有些PCI设备在处理器还没运行操作系统之前,需要完成基本初始化操作,为了预先执行的功能,PCI设备需要提供一段ROM程序来初始化设备,该寄存器记录ROM程序的基地址;
  • Capabilities Pointer寄存器:PCIe中必须支持该寄存器,存放Capabilities寄存器组的基地址; *. Interrupt Line寄存器:系统软件对PCI设备配置时写入,记录当前PCI设备的中断向量号,设备驱动通过该寄存器,判断PCI设备使用处理器系统的哪个中断向量号; *. Interrupt Pin寄存器:保存PCI设备的中断引脚,如果不使用中断引脚,则必须为0; *. Command寄存器:PCI设备的命令寄存器,寄存器初始化时,为0,此时不能接受任何存储器或者I/O请求;设备驱动程序需要通过pci_enable_device函数,使能该寄存器的I/O和Memory Space位之后,才能访问该设备的存储器或者I/O地址空间; *. Status寄存器:绝大多数位都是只读位,保持PCI设备的状态; *. Latency Timer寄存器:PCIe设备不需要使用,必须设置为0; *. Base Address Register0~5:即BAR寄存器;

10. BAR寄存器:

  • Base Address Register0~5:即BAR寄存器,保存PCI设备使用的地址空间的基地址,保存设备在PCI总线域中的地址,每个设备最多可以有6个基址空间;
  • PCI设备复位之后,存放PCI设备需要使用的基地址空间大小,该空间是I /O空间还是存储器空间等信息;
  • 软件对PCI总线进行配置时,首先获得BAR寄存器中的初始化信息,之后根据处理器系统的配置,将合理的基地址写入相应的BAR寄存器中;系统软件还可以使用该寄存器,获得PCI设备使用的BAR空间的长度,通过向BAR寄存器写入0xFFFF-FFFF,之后再读取该寄存器实现;
  • 处理器访问PCI设备的BAR空间时,需要使用BAR寄存器提供的基地址;但处理器使用存储器域的地址,而BAR寄存器存放PCI总线域的地址,因此处理器系统并不能直接使用“BAR寄存器+偏移”的方式访问PCI设备的寄存器空间,而需要将PCI总线域的地址转换为存储器域的地址;
  • 即使x86处理器系统使能了IOMMU,这两个地址也并不一定相等,因此处理器系统直接使用这个PCI总线域的物理地址,并不能确保访问PCI设备BAR空间的正确性;除此之外在Linux系统中,ioremap函数的输入参数为存储器域的物理地址,而不能使用PCI总线域的物理地址;
  • 而在pci_dev -> resource[bar].start参数中保存的地址已经经过PCI总线域到存储器域的地址转换,因此在编写Linux系统的设备驱动程序时,需要使用pci_dev -> resource[bar].start参数中的物理地址,然后再经过ioremap函数将物理地址转换为“存储器域”的虚拟地址,再访问;
Published 28 November 2014
分享按钮