PCIe总线-配置空间介绍(三)

1.概述

配置空间是PCIe设备/桥的标识符,其保存了设备/桥的信息。主机在枚举设备/桥的时候需要先访问配置空间,获取设备厂家、型号、类型、所需资源等信息,然后再分配资源,最后才能访问PCIe设备的存储或IO地址空间。PCIe总线规定了三种类型的配置空间,分别是PCIe Agent设备使用的配置空间、PCIe桥使用的配置空间和Cardbus桥片使用的配置空间,本节只介绍前两种。

2.配置空间布局

PCIe配置空间的布局如下图所示,总共4KB,PCIe设备的每个Function都对应一个配置空间。0-3Fh(64字节)是PCI兼容配置空间头,按类型可分为Type 0配置空间头和Type 1配置空间头。PCIe设备使用Type 0配置空间头,PCIe桥使用Type 1配置空间头。所有的PCI、PCI-X、PCIe设备(桥)必须支持64字节的配置空间头,即00h-40h。40h-FFh(192字节)是PCI/PCI-X和PCIe扩展的配置空间,主要存放一些与MSI或者MSI-X中断机制和电源管理相关的Capability Structures。支持中断的PCI、PCI-X、PCIe设备(桥)必须支持40h-FFh的配置空间。0-FFh(256字节)是PCI兼容配置空间,可通过传统的PCI方式(基于ID寻址)或PCIe ECAM(Enhanced Configuration Access Mechanism)访问。100h-FFFh(3840字节)是PCIe协议扩展的可选配置空间,主要存放AER、虚拟通道、设备序列号等Capability Structures。100h-FFFh只能通过PCIe ECAM访问。

PCIe配置空间布局

在一个PCIe总线中,Type 0配置空间头和Type 1配置空间头如下图所示。

Type0_And_Type1_Header

3.Type 0 Header

Type 0配置空间头如下图所示。

type0配置空间头

每个字段的具体意义如下:

字段意义偏移地址宽度
Vendor ID厂商ID,由PCI-SIG统一分配,如Intel的厂商ID为0x8086,0x002B
Device ID设备ID,由PCI-SIG统一分配,如Intel 82571EB网卡的设备ID为0x105E0x022B
Command命令寄存器,初始化的时候默认值为0,具体见下面的解释0x042B
Status保存PCIe状态0x062B
Revision ID保存PCIe版本号0x081B
Class Code保存PCIe设备的分类,由Base Class Code、Sub Class Code和Interface组成。Base Class Code是设备的基本分类,如显卡、网卡、PCIe桥等设备。Sub Class Code则会将设备进一步细分。Interface定义编程接口。0x093B
Cache Line Size保存主机处理器的Cache行长度,该寄存器由主机的系统软件设置。若PCIe设备不支持与Cache相关的总线事务,系统软件可不设置该寄存器。0x0C1B
Latency Timer控制PCI设备占用总线的时间,对PCIe总线无意义。0x0D1B
Header Type记录设备的类型。bit[7]=0表示单功能设备,bit[7]=1表示多功能设备,bit[6:0]=0表示PCIe Agent设备,bit[6:0]=1表示PCIe桥设备,bit[6:0]=2表示PCIe CardBus桥。0x0E1B
BIST可选,用于内部自检0x0F1B
Base Address 0BAR寄存器,保存主机分配给该PCIe设备的PCIe域地址,64位地址使用2个BAR0x104B
Base Address 1BAR寄存器,保存主机分配给该PCIe设备的PCIe域地址,64位地址使用2个BAR0x144B
Base Address 2BAR寄存器,保存主机分配给该PCIe设备的PCIe域地址,64位地址使用2个BAR0x184B
Base Address 3BAR寄存器,保存主机分配给该PCIe设备的PCIe域地址,64位地址使用2个BAR0x1C4B
Base Address 4BAR寄存器,保存主机分配给该PCIe设备的PCIe域地址,64位地址使用2个BAR0x204B
Base Address 5BAR寄存器,保存主机分配给该PCIe设备的PCIe域地址,64位地址使用2个BAR0x244B
Cardbus CIS Pointer不介绍0x284B
Subsystem Vendor ID记录PCIe设备生产厂商0x2C2B
Subsystem ID记录PCIe设备生产厂商0x2E2B
Expansion ROM Base Address固件程序地址,用于初始化PCIe设备0x304B
Capabilities PointerCapabilities寄存器相对于配置空间的偏移地址,PCI-X和PCIe必须支持该功能0x341B
Reserved保留0x353B
Reserved保留0x384B
Interrupt Line保存当前PCIe设备使用的中断向量号,由主机系统软件分配,通常不使用0x3C1B
Interrupt Pin保存PCIe设备使用的中断引脚,由主机系统软件分配,1表示INTA#,2表示INTB#,3表示INTC#,4表示INTD#,PCIe设备可使用INTx模拟INTA~D#中断0x3D1B
Min_GntPCIe设备能忍受的最大延时,只读寄存器0x3E1B
Max_LatPCIe设备期望的最小延时,只读寄存器0x3F1B

3.1.Command

Command寄存器为PCIe设备的命令寄存器,默认值为0,此时PCIe设备除了能够接收配置请求总线事之外,不能接收任何存储器或者I/O请求。

Command寄存器位域如下图所示:

Command寄存器

Command寄存器位域定义如下表所示:

位域意义属性
0I/O Space位,默认值为0。表示是否响应I/O请求。为1时响应,为0时不响应。如果支持I/O空间,系统软件会将该位置1。RW
1Memory Space位,默认值为0。表示是否响应Memory请求。为1时响应,为0时不响应。如果支持Memory地址空间,系统软件会将该位置1。RW
2Bus Master位,默认值为0。对于EP表示是否可以发送I/O或者Memory请求,包括MSI/MSI-X中断,对于Root和Switch端口表示是否会将I/O或者Memory请求转发到上行端口。为1时可以发送或者可以转发,为0时不发送或者不转发。RW
3Special Cycle位,默认值为0。表示是否响应Special总线事务。为1时响应,为0时不响应。Special总线事务可以将一些信息广播到多个目标设备RO
4Memory Write and Invalidate位,默认值为0。对于PCIe总线没有意义RO
5VGA Palette Snoop位,默认值为0。对于PCIe总线没有意义RO
6Parity Error Response位,默认值为0。此位控制TLP出现奇偶校验错误时是否在Status寄存器中记录。为1时记录,为0时不记录RW
7IDSEL Stepping/Wait Cycle Control位,默认值为0。对于PCIe总线没有意义RO
8SERR# Enable位,默认值为0。对于PCIe总线没有意义RO
9Fast Back-to-Back Transactions Enable位,默认值为0。对于PCIe总线没有意义RO
10Interrupt Disable位,默认值为0。表示EP是否可以发送INTx中断。为1时不可以,为0时可以。RW

3.2.Status

Status寄存器保存PCIe设备的状态。
Status寄存器的位域如下图所示:

Status寄存器

Status寄存器的位域定义如下表所示:

位域意义属性
0-2保留RO
3中断状态位。该位为1时且Command bit[10]=0,表示PCIe设备使用INTx信号提交中断。大多数的PCIe设备有自己的中断状态寄存器,可同通过BAR访问,很少使用该寄存器。RO
4Capabilities List有效位。为1时Capabilities Pointer有效,否则无效RO
566MHz Capability位,默认值为0。为1时表示PCIe设备支持66MHz的PCI总线。对PCIe总线无意义RO
6保留RO
7Fast Back-to-Back Transactions Capable位,默认值为0。对于PCIe总线没有意义RO
8Master Data Parity Error位,默认值为0。当该位设置且Command寄存器bit[6]=1,对于EP Function来说,表示其收到了错误的完成报文或者其发送了错误的请求,对于Root Port、Switch上行口或者Switch下行口,表示其接收到了下行口的错误完成报文或者向上行口发送了错误的请求。Command寄存器bit[6]=0,该位保持为0RW1C
9-10DEVSEL Timing,默认值为0。对于PCIe总线没有意义RO
11Signaled Target Abort位,默认值为0。This bit is Set when a Function completes a Posted or Non-Posted Request as a Completer Abort error. This applies to a Function with a Type 1 Configuration header when the Completer Abort was generated by its Primary Side.RW1C
12Received Target Abort位,默认值为0。This bit is Set when a Requester receives a Completion with Completer Abort Completion Status. On a Function with a Type 1 Configuration header, the bit is Set when the Completer Abort is received by its Primary Side.RW1C
13Received Master Abort位,默认值为0。This bit is Set when a Requester receives a Completion with Unsupported Request Completion Status. On a Function with a Type 1 Configuration header, the bit is Set when the Unsupported Request is received by its Primary Side.。RW1C
14Signaled System Error位,默认值为0。This bit is Set when a Function sends an ERR_FATAL or ERR_NONFATAL Message, and the SERR# Enable bit in the Command register is 1.RW1C
15Detected Parity Error,This bit is Set by a Function whenever it receives a Poisoned TLP, regardless of the state the Parity Error Response bit in the Command register. On a Function with a Type 1 Configuration header, the bit is Set when the Poisoned TLP is received by its Primary Side.RW1C

3.3.Base Address

Base Address寄存器简称为BAR,保存了PCIe设备/桥的Function使用的PCIe总线域地址的基地址。Type 0设备每个Function最多可以有6个BAR,Type 1设备每个Function最多可以有2个BAR。若使用64位PCIe总线域地址,则2个BAR表示一个64位地址,BARn表示低32位,BARn+1表示高32位。

BAR保存的PCIe总线域基地址有两种类型,分别是IO地址空间和存储地址空间,存储地址空间有4中属性,分别是预取(prefetchable)、非预取(non-prefetchable)、32位和64位。主机在枚举的时候先读取BAR,然后判断所需的总线域基地址类型,若是存储地址空间,则进一步获取存储地址空间的属性,接着向BAR写如0xFFFFFFFF,最后再读取BAR,根据可以写入的最低有效位,获取Function请求IO地址空间和存储地址空间的长度。

当BAR表示的是存储地址空间时,位域如下图所示:

BAR存储空间

当BAR表示的是IO地址空间时,位域如下图所示:

BAR_IO空间

  1. 32位存储地址空间
    32位存储地址空间分为预取(prefetchable)和非预取(non-prefetchable)。下面以32位非预取存储地址空间的初始化流程为例进行分析:
    1. 当PCIe Function初始化完成后,BAR的基地址类型和属性也初始化完毕。图中bit[3-0]都是0,表示这是一个32位非预取存储地址空间。
    2. 主机先读取BAR,获取BAR的类型和属性。图中未画出。
    3. 主机向BAR的所有bit写1,此时BAR中可以写入的bit变为1,不可写入bit的保持原来的值。图中bit[31-12]=1,表示该BAR请求的存储地址空间大小为2^12=4KB。
    4. 主机获取这些信息后,向BAR中配置存储地址空间的基地址。图中配置的是0xF9000000,bit[11-0]保持为0,即该BAR表示的32位非预取存储地址空间范围为0xF9000000-0xF9000FFF,大小为4KB。

32‐Bit_Non‐Prefetchable_Memory_BAR_Set_Up

实质上,当该BAR表示的PCIe总线域地址向存储域地址转换时,bit[31-12]被转换为存储域基地址,bit[11-0]被视为存储域基地址的偏移,直接映射到存储域空间,不做转换。

  1. 64位存储地址空间
    64位存储地址空间分为预取(prefetchable)和非预取(non-prefetchable)。下面以64位预取存储地址空间的初始化流程为例进行分析:
    1. 当PCIe Function初始化完成后,BAR的基地址类型和属性也初始化完毕。图中bit[3-0]=0xC,表示这是一个64位预取存储地址空间,需要两个BAR表示。
    2. 主机先读取BAR,获取BAR的类型和属性。图中未画出。
    3. 主机向BARn和BARn+1的所有bit写1,此时BAR中可以写入的bit变为1,不可写入bit的保持原来的值。图中bit[63-26]=1,表示该BAR请求的存储地址空间大小为2^26=64MB。
    4. 主机获取这些信息后,向BAR中配置存储地址空间的基地址。图中配置的是0x240000000,bit[25-0]保持为0,即该BAR表示的64位预取存储地址空间范围为0x240000000-0x243FFFFFF,大小为64MB。

64‐Bit_Prefetchable_Memory_BAR_Set_Up

实质上,当该BAR表示的PCIe总线域地址向存储域地址转换时,bit[63-26]被转换为存储域基地址,bit[25-0]被视为存储域基地址的偏移,直接映射到存储域空间,不做转换。

  1. IO地址空间
    IO地址空间的初始化流程如下图所示:
    1. 当PCIe Function初始化完成后,BAR的基地址类型也初始化完毕。图中bit[0]=0x0,表示这是一个IO地址空间。
    2. 主机先读取BAR,获取BAR的类型。图中未画出。
    3. 主机向BAR的所有bit写1,此时BAR中可以写入的bit变为1,不可写入bit的保持原来的值。图中bit[31-8]=1,表示该BAR请求的存储地址空间大小为2^8=256B。
    4. 主机获取这些信息后,向BAR中配置IO地址空间的基地址。图中配置的是0x4000,bit[7-0]保持为0,即该BAR表示的IO地址空间范围为0x4000-0x40FF,大小为256B。

IO_BAR_Set_Up

早期的IO设备内部寄存器只能通过IO地址空间进行访问,但是这种方式局限性很大,而且效率低。后来为了提高灵活性和效率,将IO设备内部寄存器统一映射到存储地址空间,使用MMIO方式访问IO设备内部寄。PCIe为了兼容PCI,保留了IO地址空间,但现在很少使用。

4.Type 1 Header

Type 1配置空间用来描述PCIe桥,PCIe桥除了作为PCIe设备之外,还需要管理其下面连接的PCIe子总线使用的各类资源。Type 1配置空间头如下图所示。

type1配置空间头

每个字段的具体意义如下:

字段意义偏移地址宽度
Vendor ID厂商ID,由PCI-SIG统一分配,如Intel的厂商ID为0x8086,0x002B
Device ID设备ID,由PCI-SIG统一分配,如Intel 82571EB网卡的设备ID为0x105E0x022B
Command命令寄存器,初始化的时候默认值为0,具体见Type 0 Header解释0x042B
Status保存PCIe状态0x062B
Revision ID保存PCIe的版本号0x081B
Class Code保存PCIe设备的分类,由Base Class Code、Sub Class Code和Interface组成。Base Class Code是设备的基本分类,如显卡、网卡、PCIe桥等设备。Sub Class Code则会将设备进一步细分。Interface定义编程接口。0x093B
Cache Line Size保存主机处理器的Cache行长度,该寄存器由主机的系统软件设置。若PCIe设备不支持与Cache相关的总线事务,系统软件可不设置该寄存器。0x0C1B
Primary Latency Timer上游总线的延迟时间,对PCIe总线无意义。0x0D1B
Header Type记录设备的类型。bit[7]=0表示单功能设备,bit[7]=1表示多功能设备,bit[6:0]=0表示PCIe Agent设备,bit[6:0]=1表示PCIe桥设备,bit[6:0]=2表示PCIe CardBus桥。0x0E1B
BIST可选,用于内部自检0x0F1B
Base Address 0BAR寄存器,保存主机分配给桥的PCIe域地址,64位地址使用2个BAR0x104B
Base Address 1BAR寄存器,保存主机分配给桥的PCIe域地址,64位地址使用2个BAR0x144B
Primary Bus Number保存该PCIe桥的上游PCIe总线号0x181B
Secondary Bus Number保存桥的下游总线中总线编号最小的PCIe总线号0x191B
Subordinate Bus Number保存桥的下游总线中总线编号最大的PCIe总线号0x1A1B
Secondary Latency TimerSecondary总线的延迟时间,对PCIe总线无意义。0x1B1B
I/O Base保存桥的下游总线连接的所有PCIe设备IO地址空间的基地址。若桥没有实现I/O地址空间,则应该只读并且返回0,反之高4位可以修改0x1C1B
I/O Limit保存桥的下游总线连接的所有PCIe设备IO地址空间的大小。若桥没有实现I/O地址空间,则应该只读并且返回0,反之高4位可以修改0x1D1B
Secondary Status记录Secondary总线的状态0x1E2B
Memory Base保存桥的下游总线连接的所有PCIe设备非预取存储地址空间的基地址0x202B
Memory Limit保存桥的下游总线连接的所有PCIe设备非预取存储地址空间的大小0x222B
Prefetchable Memory Base保存桥的下游总线连接的所有PCIe设备预取存储地址空间的基地址0x242B
Prefetchable Memory Limit保存桥的下游总线连接的所有PCIe设备预取存储地址空间的大小0x262B
Prefetchable Base Upper 32 Bits保存桥的下游总线连接的所有PCIe设备预取存储地址空间基地址的高32位0x284B
Prefetchable Limit Upper 32 Bits保存桥的下游总线连接的所有PCIe设备预取存储地址空间大小的高32位0x2C4B
I/O Base Upper 16 Bits保存桥的下游总线连接的所有PCIe设备IO地址空间基地址的高16位。若桥没有实现I/O地址空间,则应该只读并且返回00x302B
I/O Limit Upper 16 Bits保存桥的下游总线连接的所有PCIe设备IO地址空间大小的高16位。若桥没有实现I/O地址空间,则应该只读并且返回00x322B
Capability PointerCapabilities寄存器相对于配置空间的偏移地址,PCI-X和PCIe必须支持该功能0x341B
Reserved保留0x353B
Expansion ROM Base Address固件程序地址,用于初始化PCIe桥0x384B
Interrupt Line保存当前PCIe设备使用的中断向量号,由主机系统软件分配,通常不使用0x3C1B
Interrupt Pin保存PCIe设备使用的中断引脚,由主机系统软件分配,1表示INTA#,2表示INTB#,3表示INTC#,4表示INTD#,PCIe设备可使用INTx模拟INTA~D#中断0x3D1B
Bridge Control控制桥的寄存器,最终要的是bit[6](Secondary Bus Reset), 当bit[6]=1时,PCIe桥将对该port下面连接的所有PCIe设备/桥发起hot reset。0x3E2B

4.1.Base Address

Type 1设备中只含有两个BAR,其意义和Type 0中的BAR寄存器相同。但在Type 1表示的PCIe桥中,这两个BAR寄存器是可选的,如果桥设备不存在私有寄存器,可以不使用这两个BAR寄存器。不存在私有寄存器,且没有专门驱动的PCIe桥,被称为透明桥。

4.2.I/O地址空间

I/O Base、I/O Limit、I/O Base Upper 16 Bits和I/O Limit Upper 16 Bits共同决定了桥的下游总线IO地址空间范围。计算方法如下图所示:

  1. I/O Base和I/O Limit的低2位决定了IO地址是16位还是32位,若是32位则需要使用I/O Base Upper 16 Bits和I/O Limit Upper 16 Bits。
  2. I/O Base表示I/O地址空间基地址,按4KB对齐,低12位都是0,因此图中的I/O基地址为0x4000。
  3. I/O Limit表示I/O地址空间最大地址,低12位都是1,即为0xFFF。因此图中的I/O地址空间最大地址为0x4FFF。
  4. 图中I/O地址空间为16位,因此I/O地址空间范围为0x4000-0x4FFF。

IO_Base和IO_Limit

4.3.非预取地址空间

Memory Base和Memory Limit共同决定了非预取地址空间的范围。计算方法如下图所示:

  1. Memory Base和Memory Limit低4位只读,默认为0,非预取地址空间默认为32位。
  2. Memory Base表示非预取地址空间基地址,按1MB对齐,即低20位为0。
  3. Memory Limit表示非预取地址空间最大地址,低20位都为1,即为0xFFFFF。
  4. 因此非预取地址空间范围为0xF9000000-0xF90FFFFF。

非预取地址空间计算方法

4.4.预取地址空间

Prefetchable Memory Base、Prefetchable Memory Limit、Prefetchable Base Upper 32 Bits和Prefetchable Limit Upper 32 Bits共同决定了预取地址空间的范围。计算方法如下图所示:

  1. Prefetchable Memory Base和Prefetchable Memory Limit低4位只读,而且决定了预取地址空间是32位还是64位,0x0表示32位,0x1表示64位。若是64位地址,则需要使用Prefetchable Base Upper 32 Bits和Prefetchable Limit Upper 32 Bits。
  2. Prefetchable Memory Base表示预取地址空间基地址,按1MB对齐,即低20位为0。
  3. Prefetchable Memory Limit表示预取地址空间最大地址,低20位都为1,即为0xFFFFF。
  4. 图中预取地址空间为64位,因此I/O地址空间范围为0x240000000-0x243FFFFFF。

预取地址空间计算方法

5.Capabilities Structures

Capabilities Structures主要有MSI、MSI-X、PCI Express、电源、AER、PCI Express Extended等Capabilities Structures。第一个Capabilities Structures的地址由配置空间Header的Capabilities Pointer寄存器保存,系统可以根据此遍历所有的Capabilities Structures。Capabilities Structures的链表如下图所示。

Capability结构链表

每一个Capabilities Structures都有一个独一无二的Capability ID,该ID保存在Capabilities Structures的开始地址,系统软件根据此判断Capabilities Structures的类型。

PCI标准Capabilities ID如下图所示。

PCI_Standard_Capabilities

PCIe扩展Capabilities ID参考PCI Express® Base Specification Revision 5.0的9.3.7节。

5.1.MSI Capability Structures

MSI使用报文的形式向主机发送中断。具体是使用存储器写请求,向MSI Capability Structures中的Message Address写入Message Data,写入后会在主机侧触发中断。

MSI最多支持32个中断,且要求主机分配的中断号连续。MSI Capability Structures共有4种形式,分别是32位和64位不带中断Mask和Pending Structure,32位和64位带中断Mask和Pending Structures,具体如下图所示。

MSI_Capability_Structure

MSI_Capability_Structure_for_32-bit_Message_Address_and_PVM

MSI_Capability_Structure_for_64-bit_Message_Address_and_PVM

MSI Capability Structures各个寄存器的定义如下表所示:

定义描述属性
Capability ID记录MSI Capability的ID号,值为0x05RO
Next Capability Pointer存放下一个Capability Structure的偏移地址,0x00表示该Capability是最后一个RO
Message Control存放Function使用MSI机制进行中断请求的状态与控制信息-
Message Address存放MSI存储器写事务目的地址的低32位,bit[1:0]为0,4字节对齐,该地址由系统软件分配并设置RW
Message Upper Address存放MSI存储器写事务目的地址的高32位,该地址由系统软件分配并设置RW
Message Data存放MSI存储器写事务携带的数据。总共4字节,Message占低2字节,若扩展Message数据使能,则高2字节为扩展Message数据,否则为0。当只有一个MSI中断(Multiple Message Enable=0)时,Message表示一个真实的数据,Function不会改变Message。当有多个MSI中断(Multiple Message Enable>0)时,Message表示Function可以改变Message低位的bit数,以产生不同的中断,比如当Multiple Message Enable=2时,表示Function需要4个中断,则Function可以修改Message的bit[1]和bit[0],以区分4个中断RW
Extended Message Data存放MSI存储器写事务携带的数据。总共4字节,Message占低2字节,若扩展Message数据使能,则高2字节为扩展Message数据,否则为0RW/undefined/RsvdP
Mask Bits存放MSI中断屏蔽位。系统软件可以向某个bit写1,此时会将对应的中断禁止,清零时会使能对应的中断RW
Pending Bits存放MSI中断Pending位。当Function中断发生时,根据中断号会将对应的bit设置为1RO

Message Control寄存器位域如下图所示:

Message_Control_Register的意义

Message Control寄存器位域的定义如下表所示:

位域定义描述属性
15:11RsvdP保留-
10Extended Message Data Enable扩展Message数据使能位,系统软件需要先读取Extended Message Data Capable判断Function是否支持扩展Message数据,若支持再判断是否使能该位RW/RO
9Extended Message Data CapableFunction是否支持扩展Message数据RO
8Per-Vector Masking CapableFunction是否支持MSI中断Mask和Pending。0表示不支持,1表示支持RO
764-bit Address CapableFunction是否支持64位地址Structure。0表示只支持32位地址Structure,1表示支持64位地址StructureRO
6:4Multiple Message Enable系统软件给Function实际分配的MSI中断数量。系统软件先读取Multiple Message Capable位确定Function请求的中断数量,然后再分配。通常情况下两者相等,若系统中断数量不足,则Multiple Message Enab可能会小于Multiple Message Capable。最多和Multiple Message Capable设置的中断数量一样RW
3:1Multiple Message CapableFunction需要的中断向量数量,按2的n次方对齐,如0表示需要1个中断向量,1表示需要2个中断向量,…,5表示需要32个中断向量,6和7保留。若设备实际上需要3个中断,则需要设置为2。系统软件根据此位域给Function分配MSI中断数量RO
0MSI EnableMSI中断机制使能位,当MSI或MSI-X使能时,INTx中断将被自动禁止RW

5.2.MSI-X

MSI-X的中断机制和MSI类似,都是向主机的某个地址写Message数据以产生中断。但MSI-X每一个中断都有独立的Message Address和Message Data,Message Address和Message Data组成一个中断向量表,同时MSI-X使用了独立的中断Pending表。中断向量表和中断Pending表存放在BAR空间中。因此MSI-X支持的中断数量更多,且不需要中断号连续。

5.2.1.MSI-X Capability Structures

MSI-X Capability Structures主要的作用是记录中断向量表和Pending表保存的位置。MSI-X Capability Structure如下图所示。

MSI-X_Capability_Structure

MSI Capability Structures各个寄存器的定义如下表所示:

定义描述属性
Capability ID记录MSI-X Capability的ID号,值为0x11RO
Next Capability Pointer存放下一个Capability Structure的偏移地址,0x00表示该Capability是最后一个RO
Message Control存放Function使用MSI-X机制进行中断请求的状态与控制信息-
Table BIR表示MSI-X中断向量表存放在那个BAR空间中,0-5与BAR0-5对应,若是64位的BAR,则表示低32位BAR的编号RO
Table Offset表示该MSI-X中断向量表在对应BAR空间中的偏移地址,偏移地址为32位,低3位为0,按8字节对齐RO
PBA BIR表示MSI-X中断Pending表存放在那个BAR空间中,0-5与BAR0-5对应,若是64位的BAR,则表示低32位BAR的编号。通常情况下中断向量表和中断Pending表存放在同一个BAR空间中RO
PBA Offset表示该MSI-X中断Pending表在对应BAR空间中的偏移地址,偏移地址为32位,低3位为0,按8字节对齐RO

Message Control寄存器位域如下图所示:

Message_Control_Register_for_MSI-X

Message Control寄存器位域的定义如下表所示:

位域定义描述属性
15MSI-X EnableMSI-X中断机制使能位,当MSI、MSI-X和INTx中断只能使用其中一个RW
14Function MaskMSI-X中断全局Mask位,当此位为1时,无论Pending表如何设置,所有中断都会被屏蔽RO
13:11Reserved保留RsvdP
10:0Table SizeMSI-X中断向量表的大小,存放Message Address和Message Data。若系统软件读取的值为0x3,则中断向量表的大小为4字节。RO
5.2.2.MSI-X Table

MSI-X Table如下图所示。每一个Entry表示一个MSI-X中断向量,占用16字节。一个Entry由4部分组成,分别是Message Address、Message Upper Address、Message Data、Vector Control。

MSI-X_Table_Structure

MSI-X Table每个Entry的寄存器定义如下表所示:

定义描述属性
Message Address存放MSI存储器写事务目的地址的低32位,bit[1:0]为0,4字节对齐,该地址由系统软件分配并设置RW
Message Upper Address存放MSI存储器写事务目的地址的高32位,如果为0,则使用32地址,否则使用64位地址,该地址由系统软件分配并设置。RW
Message Data存放MSI存储器写事务携带的数据,总共4字节RW
Vector Control控制该中断entry的行为-

Vector Control寄存器位域如下图所示:

Vector_Control_Register_for_MSI-X_Table_Entries

Vector Control寄存器位域定义如下表所示:

位域定义描述属性
31:24ST Upper如果Function实现了TPH Requester Extended Capability而且ST表位域值为10b,同时Extended TPH Requester Supported位为1,则ST Upper保存了高8位的Steering Tag,可以读写,否则保留RW or Rsvd
23:16ST Lower如果Function实现了TPH Requester Extended Capability而且ST表位域值为10b,则ST Lower保存了低8位的Steering Tag,可以读写,否则保留RW or Rsvd
15:1Reserved保留RW or RsvdP
0Mask Bit中断屏蔽位,为1屏蔽该MSI-X中断,为0时可以正常发送MSI-X中断,默认值为1RW
5.2.3.MSI-X PBA

MSI-X中断Pending Table如下图所示。每一个Entry由64位组成,其中每一位与MSI-X中断表中的一个Entry对应,则一个Entry和MSI-X中断表的64个Entry对应。当Pending Table中的某一个bit置1时,表明与之对应的MSI-X中断发生了。

MSI-X_PBA_Structure

5.3.PCI Express Capability Structure

PCI Express Capability Structure存放和PCIe总线相关的信息,包括PCIe链路、插槽、设备状态、是否支持PCIe新特性等信息。PCI Express Capability Structure整体的Structure如下图所示。

所有PCIe设备Functions必须实现PCI Express Capabilities、Device Capabilities、Device Status和Device Control寄存器。PCIe设备Functions选择实现Device Capabilities 2、Device Status 2和Device Control 2寄存器,若没有实现,则保持为0。

Root Ports、Switch Ports、Bridges和Endpoints(非RCiEPs)必须实现Link Capabilities、Link Status、Link Control、Link Capabilities 2, Link Status 2和Link Control 2寄存器,Functions无需实现上述寄存器,保持为0即可。

Switch Downstream和Root Ports选择实现Slot Capabilities、Slot Status和Slot Control寄存器。如果port连接了插槽,则必须实现Slot Capabilities寄存器,如果port连接了插槽或者Data Link Layer Link Active Reporting Capable位设置,则必须实现Slot Status和Slot Control寄存器。Functions无需实现上述寄存器,保持为0即可。Switch Downstream和Root Ports选择实现Slot Capabilities 2、Slot Status 2和Slot Control 2寄存器,Functions无需实现上述寄存器,保持为0即可。

Root Ports and Root Complex Event Collectors必须实现Root Capabilities, Root Status, and Root Control寄存器,Functions无需实现上述寄存器,保持为0即可。

PCI_Express_Capability_Structure

下面只介绍比较重要的寄存器。

5.3.1.PCI Express Capabilities Register

PCI Express Capabilities寄存器记录了PCIe设备Function类型及相关的capabilities,位域如下图所示。

PCI_Express_Capabilities_Register

PCI Express Capabilities位域的定义如下表所示:

位域定义描述属性
14UndefinedPCIe5.0之前的版本表示是否支持TCS Routing,PCIe5.0未定义RO
13:9Interrupt Message Number使用MSI或MSI-X中断的编号。当Slot Status或Root Status寄存器的状态发生变化时,该PCIe设备可以通过MSI或MSI-X中断通知主机。RO
8Slot Implemented该位为1时表示当前port连接了PCIe插槽。对下行port有效,对上行port无效HwInit
7:4Device/Port Type保存PCIe Function类型,对于多Function的设备,Function类型可能不相同。Type 0配置空间头:0x0表示PCI Express Endpoint,0x1表示Legacy PCI Express Endpoint,0x9表示RCiEP,0xA表示Root Complex Event Collector。Type 1配置空间头:0x4表示Root Port of PCI Express Root Complex,0x5表示Upstream Port of PCI Express Switch,0x6表示Downstream Port of PCI Express Switch,0x7表示PCI Express to PCI/PCI-X Bridge,0x8表示PCI/PCI-X to PCI Express BridgeRO
3:0Capability Version保存PCI-SIG定义的PCI Express Capability structure版本编号RO
5.3.2.Device Capabilities Register

Device Capabilities寄存器记录了PCIe设备Function特有的capabilities,位域如下图所示。

Device_Capabilities_Register

Device Capabilities寄存器位域的定义如下表所示:

位域定义描述属性
28Function Level Reset Capability是否支持FLRRO
27:26Captured Slot Power Limit Scale上行port最大功耗系数,0x0表示1.0,0x1表示0.1,0x2表示0.01,0x3表示0.001RO
25:18Captured Slot Power Limit Value上行port最大功耗,和Captured Slot Power Limit Scale一起使用RO
16ERR_COR Subclass Capable是否支持ERR_COR SubclassRO
15Role-Based Error Reporting是否支持错误上报RO
14:12Undefined未定义RO
11:9Endpoint L1 Acceptable Latency退出L1状态所能接收的延时。0x0表示最大1us,0x1表示最大2us,0x2表示最大4us,0x3表示最大8us,0x4表示最大16us,0x5表示最大32us,0x6表示最大64usRO
8:6Endpoint L0s Acceptable Latency退出L0s状态所能接收的延时。0x0表示最大64ns,0x1表示最大128ns,0x2表示最大256ns,0x3表示最大512ns,0x4表示最大1us,0x5表示最大2us,0x6表示最大4usRO
5Extended Tag Field Supported表示最大支持的Tag长度,0x0表示支持5bit,0x1表示支持8bitRO
4:3Phantom Functions Supported是否支持Phantom FunctionsRO
2:0Max_Payload_Size Supported保存了TLP包中数据包的最大长度。0x0表示128字节,0x1表示256字节,0x2表示512字节,0x3表示1024字节,0x4表示2028字节,0x5表示4096字节。RO
5.3.3.Device Control Register

Device Control寄存器的位域如下图所示,主要用于设置MPS(Max_Payload_Size)、MRRS(Max_Read_Request_Size)。
Device Control Register

5.4.PCI Express Extended Capabilities

PCI Express Extended Capabilities保存在配置空间的100h-FFFh中。PCI Express Extended Capabilities只能通过EACM访问。PCI Express Extended Capabilities布局如下图所示,详细信息可以参考PCIe Space文档。

PCI_Express_Extended_Configuration_Space_Layout

Linux中访问PCI Express Extended Capabilities的代码如下所示。

[include/uapi/linux/pci_regs.h]
#define PCI_CFG_SPACE_SIZE	256
#define PCI_CFG_SPACE_EXP_SIZE	4096
[drivers/pci/pci.c]
int pci_find_next_ext_capability(struct pci_dev *dev, int start, int cap)
{
	u32 header;
	int ttl;
	int pos = PCI_CFG_SPACE_SIZE;

	/* minimum 8 bytes per capability */
	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;

	if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
		return 0;

	if (start)
		pos = start;

	if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
		return 0;

	/*
	 * If we have no capabilities, this is indicated by cap ID,
	 * cap version and next pointer all being 0.
	 */
	if (header == 0)
		return 0;

	while (ttl-- > 0) {
		if (PCI_EXT_CAP_ID(header) == cap && pos != start)
			return pos;

		pos = PCI_EXT_CAP_NEXT(header);
		if (pos < PCI_CFG_SPACE_SIZE)
			break;

		if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
			break;
	}

	return 0;
}

PCIe的配置空间内容很多,且版本升级后又会增加。上述只介绍了配置空间中比较常见的内容,详细内容需要参考最新的PICe Spec文档。

参考资料

  1. PCIEXPRESS体系结构导读
  2. PCI Express technology 3.0
  3. PCI_Express_Base_r3.0_10Nov10
  4. PCI-to-PCI Bridge Architecture Specification Revision 1.1
  5. https://blog.csdn.net/qq_42208449/article/details/132475653
  6. PCI Express® Base Specification Revision 5.0 Version 1.0
  • 22
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用BUS_INTERFACE_STANDARD总线方式访问pcie配置空间的示例代码: ```c // 定义PCI设备的地址 #define PCI_CONFIG_ADDR(bus, dev, func, reg) ((unsigned int)( \ (unsigned int)(bus) << 16 | \ (unsigned int)(dev) << 11 | \ (unsigned int)(func) << 8 | \ (unsigned int)(reg) << 2 | \ (unsigned int)0x80000000) ) // 从PCI配置空间读取一个32位的值 unsigned int ReadPCIConfigDword(BUS_INTERFACE_STANDARD* pBusIntf, unsigned int bus, unsigned int device, unsigned int function, unsigned int reg) { unsigned int addr = PCI_CONFIG_ADDR(bus, device, function, reg); unsigned int value = 0; pBusIntf->ReadBusData(pBusIntf->Context, EfiPciWidthUint32, addr, 1, &value); return value; } // 向PCI配置空间写入一个32位的值 void WritePCIConfigDword(BUS_INTERFACE_STANDARD* pBusIntf, unsigned int bus, unsigned int device, unsigned int function, unsigned int reg, unsigned int value) { unsigned int addr = PCI_CONFIG_ADDR(bus, device, function, reg); pBusIntf->WriteBusData(pBusIntf->Context, EfiPciWidthUint32, addr, 1, &value); } ``` 在上面的代码中,我们首先定义了一个宏来生成PCI设备的地址,然后实现了读取和写入32位值的函数。这些函数使用了EFI的BUS_INTERFACE_STANDARD总线接口来访问PCI配置空间。具体来说,`ReadBusData`和`WriteBusData`函数被用来读取和写入数据。这些函数需要传入总线接口的上下文指针、数据宽度、地址、数据数量和数据缓冲区。在本例中,我们只读写了一个32位的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值