访问 PCIE 空间的两种方法

本文根据 Intel 文档【参考1】写成。
访问 PCIE 设备配置空间有2种方法: IO Port(0xCF8/0xCFC) 和 MMIO。前者是最传统的方式,能够访问 256Bytes的,很多扩展出来的超过256Bytes的就无能为力了;后者是比较新的方法。
先说一下第一种方法:
image002

比如,我们要访问南桥,Bus:0,Dev:1F,Func:0. 手工计算如下:

Capture

访问时,写为 dport(0xcf8,0x8000F800),写入之后再读取一次dport(0xcfc) 就是结果本例中是 Bus0/Dev 1F/Func 0/ Reg 0 ,PCI设备的 DID、VID
用代码表示就是:
address = BIT31 | ((Bus & 0xFF) << 16) | ((Dev & 0x1F) << 11) | ((Fun & 0x7) << 8) | (Reg & 0xfffffffc); 第二种方法: PCI 的寄存器会映射到内存中,系统中最多有256个Bus, 每个Bus最多有32个Device, 每个Device最多可以有4096个bytes的寄存器. 因此,整个映射最多占用256MB。下面这个图解释这个事情: image003

这么大的位置,是放置在4G以下的位置。一般会以 0xE000 0000为基地址。保险起见,最好查一下你代码中是否有重新定义。或者直接去看 0xE000 0000是否为一个PCI Header。

image004

还是以访问南桥为例子,手工计算如下:
Memory Address = PCI Express* Configuration Space Base Address + (Bus Number x 100000h) + (Device Number x 8000h) + (Function Number x 1000h) +
(Register Offset)

Bus:0,Dev:1F,Func:0 的地址在: 0xE000 0000 + 1Fh x 8000h = 0xE00F8000

参考:
1. http://www.docin.com/p-525417787.html 321090 Accessing PCI Express* Configuration Registers Using Intel® Chipsets

《访问 PCIE 空间的两种方法》有5个想法

  1. 您好,我想问一下,知道了PCI设备的VID和DID号之后,要怎么去读出来设备的设备名呢?比如VID和DID号分别为8086和3ED0,bus/dev/fun为00/00/00时,怎么去读出来Intel Host bridge这个设备名

    1. 你说的这个是来自操作系统中设备驱动的名字,并不是存放在PCI 设备中的信息。如果想读取的话,有两种方法:1.Windows 下面编程,枚举设备管理器中的设备名称。2.自己维护一个 Table, 其中存放VID/DID 和设备名称,需要的时候查表。

  2. 请问一下您的Intel文档【参考1】是Intel开发手册吗?如果是的话请问是哪一卷哪一节,如果不是的话麻烦请告知一下是什么文档。谢谢

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注