PCI Express解析——系列文章【5】:PCIe原理分析之——PCI Express 配置解析BDF、BAR、 MEM Read举例
- 2.5 Memory Read举例
- (1)事务层TLP包准备
- (2)数据链路层校验信息
- (3)物理层编码
- (4)接收端处理方式
- 2.6 PCI Express配置解析
- 2.6.1 关于RC、Switch、EP
- (1)RC是什么?
- (2) Switch是什么?
- (3) EP是什么?
- 2.6.2 关于PCIe的BDF和配置空间
- 2.6.2.1 BDF是什么?
- 2.6.2.2 配置空间
- 2.6.3 基地址空间(Base Address Register)
- 2.6.3.1 地址关系问题
- (1) 关于地址问题
- 2.6.3.2 BAR空间
- [上篇--PCI Express解析——系列文章【4】:PCIe原理分析之——PCI Express系统模块、PCIe体系结构]()
上文明确PCIe的基本工作原理,下面就PCIe相关的常见配置和一些关键概念明细。PCIe总线作为处理器系统的局部总线,主要目的时为了连接处理器系统中的多个设备,当然不可避免的可连接其他处理器系统,此时PCIe体系结构的实现方案略有不同。例如Intel、PowerPC等。但是绝大多是使用了RC、Switch、PCIe-to-PCI桥、PCIe设备。其中PCIe设备也称Endpoint(EP设备)。
Author: Nirvana Of Phoenixl
Proverbs for you:There is no doubt that good things will always come, and when it comes late, it can be a surprise.
2.5 Memory Read举例
前面的一系列文章简要地介绍了PCIe总线的结构、事务层、数据链路层和物理层。下面我们用一个简单地的例子来回顾并总结一下。
如下图所示,Requester的应用层(软件层)首先向其事务层发送如下信息:32位(或者64位)的Memory地址,事务类型(Transaction Type),数据量(以DW为单位),
TC(Traffic Class,即优先级),字节使能(Byte Enable)和属性信息(Attributes)等。
(1)事务层TLP包准备
然后接收端的事务层使用这些信息创建了一个Mrd TLP(Memory Read的事务层包),并将Requester的ID(BDF,Bus & Device & Function)
写入到该TLP的Header
中,以便Completer根据这一BDF将Completion信息返回给Requester。然后这个TLP会根据其TC的值被放到对应的VC Buffer中,Flow Control逻辑便会检测接收端的对应的接收VC Buffer空间是否充足。一旦接收端的VC Buffer空间充足,TLP便会准备被向接收端发送。
(2)数据链路层校验信息
当TLP到达数据链路层(Data Link Layer)时候,数据链路层会为其添加上12位的序列号(Sequence Number)和32位的LCRC
。并将添加上这些信息之后的TLP(即DLLP)在Replay Buffer中做一个备份,并随后将其发送至物理层。
(3)物理层编码
物理层接收到DLLP之后,为其添加上起始字符(Start & End Characters,又叫帧字符,Frame Characters),然后依次进行解字节(Strip Byte)、扰码(Scramble)、8b/10b编码并进行串行化
,随后发送至相邻的PCIe设备的物理层。
(4)接收端处理方式
接收端PCIe设备(即Completer)的物理层接收到数据之后,依次执行与发送端相反的操作。并从数据中恢复出时钟,
然后将恢复出来的DLLP发送至数据链路层。
如果接收端不能正确返回信息,接收端会类似前面发送端一样,将错误信息返回接收端。
【注】上述过程上节内容有将一部分,过程如下图
2.6 PCI Express配置解析
上文明确PCIe的基本工作原理,下面就PCIe相关的常见配置和一些关键概念明细。
PCIe总线作为处理器系统的局部总线,主要目的时为了连接处理器系统中的多个设备,当然不可避免的可连接其他处理器系统,此时PCIe体系结构的实现方案略有不同。例如Intel、PowerPC等。但是绝大多是使用了RC、Switch、PCIe-to-PCI桥、PCIe设备
。其中PCIe设备也称Endpoint(EP设备)。
2.6.1 关于RC、Switch、EP
(1)RC是什么?
前文提到在PCIe规范中并没有明确规定RC实现的细则,实际上RC相当于PCIe的主桥,有的处理器系统将PCIe主桥称为PCIe总线控制器
。在不同的处理器系统中RC内包含的组件不同,除过PCIe总线控制器之外还有其他组件,因此RC并不等同于PCIe总线控制器
。
在x86系统中,RC内部集成了一些PCI设备、RCRB(RC Register Block)和Event Collector等组成部件。其中RCRB由一系列管理存储器系统的寄存器组成,而Event Collector用来处理PCIe设备的错误消息报文。RCRB寄存器组属于PCI总线域地址空间。
RC主要完成存储器域到PCIe域地址空间的转换
我们可以将RC理解为一种PCIe的控制器,后面会讲解为什么会存在地址转换的机制,以及PCIe总线域和处理器总线域!
(2) Switch是什么?
主要用于数据链路的扩展。从软件系统角度看,每一个PCIe链路都占用一个PCI总线号,但是一条PCI链路只能连接一个PCIe设备、Switch、EP或者PCIe桥片。PCIe总线使用端到端的连接方式,一条PCIe链路只能链接一个设备。
一个PCIe链路需要挂接多个EP时,需要使用Switch进行链路扩展。一个标准的Switch具有一个上游端口(upStream)和多个下游端口(downStream)。
上游端口与RC或者其他Switch的下游端口相连,而下游端口可以与EP、PCIe-to-PCI桥或者下游的Switch上游端口连接。在PCIe体系结构中,Switch设计难度仅次于RC,是PCIe体系结构的核心所在。
从软件系统角度来看,Switch内部实际上是由多个PCI-to-PCI桥组成,其中每一个上游和下游端口都对应一个虚拟的PCI桥。一个Switch有多少端口就有多个个PCI配置空间。这和虚拟通道VC以及优先级仲裁相关,详解需看详细协议内容。
switch用于扩展PCIe总线的端口
(3) EP是什么?
端点设备,也就通常我们说的可以连接在PCIe总线上的设备,比如显卡、声卡等PCIe端点设备。
EP作为PCIe总线的端点设备存在,也就是作为挂在总线上的具体设备
2.6.2 关于PCIe的BDF和配置空间
2.6.2.1 BDF是什么?
在实际利用PCIe时候,利用最多就是如何在PCIe总线上挂接设备,从而实现利用PCIe总线将处理器系统与PCIe设备连接起来,实现高速串行通信。
上文提到在一个PCIe体系结构中含有众多的Switch和EP设备
,如何找到这些设备呢?答案是通过BDF(bus、device、function)找到。
每一个PCIe设备可以只有一个功能(Function),即Fun0。也可以拥有最多8个功能
,即多功能设备(Multi-Fun)。不管这个PCIe设备拥有多少个功能,其每一个功能都有一个唯一独立的配置空间(Configuration Space)与之对应。
和PCI总线一样,PCIe总线中的每一个功能(Function)都有一个唯一的标识符与之对应。这个标识符就是BDF(Bus,Device,Function),
PCIe的配置软件(即Root的应用层,一般是PC)应当有能力识别整个PCIe总线系统的拓扑逻辑,以及其中的每一条总线(Bus),每一个设备(Device)和每一项功能(Function)。
在BDF中,Bus Number占用8位,Device Number占用5位,Function Number占用3位
。显然,PCIe总线最多支持256个子总线,每个子总线最多支持32个设备,每个设备最多支持8个功能。
PCIe总线采用的是一种深度优先(Depth First Search)的拓扑算法
,且Bus0总是分配给Root Complex。Root中包含有集成的Endpoint和多个端口(Port),每个端口内部都有一个虚拟的PCI-to-PCI桥(P2P),并且这个桥也应有设备号和功能号。需要注意的是,每个设备必须要有功能0(Fun0),其他的7个功能(Fun1~Fun7)都是可选的。
2.6.2.2 配置空间
每个PCIE设备都有自己的独立的一段配置空间,该部分空间是这个设备的,系统会给这个设备分配一段内存空间,CPU访问这段内存空间即访问对此设备的配置空间。设备在出厂时,配置空间是有默认初始值的。
PCIE设备发展向前兼容PCI,每个设备的配置空间的前256个Byte是PCI空间,后(4k-256)个Byte的空间是PCIE扩展空间,这是二者的主要区别。
X86系统中,对PCIE设备配置空间的地址映射一般有两种方式:内存映射(MEM)和IO映射
。因此开发者也可以通过内存访问或者IO访问来访问其配置空间。
配置空间主要有两种,开发者也是搞清楚这两种即可,一是Type0:设备空间,二是Type1: Bridge空间。
【注】对于不同厂商来说,具体的细节可能有所不同,但是协议的基本是一致的。
需要特别注意的是,PCIe的Spec中明确规定只有Root有权限发起配置请求
(Originate Configuration Requests),也就是说PCIe系统里面的其他设备是不允许去配置其他设备的配置空间的,即peer-to-peer的配置请求是不允许的。并且配置请求的路由(Routing)方式只能是采用BDF(Bus Device Function)
。
处理器一般不能够直接发起配置读写请求,因为其只能产生Memory Request和IO Request。这就意味着Root必须要将处理器的相关请求转换为配置读写请求。针对传统的PCI设备(Legacy PCI),采用的是IO间接寻址访问(IO-indirect Accesses);针对PCIe设备,采用的是Memory-Mapped Accesses。
配置空间是针对Function而言的,每一个fun都有其配置空间,实际上就是一堆寄存器。Type0和Type1,分别对应非桥设备(Endpoint)和桥设备(Root和Switch端口中的P2P桥)。
Type0还是Type1是由事务层包(TLP)包头中的Type Field所决定的,而读还是写则是由TLP包头中的Format Field所决定的
。
Fmt+type
【注】Root最先发送的配置请求一定是Type1型的。非桥设备(Endpoint)会直接忽略Type1型的配置请求。
每个PCIe设备下的function都要实现4KB的配置空间,从设备内部地址0开始,注意这里是在设备内部的。因此访问PCIe配置空间不能通过直接读写系统总线实现,因为系统总线上看到的是CPU地址。在PCIe标准中,访问PCIe配置空间的是cfg tlp(configuration transaction layer packet)。cfg tlp又分为type 0和type 1,type 1用来访问PCIe桥,type 0访问端点设备。综上所述,要访问SW的配置空间,就要发起cfg type1 tlp
;要访问EP配置空间,就要发起cfg type0 tlp
。
【析】这就是为什么要RC在处理端,要完成地址域的转换!
2.6.3 基地址空间(Base Address Register)
在谈及基地址空间时,需要明确上文所有的地址空间配置均是基于PCIe设备或者PCIe总线的地址空间。这就要提到一个重要的概念,也就是存储器地址空间域和PCIe总线地址空间域,当然也可以将其分别称为PCIe设备内部地址空间和外部系统总线地址。
2.6.3.1 地址关系问题
简单理解就是处理器地址和PCIe地址。前文提及这两者并不是一致的,而是分别独立的。下面需要解决两点内容其一两地址联系、其二如何发起类型0和1的配置。
(1) 关于地址问题
关于地址相关的问题:
第一: 存储器地址,就是CPU,DMA等设备直接读写的地址。
第二:TLP中的地址。
第三: BAR空间地址。
如果两两组合的话,能够形成三种关系,但是事实上,这三者之间的关系其实就两部分:
存储器地址和TLP地址字段的关系。
TLP地址字段和BAR空间地址的关系。
解决这两个问题,地址相关的问题就应该都清楚了。
首先要知道BAR有什么用?通过BAR寄存器,我们首先知道这个基址对应的空间属性,然后给这段空间分配一个基址,TLP就能根据地址被路由到对应设备的BAR空间中去。
这就是TLP中的地址字段和BAR空间的地址之间的关系
。还有一个问题是关于存储器地址和TLP地址字段的关系,有个硬件单元非常重要,那就是ATU(MATU)
。这里详细介绍一下BAR的配置问题。
2.6.3.2 BAR空间
每个PCIe的function都有自己的配置空间(configuration space)其实就是配置寄存器
,也是软件可以控制的基本
。只不过配置寄存器需要通过TLP包去访问
,也就是利用在核心层或者说应用层设置好方案,在事务层生成TLP从而配置。实际上每一个PCIe设备都有自己独立的一套内部空间,不仅仅是配置空间,包括每个设备提供那些IO地址、Mem地址。而基地址BAR就是来表征这些地址空间的。
基地址寄存器(BAR)在配置空间(Configuration Space)中的位置如下图所示:
其中Type0 Header最多有6个BAR
,而Type1 Header最多有两个BAR
。这就意味着,对于Endpoint来说,最多可以拥有6个不同的地址空间。但是实际应用中基本上不会用到6个,通常1~3个BAR比较常见。
主要注意的是,如果某个设备的BAR没有被全部使用,则对应的BAR应被硬件全被设置为0,并且告知软件这些BAR是不可以操作的。对于被使用的BAR来说,其部分低比特位是不可以被软件操作的,只有其高比特位才可以被软件操作。而这些不可操作的低比特决定了当前BAR支持的操作类型和可申请的地址空间的大小。
一旦BAR的值确定了(Have been programmed),其指定范围内的当前设备中的内部寄存器(或内部存储空间)就可以被访问了。当该设备确认某一个请求(Request)中的地址在自己的BAR的范围内,便会接受这请求。