配置

硬件外围设备通过总线(例如 PCI 总线)连接到 CPU。

在启动过程中,BIOS(或等效的平台启动软件) 会发现连接到 PCI 总线的所有外围设备。 系统会为每个外围设备分配资源(特别是中断矢量、 和地址范围)。

其影响是,分配给每个外围设备的实际资源 在重新启动后会有所不同。 当操作系统软件启动时,它会枚举 总线并启动所有支持设备的驱动程序。 然后,驱动程序会调用 PCI 函数,以获取 其设备,以便能够映射寄存器并绑定到中断。

基础地址寄存器

基本地址寄存器 (BAR) 是一种配置寄存器, PCI 设备。 BIOS 会在其中存储设备相关信息,例如分配的中断矢量 控制寄存器的位置和地址。 其他特定于设备的信息也存储在其中。

调用Pci::MapMmio() 将 BAR 寄存器映射到驱动程序主机的地址空间:

#include <lib/device-protocol/pci.h>

zx_status_t Pci::MapMmio(uint32_t bar_id, uint32_t cache_policy,
                         std::optional<fdf::MmioBuffer>* mmio);

ddk::Pci 类是用于与 PCI 总线通信的接口驱动程序。

第一个参数 bar_id 是 BAR 寄存器编号,从 0 开始。

第二个参数 cache_policy 决定了访问的缓存政策。 可以采用以下值:

cache_policy的值 含义
ZX_CACHE_POLICY_CACHED 使用硬件缓存
ZX_CACHE_POLICY_UNCACHED 停用缓存
ZX_CACHE_POLICY_UNCACHED_DEVICE 停用缓存,并将其视为设备内存
ZX_CACHE_POLICY_WRITE_COMBINING 未缓存,同时写入

请注意,ZX_CACHE_POLICY_UNCACHED_DEVICE 取决于架构 实际上,在某些架构上可能等同于 ZX_CACHE_POLICY_UNCACHED

最后一个参数是已创建缓冲区的输出参数。

读取和写入内存

调用 Pci::MapMmio() 函数返回有效结果,您可以通过 MmioBuffer 接口访问 BAR,例如:

#include <lib/device-protocol/pci.h>
#include <lib/mmio/mmio-buffer.h>

std::optional<fdf::MmioBuffer> mmio;
zx_status_t status = pci.MapMmio(0, ZX_CACHE_POLICY_UNCACHED_DEVICE, &mmio);
if (status == ZX_OK) {
  mmio.Write32(0x1234, REGISTER_X);  // configure register X for deep sleep mode
}