深入解析PCIe地址空间与寄存器机制:从地址映射到TLP生成的完整流程

devtools/2024/12/22 16:36:01/

往期内容

本文章相关专栏往期内容,PCI/PCIe子系统专栏:

  1. 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入
  2. 深入解析非桥PCI设备的访问和配置方法
  3. PCI桥设备的访问方法、软件角度讲解PCIe设备的硬件结构
  4. 深入解析PCIe设备事务层与配置过程
  5. PCIe的三种路由方式
  6. PCI驱动与AXI总线框架解析(RK3399)

Uart子系统专栏:

  1. 专栏地址:Uart子系统
  2. Linux内核早期打印机制与RS485通信技术
    – 末片,有专栏内容观看顺序

interrupt子系统专栏:

  1. 专栏地址:interrupt子系统
  2. Linux 链式与层级中断控制器讲解:原理与驱动开发
    – 末片,有专栏内容观看顺序

pinctrl和gpio子系统专栏:

  1. 专栏地址:pinctrl和gpio子系统

  2. 编写虚拟的GPIO控制器的驱动程序:和pinctrl的交互使用

    – 末片,有专栏内容观看顺序

input子系统专栏:

  1. 专栏地址:input子系统
  2. input角度:I2C触摸屏驱动分析和编写一个简单的I2C驱动程序
    – 末片,有专栏内容观看顺序

I2C子系统专栏:

  1. 专栏地址:IIC子系统
  2. 具体芯片的IIC控制器驱动程序分析:i2c-imx.c-CSDN博客
    – 末篇,有专栏内容观看顺序

总线和设备树专栏:

  1. 专栏地址:总线和设备树
  2. 设备树与 Linux 内核设备驱动模型的整合-CSDN博客
    – 末篇,有专栏内容观看顺序

img

目录

  • 往期内容
  • 1.地址空间和寄存器介绍
    • 1.1 地址空间
    • 1.2 寄存器介绍
      • 注 -- 配置空间和寄存器
      • 1.2.1 用于配置空间
      • 1.2.2 用于内存和IO
  • 2.访问示例
    • 2.1 配置空间读写
    • 2.2 MEM/IO读写示例

1.地址空间和寄存器介绍

1.1 地址空间

从PCIe的角度来看,内部总线可寻址资源分为两个地址空间。也就是说,PCIe有两个地址空间。第一个专用于内部寄存器,第二个专用于远程设备。cpu发出的地址信息范围符合这两个地址空间的范围

  1. 内部寄存器
  • Client Register Set:地址范围 0xFD000000~0xFD7FFFFF,比如选择PCIe协议的版本(Gen1/Gen2)、电源控制等
  • Core Register Set :地址范围 0xFD800000~0xFDFFFFFF,所谓核心寄存器就是用来进行设置地址映射的寄存器等
  • img
  1. 远程设备
  • Region 0:0xF8000000~0xF9FFFFFF , 32MB,用于访问外接的PCIe设备的配置空间
  • Region 1:0xFA000000~0xFA0FFFFF,1MB,用于地址转换
  • Region 2:0xFA100000~0xFA1FFFFF,1MB,用于地址转换
  • ……
  • Region 32:0xFBF00000~0xFBFFFFFF,1MB,用于地址转换
  • 其中Region 0大小为32MB,Region1~31大小分别为1MB。
  • img

远程设备的映射,总大小为64
MB,基址为0xF8000000,共分为33个区域,以下方程式描述了如何选择0到32的区域。区域0由A[RW]ADDR[25]==0解码,区域大小为32M字节。当A[RW]ADDR[25]==1时,区域1至32(配置的区域数量)由区域x=A[RW]ADDR[24:20]+1解码:

  • Region 00xF8000000~0xF9FFFFFF,大小为32 MB。

  • Region 1 到 32:每个大小为1 MB,共32个区域。

  • 区域0通过 A[RW]ADDR[25] == 0 来选择,表示当 A[RW]ADDR 的第25位为0时,选择 Region 0,其大小为 32 MB。

  • A[RW]ADDR[25] == 1 时,选择 Region 1 到 32,这些区域通过以下公式选择:

    • 区域 x = A[RW]ADDR[24:20] + 1

注意:A[RW]ADDR[25] 是地址信号的第 25 位, A[RW] 是区分读地址的信号还是写地址的信号

这些Region存在于PCIe控制器内部,并且是由控制器通过寄存器进行管理和配置的。

  • Region 的作用:

    • 每个 Region 代表了PCIe控制器中用于访问外部PCIe设备的一部分地址空间。
    • CPU发出的地址如果在某个 Region 内,那么这个地址会被映射到相应的PCIe外设上。
  • Region 是在 PCIe 控制器内部管理的:

    • 这些Region并不直接对应外设,而是PCIe控制器内部用来定义访问哪些外设,或者配置空间的一个机制。通过这些Region,PCIe控制器可以管理和调度外部PCIe设备的访问。
    • PCIe控制器通过寄存器(如ob_addr0, ob_desc0等)来描述和管理这些Region。寄存器会包含如何将主机的地址转换为PCIe TLP,以及如何访问外设。
  • 外部设备的配置空间:

    • 例如,Region 0 可能用于外部PCIe设备的配置空间,允许主机通过该Region访问PCIe设备的配置寄存器。
    • Region 1~32 可能用于外设的内存访问(例如设备的BAR空间)。

CPU访问Region 0的地址时,将会导致PCIe控制器发出读写配置空间的TLP。

CPU访问Region 1~32的地址时,将会导致PCIe控制器发出读写内存、IO空间的TLP。

1.2 寄存器介绍

CPU访问一个地址,导致PCIe控制器发出TLP。TLP里含有PCIe地址、其他信息。

这些寄存器必定涉及这2部分:

  • 地址转换:把CPU地址转换为PCIe地址
  • 提供TLP的其他信息

Region0、Region1~32,每个Region都有类似的寄存器。

一个Region,可以用于读写配置空间,可以用于读写内存空间、可以用于读写IO空间,还可以用于读写消息。

这由Region对应的寄存器决定。

每个Region都有一样寄存器,以Region 0为例,有6个寄存器:

img

CPU访问某个Region时,它是想干嘛?

  • 读写配置空间、发出对应TLP?
  • 读写内存空间、发出对应TLP?
  • 读写IO空间、发出对应TLP?
  • 读写消息、发出对应TLP?

到底是发出哪种TLP,由Region对应的ob _desc0寄存器决定:

ob_desc0[3:0]作用
1010发出的TLP用于访问Type 0的配置空间
1011发出的TLP用于访问Type 1的配置空间
0010发出的TLP用于读写内存空间
0110发出的TLP用于读写IO空间
1100发出的TLP是"Normal Message"
1101发出的TLP是"Vendor-Defined Message"

CPU访问某个Region时,最终都是要发出TLP,TLP的内容怎么确定?

  • 地址信息:ob_addr0/1把CPU地址转换为PCIe地址,提供TLP里面的地址信息
  • 其他信息:ob_desc0/1/2/3提供TLP的其他信息

注 – 配置空间和寄存器

img

img

这提到的两个地址怎么不一样?

Region 0 的地址范围为 0xF8000000 ~ 0xF9FFFFFF,表示这是 32MB 的内存区域,用于访问外部 PCIe 设备的配置空间。这是地址空间,即主机通过 PCIe 总线访问外部设备时使用的实际物理地址。

而在寄存器表中提到的 Region 0 Outbound Config Registers,如
ob_addr0ob_addr1 等,则是配置这些设备地址空间的控制寄存器。这个寄存器范围从 0x000
开始,表示这是主机内部的配置寄存器的偏移地址。它们在PCIe控制器内部,并用于设置 PCIe 控制器如何管理和访问这些设备的地址空间。

区别与联系:

  • Region 0 (0xF8000000 ~ 0xF9FFFFFF) 是外部设备的实际内存空间,主机可以通过这个范围访问连接的 PCIe 设备。
  • Outbound Config Registers(例如 ob_addr0, ob_addr1, ob_desc0 等)是用于配置和映射这个设备地址空间的控制寄存器。通过这些寄存器,可以指定设备如何响应主机的内存访问请求,或者主机如何通过这些配置寄存器访问PCIe设备。

配置流程:

  1. 配置阶段

    • 主机首先通过控制器的配置寄存器(如 ob_addr0ob_desc0 等)来设置如何映射外部设备的地址空间。这些寄存器通常位于PCIe控制器内部。
    • 通过这些寄存器,主机可以指定外部设备的基地址、大小、访问方式等信息。也就是说,主机通过这些寄存器告诉PCIe控制器:当我访问某个特定的地址区间时,我希望它指向某个PCIe设备。
  2. 访问阶段

    • 一旦配置完成,主机就可以通过特定的地址空间(例如 0xF8000000 ~ 0xF9FFFFFF 这样的外部设备地址空间)访问外部PCIe设备。
    • 当主机试图访问这些地址空间时,PCIe控制器会根据配置寄存器中的设置,将这些访问请求转换并转发给实际的外部PCIe设备。

举例说明:

  • 配置阶段:主机通过 ob_addr0 等寄存器,将控制器配置空间的0xF8000000 (Region0)这一段内存映射到某个外部 PCIe 设备的寄存器或内存空间。例如,0xF8000000 可以映射到一个 PCIe
    网络卡的配置空间。
  • 访问阶段:当主机读取或写入 0xF8000000 这一地址时,实际上是在和这个 PCIe 网络卡进行通信。PCIe控制器负责将这个请求转发给外部设备,并将设备的响应返回给主机。

疑问: CPU发出地址信息,落在PCIe控制器对应的地址空间上,地址空间对应的(比如Region0)PCIe控制器中的寄存器根据region0中的信息去解析,然后寄存器就发出TLP到对应的PCIe外设,去设置/访问PCIe外设的配置空间(地址空间) ???

1. CPU发出地址请求:

CPU发出一个内存读写请求(可能是访问PCIe外设的配置空间或内存空间),该请求的地址落入了PCIe控制器的地址空间。例如,落在了提到的Region
0
(用于PCIe设备的配置空间),设置了里面Region0空间里面的信息。

2. 地址请求到达PCIe控制器:

该地址请求进入了PCIe控制器。在PCIe控制器中,每个Region(如Region 0、Region
1等)通过对应的寄存器(例如ob_addr0ob_desc0等)来解析这个请求,决定如何处理。

  • ob_addr0ob_addr1 寄存器定义了CPU AXI地址如何映射到PCIe设备的地址空间。
  • desc0等描述符寄存器包含了如何生成PCIe TLP的具体信息,尤其是TLP头部的信息。

3. 寄存器生成TLP:

PCIe控制器通过这些寄存器,生成TLP(Transaction Layer
Packet)
。TLP是PCIe协议中用于通信的基本单位,负责在主机和PCIe设备之间传递读写请求、配置请求等。

  • 例如,当CPU需要访问某个PCIe外设的配置空间时,PCIe控制器根据Region 0的寄存器配置,生成一个配置写配置读的TLP。

4. TLP发送到PCIe外设:

生成的TLP包通过PCIe链路发送到目标PCIe设备。TLP包会包含地址、操作类型(读/写)、数据等信息。

5. PCIe外设接收并执行:

PCIe设备接收到TLP包后,会根据TLP中的地址和操作类型,执行相应的操作。例如:

  • 如果是写操作,PCIe设备会更新其配置空间或内存。
  • 如果是读操作,PCIe设备会返回读取的数据。

6. PCIe设备的响应:

如果是读请求,PCIe设备会返回相应的读响应TLP。PCIe控制器接收到这个响应后,会将结果转换为主机能够理解的形式,并返回给CPU。

大概:

  • CPU发出的请求首先到达PCIe控制器。
  • PCIe控制器通过配置寄存器(如ob_addr0ob_desc0等)解析和生成TLP。
  • TLP发送到PCIe外设,执行相应的操作。
  • 最终,PCIe设备的响应(如数据读取)通过TLP返回给CPU。

在这个过程中,寄存器起到桥接CPU的地址请求和PCIe外设地址空间的作用。它们负责地址映射和生成正确的TLP,从而实现主机和PCIe设备的通信。

CPU去设置PCIe控制器的Region中的信息,PCIe控制器中的寄存器(肯定是需要先去设置好reg才行)去解析Region中的信息然后发出TPL

img

PCIe设备内部的配置空间和寄存器的关系???

配置空间是PCIe设备中访问寄存器的一种机制和入口。它定义了设备的控制和状态寄存器的位置和访问方式。**可以把配置空间看作是设备寄存器访问的"目录",而寄存器是具体的操作和状态信息。**寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。

  • 配置空间中的寄存器:在PCIe配置空间中,有专门的控制和状态寄存器,这些寄存器的内容定义了设备的行为。例如:

    • Command Register:用于启用或禁用I/O空间、内存空间、总线主设备等功能。
    • Status Register:反映设备的状态,例如中断、总线错误等。
  • 基址寄存器(BAR,Base Address Registers):配置空间中的基址寄存器(BARs)定义了PCIe设备的寄存器(或内存)映射。它指定了设备的内存空间或I/O空间在系统地址空间中的位置。这些寄存器address告诉操作系统设备的寄存器或数据缓冲区在哪个地址范围,从而可以进行内存映射I/O(MMIO)或端口映射I/O操作。

    • 内存映射寄存器:通过配置空间中的BAR,设备的寄存器可以映射到系统的内存地址空间,主机可以通过对这些内存地址进行读写来操作设备的寄存器。

1.2.1 用于配置空间

CPU访问Region 0的地址时,将会导致PCIe控制器发出读写配置空间的TLP。

Region0一般用于读写配置空间,它对应的寄存器如下:

img

1.2.2 用于内存和IO

CPU访问Region 1~32的地址时,将会导致PCIe控制器发出读写内存、IO空间的TLP。

而其寄存器如下:

img

2.访问示例

2.1 配置空间读写

设置寄存器,才能去解析转化CPU地址信息

要读写设备的配置空间,首先要定位:Bus/Dev/Function/Reg:

img

怎么发出这些"Bus/Dev/Function/Register"信息?如下图所示:

img

img

当Region 0的寄存器ob_desc0[3:0]被配置为读写配置空间时, CPU发出Region 0的地址,地址里面隐含有这些信息:

  • Bus:cpu_addr[27:20]
  • Dev:cpu_addr[19:15]
  • Fun:cpu_addr[14:12]
  • Reg:cpu_addr[11:0]

使用过程步骤如下:

  1. 配置Region 0对应的ob_desc寄存器用于读写配置空间

通过设置寄存器ob_desc0来配置要发送的TLP的Header中的Fmt和Type字段,选择配置读/写还是IO读/写等。

img

  1. 配置Region 0对应的地址转换寄存器ob_addr

比如我们可以设置bit[5:0]为27,意味着cpu_addr[27:0]这28条地址线都会传入TLP。

img

  1. CPU读写Region 0的地址

Region 0的地址范围是:0xF8000000~0xF9FFFFFF。

CPU想访问这个设备:Bus=bus,Dev=dev,Fun=fun,Reg=reg,那么CPU读写这个地址即可:

0xF8000000 + (bus<<20) | (dev<<15) | (fun<<12) | (reg)

(bus<<20) | (dev<<15) | (fun<<12) | (reg)就可以组成cpu发出的addr_cpu

2.2 MEM/IO读写示例

设置寄存器,才能去解析转化CPU地址信息

img

  1. 配置Region 1对应的ob_desc0寄存器用于内存读写

通过设置寄存器ob_desc0来配置要发送的TLP的Header中的Fmt和Type字段,选择配置读/写还是IO读/写等。

img

  1. 配置Region 1对应的地址转换寄存器ob_addr0/1

img

addr0、addr1寄存器里保存的是PCIe地址,也就是CPU发出这个Region的CPU地址后,将会转换为某个PCI地址。

怎么转换?由addr0、addr1决定。

Region 1的CPU地址范围是:0xFA000000~0xFA0FFFFF,是1M空间。

我们一般会让PCI地址等于CPU地址,所以这样设置:

  • addr0:

    • [5:0]等于19,表示CPU_ADDR[19:0]共20位地址传入TLP
    • [31:8]等于0xFA0000
  • addr1:设置为0

如上设置后,CPU读写地址时0xFA0???,就会转换为PCI地址:0xFA0???,转换过程如下:

pci_addr = cpu_addr[19:0] | (addr0[31:20] << 20) | (addr1<<32)= 0x????? + (0xFA0 << 20) | (0 << 32)= 0xFA0?????

http://www.ppmy.cn/devtools/144418.html

相关文章

Sentinel 学习笔记3-责任链与工作流程

本文属于sentinel学习笔记系列。网上看到吴就业老师的专栏&#xff0c;原文地址如下&#xff1a; https://blog.csdn.net/baidu_28523317/category_10400605.html 上一篇梳理了概念与核心类&#xff1a;Sentinel 学习笔记2- 概念与核心类介绍-CSDN博客 补一个点&#xff1a;…

【pytorch】多层感知机

将许多全连接层堆叠在一起。每一层都输出到上面的层&#xff0c;直到生成最后的输出。我们可以把前L−1层看作表示&#xff0c;把最后一层看作线性预测器。这种架构通常称为多层感知机通常缩写为MLP。 1 激活函数 激活函数&#xff08;activation function&#xff09;通过计…

【腾讯云】AI驱动TDSQL-C Serveress 数据库技术实战营-如何是从0到1体验电商可视化分析小助手得统计功能,一句话就能输出目标统计图

欢迎来到《小5讲堂》 这是《腾讯云》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景效果图流程图创建数据库基本信息数据库配置设置密码控制台开启…

macOS brew安装

brew 可以用命令在mac上安装、卸载、更新各种软件包。它是一个用ruby写的软件&#xff0c;软件是托管在github上的。 1、安装brew&#xff0c;一般选择清华源&#xff0c;如果之前安装过brew&#xff0c;执行下面命令时会自动备份old_homebrew&#xff0c;按照操作执行即可&…

Datawhale AI冬令营——Chat-悟空设计

Chat - 悟空项目介绍 一、项目背景 当前大模型市场竞争激烈&#xff0c;通用大模型众多&#xff0c;但针对特定领域、具有特色风格的垂直领域微调模型仍有较大发展空间。以《西游记》这一高人气影视IP为依托进行微调&#xff0c;能在文化娱乐相关细分市场吸引用户关注&#xf…

Unity 6 Preview(预览版)新增功能

原文链接&#xff1a;Unity - 手册&#xff1a;Unity 6 预览版中的新增功能 目录 原文链接&#xff1a;Unity - 手册&#xff1a;Unity 6 预览版中的新增功能 编辑器和工作流程 UI 工具包 实体 图形 URP HDRP &#xff08;HDRP&#xff09; 多人游戏 游戏对象的 Netc…

智谱BigModel研习社|搭建 AI 搜索引擎 - 使用免费的Web-Search-Pro+脑图Agent智能体

**作者&#xff1a;**Cartman 文章&#xff1a;多智能体 AI 搜索引擎 点击链接&#xff0c;更多实践案例等你探索&#xff5e; #智谱 BigModel 研习社 是专业的大模型开发者交流平台&#xff0c;欢迎在评论区与我们互动&#xff01; 传统搜索引擎如今的问题在于输出很多不相关结…

Redis--背景知识

目录 一、引言 二、redis特性 1.在内存中存储数据 2.可编程化 3.扩展能力 4.持久化 5.支持集群 6.高可用 7.快 一、引言 本篇文章就Redis特性进行介绍。 二、redis特性 1.在内存中存储数据 Mysql主要通过”表“的方式来存储组织数据&#xff0c;叫做”关系型数据库“…