ACPI!ACPIBuildDeviceRequest函数分析和ACPI!ACPIBuildDeviceDpc函数的关系
NTSTATUS
ACPIBuildDeviceRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN PACPI_BUILD_CALLBACK CallBack,
IN PVOID CallBackContext,
IN BOOLEAN RunDPC
)
/*++
Routine Description:
This routine is called when a device extension is ready to be filled in.
This routine creates a request which is enqueued. When the DPC is fired,
the request will be processed
Note: AcpiDeviceTreeLock must be held to call this function
Arguments:
DeviceExtension - The device which wants to be filled in
CallBack - The function to call when done
CallBackContext - The argument to pass to that function
RunDPC - Should we enqueue the DPC immediately (if it is not
running?)
Return Value:
NTSTATUS
--*/
{
PACPI_BUILD_REQUEST buildRequest;
ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
//
// Allocate a buildRequest structure
//
buildRequest = ExAllocateFromNPagedLookasideList(
&BuildRequestLookAsideList
);
if (buildRequest == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// If the current reference is 0, that means that someone else beat
// use to the device extension that that we *CANNOT* touch it
//
if (DeviceExtension->ReferenceCount == 0) {
ExFreeToNPagedLookasideList(
&BuildRequestLookAsideList,
buildRequest
);
return STATUS_DEVICE_REMOVED;
} else {
InterlockedIncrement( &(DeviceExtension->ReferenceCount) );
}
//
// Fill in the structure
//
RtlZeroMemory( buildRequest, sizeof(ACPI_BUILD_REQUEST) );
buildRequest->Signature = ACPI_SIGNATURE;
buildRequest->TargetListEntry = &AcpiBuildDeviceList;
buildRequest->WorkDone = WORK_DONE_STEP_0;
buildRequest->Status = STATUS_SUCCESS;
buildRequest->CallBack = CallBack;
buildRequest->CallBackContext = CallBackContext;
buildRequest->BuildContext = DeviceExtension;
buildRequest->Flags = BUILD_REQUEST_VALID_TARGET |
BUILD_REQUEST_DEVICE;
//
// At this point, we need the spinlock
//
KeAcquireSpinLockAtDpcLevel( &AcpiBuildQueueLock );
//
// Add this to the list
//
InsertTailList(
&AcpiBuildQueueList,
&(buildRequest->ListEntry)
);
//
// Do we need to queue up the DPC?
//
if (RunDPC && !AcpiBuildDpcRunning) {
KeInsertQueueDpc( &AcpiBuildDpc, 0, 0 );
}
//
// Done with the lock
//
KeReleaseSpinLockFromDpcLevel( &AcpiBuildQueueLock );
//
// Done
//
return STATUS_PENDING;
}
0: kd> t
Breakpoint 4 hit
eax=0000000a ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=80ae2bca
eip=f73fcc7c esp=f789a0b4 ebp=f789a0d8 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
ACPI!ACPIBuildDeviceRequest:
f73fcc7c 55 push ebp
0: kd> kc
#
00 ACPI!ACPIBuildDeviceRequest
01 ACPI!OSNotifyCreateDevice
02 ACPI!OSNotifyCreate
03 ACPI!Device
04 ACPI!ParseTerm
05 ACPI!RunContext
06 ACPI!InsertReadyQueue
07 ACPI!RestartContext
08 ACPI!SyncLoadDDB
09 ACPI!AMLILoadDDB
0a ACPI!ACPIInitializeDDB
0b ACPI!ACPIInitializeDDBs
0c ACPI!ACPIInitialize
0d ACPI!ACPIInitStartACPI
0e ACPI!ACPIRootIrpStartDevice
0f ACPI!ACPIDispatchIrp
10 nt!IofCallDriver
11 nt!IopSynchronousCall
12 nt!IopStartDevice
13 nt!PipProcessStartPhase1
14 nt!PipProcessDevNodeTree
15 nt!PipDeviceActionWorker
16 nt!PipRequestDeviceAction
17 nt!IopInitializeBootDrivers
18 nt!IoInitSystem
19 nt!Phase1Initialization
1a nt!PspSystemThreadStartup
1b nt!KiThreadStartup
0: kd> x acpi!AcpiBuildDpc
f743b840 ACPI!AcpiBuildDpc = struct _KDPC
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!_KDPC *)0xf743b840))
(*((ACPI!_KDPC *)0xf743b840)) [Type: _KDPC]
[+0x000] Type : 19 [Type: short]
[+0x002] Number : 0x0 [Type: unsigned char]
[+0x003] Importance : 0x1 [Type: unsigned char]
[+0x004] DpcListEntry [Type: _LIST_ENTRY]
[+0x00c] DeferredRoutine : 0xf73fc5b2 [Type: void (*)(_KDPC *,void *,void *,void *)]
[+0x010] DeferredContext : 0x0 [Type: void *]
[+0x014] SystemArgument1 : 0x0 [Type: void *]
[+0x018] SystemArgument2 : 0x0 [Type: void *]
[+0x01c] DpcData : 0x0 [Type: void *]
0: kd> u f73fc5b2
ACPI!ACPIBuildDeviceDpc [d:\srv03rtm\base\busdrv\acpi\driver\nt\buildsrc.c @ 478]:
f73fc5b2 53 push ebx
f73fc5b3 8b1d70b042f7 mov ebx,dword ptr [ACPI!_imp_KefAcquireSpinLockAtDpcLevel (f742b070)]
f73fc5b9 56 push esi
f73fc5ba be98b843f7 mov esi,offset ACPI!AcpiBuildQueueLock (f743b898)
f73fc5bf 8bce mov ecx,esi
f73fc5c1 ffd3 call ebx
f73fc5c3 803d9eb843f700 cmp byte ptr [ACPI!AcpiBuildDpcRunning (f743b89e)],0
f73fc5ca 740d je ACPI!ACPIBuildDeviceDpc+0x27 (f73fc5d9)
0: kd> dv
DeviceExtension = 0x899c0d58
CallBack = 0x00000000
CallBackContext = 0x00000000
RunDPC = 0x00 ''
0: kd> dx -id 0,0,899a2278 -r1 ((ACPI!_DEVICE_EXTENSION *)0x899c0d58)
((ACPI!_DEVICE_EXTENSION *)0x899c0d58) : 0x899c0d58 [Type: _DEVICE_EXTENSION *]
[+0x000] Flags : 0xa [Type: unsigned __int64]
[+0x000] UFlags [Type: __unnamed]
[+0x008] Signature : 0x5f534750 [Type: unsigned long]
[+0x00c] DebugFlags : 0x0 [Type: unsigned long]
[+0x010] DispatchTable : 0x0 [Type: IRP_DISPATCH_TABLE *]
[+0x014] WorkContext [Type: WORK_QUEUE_CONTEXT]
[+0x014] Fdo [Type: _FDO_DEVICE_EXTENSION]
[+0x014] Filter [Type: _FILTER_DEVICE_EXTENSION]
[+0x014] Pdo [Type: _PDO_DEVICE_EXTENSION]
[+0x058] WorkQueue [Type: EXTENSION_WORKER]
[+0x058] Button [Type: BUTTON_EXTENSION]
[+0x058] Thermal [Type: THERMAL_EXTENSION]
[+0x058] LinkNode [Type: LINK_NODE_EXTENSION]
[+0x058] Dock [Type: DOCK_EXTENSION]
[+0x058] Processor [Type: _PROCESSOR_DEVICE_EXTENSION]
[+0x088] DeviceState : Stopped (0) [Type: _ACPI_DEVICE_STATE]
[+0x08c] PreviousState : Stopped (0) [Type: _ACPI_DEVICE_STATE]
[+0x090] PowerInfo [Type: _ACPI_POWER_INFO]
[+0x10c] DeviceID : 0x0 [Type: unsigned char *]
[+0x10c] Address : 0x0 [Type: unsigned long]
[+0x110] InstanceID : 0x0 [Type: unsigned char *]
[+0x114] ResourceList : 0x0 [Type: _CM_RESOURCE_LIST *]
[+0x118] PnpResourceList : 0x0 [Type: _ObjData *]
[+0x11c] OutstandingIrpCount : 1 [Type: long]
[+0x120] ReferenceCount : 2 [Type: long]
[+0x124] HibernatePathCount : 0 [Type: long]
[+0x128] RemoveEvent : 0x0 [Type: _KEVENT *]
[+0x12c] AcpiObject : 0x899affac [Type: _NSObj *]
[+0x130] DeviceObject : 0x0 [Type: _DEVICE_OBJECT *]
[+0x134] TargetDeviceObject : 0x0 [Type: _DEVICE_OBJECT *]
[+0x138] PhysicalDeviceObject : 0x0 [Type: _DEVICE_OBJECT *]
[+0x13c] ParentExtension : 0x89981a18 [Type: _DEVICE_EXTENSION *]
[+0x140] ChildDeviceList [Type: _LIST_ENTRY]
[+0x148] SiblingDeviceList [Type: _LIST_ENTRY]
[+0x150] EjectDeviceHead [Type: _LIST_ENTRY]
[+0x158] EjectDeviceList [Type: _LIST_ENTRY]
0: kd> x acpi!*rootdevice*
f743b710 ACPI!RootDeviceExtension = 0x89981a18
bp nt!IoCreateDevice
//
// Allocate a buildRequest structure
//
buildRequest = ExAllocateFromNPagedLookasideList(
&BuildRequestLookAsideList
);
if (buildRequest == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
0: kd> p
eax=899860d0 ebx=00000000 ecx=00000001 edx=0000000a esi=899860d0 edi=f743b7e0
eip=f73fccaf esp=f789a0a8 ebp=f789a0b0 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
ACPI!ACPIBuildDeviceRequest+0x33:
f73fccaf 85f6 test esi,esi
0: kd> dt _ACPI_BUILD_REQUEST 899860d0
ACPI!_ACPI_BUILD_REQUEST
+0x000 ListEntry : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x008 Signature : 0
+0x00c Flags : 3
+0x00c UFlags : __unnamed
+0x010 WorkDone : 0x10101
+0x014 CurrentWorkDone : 0x3f8
+0x018 NextWorkDone : 0
+0x01c BuildContext : 0x00000007 Void
+0x020 Status : 0n65538
+0x024 CurrentObject : 0x00000004 _NSObj
+0x028 CallBack : 0x00000004 void +4
+0x02c CallBackContext : 0xffffffff Void
+0x030 DeviceRequest : __unnamed
+0x030 RunRequest : __unnamed
+0x030 SynchronizeRequest : __unnamed
+0x044 Integer : 0x1c2000
+0x044 String : 0x001c2000 "--- memory read error at address 0x001c2000 ---"
+0x044 TargetListEntry : 0x001c2000 _LIST_ENTRY
0: kd> x acpi!AcpiBuildDeviceList
f743b888 ACPI!AcpiBuildDeviceList = struct _LIST_ENTRY [ 0xf743b888 - 0xf743b888 ]
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!_LIST_ENTRY *)0xf743b888))
(*((ACPI!_LIST_ENTRY *)0xf743b888)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0xf743b888 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xf743b888 [Type: _LIST_ENTRY *]
//
// Fill in the structure
//
RtlZeroMemory( buildRequest, sizeof(ACPI_BUILD_REQUEST) );
buildRequest->Signature = ACPI_SIGNATURE;
buildRequest->TargetListEntry = &AcpiBuildDeviceList; 关键地方1:
buildRequest->WorkDone = WORK_DONE_STEP_0;
buildRequest->Status = STATUS_SUCCESS;
buildRequest->CallBack = CallBack;
buildRequest->CallBackContext = CallBackContext;
buildRequest->BuildContext = DeviceExtension; 关键地方2:
buildRequest->Flags = BUILD_REQUEST_VALID_TARGET |
BUILD_REQUEST_DEVICE;
0: kd> dt _ACPI_BUILD_REQUEST 899860d0
ACPI!_ACPI_BUILD_REQUEST
+0x000 ListEntry : _LIST_ENTRY [ 0xf743b890 - 0x899c6d08 ]
+0x008 Signature : 0x5f534750
+0x00c Flags : 0x1001
+0x00c UFlags : __unnamed
+0x010 WorkDone : 3
+0x014 CurrentWorkDone : 0
+0x018 NextWorkDone : 0
+0x01c BuildContext : 0x899c0d58 Void
+0x020 Status : 0n0
+0x024 CurrentObject : (null)
+0x028 CallBack : (null)
+0x02c CallBackContext : (null)
+0x030 DeviceRequest : __unnamed
+0x030 RunRequest : __unnamed
+0x030 SynchronizeRequest : __unnamed
+0x044 Integer : 0xf743b888
+0x044 String : 0xf743b888 "???"
+0x044 TargetListEntry : 0xf743b888 _LIST_ENTRY [ 0xf743b888 - 0xf743b888 ]
//
// Add this to the list
//
InsertTailList(
&AcpiBuildQueueList,
&(buildRequest->ListEntry)
);
0: kd> x acpi!AcpiBuildQueueList
f743b890 ACPI!AcpiBuildQueueList = struct _LIST_ENTRY [ 0x899c6d08 - 0x899860d0 ]
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!_LIST_ENTRY *)0xf743b890))
(*((ACPI!_LIST_ENTRY *)0xf743b890)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x899c6d08 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x899860d0 [Type: _LIST_ENTRY *]
0: kd> dx -id 0,0,899a2278 -r1 ((ACPI!_LIST_ENTRY *)0x899c6d08)
((ACPI!_LIST_ENTRY *)0x899c6d08) : 0x899c6d08 [Type: _LIST_ENTRY *]
[+0x000] Flink : 0x899860d0 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xf743b890 [Type: _LIST_ENTRY *]
参考:第一个是什么情况:
0: kd> dt _ACPI_BUILD_REQUEST 0x899c6d08
ACPI!_ACPI_BUILD_REQUEST
+0x000 ListEntry : _LIST_ENTRY [ 0x899860d0 - 0xf743b890 ]
+0x008 Signature : 0x5f534750
+0x00c Flags : 0x100a
+0x00c UFlags : __unnamed
+0x010 WorkDone : 3
+0x014 CurrentWorkDone : 0
+0x018 NextWorkDone : 0
+0x01c BuildContext : 0x89981a18 Void
+0x020 Status : 0n0
+0x024 CurrentObject : (null)
+0x028 CallBack : 0xf7400be2 void ACPI!ACPIDevicePowerNotifyEvent+0
+0x02c CallBackContext : 0xf789a260 Void
+0x030 DeviceRequest : __unnamed
+0x030 RunRequest : __unnamed
+0x030 SynchronizeRequest : __unnamed
+0x044 Integer : 0xf743b868
+0x044 String : 0xf743b868 "h???"
+0x044 TargetListEntry : 0xf743b868 _LIST_ENTRY [ 0xf743b868 - 0xf743b868 ]
0: kd> u 0xf743b868
ACPI!AcpiBuildSynchronizationList:
f743b868 68b843f768 push 68F743B8h
f743b86d b843f770b8 mov eax,0B870F743h
f743b872 43 inc ebx
f743b873 f770b8 div eax,dword ptr [eax-48h]
f743b876 43 inc ebx
f743b877 f778b8 idiv eax,dword ptr [eax-48h]
f743b87a 43 inc ebx
f743b87b f778b8 idiv eax,dword ptr [eax-48h]
F:\srv03rtm>grep "AcpiBuildSynchronizationList" -nr F:\srv03rtm\base\busdrv\acpi |grep -v "inary"
F:\srv03rtm\base\busdrv\acpi/driver/nt/acpiosnt.c:182: InitializeListHead( &AcpiBuildSynchronizationList );
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:124:LIST_ENTRY AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:717: if (!IsListEmpty( &AcpiBuildSynchronizationList) ) {
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:725: &AcpiBuildSynchronizationList
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:6725: syncRequest->TargetListEntry = &AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:7037: buildRequest->TargetListEntry = &AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.h:256: extern LIST_ENTRY AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/obj/i386/acpi.map:3021: 0003:00003868 _AcpiBuildSynchronizationList 00052868 <common>
F:\srv03rtm\base\busdrv\acpi/tools/kdext/build.c:229: dumpAcpiBuildList( "ACPI!AcpiBuildSynchronizationList" );
NTSTATUS
ACPIBuildSynchronizationRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN PACPI_BUILD_CALLBACK CallBack,
IN PVOID CallBackContext,
IN PLIST_ENTRY SynchronizeListEntry,
IN BOOLEAN RunDPC
)
{
//
// Fill in the structure
//
RtlZeroMemory( buildRequest, sizeof(ACPI_BUILD_REQUEST) );
buildRequest->Signature = ACPI_SIGNATURE;
buildRequest->TargetListEntry = &AcpiBuildSynchronizationList;
0: kd> dt ACPI!_DEVICE_EXTENSION 0x89981a18
+0x000 Flags : 0x0001e000`00200010
+0x000 UFlags : __unnamed
+0x008 Signature : 0x5f534750
+0x00c DebugFlags : 0
+0x010 DispatchTable : 0xf743826c IRP_DISPATCH_TABLE
+0x014 WorkContext : WORK_QUEUE_CONTEXT
+0x014 Fdo : _FDO_DEVICE_EXTENSION
+0x014 Filter : _FILTER_DEVICE_EXTENSION
+0x014 Pdo : _PDO_DEVICE_EXTENSION
+0x058 WorkQueue : EXTENSION_WORKER
+0x058 Button : BUTTON_EXTENSION
+0x058 Thermal : THERMAL_EXTENSION
+0x058 LinkNode : LINK_NODE_EXTENSION
+0x058 Dock : DOCK_EXTENSION
+0x058 Processor : _PROCESSOR_DEVICE_EXTENSION
+0x088 DeviceState : 0 ( Stopped )
+0x08c PreviousState : 0 ( Stopped )
+0x090 PowerInfo : _ACPI_POWER_INFO
+0x10c DeviceID : 0x899bfea0 "ACPI\PNP0C08"
+0x10c Address : 0x899bfea0
+0x110 InstanceID : 0x899c53e8 "0x5F534750"
+0x114 ResourceList : 0x899bfeb8 _CM_RESOURCE_LIST
+0x118 PnpResourceList : (null)
+0x11c OutstandingIrpCount : 0n2
+0x120 ReferenceCount : 0n3
+0x124 HibernatePathCount : 0n0
+0x128 RemoveEvent : (null)
+0x12c AcpiObject : (null)
+0x130 DeviceObject : 0x89981b98 _DEVICE_OBJECT
+0x134 TargetDeviceObject : 0x899c1de0 _DEVICE_OBJECT
+0x138 PhysicalDeviceObject : 0x899c1de0 _DEVICE_OBJECT
+0x13c ParentExtension : (null)
+0x140 ChildDeviceList : _LIST_ENTRY [ 0x899c0ea0 - 0x899c0ea0 ]
+0x148 SiblingDeviceList : _LIST_ENTRY [ 0x89981b60 - 0x89981b60 ]
+0x150 EjectDeviceHead : _LIST_ENTRY [ 0x89981b68 - 0x89981b68 ]
+0x158 EjectDeviceList : _LIST_ENTRY [ 0x89981b70 - 0x89981b70 ]
参考:第一个是什么情况:
0: kd> x acpi!AcpiBuildDpcRunning
f743b89e ACPI!AcpiBuildDpcRunning = 0x00 ''
0: kd> x acpi!RunDPC
0: kd> dv RunDPC
RunDPC = 0x00 ''
//
// Do we need to queue up the DPC?
//
if (RunDPC && !AcpiBuildDpcRunning) {
KeInsertQueueDpc( &AcpiBuildDpc, 0, 0 );
}
//
// Done with the lock
//
KeReleaseSpinLockFromDpcLevel( &AcpiBuildQueueLock );
//
// Done
//
return STATUS_PENDING;
}