裸机UEFI环境下读取PCIe Vendor ID前需执行哪些前置检查?
PCIe裸机开发:读取空设备配置空间导致CPU锁死的问题
我在采用Cix Sky1 SoC的ARM板卡上,基于裸机UEFI启动场景进行PCI Express(PCIe)总线开发。根据OSDev Wiki和PCIe Base Specification v2.0规范,获取PCI配置空间中特定总线的基地址后,应读取配置空间内的VendorID寄存器:若未接入设备,该读取操作会返回0xffff,随后即可转向下一条总线,代码示例如下:
void checkDevice(uint8_t bus, uint8_t device) { uint8_t function = 0; uint16_t vendorID = getVendorID(bus, device, function); if (vendorID == 0xFFFF) return; // Device doesn't exist // ... device does exist, enumerate it }
该逻辑在我测试过的x86 PCIe总线及QEMU的PCIe总线中均能正常工作。但在当前板卡上,若使用固件提供的设备树启动,尝试读取未接入设备的PCI-to-PCI桥的VendorID时,CPU会完全锁死,甚至不产生陷阱,代码示例如下:
void checkDevice (uint8_t bus, uint8_t device) { uint8_t function = 0; printf ("Checking device %d %d %d", bus, device, function); uint16_t vendorId = getVendorID (bus, device, function); // hangs here printf ("Vendor ID %d", vendorId); if (vendorId == 0xFFFF) return; // ... }
请问在PCIe中,读取配置空间前是否需要执行其他操作,以验证该读取操作的有效性?
我已尝试的排查方向:
- PCIe规范提到配置请求可能因设备初始化耗时过长而停滞,但我在两个空插槽上等待超过3分钟仍无响应;
- 固件基于EDK2,可成功遍历PCIe总线(能从连接的NVMe和USB驱动器启动镜像),但我未找到EDK2枚举PCIe主桥的相关逻辑;
- 固件提供的设备树使用兼容字符串
cix,sky1-pcie-host而非通用的pci-ecam-host-generic,且所有节点状态均为okay; - 该芯片无全局根总线,而是包含5个独立的根总线(各有不同总线范围),每个根总线后仅接一个PCI-to-PCI桥及可能的设备。要访问PCIe功能(如CRS软件可见性控制功能),需先检测各根总线是否存在,但读取VendorID的操作恰好会导致停滞;
- 使用ACPI表而非设备树启动时,PCIe枚举可正常进行(编辑补充:实际是PCIe主桥被排除在MCFG表外,我之前误读日志以为这些总线被跳过)。目前我更倾向于使用设备树,因为暂时不想编写完整的AML解释器来访问板卡上的非PCIe设备(如内置USB端口)。
内容的提问来源于stack exchange,提问作者TheHans255
相关产品推荐
相关产品推荐

