windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/kdext/build.c
2020-09-26 16:20:57 +08:00

503 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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
}