ACPI!ACPIBuildDeviceRequest函数分析和ACPI!ACPIBuildDeviceDpc函数的关系

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;

}