3541 lines
80 KiB
C
3541 lines
80 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 Buffer[2048];
|
||
PCCHAR DeviceStateTable[] = {
|
||
"Stopped",
|
||
"Inactive",
|
||
"Started",
|
||
"Removed",
|
||
"SurpriseRemoved",
|
||
"Invalid",
|
||
};
|
||
PCCHAR DevicePowerStateTable[] = {
|
||
"PowerDeviceUnspecified",
|
||
"PowerDeviceD0",
|
||
"PowerDeviceD1",
|
||
"PowerDeviceD2",
|
||
"PowerDeviceD3",
|
||
"PowerDeviceMaximum",
|
||
};
|
||
PCCHAR SystemPowerStateTable[] = {
|
||
"PowerSystemUnspecified",
|
||
"PowerSystemWorking",
|
||
"PowerSystemSleepingS1",
|
||
"PowerSystemSleepingS2",
|
||
"PowerSystemSleepingS3",
|
||
"PowerSystemHibernate",
|
||
"PowerSystemShutdown",
|
||
"PowerSystemMaximum",
|
||
};
|
||
PCCHAR SystemPowerActionTable[] = {
|
||
"PowerActionNone",
|
||
"PowerActionReserved",
|
||
"PowerActionSleep",
|
||
"PowerActionHibernate",
|
||
"PowerActionShutdown",
|
||
"PowerActionShutdownReset",
|
||
"PowerActionShutdownOff",
|
||
"PowerActionWarmEject"
|
||
};
|
||
CCHAR ReallyShortDevicePowerStateTable[] = {
|
||
'W',
|
||
'0',
|
||
'1',
|
||
'2',
|
||
'3',
|
||
'M',
|
||
};
|
||
PCCHAR ShortDevicePowerStateTable[] = {
|
||
"Dw",
|
||
"D0",
|
||
"D1",
|
||
"D2",
|
||
"D3",
|
||
"Dmax",
|
||
};
|
||
CCHAR ReallyShortSystemPowerStateTable[] = {
|
||
'W',
|
||
'0',
|
||
'1',
|
||
'2',
|
||
'3',
|
||
'4',
|
||
'5',
|
||
'M',
|
||
};
|
||
PCCHAR ShortSystemPowerStateTable[] = {
|
||
"Sx",
|
||
"S0",
|
||
"S1",
|
||
"S2",
|
||
"S3",
|
||
"S4",
|
||
"S5",
|
||
"SM",
|
||
};
|
||
PCCHAR WorkDone[] = {
|
||
"Complete",
|
||
"Pending",
|
||
"Failure",
|
||
"Step 0",
|
||
"Step 1",
|
||
"Step 2",
|
||
"Step 3",
|
||
"Step 4",
|
||
"Step 5",
|
||
"Step 6",
|
||
"Step 7",
|
||
"Step 8",
|
||
"Step 9",
|
||
"Step 10",
|
||
"Step 11",
|
||
"Step 12",
|
||
"Step 13",
|
||
"Step 14",
|
||
"Step 15",
|
||
"Step 16",
|
||
"Step 17",
|
||
"Step 18",
|
||
"Step 19",
|
||
"Step 20",
|
||
"Step 21",
|
||
"Step 22",
|
||
"Step 23",
|
||
"Step 24",
|
||
"Step 25",
|
||
"Step 26",
|
||
};
|
||
|
||
FLAG_RECORD DeviceExtensionButtonEventFlags[] = {
|
||
{ 0x00000001, "Pwr", "\"Power Button\"" , NULL, NULL },
|
||
{ 0x00000002, "Slp", "\"Sleep Button\"" , NULL, NULL },
|
||
{ 0x00000004, "Lid", "\"Lid Switch\"" , NULL, NULL },
|
||
{ 0x80000000, "Wake", "\"Wake Capable\"" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD DeviceExtensionFlags[] = {
|
||
{ 0x0000000000000001, "Nev", "NeverPresent" , NULL, NULL },
|
||
{ 0x0000000000000002, "!P" , "NotPresent" , NULL, NULL },
|
||
{ 0x0000000000000004, "Rmv", "Removed" , NULL, NULL },
|
||
{ 0x0000000000000008, "!F" , "NotFound" , NULL, NULL },
|
||
{ 0x0000000000000010, "Fdo", "FunctionalDeviceObject" , NULL, NULL },
|
||
{ 0x0000000000000020, "Pdo", "PhysicalDeviceObject" , NULL, NULL },
|
||
{ 0x0000000000000040, "Fil", "Filter" , NULL, NULL },
|
||
{ 0x0000000000010000, "Wak", "Wake" , NULL, NULL },
|
||
{ 0x0000000000020000, "Raw", "RawOK" , NULL, NULL },
|
||
{ 0x0000000000040000, "But", "Button" , NULL, NULL },
|
||
{ 0x0000000000080000, "PS0", "AlwaysOn" , NULL, NULL },
|
||
{ 0x0000000000100000, "!Fil", "NeverFilter" , NULL, NULL },
|
||
{ 0x0000000000200000, "!Stop", "NeverStop" , NULL, NULL },
|
||
{ 0x0000000000400000, "!Off", "NeverOverrideOff" , NULL, NULL },
|
||
{ 0x0000000000800000, "ISA", "ISABus" , NULL, NULL },
|
||
{ 0x0000000001000000, "EIO", "EIOBus" , NULL, NULL },
|
||
{ 0x0000000002000000, "PCI", "PCIBus" , NULL, NULL },
|
||
{ 0x0000000004000000, "Ser", "SerialPort" , NULL, NULL },
|
||
{ 0x0000000008000000, "Tz", "ThermalZone" , NULL, NULL },
|
||
{ 0x0000000010000000, "Lnk", "LinkNode" , NULL, NULL },
|
||
{ 0x0000000020000000, "!UI", "NoShowInUI" , NULL, NULL },
|
||
{ 0x0000000040000000, "!!UI", "NeverShowInUI" , NULL, NULL },
|
||
{ 0x0000000080000000, "D3", "StartInD3" , NULL, NULL },
|
||
{ 0x0000000100000000, "pci", "PCIDevice" , NULL, NULL },
|
||
{ 0x0000000200000000, "PIC", "ProgrammableInterruptController" , NULL, NULL },
|
||
{ 0x0000000400000000, "Dock-", "UnattachedDock" , NULL, NULL },
|
||
{ 0x0000100000000000, "Adr", "HasAddress" , NULL, NULL },
|
||
{ 0x0000200000000000, "HID", "HasHardwareID" , NULL, NULL },
|
||
{ 0x0000400000000000, "UID", "HasUniqueID" , NULL, NULL },
|
||
{ 0x0000800000000000, "hid", "FakeHardwareID" , NULL, NULL },
|
||
{ 0x0001000000000000, "uid", "FakeUniqueID" , NULL, NULL },
|
||
{ 0x0002000000000000, "BAD", "FailedInit" , NULL, NULL },
|
||
{ 0x0004000000000000, "SRS", "Programmable" , NULL, NULL },
|
||
{ 0x0008000000000000, "Fake", "NoAcpiObject" , NULL, NULL },
|
||
{ 0x0010000000000000, "Excl", "Exclusive" , NULL, NULL },
|
||
{ 0x0020000000000000, "Ini", "RanINI" , NULL, NULL },
|
||
{ 0x0040000000000000, "Ena", "Enabled" , "!Ena", "NotEnabled" },
|
||
{ 0x0080000000000000, "BAD", "Failed" , NULL, NULL },
|
||
{ 0x0100000000000000, "Pwr", "AcpiPower" , NULL, NULL },
|
||
{ 0x0200000000000000, "Dock", "DockProfile" , NULL, NULL },
|
||
{ 0x0400000000000000, "S->D", "BuiltPowerTables" , NULL, NULL },
|
||
{ 0x0800000000000000, "PME", "UsesPME" , NULL, NULL },
|
||
{ 0x1000000000000000, "!Lid", "NoLidAction" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD DeviceExtensionThermalFlags[] = {
|
||
{ 0x00000001, "Cooling", "\"Cooling Level\"" , NULL, NULL },
|
||
{ 0x00000002, "Temp", "Temp" , NULL, NULL },
|
||
{ 0x00000004, "Trip", "\"Trip Points\"" , NULL, NULL },
|
||
{ 0x00000008, "Mode", "Mode" , NULL, NULL },
|
||
{ 0x00000010, "Init", "Initialize" , NULL, NULL },
|
||
{ 0x20000000, "Wait", "\"Wait for Notify\"" , NULL, NULL },
|
||
{ 0x40000000, "Busy", "Busy" , NULL, NULL },
|
||
{ 0x80000000, "Loop", "\"In Service Loop\"" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD PM1ControlFlags[] = {
|
||
{ 0x0001, "", "SCI_EN" , NULL, NULL },
|
||
{ 0x0002, "", "BM_RLD" , NULL, NULL },
|
||
{ 0x0004, "", "GBL_RLS" , NULL, NULL },
|
||
{ 0x0400, "", "SLP_TYP0" , NULL, NULL },
|
||
{ 0x0800, "", "SLP_TYP1" , NULL, NULL },
|
||
{ 0x1000, "", "SLP_TYP2" , NULL, NULL },
|
||
{ 0x2000, "", "SLP_EN" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD PM1StatusFlags[] = {
|
||
{ 0x0001, "", "TMR_STS" , NULL, NULL },
|
||
{ 0x0010, "", "BM_STS" , NULL, NULL },
|
||
{ 0x0020, "", "GBL_STS" , NULL, NULL },
|
||
{ 0x0100, "", "PWRBTN_STS" , NULL, NULL },
|
||
{ 0x0200, "", "SLPBTN_STS" , NULL, NULL },
|
||
{ 0x0400, "", "RTC_STS" , NULL, NULL },
|
||
{ 0x8000, "", "WAK_STS" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD PM1EnableFlags[] = {
|
||
{ 0x0001, "", "TMR_EN" , NULL, NULL },
|
||
{ 0x0020, "", "GBL_EN" , NULL, NULL },
|
||
{ 0x0100, "", "PWRBTN_EN" , NULL, NULL },
|
||
{ 0x0200, "", "SLPBTN_EN" , NULL, NULL },
|
||
{ 0x0400, "", "RTC_EN" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD PowerNodeFlags[] = {
|
||
{ 0x00001, "PO", "Present" , NULL, NULL },
|
||
{ 0x00002, "Init", "Initialized" , NULL, NULL },
|
||
{ 0x00004, "!STA", "\"Status Unknown\"" , NULL, NULL },
|
||
{ 0x00010, "On", "On" , "Off", "Off" },
|
||
{ 0x00020, "On+", "OverrideOn" , NULL, NULL },
|
||
{ 0x00040, "Off-", "OverrideOff" , NULL, NULL },
|
||
{ 0x00200, "On++", "AlwaysOn" , NULL, NULL },
|
||
{ 0x00400, "Off--", "AlwaysOff" , NULL, NULL },
|
||
{ 0x10000, "Fail", "Failed" , NULL, NULL },
|
||
{ 0x20000, "Hiber", "HibernatePath" , NULL, NULL },
|
||
};
|
||
|
||
FLAG_RECORD PowerRequestFlags[] = {
|
||
{ 0x00001, "Dly", "Delayed", NULL, NULL },
|
||
{ 0x00002, "!Q", "NoQueue", NULL, NULL },
|
||
{ 0x00004, "Lck", "LockDevice", NULL, NULL },
|
||
{ 0x00008, "!Lck", "UnlockDevice", NULL, NULL },
|
||
{ 0x00010, "+Hbr", "LockHiber", NULL, NULL },
|
||
{ 0x00020, "-Hbr", "UnlockHiber", NULL, NULL },
|
||
{ 0x00040, "Can", "HasCancel", NULL, NULL },
|
||
};
|
||
|
||
VOID
|
||
displayAcpiDeviceExtension(
|
||
IN PDEVICE_EXTENSION DeviceExtension,
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is responsible for displaying a device extension
|
||
|
||
Arguments:
|
||
|
||
DeviceExtension - Extension to display
|
||
Address - Where the extension lives in memory
|
||
Verbose - How much information to display
|
||
IndentLevel - How much to tab it over
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL b;
|
||
DEVICE_POWER_STATE k;
|
||
DWORD_PTR displacement;
|
||
IRP_DISPATCH_TABLE dispatchTable;
|
||
PACPI_POWER_INFO powerInfo;
|
||
SYSTEM_POWER_STATE s;
|
||
UCHAR indent[80];
|
||
ULONG i,j;
|
||
ULONG returnLength;
|
||
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
powerInfo = &(DeviceExtension->PowerInfo);
|
||
|
||
//
|
||
// Check signature
|
||
//
|
||
if (DeviceExtension->Signature != ACPI_SIGNATURE) {
|
||
|
||
dprintf(
|
||
"%s Unknown Signature. This does appear to be an "
|
||
"ACPI Extension\n",
|
||
indent
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Line #1
|
||
//
|
||
dprintf("%sACPI DeviceExtension - %lx - ",indent, Address);
|
||
displayAcpiDeviceExtensionName( Address );
|
||
#if 0
|
||
if (DeviceExtension->Flags & DEV_PROP_HID) {
|
||
|
||
if (DeviceExtension->DeviceID != NULL) {
|
||
|
||
memset( Buffer, '0', 2048 );
|
||
b = ReadMemory(
|
||
(ULONG_PTR) DeviceExtension->DeviceID,
|
||
Buffer,
|
||
32,
|
||
&returnLength
|
||
);
|
||
if (!b || Buffer[0] == '\0') {
|
||
|
||
dprintf(" (%lx)", DeviceExtension->DeviceID );
|
||
|
||
} else {
|
||
|
||
dprintf(" %s", Buffer );
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf( " NULL" );
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_UID) {
|
||
|
||
if (DeviceExtension->InstanceID) {
|
||
|
||
memset( Buffer, '0', 256 );
|
||
b = ReadMemory(
|
||
(ULONG_PTR) DeviceExtension->InstanceID,
|
||
Buffer,
|
||
256,
|
||
&returnLength);
|
||
if (!b || returnLength != 256 || Buffer[0] == '\0') {
|
||
|
||
dprintf(" [ (%lx) ]", DeviceExtension->InstanceID );
|
||
|
||
} else {
|
||
|
||
dprintf(" [%s]", Buffer );
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf(" [NULL]");
|
||
|
||
}
|
||
|
||
}
|
||
|
||
} else if (DeviceExtension->Flags & DEV_PROP_ADDRESS) {
|
||
|
||
dprintf(" %lx", DeviceExtension->Address );
|
||
|
||
}
|
||
#endif
|
||
dprintf("\n");
|
||
|
||
//
|
||
// Line #2
|
||
//
|
||
dprintf(
|
||
"%s DevObj %8lx PhysicalObj %8lx ",
|
||
indent,
|
||
DeviceExtension->DeviceObject,
|
||
DeviceExtension->PhysicalDeviceObject
|
||
);
|
||
if (DeviceExtension->TargetDeviceObject != NULL) {
|
||
|
||
dprintf("AttachedTo %8lx", DeviceExtension->TargetDeviceObject );
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
//
|
||
// Line #3
|
||
//
|
||
dprintf(
|
||
"%s AcpiObject %8lx ParentExt %8lx\n",
|
||
indent,
|
||
DeviceExtension->AcpiObject,
|
||
DeviceExtension->ParentExtension
|
||
);
|
||
|
||
//
|
||
// Line #4
|
||
//
|
||
dprintf(
|
||
"%s PnpState %-8s OldPnpState %-8s\n",
|
||
indent,
|
||
DeviceStateTable[DeviceExtension->DeviceState],
|
||
DeviceStateTable[DeviceExtension->PreviousState]
|
||
);
|
||
|
||
//
|
||
// Line #4
|
||
//
|
||
dprintf("%s ",indent);
|
||
if (DeviceExtension->ResourceList != NULL) {
|
||
|
||
dprintf("CmResList %lx ", DeviceExtension->ResourceList );
|
||
|
||
} else {
|
||
|
||
dprintf(" ");
|
||
|
||
}
|
||
if (DeviceExtension->PnpResourceList != NULL) {
|
||
|
||
dprintf("PnpResList %lx ", DeviceExtension->PnpResourceList );
|
||
|
||
} else {
|
||
|
||
dprintf(" ");
|
||
|
||
}
|
||
|
||
dprintf(
|
||
"RefCounts %dD %dI %dH %dW\n",
|
||
DeviceExtension->ReferenceCount,
|
||
DeviceExtension->OutstandingIrpCount,
|
||
DeviceExtension->HibernatePathCount,
|
||
powerInfo->WakeSupportCount
|
||
);
|
||
|
||
//
|
||
// Line #5
|
||
//
|
||
if (DeviceExtension->Flags & DEV_PROP_DOCK) {
|
||
|
||
dprintf( "%s Dock %8lx ", indent, DeviceExtension->Dock );
|
||
|
||
} else {
|
||
|
||
dprintf( "%s ", indent );
|
||
|
||
}
|
||
dprintf(
|
||
"Dispatch %8lx ",
|
||
DeviceExtension->DispatchTable
|
||
);
|
||
if (DeviceExtension->RemoveEvent != NULL) {
|
||
|
||
dprintf("Remove %lx", DeviceExtension->RemoveEvent);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
//
|
||
// Line #6
|
||
//
|
||
if (powerInfo->DeviceNotifyHandler != NULL) {
|
||
|
||
GetSymbol(
|
||
powerInfo->DeviceNotifyHandler,
|
||
Buffer,
|
||
&displacement
|
||
);
|
||
dprintf(
|
||
"%s Handler %lx Context %8lx %s+%x\n",
|
||
indent,
|
||
powerInfo->DeviceNotifyHandler,
|
||
powerInfo->Context,
|
||
Buffer,
|
||
displacement
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Line #7-12
|
||
//
|
||
for (k = PowerDeviceUnspecified; k <= PowerDeviceD3; k++) {
|
||
|
||
if (k < PowerDeviceD3) {
|
||
|
||
if (powerInfo->PowerObject[k] == NULL &&
|
||
powerInfo->PowerNode[k] == NULL) {
|
||
|
||
continue;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
if (powerInfo->PowerObject[k] == NULL) {
|
||
|
||
continue;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// Did we print on this line?
|
||
//
|
||
b = FALSE;
|
||
dprintf("%s ", indent);
|
||
if (powerInfo->PowerObject[k] != NULL) {
|
||
|
||
dprintf(
|
||
"_PS%c %lx ",
|
||
ReallyShortDevicePowerStateTable[k],
|
||
powerInfo->PowerObject[k]
|
||
);
|
||
b = TRUE;
|
||
|
||
}
|
||
if (k <= PowerDeviceD2 && powerInfo->PowerNode[k] != NULL) {
|
||
|
||
if (b) {
|
||
|
||
dprintf(
|
||
"%s Nodes %lx ",
|
||
ShortDevicePowerStateTable[k],
|
||
powerInfo->PowerNode[k]
|
||
);
|
||
|
||
} else {
|
||
|
||
dprintf(
|
||
"%s Nodes %lx ",
|
||
ShortDevicePowerStateTable[k],
|
||
powerInfo->PowerNode[k]
|
||
);
|
||
|
||
}
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
//
|
||
// Line #13
|
||
//
|
||
dprintf( "%s State %-2s", indent, ShortDevicePowerStateTable[powerInfo->PowerState]);
|
||
if (powerInfo->DesiredPowerState != powerInfo->PowerState) {
|
||
|
||
dprintf("->%-4s ", ShortDevicePowerStateTable[powerInfo->DesiredPowerState]);
|
||
|
||
} else {
|
||
|
||
dprintf(" ");
|
||
|
||
}
|
||
dprintf("SxD Mapping ");
|
||
for (s = PowerSystemWorking; s < PowerSystemMaximum; s++) {
|
||
|
||
k = powerInfo->DevicePowerMatrix[s];
|
||
if (k == PowerDeviceUnspecified) {
|
||
|
||
continue;
|
||
|
||
}
|
||
dprintf(
|
||
"S%c->D%c ",
|
||
ReallyShortSystemPowerStateTable[s],
|
||
ReallyShortDevicePowerStateTable[k]
|
||
);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
//
|
||
// Line #14
|
||
//
|
||
if (DeviceExtension->Flags & DEV_CAP_WAKE) {
|
||
|
||
//
|
||
// Print the start of the line
|
||
//
|
||
dprintf("%s ", indent);
|
||
|
||
s = powerInfo->SystemWakeLevel;
|
||
if (s == PowerSystemUnspecified) {
|
||
|
||
dprintf("Sw->Sx " );
|
||
|
||
} else {
|
||
|
||
dprintf("Sw->S%c ", ReallyShortSystemPowerStateTable[s] );
|
||
|
||
}
|
||
|
||
k = DeviceExtension->PowerInfo.DeviceWakeLevel;
|
||
if (k == PowerDeviceUnspecified) {
|
||
|
||
dprintf("Dw->Dx " );
|
||
|
||
} else {
|
||
|
||
dprintf("Dw->D%c ", ReallyShortDevicePowerStateTable[k] );
|
||
|
||
}
|
||
dprintf(
|
||
" Wake Pin %8d WakeCount %8x\n",
|
||
powerInfo->WakeBit,
|
||
powerInfo->WakeSupportCount
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Line #15
|
||
//
|
||
if (powerInfo->CurrentPowerRequest != NULL) {
|
||
|
||
dprintf(
|
||
"%s CurrentReq %lx ",
|
||
indent,
|
||
powerInfo->CurrentPowerRequest
|
||
);
|
||
if (powerInfo->PowerRequestListEntry.Flink !=
|
||
(PLIST_ENTRY) (Address + FIELD_OFFSET(DEVICE_EXTENSION, PowerInfo.PowerRequestListEntry) ) ) {
|
||
|
||
dprintf(
|
||
"PowerReqList %lx %lx",
|
||
CONTAINING_RECORD( powerInfo->PowerRequestListEntry.Flink, ACPI_POWER_REQUEST, SerialListEntry ),
|
||
CONTAINING_RECORD( powerInfo->PowerRequestListEntry.Blink, ACPI_POWER_REQUEST, SerialListEntry )
|
||
);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
//
|
||
// At this point, we are done with the common bits, and now deal with the
|
||
// special parts of the extension
|
||
//
|
||
if ( (DeviceExtension->Flags & DEV_TYPE_FDO) ) {
|
||
|
||
dprintf(
|
||
"%s DPC Obj %8lx Int Object %08lx\n",
|
||
indent,
|
||
(Address + FIELD_OFFSET(DEVICE_EXTENSION, Fdo.InterruptDpc) ),
|
||
DeviceExtension->Fdo.InterruptObject
|
||
);
|
||
dprintf(
|
||
"%s PM1 Status %8lx\n",
|
||
indent,
|
||
DeviceExtension->Fdo.Pm1Status
|
||
);
|
||
dumpPM1StatusRegister( DeviceExtension->Fdo.Pm1Status, IndentLevel + 2 );
|
||
|
||
}
|
||
if ( (DeviceExtension->Flags & DEV_CAP_BUTTON) ) {
|
||
|
||
dprintf(
|
||
"%s LidState %-8s SpinLock %x ",
|
||
indent,
|
||
(DeviceExtension->Button.LidState ? "TRUE" : "FALSE"),
|
||
(Address + FIELD_OFFSET(DEVICE_EXTENSION, Button.SpinLock) )
|
||
);
|
||
if (DeviceExtension->Button.Events) {
|
||
|
||
dumpFlags(
|
||
(DeviceExtension->Button.Events),
|
||
&DeviceExtensionButtonEventFlags[0],
|
||
sizeof(DeviceExtensionButtonEventFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel,
|
||
(DUMP_FLAG_SHORT_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE | DUMP_FLAG_NO_EOL)
|
||
);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
if (DeviceExtension->Button.Capabilities) {
|
||
|
||
dprintf(
|
||
"%s Capability %lx ",
|
||
indent,
|
||
DeviceExtension->Button.Capabilities
|
||
);
|
||
dumpFlags(
|
||
(DeviceExtension->Button.Capabilities),
|
||
&DeviceExtensionButtonEventFlags[0],
|
||
sizeof(DeviceExtensionButtonEventFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel,
|
||
(DUMP_FLAG_LONG_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE | DUMP_FLAG_NO_EOL)
|
||
);
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
}
|
||
if ( (DeviceExtension->Flags & DEV_CAP_THERMAL_ZONE) ) {
|
||
|
||
THRM_INFO thrm;
|
||
|
||
dprintf(
|
||
"%s Info %lx Flags %8x ",
|
||
indent,
|
||
DeviceExtension->Thermal.Info,
|
||
DeviceExtension->Thermal.Flags
|
||
);
|
||
dumpFlags(
|
||
(DeviceExtension->Thermal.Flags),
|
||
&DeviceExtensionThermalFlags[0],
|
||
sizeof(DeviceExtensionThermalFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel,
|
||
(DUMP_FLAG_SHORT_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE | DUMP_FLAG_NO_EOL)
|
||
);
|
||
dprintf("\n");
|
||
|
||
//
|
||
// Read the thermal Information and print it
|
||
//
|
||
b = ReadMemory(
|
||
(ULONG_PTR) DeviceExtension->Thermal.Info,
|
||
&thrm,
|
||
sizeof(THRM_INFO),
|
||
&returnLength
|
||
);
|
||
if (!b || returnLength != sizeof(THRM_INFO)) {
|
||
|
||
dprintf(
|
||
"%s Could not read THRM_INFO @ %08lx\n",
|
||
indent,
|
||
DeviceExtension->Thermal.Info
|
||
);
|
||
|
||
} else {
|
||
|
||
displayThermalInfo(
|
||
&thrm,
|
||
(ULONG_PTR) DeviceExtension->Thermal.Info,
|
||
Verbose,
|
||
IndentLevel + 2
|
||
);
|
||
|
||
}
|
||
}
|
||
|
||
//
|
||
// Last Line. At this point, we can dump the ACPI Flags
|
||
//
|
||
dprintf("%s Flags %016I64x ", indent, DeviceExtension->Flags );
|
||
dumpFlags(
|
||
(DeviceExtension->Flags),
|
||
&DeviceExtensionFlags[0],
|
||
sizeof(DeviceExtensionFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel + 4,
|
||
(DUMP_FLAG_SHORT_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE)
|
||
);
|
||
dumpFlags(
|
||
(DeviceExtension->Flags),
|
||
&DeviceExtensionFlags[0],
|
||
sizeof(DeviceExtensionFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel + 4,
|
||
(DUMP_FLAG_LONG_NAME)
|
||
);
|
||
|
||
}
|
||
|
||
VOID
|
||
displayAcpiDeviceExtensionBrief(
|
||
IN PDEVICE_EXTENSION DeviceExtension,
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine displays a one line summary of the device extension
|
||
|
||
Arguments:
|
||
|
||
DeviceExtension - The extension to display
|
||
Address - Where the extension is located
|
||
Verbose - How much information to display
|
||
IndentLevel - How much whitespace to use
|
||
|
||
Return Value:
|
||
|
||
VOID
|
||
|
||
--*/
|
||
{
|
||
BOOL b;
|
||
PDEVICE_EXTENSION deviceExtension;
|
||
ULONG address;
|
||
ULONG i;
|
||
ULONG returnLength;
|
||
ULONG startAddress;
|
||
|
||
//
|
||
// Should we print this extension?
|
||
//
|
||
if ( (Verbose & VERBOSE_PRESENT) &&
|
||
(DeviceExtension->Flags & DEV_TYPE_NOT_FOUND) ) {
|
||
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Make the IndentLevel 'relative' - Device By 4
|
||
//
|
||
IndentLevel /= 4;
|
||
|
||
//
|
||
// Indent the text
|
||
//
|
||
for (i = 0; i < IndentLevel; i++) {
|
||
|
||
dprintf("| ");
|
||
|
||
}
|
||
|
||
//
|
||
// Print the address of the object
|
||
//
|
||
dprintf("%08lx", Address );
|
||
|
||
//
|
||
// Try to get the name & instance
|
||
//
|
||
if (DeviceExtension->Flags & DEV_PROP_HID) {
|
||
|
||
if (DeviceExtension->DeviceID) {
|
||
|
||
memset( Buffer, '0', 2048 );
|
||
b = ReadMemory(
|
||
(ULONG_PTR) DeviceExtension->DeviceID,
|
||
Buffer,
|
||
256,
|
||
&returnLength
|
||
);
|
||
if (b && Buffer[0] != '\0') {
|
||
|
||
dprintf(" %s", Buffer );
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf(" <Unknown HID>");
|
||
|
||
}
|
||
|
||
if (DeviceExtension->Flags & DEV_PROP_UID) {
|
||
|
||
if (DeviceExtension->InstanceID) {
|
||
|
||
memset( Buffer, '0', 2048 );
|
||
b = ReadMemory(
|
||
(ULONG_PTR) DeviceExtension->InstanceID,
|
||
Buffer,
|
||
256,
|
||
&returnLength
|
||
);
|
||
if (b && Buffer[0] != '\0') {
|
||
|
||
dprintf("(%s)", Buffer );
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf(" <Unknown UID>");
|
||
|
||
}
|
||
|
||
}
|
||
|
||
} else if (DeviceExtension->Flags & DEV_PROP_ADDRESS) {
|
||
|
||
dprintf(" %lx", DeviceExtension->Address );
|
||
|
||
} else {
|
||
|
||
dprintf(" <NULL>");
|
||
|
||
}
|
||
|
||
if (Verbose & VERBOSE_THERMAL) {
|
||
|
||
DEVICE_POWER_STATE d;
|
||
SYSTEM_POWER_STATE s;
|
||
|
||
if (DeviceExtension->PowerInfo.PowerState == 0) {
|
||
|
||
dprintf(" Dx" );
|
||
|
||
} else {
|
||
|
||
dprintf(" D%d", (DeviceExtension->PowerInfo.PowerState - 1) );
|
||
|
||
}
|
||
|
||
for (s = PowerSystemWorking; s < PowerSystemMaximum; s++) {
|
||
|
||
d = DeviceExtension->PowerInfo.DevicePowerMatrix[s];
|
||
if (d == PowerDeviceUnspecified) {
|
||
|
||
continue;
|
||
|
||
}
|
||
|
||
dprintf(
|
||
" S%c->D%c",
|
||
ReallyShortSystemPowerStateTable[s],
|
||
ReallyShortDevicePowerStateTable[d]
|
||
);
|
||
|
||
}
|
||
|
||
if (DeviceExtension->Flags & DEV_CAP_WAKE) {
|
||
|
||
s = DeviceExtension->PowerInfo.SystemWakeLevel;
|
||
if (s == PowerSystemUnspecified) {
|
||
|
||
dprintf(" Sw->Sx" );
|
||
|
||
} else {
|
||
|
||
dprintf(" Sw->S%c", ReallyShortSystemPowerStateTable[s] );
|
||
|
||
}
|
||
|
||
d = DeviceExtension->PowerInfo.DeviceWakeLevel;
|
||
if (d == PowerDeviceUnspecified) {
|
||
|
||
dprintf(" Dw->Dx" );
|
||
|
||
} else {
|
||
|
||
dprintf(" Dw->D%c", ReallyShortDevicePowerStateTable[d] );
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// If we are displaying thermal information, cut short early
|
||
//
|
||
dprintf("\n");
|
||
return;
|
||
|
||
}
|
||
|
||
dprintf(" NS %08lx", DeviceExtension->AcpiObject );
|
||
if (DeviceExtension->PowerInfo.PowerState == 0) {
|
||
|
||
dprintf(" Dx" );
|
||
|
||
} else {
|
||
|
||
dprintf(" D%d", (DeviceExtension->PowerInfo.PowerState - 1) );
|
||
|
||
}
|
||
|
||
//
|
||
// Print the device state
|
||
//
|
||
if (DeviceExtension->DeviceState == Stopped) {
|
||
|
||
dprintf(" stop");
|
||
|
||
} else if (DeviceExtension->DeviceState == Inactive) {
|
||
|
||
dprintf(" inac");
|
||
|
||
} else if (DeviceExtension->DeviceState == Started) {
|
||
|
||
dprintf(" star");
|
||
|
||
} else if (DeviceExtension->DeviceState == Removed) {
|
||
|
||
dprintf(" remv");
|
||
|
||
} else if (DeviceExtension->DeviceState == SurpriseRemoved) {
|
||
|
||
dprintf(" surp");
|
||
|
||
} else {
|
||
|
||
dprintf(" inva");
|
||
|
||
}
|
||
dprintf(" %d-%d-%d",
|
||
DeviceExtension->OutstandingIrpCount,
|
||
DeviceExtension->ReferenceCount,
|
||
DeviceExtension->HibernatePathCount
|
||
);
|
||
|
||
//
|
||
// Display the flags
|
||
//
|
||
dumpFlags(
|
||
(DeviceExtension->Flags),
|
||
&DeviceExtensionFlags[0],
|
||
sizeof(DeviceExtensionFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel + 4,
|
||
(DUMP_FLAG_SHORT_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE)
|
||
);
|
||
|
||
// displayAcpiDeviceExtensionFlags( DeviceExtension );
|
||
}
|
||
|
||
VOID
|
||
displayAcpiDeviceExtensionFlags(
|
||
IN PDEVICE_EXTENSION DeviceExtension
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine displays the Flag for a device extension
|
||
|
||
This routine prints a new line at the end of the only line of text that
|
||
it consumes
|
||
|
||
Arguments:
|
||
|
||
DeviceExtension - The extension whose flags to dump
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// Dump the flags
|
||
//
|
||
if (DeviceExtension->Flags & DEV_TYPE_NEVER_PRESENT) {
|
||
|
||
dprintf(" Nev");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_TYPE_NOT_PRESENT) {
|
||
|
||
dprintf(" N/P");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_TYPE_REMOVED) {
|
||
|
||
dprintf(" Rmv");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_TYPE_NOT_FOUND) {
|
||
|
||
dprintf(" N/F");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_TYPE_FDO) {
|
||
|
||
dprintf(" Fdo");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_TYPE_PDO) {
|
||
|
||
dprintf(" Pdo");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_TYPE_FILTER) {
|
||
|
||
dprintf(" Fil");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_WAKE) {
|
||
|
||
dprintf(" Wak");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_RAW) {
|
||
|
||
dprintf(" Raw");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_BUTTON) {
|
||
|
||
dprintf(" But");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_ALWAYS_PS0) {
|
||
|
||
dprintf(" PS0");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_NO_FILTER) {
|
||
|
||
dprintf(" !Fil");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_NO_STOP) {
|
||
|
||
dprintf(" !Stop");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_NO_OVERRIDE) {
|
||
|
||
dprintf(" !Off");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_ISA) {
|
||
|
||
dprintf(" Isa");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_EIO) {
|
||
|
||
dprintf(" Eio");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_PCI) {
|
||
|
||
dprintf(" Pci");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_SERIAL) {
|
||
|
||
dprintf(" Ser");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_THERMAL_ZONE) {
|
||
|
||
dprintf(" Thrm");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_LINK_NODE) {
|
||
|
||
dprintf(" Lnk");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_NO_SHOW_IN_UI) {
|
||
|
||
dprintf(" !UI");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_NEVER_SHOW_IN_UI) {
|
||
|
||
dprintf(" !!UI");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_START_IN_D3) {
|
||
|
||
dprintf(" D3");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_PCI_DEVICE) {
|
||
|
||
dprintf(" PciD");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_PIC_DEVICE) {
|
||
|
||
dprintf(" PIC");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_CAP_UNATTACHED_DOCK) {
|
||
|
||
dprintf(" Dock-");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_ADDRESS) {
|
||
|
||
dprintf(" Adr");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_FIXED_HID) {
|
||
|
||
dprintf(" FHid");
|
||
|
||
} else if (DeviceExtension->Flags & DEV_PROP_HID) {
|
||
|
||
dprintf(" Hid");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_FIXED_UID) {
|
||
|
||
dprintf(" FUid");
|
||
|
||
} else if (DeviceExtension->Flags & DEV_PROP_UID) {
|
||
|
||
dprintf(" Uid");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_FAILED_INIT) {
|
||
|
||
dprintf(" !INIT");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_SRS_PRESENT) {
|
||
|
||
dprintf(" SRS");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_NO_OBJECT) {
|
||
|
||
dprintf(" Fake");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_EXCLUSIVE) {
|
||
|
||
dprintf(" Excl");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_RAN_INI) {
|
||
|
||
dprintf(" Ini");
|
||
|
||
}
|
||
if (!(DeviceExtension->Flags & DEV_PROP_DEVICE_ENABLED)) {
|
||
|
||
dprintf(" !Ena");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_DEVICE_FAILED) {
|
||
|
||
dprintf(" Fail");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_ACPI_POWER) {
|
||
|
||
dprintf(" Pwr");
|
||
|
||
}
|
||
|
||
if (DeviceExtension->Flags & DEV_PROP_DOCK) {
|
||
|
||
dprintf(" Prof");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_BUILT_POWER_TABLE) {
|
||
|
||
dprintf(" S->D");
|
||
|
||
}
|
||
if (DeviceExtension->Flags & DEV_PROP_HAS_PME) {
|
||
|
||
dprintf(" PME");
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
VOID
|
||
displayAcpiDeviceExtensionName(
|
||
IN ULONG_PTR DeviceExtensionAddress
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
This routine is tasked to with displaying the name of the device in the
|
||
best possible manner
|
||
|
||
Arguments:
|
||
|
||
DeviceExtensionAddress - The Address of the DeviceExtension
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
{
|
||
BOOL status;
|
||
DEVICE_EXTENSION deviceExtension;
|
||
NSOBJ acpiObject;
|
||
UCHAR nameBuffer[80];
|
||
ULONG_PTR nameAddress;
|
||
ULONG returnLength;
|
||
|
||
//
|
||
// Read the entier extension
|
||
//
|
||
status = ReadMemory(
|
||
DeviceExtensionAddress,
|
||
&deviceExtension,
|
||
sizeof(DEVICE_EXTENSION),
|
||
&returnLength
|
||
);
|
||
if (status && returnLength == sizeof(DEVICE_EXTENSION) ) {
|
||
|
||
if (deviceExtension.Flags & DEV_PROP_HID) {
|
||
|
||
if (deviceExtension.DeviceID != NULL) {
|
||
|
||
//
|
||
// Now, try to read the name into the buffer
|
||
//
|
||
status = ReadMemory(
|
||
(ULONG_PTR) deviceExtension.DeviceID,
|
||
nameBuffer,
|
||
79,
|
||
&returnLength
|
||
);
|
||
if (status && returnLength) {
|
||
|
||
nameBuffer[returnLength] = '\0';
|
||
dprintf("%s",nameBuffer);
|
||
|
||
|
||
} else {
|
||
|
||
dprintf("(%lx)", deviceExtension.DeviceID);
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf("NULL");
|
||
|
||
}
|
||
|
||
}
|
||
if (deviceExtension.Flags & DEV_PROP_UID) {
|
||
|
||
if (deviceExtension.InstanceID != NULL) {
|
||
|
||
//
|
||
// Now, try to read the name into the buffer
|
||
//
|
||
status = ReadMemory(
|
||
(ULONG_PTR) deviceExtension.InstanceID,
|
||
nameBuffer,
|
||
79,
|
||
&returnLength
|
||
);
|
||
if (status && returnLength) {
|
||
|
||
nameBuffer[returnLength] = '\0';
|
||
dprintf(" [%s]",nameBuffer);
|
||
|
||
|
||
} else {
|
||
|
||
dprintf(" [ (%lx) ]", deviceExtension.InstanceID);
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dprintf(" [NULL]");
|
||
|
||
}
|
||
|
||
}
|
||
if (deviceExtension.Flags & DEV_PROP_ADDRESS) {
|
||
|
||
dprintf("%lx", deviceExtension.Address );
|
||
|
||
}
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// In this case, obtain the address of the ACPIObject for this device
|
||
//
|
||
nameAddress = (ULONG_PTR) &(deviceExtension.AcpiObject) -
|
||
(ULONG_PTR) &(deviceExtension) + DeviceExtensionAddress;
|
||
status = ReadMemory(
|
||
nameAddress,
|
||
&(deviceExtension.AcpiObject),
|
||
sizeof(PNSOBJ),
|
||
&returnLength
|
||
);
|
||
if (status && returnLength == sizeof(PNSOBJ)) {
|
||
|
||
//
|
||
// Read the object
|
||
//
|
||
status = ReadMemory(
|
||
(ULONG_PTR) deviceExtension.AcpiObject,
|
||
&acpiObject,
|
||
sizeof(NSOBJ),
|
||
&returnLength
|
||
);
|
||
if (status && returnLength == sizeof(NSOBJ)) {
|
||
|
||
memcpy( nameBuffer, &(acpiObject.dwNameSeg), 4 );
|
||
nameBuffer[4] = '\0';
|
||
|
||
dprintf("Acpi(%s)", nameBuffer);
|
||
return;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
dprintf("Unknown");
|
||
return;
|
||
}
|
||
VOID
|
||
displayThermalInfo(
|
||
IN PTHRM_INFO ThrmInfo,
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
This routine displays a thermal information structure
|
||
|
||
--*/
|
||
{
|
||
BOOLEAN noIndent;
|
||
UCHAR indent[80];
|
||
UINT i;
|
||
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
|
||
dprintf(
|
||
"%s Stamp %8lx Affinity %08lx Mode %s\n",
|
||
indent,
|
||
ThrmInfo->Info.ThermalStamp,
|
||
ThrmInfo->Info.Processors,
|
||
(ThrmInfo->Mode == 0 ? "Active" : "Passive")
|
||
);
|
||
dprintf(
|
||
"%s SampleRate %8ss Constant1 %08lx Constant2 %08lx\n",
|
||
indent,
|
||
TimeToSeconds( ThrmInfo->Info.SamplingPeriod ),
|
||
ThrmInfo->Info.ThermalConstant1,
|
||
ThrmInfo->Info.ThermalConstant2
|
||
);
|
||
dprintf(
|
||
"%s _TMP %8lx TempData %8lx CoolingLvl %2d\n",
|
||
indent,
|
||
ThrmInfo->TempMethod,
|
||
Address + FIELD_OFFSET( THRM_INFO, Temp ),
|
||
ThrmInfo->CoolingLevel
|
||
);
|
||
for (i = 0; i < 10; i++) {
|
||
|
||
noIndent = FALSE;
|
||
|
||
if (i == 0) {
|
||
|
||
dprintf(
|
||
"%s Current %8sK ",
|
||
indent,
|
||
TempToKelvins( ThrmInfo->Info.CurrentTemperature )
|
||
);
|
||
|
||
} else if (i == 1) {
|
||
|
||
dprintf(
|
||
"%s Critical %8sK ",
|
||
indent,
|
||
TempToKelvins( ThrmInfo->Info.CriticalTripPoint )
|
||
);
|
||
|
||
} else if (i == 2) {
|
||
|
||
dprintf(
|
||
"%s Passive %8sK ",
|
||
indent,
|
||
TempToKelvins( ThrmInfo->Info.PassiveTripPoint )
|
||
);
|
||
|
||
} else {
|
||
|
||
noIndent = TRUE;
|
||
|
||
}
|
||
|
||
if (i >= ThrmInfo->Info.ActiveTripPointCount) {
|
||
|
||
if (ThrmInfo->Info.ActiveTripPoint[i] != 0 ||
|
||
ThrmInfo->ActiveList[i] != NULL) {
|
||
|
||
if (noIndent == TRUE) {
|
||
|
||
dprintf( "%s ", indent );
|
||
|
||
}
|
||
dprintf(
|
||
"*Active #%d %8sK Method %lx\n",
|
||
i,
|
||
TempToKelvins( ThrmInfo->Info.ActiveTripPoint[i] ),
|
||
ThrmInfo->ActiveList[i]
|
||
);
|
||
|
||
} else if (i < 3) {
|
||
|
||
dprintf("\n");
|
||
|
||
} else {
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
|
||
} else {
|
||
|
||
if (noIndent == TRUE) {
|
||
|
||
dprintf( "%s ", indent );
|
||
|
||
}
|
||
dprintf(
|
||
"Active #%d %8sK Method %lx\n",
|
||
i,
|
||
TempToKelvins( ThrmInfo->Info.ActiveTripPoint[i] ),
|
||
ThrmInfo->ActiveList[i]
|
||
);
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiDeviceNode(
|
||
IN PACPI_DEVICE_POWER_NODE DeviceNode,
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine dumps the contents of a single device node
|
||
|
||
Arguments:
|
||
|
||
DeviceNode - What to dump
|
||
Address - Where that node is located
|
||
IndentLevel - How much whitespace to use
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
UCHAR indent[80];
|
||
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
|
||
dprintf(
|
||
"%sDevice Node - %08lx -> Extension - %08lx",
|
||
indent,
|
||
Address,
|
||
DeviceNode->DeviceExtension
|
||
);
|
||
if (DeviceNode->DeviceExtension != NULL) {
|
||
|
||
dprintf(" - ");
|
||
displayAcpiDeviceExtensionName(
|
||
(ULONG_PTR) DeviceNode->DeviceExtension
|
||
);
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
dprintf(
|
||
"%s System %2s Device %2s Wake %s\n",
|
||
indent,
|
||
ShortSystemPowerStateTable[DeviceNode->SystemState],
|
||
ShortDevicePowerStateTable[DeviceNode->AssociatedDeviceState],
|
||
(DeviceNode->WakePowerResource ? "TRUE" : "FALSE")
|
||
);
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiDeviceNodes(
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine walks a Device Power List (given the address of the
|
||
start of that list)
|
||
|
||
Arguments:
|
||
|
||
Address - Where in memory the first node is located
|
||
Verbose - How much information to display
|
||
IndentLevel - How many characters to indent
|
||
|
||
Return Value:
|
||
|
||
VOID
|
||
|
||
--*/
|
||
{
|
||
BOOL status;
|
||
ACPI_DEVICE_POWER_NODE deviceNode;
|
||
ACPI_POWER_DEVICE_NODE powerNode;
|
||
ULONG returnLength;
|
||
ULONG_PTR deviceAddress = Address;
|
||
|
||
while (deviceAddress != 0) {
|
||
|
||
//
|
||
// Read the current node
|
||
//
|
||
status = ReadMemory(
|
||
deviceAddress,
|
||
&deviceNode,
|
||
sizeof(ACPI_DEVICE_POWER_NODE),
|
||
&returnLength
|
||
);
|
||
if (status != TRUE || returnLength != sizeof(ACPI_DEVICE_POWER_NODE)) {
|
||
|
||
dprintf(
|
||
"dumpAcpiDeviceNodes: could not read device node memory "
|
||
"%08lx\n",
|
||
deviceAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the node
|
||
//
|
||
dumpAcpiDeviceNode(
|
||
&deviceNode,
|
||
deviceAddress,
|
||
Verbose,
|
||
IndentLevel
|
||
);
|
||
|
||
status = ReadMemory(
|
||
(ULONG_PTR) deviceNode.PowerNode,
|
||
&powerNode,
|
||
sizeof(ACPI_POWER_DEVICE_NODE),
|
||
&returnLength);
|
||
if (status != TRUE ||
|
||
returnLength != sizeof(ACPI_POWER_DEVICE_NODE)) {
|
||
|
||
dprintf(
|
||
"dumpAcpiDeviceNode: could not read power node memory "
|
||
"%08lx\n",
|
||
deviceNode.PowerNode
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the power resource
|
||
//
|
||
dumpAcpiPowerNode(
|
||
&powerNode,
|
||
(ULONG_PTR) deviceNode.PowerNode,
|
||
Verbose,
|
||
IndentLevel
|
||
);
|
||
|
||
//
|
||
// setup next entry in the list
|
||
//
|
||
deviceAddress = (ULONG_PTR) deviceNode.Next;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiExtension(
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This dumps the ACPI device extension in a format that is readable by the
|
||
user debugging the system
|
||
|
||
Arguments:
|
||
|
||
Address - Where the DeviceObject is located
|
||
Verbose - How much information to display
|
||
IndentLevel - How much whitespace to have
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL b;
|
||
DEVICE_EXTENSION deviceExtension;
|
||
PLIST_ENTRY listEntry;
|
||
UCHAR indent[80];
|
||
ULONG_PTR curAddress;
|
||
ULONG returnLength;
|
||
ULONG_PTR stopAddress;
|
||
ULONG subVerbose;
|
||
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
|
||
//
|
||
// Read the sibling device extension
|
||
//
|
||
b = ReadMemory(
|
||
Address,
|
||
&deviceExtension,
|
||
sizeof(DEVICE_EXTENSION),
|
||
&returnLength
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf(
|
||
"%s***ReadMemory Failed from %p\n",
|
||
Address
|
||
);
|
||
return;
|
||
|
||
} else if (returnLength != sizeof(DEVICE_EXTENSION) ) {
|
||
|
||
dprintf(
|
||
"%s***Error: Only read %08lx of %08lx bytes for %p\n",
|
||
returnLength,
|
||
sizeof(DEVICE_EXTENSION),
|
||
Address
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
if ( (Verbose & VERBOSE_ALL) ) {
|
||
|
||
displayAcpiDeviceExtension(
|
||
&deviceExtension,
|
||
Address,
|
||
Verbose,
|
||
IndentLevel
|
||
);
|
||
|
||
} else {
|
||
|
||
displayAcpiDeviceExtensionBrief(
|
||
&deviceExtension,
|
||
Address,
|
||
Verbose,
|
||
IndentLevel
|
||
);
|
||
|
||
}
|
||
|
||
if (! (Verbose & VERBOSE_LOOP) ) {
|
||
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Determine the current and stop addresses
|
||
//
|
||
stopAddress = (ULONG_PTR) &(deviceExtension.ChildDeviceList) -
|
||
(ULONG_PTR) &deviceExtension + Address;
|
||
listEntry = deviceExtension.ChildDeviceList.Flink;
|
||
|
||
//
|
||
// Loop while there are children
|
||
//
|
||
while (listEntry != (PLIST_ENTRY) stopAddress) {
|
||
|
||
//
|
||
// Check for Ctrl-C
|
||
//
|
||
if (CheckControlC()) {
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
//
|
||
// The currentAddress is at the ListEntry --- lets convert
|
||
//
|
||
curAddress = (ULONG_PTR) CONTAINING_RECORD(
|
||
listEntry,
|
||
DEVICE_EXTENSION,
|
||
SiblingDeviceList
|
||
);
|
||
|
||
//
|
||
// Read the entry
|
||
//
|
||
b = ReadMemory(
|
||
curAddress,
|
||
&deviceExtension,
|
||
sizeof(DEVICE_EXTENSION),
|
||
&returnLength
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf(
|
||
"%s ***ReadMemory Failed from %p\n",
|
||
curAddress
|
||
);
|
||
return;
|
||
|
||
} else if (returnLength != sizeof(DEVICE_EXTENSION) ) {
|
||
|
||
dprintf(
|
||
"%s ***Error: Only read %08lx of %08lx bytes "
|
||
"for %p\n",
|
||
returnLength,
|
||
sizeof(DEVICE_EXTENSION),
|
||
curAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Recurse
|
||
//
|
||
dumpAcpiExtension(
|
||
curAddress,
|
||
Verbose,
|
||
IndentLevel + 4
|
||
);
|
||
|
||
//
|
||
// Point to the next extension
|
||
//
|
||
listEntry = deviceExtension.SiblingDeviceList.Flink;
|
||
|
||
}
|
||
}
|
||
|
||
VOID
|
||
dumpPM1ControlRegister(
|
||
IN ULONG Value,
|
||
IN ULONG IndentLevel
|
||
)
|
||
{
|
||
|
||
|
||
//
|
||
// Dump the PM1 Control Flags
|
||
//
|
||
dumpFlags(
|
||
(Value & 0xFF),
|
||
&PM1StatusFlags[0],
|
||
sizeof(PM1ControlFlags) / sizeof(FLAG_RECORD),
|
||
IndentLevel,
|
||
(DUMP_FLAG_LONG_NAME | DUMP_FLAG_SHOW_BIT | DUMP_FLAG_TABLE)
|
||
);
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpPM1StatusRegister(
|
||
IN ULONG Value,
|
||
IN ULONG IndentLevel
|
||
)
|
||
{
|
||
|
||
//
|
||
// Dump the PM1 Status Flags
|
||
//
|
||
dumpFlags(
|
||
(Value & 0xFFFF),
|
||
PM1StatusFlags,
|
||
(sizeof(PM1StatusFlags) / sizeof(FLAG_RECORD)),
|
||
IndentLevel,
|
||
(DUMP_FLAG_LONG_NAME | DUMP_FLAG_SHOW_BIT | DUMP_FLAG_TABLE)
|
||
);
|
||
|
||
//
|
||
// Switch to the PM1 Enable Flags
|
||
//
|
||
Value >>= 16;
|
||
|
||
|
||
//
|
||
// Dump the PM1 Enable Flags
|
||
//
|
||
dumpFlags(
|
||
(Value & 0xFFFF),
|
||
PM1EnableFlags,
|
||
(sizeof(PM1EnableFlags) / sizeof(FLAG_RECORD)),
|
||
IndentLevel,
|
||
(DUMP_FLAG_LONG_NAME | DUMP_FLAG_SHOW_BIT | DUMP_FLAG_TABLE)
|
||
);
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiPowerList(
|
||
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( "dumpAcpiPowerList: could not read %s\n", ListName );
|
||
|
||
} else {
|
||
|
||
dprintf(" %s at %p\n", ListName, address );
|
||
status = ReadMemory(
|
||
address,
|
||
&listEntry,
|
||
sizeof(LIST_ENTRY),
|
||
&returnLength
|
||
);
|
||
if (status == FALSE || returnLength != sizeof(LIST_ENTRY)) {
|
||
|
||
dprintf(
|
||
"dumpAcpiPowerList: could not read LIST_ENTRY at %08lx\n",
|
||
address
|
||
);
|
||
|
||
} else {
|
||
|
||
dumpDeviceListEntry(
|
||
&listEntry,
|
||
address
|
||
);
|
||
dprintf("\n");
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiPowerLists(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine fetches the Power Device list from the target and
|
||
displays it
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL status;
|
||
LIST_ENTRY listEntry;
|
||
ULONG_PTR address;
|
||
ULONG returnLength;
|
||
ULONG value;
|
||
|
||
status = GetUlongPtr( "ACPI!AcpiPowerLock", &address );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiPowerLists: Could not read ACPI!AcpiPowerLock\n");
|
||
return;
|
||
|
||
}
|
||
|
||
dprintf("ACPI Power Information\n");
|
||
if (address) {
|
||
|
||
dprintf(" + ACPI!AcpiPowerLock 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!AcpiPowerLock is not owned\n");
|
||
|
||
}
|
||
|
||
status = GetUlongPtr( "ACPI!AcpiPowerQueueLock", &address );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiPowerLists: Could not read ACPI!AcpiPowerQueueLock\n");
|
||
return;
|
||
|
||
}
|
||
if (address) {
|
||
|
||
dprintf(" + ACPI!AcpiPowerQueueLock 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!AcpiPowerQueueLock is not owned\n" );
|
||
|
||
}
|
||
|
||
status = GetUlong( "ACPI!AcpiPowerWorkDone", &value );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiPowerLists: Could not read ACPI!AcpiPowerWorkDone\n");
|
||
return;
|
||
|
||
}
|
||
dprintf(" + AcpiPowerWorkDone = %s\n", (value ? "TRUE" : "FALSE" ) );
|
||
|
||
|
||
status = GetUlong( "ACPI!AcpiPowerDpcRunning", &value );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiPowerLists: Could not read ACPI!AcpiPowerDpcRunning\n");
|
||
return;
|
||
|
||
}
|
||
dprintf(" + AcpiPowerDpcRunning = %s\n", (value ? "TRUE" : "FALSE" ) );
|
||
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerQueueList" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerDelayedQueueList" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerPhase0List" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerPhase1List" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerPhase2List" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerPhase3List" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerPhase4List" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerPhase5List" );
|
||
dumpAcpiPowerList( "ACPI!AcpiPowerWaitWakeList" );
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiPowerNode(
|
||
IN PACPI_POWER_DEVICE_NODE PowerNode,
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called to display a power node
|
||
|
||
Arguments:
|
||
|
||
PowerNode - The power node to dump
|
||
Address - Where the power node is located
|
||
Verbose - How much information to display
|
||
IndentLevel - How many characters to indent
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL status;
|
||
NSOBJ ns;
|
||
UCHAR buffer[5];
|
||
UCHAR indent[80];
|
||
ULONG returnLength;
|
||
|
||
buffer[4] = '\0';
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
|
||
//
|
||
// Read the associated power resource object
|
||
//
|
||
status = ReadMemory(
|
||
(ULONG_PTR) PowerNode->PowerObject,
|
||
&ns,
|
||
sizeof(NSOBJ),
|
||
&returnLength
|
||
);
|
||
if (status != FALSE && returnLength == sizeof(NSOBJ)) {
|
||
|
||
memcpy( buffer, &(ns.dwNameSeg), 4 );
|
||
|
||
} else {
|
||
|
||
buffer[0] = '\0';
|
||
|
||
}
|
||
|
||
dprintf("%sPower Node - %08lx %s\n", indent, Address, buffer );
|
||
dprintf(
|
||
"%s Resource %8lx Order %8lx WorkDone %8s\n",
|
||
indent,
|
||
PowerNode->PowerObject,
|
||
PowerNode->ResourceOrder,
|
||
WorkDone[ PowerNode->WorkDone ]
|
||
);
|
||
dprintf(
|
||
"%s On Method %8lx Off Method %8lx UseCounts %8lx\n",
|
||
indent,
|
||
PowerNode->PowerOnObject,
|
||
PowerNode->PowerOffObject,
|
||
PowerNode->UseCounts
|
||
);
|
||
dprintf(
|
||
"%s Level %8s Flags %8lx ",
|
||
indent,
|
||
ShortSystemPowerStateTable[PowerNode->SystemLevel],
|
||
PowerNode->Flags
|
||
);
|
||
dumpFlags(
|
||
(PowerNode->Flags),
|
||
&PowerNodeFlags[0],
|
||
sizeof(PowerNodeFlags)/sizeof(FLAG_RECORD),
|
||
0,
|
||
(DUMP_FLAG_SHORT_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE)
|
||
);
|
||
if (Verbose & VERBOSE_4) {
|
||
|
||
dumpFlags(
|
||
(PowerNode->Flags),
|
||
&PowerNodeFlags[0],
|
||
sizeof(PowerNodeFlags)/sizeof(FLAG_RECORD),
|
||
IndentLevel + 4,
|
||
(DUMP_FLAG_LONG_NAME)
|
||
);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpAcpiPowerNodes(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine fetches the Power Device list from the target and
|
||
displays it
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
ACPI_DEVICE_POWER_NODE deviceNode;
|
||
ACPI_POWER_DEVICE_NODE powerNode;
|
||
BOOL status;
|
||
LIST_ENTRY listEntry;
|
||
PLIST_ENTRY list;
|
||
ULONG_PTR addr;
|
||
ULONG_PTR address;
|
||
ULONG_PTR endAddress;
|
||
ULONG returnLength;
|
||
ULONG_PTR startAddress;
|
||
|
||
status = GetUlongPtr( "ACPI!AcpiPowerLock", &address );
|
||
if (status == FALSE) {
|
||
|
||
dprintf("dumpAcpiPowerNodes: Could not read ACPI!AcpiPowerLock\n");
|
||
return;
|
||
|
||
}
|
||
|
||
dprintf("ACPI Power Nodes\n");
|
||
if (address) {
|
||
|
||
dprintf(" + ACPI!AcpiPowerLock 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!AcpiPowerLock is not owned\n");
|
||
|
||
}
|
||
|
||
dprintf("Power Node List\n");
|
||
startAddress = GetExpression( "ACPI!AcpiPowerNodeList" );
|
||
if (!startAddress) {
|
||
|
||
dprintf("dumpAcpiPowerNodes: could not read ACPI!AcpiPowerNodeList\n");
|
||
return;
|
||
|
||
}
|
||
status = ReadMemory(
|
||
startAddress,
|
||
&listEntry,
|
||
sizeof(LIST_ENTRY),
|
||
&returnLength
|
||
);
|
||
if (status == FALSE || returnLength != sizeof(LIST_ENTRY)) {
|
||
|
||
dprintf(
|
||
"dumpAcpiPowerNodes: could not read LIST_ENTRY at %08lx\n",
|
||
startAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Check to see if the list is empty
|
||
//
|
||
if ( (ULONG_PTR) listEntry.Flink == startAddress) {
|
||
|
||
dprintf(" Empty\n");
|
||
return;
|
||
|
||
}
|
||
|
||
address = (ULONG_PTR) CONTAINING_RECORD(
|
||
(listEntry.Flink),
|
||
ACPI_POWER_DEVICE_NODE,
|
||
ListEntry
|
||
);
|
||
while (address != startAddress && address != 0) {
|
||
|
||
//
|
||
// Read the queued item
|
||
//
|
||
status = ReadMemory(
|
||
address,
|
||
&powerNode,
|
||
sizeof(ACPI_POWER_DEVICE_NODE),
|
||
&returnLength
|
||
);
|
||
if (status == FALSE || returnLength != sizeof(ACPI_POWER_DEVICE_NODE)) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read Node at %08lx\n",
|
||
address
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// dump the node
|
||
//
|
||
dumpAcpiPowerNode(
|
||
&powerNode,
|
||
address,
|
||
0,
|
||
0
|
||
);
|
||
|
||
//
|
||
// Lets walk the list of power nodes
|
||
//
|
||
list = powerNode.DevicePowerListHead.Flink;
|
||
endAddress = ( (ULONG_PTR) &(powerNode.DevicePowerListHead) -
|
||
(ULONG_PTR) &(powerNode) ) +
|
||
address;
|
||
|
||
//
|
||
// Loop until back at the start
|
||
//
|
||
while (list != (PLIST_ENTRY) endAddress) {
|
||
|
||
//
|
||
// Crack the record
|
||
//
|
||
addr = (ULONG_PTR) CONTAINING_RECORD(
|
||
list,
|
||
ACPI_DEVICE_POWER_NODE,
|
||
DevicePowerListEntry
|
||
);
|
||
|
||
status = ReadMemory(
|
||
addr,
|
||
&deviceNode,
|
||
sizeof(ACPI_DEVICE_POWER_NODE),
|
||
&returnLength
|
||
);
|
||
if (status == FALSE ||
|
||
returnLength != sizeof(ACPI_DEVICE_POWER_NODE)) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read Node at %08lx\n",
|
||
addr
|
||
);
|
||
continue;
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the record
|
||
//
|
||
dumpAcpiDeviceNode(
|
||
&deviceNode,
|
||
addr,
|
||
0,
|
||
2
|
||
);
|
||
|
||
//
|
||
// Next record
|
||
//
|
||
list = deviceNode.DevicePowerListEntry.Flink;
|
||
|
||
}
|
||
|
||
dprintf("\n");
|
||
|
||
//
|
||
// Next record
|
||
//
|
||
address = (ULONG_PTR) CONTAINING_RECORD(
|
||
powerNode.ListEntry.Flink,
|
||
ACPI_POWER_DEVICE_NODE,
|
||
ListEntry
|
||
);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpDeviceListEntry(
|
||
IN PLIST_ENTRY ListEntry,
|
||
IN ULONG_PTR Address
|
||
)
|
||
/*++
|
||
|
||
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_POWER_REQUEST request;
|
||
BOOL stat;
|
||
PACPI_POWER_REQUEST nextRequest;
|
||
PACPI_POWER_REQUEST requestAddress;
|
||
ULONG i = 0;
|
||
ULONG returnLength;
|
||
|
||
//
|
||
// 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_POWER_REQUEST,
|
||
ListEntry
|
||
);
|
||
|
||
//
|
||
// Read the queued item
|
||
//
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) requestAddress,
|
||
&request,
|
||
sizeof(ACPI_POWER_REQUEST),
|
||
&returnLength
|
||
);
|
||
if (stat == FALSE || returnLength != sizeof(ACPI_POWER_REQUEST)) {
|
||
|
||
dprintf(
|
||
"dumpDeviceListEntry: Cannot read PowerRequest at %08lx\n",
|
||
requestAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
if (request.CallBack != NULL) {
|
||
|
||
GetSymbol(
|
||
request.CallBack,
|
||
Buffer,
|
||
&displacement
|
||
);
|
||
|
||
} else {
|
||
|
||
Buffer[0] = '\0';
|
||
|
||
}
|
||
|
||
//
|
||
// Dump the entry for the device
|
||
//
|
||
dprintf(
|
||
" %08lx\n"
|
||
" DeviceExtension: %08lx",
|
||
requestAddress,
|
||
request.DeviceExtension
|
||
);
|
||
if (request.DeviceExtension != NULL) {
|
||
|
||
dprintf(" - ");
|
||
displayAcpiDeviceExtensionName(
|
||
(ULONG_PTR) request.DeviceExtension
|
||
);
|
||
|
||
}
|
||
dprintf("\n");
|
||
dprintf(
|
||
" Status: %08lx %s->%s\n",
|
||
request.Status,
|
||
WorkDone[request.WorkDone],
|
||
WorkDone[request.NextWorkDone]
|
||
);
|
||
nextRequest = CONTAINING_RECORD(
|
||
request.SerialListEntry.Flink,
|
||
ACPI_POWER_REQUEST,
|
||
SerialListEntry
|
||
);
|
||
if (nextRequest != requestAddress) {
|
||
|
||
dprintf(
|
||
" SerialListEntry: F - %08lx B - %08lx -> %08lx\n",
|
||
request.SerialListEntry.Flink,
|
||
request.SerialListEntry.Blink,
|
||
nextRequest
|
||
);
|
||
|
||
}
|
||
dprintf(
|
||
" CallBack: %08lx (%s)\n"
|
||
" Context: %08lx\n"
|
||
" RequestType: %02lx\n"
|
||
" ResultData: %08lx\n",
|
||
request.CallBack,
|
||
Buffer,
|
||
request.Context,
|
||
request.RequestType,
|
||
requestAddress + (FIELD_OFFSET(ACPI_POWER_REQUEST, ResultData ) )
|
||
);
|
||
|
||
//
|
||
// Dump some of the request specific information
|
||
//
|
||
if (request.RequestType == AcpiPowerRequestDevice) {
|
||
|
||
dprintf(
|
||
" RequestType: AcpiPowerRequestDevice\n"
|
||
" DevicePowerState: %s\n"
|
||
" Flags: %x ",
|
||
DevicePowerStateTable[request.u.DevicePowerRequest.DevicePowerState],
|
||
request.u.DevicePowerRequest.Flags
|
||
);
|
||
dumpFlags(
|
||
(request.u.DevicePowerRequest.Flags),
|
||
&PowerRequestFlags[0],
|
||
sizeof(PowerRequestFlags)/sizeof(FLAG_RECORD),
|
||
0,
|
||
(DUMP_FLAG_LONG_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE)
|
||
);
|
||
|
||
} else if (request.RequestType == AcpiPowerRequestSystem) {
|
||
|
||
dprintf(
|
||
" RequestType: AcpiPowerRequestSystem\n"
|
||
" SystemPowerState: %s\n"
|
||
" SystemPowerAction: %s\n",
|
||
SystemPowerStateTable[request.u.SystemPowerRequest.SystemPowerState],
|
||
SystemPowerActionTable[request.u.SystemPowerRequest.SystemPowerAction]
|
||
);
|
||
|
||
} else if (request.RequestType == AcpiPowerRequestWaitWake) {
|
||
|
||
dprintf(
|
||
" RequestType: AcpiPowerRequestWaitWake\n"
|
||
" SystemPowerState: %s\n"
|
||
" Flags: %x ",
|
||
SystemPowerStateTable[request.u.WaitWakeRequest.SystemPowerState],
|
||
request.u.WaitWakeRequest.Flags
|
||
);
|
||
dumpFlags(
|
||
(request.u.WaitWakeRequest.Flags),
|
||
&PowerRequestFlags[0],
|
||
sizeof(PowerRequestFlags)/sizeof(FLAG_RECORD),
|
||
0,
|
||
(DUMP_FLAG_LONG_NAME | DUMP_FLAG_NO_INDENT |
|
||
DUMP_FLAG_SINGLE_LINE)
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Point to the next entry
|
||
//
|
||
ListEntry = request.ListEntry.Flink;
|
||
|
||
} // while
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpIrpListEntry(
|
||
IN PLIST_ENTRY ListEntry,
|
||
IN ULONG_PTR Address
|
||
)
|
||
/*++
|
||
|
||
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
|
||
|
||
--*/
|
||
{
|
||
BOOL stat;
|
||
DEVICE_OBJECT deviceObject;
|
||
DEVICE_EXTENSION deviceExtension;
|
||
IO_STACK_LOCATION irpStack;
|
||
PIRP irpAddress;
|
||
PIO_STACK_LOCATION tempStack;
|
||
IRP irp;
|
||
ULONG returnLength;
|
||
|
||
//
|
||
// Look at the first element in the list
|
||
//
|
||
ListEntry = ListEntry->Flink;
|
||
|
||
//
|
||
// Loop for all items in the list
|
||
//
|
||
while (ListEntry != (PLIST_ENTRY) Address) {
|
||
|
||
irpAddress = CONTAINING_RECORD(
|
||
ListEntry,
|
||
IRP,
|
||
Tail.Overlay.ListEntry
|
||
);
|
||
|
||
//
|
||
// Read the queued item
|
||
//
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) irpAddress,
|
||
&irp,
|
||
sizeof(IRP),
|
||
&returnLength
|
||
);
|
||
if (stat == FALSE || returnLength != sizeof(IRP)) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read Irp at %08lx\n",
|
||
irpAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
//
|
||
// Get the current stack location
|
||
//
|
||
tempStack = IoGetCurrentIrpStackLocation( &irp );
|
||
if (tempStack == NULL) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read IrpStack for Irp at %08lx\n",
|
||
irpAddress
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) tempStack,
|
||
&irpStack,
|
||
sizeof(IO_STACK_LOCATION),
|
||
&returnLength
|
||
);
|
||
if (stat == FALSE || returnLength != sizeof(IO_STACK_LOCATION)) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read IoStackLocation at %08lx\n",
|
||
tempStack
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) irpStack.DeviceObject,
|
||
&deviceObject,
|
||
sizeof(DEVICE_OBJECT),
|
||
&returnLength
|
||
);
|
||
if (stat == FALSE || returnLength != sizeof(DEVICE_OBJECT)) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read DeviceObject at %08lx\n",
|
||
irpStack.DeviceObject
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) deviceObject.DeviceExtension,
|
||
&deviceExtension,
|
||
sizeof(DEVICE_EXTENSION),
|
||
&returnLength
|
||
);
|
||
if (stat == FALSE || returnLength != sizeof(DEVICE_EXTENSION)) {
|
||
|
||
dprintf(
|
||
"dumpIrpListEntry: Cannot read DeviceExtension at %08lx\n",
|
||
deviceObject.DeviceExtension
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
memset( Buffer, '0', 2048 );
|
||
stat = ReadMemory(
|
||
(ULONG_PTR) deviceExtension.DeviceID,
|
||
Buffer,
|
||
256,
|
||
&returnLength
|
||
);
|
||
if (stat && Buffer[0] != '\0' && returnLength != 0) {
|
||
|
||
dprintf(
|
||
" Irp: %08x Device: %08lx (%s)\n",
|
||
irpAddress,
|
||
irpStack.DeviceObject,
|
||
Buffer
|
||
);
|
||
|
||
} else {
|
||
|
||
dprintf(
|
||
" Irp: %08x Device: %08lx\n",
|
||
irpAddress,
|
||
irpStack.DeviceObject
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Next item on the queue
|
||
//
|
||
ListEntry = irp.Tail.Overlay.ListEntry.Flink;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpNSObject(
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function dumps a Name space object
|
||
|
||
Arguments:
|
||
|
||
Address - Where to find the object
|
||
Verbose - Should the object be dumped as well?
|
||
IndentLevel - How much to indent
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL b;
|
||
NSOBJ ns;
|
||
UCHAR buffer[5];
|
||
UCHAR indent[80];
|
||
|
||
//
|
||
// Init the buffers
|
||
//
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
buffer[4] = '\0';
|
||
|
||
//
|
||
// First step is to read the root NS
|
||
//
|
||
b = ReadMemory(
|
||
Address,
|
||
&ns,
|
||
sizeof(NSOBJ),
|
||
NULL
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf("%sdumpNSObject: could not read %x\n", indent,Address );
|
||
return;
|
||
|
||
}
|
||
|
||
if (ns.dwNameSeg != 0) {
|
||
|
||
memcpy( buffer, &(ns.dwNameSeg), 4 );
|
||
|
||
} else {
|
||
|
||
sprintf( buffer, " ");
|
||
|
||
}
|
||
|
||
dprintf(
|
||
"%sNameSpace Object %s (%08lx) - Device %08lx\n",
|
||
indent,
|
||
buffer,
|
||
Address,
|
||
ns.Context
|
||
);
|
||
if (Verbose & VERBOSE_NSOBJ) {
|
||
|
||
dprintf(
|
||
"%s Flink %08lx Blink %08lx Parent %08lx Child %08lx\n",
|
||
indent,
|
||
ns.list.plistNext,
|
||
ns.list.plistPrev,
|
||
ns.pnsParent,
|
||
ns.pnsFirstChild
|
||
);
|
||
|
||
}
|
||
dprintf(
|
||
"%s Value %08lx Length %08lx Buffer %08lx Flags %08lx",
|
||
indent,
|
||
ns.ObjData.uipDataValue,
|
||
ns.ObjData.dwDataLen,
|
||
ns.ObjData.pbDataBuff,
|
||
ns.ObjData.dwfData
|
||
);
|
||
if (ns.ObjData.dwfData & DATAF_BUFF_ALIAS) {
|
||
|
||
dprintf(" Alias" );
|
||
|
||
}
|
||
if (ns.ObjData.dwfData & DATAF_GLOBAL_LOCK) {
|
||
|
||
dprintf(" Lock");
|
||
|
||
}
|
||
dprintf("\n");
|
||
|
||
dumpObject( Address, &(ns.ObjData), Verbose, IndentLevel + 4);
|
||
}
|
||
|
||
VOID
|
||
dumpNSTree(
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Level
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This thing dumps the NS tree
|
||
|
||
Arguments:
|
||
|
||
Address - Where to find the root node --- we start dumping at the children
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL end = FALSE;
|
||
BOOL b;
|
||
NSOBJ ns;
|
||
UCHAR buffer[5];
|
||
ULONG_PTR next;
|
||
ULONG back;
|
||
ULONG_PTR m1 = 0;
|
||
ULONG_PTR m2 = 0;
|
||
ULONG reason;
|
||
ULONG dataBuffSize;
|
||
|
||
buffer[4] = '\0';
|
||
|
||
//
|
||
// Indent
|
||
//
|
||
for (m1 = 0; m1 < Level; m1 ++) {
|
||
|
||
dprintf("| ");
|
||
|
||
}
|
||
|
||
//
|
||
// First step is to read the root NS
|
||
//
|
||
b = ReadMemory(
|
||
Address,
|
||
&ns,
|
||
sizeof(NSOBJ),
|
||
NULL
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf("dumpNSTree: could not read %x\n", Address );
|
||
return;
|
||
|
||
}
|
||
|
||
if (ns.dwNameSeg != 0) {
|
||
|
||
memcpy( buffer, &(ns.dwNameSeg), 4 );
|
||
dprintf("%4s ", buffer );
|
||
|
||
} else {
|
||
|
||
dprintf(" " );
|
||
|
||
}
|
||
dprintf(
|
||
"(%08x) - ", Address );
|
||
|
||
if (ns.Context != 0) {
|
||
|
||
dprintf("Device %08lx\n", ns.Context );
|
||
|
||
} else {
|
||
|
||
//
|
||
// We need to read the pbDataBuff here
|
||
//
|
||
if (ns.ObjData.pbDataBuff != 0) {
|
||
|
||
dataBuffSize = (ns.ObjData.dwDataLen > 2047 ?
|
||
2047 : ns.ObjData.dwDataLen
|
||
);
|
||
b = ReadMemory(
|
||
(ULONG_PTR) ns.ObjData.pbDataBuff,
|
||
Buffer,
|
||
dataBuffSize,
|
||
NULL
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf(
|
||
"dumpNSTree: could not read %x\n",
|
||
ns.ObjData.pbDataBuff
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
}
|
||
switch(ns.ObjData.dwDataType) {
|
||
default:
|
||
case OBJTYPE_UNKNOWN: dprintf("Unknown\n"); break;
|
||
case OBJTYPE_INTDATA:
|
||
dprintf("Integer - %lx\n", ns.ObjData.uipDataValue);
|
||
break;
|
||
case OBJTYPE_STRDATA:
|
||
Buffer[dataBuffSize+1] = '\0';
|
||
dprintf(
|
||
"String - %s\n",
|
||
Buffer
|
||
);
|
||
break;
|
||
case OBJTYPE_BUFFDATA:
|
||
dprintf(
|
||
"Buffer - %08lx L=%04x\n",
|
||
ns.ObjData.pbDataBuff,
|
||
ns.ObjData.dwDataLen
|
||
);
|
||
break;
|
||
case OBJTYPE_PKGDATA: {
|
||
|
||
PPACKAGEOBJ package = (PPACKAGEOBJ) Buffer;
|
||
|
||
dprintf("Package - NumElements %x\n",package->dwcElements);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_FIELDUNIT:{
|
||
|
||
PFIELDUNITOBJ fieldUnit = (PFIELDUNITOBJ) Buffer;
|
||
|
||
dprintf(
|
||
"FieldUnit - Parent %x Offset %x Start %x "
|
||
"Num %x Flags %x\n",
|
||
fieldUnit->pnsFieldParent,
|
||
fieldUnit->FieldDesc.dwByteOffset,
|
||
fieldUnit->FieldDesc.dwStartBitPos,
|
||
fieldUnit->FieldDesc.dwNumBits,
|
||
fieldUnit->FieldDesc.dwFieldFlags
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_DEVICE:
|
||
dprintf("Device\n");
|
||
break;
|
||
case OBJTYPE_EVENT:
|
||
dprintf("Event - PKEvent %x\n", ns.ObjData.pbDataBuff);
|
||
break;
|
||
case OBJTYPE_METHOD: {
|
||
|
||
PMETHODOBJ method = (PMETHODOBJ) Buffer;
|
||
|
||
dprintf(
|
||
"Method - Flags %x Start %08lx Len %x\n",
|
||
method->bMethodFlags,
|
||
(ULONG_PTR) method->abCodeBuff - (ULONG_PTR) method +
|
||
(ULONG_PTR) ns.ObjData.pbDataBuff,
|
||
(ULONG) ns.ObjData.dwDataLen - sizeof(METHODOBJ) +
|
||
ANYSIZE_ARRAY
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_OPREGION: {
|
||
|
||
POPREGIONOBJ opRegion = (POPREGIONOBJ) Buffer;
|
||
|
||
dprintf(
|
||
"Opregion - RegionsSpace=%08x OffSet=%x Len=%x\n",
|
||
opRegion->bRegionSpace,
|
||
opRegion->uipOffset,
|
||
opRegion->dwLen
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_BUFFFIELD: {
|
||
|
||
PBUFFFIELDOBJ field = (PBUFFFIELDOBJ) Buffer;
|
||
|
||
dprintf(
|
||
"Buffer Field Ptr=%x Len=%x Offset=%x Start=%x"
|
||
"NumBits=%x Flgas=%x\n",
|
||
field->pbDataBuff,
|
||
field->dwBuffLen,
|
||
field->FieldDesc.dwByteOffset,
|
||
field->FieldDesc.dwStartBitPos,
|
||
field->FieldDesc.dwNumBits,
|
||
field->FieldDesc.dwFieldFlags
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_FIELD: {
|
||
|
||
dprintf("Field\n");
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_INDEXFIELD: dprintf("Index Field\n"); break;
|
||
|
||
case OBJTYPE_MUTEX: dprintf("Mutex\n"); break;
|
||
case OBJTYPE_POWERRES: dprintf("Power Resource\n"); break;
|
||
case OBJTYPE_PROCESSOR: dprintf("Processor\n"); break;
|
||
case OBJTYPE_THERMALZONE: dprintf("Thermal Zone\n"); break;
|
||
case OBJTYPE_DDBHANDLE: dprintf("DDB Handle\n"); break;
|
||
case OBJTYPE_DEBUG: dprintf("Debug\n"); break;
|
||
case OBJTYPE_OBJALIAS: dprintf("Object Alias\n"); break;
|
||
case OBJTYPE_DATAALIAS: dprintf("Data Alias\n"); break;
|
||
case OBJTYPE_BANKFIELD: dprintf("Bank Field\n"); break;
|
||
|
||
}
|
||
|
||
}
|
||
m1 = next = (ULONG_PTR) ns.pnsFirstChild;
|
||
|
||
while (next != 0 && end == FALSE) {
|
||
|
||
if (CheckControlC()) {
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
b = ReadMemory(
|
||
next,
|
||
&ns,
|
||
sizeof(NSOBJ),
|
||
NULL
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf("dumpNSTree: could not read %x\n", next );
|
||
return;
|
||
|
||
}
|
||
|
||
dumpNSTree( next, Level + 1);
|
||
|
||
//
|
||
// Do the end check tests
|
||
//
|
||
if ( m2 == 0) {
|
||
|
||
m2 = (ULONG_PTR) ns.list.plistPrev;
|
||
|
||
} else if (m1 == (ULONG_PTR) ns.list.plistNext) {
|
||
|
||
end = TRUE;
|
||
reason = 1;
|
||
|
||
} else if (m2 == next) {
|
||
|
||
end = TRUE;
|
||
reason = 2;
|
||
}
|
||
|
||
next = (ULONG_PTR) ns.list.plistNext;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
dumpObject(
|
||
IN ULONG_PTR Address,
|
||
IN POBJDATA Object,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This dumps an Objdata so that it can be understand --- great for debugging some of the
|
||
AML code
|
||
|
||
Arguments:
|
||
|
||
Address - Where the Object is located
|
||
Object - Pointer to the object
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
BOOL b;
|
||
NTSTATUS status;
|
||
UCHAR buffer[2048];
|
||
UCHAR indent[80];
|
||
ULONG max;
|
||
ULONG returnLength;
|
||
|
||
//
|
||
// Init the buffers
|
||
//
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
|
||
dprintf("%sObject Data - %08lx Type - ", indent, Address );
|
||
|
||
//
|
||
// First step is to read whatever the buffer points to, if it
|
||
// points to something
|
||
//
|
||
if (Object->pbDataBuff != 0) {
|
||
|
||
max = (Object->dwDataLen > 2047 ? 2047 : Object->dwDataLen );
|
||
b = ReadMemory(
|
||
(ULONG_PTR) Object->pbDataBuff,
|
||
buffer,
|
||
max,
|
||
&returnLength
|
||
);
|
||
if (!b || returnLength != max) {
|
||
|
||
dprintf(
|
||
"%sdumpObject: Could not read buffer %08lx (%d) %x<->%x\n",
|
||
indent,
|
||
Object->pbDataBuff,
|
||
b,
|
||
max,
|
||
returnLength
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
}
|
||
switch( Object->dwDataType ) {
|
||
case OBJTYPE_INTDATA:
|
||
dprintf(
|
||
"%02x <Integer> Value=%08lx\n",
|
||
Object->dwDataType,
|
||
Object->uipDataValue
|
||
);
|
||
break;
|
||
case OBJTYPE_STRDATA:
|
||
buffer[max] = '\0';
|
||
dprintf(
|
||
"%02x <String> String=%s\n",
|
||
Object->dwDataType,
|
||
buffer
|
||
);
|
||
break;
|
||
case OBJTYPE_BUFFDATA:
|
||
dprintf(
|
||
"%02x <Buffer> Ptr=%08lx Length = %2x\n",
|
||
Object->dwDataType,
|
||
Object->pbDataBuff,
|
||
Object->dwDataLen
|
||
);
|
||
break;
|
||
case OBJTYPE_PKGDATA: {
|
||
|
||
PPACKAGEOBJ package = (PPACKAGEOBJ) buffer;
|
||
ULONG i = 0;
|
||
ULONG j = package->dwcElements;
|
||
|
||
dprintf(
|
||
"%02x <Package> NumElements=%02x\n",
|
||
Object->dwDataType,
|
||
j
|
||
);
|
||
|
||
if (Verbose & VERBOSE_OBJECT) {
|
||
|
||
for (; i < j; i++) {
|
||
|
||
dumpObject(
|
||
(ULONG_PTR) &(package->adata[i]) - (ULONG_PTR) package +
|
||
(ULONG_PTR) Object->pbDataBuff,
|
||
&(package->adata[i]),
|
||
Verbose,
|
||
IndentLevel+ 2
|
||
);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_FIELDUNIT: {
|
||
|
||
PFIELDUNITOBJ fieldUnit = (PFIELDUNITOBJ) buffer;
|
||
|
||
dprintf(
|
||
"%02x <Field Unit> Parent=%08lx Offset=%08lx Start=%08x "
|
||
"Num=%x Flags=%x\n",
|
||
Object->dwDataType,
|
||
fieldUnit->pnsFieldParent,
|
||
fieldUnit->FieldDesc.dwByteOffset,
|
||
fieldUnit->FieldDesc.dwStartBitPos,
|
||
fieldUnit->FieldDesc.dwNumBits,
|
||
fieldUnit->FieldDesc.dwFieldFlags
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_DEVICE:
|
||
dprintf(
|
||
"%02x <Device>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
case OBJTYPE_EVENT:
|
||
dprintf(
|
||
"%02x <Event> PKEvent=%08lx\n",
|
||
Object->dwDataType,
|
||
Object->pbDataBuff
|
||
);
|
||
break;
|
||
case OBJTYPE_METHOD: {
|
||
|
||
PMETHODOBJ method = (PMETHODOBJ) buffer;
|
||
|
||
max = Object->dwDataLen - sizeof(METHODOBJ) + ANYSIZE_ARRAY;
|
||
dprintf(
|
||
"%02x <Method> Flags=%x Start=%x Len=%x\n",
|
||
Object->dwDataType,
|
||
method->bMethodFlags,
|
||
(ULONG_PTR) method->abCodeBuff - (ULONG_PTR) method +
|
||
(ULONG_PTR) Object->pbDataBuff,
|
||
max
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_MUTEX:
|
||
|
||
dprintf(
|
||
"%02x <Mutex> Mutex=%08lx\n",
|
||
Object->dwDataType,
|
||
Object->pbDataBuff
|
||
);
|
||
break;
|
||
|
||
case OBJTYPE_OPREGION: {
|
||
|
||
POPREGIONOBJ opRegion = (POPREGIONOBJ) buffer;
|
||
|
||
dprintf(
|
||
"%02x <Operational Region> RegionSpace=%08x OffSet=%x "
|
||
"Len=%x\n",
|
||
Object->dwDataType,
|
||
opRegion->bRegionSpace,
|
||
opRegion->uipOffset,
|
||
opRegion->dwLen
|
||
);
|
||
break;
|
||
|
||
}
|
||
|
||
case OBJTYPE_POWERRES: {
|
||
|
||
PPOWERRESOBJ powerRes = (PPOWERRESOBJ) buffer;
|
||
|
||
dprintf(
|
||
"%02x <Power Resource> SystemLevel=S%d Order=%x\n",
|
||
Object->dwDataType,
|
||
powerRes->bSystemLevel,
|
||
powerRes->bResOrder
|
||
);
|
||
break;
|
||
|
||
}
|
||
|
||
case OBJTYPE_PROCESSOR: {
|
||
|
||
PPROCESSOROBJ proc = (PPROCESSOROBJ) buffer;
|
||
|
||
dprintf(
|
||
"%02x <Processor> AcpiID=%x PBlk=%x PBlkLen=%x\n",
|
||
Object->dwDataType,
|
||
proc->bApicID,
|
||
proc->dwPBlk,
|
||
proc->dwPBlkLen
|
||
);
|
||
break;
|
||
|
||
}
|
||
|
||
case OBJTYPE_THERMALZONE:
|
||
dprintf(
|
||
"%02x <Thermal Zone>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
case OBJTYPE_BUFFFIELD: {
|
||
|
||
PBUFFFIELDOBJ field = (PBUFFFIELDOBJ) buffer;
|
||
|
||
dprintf(
|
||
"%02x <Buffer Field> Ptr=%x Len=%x Offset=%x Start=%x "
|
||
"NumBits=%x Flags=%x\n",
|
||
Object->dwDataType,
|
||
field->pbDataBuff,
|
||
field->dwBuffLen,
|
||
field->FieldDesc.dwByteOffset,
|
||
field->FieldDesc.dwStartBitPos,
|
||
field->FieldDesc.dwNumBits,
|
||
field->FieldDesc.dwFieldFlags
|
||
);
|
||
break;
|
||
|
||
}
|
||
|
||
case OBJTYPE_DDBHANDLE:
|
||
dprintf(
|
||
"%02x <DDB Handle> Handle=%x\n",
|
||
Object->dwDataType,
|
||
Object->pbDataBuff
|
||
);
|
||
break;
|
||
case OBJTYPE_DEBUG:
|
||
dprintf(
|
||
"%02x <Internal Debug>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
case OBJTYPE_OBJALIAS:
|
||
|
||
dprintf(
|
||
"%02x <Internal Object Alias> NS Object=%x\n",
|
||
Object->dwDataType,
|
||
Object->uipDataValue
|
||
);
|
||
dumpNSObject( Object->uipDataValue, Verbose, IndentLevel + 2 );
|
||
break;
|
||
case OBJTYPE_DATAALIAS: {
|
||
|
||
OBJDATA objData;
|
||
|
||
dprintf(
|
||
"%02x <Internal Data Alias> Data Object=%x\n",
|
||
Object->dwDataType,
|
||
Object->uipDataValue
|
||
);
|
||
|
||
b = ReadMemory(
|
||
(ULONG) Object->uipDataValue,
|
||
&objData,
|
||
sizeof(OBJDATA),
|
||
NULL
|
||
);
|
||
if (!b) {
|
||
|
||
dprintf(
|
||
"dumpObject: could not read %x\n",
|
||
Object->uipDataValue
|
||
);
|
||
return;
|
||
|
||
}
|
||
dumpObject(
|
||
(ULONG) Object->uipDataValue,
|
||
&objData,
|
||
Verbose,
|
||
IndentLevel + 2
|
||
);
|
||
break;
|
||
|
||
}
|
||
case OBJTYPE_BANKFIELD:
|
||
dprintf(
|
||
"%02x <Internal Bank Field>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
case OBJTYPE_FIELD:
|
||
dprintf(
|
||
"%02x <Internal Field>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
case OBJTYPE_INDEXFIELD:
|
||
dprintf(
|
||
"%02x <Index Field>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
case OBJTYPE_UNKNOWN:
|
||
default:
|
||
dprintf(
|
||
"%02x <Unknown>\n",
|
||
Object->dwDataType
|
||
);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
dumpPObject(
|
||
IN ULONG_PTR Address,
|
||
IN ULONG Verbose,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is a wrapper for dumpObject
|
||
|
||
|
||
--*/
|
||
{
|
||
BOOL result;
|
||
OBJDATA objdata;
|
||
ULONG returnLength;
|
||
|
||
result = ReadMemory(
|
||
Address,
|
||
&objdata,
|
||
sizeof(OBJDATA),
|
||
&returnLength
|
||
);
|
||
if (result != TRUE || returnLength != sizeof(OBJDATA) ) {
|
||
|
||
UCHAR indent[80];
|
||
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
||
memset( indent, ' ', IndentLevel );
|
||
indent[IndentLevel] = '\0';
|
||
|
||
dprintf(
|
||
"%sdumpPObject: Could not OBJDATA %08lx\n",
|
||
indent,
|
||
Address
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
dumpObject(
|
||
Address,
|
||
&objdata,
|
||
Verbose,
|
||
IndentLevel
|
||
);
|
||
return;
|
||
|
||
}
|
||
|
||
PUCHAR
|
||
TempToKelvins(
|
||
IN ULONG Temp
|
||
)
|
||
{
|
||
static UCHAR buffer[80];
|
||
|
||
sprintf( buffer, "%d.%d", (Temp / 10 ), (Temp % 10) );
|
||
return buffer;
|
||
}
|
||
|
||
PUCHAR
|
||
TimeToSeconds(
|
||
IN ULONG Time
|
||
)
|
||
{
|
||
static UCHAR buffer[80];
|
||
|
||
sprintf( buffer, "%d.%d", (Time / 10 ), (Time % 10) );
|
||
return buffer;
|
||
|
||
}
|