分析
更新两次:
看起来这里的问题是如何启用 PCIe ECAM。首次启动 QSP 时,对 0xe000_0000 的访问将转到 RAM。然后,通过 UEFI 初始化 PCIe 系统(在 QPI 控制器中写入 PCIEXBAR 寄存器),并访问 0xe000_0000 命中 PCI 配置空间。在 QSP 6.0.42 和 6.0.53 中,使用标准 QSP UEFI,写入 PCIEXBAR 并显示 mcfg 空间。
在 Simics 中 PCIe 的实现确实在这两个版本之间发生了变化。在最新的 QSP 版本中使用了一个新的 PCIe 库,它改变了 PCIe 的内部结构。这就解释了在最新 QSP 中进入内存访问路径的翻译器,而在旧模型中有一个不透明的对象。软件的相同功能,模型中的不同实现。
要在新模型中发现对 PCIEXBAR 的写入,请使用以下 Simics CLI 命令:
simics> print-device-regs "board.mb.socket[0].qpi_arch"
查看socket 0的设备寄存器,这是所有处理器内核默认所在的位置。
要在 UEFI 写入寄存器时停止,请执行以下操作:
simics> break-io device = "board.mb.socket[0].qpi_arch.bank.f1"
在断点之前,pci_bus 内存的映射如下所示:
simics> board.mb.nb.pci_bus.port.mem.map
┌───────────┬───────────────────────┬──┬──────┬───────────┬───────────────────┬────┬─────┬────┐
│ Base│Object │Fn│Offset│ Length│Target │Prio│Align│Swap│
├───────────┼───────────────────────┼──┼──────┼───────────┼───────────────────┼────┼─────┼────┤
│0x000a_0000│board.mb.gpu.dmap_space│ │0x0000│0x0002_0000│ │ 0│ │ │
│0x000c_0000│board.mb.shadow │ │0x0000│0x0004_0000│board.mb.shadow_mem│ 1│ │ │
│0xfec0_0000│board.mb.sb.ioapic │ │0x0000│ 0x0020│ │ -1│ 8│ │
│0xffe0_0000│board.mb.rom │ │0x0000│0x0020_0000│ │ 0│ │ │
│ -default-│board.mb.dram_space │ │0x0000│ │ │ │ │ │
└───────────┴───────────────────────┴──┴──────┴───────────┴───────────────────┴────┴─────┴────┘
然后在寄存器被写入之后:
simics> board.mb.nb.pci_bus.port.mem.map
┌───────────┬─────────────────────────────────────┬──┬──────┬───────────┬───────────────────┬────┬─────┬────┐
│ Base│Object │Fn│Offset│ Length│Target │Prio│Align│Swap│
├───────────┼─────────────────────────────────────┼──┼──────┼───────────┼───────────────────┼────┼─────┼────┤
│0x000a_0000│board.mb.gpu.dmap_space │ │0x0000│0x0002_0000│ │ 0│ │ │
│0x000c_0000│board.mb.shadow │ │0x0000│0x0004_0000│board.mb.shadow_mem│ 1│ │ │
│0xe000_0000│board.mb.socket[0].qpi_arch.port.mcfg│ │0x0000│0x1000_0000│ │ 0│ │ │
│0xfec0_0000│board.mb.sb.ioapic │ │0x0000│ 0x0020│ │ -1│ 8│ │
│0xffe0_0000│board.mb.rom │ │0x0000│0x0020_0000│ │ 0│ │ │
│ -default-│board.mb.dram_space │ │0x0000│ │ │ │ │ │
└───────────┴─────────────────────────────────────┴──┴──────┴───────────┴───────────────────┴────┴─────┴────┘
因此,问题实际上是您的 UEFI 正在编写什么来激活 PCIEXBAR,以及它在旧模型中如何工作,但在新模型中却没有。
UEFI 运行后
几秒钟后,内存映射会随着 PCIe ECAM 的启用而改变。
新 QSP:
simics> probe-address p:0xe000_0000
┌─────────────────────────────────────┬───────────┬─────┐
│ Target │ Offset │Notes│
├─────────────────────────────────────┼───────────┼─────┤
│board.mb.cpu0.mem[0][0] │0xe000_0000│ │
│board.mb.phys_mem │0xe000_0000│ │
│board.mb.nb.pci_bus.port.mem │0xe000_0000│~ │
│board.mb.nb.pci_bus.mem_space │0xe000_0000│ │
│board.mb.socket[0].qpi_arch.port.mcfg│0x0000_0000│* │
│board.mb.nb.pci_bus.port.cfg │0x0000_0000│~ │
│board.mb.nb.pci_bus.cfg_space │0x0000_0000│ │
│board.mb.nb.bridge.bank.pcie_config │0x0000_0000│ │
└─────────────────────────────────────┴───────────┴─────┘
'*' - Translator implementing 'translator' interface
'~' - Translator implementing 'transaction_translator' interface
Destination: board.mb.nb.bridge.bank.pcie_config offset 0x0
Register: vendor_id @ 0x0 (2 bytes) + 0
旧 QSP(使用功能较弱的 CLI 探测命令):
simics> probe-address p:0xe0000000
┌─────────────────────────┬───────────┬─────┐
│ Target │ Offset │Notes│
├─────────────────────────┼───────────┼─────┤
│board.mb.cpu0.mem[0][0] │0xe000_0000│ │
│board.mb.phys_mem │0xe000_0000│ │
│board.mb.nb.pci_mem │0xe000_0000│ │
│board.mb.socket_sad_f1[0]│0x0000_0000│ │
└─────────────────────────┴───────────┴─────┘
Destination: board.mb.socket_sad_f1[0] offset 0x0 - no register information available
模拟初始状态
调出目标的两个版本并检查物理内存映射。
查看新的 QSP,在运行任何代码之前,从targets/qsp-x86/qsp-clear-linux.simics
脚本开始,我看到了这个:
simics> probe-address obj = "board.mb.cpu0.mem[0][0]" p:0xe010_0000
┌─────────────────────────────┬───────────┬─────┐
│ Target │ Offset │Notes│
├─────────────────────────────┼───────────┼─────┤
│board.mb.cpu0.mem[0][0] │0xe010_0000│ │
│board.mb.phys_mem │0xe010_0000│ │
│board.mb.nb.pci_bus.port.mem │0xe010_0000│~ │
│board.mb.nb.pci_bus.mem_space│0xe010_0000│ │
│board.mb.dram_space │0xe010_0000│ │
│board.mb.ram │0xe010_0000│ │
└─────────────────────────────┴───────────┴─────┘
'~' - Translator implementing 'transaction_translator' interface
Destination: board.mb.ram offset 0xe0100000
simics> board.mb.cpu0.mem[0][0].map
┌───────────┬────────────────────────┬──┬──────┬──────┬──────┬────┬─────┬────┐
│ Base│Object │Fn│Offset│Length│Target│Prio│Align│Swap│
├───────────┼────────────────────────┼──┼──────┼──────┼──────┼────┼─────┼────┤
│0xfee0_0000│board.mb.cpu0.apic[0][0]│ │0x0000│0x1000│ │ 0│ 8│ │
│ -default-│board.mb.phys_mem │ │0x0000│ │ │ │ │ │
└───────────┴────────────────────────┴──┴──────┴──────┴──────┴────┴─────┴────┘
simics> board.mb.phys_mem.map
┌────────────────┬────────────────┬──┬────────────────┬────────────┬──────┬────┬─────┬────┐
│ Base│Object │Fn│ Offset│ Length│Target│Prio│Align│Swap│
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│ 0x0000│board.mb.dram_ │ │ 0x0000│ 0x000a_0000│ │ 0│ │ │
│ │space │ │ │ │ │ │ │ │
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│ 0x0010_0000│board.mb.dram_ │ │ 0x0010_0000│ 0xdff0_0000│ │ 0│ │ │
│ │space │ │ │ │ │ │ │ │
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│0x0001_0000_0000│board.mb.dram_ │ │0x0001_0000_0000│0x0001_0000_│ │ 0│ │ │
│ │space │ │ │ 0000│ │ │ │ │
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│ -default-│board.mb.nb.pci_│ │ 0x0000│ │ │ │ │ │
│ │bus.port.mem │ │ │ │ │ │ │ │
└────────────────┴────────────────┴──┴────────────────┴────────────┴──────┴────┴─────┴────┘
即,该位置应该击中 RAM。
您不能只忽略未映射的写入 - 如果您想在那里保存某些状态,您需要内存或某些设备映射到物理内存。如果被告知将数据写入“虚空”中的位置,处理器将无法做很多合理的工作。
那么 - 您的 UEFI 期望在这些地址上是什么?您如何模拟 PCIe 访问?
在 Simics QSP 6.0.44 中,图片看起来类似:
simics> probe-address obj = "board.mb.cpu0.mem[0][0]" p:0xe010_0000
┌───────────────────────┬───────────┬─────┐
│ Target │ Offset │Notes│
├───────────────────────┼───────────┼─────┤
│board.mb.cpu0.mem[0][0]│0xe010_0000│ │
│board.mb.phys_mem │0xe010_0000│ │
│board.mb.nb.pci_mem │0xe010_0000│ │
│board.mb.dram_space │0xe010_0000│ │
│board.mb.ram │0xe010_0000│ │
└───────────────────────┴───────────┴─────┘
Destination: board.mb.ram offset 0xe0100000
simics> board.mb.cpu0.mem[0][0].map
┌───────────┬────────────────────────┬──┬──────┬──────┬──────┬────┬─────┬────┐
│ Base│Object │Fn│Offset│Length│Target│Prio│Align│Swap│
├───────────┼────────────────────────┼──┼──────┼──────┼──────┼────┼─────┼────┤
│0xfee0_0000│board.mb.cpu0.apic[0][0]│ │0x0000│0x1000│ │ 0│ 8│ │
│ -default-│board.mb.phys_mem │ │0x0000│ │ │ │ │ │
└───────────┴────────────────────────┴──┴──────┴──────┴──────┴────┴─────┴────┘
simics> board.mb.phys_mem.map
┌────────────────┬────────────────┬──┬────────────────┬────────────┬──────┬────┬─────┬────┐
│ Base│Object │Fn│ Offset│ Length│Target│Prio│Align│Swap│
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│ 0x0000│board.mb.dram_ │ │ 0x0000│ 0x000a_0000│ │ 0│ │ │
│ │space │ │ │ │ │ │ │ │
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│ 0x0010_0000│board.mb.dram_ │ │ 0x0010_0000│ 0xdff0_0000│ │ 0│ │ │
│ │space │ │ │ │ │ │ │ │
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│0x0001_0000_0000│board.mb.dram_ │ │0x0001_0000_0000│0x0001_0000_│ │ 0│ │ │
│ │space │ │ │ 0000│ │ │ │ │
├────────────────┼────────────────┼──┼────────────────┼────────────┼──────┼────┼─────┼────┤
│ -default-│board.mb.nb.pci_│ │ 0x0000│ │ │ │ │ │
│ │mem │ │ │ │ │ │ │ │
└────────────────┴────────────────┴──┴────────────────┴────────────┴──────┴────┴─────┴────┘