PCI总线
注:本博客内容主要摘自<PCI Express 体系结构导读>
一、PCI总线作用
PCI总线是PC机广泛使用的外围高速总线接口,显卡、网卡、声卡等高速设备都通过PCI总线接到CPU。
二、PCI总线组成
2.1 x86架构的PCI总线结构
x86架构采用南北桥结构,北桥集成了AGP控制器可以接显卡,集成了ddr控制器可以接内存条,集成了PCI总线控制器(HOST主桥)可以接PCI设备。南桥主要接一些低速设备,如USB、LAN、ATA等。如下所示:
x86架构的PCI总线结构如下所示:
2.2 SOC架构的PCI总线结构
而在soc架构的芯片中,HOST主桥则集成在soc中,soc中包含有PCI总线控制器,这个控制器就可以认为是HOST主桥。下图是freescale的PowerPC处理器,型号为MPC8584,采用soc架构,如下所示:
图2.2 MPC8548处理器拓扑图
2.3PCI设备
PCI总线有三种类型设备,分别是PCI主设备、PCI从设备、PCI桥设备。PCI从设备只能被动接受来自主桥和其它PCI从设备的读写请求,而PIC主设备可以通过总线仲裁获得总线使用权。PCI设备即可作为主设备也可作为从设备,在PCI总线中的主设备和从设备统称为PCI Agent,如声卡、网卡都输入PCI Agent。PCI桥设备是特殊的PCI设备,用来扩展PCI总线,PCI桥存在使得系统大规模互联称为可能。
PCI桥使得PCI总线有极大的扩展性,一条PCI总线能连接的PCI设备是有数量限制的, 如果需要连接更多的PCI设备,就需要用PCI桥来扩展PCI总线。每一个PCI桥都可以扩展出一条PCI总线,图2.3所示:
图2.3 使用PCI桥扩展PCI总线
2.4 HOST主桥
在PCI体系中,有两类桥,一类是PCI主桥,另外一类是PCI桥设备。HOST主桥的基本功能是完成存储器域到pci域的转换和管理pci设备的配置空间。不同处理器对HOST主桥的处理并不相同,x86体系中,HOST主桥集成在北桥中,而soc体系的芯片将HOST主桥集成在soc中。
三、PCI总线的总线号和设备号分配
PCI总线使用地址译码的方式进行数据传递,采用ID译码的方式进行配置信息传递。每一个PCI设备都有一个BAR(基地址)寄存器,系统通过BAR+偏移地址的方式访问PCI设备的存储空间。ID译码方式使用PCI设备的ID号,ID号=总线号+设备号+功能号。系统首先需要在初始化时分配PCI总线的总线号、设备号,这样才能通过ID号访问PCI设备的配置空间,配置PCI设备。PCI总线初始化指的是系统上电初始化PCI总线时分配PCI总线号、设备号、配置PCI设备Base Address寄存器等初始化操作。
3.1 PCI Agent 和PCI桥的配置空间
在系统上的初始化时,cpu会通过HOST主桥去配置PCI Agent和PCI桥的配置寄存器,PCI 设备的配置寄存器的初始值通常存储在PCI设备的E2PROM中,PCI设备上的后会自动加载E2PROM中的信息去配置好相关寄存器。
1、PCI Agent的配置寄存器
PCI Agent的配置寄存器如下所示:
(1)Device ID(r)和Vendor ID(r):其值有PCISIG组织分配。Vendor ID代表PCI设备的厂商,Device ID代表这个厂商生产具体设备的标号
(2)Revision ID(r):表示PCI设备版本号
(3)Class ID(r):用于将PIC设备分类,有三个字段组成,分别为Base Class Code、Sub Class Code、Inerface。Base Class Code代表设备类型,如显卡、网卡、PCI桥等。Sub Class Code则对这些设备进行进一步细分。Inerface表示编程接口。如一个正“正向译码”的桥设备Class ID这三个字段分别为0x06、0x04、0x01。
(4)Command (rw)寄存器:该寄存器是PCI设备的命令寄存器
(5)Status(rw)寄存器:该寄存器是PCI设备的状态寄存器
(6)Header Type(r)寄存器:第7位为1表示PCI设备是多功能设备,为0表示单功能设备。0~6位为配置空间类型,0表示PCI Agent配置空间,1表示PCI 桥配置空间。软件系统用该寄存器区分不同配置空间。
(7)Base Address(rw)寄存器:PCI设备在PCI总线域的基地址寄存,处理器在访问PCI设备时需要通过“Base Address+偏移地址访问”。这个寄存器值是有处理器在初始化PCI总线时分配给PCI设备的。
注:其它寄存说明可参考<PCI Express 体系结构导读>
2、PCI桥的配置寄存器
PCI桥配置寄存器如下所示:
Device ID(r)、Vendor ID(r)、Revision ID(r)、Class ID(r)、Command (rw)、Status(rw)、Header Type(r)、Base Address(rw)这些寄存器功能和PCI Agent一样。
(1)Subordinate Bus Number(rw)、Secondary Bus Number(rw)和Primary Bus Number(rw)寄存器:Subordinate Bus Number寄存器存放当前PCI 桥下面编号最大的PCI 总线号,Secondary Bus Number寄存存放当前PCI 桥下面编号最小的PCI 总线号,PCI桥能管理的总线号在Secondary Bus Number~Subordinate Bus Number之间,Primary Bus Number寄存器存放PCI桥上游的PIC总线号。这些寄存器都有系统在初始化时遍历总线设置。
(2)Memory Base(rw)和Memory Limit(rw)寄存器:这两个寄存器存放该PCI桥管理的PCI Agent设备的起始及地址和空间大小
3.2 PCI总线BUS号初始化
系统在上电初始化时系统会使用DFS算法遍历PCI总线,分配总线号,即初始化PCI桥设备的Subordinate Bus Number(rw)、Secondary Bus Number(rw)和Primary Bus Number(rw)寄存器。。具体过程见<PCI Express 体系结构导读>2.4.3章节。总线号分配完成后如下所示:
3.3 PCI总线Device号分配
一条PCI总线上有各种PCI设备,每一个PCI设备在总线上有唯一一个设备号,系统通过“总线号+设备号”定位到需要访问的设备。PCI寄存器中并没有“设备号”寄存器,HOST主桥通过IDSEL引脚选择PCI设备,IDSEL相当于PCI设备的片选信号。HOST主桥并没有独立的片选信号引脚去连接每个PCI设备的片选信号,而是将PIC设备的IDSEL信号与AD[31:11]信号相连。通常将AD[31:16]与片选信号相连接。比如主板上有5个PIC卡槽,可以接5个PIC设备,第一个PIC设备的IDSEL信号连接到AD16,表示设备0,HOST主桥只要拉高AD16就选中了设备0。第二个PIC设备的IDSEL信号连接到AD17,表示设备1,HOST主桥只要拉高AD11就选中了设备1,依次类推。由此可将,PIC总线的Device是有硬件连接决定的,即IDSEL信号与AD[31:11]信号的连接情况。
四、PCI总线的配置空间访问
PCI总线的配置空间是3.2节介绍的PCI设备的配置寄存器。PCI总线通过ID寻址的方式访问PCI设备的配置空间。ID号有总线号、设备号和功能号组成,总线号和设备号的分配见3.2和3.3节。功能号与PCI设备的体设计相关。系统访问PCI设备的寄存器是通过ID+寄存器号完成的。PCI总线定义了Type 00h和Type 01h这两种配置请求,因为Type 00h请求用来访问与HOST 主桥或PCI桥直接相连的PCI Agent,Type 01h请求用来访问隔着PCI 桥的PCI Agent。Type 01通过PCI桥时,最终会转换为Type 00h请求。如图2.3所示,PCI主桥可以使用Type 00h配置请求访问PCI设备01,而使用Type 01h请求通过PCI桥1、2或则3转换为Type 00h配置请求后,访问PCI总线树上的PCI设备11、21、22、31或32.
x86处理器用CONFIG_ADDRESS和CONFIG_DAT这两个寄存器访问pci总线的配置空间。
图4.1 CONFIG_ADDRESS寄存器
但Enable位为1时,HOST主桥将对这个寄存器的读写访问转换为PCI配置读写总线事务。当把PCI设备的ID号写入到CONFIG_ADDRESS寄存器,且使能Enable位为1时,这个寄存器的内容将复制到PCI的AD[31:0]总线上,如图4.2和4.3所示分别为Type 01h和Type 00h的配置请求;
图4.2 CONFIG_ADDRESS寄存器与Type 01h配置请求
图4.3 CONFIG_ADDRESS寄存器与Type 00h配置请求
从图总可以看出,Type 01h配请求把CONFIG_ADDRESS寄存器的第0位设置为1,表示Type 01h请求,然后把寄存器中的内容全部复制到AD[31:0]中。Type 00h请求把CONFIG_ADDRESS寄存器的第0位设置为0,表示Type 00h请求,Bus Number并没有复制到AD[31:0]中,因为Type 00h请求是访问与HOST 主桥或PCI桥直接相连的PCI Agent,所以不需要总线号。AD[31:11]与Device Number的字段有关,AD[31:11]有且一位为1,为1的那位即为PCI 设备的片选信号,详情见3.3节。
五、PCI总线的数据交换
PCI处理器和PCI Agent以及PCI Agent和PCI Agent之间可以使用存储器读写和I/O读写事务进行数据交换。PCI 桥并不之间参与数据交换,而是转发来之HOST 主桥或则PCI Agent设备的数据。PCI总线通过地址寻址访问PCI 设备的存储空间,每个PCI设备都有一个基地址寄存器Base Address,PCI总线通过“BAR+偏移地址”的形式来访问PIC设备的存储空间。
5.1 存储器域与PCI总线域
HOST主桥的主要作用就是隔离存储器域和PCI总线域,实现存储器域和PIC总线域相互转换。存储器域指的是cpu能直接访问到的空间,在x86架构中南桥和北桥都能被cpu直接访问,都是属于存储器。在soc架构中,ddr控制器,pci控制器、usb控制器等这些外围设备也能被cpu直接访问,也属于存储器域。PIC总线域只有PCI Agent、PCI桥和HOST主桥能直接访问,cpu要想访问PCI总线域需要通过HOST主桥完成存储器域到PCI域的地址转换,PCI设备要想访问存储器域也要通过HOST主桥将PCI域地址转成存储器域地址。
5.2 存储器地址和PCI总线地址的转换
假设所有PCI Agent只使用BAR0寄存器,每个PCI Agent有16MB的存储空间(0x0100-0000),而且PCI桥不占用PCI总线的地址空间。一共有8个PCI Agent设备,总共需要占用8*16=128MB的地址空间,在PCI总线上分配的空间地址范围为0x7000-0000~0x77FF-FFFF。系统不能直接访问PIC 总线域的空间,需要进行地址映射,假设在存储器域中将0xF000-0000~0xF7FF-FFFF(128MB)这都地址空间映射到了PIC总线的0x7000-0000~0x77FF-FFFF地址空间。但处理器访问0xF000-0000~0xF7FF-FFFF这段空间时,HOST主桥会认领这个存储器访问,并将该存储器访问使用的物理地址转换为0x7000-0000~0x77FF-FFFF这段地址。
但PCI设备使用DMA访问存储器地址空间时,处理器同样需要将存储器域的地址映射到PIC总线域的地址。假设在一个处理器系统中,DDR为2GB,器存储器地址范围为0x0000-0000~0x7FFF-FFFF,这段地址将映射到PCI总线的0x8000-0000~0xFFFF-FFFF。PCI设备进行DMA传输时,必须使用0x8000-0000~0xFFFF-FFFF这段地址,HOST主桥才能认领这个总线事务,并将这个地址转换为存储器域地址,并与0x0000-0000~0x7FFF-FFFF这段空间进行数据交换。
图5.1 存储器域PCI总线域的地址映射关系
5.3 PCI Agent BAR寄存器和PCI桥Base、Limit寄存器的初始化
系统在访问PCI设备的存储空间之前,需要对PCI Agent BAR寄存器和PCI桥Base、LImit寄存器进行初始化。系统使用DFS算法遍历PCI总线时,完成对这些寄存器的初始化。
图5.2 BAR寄存器的初始化
5.4 处理器向PCI设备写数据
下面以图5.2为例,说明处理器向PCI 设备11写数据的过程。PCI设备11的PCI总线地址范围是0x7300-0000~0x73FF-FFFF,这段地址在存储器域的对应地址范围是0xF300-000~0xF3FF-FFFF。下面假设处理器要向PCI设备11的0x7300-0008地址写数据。
(1)PIC域的0x7300-0008地址对应的处理器域地址是0xF300-0008,因为处理器不能直接访问PCI域,所以处理器访问的是0xF300-0008这个地址,当处理器访问这个地址时,HOST主桥会认领这个访问请求,因为这个地址映射到了PCI总线域。
(2)PCI主桥将0xF300-0008这个存储器域地址转换为0x7300-0008的PCI域地址,并向PCI总线0发起一次写访问。
(3)0x7300-0008这个地址在PCI桥1的Memory Base寄存器值和Memory Limit寄存器值之间,PCI桥1就认为这个地址在它的管理范围之内,所以就认领了这个任务,并向PCI总线1转发了这次任务。
(4)0x7300-0008这个地址刚在是PCI总线1的PCI设备11的地址空间,PCI设备11就接受了这次写访问请求。
5.5 PCI设备的DMA操作
下面以PCI设备11向存储器域0x1000-0000~0x1000-FFFF写数据为例说明PCI设备向处理器发送数据工程
(1)因为PCI设备不能直接访问0x1000-0000~0x1000-FFFF这段存储器域空间,它只能通过访问映射到这段存储器域空间的0x9000-0000~0x9000-FFFF PCI域空间进行访问。
(2)PCI设备11向PCI总线1发送存储器写请求事务,PCI桥1接受到这个事务请求后,发现自己不能处理这个事务,就将这个事务请求向上游总线转发,也就是PCI总线0.
(3)HOST主桥发现0x9000-0000~0x9000-FFFF这段地址空间已经映射到了存储器域的空间,已是将这个PCI域总线地址空间转换为0x1000-0000~0x1000-FFFF存储器域地址空间。
(4)存器控制器将从HOST主桥接受数据,并将写入存储器。