当前位置: 首页 > article >正文

MindShare PCIE 3.0 笔记-第三四章

MindShare 官网,地址如下:
MindShare

Charpter 3: Configuration 概述

主要介绍 PCIe 驱动对 PCIE 设备中 function 的 Config Header 的访问.

1. 总线、设备与功能定义

每一个 PCIE function 都是独一无二的,通过设备号与总线号区分。

2. PCIe 总线

PCIe 最多可以分配 256 个总线总线号,总线 0 在 Root Complex 中,由硬件分配。总线 0 下挂一个或多个 PCI-PCI bridge。

每一个 PCI-PCI bridge 都会创建一个新总线。

pcie 驱动从 bus0,device0, funcion0 开始查找,如果查找到一个 PCIE Bridge,PCIE 驱动就分配一个新的总线号。(枚举过程)

3. PCIe 设备

允许 32 个设备连接到同一个 PCIE 总线,但是 PCIE 是点对点的连接,意味着只有一个设备可以连接到 PCIE 链路,这个设备总是设备 0.
但是 Root Complex 与 Switch 内部存在一条虚拟总线,这个虚拟总线允许多个设备连接。

所以需要使用 Switch 来扩展 pcie 拓扑结构

4. PCIe 功能

每个设备都必须实现 function 0, 每一个设备最多实现 8 个 function, function 编号不必连续。

每一个 function 都有自己的配置空间。

5.示例的 PCIe 拓扑结构

下图展示了一个 PCIe 示例拓扑结构中 bus, device, function 分配与使用:
在这里插入图片描述

6. 配置地址空间

PCIe 设备为每一个 function 定义了一个专用的配置空间块。配置空间前 64 字节为 PCI 兼容配置空间。

配置空间的剩余 192 字节可以实现一些可选的功能结构。
PCIE 必须实现如下的功能结构:

  1. PCIe 功能结构
  2. 电源管理
  3. MSI、MSI-X

7. 64 字节 PCI 兼容配置空间

64 字节 PCI 兼容配置空间如下:
在这里插入图片描述

8. 扩展配置空间- 4KB PCIe Configuration Space

PCIe 诞生时,256 字节配置空间不足以包含所有的功能结构,所以将 256 字节配置空间扩展为 4KB,前 64 字节依旧为 PCI 兼容配置空间:
在这里插入图片描述

9. Host-PCI Bridge 配置空间

Host-PCI Bridge 是一个特殊的设备,位于 Root Complex 中,接受 CPU 的请求,并转换为标准 PCI 请求。代表 CPU 与下游 PCIe 设备通信。

Host-PCI Bridge 的配置空间实现是基于芯片的,不同 SOC 厂商也许有不同的实现,且通过内存映射的寄存器访问。

10. 只有 Root-Complex 可以发起配置请求

Root Complex 作为 CPU 代言人,只有 Root Complex 可以发起配置请求。

Root Complex 基于设备的总线号、设备号与功能号配置下游的设备。

11. 配置空间请求事务的生成

CPU 由于只能访问地址,所以不能直接生成 PCI 的配置读、写请求,需要 Root Complex 将地址访问翻译为对应的 pci 配置请求。

配置空间能通过两种方式访问:
1. 传统 PCI 配置机制,使用 I/O 间接访问(x86 处理器?);
2. 增强型的配置机制,使用内存映射访问。

12. 传统 PCI 配置机制 - I/O 间接访问(x86? ARM不使用)

使用两个 4 字节的 I/O 地址空间的寄存器实现配置空间的间接访问。

  • Configuration Address Port: 0xCF8
  • Configuration Data Port: 0xCFC

Configuration Address Port 寄存器位域说明如下:
在这里插入图片描述

13. 总线比较与数据端口访问

PCI bridge 实现一个 Secondary Bus Number Register (次级总线号寄存器)和一个 Subordinate Bus Number Register (下属总线号寄存器)。

次级总线号是 bridge 之下的第一个总线号;

下属总线号是 bridge 之下的最大的一个活跃目标总线号

当 Bridge 收到一个配置请求,会对比目标总线号是否在 secondary Bus number 与 Subordinate Bus number 之间,如果在,说明目标设备是当前总线的下游设备。

如果目标总线号与次级总线号相等,那么 bridge 会发送 Type 0 Request(硬件数据包类型)。

如果目标总线号在 secondary Bus number 与 Subordinate Bus number 之间,那么 bridge 会发送 Type 1 Request.

下图为次级总线号与下属总线号分配示例:
在这里插入图片描述

14. 增强型配置访问机制 - 地址映射访问(ARM,我们主要使用)

增强型配置访问机制使用地址映射的机制访问配置空间。

使用增强型配置访问机制,每一个 function 需要 4KB 配置空间,一个 PCIE 架构需要 256MB 配置空间。

地址映射中位域定义如下表:

位域描述
bit[63:28]配置空间 256MB 对齐,表示配置空间的高位,具体值由 SOC 芯片厂商确定
bit[27:20]Bus Number - [0 : 255]
bit[19:15]Device Number - [0 : 31]
bit[14:12]Function Number - [0 : 7]
bit[11: 2]4KB 配置空间内寄存器偏移,4字节对齐
bit[ 1: 0]定义访问的大小与字节使能设置(不清楚,默认0?)。

直接访问上述位域组成的地址,可访问任一 bus / dev / func 的配置空间。

比如:

mov ax,[E0400000h];memory-mapped Config read,16bit 读访问

上述 16 位内存读请求,表示访问 Bus 4, Dev0, Function 0, Register 0(Vendor ID 寄存器)。

PCIe 配置读请求发送流程如下图:
在这里插入图片描述

15. 配置空间访问请求

这是硬件相关的,软件不需要太关心。

Bridge 可以翻译生成 Type0 与 Type1 两种配置请求,当目标总线是当前 bridge 的次级总线时,生成 Type 0 请求,当目标请求是下属总线时,生成 Type 1 请求。

16. PCIe 系统枚举

系统上电后,pcie 驱动必须扫描整个 pcie 拓扑结构,用于分配 Bus Number,扫描过程称为枚举。

PCI-PCI bridge 的上行端口连接主级(上级)总线,bridge 的下行端口连接次级总线

系统上电后,驱动只能确定 Root Complex 中的 Host/PCI Bridge 与 bus 0 存在。
在这里插入图片描述
Root Complex 中的 Host-PCI Bridge 没有上级总线,只有作为 bus 0 的次级总线

17. 查找 function 是否存在

因为每一个 function 都有 4KB 的 configuration space。

所以 pcie 驱动通常使用读 Vendor ID 寄存器的方法来发现一个设备。Vendor ID 由 PCI-SIG 分配,并被硬件编码进 Vendor ID 寄存器。

通过组合不同的 bus, device, function,读对应的配置空间 Vendor ID 寄存器,驱动可以查找到系统存在的所有设备。

PCIe 驱动读 Vendor ID 寄存器时,返回 0xFFFF, 即表示当前设备不存在。

(也存在一种情况,设备存在,但未准备好响应配置读请求。)

18. 确定 function 类型:Endpint 或 bridge

标准的 PCIe 枚举处理能够确定一个function 是否为终端或 bridge。

Header Type 位域的低 7 位,可以用于确定 Function 类型:

  • 0 为终端设备;

  • 1 表示 PCI- PCI bridge

  • 2 表示 CardBus Bridge(不再使用)

位域图如下:
在这里插入图片描述

19. 上电枚举示例

首先贴出如下的上电枚举完成后 ,bus 分配结果图:
在这里插入图片描述
上电启动后,驱动执行枚举:

  1. 软件更新 Host-PCI Bridge 的 Secondary Bus Number 寄存器为 0,并设备 Subordinate Bus Number 寄存器为 255.(这是 Root Complex Controller 的内存控制寄存器?操作外设控制器?)
  2. 从 bus 0- device 0 - function 0 开始枚举, 尝试读取 Vendor ID, 如果 Vendor ID 存在,那么说明当前 device 存在且包含至少 1 个 function, 如果没有返回有效的 Vendor ID, 那么说明当前设备不存在,因为每一个 device 必须实现 function 0。
  3. bus 0- device 0 - function 0 的配置空间对应 Bridge A 的配置头,Header Type 位域值为 01h, 表示这是一个桥,Header Type 位域 bit7 = 0, 表示这是一个单 function 设备。
  4. 驱动的枚举过程查找到了一个 bridge 桥,那么分配总线号:
    • Primary Bus Number Register = 0 : 上级总线号为 0 号总线
    • Secondary Bus Number Register = 1 : 下级总线号为 1 号总线
    • Subordinate Bus Number Register = 255 : 最大活跃下级总线号暂时设置为 255(以便执行一个深度优先的枚举)
  5. 驱动必须执行一个深度优先的枚举,所以此时应该优先枚举 bus1 下的设备,而不是 bus 0 的其他设备。
  6. 驱动继续枚举 bus 1 - device 0 - function 0, 尝试读取 Vendor ID, 返回 Bridge C 的 Vendor ID,Header Type 位域值为 01h, 表示这是一个桥,Header Type 位域 bit7 = 0, 表示这是一个单 function 设备。
  7. Bridge C 的 Header Type 位域值为 0x01, 表示这是一个 PCI Bridge,Header Type 位域 bit7 = 0, 表示这是一个单 function 设备。
  8. 驱动的枚举过程查找到了一个 bridge, 那么分配总线号:
    • Primary Bus Number Register = 1 : 上级总线号为 1 号总线
    • Secondary Bus Number Register = 2 : 下级总线号为 2 号总线
    • Subordinate Bus Number Register = 255 : 最大活跃下级总线号暂时设置为 255(以便执行一个深度优先的枚举)
  9. 驱动继续执行一个深度优先的枚举,枚举 bus 2 - device 0 - function 0, 也就是对应 Bridge D.

Chapter 4: 地址空间与传输路由

本章描述 Endpoint/Bridge 的 function 通过 BAR 寄存器请求地址空间,驱动必须设置所有 bridge 的 Base/Limit 寄存器来正确路由 TLP。

1. 三种内存地址空间

大多数 PCIE 设备都存在内部寄存器和存储区, 意味着 PCIE 设备需要把内部寄存器与存储区映射到 CPU 可寻址的内存地址空间。

PCIE 支持三种内存地址空间:

  1. Configuration Space
  2. Memory Space
  3. I/O Space

2. 配置空间

前面的章节已经说明,配置空间用来控制与检查设备状态,每一个 PCIE 设备的 Function 都有专门的配置空间。

3. Memory 与 I/O 空间

早期的 intel 处理器,通过 I/O 地址空间来访问 I/O 设备的内部寄存器和存储区。

但如今 I/O 设备的寄存器和存储区被映射到内存地址空间,称为 MMIO(内存映射 I/O 设备)。

PCIE 规范也不鼓励使用 I/O 地址空间来映射设备寄存器和存储区

PCIe 可以支持将内存地址映射到 64bit Mem 空间。

不仅 Endpoint 可以使用 MMIO 来访问,switch 与 Root Complex 也可以使用 MMIO 访问特有的寄存器(Root Complex 也包含 PCI-PCI Bridge)。

4. Prefetchable 与 Non-Prefetchable Mem 空间

Perfetchable Memory 存在下列优良的属性:

  1. 读取没有副作用
  2. 允许写合并

如果一个内存区域被定义为 Perfetchable,那么该区域的数据被允许提前准备好,以便请求者下一步读取(类似 CPU 的提取预测,用于提升性能)。

问:什么样的内存空间读取存在副作用?

答:内存映射的状态寄存器,如果设计为读清除时,那么读取可能存在副作用。

Pcie 设备内存映射示例:
在这里插入图片描述

5. Base Address Registers (BARs)

每一个 PCIE 设备可能需要映射不同的地址空间类型和大小。

pcie 设备不能决定自身内部寄存器与存储区在内存空间的位置,这应该由系统的 pcie 驱动决定.

因此 pcie 设备需要提供一种方式,供驱动确定设备需要的地址空间类型与大小。

如果可以满足 pcie 设备的地址要求,那么驱动会分配合适的地址类型与大小。

pcie 设备通过 Configuration Header 的 Base Address Registers(BAR)指示 PCIE 驱动应该分配地址类型与大小。

Type 0 Header (Endpoint) 有 6 个 32 位的 BAR 寄存器。

Type 1 Header (Bridge) 有 2 个 32 位的 BAR 寄存器。

Pcie 设备的设计者将 pcie 设备所需要的地址与类型信息硬件编码到 BARs 的低位

Type 0 Header 拥有 6 个 BAR,那么最多可以为设备分配 6 个不同的地址空间(只要 pcie 设备对 BAR 的低位进行了硬件编码)

如果一个 BAR 寄存器被硬件编码为全 0(写 1 无效),那么表示驱动不需要为当前 BAR 进行内存映射。

BAR 寄存器在 Header 中的位置如下:
在这里插入图片描述
一旦 BAR 被编码,那么可以通过内存映射的形式访问 pcie 设备的寄存器和地址空间。内存访问的地址必须是 BAR 设置的地址范围之内。

6. 32 位内存空间映射请求 - BAR 配置示例

在本例中,PCIe 设备的 function 的 BAR0 请求一个 4KB 的 Non-Prefetchable memory(NP-MMIO) 用于映射本身的寄存器与存储区。

BAR 配置图解如下:
在这里插入图片描述
BAR 配置过程如下:

  1. 在上图的(1)中展示了未初始化的 BAR0,BAR0 的低位保存着 pcie 设备设计者硬件编码的内存映射大小与类型。PCIE 驱动首先写全 1 到每一个 BAR 来设置所有的可写位(低位的硬件编码位不受影响)。

  2. 写每一个 BAR 寄存器为 1 后,驱动读回 BAR 寄存器, 如上图中的(2),从 BAR0 开始,来确定 pcie 设备请求的地址空间大小与类型。 写全 1 后,最低有效位指示了 pcie 设备需要的内存地址空间(低 4 位不算最低有效位)。

    • 上例中,读回的结果为 0xFFFF F000, 各位域描述如下图:在这里插入图片描述
    BAR 位域描述
    bit 00 表示请求映射 Mem 空间,1表示请求映射 I/O 空间,本例中,读回为 0
    bit[2:1]00 表示请求映射 32 位 Mem, 10 表示请求映射 64 位 Mem, 本例中,读回为 0b00
    bit30 表示请求映射 non-prefetchable mem, 1 表示请求映射 prefetchable Mem, 本例中读回为 0
    bit[11: 4]本例中硬件编码为全0,读回为0
    bit[31:12]本例中读回为全1,最低有效位 bit12 = 1, 表示请求映射的内存大小 2^12 = 4KB
  3. 最后一步是为当前 BAR 分配合适的地址范围, 如上图中的(3), 本例中 BAR0 地址映射请求被映射到 0xF900_0000 - 0xF900_0FFF。

BAR0 寄存器编码后,一旦驱动使能 Command Register(04h),pcie 设备会接收内存访问请求。

7. 64位内存空间映射请求 - BAR 配置示例

当 BAR 指示请求映射的内存类型为 64 位内存时,此时使用两个连续的 BAR 被用来支持 64 位地址映射请求。

在本例中, BAR1 与 BAR2 被用来请求 64MB 的 64bit Prefetchable-Memory 用于映射自身的寄存器与存储区.

BAR 配置图解如下:
在这里插入图片描述
BAR 配置过程如下:

  1. 上图中,(1)展示了 BAR 未初始化的状态内容,pcie 设备设计者硬件编码了 BAR1 的低位,用来指示请求映射的地址类型与大小。上图中,(2)展示了BAR1 与 BAR2 已被全写为 1 的寄存器内容。

  2. PCIE 驱动读回 BAR1,发现 BAR1 请求 64 bit 地址空间,所以驱动会将 BAR2 作为 64-bit 的高位,并读取 BAR2, 此时 BAR2 的低 4 位不在指示请求映射的地址类型。读回的寄存器位域解释如下:

    BAR1/2 位域描述
    BAR1- bit0读回为 0,指示请求映射 Memory 内存空间
    BAR1- bit[2:1]读回为 0b10, 指示请求的是 64bit Mem, 此时驱动会将 BAR2 会作为 64bit 的高 32 位
    BAR1- bit3读回为 1, 指示请求映射的是 prefetchable Mem
    BAR1- bit[25:4]读回为全 0,硬件编码为 0,表示请求映射的内存大小
    BAR1- bit[31:26]读回为全 1,最低有效位为 1,表示请求映射的内存大小为 2^26 = 64MB
    BAR2-bit[31:0]读回为全1,64bit Mem 的高32位
  3. 最后一步是驱动分配合适的地址空间类型与大小,并设置 BAR2-BAR1。

BAR 配置完成后,只要驱动使能 Command Register(04h),那么可以进行内存访问。

8. I/O 空间映射请求 - BAR 配置示例

(略, ARM 不需要配置)

9. 所有的 BAR 寄存器必须按顺序配置

如果不存在地址映射请求,那么 BAR 会被硬件编码为全0,也就是写 1 无效。

即使存在一个 BAR 为全0,依然要配置接下来的 BAR,即所有的 BAR 都需要尝试配置,因为 function 设计者可能不会选择 BAR0 作为设备的地址映射请求。

10. Bridge 设备 Header 中的 Base 与 Limit 寄存器

只要 function 的 BARs 被编码,那么 function 就获得使用的地址映射范围。

每一个 bridge 需要知道下游设备的地址映射范围,以便于将上级总线的事务,转发给下级总线。

在 Type 1 Header 中存在 Base 与 Limit 寄存器用于保存下游设备的地址映射范围,也就是 BAR 映射的地址范围.

Bridge 的存在 3 类 Base 与 Limit 寄存器需要设置, 对应三种内存空间:

  1. Prefetchable Mem
  2. Non-Prefetchable Mem
  3. I/O Space

11. Bridge 设备中 Prefetchable Mem Base/Limit 寄存器

Type 1 header 拥有两对 prefetchable memory base/limit register:

  1. Prefetchable Memory Base/Limit registers
  2. Prefetchable Memory Base/Limit registers upper 32 bits

两对 prefetchable memory base/limit register 位置如下图,寄存器值设置为上述(第 7 点)配置的值:在这里插入图片描述
寄存器解释如下:

寄存器描述
Prefetchable Memory Base0x400116位的寄存器,高 12 位用于保存地址映射的 bit[31:20], 低 4 位,为 1 时,表示使用 64 bit Mem,为 0 时表示使用 32位 Mem
Prefetchable Memory Limit0x43f116位的寄存器,高 12 位用于保存地址映射的 bit[31:20], 低 4 位,为 1 时,表示使用 64 bit Mem,为 0 时表示使用 32位 Mem
Prefetchable Memory Base Upper 32 Bits0x232 Bit 寄存器, 保存 64 位地址映射的 bit[63:32]
Prefetchable Memory Limit Upper 32 Bits0x232 Bit 寄存器, 保存 64 位地址映射的 bit[63:32]

(只有 prefetchable 内存支持 64 bit 地址映射)

12. Non-Prefetchable Mem Base/Limit 寄存器

bridge 的不可预取内存映射范围。

type 1 header 只支持 32 位的 Non-Perfetchable Mem.只有一对 16 位的 BASE/Limit 寄存器对用于指示地址范围:

  1. Memory Base
  2. Memory Limit

Memory base/limit register 位置如下图,寄存器值设置为上述(第 6 点)配置的值:在这里插入图片描述
寄存器解释如下:

寄存器描述
(Non‐Prefetchable) Memory Base0xF90016 位的寄存器,高 12 位存储不可预取内存地址的 Bit[31:20], 低 4 位固定为 0
(Non‐Prefetchable) Memory Limit0xF90016 位的寄存器,高 12 位存储不可预取内存地址的 Bit[31:20], 低 4 位固定为 0

bridge 对于内存的最小配置范围是 1MB ,那么即使下游端点使用不到 1MB,空余的地址范围依旧不允许分配给其他设备。

13. Bridge 设备中 I/O 范围

类似 Mem Base/Limit, Type 1 Header也有两对 Base/Limit 用于配置 I/O 空间。
在这里插入图片描述
寄存器解释:略

14. Bridge 未使用 Base 与 Limit 寄存器

并不是所有的 pcie 设备会使用 3 种类型的地址空间,实际上 pcie 规范不鼓励使用 I/O 空间。

如果 Bridge 的下游 endpoint 没有请求 I/O 地址空间,那么可以把 I/O Base 设置为比 I/O Limit 大,以此种形式来表明,当前 bridge 的下游设备未映射 I/O 空间。

15. PCIE 事务通过 Base/Limit 实现地址路由,将 pcie 数据包发送给对应设备

系统枚举的分配 bus 号用来干嘛?(读/写配置空间)

当 cpu 内存访问的地址在某一个 BASE:Limit 范围内时, brige 会路由pcie 数据到下级总线。示例如下图:在这里插入图片描述


http://www.kler.cn/a/377927.html

相关文章:

  • 车载网关性能 --- GW ECU报文(message)处理机制的技术解析
  • LightGBM分类算法在医疗数据挖掘中的深度探索与应用创新(上)
  • 【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
  • 网络安全概论——身份认证
  • STM32F103 | Embedded IDE03 - 使用OpenOCD在STM32F103项目时出现下载固件失败
  • 36. Three.js案例-创建带光照和阴影的球体与平面
  • Spring Boot技术:校园社团信息管理的革新者
  • 小柴带你学AutoSar系列三、标准和规范篇(4)RTE
  • C语言另一种编码方式开发状态机(无switch)
  • MySQL有关基础查询的知识点
  • Fetch 请求不支持取消操作的问题及解决方案
  • GaussDB和Oracle的语法对比
  • 使用RabbitMQ实现微服务间的异步消息传递
  • Java学习教程,从入门到精通,Java 循环结构:while 和 do...while(17)
  • 2024年 · 地表最强的十大遥感影像分割模型
  • Js内建对象
  • 10个领先的增强现实平台【AR】
  • uniapp 使用uni.getRecorderManager录音,wav格式采样率低于44100,音频播放不了问题解决
  • 无人机敏捷反制技术算法详解!
  • 同一个页面击穿element样式后,会影响同样组件的使用
  • C#与C++交互开发系列(二十):跨进程通信之共享内存(Shared Memory)
  • 论文阅读:Computational Long Exposure Mobile Photography (一)
  • [SICTF Round4] Crypto
  • 简易了解Pytorch中的@ 和 * 运算符(附Demo)
  • 图优化以及如何将信息矩阵添加到残差
  • 网络编程项目之UDP聊天室