为了访问PCI配置空间,根据各种文章使用了I / O端口地址0xCF8、0xCFC。
mov eax, dword 0x80000000
mov dx, word 0x0CF8
out dx, eax
mov dx, word 0x0CFC
in eax, dx
上面代码中eax的值为0x12378086
,表示vendor ID = 0x8086
和device ID = 0x1237
。
这是问题。
第一季度。我已经看到这种方法仅适用于PCI配置空间。那么,访问PCIe配置空间的另一种方法是什么?
“无法使用传统的PCI方法(通过端口0xCF8和0xCFC)访问此扩展的配置空间 ”
https://wiki.osdev.org/PCI_Express
但是其他一些文章说,这种传统方法也与PCIe配置空间兼容。
这令人困惑。
第二季度。如果传统的0xCF8、0xCFC也可以与PCIe配置空间配合使用,那么将不胜枚举NASM汇编源代码(不涉及linux),因为我看过很多ECAM(增强型配置访问机制)文章,但所有这些都是关于概念性内容。
硬件规格:
Motherboard : P775TM1
Processor : Intel i7 8700K
答案 0 :(得分:5)
Q1。我已经看到这种方法仅适用于PCI配置空间。那么,访问PCIe配置空间的另一种方法是什么?
对于80x86 PC,实际上有3种机制可以访问PCI配置空间。您提到的传统机制(使用IO端口0x0CF8和0x0xCFC)是“机制#1”。还有另一种称为“机制2”的传统机制,该机制也使用了0x0CF8和0x0xCFC。但是它并没有被许多芯片组使用,并且(对于现代计算机)可以认为已经过时了。
每个PCI“功能”的PCI配置空间大小最初为256字节;对于这两种传统机制,您只能访问256个字节。当他们发明PCI-E时,他们添加了第三种机制(内存映射的ECAM),并且还将每个PCI-E“功能”的PCI配置空间增加到4096字节。传统的“机制#1”仍然有效,但仍只能访问前256个字节(PCI-E“功能”可以拥有的4096个字节中的一个)。幸运的是,硬件制造商足够聪明,可以确保较旧的操作系统需要访问的内容在前256个字节之内,因此不支持PCI-E的较旧的操作系统仍然可以正常工作(使用“机制#1”),其余4096字节(如果没有ECAM则无法访问)大部分用于PCI-E扩展功能。
注意:可能有一个“ PCI-E到PCI常规”桥,桥后面有PCI常规设备。在这种情况下,即使PCI传统设备/功能仍在使用ECAM,也只能提供256字节的PCI配置空间。
要使用ECAM;您将需要使用ACPI的“表索引”(RSDT或XSDT)来查找称为“ MCFG”的表。遗憾的是(除非自从我上次查找以来已更改),该表在所属的ACPI规范中没有进行描述;而是在PCI规范中进行了描述,该规范被锁定在“恶意昂贵”的PCI SIG付费墙后面。希望您可以在某处找到可靠的第三方描述。
一般而言; MCFG表由描述用于一系列总线号的地址范围的条目组成;总线号的多个不同范围可能有多个不同的地址范围。这个想法是使用设备的总线号来找到正确区域的地址。然后组合“ address_of_area + ((bus - first_bus_for_area) << 20) | (device << 15) | (function << 12)
”以找到功能的PCI配置空间的起始地址。找到后,您可以在该物理页面中读/写偏移量,以访问功能的PCI配置空间中的相应偏移量。
答案 1 :(得分:5)
您阅读了报价
无法使用传统的PCI方法(通过端口0xCF8和0xCFC)访问此扩展的配置空间
脱离上下文。
这是上下文中的引号(强调我的意思):
PCI Express总线将配置空间从256字节扩展到4096字节。无法使用传统的PCI方法(通过端口0xCF8和0xCFC)访问扩展的配置空间 。
作者谈论的是PCIe配置空间的 part ,该空间始于0x100。
一开始,每个PCI设备功能的配置空间为256字节。
在端口0xcf8和0xcfc处使用PCI传统机制(我们可以忽略存在两种机制的事实)来访问此空间。
PCIe将该空间从256字节扩展到4KiB,并引入了一种新的机制来访问配置空间(其中的 all )。
所以,回顾一下:
引用PCIe规范:
PCI Express将配置空间扩展为每个功能4096个字节,而256个字节 PCI本地总线规范允许。
PCI Express配置空间分为PCI 3.0 兼容区域,由功能的配置空间的前256个字节和一个 PCI Express扩展配置空间,由剩余的配置空间组成 (请参见图7-3)。
可以使用以下任一方法访问兼容PCI 3.0的配置空间: PCI本地总线规范 [NdR:旧版配置机制] 中定义的机制或PCI Express增强配置 访问机制(ECAM)将在本节后面介绍。
使用任一访问权限进行的访问 机制是等效的。只能使用ECAM来访问PCI Express扩展配置空间。
非常(非常)可能是英特尔的CPU在未来很多年内将支持旧式PCI配置机制。
在内部,生成PCI配置事务的非核心部分(即系统代理/ UBox)已经仅使用PCIe配置事务(即与ECAM生成的MMCFG类型相同),但是未删除旧软件接口。
由于PCIe根联合体位于CPU中,因此与旧版PCI 软件兼容性有关,CPU是唯一要考虑的问题(旧版PCI需要PCIe至PCI桥接器,这可能会暴露配置)机制)。
简而言之,您可以安全地使用旧式PCI机制来访问PCIe配置空间的前256个字节(每个功能)。
实际上,除非英特尔找到配置非核心设备的新方法,否则传统机制将永远不会消失,因为需要配置ECAM本身。
遗留机制可以直接使用,您已经使用它发布了一些代码。我不确定还需要什么。
您可以像这样使用它:
%define CFG(bus, dev, fun, reg) (0x80000000 | (bus << 16) | (dev << 11) | (fun << 8) | reg)
%macro cfg_arm 4
mov dx, 0cf8h
mov eax, CFG(%1, %2, %3, %4)
out dx, eax
%endmacro
%macro cfg_read 4
cfg_arm %1, %2, %3, %4
mov dx, 0cfch
in eax, dx
%endmacro
%macro cfg_write 5
cfg_arm %1, %2, %3, %4
mov dx, 0cfch
mov eax, %5
out dx, eax
%endmacro
cfg_read 0, 0, 0, 0 ;eax <- VID:DID of dev 0, fun 0 on bus 0
此代码未测试
如果您指的是配置空间的内容(即要设置的内容),则范围太广。
您可以阅读感兴趣设备的数据表,它们通常也可以记录PCI规范中定义的标准寄存器。
或者,您可以阅读PCI规范本身。
如果您问如何使用ECAM,请阅读Brendan的答案。
我唯一可以添加的是,对于您的CPU,您可以通过从CPU的iMC的(传统)PCI配置空间读取寄存器PCIEXBAR(偏移60h)来找到ECAM的基础, ,有趣的0)。
像这样:
cfg_read 0, 0, 0, 60h ;Low 32-bit
mov ebx, eax
cfg_read 0, 0, 0, 64h ;high 32-bit
shl rax, 32
or rax, rbx ;RAX = ptr to ECAM area
固件已将所有内容配置为正确使用此区域。