【一】PCIe基础知识-程序员宅基地

技术标签: linux  lspci  PCIe  BusClass  

一、PCIe概述

1、PCIe速度

  1. PCI采用总线共享式通讯方式;PCIe采用点到点(Endpoint to Endpoint)通讯方式,互为接收端和发送端,全双工,基于数据包传输;
  2. 两个PCIe设备之间的连接称作一条链路(link), 一条链路可以包含多个通道(每对接收和发送对称作一个通道(lane)),可增加通道个数来满足更高的带宽要求。

物理底层采用差分信号(PCI链路采用并行总线,而PCIe链路采用串行总线),一条Lane中有两组差分信号,共四根信号线,而PCIe Link可以由多条Lane组成,可以支持1、2、4、8、12、16、32条;

版本 编码方案 传输速率 X1 吞吐量 X4 吞吐量 X8 吞吐量 X16 吞吐量
1.0 8b/10b 2.5GT/s 250MB/s 1GB/s 2GB/s 4GB/s
2.0 8b/10b 5GT/s 500MB/s 2GB/s 4GB/s 8GB/s
3.0 128b/130b 8GT/s 984.6MB/s 3.938GB/s 7.877GB/s 15.754GB/s
4.0 128b/130b 16GT/s 1.969GB/s 7.877GB/s 15.754GB/s 31.508GB/s
5.0 128b/130b 32 or 25GT/s 3.9 or 3.08GB/s 15.8 or 12.3GB/s 31.5 or 24.6GB/s 63.0 or 49.2GB/s

PCIe吞吐量计算方法: 吞吐量 = 传输速率 * 编码方案

  • PCIe1.0传输速率为2.5Gb/s,物理层使用8/10编码(8Bit数据在物理线路上需要10比特传输),PCIe1.0 x 1的带宽 =2.5Gb/s * 8/10bit = 2Gb/s = 2000Mb/s = 250MB/s
  • PCIe2.0传输速率为5Gb/s,物理层使用8/10编码, PCIe2.0 x 1的带宽 = 5Gb/s *
    8/10bit = 4Gb/s = 4000Mb/s = 500MB/s
  • PCIe3.0传输速率为8Gb/s,物理层使用128/130编码进行数据传输,PCIe3.0 x 1的带宽 = 8Gb/s * 128/130bit7.8769Gb/s = 7876.9Mb/s = 984.6MB/s

Mb/s 兆比特每秒,指每秒传输的比特位数
MB/s 兆字节每秒,指每秒传输的字节数量,1MB/s = 8Mb/s


2、PCIe拓扑结构

PCIe采用树形拓扑结构, 由root complexswitchendpoint等类型的PCIe设备组成

在这里插入图片描述

  • root complex(RC) 根桥设备,CPU和PCIe拓扑之间的接口,负责PCIe报文的解析和生成。RC会将CPU的request转换成PCIe的4种不同的请求(ConfigurationMemoryI/OMessage);
  • switch PCIe的转接器设备(扩展PCIe端口),为挂在它上的设备(endpointswitch)提供路由和转发服务。
  • PCIe endponit(EP) PCIe终端设备,如网卡、显卡等。
  • PCI Express-PCI bridge 桥接设备,连接其他的PCI总线、PCI-X、PCIe总线。

  和PCI并行总线不同,PCIe的总线采用了高速差分总线,并采用端到端的连接方式, 因此在每一条PCIe链路中两端只能各连接一个设备, 如果需要挂载更多的PCIe设备,那就需要用到switch转接器。

  Switch扩展了PCIe端口,靠近RC的那个端口,我们叫上游端口(upstream port),而分出来的其他端口,我们叫下游端口(downstream port)。一个Switch只有一个上游端口,可以扩展出若干个下游端口。下游端口可以直接连接Endpoint,也可以连接 Switch,扩展出更多的PCIe端口。


3、PCIe信号定义

在这里插入图片描述

  • PETpx、PETnx: 数据发送器差分线对;
  • PERpx、PERnx: 数据接收器差分线对,x代表通道号;
  • PERST#: 全局复位信号有效时(#:低电平有效),PCIe设备将对内部逻辑进行复位操作;
  • REFCLK+、REFCLK-: PCIe参考时钟信号;
  • WAKE#: CPU向PCIe设备提供唤醒请求后,为该PCIe设备提供主电源Vcc;
  • SMCLK: 系统管理总线时钟;
  • SMDAT: 系统管理总线数据;

4、PCIe分层结构

在这里插入图片描述

  • Transaction Layer:【事务层】负责TLP包(Transaction Layer Packet)的封装与解封装,此外还负责QoS,流控、排序等功能;

  • Data Link Layer:【数据链路层】负责DLLP包(Data Link Layer Packet)的封装与解封装,此外还负责链接错误检测和校正,使用Ack/Nak协议来确保传输可靠;

  • Physical Layer:【物理层】 处理所有的Packet数据物理传输,发送端数据分发到各个Lane传输(stripe),接收端把各个Lane上的数据汇总起来(De-stripe),每个Lane上加扰(Scramble,让0和1分布均匀,去除信道的电磁干扰EMI)、去扰(De-scramble),以及8/10或者128/130编码解码等。

PCIe传输的数据从上到下,都是以packet的形式传输的,每个packet都是有其固定的格式的。

在这里插入图片描述

  1. 红色部分【事物层】: HeaderData是事务层上层给的信息,事务层给它末尾加 ECRCEnd-to-End CRC, 端到端 CRC)字段,,就构成了一个TLPTransaction Layer Packet);

  2. 蓝色部分【数据链路层】: 负责在 TLP 中添加一个序列号、LCRC 字段(Link CRC, 链路CRC),构成了一个DLLP包(Data Link Layer Packet);

  3. 绿色部分【物理层】: DLLP下传到物理层,头上加个Start,末尾加个End符号,把这些数据分派到各个Lane上,然后每个Lane上加扰码,经8/10或128/130编码,最后通过物理传输介质传输给接收方。( 解析是一个逆向的过程


二、PCIe事物层

  事务层根据上层(软件层或者应用层)请求(Request)的类型、目的地址和其它相关属性,把这些请求打包,产生TLPTransaction Layer Packet)。

TLP = Request TLP 【请求】 + Completion TLP 【响应】

1、TLP请求

  根据软件层的不同请求,事务层产生四种不同的TLP请求:

  • Memory: 【内存空间访问】,数据在彼此的Memory之间交互, PCIe总线上的主流传输;针对32bit寻址,支持4G的地址空间,针对64bit寻址,支持16G的地址空间;

  • IO:【 IO空间访问】,新的PCIe设备设备的物理空间只支持内存映射(Memory map)到Host主存,存在访问IO空间的TLP,是为了兼顾老设备;PCI最大支持4G的IO空间,但受限于x86处理器IO空间16bits带宽),很多平台将PCI的IO地址空间限定在64KB

  • Configuration:【配置空间访问】,由Host发起(确切的说是RC),往往只在上电枚举和配置阶段会发起Configuration的访问; 备注x86 CPU可以直接访问memory空间和I/O空间,配置空间则不能直接访问,而是通过 IO映射数据端口地址端口间接访问PCI的配置空间;

  • Message: PCI通过边带信号线(sideband signal)传输中断、错误以及电源管理相关信息,而PCIe是通过Packet传输,只有在中断、错误等情况下,才会有Message TLP

  补充:

  • x86 CPU采用 独立编址的方式,将memory操作与IO操作分开了,才有了memory空间IO空间的区分;
  • ARMPower PC处理器把寄存器与内存 统一编址,访问寄存器就通过访问一般的内存指令进行,这类CPU没有专门用于设备l/O的指令。
    在这里插入图片描述

2、TLP响应

  • Non-Posted TLP: 要求设备必须响应,对方通过返回一个Completion TLP来作为响应(可包含需要返回的有效数据或状态),如ConfigurationIOMemory Read

  • Posted TLP: 不要求对端设备响应(Posted:邮政)。投递消息后不保证接收方一定能收到,存在丢数据的风险(概率很小),因此数据链路层提供了ACK/NAK机制,一定程度上能保证TLP正确交互;只有MessageMemory Write采用Posted TLP方式。

TLP事务种类 名称缩写
Memory Read MRd
Memory Write MWr
Configuration Read(Type 0 and Type 1) CfgRd0, CfgRd1
Configuration Write(Type 0 and Type 1) CfgWr0,CfgWr1
Message Request with Data MsgD
Message Request without Data Msg
Completion with Data(响应包中含数据) CplD
Completion without Data(响应包中不含数据) Cpl

在这里插入图片描述
例1: Endpoint想读Host内存的数据,因此,它在事务层上生成一个Memory Read TLP,该MRd一路向上,翻过B,越过A,最终到达Root ComplexRC收到该Request,就到内存中取该Endpoint所需的数据,RC通过Completion with Data TLPCplD)返回数据,原路返回到EP

  一个TLP,最多只能携带4KB有效数据,如果EP需要读16KB的数据,RC必须返回4个CplDEndpoint(EP只需发1个MRd)。

例2: Host想往某个EP写入数据,因此RC在其事务层生成一个Memory Write TLP(要写的数据在该TLP中),翻过A,越过B,直到目的地。Memory Write TLPPosted的,因此,EP收到数据后不需返回Completion TLP

  由于一个TLP只能携带4KB数据,Host想往Endpoint上写入16KB数据,RC必须发送4个MWr TLP


3、TLP结构

在这里插入图片描述

  • Header: 根据上层请求内容生成TLP Header(发送者的相关信息、目标地址、TLP类型、数据长度等);
  • Data Payload: 有效载荷数据。该域不是必须的(不是每个TLP都必须携带数据,如存储器读操作、配置和IO写完成操作,数据是由目标设备通过Completion TLP返回),最大数据长度为1024DW(4K)
  • ECRC(End to End CRC): 根据HeaderData生成CRC,在接收端根据收到的TLP,重新生成HeaderData的CRC,和收到的CRC比较,相等说明数据在传输过程中没有出错,否则就有错(可以设置不加CRC);

  一个Header大小可以是3DW(DW:双字,一个DW为4Byte),也可以是4DW(16Byte),格式和内容随事务类型变化,总结如下:

  • Completion TLP(响应TLP) 的Header大小总是3DW
  • Configuration的Header大小总是3DW
  • Message TLP的Header 大小总是4DW
  • 如果Host内存空间小于4GB,则Memory读写TLP Header大小为3DW,大于4GB则为4DW

4DWTLP Header为例:

在这里插入图片描述

  • Fmt[2:0]: Format,表明该TLP是否带有数据,Header是3DW还是4DW所有的读操作(存储、IO、配置)TLP都不带数据,而写请求(存储、IO、配置)的TLP带数据,其他TLP可能带、也可能不带数据。
Fmt[2:0] 描述
000 3 DW header,无数据
001 4 DW header,无数据
010 3 DW header,有数据
011 4 DW header,有数据
100 TLP Prefix(可选功能)
  • Type[4:0]: TLP类型,与 Fmt 字段一起用于规定事务类型、帧头长度和是否有数据负载。如果存储器读写 TLP 支持 64 位地址模式时,TLP 头长度为 4DW,否则为 3DW。而完成报文的 TLP 头不含有地址信息,使用的 TLP 头长度为 3DW,其中 Byte4~Byte15 格式与 TLP 类型有关。
      PCIe 总线规范还规定了 MRdLk 报文(锁定存储器读请求),该报文的作用是与 PCI 总线的所操作相兼容,但是 PCIe 总线规范不建议用户使用该功能,因为这将极大地影响 PCIe 总线的数据传送效率。
      PCIe 总线规范使用 Fmt 字段区分读写操作,当 Fmt 是“带数据”的报文一定是“写操作”;当 Fmt 字段是不带数据的报文,一定是“读操作”。
TLP Fmt[1:0] Type[4:0]
Memory Read Request(MRd):存储器读请求 00 = 3 DW header,无数据  01 = 4 DW header,无数据 0 0000
Memory Read Lock Request(MRdLk):锁定存储器读请求 00 = 3 DW header,无数据  01 = 4 DW header,无数据 0 0001
Memory Write Request(MWr):存储器写请求 10 = 3 DW header,有数据  11 = 4 DW header,有数据 0 0000
IO Read Request(IORd):IO读请求 00 = 3 DW header,无数据 0 0010
IO Write Request(IOWr):IO写请求 10 = 3 DW header,有数据 0 0010
Config Type 0 Read Request( CfgRd0):Type0配置读请求 00 = 3 DW header,无数据 0 0100
Config Type 0 Write Request( CfgWr0):Type0配置写请求 10 = 3 DW header,有数据 0 0100
Config Type 1 Read Request( CfgRd1):Type1配置读请求 00 = 3 DW header,无数据 0 0101
Config Type 1 Write Request( CfgWr1):Type1配置写请求 10 = 3 DW header,有数据 0 0101
Message Request(Msg):消息请求 01 = 4 DW header,无数据 1 0r[2:0]
Message Request with Data(MsgD):带数据的消息请求 11 = 4 DW header,有数据 1 0r[2:0]
Completion( Cpl):完成 00 = 3 DW header,无数据 0 1010
Completion with Data(CplD):带数据的完成 10 = 3 DW header,有数据 0 1010
Completion-Locked(CplLk):锁定完成 00 = 3 DW header,无数据 0 1011
Completion-Locked with Data(CplDLk):带数据的锁定完成 10 = 3 DW header,有数据 0 1011
  • R: 保留字段(reserve),应被置为0;

  • TC[2:0] : 表示当前传输的等级(Traffic Class),有 8 种传输类型(TC0~TC7,默认为 0),该字段为 PCIe 的 QoS(Quality of Service)相关。目前多数处理器系统的 RC 仅支持一个 VC 通路(Virtual Channel,虚拟通道,VC0~VC7),多数 EP 中只含有一个 VC,因此这些 EP 在发送 TLP 时仅用 TC0。不同的 TC 使用 PCIe 链路中不同的 VC,而不同的 VC 仲裁机制不同,EP 或者 RC 可以通过调整 TLP 中的 TC 字段,从而调整 TLP 的优先级。

  • Attr[2:0]: 属性(Attrbiute),Attr[2]:表示该 TLP 是否支持 PCIe 总线中的 ID-based OrderingAttr[1]:表示是否支持 Relaxed OrderingAttr[0]:表示该 TLP 在经过 RC 到达存储器时,是否需要进行 Cache 一致性处理。

Attr[2] Attr[1] 类型
0 0 缺省,即强序模型
0 1 PCI-X Relaxed Ordering模型
1 0 ID-based Ordering(IDO)模型
1 1 同时支持Relaxed Ordering和IDO模型
  • TH: 表示TLP中是否含有TLP处理信息提示(TLP Processing Hints),TLP 发送端可以使用 TPH 信息,通知接收端即将访问数据的特性,以便接收端合理地预读和管理数据。

  • TD: TLP Digest,该bit置位,说明该TLP包含ECRC,接收端应该做CRC校验;

  • EP: Poisoned Data表示当前 TLP 中的 Data Payload 是否有效(1:有效、0:无效);

  • AT[1:0]: 地址种类(Address Type),在一些 PCIe 设备中设置了 ATC(Address Translation Cache)部件,该部件的主要功能是进行地址转换,只有在支持 IOMMU 技术的处理器系统中,PCIe 设备才能使用该字段。该字段的主要目的是为了方便多个虚拟主机共享同一个 PCIe 设备。

  • Length[9:0]: 该字段用来描述 Data Payload 数据有效负载的大小(单位:DW),TLP最大数据长度4KB(10bit、最大1024,单位DW例如存储器读请求时,TLP 中没有 Data Payload 字段,此时使用 Length 字段表示需要读取n个DW( 0≤n≤1024)该长度总是DW的整数倍,如果TLP的数据不是DW(4Byte)的整数倍,则需要用到下面两个域:Last DW BE1st DW BE

  • DW BE: PCIe 总线以字节为基本单位进行数据传递,但是 length 字段以 DW 为最小单位。为此 TLP 使用 Last DW BEFirst DW BE 两个字段进行字节使能,使得在一个 TLP 中,有效数据负载以字节为单位。


4、TLP Memory

   PCIe设备开放给Host访问的设备空间,首先会映射到Host的内存空间,Host如果想访问设备的某个空间,TLP Header中的地址应设置为该访问空间在Host内存的映射地址。

  • Memory读写请求使用地址路由方式进行数据传递。
  • 如果Host内存空间小于4GB,则Memory读写TLP Header大小为3DW,大于4GB则为4DW

  因为对4GB内存空间,32bit的地址用1个DW(Byte8-11)就可以表示;而4GB以上的内存空间,需要2个DW(Byte8-15)表示地址;
在这里插入图片描述
  该TLP经过Switch时,Switch会根据地址信息,把该TLP转发到目标设备。之所以能唯一的找到目标设备,那是因为不同的Endpoint设备空间会映射到Host内存空间的不同位置。

  每个设备在PCIe系统中都有唯一的ID,该ID由总线(Bus)、设备(Device)、功能(Function)三者唯一确定,详见下一章。

  • Request ID: 该字段包含生成TLP报文的Bus Number[7:0]Device Number[4:0]Function Number[2:0],因为存储器写请求并不需要返回完成报文(Request ID),但是仍予以保留。

  Request ID字段和Tag字段合称为Transaction ID,其作用是使接收端分析报文的Transaction ID,确认报文到达的最终目的地。在同一段时间内,在当前的PCIe总线域中不能存在两个及以上的Transaction ID相同存储器读请求。
在这里插入图片描述

  • Tag: 该字段决定发送能暂存多少个同类型的TLP;假若Tag字段为5时,发送端能够暂存32个同类型的报文。

5、TLP Message

  • Message TLP支持地址路由ID路由,但绝大多数情况下使用隐式路由方式进行数据传递。

  • Message TLP用以传输中断、错误、电源管理等信息,取代PCI时代的边带信号传输。

  • Message TLP的Header 大小总是4DW。
    在这里插入图片描述
    Message Code来指定该Message的类型,不同的Message Code,最后两个DW的意义也不同。具体如下:

6、TLP路由方式

  TLP的路由方式指TLP经过Switch或者PCIe桥片时采用哪条路径到达EP或RC的方法。PCIe总线继承了PCI总线的地址路由ID路由方式,并新增了隐式路由方式。

  • 存储器和IO读写操作请求TLP使用基于地址的路由方式,这种方式使用TLP中的Address字段进行路由选径,最终到达目的地。

  • 配置读写报文、Vendor_Defined Messages报文、cpl/cplD报文使用基于ID路由方式,这种方式使用PCIe Bus Number进行路由路径选择,在Switch或多端口RC的虚拟PCI-to-PCI桥配置空间中,包含如何使用PCI总线号进行路由路径选择的信息。

  • 隐式路由是指从下游端口到上游端口进行数据传递的使用路由方式,或者用于RC向EP发出广播报文。隐式路由主要用于Message报文的传递,在PCIe总线中定义了一系列消息报文,包括INTx Interrupt Signaling(中断信号)、Power Management Message(电源管理信息)、Error Signal Message(错误信息)等报文,在这些报文中,除了Vendor_Defined Messages报文,其他所有信息报文都使用隐式路由方式。


三、PCIe配置空间

  • Configuration的Header大小总是3DW。
  • Configuration读写请求使用ID路由方式进行数据传递。
  • BDFBus-总线号 + Device-设备号 + Function-功能号)构成了每个PCIe设备节点的身份证号,决定了唯一的目标设备;寻址基本单元是function
  • Ext Reg Number(扩展寄存器号) + Register Numbe(寄存器号)相当于配置空间的偏移。

在这里插入图片描述

  一个PCIe系统最多有256条Bus,每条Bus上最多挂32个Device,每个Device最多又能实现8个Function,每个Function对应着4KB的配置空间(PCI或者PCI-X为256Byte)。

   Host软件可以读取该设备的配置空间来获取信息,也可以通过它来配置该设备。上电时,这些配置空间都需映射到Host的内存空间,因此,Host需要占用内存空间是:256*32*8*4KB =256MB

PCIe设备的配置空间是协议规定好的,Pcie的配置空间如下:
在这里插入图片描述

1、PCI标准配置空间头

  PCI标准配置空间分 type0(Endpoint)和 type1(Switch)两种。

在这里插入图片描述

  • Device ID: 设备ID, 表示该PCI设备的设备号,只读。
  • Vendor ID: 厂商ID, 表示生产该设备的厂商的编号(Intel ID8086),只读。
  • Status: 设备状态寄存器,用于保存PCIe设备的状态,如中断状态或运行产生错误时的状态。
Bit位 说明
bit[2:0] 保留
bit3 中断状况:表示该功能有一个未完成的中断请求,默认值为0,仅与INTx消息有关
bit4 功能列表:表示在功能的PCI兼容配置空间前48个双字中存在一个或多个扩展功能寄存器组。PCIe功能都要求实现PCie功能结构,所以该比特必须设置为1
bit5 在PCI中支持66MHz,在PCIE中保留(为0)。
bit6 UDF支持,现在保留
bit7 在PCI中支持快速背靠背,在PCIE中保留(为0)。
bit8 主控器数据奇偶错误,如果在命令寄存器设置了奇偶错误允许比特,且满足如下条件之一,请求者就设置主控器数据奇偶错误比特:①、如果请求者收到一个有错误的完成;②、如果请求者写请求中毒。如果清除了奇偶错误比特,则不会设置主控器数据奇偶错误比特。默认值为0
bit[10:9] PCI中的DEVSEL计时,在PCIE中保留(为0)。
bit11 已发送目标异常中断,当充当完成者的功能通过发送完成者异常中断完成状况到请求者要求终止请求时,设置该比特。默认值为0。
bit12 已接收目标异常中断,当请求者收到一个待完成者异常中断完成状况的完成时,设置该比特,默认值为0。
bit13 已接收主控器异常中断,当请求者收到一个带未受支持的请求完成状况的完成时,设置该比特,默认值为0。
bit14 已发信号系统错误,当功能发送ERR_FATAL或ERR_NONFATAL消息,并且命令寄存器中的SERR允许比特设为1时,设置该比特,默认值为0。
bit15 已发现奇偶错误,不论功能的命令寄存器中奇偶错误启动比特状态如何,只要收到一个中毒的TLP,就设置该比特。默认值为0。
  • Command: PCI设备命令寄存器, 在pci设备使能pci_enable_device时会配置该寄存器。主要负责使能或关闭pci设备的I/O访问memory访问INTx中断等。
Bit位 说明
Bit0 该位用于控制设别如何响应I/O空间的访问请求,复位后默认为0。
该位为0时,设备不会响应I/O空间访问请求。
该位为1时,设备正常响应I/O空间访问请求。
Bit1 该位用于控制设别如何响应Memory空间的访问请求,复位后默认为0。
该位为0时,设备不会响应Memory空间访问请求。
该位为1时,设备正常响应Memory空间访问请求。
Bit2 Endpoint:该位决定了设备能否发出Memory读写请求、I/O读写请求。  1:允许  0:不允许(默认)
Switch:该位决定了设备能否将Memory读写请求和I/O读写请求转发至上游方向(Upstream Direction)。
  Switch的 Downsteam端口收到Memory请求和I/O请求后,应该按照Unsupported Requests(UR)处理。对于收到的 Non-Posted 请求,应该向 Requester 发送一个UR Completion状态位置位的Completion。
  该位并不会影响 Completion 的转发,除了Memory读写请求和I/O读写请求,其他类型的请求不受该位控制。
Bit3 PCI专用循环,PCIe不用,默认为0。
Bit4 PCI中存储器写和存储器失效允许,PCIe不用,默认为0。
Bit5 PCI中允许VGA调色板侦测允许,PCIe不用,默认为0。
Bit6 奇偶错误响应,在状况寄存器中,如果设置了奇偶错误响应比特,且有下列条件之一发生,请求者将设置主控器数据奇偶比特:
①、如果请求者受到一个有错误的完成;②、如果请求者写请求中毒;③、如果清除了奇偶错误比特,则不会设置主控器数据奇偶错误比特。
Bit7 PCI中的步长控制,PCIe不用,默认为0。
Bit8 Endpoint:为1时,设备可以向RC发送ERR_FATAL和ERR_NONFATAL错误消息。
Switch:为1时,设备可以将ERR_FATAL和ERR_NONFATAL错误消息转发到上游总线。  ERR_COR 消息不受该位控制,默认值为0。
Bit9 PCI中启用快速背靠背功能允许,PCIe不用,默认为0。
Bit10 该位用于控制设备能否产生INTx中断。  1:不允许设备产生INTx中断。  默认值为0。
Bit[15:11] 保留
  • Class Code: 设备分类信息, 表示pci设备属于哪一种类别。
说明 说明
0x00 在定义类代码前建立的功能(PCI2.0前) 0x0a 坞站
0x01 海量存储控制器 0x0b 处理器
0x02 网络控制器 0x0c 串行总线控制器
0x03 显示控制器 0x0d 无线控制器
0x04 多媒体设备 0x0e 智能IO控制器
0x05 存储器控制器 0x0f 卫星通信控制器
0x06 桥设备 0x10 加密/解密控制器
0x07 简单的通信控制器 0x11 数据获取和信号处理控制器
0x08 基本的系统外围设备 0x12-0xfe 保留
0x09 输入设备 0xff 不舍和任何定义类代码的设备
  • Revision ID: 设备版本ID, 表示PCI设备的版本号。该寄存器可以被认为是Device ID寄存器的扩展。 只读。

  • BIST:Built-In Self-Test)可选,用于内部自检。

Bit位 说明
Bit[3:0] 完成代码,为0表示成功完成;非0表示发生了与特定功能有关的错误
Bit[5:4] 保留
Bit6 开始BIST(Start BIST),向该比特写入1,表示开始该功能的BIST。完成后,该功能将自动复位该比特。如果BIST不能在2s内完成,软件将不能执行该功能。
Bit7 具有BIST功能,如果功能有BIST,将返回1,否则返回0。
  • Header type: PCI设备头类型寄存器。
Bit位 说明
Bit[6:0] 0:PCIE EP设备(Non-Bridge Function)  1:PCIE 桥设备(PCI-to-PCI Bridge)  2:PCIE CardBus桥设备(CardBus Bridge)
bit7 0:单功能设备  1:多功能设备
  • Lantency Timer: 在PCI总线中,多个设备共享同一条总线带宽,该寄存器用来控制PCI设备占用PCI总线的时间。PCIe设备不需要使用该寄存器,该寄存器的值必须为0。因为PCIe总线的仲裁方法与PCI总线不同,使用的连接方法也与PCI总线不同。
  • Cache line size: cache缓存大小。对于PCIe设备,该寄存器的值无意义。
  • Base Address register: BAR地址寄存器负责PCI设备内部空间的映射,下一节重点介绍;
  • Expansion Rom Base Address: 扩展ROM映射基地址寄存器。分配给ROM使用,用于PCI设备在处理器还没有运行操作系统之前,完成基本的初始化设置。

其他寄存器不在列举,后期用到再补充。具体可查看手册《PCI Express Base Specification Revision 3.0》。


2、BAR配置空间

  对Endpoint Configuration(Type 0),提供了最多6个BAR,而对Switch(Type 1)来说,只有2个。如果某个设备的BAR没有被全部使用,则对应的BAR应被硬件全被设置为0。

在这里插入图片描述

  系统启动后,CPU读取EP/Switch所需PCI域空间的大小、属性(出厂时已固定写入BAR寄存器、只读),并分配对应的系统内存空间,将root complex里申请的PCI域地址空间基地址大小保存在BAR寄存器。该地址空间需要映射到IO地址空间里或者内存地址空间之后CPU才能使用 ;

在这里插入图片描述
  对于被使用的BAR来说,其部分低比特位是不可以被软件操作的,只有其高比特位才可以被软件操作。而这些不可操作的低比特决定了当前BAR支持的操作类型和可申请的地址空间的大小。


3、PCIe工作过程

PCIe上电后主要经历链路训练、枚举扫描、配置BAR空间三个过程。

3.1、链路初始化和训练

  物理层实现链路训练(Link Training)和链路初始化(Link Initialization)的功能,这一般是通过链路训练状态机(Link Training and Status State MachineLTSSM)自动完成。

  链路训练主要为确认PCIe设备的基本属性:链路宽度(X1、X2、X4…)、速率(Link Data Rate)、通道位置翻转(Lane Reversal)、信号极性翻转(Polarity Inversion)、位锁定且时钟恢复(Bit Lock per Lane)、字符Gen1/2块锁定(Symbol lock or Block alignment per Lane)、通道对齐(Lane-to-Lane De-Skew Within a Multi-Lane Link)等。

具体细节可阅读:PCIe物理层链路训练和初始化(详细)总结附图文解析-PCIe专题知识(三)

3.2、枚举扫描

PCIe的Switch(Type1)配置空间字段含义的补充:

  • Subordinate Bus Number 设备最后一级总线号,即该Switch子树下最大总线号
  • Secondary Bus Number 当前总线号
  • Primary Bus Number 上一级总线号

  CPU需知道系统中有那些PCIe设备,并且为每个设备分配总线号。而Host对PCIe设备扫描采用了深度优先算法,其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只访问一次。

PCIe设备枚举过程如下:

1、在处理器系统中,一般将Root complex中与Host Bridge相连接的PCI总线命名为PCIe Bus 0,系统将初始化Bus 0配置空间并将寄存器Sec设为0,由于无法确定Bus 0下挂载PCIe设备情况,暂将Sub设为0xFF;

2、PCIe Host主桥扫描Bus 0上的设备,主桥发现Bridge 1后,将Bridge1下面的Pcie Bus定为 Bus 1,系统将初始化Bridge 1的配置空间,并设置Pri = 0、Sec = 1(表明Bridge1 的上游总线是0,下游总线是1)、Sub暂时设置为0xFF;

3、系统继续扫描Bus 1下设备,通过该设备的获取配置空间,发现这是个Switch设备。系统将该设备Bridge 1下的PCIe Bus定为Bus 2,并设置该桥Pri = 1、Sec = 2、Sub = 0xFF;

4、系统继续扫描Bus 2下设备,系统将该设备Bridge 2下的PCIe Bus定为Bus 3,并设置该桥Pri = 2、Sec = 3;扫描Bus 3下设备,通过该设备的获取配置空间,发现这是个Ep设备,故设置Sub = 3;

5、系统继续扫描Bus 2下设备,系统将该设备Bridge 3下的PCIe Bus定为Bus 4,并设置该桥Pri = 2、Sec = 4;扫描Bus 4下设备,通过该设备的获取配置空间,发现这是个Ep设备,故设置Sub = 4;

6、系统继续扫描Bus 0下设备,通过该设备的获取配置空间,发现这是个Switch设备。系统将该设备Bridge 1下的PCIe Bus定为Bus 4,并设置该桥Pri = 0、Sec = 5、Sub = 0xFF;
  … …
在这里插入图片描述


3.3 、配置BAR空间

作用: 配置PCIe设备的基地址寄存器,给PCIe分配地址空间;

在这里插入图片描述
Eg: 系统软件为PCIe设备分配映射Memory空间:

  • 设备上电时,系统软件向该BAR写全1,再读回该BAR寄存器,如果返回全0,表明该BAR没有实现;

  • 如果返回非0(如下图所示:0xFFFF F000),表明这个BAR对应了一个32位Memory空间,0xFFFF F000可操作的最低位为12,则该BAR可申请地址空间大小为4KB2^12);

  • 系统软件在系统Memory空间中映射4KB的空间,并将分配的基地址写入BAR寄存器的高20位;

  • CPU若想访问该PCIe设备空间,只需要访问对应的内存空间即可。


参考:FPGA-PCIe解读老男孩读PCIe介绍系列、《PCI EXPRESS系统体系结构标准教材》


路虽远行则将至、事虽难做则必成
MrWang
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/TurboTab/article/details/130328213

智能推荐

前端开发之vue-grid-layout的使用和实例-程序员宅基地

文章浏览阅读1.1w次,点赞7次,收藏34次。vue-grid-layout的使用、实例、遇到的问题和解决方案_vue-grid-layout

Power Apps-上传附件控件_powerapps点击按钮上传附件-程序员宅基地

文章浏览阅读218次。然后连接一个数据源,就会在下面自动产生一个添加附件的组件。把这个控件复制粘贴到页面里,就可以单独使用来上传了。插入一个“编辑”窗体。_powerapps点击按钮上传附件

C++ 面向对象(Object-Oriented)的特征 & 构造函数& 析构函数_"object(cnofd[\"ofdrender\"])十条"-程序员宅基地

文章浏览阅读264次。(1) Abstraction (抽象)(2) Polymorphism (多态)(3) Inheritance (继承)(4) Encapsulation (封装)_"object(cnofd[\"ofdrender\"])十条"

修改node_modules源码,并保存,使用patch-package打补丁,git提交代码后,所有人可以用到修改后的_修改 node_modules-程序员宅基地

文章浏览阅读133次。删除node_modules,重新npm install看是否成功。在 package.json 文件中的 scripts 中加入。修改你的第三方库的bug等。然后目录会多出一个目录文件。_修改 node_modules

【】kali--password:su的 Authentication failure问题,&sudo passwd root输入密码时Sorry, try again._password: su: authentication failure-程序员宅基地

文章浏览阅读883次。【代码】【】kali--password:su的 Authentication failure问题,&sudo passwd root输入密码时Sorry, try again._password: su: authentication failure

整理5个优秀的微信小程序开源项目_微信小程序开源模板-程序员宅基地

文章浏览阅读1w次,点赞13次,收藏97次。整理5个优秀的微信小程序开源项目。收集了微信小程序开发过程中会使用到的资料、问题以及第三方组件库。_微信小程序开源模板

随便推点

Centos7最简搭建NFS服务器_centos7 搭建nfs server-程序员宅基地

文章浏览阅读128次。Centos7最简搭建NFS服务器_centos7 搭建nfs server

Springboot整合Mybatis-Plus使用总结(mybatis 坑补充)_mybaitis-plus ruledataobjectattributemapper' and '-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏3次。前言mybatis在持久层框架中还是比较火的,一般项目都是基于ssm。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但正其操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。mybatis-plus就很好的解决了这个问题。..._mybaitis-plus ruledataobjectattributemapper' and 'com.picc.rule.management.d

EECE 1080C / Programming for ECESummer 2022 Laboratory 4: Global Functions Practice_eece1080c-程序员宅基地

文章浏览阅读325次。EECE 1080C / Programming for ECESummer 2022Laboratory 4: Global Functions PracticePlagiarism will not be tolerated:Topics covered:function creation and call statements (emphasis on global functions)Objective:To practice program development b_eece1080c

洛谷p4777 【模板】扩展中国剩余定理-程序员宅基地

文章浏览阅读53次。被同机房早就1年前就学过的东西我现在才学,wtcl。设要求的数为\(x\)。设当前处理到第\(k\)个同余式,设\(M = LCM ^ {k - 1} _ {i - 1}\) ,前\(k - 1\)个的通解就是\(x + i * M\)。那么其实第\(k\)个来说,其实就是求一个\(y\)使得\(x + y * M ≡ a_k(mod b_k)\)转化一下就是\(y * M ...

android 退出应用没有走ondestory方法,[Android基础论]为何Activity退出之后,系统没有调用onDestroy方法?...-程序员宅基地

文章浏览阅读1.3k次。首先,问题是如何出现的?晚上复查代码,发现一个activity没有调用自己的ondestroy方法我表示非常的费解,于是我检查了下代码。发现再finish代码之后接了如下代码finish();System.exit(0);//这就是罪魁祸首为什么这样写会出现问题System.exit(0);////看一下函数的原型public static void exit (int code)//Added ..._android 手动杀死app,activity不执行ondestroy

SylixOS快问快答_select函数 导致堆栈溢出 sylixos-程序员宅基地

文章浏览阅读894次。Q: SylixOS 版权是什么形式, 是否分为<开发版税>和<运行时版税>.A: SylixOS 是开源并免费的操作系统, 支持 BSD/GPL 协议(GPL 版本暂未确定). 没有任何的运行时版税. 您可以用她来做任何 您喜欢做的项目. 也可以修改 SylixOS 的源代码, 不需要支付任何费用. 当然笔者希望您可以将使用 SylixOS 开发的项目 (不需要开源)或对 SylixOS 源码的修改及时告知笔者.需要指出: SylixOS 本身仅是笔者用来提升自己水平而开发的_select函数 导致堆栈溢出 sylixos

推荐文章

热门文章

相关标签