1981 lines
47 KiB
C++
1981 lines
47 KiB
C++
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
thermal
|
|
|
|
Abstract:
|
|
|
|
WinDbg Extension Api
|
|
|
|
Author:
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define TZ_LOOP 0x00000001
|
|
#define TZ_DUMP_INFO 0x00000002
|
|
#define TZ_NO_HEADER 0x80000000
|
|
|
|
PCHAR DumpPowerStateMappings[10] = {
|
|
"x", "0", "1", "2", "3", "4", "5", "?", "?", "?"
|
|
};
|
|
|
|
PCHAR DumpPowerActionMappings[] = {
|
|
" None",
|
|
" Reserved",
|
|
" Sleep",
|
|
"Hibernate",
|
|
" Shutdown",
|
|
" Reset",
|
|
" Off"
|
|
};
|
|
|
|
PCHAR DumpDynamicThrottleMapping[] = {
|
|
" None",
|
|
"Constant",
|
|
" Degrade",
|
|
"Adaptive",
|
|
" Maximum"
|
|
};
|
|
|
|
PCHAR
|
|
DumpTimeInStandardForm(
|
|
IN ULONG64 CurrentTime
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Print the Kernel's view of time into something that a user can
|
|
understand
|
|
|
|
Arguments:
|
|
|
|
CurrentTime - Kernel's Idea of time
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
static CHAR TimeBuffer[256];
|
|
ULONG TimeIncrement;
|
|
TIME_FIELDS Times;
|
|
LARGE_INTEGER RunTime;
|
|
|
|
TimeIncrement = GetNtDebuggerDataValue( KeTimeIncrement );
|
|
RunTime.QuadPart = UInt32x32To64(CurrentTime, TimeIncrement);
|
|
RtlTimeToElapsedTimeFields( &RunTime, &Times);
|
|
if (Times.Hour) {
|
|
sprintf(TimeBuffer,"%3ld:%02ld:%02ld.%03lds",
|
|
Times.Hour,
|
|
Times.Minute,
|
|
Times.Second,
|
|
Times.Milliseconds);
|
|
} else if (Times.Minute) {
|
|
sprintf(TimeBuffer,"%02ld:%02ld.%03lds",
|
|
Times.Minute,
|
|
Times.Second,
|
|
Times.Milliseconds);
|
|
} else {
|
|
sprintf(TimeBuffer,"%02ld.%03lds",
|
|
Times.Second,
|
|
Times.Milliseconds);
|
|
}
|
|
return TimeBuffer;
|
|
}
|
|
|
|
PCHAR
|
|
DumpMicroSecondsInStandardForm(
|
|
IN ULONG64 CurrentTime
|
|
)
|
|
{
|
|
static CHAR PerfBuffer[256];
|
|
ULONG64 FreqAddr;
|
|
LARGE_INTEGER Freq;
|
|
ULONG Result;
|
|
ULONG64 MicroSeconds;
|
|
ULONG64 MilliSeconds;
|
|
ULONG64 Seconds;
|
|
ULONG64 Minutes;
|
|
ULONG64 Hours;
|
|
ULONG64 Days;
|
|
|
|
MicroSeconds = CurrentTime;
|
|
MilliSeconds = MicroSeconds / 1000;
|
|
MicroSeconds = MicroSeconds % 1000;
|
|
|
|
Seconds = MilliSeconds / 1000;
|
|
MilliSeconds = MilliSeconds % 1000;
|
|
|
|
Minutes = Seconds / 60;
|
|
Seconds = Seconds % 60;
|
|
|
|
Hours = Minutes / 60;
|
|
Minutes = Minutes % 60;
|
|
|
|
Days = Hours / 24;
|
|
Hours = Hours % 24;
|
|
|
|
#if 0
|
|
sprintf(PerfBuffer,"%02ld:%02ld:%02ld.%03ld.%03lds",
|
|
(ULONG)Hours,
|
|
(ULONG)Minutes,
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
return PerfBuffer;
|
|
#endif
|
|
|
|
if (Hours) {
|
|
sprintf(PerfBuffer,"%02ld:%02ld:%02ld.%03ld.%03lds",
|
|
(ULONG)Hours,
|
|
(ULONG)Minutes,
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
} else if (Minutes) {
|
|
sprintf(PerfBuffer,"%02ld:%02ld.%03ld.%03lds",
|
|
(ULONG)Minutes,
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
} else if (Seconds) {
|
|
sprintf(PerfBuffer,"%02ld.%03ld.%03lds",
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
} else {
|
|
sprintf(PerfBuffer,".%03ld.%03lds",
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
}
|
|
return PerfBuffer;
|
|
}
|
|
|
|
|
|
PCHAR
|
|
DumpPerformanceCounterInStandardForm(
|
|
IN ULONG64 CurrentTime
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Print a performance counter's view of time into something that a
|
|
user can understand
|
|
|
|
--*/
|
|
{
|
|
static CHAR PerfBuffer[256];
|
|
ULONG64 FreqAddr;
|
|
LARGE_INTEGER Freq;
|
|
ULONG Result;
|
|
ULONG64 MicroSeconds;
|
|
ULONG64 MilliSeconds;
|
|
ULONG64 Seconds;
|
|
ULONG64 Minutes;
|
|
ULONG64 Hours;
|
|
ULONG64 Days;
|
|
|
|
FreqAddr = GetExpression( "nt!KdPerformanceCounterRate" );
|
|
if (!FreqAddr || !ReadMemory( FreqAddr, &Freq, sizeof(Freq), &Result) ) {
|
|
sprintf(PerfBuffer,"<unknown rate>");
|
|
return PerfBuffer;
|
|
}
|
|
|
|
|
|
MicroSeconds = (CurrentTime * 1000000L) / Freq.LowPart;
|
|
MilliSeconds = MicroSeconds / 1000;
|
|
MicroSeconds = MicroSeconds % 1000;
|
|
|
|
Seconds = MilliSeconds / 1000;
|
|
MilliSeconds = MilliSeconds % 1000;
|
|
|
|
Minutes = Seconds / 60;
|
|
Seconds = Seconds % 60;
|
|
|
|
Hours = Minutes / 60;
|
|
Minutes = Minutes % 60;
|
|
|
|
Days = Hours / 24;
|
|
Hours = Hours % 24;
|
|
|
|
#if 0
|
|
sprintf(PerfBuffer,"%02ld:%02ld:%02ld.%03ld.%03lds",
|
|
(ULONG)Hours,
|
|
(ULONG)Minutes,
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
return PerfBuffer;
|
|
#endif
|
|
|
|
if (Hours) {
|
|
sprintf(PerfBuffer,"%02ld:%02ld:%02ld.%03ld.%03lds",
|
|
(ULONG)Hours,
|
|
(ULONG)Minutes,
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
} else if (Minutes) {
|
|
sprintf(PerfBuffer,"%02ld:%02ld.%03ld.%03lds",
|
|
(ULONG)Minutes,
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
} else if (Seconds) {
|
|
sprintf(PerfBuffer,"%02ld.%03ld.%03lds",
|
|
(ULONG)Seconds,
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
} else {
|
|
sprintf(PerfBuffer,".%03ld.%03lds",
|
|
(ULONG)MilliSeconds,
|
|
(ULONG)MicroSeconds
|
|
);
|
|
}
|
|
return PerfBuffer;
|
|
}
|
|
|
|
VOID
|
|
DumpTemperatureInKelvins(
|
|
IN ULONG Temperature
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the temperatures in Kelvins
|
|
|
|
Arguments:
|
|
|
|
Temperature - What to dump in Kelvins
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
dprintf(" (%d.%dK)", (Temperature / 10), (Temperature % 10) );
|
|
}
|
|
|
|
VOID
|
|
DumpPowerActionPolicyBrief(
|
|
IN ULONG Action,
|
|
IN ULONG Flags,
|
|
IN ULONG EventCode
|
|
)
|
|
{
|
|
dprintf("%s Flags: %08lx Event: %08lx ",
|
|
DumpPowerActionMappings[Action],
|
|
Flags,
|
|
EventCode
|
|
);
|
|
if (Flags & POWER_ACTION_QUERY_ALLOWED) {
|
|
|
|
dprintf(" Query");
|
|
|
|
}
|
|
if (Flags & POWER_ACTION_UI_ALLOWED) {
|
|
|
|
dprintf(" UI");
|
|
|
|
}
|
|
if (Flags & POWER_ACTION_OVERRIDE_APPS) {
|
|
|
|
dprintf(" Override");
|
|
|
|
}
|
|
if (Flags & POWER_ACTION_LOCK_CONSOLE) {
|
|
|
|
dprintf(" Lock");
|
|
|
|
}
|
|
if (Flags & POWER_ACTION_DISABLE_WAKES) {
|
|
|
|
dprintf(" NoWakes");
|
|
|
|
}
|
|
if (Flags & POWER_ACTION_CRITICAL) {
|
|
|
|
dprintf(" Critical");
|
|
|
|
}
|
|
|
|
if (EventCode & POWER_LEVEL_USER_NOTIFY_TEXT) {
|
|
|
|
dprintf(" NotifyText");
|
|
|
|
}
|
|
if (EventCode & POWER_LEVEL_USER_NOTIFY_SOUND) {
|
|
|
|
dprintf(" NotifySound");
|
|
|
|
}
|
|
if (EventCode & POWER_LEVEL_USER_NOTIFY_EXEC) {
|
|
|
|
dprintf(" NotifyExec");
|
|
|
|
}
|
|
dprintf("\n");
|
|
}
|
|
|
|
VOID
|
|
DumpSystemPowerPolicy(
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
System Power Policy change
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
UCHAR temp;
|
|
|
|
InitTypeRead(Address, nt!_SYSTEM_POWER_POLICY);
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%sSYSTEM_POWER_POLICY (R.%d) @ 0x%08p\n",
|
|
Pad, (ULONG) ReadField(Revision), Address);
|
|
|
|
}
|
|
|
|
temp = (UCHAR) ReadField(DynamicThrottle);
|
|
if (temp > PO_THROTTLE_MAXIMUM) {
|
|
temp = PO_THROTTLE_MAXIMUM;
|
|
}
|
|
|
|
dprintf("%s PowerButton: ", Pad);
|
|
DumpPowerActionPolicyBrief( (ULONG) ReadField(PowerButton.Action),
|
|
(ULONG) ReadField(PowerButton.Flags),
|
|
(ULONG) ReadField(PowerButton.EventCode));
|
|
dprintf("%s SleepButton: ", Pad);
|
|
DumpPowerActionPolicyBrief( (ULONG) ReadField(SleepButton.Action),
|
|
(ULONG) ReadField(SleepButton.Flags),
|
|
(ULONG) ReadField(SleepButton.EventCode));
|
|
dprintf("%s LidClose: ", Pad);
|
|
DumpPowerActionPolicyBrief( (ULONG) ReadField(LidClose.Action),
|
|
(ULONG) ReadField(LidClose.Flags),
|
|
(ULONG) ReadField(LidClose.EventCode));
|
|
dprintf("%s Idle: ", Pad);
|
|
DumpPowerActionPolicyBrief( (ULONG) ReadField(Idle.Action),
|
|
(ULONG) ReadField(Idle.Flags),
|
|
(ULONG) ReadField(Idle.EventCode));
|
|
dprintf("%s OverThrottled: ", Pad);
|
|
DumpPowerActionPolicyBrief( (ULONG) ReadField(OverThrottled.Action),
|
|
(ULONG) ReadField(OverThrottled.Flags),
|
|
(ULONG) ReadField(OverThrottled.EventCode));
|
|
dprintf("%s IdleTimeout: %8lx IdleSensitivity: %d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField(IdleTimeout),
|
|
(ULONG) ReadField(IdleSensitivity));
|
|
dprintf("%s MinSleep: S%s MaxSleep: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(MinSleep)],
|
|
DumpPowerStateMappings[(ULONG) ReadField(MaxSleep)]);
|
|
dprintf("%s LidOpenWake: S%s FastSleep: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(LidOpenWake)],
|
|
DumpPowerStateMappings[(ULONG) ReadField(ReducedLatencySleep)]);
|
|
dprintf("%s WinLogonFlags: %8lx S4Timeout: %8lx\n",
|
|
Pad,
|
|
(ULONG) ReadField(WinLogonFlags),
|
|
(ULONG) ReadField(DozeS4Timeout));
|
|
dprintf("%s VideoTimeout: %8d VideoDim: %2d\n",
|
|
Pad,
|
|
(ULONG) ReadField(VideoTimeout),
|
|
(ULONG) ReadField(VideoDimDisplay));
|
|
dprintf("%s SpinTimeout: %8lx OptForPower: %2d\n",
|
|
Pad,
|
|
(ULONG) ReadField(SpindownTimeout),
|
|
(ULONG) ReadField(OptimizeForPower)
|
|
);
|
|
dprintf("%s FanTolerance: %4d%% ForcedThrottle: %4d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField(FanThrottleTolerance),
|
|
(ULONG) ReadField(ForcedThrottle));
|
|
dprintf("%s MinThrottle: %4d%% DyanmicThrottle: %8s (%d)\n",
|
|
Pad, (ULONG) ReadField(MinThrottle),
|
|
DumpDynamicThrottleMapping[temp],
|
|
temp
|
|
);
|
|
}
|
|
|
|
DECLARE_API( popolicy )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the power policy
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG64 PolicyAddress;
|
|
ULONG Flags = 0;
|
|
ULONG Result;
|
|
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (!Address) {
|
|
|
|
Address = GetExpression("nt!PopPolicy");
|
|
if (!Address) {
|
|
|
|
dprintf("Could not read PopPolicy\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (!ReadPointer(Address,
|
|
&PolicyAddress) ) {
|
|
|
|
dprintf("Could not read PopPolicy at %p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
Address = PolicyAddress;
|
|
|
|
}
|
|
if (!Address) {
|
|
|
|
dprintf("!popolicy [addr [flags]]\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
if (GetFieldValue( Address,
|
|
"nt!_SYSTEM_POWER_POLICY",
|
|
"Revision",
|
|
Result) ) {
|
|
|
|
dprintf("Could not read PopPolicy at %p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
DumpSystemPowerPolicy( "", Address, Flags );
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpProcessorPowerPolicy(
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Processor Power Policy change
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG i;
|
|
ULONG count;
|
|
ULONG offset;
|
|
ULONG64 size;
|
|
|
|
InitTypeRead(Address, nt!_PROCESSOR_POWER_POLICY);
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%sPROCESSOR_POWER_POLICY %p (Rev .%d)\n",
|
|
Pad,
|
|
Address,
|
|
(ULONG) ReadField(Revision)
|
|
);
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s DynamicThrottle: %4d PolicyCount: %8d\n",
|
|
Pad,
|
|
(ULONG) ReadField(DynamicThrottle),
|
|
(ULONG) ReadField(PolicyCount)
|
|
);
|
|
|
|
GetFieldOffset("nt!_PROCESSOR_POWER_POLICY", "Policy", &offset);
|
|
Address += offset;
|
|
size = GetTypeSize("nt!_PROCESSOR_POWER_POLICY_INFO");
|
|
count = (ULONG) ReadField(PolicyCount);
|
|
if (count > 3) {
|
|
|
|
count = 3;
|
|
|
|
}
|
|
|
|
//
|
|
// Walk the PROCESSOR_POWER_POLICY_INFO structures
|
|
//
|
|
for (i = 0; i < count; i++) {
|
|
|
|
InitTypeRead(Address, nt!_PROCESSOR_POWER_POLICY_INFO);
|
|
dprintf(
|
|
"\n%s PROCESSOR_POWER_POLICY_INFO %p\n",
|
|
Pad,
|
|
Address
|
|
);
|
|
dprintf(
|
|
"%s PromotePercent: %4d%% DemotePercent: %4d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField( PromotePercent ),
|
|
(ULONG) ReadField( DemotePercent )
|
|
);
|
|
dprintf(
|
|
"%s AllowPromotion: %5s AllowDemotion: %5s\n",
|
|
Pad,
|
|
( (ULONG) ReadField( AllowPromotion ) ? " TRUE" : "FALSE"),
|
|
( (ULONG) ReadField( AllowDemotion) ? " TRUE" : "FALSE")
|
|
);
|
|
dprintf(
|
|
"%s TimeCheck: %21s (%8p)\n",
|
|
Pad,
|
|
DumpMicroSecondsInStandardForm( ReadField( TimeCheck ) ),
|
|
(ULONG) ReadField( TimeCheck )
|
|
);
|
|
dprintf(
|
|
"%s PromoteLimit: %21s (%8p)\n",
|
|
Pad,
|
|
DumpMicroSecondsInStandardForm( ReadField( PromoteLimit ) ),
|
|
(ULONG) ReadField( PromoteLimit )
|
|
);
|
|
dprintf(
|
|
"%s DemoteLimit: %21s (%8p)\n",
|
|
Pad,
|
|
DumpMicroSecondsInStandardForm( ReadField( DemoteLimit ) ),
|
|
(ULONG) ReadField( DemoteLimit )
|
|
);
|
|
Address += size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DECLARE_API( poprocpolicy )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the power policy
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG64 PolicyAddress;
|
|
ULONG Flags = 0;
|
|
ULONG Result;
|
|
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (!Address) {
|
|
|
|
Address = GetExpression("nt!PopProcessorPolicy");
|
|
if (!Address) {
|
|
|
|
dprintf("Could not read PopProcessorPolicy\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (!ReadPointer(Address,&PolicyAddress) ) {
|
|
|
|
dprintf("Could not read PopProcessorPolicy at %p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
Address = PolicyAddress;
|
|
|
|
}
|
|
if (!Address) {
|
|
|
|
dprintf("!poprocpolicy [addr [flags]]\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
if (GetFieldValue( Address,"PROCESSOR_POWER_POLICY", "Revision", Result) ) {
|
|
|
|
dprintf("Could not read PopProcessorPolicy at %p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
DumpProcessorPowerPolicy( "", Address, Flags );
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpProcessorPowerState(
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Processor Power State dump
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG time;
|
|
ULONG temp;
|
|
CHAR FunctionName[256];
|
|
ULONG64 Offset;
|
|
|
|
InitTypeRead(Address, nt!_PROCESSOR_POWER_STATE);
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%sPROCESSOR_POWER_STATE %p\n", Pad, Address );
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s IdleState: %16p IdleHandlers: %16p\n",
|
|
Pad,
|
|
ReadField(IdleState),
|
|
ReadField(IdleHandlers)
|
|
);
|
|
dprintf(
|
|
"%s C1 Idle Transitions: %8lx C1 Idle Time: %17s\n",
|
|
Pad,
|
|
(ULONG) ReadField( TotalIdleTransitions[0] ),
|
|
DumpPerformanceCounterInStandardForm( ReadField( TotalIdleStateTime[0] ) )
|
|
);
|
|
dprintf(
|
|
"%s C2 Idle Transitions: %8lx C2 Idle Time: %17s\n",
|
|
Pad,
|
|
(ULONG) ReadField( TotalIdleTransitions[1] ),
|
|
DumpPerformanceCounterInStandardForm( ReadField( TotalIdleStateTime[1] ) )
|
|
);
|
|
dprintf(
|
|
"%s C3 Idle Transitions: %8lx C3 Idle Time: %17s\n\n",
|
|
Pad,
|
|
(ULONG) ReadField( TotalIdleTransitions[2] ),
|
|
DumpPerformanceCounterInStandardForm( ReadField( TotalIdleStateTime[2] ) )
|
|
);
|
|
dprintf(
|
|
"%s DebugDelta: %16I64x LastCheck: %17s\n",
|
|
Pad,
|
|
ReadField(DebugDelta),
|
|
DumpPerformanceCounterInStandardForm( ReadField( LastCheck ) )
|
|
);
|
|
dprintf(
|
|
"%s DebugCount: %8lx IdleTime.Start: %17s\n",
|
|
Pad,
|
|
(ULONG) ReadField(DebugCount),
|
|
DumpPerformanceCounterInStandardForm( ReadField( IdleTimes.StartTime ) )
|
|
);
|
|
dprintf(
|
|
"%s PromotionCheck: %8lx IdleTime.End: %17s\n",
|
|
Pad,
|
|
(ULONG) ReadField(PromotionCheck ),
|
|
DumpPerformanceCounterInStandardForm( ReadField( IdleTimes.EndTime ) )
|
|
);
|
|
dprintf(
|
|
"%s IdleTime1: %8lx Idle0LastTime: %17s\n",
|
|
Pad,
|
|
(ULONG) ReadField(IdleTime1),
|
|
DumpTimeInStandardForm( ReadField( Idle0LastTime ) )
|
|
);
|
|
dprintf(
|
|
"%s IdleTime2: %8lx LastSystTime: %17s\n",
|
|
Pad,
|
|
(ULONG) ReadField(IdleTime2),
|
|
DumpTimeInStandardForm( ReadField( LastSysTime ) )
|
|
);
|
|
dprintf(
|
|
"%s CurrentThrottle: %4d%% Idle0KernelTimeLimit: %15s\n",
|
|
Pad,
|
|
(ULONG) ReadField(CurrentThrottle),
|
|
DumpTimeInStandardForm( ReadField( Idle0KernelTimeLimit ) )
|
|
);
|
|
dprintf(
|
|
"%s CurrentThrottleIndex: %4d ThermalThrottleLimit: %4d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField(CurrentThrottleIndex),
|
|
(ULONG) ReadField(ThermalThrottleLimit)
|
|
);
|
|
dprintf(
|
|
"%s KneeThrottleIndex: %4d ThermalThrottleIndex: %4d\n",
|
|
Pad,
|
|
(ULONG) ReadField(KneeThrottleIndex),
|
|
(ULONG) ReadField(ThermalThrottleIndex)
|
|
);
|
|
dprintf(
|
|
"%s ThrottleLimitIndex: %4d Flags: %8x\n",
|
|
Pad,
|
|
(ULONG) ReadField(ThrottleLimitIndex),
|
|
(ULONG) ReadField(Flags)
|
|
);
|
|
dprintf(
|
|
"%s PerfStates: %8p PerfStatesCount: %4d\n",
|
|
Pad,
|
|
ReadField(PerfStates),
|
|
(ULONG) ReadField(PerfStatesCount)
|
|
);
|
|
dprintf(
|
|
"%s ProcessorMinThrottle: %4d%% ProcessorMaxThrottle: %4d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField(ProcessorMinThrottle),
|
|
(ULONG) ReadField(ProcessorMaxThrottle)
|
|
);
|
|
dprintf(
|
|
"%s PromotionCount: %8d DemotionCount: %8d\n",
|
|
Pad,
|
|
(ULONG) ReadField( PromotionCount ),
|
|
(ULONG) ReadField( DemotionCount )
|
|
);
|
|
dprintf(
|
|
"%s ErrorCount: %8d RetryCount: %8d\n",
|
|
Pad,
|
|
(ULONG) ReadField(ErrorCount),
|
|
(ULONG) ReadField(RetryCount)
|
|
);
|
|
dprintf(
|
|
"%s LastBusyPercentage: %4d%% LastC3Percentage: %4d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField( LastBusyPercentage ),
|
|
(ULONG) ReadField( LastC3Percentage )
|
|
);
|
|
dprintf(
|
|
"%s LastAdjustedBusyPercent: %4d%%\n",
|
|
Pad,
|
|
(ULONG) ReadField(LastAdjustedBusyPercentage)
|
|
);
|
|
dprintf("\n");
|
|
GetSymbol(ReadField(IdleFunction), FunctionName, &Offset);
|
|
dprintf(
|
|
"%s IdleFunction: %50s\n",
|
|
Pad,
|
|
FunctionName
|
|
);
|
|
GetSymbol(ReadField(PerfSetThrottle), FunctionName, &Offset);
|
|
dprintf(
|
|
"%s PerfSetThrottle: %50s\n",
|
|
Pad,
|
|
FunctionName
|
|
);
|
|
dprintf(
|
|
"%s PreviousC3StateTime: %21s (%16p)\n",
|
|
Pad,
|
|
DumpPerformanceCounterInStandardForm( ReadField( PreviousC3StateTime ) ),
|
|
ReadField( PreviousC3StateTime )
|
|
);
|
|
dprintf(
|
|
"%s PerfSystemTime: %21s (%8x)\n",
|
|
Pad,
|
|
DumpTimeInStandardForm( ReadField(PerfSystemTime) ),
|
|
ReadField( PerfSystemTime )
|
|
);
|
|
dprintf(
|
|
"%s PerfIdleTime: %21s (%8x)\n",
|
|
Pad,
|
|
DumpTimeInStandardForm( ReadField(PerfIdleTime) ),
|
|
ReadField( PerfIdleTime )
|
|
);
|
|
dprintf(
|
|
"%s PerfTickCount: %21s (%8x)\n",
|
|
Pad,
|
|
DumpTimeInStandardForm( ReadField(PerfTickCount) ),
|
|
ReadField( PerfTickCount )
|
|
);
|
|
|
|
//
|
|
// At this point, go look at the corresponding PRCB to see what the
|
|
// kernel and user times are
|
|
//
|
|
GetFieldOffset("nt!_KPRCB", "PowerState", &temp);
|
|
Address -= temp;
|
|
InitTypeRead( Address, _KPRCB );
|
|
time = (ULONG) ReadField(UserTime) + (ULONG) ReadField(KernelTime);
|
|
dprintf(
|
|
"%s CurrentSystemTime: %21s (%8x)\n",
|
|
Pad,
|
|
DumpTimeInStandardForm( time ),
|
|
time
|
|
);
|
|
|
|
//
|
|
// Read the Idle Thread to see what the current idle thread time is
|
|
//
|
|
Address = ReadField( IdleThread );
|
|
InitTypeRead( Address, _KTHREAD );
|
|
time = (ULONG) ReadField(KernelTime);
|
|
dprintf(
|
|
"%s CurrentIdleTime: %21s (%8x)\n",
|
|
Pad,
|
|
DumpTimeInStandardForm( time ),
|
|
time
|
|
);
|
|
|
|
}
|
|
|
|
DECLARE_API( poproc )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the Processor Power State
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG64 Pkprcb;
|
|
ULONG Flags = 0;
|
|
ULONG processor;
|
|
ULONG64 Result;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
|
|
if (Address == 0) {
|
|
|
|
HRESULT Hr;
|
|
|
|
INIT_API();
|
|
|
|
GetCurrentProcessor(Client, &processor, NULL);
|
|
|
|
Hr = g_ExtData->ReadProcessorSystemData(processor,
|
|
DEBUG_DATA_KPRCB_OFFSET,
|
|
&Pkprcb,
|
|
sizeof(Pkprcb),
|
|
NULL);
|
|
|
|
|
|
if (Hr != S_OK)
|
|
{
|
|
dprintf("Cannot get PRCB address\n");
|
|
}
|
|
else
|
|
{
|
|
InitTypeRead(Pkprcb,nt!_KPRCB);
|
|
Address = ReadField(PowerState);
|
|
if (!Address)
|
|
{
|
|
dprintf("Unable to get PowerState from the PRCB at %p",Pkprcb);
|
|
dprintf("poproc <address>\n");
|
|
Hr = E_INVALIDARG;
|
|
|
|
}
|
|
}
|
|
|
|
if (Hr != S_OK)
|
|
{
|
|
return Hr;
|
|
}
|
|
}
|
|
|
|
if (GetFieldValue( Address,
|
|
"PROCESSOR_POWER_STATE",
|
|
"IdleTime1",
|
|
Result) ) {
|
|
|
|
dprintf("Could not read PROCESSOR_POWER_STATE at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
//
|
|
// Dump the Trigger Information
|
|
//
|
|
DumpProcessorPowerState("", Address, Flags );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpPowerCapabilities(
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the power capabilities
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
InitTypeRead(Address, nt!SYSTEM_POWER_CAPABILITIES);
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%sPopCapabilities @ 0x%08p\n", Pad, Address );
|
|
|
|
}
|
|
|
|
dprintf("%s Misc Supported Features: ", Pad);
|
|
if ((ULONG) ReadField(PowerButtonPresent)) {
|
|
|
|
dprintf(" PwrButton");
|
|
}
|
|
if ((ULONG) ReadField(SleepButtonPresent)) {
|
|
|
|
dprintf(" SlpButton");
|
|
}
|
|
if ((ULONG) ReadField(LidPresent)) {
|
|
|
|
dprintf(" Lid");
|
|
}
|
|
if ((ULONG) ReadField(SystemS1)) {
|
|
|
|
dprintf(" S1");
|
|
}
|
|
if ((ULONG) ReadField(SystemS2)) {
|
|
|
|
dprintf(" S2");
|
|
}
|
|
if ((ULONG) ReadField(SystemS3)) {
|
|
|
|
dprintf(" S3");
|
|
}
|
|
if ((ULONG) ReadField(SystemS4)) {
|
|
|
|
dprintf(" S4");
|
|
}
|
|
if ((ULONG) ReadField(SystemS5)) {
|
|
|
|
dprintf(" S5");
|
|
}
|
|
if ((ULONG) ReadField(HiberFilePresent)) {
|
|
|
|
dprintf(" HiberFile");
|
|
}
|
|
if ((ULONG) ReadField(FullWake)) {
|
|
|
|
dprintf(" FullWake");
|
|
}
|
|
if ((ULONG) ReadField(VideoDimPresent)) {
|
|
|
|
dprintf(" VideoDim");
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf("%s Processor Features: ", Pad);
|
|
if ((ULONG) ReadField(ThermalControl)) {
|
|
|
|
dprintf(" Thermal");
|
|
}
|
|
if ((ULONG) ReadField(ProcessorThrottle)) {
|
|
|
|
dprintf(" Throttle (MinThrottle = %d%%, Scale = %d%%)",
|
|
(ULONG) ReadField(ProcessorMinThrottle),
|
|
(ULONG) ReadField(ProcessorThrottleScale));
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf("%s Disk Features: ", Pad );
|
|
if ((ULONG) ReadField(DiskSpinDown)) {
|
|
|
|
dprintf(" SpinDown");
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf("%s Battery Features: ", Pad);
|
|
if ((ULONG) ReadField(SystemBatteriesPresent)) {
|
|
|
|
dprintf(" BatteriesPresent");
|
|
|
|
}
|
|
if ((ULONG) ReadField(BatteriesAreShortTerm)) {
|
|
|
|
dprintf(" ShortTerm");
|
|
}
|
|
dprintf("\n");
|
|
if ((ULONG) ReadField(SystemBatteriesPresent)) {
|
|
|
|
dprintf("%s Battery 0 - Capacity: %8lx Granularity: %8lx\n",
|
|
Pad,
|
|
(ULONG) ReadField(BatteryScale[0].Capacity),
|
|
(ULONG) ReadField(BatteryScale[0].Granularity)
|
|
);
|
|
dprintf("%s Battery 1 - Capacity: %8lx Granularity: %8lx\n",
|
|
Pad,
|
|
(ULONG) ReadField(BatteryScale[1].Capacity),
|
|
(ULONG) ReadField(BatteryScale[1].Granularity)
|
|
);
|
|
dprintf("%s Battery 2 - Capacity: %8lx Granularity: %8lx\n",
|
|
Pad,
|
|
(ULONG) ReadField(BatteryScale[2].Capacity),
|
|
(ULONG) ReadField(BatteryScale[2].Granularity)
|
|
);
|
|
|
|
}
|
|
dprintf("%s Wake Caps\n", Pad);
|
|
dprintf("%s Ac OnLine Wake: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(AcOnLineWake)]);
|
|
dprintf("%s Soft Lid Wake: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(SoftLidWake)]);
|
|
dprintf("%s RTC Wake: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(RtcWake)]);
|
|
dprintf("%s Min Device Wake: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(MinDeviceWakeState)]);
|
|
dprintf("%s Default Wake: S%s\n",
|
|
Pad,
|
|
DumpPowerStateMappings[(ULONG) ReadField(DefaultLowLatencyWake)]);
|
|
|
|
}
|
|
|
|
DECLARE_API( pocaps )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the power capabilities
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG Flags = 0;
|
|
ULONG Result;
|
|
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (!Address) {
|
|
|
|
Address = GetExpression("nt!PopCapabilities");
|
|
if (!Address) {
|
|
|
|
dprintf("Could not read PopCapabilities\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
}
|
|
if (!Address) {
|
|
|
|
dprintf("!pocaps [addr [flags]]\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (GetFieldValue(Address,
|
|
"nt!SYSTEM_POWER_CAPABILITIES",
|
|
"PowerButtonPresent",
|
|
Result) ) {
|
|
|
|
dprintf("Could not read PopCapabilities at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
DumpPowerCapabilities( "", Address, Flags );
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpPopActionTrigger(
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
ULONG Type, PopFlags;
|
|
|
|
InitTypeRead(Address, nt!_POP_ACTION_TRIGGER);
|
|
|
|
//
|
|
// Header line
|
|
//
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%sPOP_ACTION_TRIGGER @ 0x%08p\n", Pad, Address );
|
|
|
|
}
|
|
|
|
dprintf("%s Type: ", Pad);
|
|
switch(Type = (ULONG) ReadField(Type)) {
|
|
case PolicyDeviceSystemButton:
|
|
dprintf(" SystemButton"); break;
|
|
case PolicyDeviceThermalZone:
|
|
dprintf(" ThermalZone"); break;
|
|
case PolicyDeviceBattery:
|
|
dprintf(" Battery"); break;
|
|
case PolicyInitiatePowerActionAPI:
|
|
dprintf(" InitActionAPI"); break;
|
|
case PolicySetPowerStateAPI:
|
|
dprintf(" SetStateAPI"); break;
|
|
case PolicyImmediateDozeS4:
|
|
dprintf(" DozeS4"); break;
|
|
case PolicySystemIdle:
|
|
dprintf(" SystemIdle"); break;
|
|
default:
|
|
dprintf(" Unknown"); break;
|
|
}
|
|
|
|
dprintf(" Flags: %02x%02x%02x%02x",
|
|
(ULONG) ReadField(Spare[2]),
|
|
(ULONG) ReadField(Spare[1]),
|
|
(ULONG) ReadField(Spare[0]),
|
|
(PopFlags = (ULONG) ReadField(Flags)));
|
|
if (PopFlags & PO_TRG_USER) {
|
|
|
|
dprintf(" UserAction");
|
|
|
|
}
|
|
if (PopFlags & PO_TRG_SYSTEM) {
|
|
|
|
dprintf(" SystemAction");
|
|
|
|
}
|
|
if (PopFlags & PO_TRG_SYNC) {
|
|
|
|
dprintf(" Sync");
|
|
|
|
}
|
|
if (PopFlags & PO_TRG_SET) {
|
|
|
|
dprintf(" Set");
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
if (Type != PolicyDeviceBattery) {
|
|
|
|
dprintf("%s Wait Trigger: %08p\n", Pad, ReadField(Wait ));
|
|
|
|
} else {
|
|
|
|
dprintf("%s BatteryLevel: %08lx\n", Pad, (ULONG) ReadField(Battery.Level ));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DECLARE_API( potrigger )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a Pop Action Trigger
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG Flags = 0;
|
|
ULONG Result;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (Address == 0) {
|
|
|
|
dprintf("potrigger <address>\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (GetFieldValue(Address,
|
|
"nt!_POP_ACTION_TRIGGER",
|
|
"Type",
|
|
Result) ) {
|
|
|
|
dprintf("Could not read POP_ACTION_TRIGGER at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
//
|
|
// Dump the Trigger Information
|
|
//
|
|
DumpPopActionTrigger("", Address, Flags );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpThermalZoneInformation(
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Displays the thermal zone information structure
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG i, Count;
|
|
|
|
InitTypeRead(Address, nt!_THERMAL_INFORMATION);
|
|
//
|
|
// Header line
|
|
//
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%sThermalInfo @ 0x%08p\n", Pad, Address );
|
|
|
|
}
|
|
|
|
//
|
|
// First line
|
|
//
|
|
dprintf("%s Stamp: %08lx Constant1: %08lx Constant2: %08lx\n",
|
|
Pad,
|
|
(ULONG) ReadField(ThermalStamp),
|
|
(ULONG) ReadField(ThermalConstant1),
|
|
(ULONG) ReadField(ThermalConstant2));
|
|
|
|
//
|
|
// Second Line
|
|
//
|
|
dprintf("%s Affinity: %08lx Period: %08lx ActiveCnt: %08lx\n",
|
|
Pad,
|
|
(ULONG) ReadField(Processors),
|
|
(ULONG) ReadField(SamplingPeriod),
|
|
(ULONG) ReadField(ActiveTripPointCount ));
|
|
|
|
//
|
|
// Temperatures
|
|
//
|
|
dprintf("%s Current Temperature: %08lx",
|
|
Pad,
|
|
(ULONG) ReadField(CurrentTemperature ));
|
|
DumpTemperatureInKelvins((ULONG) ReadField(CurrentTemperature));
|
|
dprintf("\n");
|
|
dprintf("%s Passive TripPoint Temperature: %08lx",
|
|
Pad,
|
|
(ULONG) ReadField(PassiveTripPoint ));
|
|
DumpTemperatureInKelvins((ULONG) ReadField(PassiveTripPoint));
|
|
dprintf("\n");
|
|
|
|
//
|
|
// Active trip points
|
|
//
|
|
Count = (ULONG) ReadField(ActiveTripPointCount);
|
|
for (i = 0; i < Count; i++) {
|
|
CHAR Buff[40];
|
|
ULONG Act;
|
|
|
|
sprintf(Buff, "ActiveTripPoint[%d]", i);
|
|
dprintf("%s Active TripPoint Temperature %d: %08lx",
|
|
Pad,
|
|
i,
|
|
(Act = (ULONG) GetShortField(0, Buff, 0)));
|
|
DumpTemperatureInKelvins(Act);
|
|
dprintf("\n");
|
|
|
|
}
|
|
|
|
//
|
|
// Dump critical temperatures
|
|
//
|
|
dprintf("%s Critical TripPoint Temperature: %08lx",
|
|
Pad,
|
|
(ULONG) ReadField(CriticalTripPoint ));
|
|
DumpTemperatureInKelvins((ULONG) ReadField(CriticalTripPoint));
|
|
dprintf("\n");
|
|
|
|
}
|
|
|
|
DECLARE_API( tzinfo )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the thermal zone information structure
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
// THERMAL_INFORMATION ThermalInfo;
|
|
ULONG64 Address = 0;
|
|
ULONG Flags = 0;
|
|
ULONG Result;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (Address == 0) {
|
|
|
|
dprintf("tzinfo <address>\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (GetFieldValue(Address,
|
|
"nt!_THERMAL_INFORMATION",
|
|
"ThermalStamp",
|
|
Result) ) {
|
|
|
|
dprintf("Could not read THERMAL_INFO at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
//
|
|
// Dump the thermal zone information
|
|
//
|
|
DumpThermalZoneInformation("", Address, Flags );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpThermalZone(
|
|
IN ULONG Count,
|
|
IN PCHAR Pad,
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a thermal zone
|
|
|
|
--*/
|
|
{
|
|
ULONG ThFlags, Off1, Off2, LastTemp;
|
|
|
|
InitTypeRead(Address, NT!_POP_THERMAL_ZONE);
|
|
//
|
|
// Header line
|
|
//
|
|
if (!(Flags & TZ_NO_HEADER)) {
|
|
|
|
dprintf("%s%d - ThermalZone @ 0x%08p\n", Pad, Count, Address );
|
|
|
|
}
|
|
|
|
//
|
|
// First line
|
|
//
|
|
dprintf("%s State: ",Pad);
|
|
switch ((ULONG) ReadField(State)) {
|
|
case 1: dprintf(" Read"); break;
|
|
case 2: dprintf("Set Mode"); break;
|
|
case 3: dprintf(" Active"); break;
|
|
default:dprintf("No State"); break;
|
|
}
|
|
dprintf(" Flags: %08lx", (ThFlags = (ULONG) ReadField(Flags)));
|
|
if (ThFlags & PO_TZ_THROTTLING) {
|
|
dprintf(" Throttling");
|
|
}
|
|
if (ThFlags & PO_TZ_CLEANUP) {
|
|
dprintf(" CleanUp");
|
|
}
|
|
dprintf("\n");
|
|
|
|
//
|
|
// Second Line
|
|
//
|
|
dprintf("%s Mode: ", Pad );
|
|
switch((ULONG) ReadField(Mode)) {
|
|
case 0: dprintf(" Active"); break;
|
|
case 1: dprintf(" Passive"); break;
|
|
default: dprintf(" Invalid"); break;
|
|
}
|
|
dprintf(" PendingMode: ");
|
|
switch((ULONG) ReadField(PendingMode)) {
|
|
case 0: dprintf(" Active"); break;
|
|
case 1: dprintf(" Passive"); break;
|
|
default: dprintf(" Invalid"); break;
|
|
}
|
|
dprintf("\n");
|
|
|
|
|
|
dprintf("%s ActivePoint: %08lx PendingTrp: %08lx\n",
|
|
Pad, (ULONG) ReadField(ActivePoint), (ULONG) ReadField(PendingActivePoint ));
|
|
dprintf("%s SampleRate: %08lx LastTime: %016I64x\n",
|
|
Pad, (ULONG) ReadField(SampleRate), ReadField(LastTime ));
|
|
GetFieldOffset("NT!_POP_THERMAL_ZONE", "PassiveTimer", &Off1);
|
|
GetFieldOffset("NT!_POP_THERMAL_ZONE", "PassiveDpc", &Off2);
|
|
dprintf("%s Timer: %08lx Dpc: %08lx\n",
|
|
Pad,
|
|
Address + Off1,
|
|
Address + Off2);
|
|
GetFieldOffset("NT!_POP_THERMAL_ZONE", "OverThrottled", &Off1);
|
|
dprintf("%s OverThrottled: %08lx Irp: %08p\n",
|
|
Pad,
|
|
Address + Off1,
|
|
ReadField(Irp ));
|
|
dprintf("%s Throttle: %08lx LastTemp: %08lx",
|
|
Pad,
|
|
(ULONG) ReadField(Throttle),
|
|
(LastTemp = (ULONG) ReadField(LastTemp )));
|
|
DumpTemperatureInKelvins( LastTemp );
|
|
dprintf("\n");
|
|
GetFieldOffset("NT!_POP_THERMAL_ZONE", "Info", &Off1);
|
|
dprintf("%s Thermal Info: %08lx\n",
|
|
Pad,
|
|
Address + Off1);
|
|
if (Flags & TZ_DUMP_INFO) {
|
|
|
|
CHAR buffer[80];
|
|
|
|
//
|
|
// Increase the buffer
|
|
//
|
|
sprintf(buffer," %s", Pad );
|
|
|
|
//
|
|
// Dump the thermal zone
|
|
//
|
|
DumpThermalZoneInformation(
|
|
buffer,
|
|
(Address + Off1),
|
|
(Flags | TZ_NO_HEADER)
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
DECLARE_API( tz )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
args -
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG Count = 0;
|
|
ULONG64 EndAddress = 0, Flink;
|
|
ULONG Flags = 0;
|
|
ULONG Result;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (Address == 0) {
|
|
|
|
Address = GetExpression("nt!PopThermal");
|
|
if (!Address) {
|
|
|
|
dprintf("Could not read PopThermal\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (GetFieldValue(Address,
|
|
"nt!_LIST_ENTRY",
|
|
"Flink",
|
|
Flink) ) {
|
|
|
|
dprintf("Could not read PopThermal at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
if (Flink == Address) {
|
|
|
|
dprintf("No Thermal Zones\n");
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
Flags |= TZ_LOOP;
|
|
EndAddress = Address;
|
|
Address = Flink;
|
|
|
|
} else {
|
|
|
|
EndAddress = Address;
|
|
|
|
}
|
|
|
|
//
|
|
// Now read the proper thermal zone
|
|
//
|
|
if (GetFieldValue(Address,
|
|
"nt!_LIST_ENTRY",
|
|
"Flink",
|
|
Flink) ) {
|
|
|
|
dprintf("Could not read LIST_ENTRY at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
//
|
|
// Do we stop looping?
|
|
//
|
|
if (!Flags & TZ_LOOP) {
|
|
|
|
EndAddress = Flink;
|
|
|
|
}
|
|
|
|
do {
|
|
|
|
//
|
|
// Read the thermal zone
|
|
// Try both names for backward compatibility
|
|
//
|
|
if (GetFieldValue(Address, "NT!_POP_THERMAL_ZONE", "Link.Flink", Flink) &&
|
|
GetFieldValue(Address, "NT!POP_THERMAL_ZONE", "Link.Flink", Flink)) {
|
|
dprintf("Could not read THERMAL_ZONE at %08p\n", Address );
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
//
|
|
// Dump the zone
|
|
//
|
|
DumpThermalZone( Count, "", Address, Flags );
|
|
|
|
//
|
|
// Check for Control C
|
|
//
|
|
if (CheckControlC()) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
//
|
|
// Next
|
|
//
|
|
Address = Flink;
|
|
Count++;
|
|
|
|
} while (Address != EndAddress );
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpPopIdleHandler(
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
CHAR FunctionName[256];
|
|
ULONG64 Offset;
|
|
|
|
if (InitTypeRead(Address,nt!_POP_IDLE_HANDLER)) {
|
|
// If the new type name fails, use the old one
|
|
InitTypeRead(Address,nt!POP_IDLE_HANDLER);
|
|
}
|
|
|
|
dprintf("PopIdleHandle[%d] - POP_IDLE_HANDLER %p\n",(ULONG)ReadField(State),Address);
|
|
dprintf(" State: %8d PromoteCount: %8d\n",
|
|
(ULONG)ReadField(State),
|
|
(ULONG)ReadField(PromoteCount)
|
|
);
|
|
dprintf(" DemotePercent: %8d%% PromotePercent: %8d%%\n",
|
|
(ULONG)ReadField(DemotePercent),
|
|
(ULONG)ReadField(PromotePercent)
|
|
);
|
|
dprintf(" Demote: %8d Promote: %8d\n",
|
|
(ULONG)ReadField(Demote),
|
|
(ULONG)ReadField(Promote)
|
|
);
|
|
dprintf("\n");
|
|
GetSymbol(ReadField(IdleFunction), FunctionName, &Offset);
|
|
dprintf(" Function: %27s (%p)\n",
|
|
FunctionName,
|
|
ReadField(IdleFunction)
|
|
);
|
|
dprintf(" Latency: %27s (%8x)\n",
|
|
DumpPerformanceCounterInStandardForm( (ULONG)ReadField(Latency) ),
|
|
(ULONG)ReadField(Latency)
|
|
);
|
|
dprintf(" TimeCheck: %27s (%8x)\n",
|
|
DumpPerformanceCounterInStandardForm( (ULONG)ReadField(TimeCheck) ),
|
|
(ULONG)ReadField(TimeCheck)
|
|
);
|
|
dprintf(" PromoteLimit: %27s (%8x)\n",
|
|
DumpPerformanceCounterInStandardForm( (ULONG)ReadField(PromoteLimit) ),
|
|
(ULONG)ReadField(PromoteLimit)
|
|
);
|
|
dprintf(" DemoteLimit: %27s (%8x)\n",
|
|
DumpPerformanceCounterInStandardForm( (ULONG)ReadField(DemoteLimit) ),
|
|
(ULONG) ReadField(DemoteLimit)
|
|
);
|
|
dprintf("\n");
|
|
|
|
}
|
|
|
|
DECLARE_API( poidle )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG64 Pkprcb;
|
|
ULONG64 PowerState;
|
|
ULONG64 Size;
|
|
ULONG Loop = 3;
|
|
ULONG Flags = 0;
|
|
ULONG processor = 0;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
|
|
if (Address == 0) {
|
|
|
|
HRESULT Hr;
|
|
|
|
INIT_API();
|
|
|
|
GetCurrentProcessor(Client, &processor, NULL);
|
|
|
|
Hr = g_ExtData->ReadProcessorSystemData(processor,
|
|
DEBUG_DATA_KPRCB_OFFSET,
|
|
&Pkprcb,
|
|
sizeof(Pkprcb),
|
|
NULL);
|
|
|
|
|
|
if (Hr != S_OK) {
|
|
|
|
dprintf("Cannot get PRCB address\n");
|
|
|
|
} else {
|
|
|
|
InitTypeRead(Pkprcb,nt!_KPRCB);
|
|
PowerState = ReadField(PowerState);
|
|
if (!PowerState) {
|
|
|
|
dprintf("Unable to get PowerState from the PRCB at %p",Pkprcb);
|
|
dprintf("poproc <address>\n");
|
|
Hr = E_INVALIDARG;
|
|
|
|
}
|
|
|
|
}
|
|
if (Hr != S_OK){
|
|
|
|
return Hr;
|
|
|
|
}
|
|
|
|
if (GetFieldValue( PowerState,
|
|
"PROCESSOR_POWER_STATE",
|
|
"IdleHandlers",
|
|
Address) ) {
|
|
|
|
dprintf("Could not read PROCESSOR_POWER_STATE at %p\n", PowerState );
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
Loop = 3;
|
|
|
|
}
|
|
|
|
//
|
|
// We will need to know how large the structure is..
|
|
//
|
|
Size = GetTypeSize("nt!_POP_IDLE_HANDLER");
|
|
if (!Size) {
|
|
Size = GetTypeSize("nt!POP_IDLE_HANDLER");
|
|
}
|
|
|
|
do {
|
|
|
|
DumpPopIdleHandler( Address, Flags );
|
|
Address += Size;
|
|
if (CheckControlC() || !Loop) {
|
|
break;
|
|
}
|
|
Loop--;
|
|
|
|
} while ( Loop );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
DumpProcessorPerfState(
|
|
IN ULONG64 Address,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Value = 0;
|
|
|
|
InitTypeRead(Address,nt!PROCESSOR_PERF_STATE);
|
|
dprintf(
|
|
" Power: %4dmW",
|
|
(ULONG)ReadField(Power)
|
|
);
|
|
Value = ReadField(Flags);
|
|
if (Value) {
|
|
dprintf(" NonLinear\n");
|
|
} else {
|
|
dprintf(" Linear\n");
|
|
}
|
|
dprintf(
|
|
" Frequency: %8d%% MinCapacity: %8d%%\n",
|
|
(ULONG)ReadField(PercentFrequency),
|
|
(ULONG)ReadField(MinCapacity)
|
|
);
|
|
dprintf(
|
|
" IncreaseLevel: %8d%% DecreaseLevel: %8d%%\n",
|
|
(ULONG)ReadField(IncreaseLevel),
|
|
(ULONG)ReadField(DecreaseLevel)
|
|
);
|
|
dprintf(
|
|
" IncreaseCount: %8x DecreaseCount: %8x\n",
|
|
(ULONG)ReadField(IncreaseCount),
|
|
(ULONG)ReadField(DecreaseCount)
|
|
);
|
|
dprintf(
|
|
" PerformanceTime: %21s (%8x)\n",
|
|
DumpPerformanceCounterInStandardForm( ReadField(PerformanceTime) ),
|
|
ReadField(PerformanceTime)
|
|
);
|
|
dprintf(
|
|
" IncreaseTime: %21s (%8x)\n",
|
|
DumpTimeInStandardForm( (ULONG) ReadField(IncreaseTime) ),
|
|
ReadField(IncreaseTime)
|
|
);
|
|
dprintf(
|
|
" DecreaseTime: %21s (%8x)\n",
|
|
DumpTimeInStandardForm( (ULONG) ReadField(DecreaseTime) ),
|
|
ReadField(DecreaseTime)
|
|
);
|
|
|
|
}
|
|
|
|
DECLARE_API( poperf )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
ULONG64 Address = 0;
|
|
ULONG64 Count = 1;
|
|
ULONG64 Index;
|
|
ULONG64 PolicyAddress;
|
|
ULONG64 Size = 0;
|
|
ULONG Flags = 0;
|
|
ULONG Processor;
|
|
ULONG Prcb;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
if (GetExpressionEx(args, &Address, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
if (Address == 0) {
|
|
|
|
HRESULT Hr;
|
|
|
|
INIT_API();
|
|
|
|
//
|
|
// Fetch them from the current processor's prcb
|
|
//
|
|
GetCurrentProcessor(Client, &Processor, NULL);
|
|
|
|
Hr = g_ExtData->ReadProcessorSystemData(
|
|
Processor,
|
|
DEBUG_DATA_KPRCB_OFFSET,
|
|
&Address,
|
|
sizeof(Address),
|
|
NULL
|
|
);
|
|
if (Hr != S_OK) {
|
|
|
|
dprintf("Unable to get PRCB address\n");
|
|
return Hr;
|
|
|
|
}
|
|
|
|
InitTypeRead(Address,nt!_KPRCB);
|
|
PolicyAddress = ReadField(PowerState.PerfStates);
|
|
Count = ReadField(PowerState.PerfStatesCount);
|
|
|
|
//
|
|
// Remember what's the address we will use
|
|
//
|
|
Address = PolicyAddress;
|
|
dprintf("Prcb.PowerState.PerfStates - %p (%d Levels)\n", Address, (ULONG) Count );
|
|
|
|
} else {
|
|
|
|
dprintf("PROCESSOR_PERF_STATE - %p\n",Address);
|
|
|
|
}
|
|
|
|
//
|
|
// We will need to know how large the structure is..
|
|
//
|
|
Size = GetTypeSize("nt!PROCESSOR_PERF_STATE");
|
|
|
|
//
|
|
// Dump all the states
|
|
//
|
|
for (Index = 0; Index < Count; Index++, Address += Size) {
|
|
|
|
DumpProcessorPerfState( Address, Flags );
|
|
if (CheckControlC()) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Done
|
|
//
|
|
return S_OK;
|
|
}
|
|
|
|
DECLARE_API( whattime )
|
|
{
|
|
ULONG64 Address = 0;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
GetExpressionEx(args, &Address, &args);
|
|
|
|
dprintf(
|
|
"%d Ticks in Standard Time: %s\n",
|
|
(ULONG) Address,
|
|
DumpTimeInStandardForm( (ULONG) Address )
|
|
);
|
|
return S_OK;
|
|
}
|
|
|
|
DECLARE_API( whatperftime )
|
|
{
|
|
ULONG64 Address = 0;
|
|
|
|
//
|
|
// Get address and flags
|
|
//
|
|
GetExpressionEx(args, &Address, &args);
|
|
|
|
dprintf(
|
|
"%ld Performance Counter in Standard Time: %s\n",
|
|
(ULONG) Address,
|
|
DumpPerformanceCounterInStandardForm( Address )
|
|
);
|
|
return S_OK;
|
|
}
|