1. 节点BAT2方法VMPS中的PCI地址获取机制解析
在ACPI驱动开发过程中,我们经常会遇到需要获取PCI设备地址信息的场景。最近在调试一个电池设备节点BAT2时,发现其VMPS方法中访问\_SB.PCI0.OEMR会触发acpi!GetPciAddress调用,这个现象值得深入分析。
1.1 问题现象与调用链
当执行BAT2设备的_STA方法时,会调用VMPS方法,其ASL代码如下:
asl复制Method (VMPS, 1, NotSerialized) {
Acquire (OEML, 0xFFFF)
IVOC (0x81, Arg0)
Store (\_SB.PCI0.OEMR, Local0) // 触发GetPciAddress调用
Release (OEML)
Return (Local0)
}
通过Windbg调试,我们可以观察到完整的调用堆栈:
code复制00 ACPI!GetPciAddress
01 ACPI!PciConfigSpaceHandlerWorker
02 ACPI!PciConfigSpaceHandler
03 ACPI!InternalOpRegionHandler
04 ACPI!AccessBaseField
05 ACPI!AccessFieldData
06 ACPI!ReadFieldObj
07 ACPI!RunContext
08 ACPI!DispatchCtxtQueue
09 ACPI!StartTimeSlicePassive
0a ACPI!ACPIWorker
0b nt!PspSystemThreadStartup
0c nt!KiThreadStartup
1.2 GetPciAddress的工作原理
GetPciAddress函数的核心任务是获取PCI设备的Bus和Slot信息。其实现逻辑如下:
- 首先检查是否已经获取过Slot信息(通过state->Flags & PCISUPP_GOT_SLOT_INFO)
- 如果没有,则调用GetPciAddress获取信息并设置标志位
- 将获取到的Bus和Slot信息存入state结构体
关键代码段:
c复制if (!(
