PCI 和 PCIe 是否允许更改 BAR 值以将设备寄存器重新映射到新地址?

问题描述 投票:0回答:1

(为我之前的问题道歉,我的内核中的代码错误导致BAR的“所需映射空间”值错误,并且误导了我写了错误的问题描述。)

我正在为我自己的在 x86-64 PC 上工作的内核实现一个简单的 NVMe 驱动程序。由于我的英语很差,虽然我读过 PCIe 规范和其他资料,但我对这些事情不太确定:

  1. BAR的初始值是什么意思(通过固件或其他方式为设备预先分配地址,或者只是一个随机值)?
  2. PCI 或 PCIe 硬件是否允许软件重新分配该地址?可以通过向BAR写入另一个值来更改映射地址吗?
  3. 《PCI Express技术3.0》的结论是,不同标志位组合的BAR描述了3种地址空间:32位内存空间、64位内存空间和I/O空间。这是否意味着与设备通信的3种不同方式:32位mmio ,64位mmio和16位pio(使用x86输入/输出指令)?

在VMware上我定义了一个32GB的虚拟NVMe SSD,对应的值为:0xfea00004(BAR的初始值)0xffffc000(最低非零位为第14位,因此“空格”值为0x4000)

是否意味着SSD的寄存器已经映射到0xfea00000开始的地址,它需要的映射空间是16KB。 16KB对于这款SSD来说绝对够用吗?

顺便问一下,如果BAR的初始值是由固件或其他东西分配的,那么它们排列得很好,没有重叠吗?

x86 x86-64 pci pci-e nvme
1个回答
0
投票

鉴于您的问题有很多问题,我会以交错的方式回复:

  1. BAR 的初始值的含义是什么(由固件或其他方式为设备预先分配地址,或者只是随机的) 值)?

固件已对其进行设置,因此您无需进行枚举即可与设备通信。

  1. PCI 或 PCIe 硬件是否允许软件重新分配该地址?可以通过向BAR写入另一个值来更改映射地址吗?

是的,它可以更改,但是您需要确保其上游的网桥已设置为路由数据包。所有这些都是作为 PCIe 枚举过程的一部分完成的。操作系统通常会(再次)进行 PCIe 总线枚举并丢弃固件设置的旧值。

  1. 《PCI Express技术3.0》得出结论,不同标志位组合的BAR描述了3种地址空间:32bit 内存空间、64位内存空间和I/O空间。这是否意味着3 与设备通信的不同方式:32位mmio、64位mmio和 16位pio(使用x86输入/输出指令)?

有3个地址空间:

  • 内存空间:可以用32位或64位地址来寻址,显然,你用32位来寻址前4GB,剩下的用64位。
  • IO空间:可以使用16位端口或32位端口来解决(某些架构支持32位端口)
  • 配置空间:这个是用来设置BAR的,最多4KB。

这是否意味着SSD的寄存器已映射到地址 0xfea00000,它需要的映射空间是16KB。绝对是16KB 这个SSD够用吗?

没错,对于这种情况,16KB 就足够了,最重要的结构(如命令队列和完成队列)位于 RAM 中,因此,它们不会消耗设备内存空间。

顺便说一句,如果 BAR 的初始值是由固件或 还有一些,它们排列得很好没有重叠吗?

是的,如果固件在将控制权传递给操作系统之前进行了 PCIe 枚举,您可以预期它做得正确并且没有重叠

© www.soinside.com 2019 - 2024. All rights reserved.