PCIe Configuration Space基础知识学习

写在前面的话:

真的可能是英语学得不好,计算基础也学得不好,在学习过程中一些基础的概念都弄不清楚,比如PCIe Capability和PCIe Extended Configuration Space我看名字还以为两者有什么关系,现在弄清楚之后发现两者根本就不是一个水平的概念,现在回想刚接触Spec第7章的我……有点蠢。

主要参考:

NCB-PCI_Express_Base_5.0r1.0-2019-05-22.pdf(也就是PCIe base spec 5.0)

《PCI Express 体系结构导读》

CSDN以及其他各路大神的博客链接,我会在文中或者最后贴上,只限和spec chapter7相关的(学习spec的时候有很多大神博客真幸福,比学习sas幸福多了)

一、Configuration Space总述

PCIe Configuration Space基础知识学习_第1张图片

上图是经典的configuration space图,来自spce5.0 r1.0,参考一下《PCI Express 体系结构导读》中的话,

PCI 设备使用的基本配置空间。这个基本配置空间共由 64 个字节组成,其地址范围为 0x00~0x3F ,这 64 个字节是所有 PCI 设备必须支持的。事实上,许多 PCI 设备也仅支持这 64 个配置寄存器。
此外 PCI/PCI-X PCIe 设备还扩展了 0x40~0xFF 这段配置空间, 在这段空间主要存放一些与 MSI 或者 MSI-X 中断机制和电源管理相关的 Capability 结构 。其中所有能够提交中断请求的 PCIe 设备,必须支持 MSI 或者 MSI-X Capability 结构。
PCIe 设备还支持 0x100~0xFFF 这段扩展配置空间。 PCIe 设备使用的扩展配置空间最大为 4KB ,在 PCIe 总线的扩展配置空间中,存放 PCIe 设备所独有的一些 Capability 结构,而 PCI 设备不能使用这段空间。

读完上面的话,我恍悟了capabilities的概念,之前就是很疑惑,也不知道其实在PCIe里面有两个capabilities链表

换成我自己的理解,就是最开始只有PCI设备,它的配置空间就只有0x00~0x3F这么大,这里存放configuration space Header,后来更新换代,新的PCI/PCI-X扩展了0x40~0xFF这段配置空间,在这段空间里存放第一个capabilities链表,这些capabilities主要和中断以及电源管理相关,这里放上一个lecroy协议分析仪分析的configuration space图。

PCIe Configuration Space基础知识学习_第2张图片

 框起来的就是存放在这段空间内的capabilities,注意这里有一个PCI Express Capability,初学时我一直在想这个和PCIe extended configuration space有什么关系,幻想是不是在PCI Configuration Space里面使能了这个Capability,PCIe extended configuration space才能使用。学习禁止幻想,好好读书,两者没有关系。PCIe Capability就是一个叫做PCIe这个名字的Capability,和中断用的Capability,电源管理用的Capability一样,放在0x40~0xFF这段配置空间,“存放一些和PCIe总线相关的信息,包括PCIe链路和插槽的信息”。0x40~0xFF空间不是全部塞满capabilities的,《PCI Express 体系结构导读》中说“事实上,许多PCI设备也仅支持这64个配置寄存器。”就是可能扩展的空间没有实际利用掉,就没有capabilities……

然后设备再更新换代,就有了PCIe,要扩展更多空间,所以有了“PCIe设备还支持0x100~0xFFF这段扩展配置空间”这句话,0x100~0xFFF这段空间存放第二个capabilities链表。

PCIe Configuration Space基础知识学习_第3张图片

   再总结一下,Configuration Space可以分为两段(对着第一个图看可能更清晰),第一段是PCI configuration Space(spec上也称之为PCI-Compatible Configuration),这一段可以分为两部分,第一部分是0x00~0x3F存放Configuration space Header,第二部分是0x40~0xFF存放中断、电源管理相关的一些capabilities,这些capabilities组成一个链表,有头有尾;第二段是PCI EXpress Extended Configuration space,这一部分存放PCIe独有的一些capabilities,这是另外一个链表,也有自己的首尾。

(总结的话有点废话……但是对于初学的我来说,终于理清楚了,感谢龙哥,感谢协议分析仪,终于看到第二个链表起始位置就在100h,理解了再去看之前大神的博客里面的话,觉得自己好傻哈哈哈)

二、Configuration Space分述

这里按照第一节的总结的话来分述,但是我觉得spec把逻辑复杂了,小节标题整体按照spec的思路,但是有些部分不是完全按照的。

1. Configuration Space Header——0x00~0x3F

1.1 Type 0 Configuration Space Header

PCIe Configuration Space基础知识学习_第4张图片

header里面每一个register的含义概念,在spec上都可以查找到,每个bit的含义也都有明确定义,如果看不懂可以参考《PCI Express 体系结构导读》,但是没有实际应用的时候,看了也就是看个表皮,我现在就是只知道有这个概念,每个bit什么时候使能都不太懂,遇到具体问题可以具体查看每个bit。根据前一段的学习,我觉得比较大的概念是Base Address Register(BAR),Expansion Rom Base Address和Capabilities Pointer(status和command似乎也很重要,但是还没深入学到,严谨来讲,每一个bit都很重要),所以只简单说一些我对着三个register的学习及理解。

1.1.1Base Address Register(BAR)

X86 采用独立编址的方式,将 memory 操作与外设 IO 操作分开了,才有了 memory 空间和 IO 空间的区分。 X86 平台 CPU 内部对内存和外设寄存器访问的指令也是不同的。
IO 空间 :访问外部设备寄存器的地址区域,( PCI 支持 4GB IO 空间,但是 x86 平台为 64KB )。
memory 空间 :访问内存的地址空间, 32 位平台为 4G 。 此 memory 空间和 main memory (平时常说的内存或者主存)是两个概念, 32bit 平台下 CPU memory 地址总线只能寻址到 4G ,这 4G 空间包括 main memory 、外设 IO 空间映射( MMIO )等,不能全给 main memory ,因此 32bit CPU 是无法配置 4G 内存的。
X86 CPU 可以直接访问 memory 空间和 IO 空间,但是不能直接访问 PCIe 配置空间(原因很简单, X86 CPU 只有 memory 指令和 IO 指令,没有配置指令)。因此,需要把 PCIe 配置空间映射到 memory 空间或者 IO 空间(一般不推荐映射到 IO 空间)。
原文链接: https://blog.csdn.net/linjiasen/article/details/87944672

PCIe Configuration Space基础知识学习_第5张图片

 上述引用的内容搞明白了,总之configuration space要映射到memory/io space中,才方便cpu访问,io方式是老设备常用的,目前大多数保留了io映射以及访问方式,但基本都采用memory映射及访问。

BAR(base address registers)就是为了把设备的内部各种资源映射到IO空间(IO BAR)或者memory 空间(memory BAR)。(这里还有一个小小问题,还没学到,等学到再补上,这个内部资源是什么呢,是设备的一些data?)

PCIe Configuration Space基础知识学习_第6张图片

Type0的BAR从 010h到024h,一共6个BAR,一个32bit是一个BAR,bit0是0就是memory映射,是1就是io映射,这里不讲io映射,只讲memory映射。

PCIe Configuration Space基础知识学习_第7张图片

 对于memory映射,bits 2:1表示映射方式是32位还是64位,如果是32位就只使用一个BAR完成一次映射,比如BAR0,如果是64位,就用两个BAR映射,比如BAR0-1。一旦BAR的值确定了(Have been programmed),其指定范围内的当前设备中的内部寄存器(或内部存储空间)就可以被访问了。

BAR配置过程:PCIe扫盲——基地址寄存器(BAR)详解-Felix-电子技术应用-AET-中国科技核心期刊-最丰富的电子设计资源平台 (chinaaet.com)http://blog.chinaaet.com/justlxy/p/5100053320

上述博客写得很详细了,参考这篇博客再结合实际抓的包,再梳理一下下BAR配置过程。

  • 未初始化的BAR0,读取低4位发现是64bit的基地址存储(CfgRd0
  • 读取未初始化的BAR0-BAR1CfgRd0
  • 初始化BAR0-BAR1,所谓初始化,就是系统(软件)向整个BAR都写1,来确定BAR的可操作的最低位是哪一位。(CfgWr0

  • 读取初始化后的BAR0-BAR1,确定当前可操作的最低位为25,因此当前BAR可申请的(最小)地址空间大小为32MB2^25. CfgRd0

  • 软件向BAR的高比特写入地址空间的起始地址(Start Address)。(CfgWr0

    起始地址: 0000 019D 0E00 0000h 

PCIe Configuration Space基础知识学习_第8张图片

 上图框起来的(5),写入的全是0应该是没有实用的第一次写入,第二个图写入的才是真正的起始的地址。抓的包,BAR2-5全是0,默认是不使用的意思。

1.1.2  Expansion Rom Base Address

 •Expansion rompci/pcie设备可选的一个外接的EPROM芯片,其中用来存储相应pci设备的初始化代码或者系统启动代码(比如pxe或者pci boot)BIOSPOST(Power-on Self Test)阶段,会扫描pci设备是否有expansion rom,有的话将其拷贝到ram中执行。PCI规范中称为expansion rom,在BIOS术语里面称为option rom。

1.2 PCI&PCIE ExpansionOption ROM_pwl999的博客-CSDN博客https://blog.csdn.net/pwl999/article/details/78208065/本小节大多摘自这篇博客……

1.1.2.1 从configuration space角度去看expansion rom:

PCIe Configuration Space基础知识学习_第9张图片

 bit11-bit31定义expansion rom的映射到memory空间的高位地址bit11-bit31(下位为11位的扩展ROM基址寄存器被软件屏蔽(设为零),形成一个32位地址)bit0表示是否使能expansion rom1使能为使能,需要注意的是expansion rompci其他的bar空间是共享地址解码的,所以一旦使能expansion rom就不能对其他的bar空间进行操作。

1.1.2.2 从System角度(BIOS 初始化过程)来看expansion rom(option Rom)

 • Expansion rom 的组织结构有相应的规范。 一个可能包含多个 rom image 可以支持多个不同类型的 pci 设备 ,每种设备也可以支持不同架构 cpu 的可执行代码。多个 image 在一个 expansion rom 芯片中的组织如下图所示,其中每份 image 的开始地址都是以 512bytes 对齐的 .
一份标准的 image 由两部分组成: PCI Expansion ROM Header Format PCI Data Structure Format 具体的格式定义如下图:
PCIe Configuration Space基础知识学习_第10张图片 PCIe Configuration Space基础知识学习_第11张图片

 BIOSPOST阶段,扫描并执行pci设备的expansion rom的过程大概分以下几步:

a、首先判断pci设备是否实现“Expansion rom base address”寄存器,有则进行下一步判断;

#define PCI_DEVICE_ROMBAR             0x30

#define PCI_BRIDGE_ROMBAR             0x38

PCIe Configuration Space基础知识学习_第12张图片

PCIe Configuration Space基础知识学习_第13张图片

 b如果有实现了expansion的基址寄存器,则配置使能expansion rom(),然后查找expansion rom是否有”AA55”的标示字符,如果有则说明设备有真实的expansion rom芯片存在;

#define PCI_EXPANSION_ROM_HEADER_SIGNATURE              0xaa55

PCIe Configuration Space基础知识学习_第14张图片

 b-1 配置和使能expansion rom

PCIe Configuration Space基础知识学习_第15张图片

 Expansion Rom初始化过程与BAR一样,空间计算方法也一样,软件把“Expansion rom base address”寄存器的基地址配置成相应的memory空间地址并使能expansion rom以后,就可以对设备的expansion rom进行读访问了。

上图中,申请了32bit的1MBMmory Address Space;起始位置为:D8A0 0000h

b-2 查找expansion rom是否有”AA55”的标示字符

PCIe Configuration Space基础知识学习_第16张图片

一份标准的image由两部分组成:PCI Expansion ROM Header FormatPCI Data Structure Format。下面是真实的抓包中读取的一份image,有助于加深对image的理解,对照着 1.1.2.2 第二幅图看理解。     

Image0->PCI Expansion ROM Header

00h~03h 0x55AA0B E9
04h~07h 0x 9D00 3E00
08h~0Bh 0x0
0Ch~0Fh 0x0
10h~13h 0x 9700 0000
14h~17h 0x0000 8100
18h~1Bh 0x 1C00 4000 offset of  PCIR data structure

  Image0-> PCI Data Structure

1Ch~1Fh 0x50434952 ASCII 码: PCIR
20h~23h B315 1B10
24h~27h 900A 1C00
28h~2Bh 0302 0000
2Ch~2Fh 0B00 0100
30h~33h 00 00 0B00 

c、如果expansion rom已经存在,则扫描是否有适合本设备和本CPU架构的image代码存在;

d、如果有适合本环境的image代码存在,则把相应的代码拷贝到ram的合适位置,并跳入header format中指定的初始化入口执行;

PCIe Configuration Space基础知识学习_第17张图片

 e、最后关闭expansion rom的使能。 

( “还有, option rom 从来就不是在flash 上运行的,它必须先行copy RAM 上面,才能执行。”option rom这一部分还是只学会了概念性的东西,对于如何copy,如何映射,只知道表面概念,驱动的代码还没有深入理解。这一部分学得不是很好,可能要好好学习一下bios或者UEFI才可以吧)

1.1.3 Capabilities Pointer

在configuration space总述中,按照理解,如果存在capabilities链表,可以分为两个,一个在PCI configuration space中,在0x40~0xFF这段配置空间;一个在PCIe extended configuration space中,在0x100~0xFFF这段配置空间.

每个链表的结构如下图:

PCIe Configuration Space基础知识学习_第18张图片

 上图是0x40~0xFF这段配置空间capabilities链表的一个例子。链表的开始在Header中0x34处1byte的值。(0x100~0xFFF这段配置空间链表的结构类似,只是链表的开始在0x100处)

在PCI 总线的基本配置空间中,包含一个Capabilities Pointer 寄存器,该寄存器存放Capabilities 结构链表的头指针。

其中每一个Capability 结构都有唯一的ID 号,每一个Capability 寄存器都有一个指针,这个指针指向下一个Capability 结构,从而组成一个单向链表结构,这个链表的最后一个Capability 结构的指针为0

看实际的包,加深一下理解:

PCIe Configuration Space基础知识学习_第19张图片

PCIe Configuration Space基础知识学习_第20张图片

(后续学习,对每个register都有深入一些的理解后,再补充进来一些。)

 1.2 Type 1 Configuration Space Header

PCIe Configuration Space基础知识学习_第21张图片

该部分也只简单说一些我对着某些register的学习(及理解)。和Type0中名称一致的register用途一样,不再累述。

 1.2.1  Primary Bus Number Register、Secondary Bus Number Register、Subordinate Bus Number Register

Subordinate Bus Number Register 存放当前 PCI 树中,编号最大的 PCI 总线号; Secondary Bus Number Register 存放当前 PCI 桥的 Secondary Bus 使用的总线号,是该 PCI 桥管理的编号最小的 PCI 总线号。因此一个 PCI 桥能管理的 PCI 总线号在 Secondary Bus Number ~ Subordinate Bus Number 之间,两个寄存器的值在软件系统遍历 PCI 总树时设置。 Primary Bus Number Register 存放该 PCI 桥上游的总线号。该寄存器可读写。

 1.2.2 Base/ Limit Registers

Base Limit 寄存器分别确定了其所有分支下设备( The device that live beneath this bridge )的地址的起始和结束地址。根据请求类型的不同,分别对应不同的 Limit&Base 组合:
Prefetchable Memory Space P-MMIO
Non- Prefetchable Memory Space NP-MMIO
IO Space IO

一旦该桥分支下面的任意设备的BAR发生改变,该桥的Base&Limit寄存器也需要做出对应的改变。

PCIe扫盲——Base & Limit寄存器详解-Felix-电子技术应用-AET-中国科技核心期刊-最丰富的电子设计资源平台 (chinaaet.com)http://blog.chinaaet.com/justlxy/p/5100053321

2. PCI configuration Space——0x40~0xFF

上面提到这里面存放一些和中断以及电源管理相关的capabilities,在spec中主要讲了PCI Power Management Capability和PCI EXpress capability。(累了不想写了,先把图放上去,其实这里需要看哪个bit概念含义对着spec看就行了,register太多了。等后期有经验,哪个bit需要着重关注,再补充)

2.1 PCI Power Management Capability

PCIe Configuration Space基础知识学习_第22张图片

PCIe Configuration Space基础知识学习_第23张图片

该寄存器主要用来记录当前PCIe设备的物理属性

系统软件需要从该寄存器获得当前PCIe设备的信息后,才能对PMCSR进行修改

PCIe Configuration Space基础知识学习_第24张图片

系统软件可以通过操作 PMCSR 寄存器,完成 PCIe 设备电源管理状态的迁移

  2.2 PCI EXpress capability

PCIe Configuration Space基础知识学习_第25张图片

 3. PCI Express Extended configuration space——0x100~0xFFF

 这段配置空间存放PCIe独有的capabilities,链表的开始在0x100,其余规则与PCI configuration space 中的capabilities链表方式一致。

PCIe Configuration Space基础知识学习_第26张图片

PCIe Configuration Space基础知识学习_第27张图片

三、总结

只学习了整体概念,具体到每一个capabilities、register的学习还需要进一步的展开,离大神还有很远很远很远很远……很远的很远的距离~以上纯属个人学习理解,应该会有很多小错误。

option rom 学习过程参考链接:

https://maxwell.blog.csdn.net/article/details/51785335

https://blog.csdn.net/Lq19880521/article/details/106078561

https://blog.csdn.net/luobing4365/article/details/102577039?spm=1001.2014.3001.5501

BIOS/UEFI 学习过程参考链接:

https://www.zhihu.com/question/28815746

https://zhuanlan.zhihu.com/p/45352657

https://blog.csdn.net/cqwei1987/article/details/107365329

https://zhuanlan.zhihu.com/p/336441128

你可能感兴趣的:(学习笔记,pci-e)