👉个人主页:highman110
👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容
参考书籍:
PCI_Express体系结构导读、
深入浅出SSD:固态存储核心技术、原理与实战
目录
概述
EP的配置空间
switch的配置空间
概述
每个PCIe设备都有这样一段空间,主机软件可以通过读取它获得该设备的一些信息,也可以通过它来配置该设备,这段空间就称为PCIe的配置空间。不同于每个设备的其他空间,PCIe设备的配置空间是协议规定好的,哪个地方放什么内容,都是有定义的。
PCIE设备的配置空间定义部分从PCI总线继承,PCIE新增了一个扩展配置寄存器空间,PCI配置空间共256字节,PCIE配置空间共4096字节,如下图:
Capacity这个字段先不讨论,我们先看一下Header,PCI和PCIE的Header定义是一样的,和地址路由相关的信息也在这里。
这里包括EP(type0)和switch(type1)两种配置空间Header定义:
EP的配置空间
Device ID和Vender ID:设备ID和供应商ID,这个没什么好说的,只读。
Command:PCI设备的命令寄存器,初始化时为0,这时的设备只能接收配置请求总线事务,不能接收存储器或IO请求的总线事务。需要软件设置该寄存器后,才能访问该设备的存储器或IO空间。寄存器定义如下图:
Status:保存PCI设备的状态,如下图:
Revision ID:设备版本号,只读。
Class Code:供系统软件识别当前PCIE设备的分类,共24bit,分为三个字节:Base class code(bit23:16将设备分类为显卡、网卡、桥设备等类型)、Sub class code(bit15:8进一步细分类)、interface(bit7:0定义编程接口)。
Header Type:8bit,只读,定义如下表:
比特位 | 定义 |
7 | 1:表示当前PCI设备是多功能设备 0:表示当前PCI设备是单功能设备 |
6:0 | 0:表示该设备使用PCI agent设备(就是endpoint)的配置空间 1:表示该设备使用PCI桥设备(swtich、RC)的配置空间 2:表示该设备使用cardbus桥片的配置空间 |
Cache line size:记录Host处理器使用的cache行长度。
Latency timer:用来控制PCI设备占用PCI总线的时间,PCIE不用,改值必须为0。
Expansion ROM base address:某些显卡、硬盘、桥片等设备,在处理器还没有运行操作系统之前,就需要完成基本的初始化设置,就是要自己加载一段firmware给自己初始化,初始化完成了才能跟主机对接。Expansion ROM base address字段就是这段固件代码存放的基地址。
Capabilities pointer:存放capabilities寄存器组的基地址。
Interrupt line:记录当前PCIE设备使用的中断向量号。
Interrupt pin:用来保存PCI设备使用的中断引脚,PCI设备有INTA#、INTB#、INTC#、INTD#四个中断引脚,该寄存器为1表示使用INTA#,寄存器为2、3、4依次表示使用INTB#、INTC#、INTD#。PCIE设备没有中断引脚,但是它也可以使用此寄存器,通过INTx中断消息模拟PCI设备的INTA#、INTB#、INTC#、INTD#四个中断信号。
Base address register:BAR寄存器,这是本节的重点。对Endpoint Configuration(Type 0)提供了最多6个BAR,而对Switch(Type 1)来说只有2个。BAR寄存器保存 PCI设备使用的地址空间的基地址,该基地址保存的是该设备在PCI总线域中的地址。
switch的配置空间
一个TLP要到达指定EP,必然会有switch或多端口RC(就是PCI桥设备)的路由选路过程(如果是一个RC对接一个EP就不需要什么路由了),而路由信息存储在桥设备的Configuration空间里,因此,很有必要先理解Switch的Configuration空间,就是前面提到的Type1 header:
有部分字段和EP type0 header一样,这里不赘述。但是PCI桥除了作为PCI设备之外,它还要管理其下连接的其他设备,这些设备同样有配置读写、内存读写、message等总线事务需要处理,所以PCI桥肯定要有一些寄存器来关联到这些设备的总线号、存储器空间,不然当一个访问switch下面EP的TLP报文来到switch时,switch将不知道报文该往哪里转发。下面大致介绍一下桥设备的type1 header相关字段。
BAR:功能和EP type0 header一样,但是对switch来说,不一定会有私有寄存器,也就不需要使用这两组寄存器设置BAR空间,这种设备就是PCI中的透明桥。
Primary bus、secondary bus、subordinate bus:这三种bus用张图来重点解释下,它们是ID路由寻址的关键寄存器。以PCI-PCI桥1为目标设备进行介绍。
Primary bus:表示一个桥设备直接相连的上游Bus Number,就是总线0。注意,下图虽然是PCI的结构图,但是PCIE的类似,swtich内部在逻辑上就是PCI to PCI桥,最上面的HOST主桥,在逻辑上可以等同于RC。
Secondary bus:表示一个桥设备直接相连的下游Bus Number,就是总线1。
Subordinate bus:表示这个桥下游最远、总线号最大的Bus Number,就是总线2,因为图中总线1下面只挂了一个桥2,如果再增加一个桥3,桥3下面的总线号为3,则此时Subordinate bus number就是3。
下面再用一张PCIE结构图说明:
对上图红框中的端口(注意,这个swtich端口就相当于一个PCI桥设备,每个端口都有一个Configuration空间,而不是整个switch共一个Configuration空间)来说,与他直接相连的上游总线号为5,也就是其primary bus number为5,与他直接相连的下游总线号为6,也就是其secondary bus number为6,他下面最远最大的总线号为9,也就是其subordinate bus number为9。
Secondary status:记录secondary bus的状态。
Status:记录PCI桥作为PCI设备时使用的状态。
Secondary latency timer:管理secondary bus的超时机制,即管理PCI桥发向下游的总线事务,另一个寄存器latency timer则是管理PCI桥发向上游的总线事务。
I/O limit、I/O base:传统PCI设备使用,PCI桥使用这两个寄存器存放其下PCI子树中所有设备使用的I/O地址空间集合的基地址(base)和大小(limit)。
Memory limit、Memory base:PCI桥使用这两个寄存器存放其下PCI子树中所有设备使用的存储器地址空间集合的基地址(base)和大小(limit)。对上游端口来说,其Configuration描述的地址范围是它下游所有设备的映射空间范围,而对每个下游端口的Configuration,描述了连接它端口设备的映射空间范围。PCI桥规定这个空间的大小至少为1MB。
Prefetchable Memory Limit、Prefetchable Memory Base:存放这些PCI设备使用的可预取存储器空间的基地址和大小。关于PCI预读机制详情还有待研究。
I/O Base Upper 16 Bits、I/O Limit Upper 16:如果PCI桥仅支持16位的I/O端口,这组寄存器只读,且其值为0。如果PCI桥支持32位I/O端口,这组寄存器可以提供I/O端口的高16位地址。
Bridge Control:该寄存器用来管理PCI桥的Secondary Bus,其主要位的描述如下:
Secondary Bus Reset位,第6位,可读写。当该位为1时,将使用下游总线提供的 RST#信号复位与PCI桥的下游总线连接的PCI设备。通常情况下与PCI桥下游总线连接的PCI设备,其复位信号需要与PCI桥提供的RST#信号连接,而不能与HOST主桥提供的RST#信号连接。
Primary Discard Timer位,第8位,可读写。PCI桥支持Delayed传送方式,当PCI桥的Primary总线上的主设备使用Delayed方式进行数据传递时,PCI桥使用Retry周期结束Primary总线的Non-Posted数据请求,并将这个Non-Posted数据请求转换为Delayed数据请求,之后主设备需要择时重试相同的Non-Posted数据请求。当该位为1时,表示在Primary Bus上的主设备需要在2^10个时钟周期之内重试这个数据请求,为0时,表示主设备需要在2^15个时钟周期之内重试这个数据请求,否则PCI桥将丢弃Delayed数据请求。
Secondary Discard Timer位,第9位,可读写。当该位为1时,表示在Secondary Bus上的主设备需要在2^10个时钟周期之内重试这个数据请求,为0时,表示主设备需要在2^15个时钟周期之内重试这个数据请求,如果主设备在规定的时间内没有进行重试时,PCI桥将丢弃Delayed数据请求。具体可参考PCI-to-PCI Bridge Architecture Specification Revision 1.2。