pcie基础知识
1、物理链路
2、PCIe数据通信方式
3、链路训练
4、总线拓扑结构
5、PCIe设备地址空间管理
6、设备枚举
一、物理链路
区别于PCI的共享总线方式,PCIe链路使用“端到端的数据传送方式”,发送端和接收端中都含有TX(发送逻辑)和RX(接受逻辑);TX是由TX(+)和TX(-)组成的差分信号,RX是由RX(+)和RX(-)组成的另一组差分信号,这两组差分信号构成一个数据通路(Lane),又叫做x1宽度的PCIe链路;PCIe链路可以由多条Lane组成(x1、x2、x4...x32),Lane越多,速率越高;
PCIe总线物理链路间的数据传送使用基于时钟的同步传送机制,但是物理链路上并没有时钟线,PCIe总线的接收端含有时钟恢复模块CDR,CDR从接收报文中提取接收时钟,从而进行同步数据传递,PCIe设备进行链路训练时将完成时钟提取工作。
PCIe版本越高,总线速率越快,主要区别在于编码方式不同;
二、PCIe数据通信方式
类似以太网数据包通信方式,PCIe数据传输协议也使用分层模型;分为事务层、数据链路层以及物理层;
事务层:
事务层是PCIe总线层次的最高层,该层接收PCIe设备核心层的数据请求,转换为PCIe总线事务,这些总线事务使用的数据包叫做TLP,包括存储器读写、I/O读写、配置读写、Message、原子操作等总线事务,总线事务通过TLP头部中的字段区分;不同的事务使用的路由方式不同,比如配置空间的读写事务采用ID路由方式、BAR空间的读写事务采用地址路由方式、存储器读写事务也使用地址路由方式、但是MSI/MSI-x中断消息报文使用隐式路由方式;不同事务传送方式也不同,存储器写TLP使用Posted方式进行传送、其他总线事务使用Non-Posted方式(发送后需要等待对端回应,并且等待期间一直占用总线使用权);可以通过设置TLP头部的相关字段改变TLP的相关功能,比如与QOS相关的,可以设置TC字段使用不同优先级的TC传送报文,通过设置Attr字段决定是否进行Cache一致性处理,如果为0,那么需要硬件支持进行Cache一致性处理,如果为1,那么硬件不参与Cache一致性处理,就需要软件保证Cache一致性;
数据链路层:
数据链路层处于事务层和物理层之间,数据链路层主要功能是保证来自事务层的TLP在PCIe链路中的正确传递,为此数据链路层定义了一系列数据链路层报文,即DLLP;数据链路层使用ACK/NAK协议发送和接收TLP,保证数据报文正确传递;数据链路层通过物理层监控PCIe链路的状态,并维护数据链路层的“控制与管理状态机”DLCMSM,当状态机变化时,向事务层通知PCIe的链路状态;
物理层:
物理层由物理层逻辑模块和物理层电气模块组成,包括数据编码、链路训练等内容;
三、链路训练
PCIe总线进行链路训练的主要目的是初始化PCIe链路的物理层、端口配置信息、相应的链路状态,并了解链路对端的拓扑结构;链路训练由芯片内部逻辑实现,软件无法干预,链路训练会进行速率协商,确定两端所能支持的最高速率,同步时钟也是在链路训练的报文中恢复出来的,链路训练完成后,PCIe设备才可正常通信;
设备从低功耗返回到正常工作模式,或者PCIe链路出现某些错误时,PCIe链路也需要重新进行训练;
PCIe总线在进行链路训练时,使用LTSSM状态机标识设备状态;
共有11个状态,常用的状态是Detect、Polling、Configuration和L0;
Detect状态:LTSSM的初始状态,当PCIe链路被复位或者数据链路层通过填写某些寄存器后,LTSSM将进入该状态;
Polling状态:PCIe链路处于该状态时,将进行Loopback测试,确定当前使用的PCIe链路可以正常工作;
Configuration状态:当PCIe进入该状态时,将确定PCIe链路的宽度、Link Number、Lane reversal、Polarity inversion和Lane-to-Lane的延时;
L0状态:PCIe链路的正常工作状态。
四、总线拓扑结构
如上图所示,PCIe总线使用树型拓扑结构组织PCIe总线上的所有设备;
以RC(Root Complex)作为树根,在现代处理器系统中,RC的设计异常复杂,并且不同处理器系统的RC设计并不相同,比如x86处理器的RC里面集成了HOST主桥、多个桥设备、存储器控制器等一系列与外部设备有关的接口;虽然各处理器的RC设计不同,但是就PCIe的功能来说是一样的,用于连接PCIe总线和系统总线,主要完成两个功能:存储器域到PCIe总线域的地址转换、物理信号的转换;
基于PCIe串行差分物理链路的特点,一条PCIe链路只允许两个PCIe设备通信,因此当需要扩展链路时,需要使用switch,如下图所示,一个switch由一个上游桥设备和多个下游桥设备构成,每个桥设备出一个外接端口,可以扩展出一条PCIe链路;RC内部也有类似的结构,包括一个主桥和多个桥设备,RC中的桥设备又叫做RP;
EP是各类PCIe设备,是树型拓扑结构的叶子节点,无法用于拓展PCIe总线。
五、PCIe设备地址空间管理
PCIe设备和系统总线是使用HOST主桥隔离开的,PCIe设备所在的空间叫PCI域地址空间,CPU能直接通过系统总线访问的空间叫存储器域地址空间,CPU需要通过HOST主桥下发PCIe总线事务报文去访问PCIe设备;PCIe设备可操作空间包括配置空间和BAR空间;PCIe设备数据访问主要包括:读写PCIe设备配置空间、读写PCIe设备BAR空间、PCIe设备使用DMA读写主存储器空间;
PCIe和PCI一样有一段64字节的基本配置空间,地址访问是0x00~0x3F,还扩展了0x40~0xFF这段配置空间,主要用于存放MSI或者MSI-X中断机制和电源管理相关的Capability结构,0x00~0xFF这段配置空间的访问是CPU通过读写HOST主桥里面的CONFIG_ADDRESS和CONFIG_DATA寄存器,让HOST主桥下发配置读写请求报文去访问的,这个报文使用ID路由方式;PCIe设备还支持0x100~0xFFF这段扩展配置空间,最大为4KB用于存放PCIe设备独有的一些Capability结构,这段空间使用ECAM方式访问,ECAM方式就是将这段空间映射到存储器空间,和BAR空间一样,通过读写存储器空间的地址让HOST主桥下发报文去访问,这些报文使用地址路由方式;
桥设备配置空间:
EP设备配置空间:
对于BAR空间,BAR空间的地址在存储器空间有与之对应的物理地址,当CPU读写这段物理地址时,HOST主桥就会接收这个读写请求,然后下发PCIe总线事务去访问PCIe设备的BAR空间,这些报文使用地址路由方式;不同的处理器系统,BAR空间和存储器空间地址转换方式不一致:
比如x86处理器,BAR空间的地址和存储器域空间的地址是一样的,也就是CPU直接读写BAR空间的地址就可以触发HOST下发PCIe总线事务;
PowerPC处理器使用Outbound寄存器组实现存储器域到PCI总线域的转换,使用Inbound寄存器组实现PCI总线域到存储器域的转换;
Outbound寄存器组:PORTARn和PORTEARn寄存器中保存当前Outbound窗口在PCI域中的64位地址空间的基地址,POWBARn寄存器保存当前Outbound窗口在存储器域中的36位地址空间的基地址,POWARn寄存器描述Outbound窗口的属性(包括窗口使能、地址空间大小等);
Inbound寄存器组:PITARn寄存器保存当前Inbound窗口在存储器域中的36位地址空间的基地址,PIWBARn和PIWBEARn寄存器保存当前Inbound窗口在PCI总线域中的64位地址空间的基地址,PIWARn寄存器描述当前Inbound窗口的属性(包括窗口使能、地址空间大小等);
六、设备枚举
PCIe总线树中各个总线、桥设备、EP设备(里面可以有多个function)都有唯一的标识符,这个标识符就是BDF(BUS号、设备号、功能号);其中BUS号是在设备枚举过程中由软件分配的,设备号和功能号是硬件决定的;
设备枚举是纯软件流程,linux内核已经实现,这个过程会做很多工作;比如,枚举过程会按照深度优先的搜索方式分配总线号、配置桥设备和EP设备,然后对每个EP设备会创建pci_dev设备结构体,这样后续对应的pci_driver驱动注册时,通过Device ID匹配到pci_dev就会调用probe函数进行初始化工作;对于EP设备,在枚举时会给EP设备分配BAR空间,并将BAR空间的基地址写入配置空间寄存器Base Address Registers;对于桥设备,会将当前桥所在的BUS号写入Primary Bus Number寄存器,将桥下挂链路BUS号写入Secondary Bus Number寄存器,将桥下挂链路最大的BUS号写入Subordinate BUS Number寄存器,并且将桥下挂设备所需的BAR空间基地址和大小写入Memory Base和Memory Limit寄存器。