【PCI】PCIe配置空间访问(九)

本文参考PCIe协议 5.0:https://download.csdn.net/download/zz2633105/89204842

配置空间结构

PCI协议定义了256 byte配置空间供PCI设备使用,随着科技发展,PCI设备种类增多,各厂商自定义的cap已经不满足于256 byte空间,此外,并行总线的PCI设备传输速率已经达到了瓶颈,因此推出了PCIe设备以替代传统PCI设备。
在这里插入图片描述
PCIe设备将配置空间扩展到了4096 byte,且前256 byte兼容PCI配置空间,因此,PCIe设备可以很好的替代PCI设备,在主机主板支持的情况下,它们能在同一系统下工作。如上图所示,传统PCI设备和PCIe设备都拥有标准配置空间头(0-0x3f),但传统PCI设备的其他cap只能放置于 0x3f~0xff 之间的配置空间中,而PCIe设备的其他cap,则可以放置于 0x3f~0xfff 之间的配置空间中,这意味着PCIe设备能提供更强劲的功能。

访问方式

PCI Express配置模型支持两种配置空间访问机制:

  • PCI-compatible Configuration Access Mechanism(CAM,PCI兼容配置访问机制,参见协议第7.2.1节)
  • PCI Express Enhanced Configuration Access Mechanism(ECAM,PCI Express增强型配置访问机制,参见协议第7.2.2节)

CAM模式是PCI协议定义的访问方式,而ECAM则是PCIe协议定义的访问方式。为了兼容传统PCI设备,PCIe协议要求ECMA机制与CAM机制访问配置空间前256 byte等效。

CAM

以x86为例,X86处理器定义了两个I/O端口寄存器,分别为CONFIG_ADDRESS何CONFIG_DATA寄存器,器地址为0xCF8和0xCFC,CAM访问机制就是通过这两个寄存器实现的。简单来说就是把需要访问的PCI设备信息按特定格式写入CONFIG_ADDRESS(0xCF8)寄存器,然后读写CONFIG_DATA(0xCFC)寄存器即可。

CONFIG_ADDRESS寄存器信息格式如下。
在这里插入图片描述

  • Enable位,第31位。该位为1时,对CONFIG_DATA寄存器进行读写时将引发PCI总线的配置周期。
  • Bus Number字段,第23~16位,访问的PCI设备总线号,每个pci桥扩展出来的信号总线编号,最多256个总线号,host主桥出来的是0号。
  • Device Number字段,第15~11位,访问的PCI设备设备号,每个总线编号下的设备编号,最多32个设备号,从0开始。
  • Function Number字段,第10~8位,访问的PCI设备功能号,设备内部实现的功能编号,最多8个,从0开始。
  • Register Number字段,第7~2位,访问的的配置空间寄存器号,由于寄存器是DW访问了,所以不需要第1~0位。

将PCI设备的总线号、设备号、功能号以及寄存器号填写到CONFIG_ADDRESS寄存器并使能第31位,然后读写CONFIG_DATA寄存器即可读写指定PCI设备的指定寄存器了。可以注意到,Register Number字段只有8bit(DW访问),所以只能访问到配置空间的前256byte。

ECAM

ECAM(Enhanced Configuration Access Mechanism)利用一个扁平的存储器映射地址空间来访问PCIe设备的配置寄存器。根据特定的格式组装访问存储器空间地址,就可以确定访问PCIe设备的配置寄存器,并且将数据更新(对于写操作)或返回(对于读操作)被寻址寄存器的内容。从存储器地址空间到PCI Express配置空间地址的映射格式参见下图定义。

在这里插入图片描述

相比CAM机制,其增加了11~8 bit,用于扩展访问256byte~4k之间的配置空间寄存器。Bus Number正常应该为20~27bit,正好对应256个bus号。更高的31~28 bit则用来作为ECAM的base地址,比如:

X86架构
[root@localhost ~]# cat /proc/iomem | grep MMCONFIG
c0000000-cfffffff : PCI MMCONFIG 0000 [bus 00-ff]

[root@localhost ~]# cat /proc/iomem | grep MMCONFIG
f8000000 - fbffffff : PCI MMCONFIG 0000 [bus 00-3f]

可以看到base地址既有0xf8000000,也有0xc0000000

ARM架构
[root@localhost ~]# cat /proc/iomem | grep ECAM
40000000-4fffffff : PCI ECAM

可以看到base地址为0x40000000

那linux系统怎么知道ECAM机制的base地址呢?对于有BIOS的系统,则由BIOS告诉linux内核;对于ARM(不带BIOS)的系统,则由设备树中填写。

ECAM机制是如何实现的呢?很简单,就是CPU发出地址访问请求,由地址转换部件判断地址是否为预留的ECAM地址区间,再将请求路由给RC或host主桥,当RC或host主桥接收到这段地址的访问,按上述格式解析填写CFG TLP报文下发即可。注意:地址转换部件不是一个真正存在的实体,更多是指功能概念。
在这里插入图片描述
一般来说,系统地址空间会预留256MB(256bus * 32dev * 8func * 4k)空间给ECAM机制使用,当然如果系统比较差,不支持那么多bus号,也可以预留小一点。

用户态访问配置空间工具

lspci

通过lcpsi可以查看系统下有哪些PCIe设备。

[root@localhost ~]# lspci
00:00.0 Host bridge: Intel Corporation Device 4648 (rev 02)
00:02.0 VGA compatible controller: Intel Corporation AlderLake-S GT1 (rev 0c)
00:0a.0 Signal processing controller: Intel Corporation Device 467d (rev 01)
00:0e.0 RAID bus controller: Intel Corporat
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值