503 lines
11 KiB
C
503 lines
11 KiB
C
/*++
|
||
|
||
Copyright (c) 1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
acpi.c
|
||
|
||
Abstract:
|
||
|
||
WinDbg Extension Api for interpretting ACPI data structures
|
||
|
||
Author:
|
||
|
||
Stephane Plante (splante) 21-Mar-1997
|
||
|
||
Based on Code by:
|
||
Peter Wieland (peterwie) 16-Oct-1995
|
||
|
||
Environment:
|
||
|
||
User Mode.
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "pch.h"
|
||
|
||
UCHAR BuildBuffer[2048];
|
||
|
||
|
||
VOID
|
||
dumpAcpiBuildListHeader(
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine displays the top line in the build list dump
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
dprintf("Request Wd Cu Nx BuildCon NsObj Status Union Special\n");
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiBuildList(
|
||
IN PUCHAR ListName
|
||
)
|
||
/*++
|
||
|
||
This routine fetects a single Power Device List from the target and
|
||
displays it
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL status;
|
||
LIST_ENTRY listEntry;
|
||
ULONG_PTR address;
|
||
ULONG returnLength;
|
||
|
||
//
|
||
// Handle the queue list
|
||
//
|
||
address = GetExpression( ListName );
|
||
if (!address) {
|
||
|
||
dprintf( "dumpAcpiBuildList: could not read %s\n", ListName );
|
||
|
||
} else {
|
||
|
||
dprintf("%s at %08lx\n", ListName, address );
|
||
status = ReadMemory(
|
||
address,
|
||
&listEntry,
|
||
sizeof(LIST_ENTRY),
|
||
&returnLength
|
||
);
|
||
if (status == FALSE || returnLength != sizeof(LIST_ENTRY)) {
|
||
|
||
dprintf(
|
||
"dumpAcpiBuildList: could not read LIST_ENTRY at %p\n",
|
||
address
|
||
);
|
||
|
||
} else {
|
||
|
||
dumpAcpiBuildListHeader();
|
||
dumpBuildDeviceListEntry(
|
||
&listEntry,
|
||
address,
|
||
0
|
||
);
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiBuildLists(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine dumps all of the devices lists used by the Build DPC
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL status;
|
||
LIST_ENTRY listEntry;
|
||
ULONG_PTR address;
|
||
ULONG returnLength;
|
||
ULONG value;
|
||
|
||
status = GetUlongPtr( "ACPI!AcpiDeviceTreeLock", &address );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiBuildLists: Could not read ACPI!AcpiDeviceTreeLock\n");
|
||
return;
|
||
|
||
}
|
||
|
||
dprintf("ACPI Build Tree Information\n");
|
||
if (address) {
|
||
|
||
dprintf(" + ACPI!AcpiDeviceTreeLock is owned");
|
||
|
||
//
|
||
// The bits other then the lowest is where the owning thread is
|
||
// located. This function uses the property that -2 is every bit
|
||
// except the least significant one
|
||
//
|
||
if ( (address & (ULONG_PTR) -2) != 0) {
|
||
|
||
dprintf(" by thread at %p\n", (address & (ULONG_PTR) - 2) );
|
||
|
||
} else {
|
||
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf(" - ACPI!AcpiDeviceTreeLock is not owned\n");
|
||
|
||
}
|
||
|
||
status = GetUlongPtr( "ACPI!AcpiBuildQueueLock", &address );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiBuildLists: Could not read ACPI!AcpiBuildQueueLock\n");
|
||
return;
|
||
|
||
}
|
||
if (address) {
|
||
|
||
dprintf(" + ACPI!AcpiBuildQueueLock is owned\n");
|
||
|
||
if ( (address & (ULONG_PTR) -2) != 0) {
|
||
|
||
dprintf(" by thread at %p\n", (address & (ULONG_PTR) - 2) );
|
||
|
||
} else {
|
||
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf(" - ACPI!AcpiBuildQueueLock is not owned\n" );
|
||
|
||
}
|
||
|
||
status = GetUlong( "ACPI!AcpiBuildWorkDone", &value );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiBuildLists: Could not read ACPI!AcpiBuildWorkDone\n");
|
||
return;
|
||
|
||
}
|
||
dprintf(" + AcpiBuildWorkDone = %s\n", (value ? "TRUE" : "FALSE" ) );
|
||
|
||
|
||
status = GetUlong( "ACPI!AcpiBuildDpcRunning", &value );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiBuildLists: Could not read ACPI!AcpiBuildDpcRunning\n");
|
||
return;
|
||
|
||
}
|
||
dprintf(" + AcpiBuildDpcRunning = %s\n", (value ? "TRUE" : "FALSE" ) );
|
||
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildQueueList" );
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildDeviceList" );
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildOperationRegionList" );
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildPowerResourceList" );
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildRunMethodList" );
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildSynchronizationList" );
|
||
dumpAcpiBuildList( "ACPI!AcpiBuildThermalZoneList" );
|
||
}
|
||
|
||
VOID
|
||
dumpBuildDeviceListEntry(
|
||
IN PLIST_ENTRY ListEntry,
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called to dump a list of devices in one of the queues
|
||
|
||
Arguments:
|
||
|
||
ListEntry - The head of the list
|
||
Address - The original address of the list (to see when we looped
|
||
around
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
{
|
||
ULONG_PTR displacement;
|
||
ACPI_BUILD_REQUEST request;
|
||
BOOL stat;
|
||
PACPI_BUILD_REQUEST requestAddress;
|
||
UCHAR buffer1[80];
|
||
UCHAR buffer2[80];
|
||
UCHAR buffer3[5];
|
||
ULONG i = 0;
|
||
ULONG returnLength;
|
||
|
||
memset( buffer3, 0, 5);
|
||
memset( buffer2, 0, 80);
|
||
memset( buffer1, 0, 80);
|
||
|
||
//
|
||
// Look at the next address
|
||
//
|
||
ListEntry = ListEntry->Flink;
|
||
|
||
while (ListEntry != (PLIST_ENTRY) Address) {
|
||
|
||
//
|
||
// Crack the listEntry to determine where the powerRequest is
|
||
//
|
||
requestAddress = CONTAINING_RECORD(
|
||
ListEntry,
|
||
ACPI_BUILD_REQUEST,
|
||
ListEntry
|
||
);
|
||
|
||
//
|
||
// Read the queued item
|
||
//
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) requestAddress,
|
||
&request,
|
||
sizeof(ACPI_BUILD_REQUEST),
|
||
&returnLength
|
||
);
|
||
if (stat == FALSE || returnLength != sizeof(ACPI_BUILD_REQUEST)) {
|
||
|
||
dprintf(
|
||
"dumpBuildDeviceListEntry: Cannot read BuildRequest at %08lx\n",
|
||
requestAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
if (request.CallBack != NULL) {
|
||
|
||
GetSymbol(
|
||
request.CallBack,
|
||
buffer1,
|
||
&displacement
|
||
);
|
||
|
||
} else {
|
||
|
||
buffer1[0] = '\0';
|
||
|
||
}
|
||
if (request.Flags & BUILD_REQUEST_VALID_TARGET) {
|
||
|
||
GetSymbol(
|
||
request.TargetListEntry,
|
||
buffer2,
|
||
&displacement
|
||
);
|
||
|
||
} else {
|
||
|
||
buffer2[0] = '\0';
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the entry for the device
|
||
//
|
||
if (!Verbose) {
|
||
|
||
dprintf(
|
||
"%08lx %2x %2x %2x %08lx %08lx %08lx %08lx",
|
||
requestAddress,
|
||
request.WorkDone,
|
||
request.CurrentWorkDone,
|
||
request.NextWorkDone,
|
||
request.BuildContext,
|
||
request.CurrentObject,
|
||
request.Status,
|
||
request.String
|
||
);
|
||
if (request.Flags & BUILD_REQUEST_VALID_TARGET) {
|
||
|
||
dprintf(
|
||
" T: %08lx (%s)",
|
||
request.TargetListEntry,
|
||
buffer2
|
||
);
|
||
|
||
} else if (request.Flags & BUILD_REQUEST_DEVICE) {
|
||
|
||
dprintf(
|
||
" O: %08lx",
|
||
requestAddress + FIELD_OFFSET( ACPI_BUILD_REQUEST, DeviceRequest.ResultData )
|
||
);
|
||
|
||
} else if (request.Flags & BUILD_REQUEST_RUN) {
|
||
|
||
memcpy( buffer3, request.RunRequest.ControlMethodNameAsUchar, 4);
|
||
dprintf(
|
||
" R: %4s",
|
||
buffer3
|
||
);
|
||
if (request.RunRequest.Flags & RUN_REQUEST_CHECK_STATUS) {
|
||
|
||
dprintf(" Sta");
|
||
|
||
}
|
||
if (request.RunRequest.Flags & RUN_REQUEST_MARK_INI) {
|
||
|
||
dprintf(" Ini");
|
||
|
||
}
|
||
if (request.RunRequest.Flags & RUN_REQUEST_RECURSIVE) {
|
||
|
||
dprintf(" Rec");
|
||
|
||
}
|
||
|
||
} else if (request.Flags & BUILD_REQUEST_SYNC) {
|
||
|
||
dprintf(
|
||
" S: %08lx",
|
||
request.SynchronizeRequest.SynchronizeListEntry
|
||
);
|
||
if (request.SynchronizeRequest.Flags & SYNC_REQUEST_HAS_METHOD) {
|
||
|
||
memcpy( buffer3, request.SynchronizeRequest.SynchronizeMethodNameAsUchar, 4);
|
||
dprintf(
|
||
" %4s",
|
||
buffer3
|
||
);
|
||
}
|
||
|
||
}
|
||
|
||
if (request.CallBack != NULL) {
|
||
|
||
dprintf(" C: %s(%08lx)", buffer1, request.CallBackContext);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
} else {
|
||
|
||
dprintf(
|
||
"%08lx\n"
|
||
" BuildContext: %08lx\n"
|
||
" ListEntry: F - %08lx B - %08lx\n"
|
||
" CallBack: %08lx (%s)\n"
|
||
" CallBackContext: %08lx\n"
|
||
" WorkDone: %lx\n"
|
||
" CurrentWorkDone: %lx\n"
|
||
" NextWorkDone: %lx\n"
|
||
" CurrentObject: %08lx\n"
|
||
" Status: %08lx\n"
|
||
" Flags: %08lx\n"
|
||
" Spare: %08lx\n",
|
||
requestAddress,
|
||
request.BuildContext,
|
||
request.ListEntry.Flink,
|
||
request.ListEntry.Blink,
|
||
request.CallBack,
|
||
buffer1,
|
||
request.CallBackContext,
|
||
request.WorkDone,
|
||
request.CurrentWorkDone,
|
||
request.NextWorkDone,
|
||
request.CurrentObject,
|
||
request.Status,
|
||
request.Flags,
|
||
request.String
|
||
);
|
||
if (request.Flags & BUILD_REQUEST_VALID_TARGET) {
|
||
|
||
dprintf(
|
||
" TargetListEntry: %08lx (%s)\n",
|
||
request.TargetListEntry,
|
||
buffer2
|
||
);
|
||
|
||
} else if (request.Flags & BUILD_REQUEST_DEVICE) {
|
||
|
||
dprintf(
|
||
" ResultData: %08lx\n",
|
||
requestAddress + FIELD_OFFSET( ACPI_BUILD_REQUEST, DeviceRequest.ResultData )
|
||
);
|
||
|
||
} else if (request.Flags & BUILD_REQUEST_RUN) {
|
||
|
||
dprintf(
|
||
" ControlMethodName: %4s\n"
|
||
" ControlMethodFlags: %08lx",
|
||
request.RunRequest.ControlMethodName
|
||
);
|
||
if (request.RunRequest.Flags & RUN_REQUEST_CHECK_STATUS) {
|
||
|
||
dprintf(" Sta");
|
||
|
||
}
|
||
if (request.RunRequest.Flags & RUN_REQUEST_MARK_INI) {
|
||
|
||
dprintf(" Ini");
|
||
|
||
}
|
||
if (request.RunRequest.Flags & RUN_REQUEST_RECURSIVE) {
|
||
|
||
dprintf(" Rec");
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
} else if (request.Flags & BUILD_REQUEST_SYNC) {
|
||
|
||
dprintf(
|
||
" SynchronizeListEntry: %08lx\n"
|
||
" MethodName: %4s\n",
|
||
request.SynchronizeRequest.SynchronizeListEntry,
|
||
request.SynchronizeRequest.SynchronizeMethodNameAsUchar
|
||
);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
//
|
||
// Point to the next entry
|
||
//
|
||
ListEntry = request.ListEntry.Flink;
|
||
|
||
} // while
|
||
|
||
}
|
||
|