一个 PCI 端点设备,除了 PCI 规范定义的 256 字节配置空间外,它有自己的内存(在端点设备本身上)。必须将此内存带入系统地址空间才能允许系统访问它。有两种方法可以将此内存带入系统地址空间 -
端口映射 IO - 用于访问 IO 设备的地址空间,将通过特殊指令 IN & OUT(在 x86 上)进行访问。x86 使用 0xCFC(配置数据端口)和 0xCF8(配置地址端口)来访问 PCI 端点设备。
内存映射 IO - 为内存映射区域保留的物理地址空间区域将由 LOAD 和 STORE 等内存指令访问。对该 MMIO 区域的访问将针对关联的端点设备。
因此,当一条指令从处理器中出来时,它要么进入内存,要么是一个 IO 操作。在系统中,我们的 IO 地址空间非常有限(x86 机器为 64KB),但物理地址空间非常大。通过端口映射的 IO 访问 PCI 端点设备也相对较慢,因为它需要更多的 CPU 周期。访问内存更快,因为它需要更少的 CPU 周期数,因此 MMIO 是比端口映射 IO 更好的方法。
注意:在枚举过程中,BIOS 必须访问设备的配置空间来进行初始化。此时PCI中只有一种方式访问设备,称为“PCI配置空间访问”机制,使用端口0xCFC和0xCF8访问配置空间,然后BIOS设置端点请求的MMIO范围设备。
注意:当我们说“物理地址空间”时,它是指 CPU 可以访问的地址范围。例如,一个 64 位处理器最多可以有 2^64 = 16EB(取决于正在使用的地址线),这是一个巨大的地址范围。“物理地址空间”并不意味着它在 RAM 内的地址范围。
注意:PCI-SIG(PCI - Special interest group)的 PCI Express 规范建议不要实现 IO 地址空间,IO 地址空间可能会在未来的 PCIe 修订/规范中完全删除。