PCIE学习系列 一(PCIe概念、结构、配置空间寄存器)

本文介绍了PCIe的基本概念,包括其与PCI的差异、采用的串行和端到端连接、高速数据传输、差分信号、虚拟化技术及多通道设计。详细讲解了BDF标识系统、配置空间的结构和大小,以及PCIe配置空间的访问方法,重点提及了PCIeCapability和ExtendedCapability的种类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pcie 的基本概念和结构

简介
PCIe的诞生是为了取代旧有的PCI(Peripheral Component Interconnect)接口,以满足日益增长的带宽需求和更高性能的要求。与传统的PCI总线相比,PCIe采用串行连接方式,并采用端到端的连接方式,这样可以使用更高的时钟频率,能够提供更高的数据传输速度和更强的性能。
PCIe还引入了许多先进的技术,如差分信号传输、数据包交换和错误检测校正机制,以提高数据传输的可靠性和稳定性。此外,PCIe还支持虚拟化技术,可以对物理设备进行虚拟划分,实现资源的共享和灵活配置。
PCIe采用了多通道的设计,在每个通道中都可以有多个数据通路。这样的设计使PCIe能够实现较高的带宽,并满足日益增长的数据传输需求。通常表示为PCIe x1、PCIe x4、PCIe x8、PCIe x16等不同规格,分别代表着不同的通道数量和带宽。
PCIe协议广泛用于计算机系统中连接各种外部设备,如图形卡、网络适配器、存储控制器等。
本文主要是PCIE的基础知识扫盲。

当前pcie协议支持到5.0版本,不同PCIe版本对应的传输速率如下:
在这里插入图片描述

PCIE总线的拓扑结构
在这里插入图片描述
PCIe采用的是树形拓扑结构, 它的体系架构一般由root complex,switch,endpoint等类型的PCIe设备组成。

root complex
RC是PCIe体系结构中的一个重要的组成部件,它与PCI总线的中Host bridge有些类似,是CPU和PCIe总线直接的接口。它的主要功能是完成存储器域到PCIe总线域的地址转换,随着虚拟化技术的引入,RC的功能也越来越复杂。RC把来自CPU的request转化成PCIe的4种不同的requests(configuration, Memory, I/O, Message)并发送给接在它下面的设备。从软件的角度来看,RC像是一组虚拟的PCI-PCI桥。

PCIe Switch & Bridge
Switch提供了分散或者是聚合的功能,它允许更多的设备接入到 一个PCIe Port。它扮演了数据包路由的功能。Bridge提供了一个转换接口用来连接其他的总线,如PCI/PCI-X。这样可以允许在PCIe的系统中接入一张旧的PCI设备。

PCIe Endpoint
它只有一个上游端口,位于PCIe拓扑结构的树的末端。它作为请求的发起者或者完成者。分为Legacy Endpoint和Native Endpoint,Legacy使用PCI总线的操作用于支持向后兼容。

BDF(Bus、Device、Function)
每一个Pcie设备可以只有一个功能(Function),即Fun0。也可以拥有最多8个功能,即多功能设备(Multi-Fun)。不管这个设备拥有多少个功能,其每一个功能都有唯一的配置空间与之对应。和PCI总线一样,PCIe总线的每一个功能(Function)都有唯一的标识符与之对应。这个标识符就是BDF(Bus、Device、Function),PCIe的配置软件(即root 的应用层)应该有能力识别整个PCIe总线的拓扑逻辑,以及其中的每一条总线(Bus),每一个设备(Device)和每一项功能(Function)。在BDF中,Bus Num占用8位,Device Num占用5位,Function Num占用3位。显然PCIe总线最多支持256条Bus、每条Bus支持32个Device,每个Device支持8个Function。

PCIe 的配置空间

那我们如何知道PCIe拓扑结构中每个PCIe设备的信息呢?此时就需要了解PCIe的配置空间。

什么是配置空间?
PCIe的配置空间(Configuration Space)是一种用于存储和管理PCIe设备相关信息的特殊地址空间。它包含了设备的配置寄存器和扩展配置寄存器,这些寄存器用于描述设备的功能、性能、资源分配等信息,设备在出厂时,配置空间是有一些默认值的。

配置空间有多大?pci和pcie的配置空间有何联系?
早期的PCI时期,系统为每个PCI设备分配的内存大小仅有256个Bytes,其中前64字节是标准配置空间header,后面的192字节是Capability结构, 展示pci能提供的能力。到后来的PCIE时期,PCIe设备性能增强,PCIe设备的配置空间扩展至4KBytes。但为了兼容PCI,PCIe的配置空间前256字节与PCI保持一致,256~4096字节是pcie 扩展配置空间。
  我们知道PCIe一共支持256条Bus,每条bus支持32个Dev,每个dev支持8个Func。因此在满负载的情况下,共需内存大小4k * 256 328 = 256MB,这个256M的内存空间是为PCIE设备准备的空间,系统不可用。这也是为什么用户可用内存空间总是会小一些的原因;
  
配置空间的结构是怎样的?
在这里插入图片描述

如图所示,配置空间的前64Bytes位标准的头部空间,之后192字节为Capabilities结构,256~4096Bytes则是PCIe的扩展配置空间。
PCI标准配置空间分为type0和type1两种,其中type0为Endpoint设备,type1为PCI Bridge和Switch设备,结构分别如图所示:
在这里插入图片描述

在这里插入图片描述

配置空间寄存器解释
公共的寄存器
Device ID: 设备ID, 表示该PCI设备的设备号,只读。
Vendor ID: 厂商ID, 表示生产该设备的厂商的编号,只读。
Status: pci设备状态寄存器,用于保存pci设备的状态,如中断状态或运行产生错误时的状态。
在这里插入图片描述

Command: PCI设备命令寄存器,主要是负责使能或关闭pci设备的I/O 访问,memory访问和INTx中断等。
在这里插入图片描述

Class Code: 设备分类信息,表示pci设备属于哪一种类别,如网卡,存储卡,显卡等。
Revision ID: 设备版本ID, 表示PCI设备的版本号。该寄存器可以被认为是Device ID寄存器的扩展。 只读。
BIST: 可选,用于内部自检。
Header type: PCI设备头类型寄存器,表示该设备是PCI EP设备还是PCI 桥设备。PCI配置空间是type0还是type1就是由该寄存器确定。
Lantency Timer: 在PCI总线中,多个设备共享同一条总线带宽,该寄存器用来控制PCI设备占用PCI总线的时间。PCIe设备不需要使用该寄存器,该寄存器的值必须为0。因为PCIe总线的仲裁方法与PCI总线不同,使用的连接方法也与PCI总线不同。
Cache line size: cache缓存大小。对于PCIe设备,该寄存器的值无意义。
Expansion Rom Base Address: 扩展ROM映射基地址寄存器。分配给ROM使用,用于PCI设备在处理器还没有运行操作系统之前,完成基本的初始化设置。
Base Address register: BAR地址寄存器负责PCI设备内部空间的映射,bit 0标识IO空间还是MEM空间,bits 2:1 用来标识address为32bit还是64bit,bit 3标识能否预取。type0有6个32bit的BAR寄存器,type1与2个32bit的BAR寄存器。每一个BAR地址对应一个地址空间。
在这里插入图片描述
在这里插入图片描述

Capbility Pointer: 第一个PCI capbility的地址偏移, capbility用于表示pci设备支持的能力。该寄存器存放Capabilities 结构链表的头指针。在一个PCIe 设备中,可能含有多个Capability 结构,这些寄存器组成一个链表,Next Capability Pointer存放下一个PCI capbility的地址偏移。
在这里插入图片描述

Interrupt Pin: PCI设备中断引脚,支持INTX A/B/C/D四个中断引脚。
Interrupt line: 表示当前PCI设备使用的中断号。

type0 独有的寄存器
CardBus CISpointer: 只读,可选,用于表明访问CIS(card info structure)的地址空间, 通常不会涉及。
Subsystem ID/ subsystem Vendor ID: 子系统和子厂商ID,可以结合Device ID和Vendor ID来组成完成的PCI设备标识。
Max_lat: 设备期望的最大延时,只读。
Min_Gbt: 设备期望的最小延时,只读。

type1 独有的寄存器
Primary Bus Number: 表示PCI设备挂在的PCI总线号。
Subordinate Bus Number: PCI桥可以管理其下的PCI总线子树。其中Subordinate Bus Number寄存器存放当前PCI子树中,编号最大的PCI总线号。
Secondary Bus Number: 存放当前PCI桥Secondary Bus使用的总线号,这个PCI总线号也是该PCI桥管理的PCI子树中编号最小的PCI总线号
Secondary Latency Timer: PCI桥下游的延时寄存器,和Latency Timer寄存器的含义相近
I/O base: 表示IO寻址的基地址, 低4bit只读,所以PCI设备默认IO寻址4K对齐,高4bit可写。
I/O limit: IO寻址的上限,高4bit可写,低4bit为全F,所以IO寻址上限是I/O limit地址 + 4K.
Secondary status: 保存PCI下游总线和设备的状态。
Memory Base: 表示memory寻址的基地址。
Memory Limit: 表示memroy寻址的上限,和IO limit类似。
Prefetchable Memory Base: 可预期内存的基地址
Prefetchable Memory Limit: 可预期内存寻址的上限。
Bridge Control Register:管理PCI桥的Secondary Bus, 可以控制 Secondary Bus的 Reset。

配置空间寄存器如何读写?
配置空间的访问分为两种方式,一种是IO访问,一种是内存映射访问。

IO访问
IO访问应该是Intel X86架构的独有产物了,简单可理解为一段存储空间,用户通过IN/OUT指令来访问。
比如这个:通过CF8 / CFC端口,用户可通过这组端口来对PCIE的前256个Byte进行访问,一个指定地址,一个指定数据。代码如下:

/*Access PCI Config Space in IO method*/
Address = BIT31|((BUS & 0XFF)<< 16)|((DEV & 0x1F)<<11)|((Fun & 0x7) << 8);
IoWrite32(0xCF8, address);                 //将要读取的地址写入到CF8
Date32 = IoRead32(0xcfc);                  //从CFC端口读出address的数据

注意:IO访问仅能读取到前256个Byte,256Byte后的空间需要用内存映射访问。

内存访问
PCIe配置空间的寄存器可以通过将其映射到系统内存地址空间的方式进行访问。通过内存映射,可以使用读写内存的指令来读取和写入配置空间的寄存器。
Enhanced Configuration Access Mechanism (ECAM)是访问PCIe配置空间的一种机制。是将PCIe的配置空间映射到MEM空间,使用MEM访问其配置空间的一种实现。

在这里插入图片描述
在内存方式中,需要根据设备的总线号、设备号和功能号计算出相应的内存地址。内存地址的计算公式为 Config Base Address + (Bus Number << 20) + (Device Number << 15) + (Function Number << 12) + offset,得到内存地址之后就可以直接读取到配置空间的寄存器值了。

如果有兴趣可以看看Linux源码中关于ECAM的实现:drivers\pci\ecam.c

PCI capbility结构
PCIE Capability可以分为PCI兼容的capability 和PCIE extended capability两类,64字节到256字节是pci\pcie设备的capability结构,256到4096则为pcie的扩展空间。
在Linux源码中能找到以下的定义,是各个capability ID和各个capability名称的定义。
PCIE Capability\PCI Capability:
在这里插入图片描述
PCIE extended capability:
在这里插入图片描述
常用的pci capability 有以下几个:Power Management、Message Signalled Interrupts、PCI Express、Hot-Plug Controller,PCIe extended capability常用的有:Single Root I/O Virtualization、Address Control Services等。

<think>好的,我现在需要回答用户的问题:“CPU数据通路可以配置PCIe寄存器吗?” 首先,我得弄清楚用户的问题到底在问什么。用户可能对计算机硬件中的CPU和PCIe设备的交互机制不太清楚,想知道CPU是否能直接通过数据通路配置PCIe寄存器。这涉及到计算机体系结构的知识,特别是CPU外围设备的通信方式。 首先,我需要回忆下CPU和PCIe设备的基本工作原理。CPU通过总线或互连结构(如现代计算机中的PCIe总线)各种外围设备通信PCIe设备有自己的配置空间,这些配置空间包含了控制设备行为的寄存器。这些寄存器通常用于初始化设备、设置中断、分配资源(如内存地址和I/O端口)等。 接下来,用户提到的“数据通路”具体指的是什么?数据通路通常指CPU内部处理数据的路径,比如ALU、寄存器文件、总线等。但在这里,用户可能指的是CPUPCIe设备之间的通信路径。如果是这样的话,问题转化为:CPU能否通过其PCIe设备之间的通信路径(数据通路)来访问和配置PCIe设备的寄存器。 根据知识,CPU确实可以访问PCIe设备的配置空间。这通常通过两种机制实现:种是传统的PCI配置空间访问机制,使用IN和OUT指令访问特定的I/O端口(如CF8h和CFCh);另种是内存映射I/O(MMIO),其中配置空间被映射到系统的物理地址空间,CPU通过普通的存储指令(如MOV)来访问这些地址。 然后需要考虑的是,操作系统通常负责管理PCIe设备的配置,普通用户程序无法直接访问这些配置空间,因为这需要特权级权限。大多数情况下,操作系统内核或驱动程序会处理PCIe寄存器的配置,而应用程序通过系统调用或设备驱动接口间接硬件交互。 此外,还需要确认CPU数据通路是否直接参过程。当CPU执行访问PCIe配置空间的指令时,这些请求会通过系统总线(如DMI)传递到芯片组(如南桥或PCH),再通过PCIe总线到达目标设备。因此,数据通路确实涉及CPU内部的数据路径以及外部总线和桥接器。 可能存在的误区是用户可能认为数据通路仅指CPU内部结构,但实际上,外部设备通信时的数据通路包括CPU、总线、桥接器和外设之间的整个路径。因此,答案是肯定的,CPU可以通过其数据通路配置PCIe寄存器,但这通常需要操作系统级别的支持以确保正确性和安全性。 最后,要确保回答准确且易于理解,避免使用过多技术术语,同时涵盖关键点:CPU如何访问PCIe配置空间、使用的机制(I/O端口或MMIO)、操作系统的作用以及数据通路的涵盖范围。这样用户不仅能得到肯定的回答,还能理解背后的原理和限制。</think>CPU可以通过数据通路配置PCIe寄存器,但需遵循以下机制和限制: ### 1. **PCIe寄存器的访问原理** - PCIe设备的**配置空间**是组标准化的寄存器,用于控制设备行为(如中断、内存地址分配等)。 - CPU通过**两种方式**访问这些寄存器: - **传统I/O端口**:使用`IN/OUT`指令操作特定端口(如`0xCF8`和`0xCFC`)。 - **内存映射I/O(MMIO)**:将配置空间映射到物理内存地址,通过普通内存读写指令(如`MOV`)访问。 ### 2. **数据通路的具体流程** 1. **CPU发起请求**:执行I/O指令或内存访问指令。 2. **芯片组路由**:请求通过系统总线(如DMI)传递至芯片组(如南桥/PCH)。 3. **PCIe总线传输**:芯片组将请求转换为PCIe事务(如配置读写TLP包)。 4. **目标设备响应**:PCIe设备接收请求并操作寄存器,返回结果。 ### 3. **操作系统层的限制** - **特权级保护**:直接访问PCIe配置空间需**Ring 0权限**(内核态)。 - **驱动程序角色**:通常由操作系统内核或设备驱动完成寄存器配置,用户程序需通过系统调用间接操作。 ### 4. **典型应用场景** - **设备初始化**:启动时为PCIe设备分配资源(如BAR寄存器)。 - **热插拔支持**:动态调整设备配置。 - **性能调优**:修改中断掩码或DMA设置。 ### 5. **安全风险防护** - **误配置风险**:错误修改寄存器可能导致系统崩溃或设备损坏。 - **硬件保护机制**:现代芯片组通过**VTD/IOMMU**限制非法访问。 ### 示例:Linux内核访问PCI配置空间 ```c // 读取PCI配置空间中的设备ID(偏移量0x00) u16 pci_read_device_id(struct pci_dev *dev) { u16 val; pci_read_config_word(dev, 0x00, &val); // 内核API封装了底层硬件操作 return val; } ``` ### 总结 CPU数据通路支持配置PCIe寄存器,但需依赖**硬件总线协议**和**操作系统权限管理**。实际开发中,用户应通过驱动程序或内核接口间接操作,而非直接访问硬件。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值