PpmIdleExecuteTransition
VOID __stdcall PpmIdleExecuteTransition(
_KPRCB *Prcb,
UINT64 TargetProcessorState,
UINT64 TargetPlatformState,
UINT8 DeepSleepEnabled,
UINT64 EnterTime,
UINT64 InterruptTime,
UINT8 SynchronizedTransition){
_PPM_IDLE_STATES *IdleStates;
unsigned __int16 v8;
UINT64 v10;
int v11;
_KAFFINITY_EX *p_SecondaryProcessorMask;
unsigned int DependencyUsed;
_PROCESSOR_IDLE_DEPENDENCY *DependencyArray;
unsigned int v15;
unsigned __int8 *p_ExpectedState;
UINT64 v17;
_KPRCB *v18;
unsigned __int64 v19;
unsigned __int64 v20;
unsigned int v21;
unsigned __int64 v22;
_KPRCB *v23;
_PPM_IDLE_STATES *v24;
unsigned __int8(__fastcall *IdleIsHalted)(void *);
void *v26;
unsigned __int8 v27;
unsigned int v28;
unsigned __int16 Count;
char v30;
char v31;
bool v32;
_PROC_PERF_CONSTRAINT *Constraint;
unsigned __int64 v34;
unsigned __int64 QosTransitionHysteresis;
_KPRCBFLAG v36;
__int32 v37;
_KPRCBFLAG v38;
UINT8 v39;
unsigned int v40;
__int64 v41;
__int64 v42;
unsigned __int64 v43;
unsigned __int64 MaxIdleDuration;
int v45;
unsigned __int64 GroupSetMember;
_KNODE *ParentNode;
INT64 v48;
_PPM_IDLE_STATES *v49;
char v50;
unsigned int v51;
INT64 v52;
int v53;
unsigned __int64 *Bitmap;
__int64 v55;
unsigned __int64 v56;
unsigned int ExitLatencyCountdown;
unsigned int v58;
unsigned int ExitSamplingCountdown;
char v60;
int v61;
volatile int DpcQueueDepth;
unsigned __int64 v63;
__int64 Group;
__int64 v65;
unsigned int v66;
__int64 v67;
_PERFINFO_PPM_STATE_SELECTION *CoordinatedTracing;
int v69;
UINT8 v70;
struct _KPRCB *CurrentPrcb;
int v72;
int v73;
int v74;
_PPM_CONCURRENCY_ACCOUNTING *v75;
_PPM_CONCURRENCY_ACCOUNTING *ClassConcurrency;
unsigned __int64 v77;
unsigned __int64 v78;
unsigned __int64 v79;
unsigned __int64 CyclesLast;
unsigned __int128 v81;
unsigned __int64 v82;
void *v83;
__int64 v84;
int(__fastcall *IdlePreExecute)(void *, unsigned int, unsigned int, unsigned int, unsigned int *);
unsigned int v86;
unsigned int *Selection;
__int64 v88;
__int64 v89;
__int64 v90;
int v91;
char v92;
__int64 v93;
__int32 v94;
__int32 v95;
__int64 v96;
struct _KPRCB *v97;
__int64 Number;
unsigned __int64 v99;
unsigned __int64 v100;
unsigned __int64 v101;
unsigned __int8 BpbCurrentSpecCtrl;
unsigned __int8 v103;
__int16 v104;
unsigned __int8 v105;
_KPRCB *PairPrcb;
signed __int16 PairRegister;
__int64 v108;
signed __int16 v109;
unsigned __int8 v110;
volatile unsigned __int8 v111;
__int64 v112;
unsigned __int64 v113;
unsigned __int64 v114;
INT64 v115;
__int64 v116;
__int64 v117;
__int64 v118;
int v119;
unsigned __int64 v120;
__int64 v121;
__int64 v122;
unsigned __int64 v123;
__int64 v124;
UINT64 v125;
__int64 v126;
__int64 v127;
volatile unsigned __int64 QpcBias;
bool v129;
__int64 v130;
__int64 v131;
int v132;
unsigned __int64 v133;
__int64 v134;
__int64 v135;
unsigned __int64 v136;
__int64 v137;
UINT64 v138;
bool v139;
__int64 v140;
_PROC_FEEDBACK_COUNTER **Counters;
INT64 v142;
unsigned __int64 v143;
unsigned __int64 v144;
UINT8 v145;
NTSTATUS v146;
int v147;
UINT64 *p_TraceFlags;
INT64 v149;
PPM_COORDINATED_SELECTION *v150;
unsigned int *v151;
unsigned __int64 v152;
unsigned __int16 v153;
unsigned int v154;
unsigned __int64 v155;
unsigned int v156;
_KPRCB *v157;
_PPM_IDLE_STATES *v158;
unsigned __int32 AsLong;
unsigned __int32 v160;
int v161;
int v162;
_KPRCB *v163;
__int64 v164;
int v165;
signed __int32 v166[8];
INT64 a5;
UINT64 ExitTime;
UINT8 DeepSleepEnableda[8];
INT64 a9;
int v171;
volatile unsigned __int8 DeepSleep;
UINT8 v173;
char v174;
unsigned __int8 v175;
UINT8 v176;
char v177;
char v178;
UINT64 PlatformState;
_PPM_IDLE_STATES *v180;
INT64 Status;
unsigned int StateIndex;
int StateIndex_4;
INT64 v184;
int v185;
UINT64 v186;
int v187;
_PPM_CONCURRENCY_ACCOUNTING *Concurrency;
_KAFFINITY_EX *v189;
UINT64 TraceFlags;
void *Context;
_KAFFINITY_EX *v192;
unsigned __int64 v193;
unsigned __int16 v194;
int v195;
__int16 v196;
int v197;
int v198;
__int64 v199;
__int64 v200;
UINT64 FromFrequency;
__int64 v202;
unsigned __int64 v203;
PPM_COORDINATED_SELECTION *CoordinatedSelection;
_KPRCB *Prcba;
_PPM_SELECTION_MENU Menu;
__int128 v207;
__int64 v208;
__int128 v209;
__int128 v210;
__int128 v211;
__int128 v212;
INT64 v213[2];
__int128 v214;
__int128 v215;
__int128 v216;
__int128 v217;
__int128 v218;
__int128 v219;
__int128 v220;
__int64 v221;
_KAFFINITY_EX Affinity2;
_KAFFINITY_EX Affinity;
int v224;
char v225;
IdleStates = Prcb->PowerState.IdleStates;
v8 = 0;
v221 = 0i64;
DeepSleep = 0;
v174 = 0;
LOBYTE(v187) = 0;
v10 = 0i64;
LOBYTE(StateIndex_4) = 0;
v11 = 0;
v177 = 0;
v175 = 0;
Context = IdleStates->PrepareInfo.Context;
Prcba = Prcb;
*(_OWORD *)v213 = 0i64;
v214 = 0i64;
CoordinatedSelection = &IdleStates->CoordinatedSelection;
v203 = DeepSleepEnabled;
StateIndex = TargetPlatformState;
LODWORD(PlatformState) = TargetProcessorState;
LODWORD(Concurrency) = 0;
v186 = 0i64;
v184 = 7i64;
LODWORD(TraceFlags) = -1;
v180 = IdleStates;
v199 = (__int64)IdleStates + 248 * (unsigned int)TargetProcessorState;
v178 = 0;
LODWORD(Status) = 0;
v215 = 0i64;
v216 = 0i64;
v217 = 0i64;
v218 = 0i64;
v219 = 0i64;
v220 = 0i64;
if( !v225
|| IdleStates->PrepareInfo.Constraints.Interruptible
|| IdleStates->State[(unsigned int)TargetProcessorState].WakesSpuriously )
{
v173 = 0;
v176 = 3;
}
else
{
v173 = 1;
v176 = 4;
}
v185 = 3;
if( !IdleStates->InterfaceVersion )
{
if( v225 )
PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, 1u);
p_SecondaryProcessorMask = &IdleStates->SecondaryProcessorMask;
v189 = &IdleStates->SecondaryProcessorMask;
*(_QWORD *)&IdleStates->SecondaryProcessorMask.Count = 1310721i64;
memset(IdleStates->SecondaryProcessorMask.Bitmap, 0i64, sizeof(IdleStates->SecondaryProcessorMask.Bitmap));
DependencyUsed = IdleStates->PrepareInfo.DependencyUsed;
DependencyArray = IdleStates->PrepareInfo.DependencyArray;
v208 = 0i64;
Menu.Entries = (_PPM_SELECTION_MENU_ENTRY *)&v207;
v15 = 0;
*(_QWORD *)&Menu.Count = 1i64;
v207 = 0i64;
LOBYTE(v207) = 1;
BYTE2(v207) = 1;
if( DependencyUsed )
{
p_ExpectedState = &DependencyArray->ExpectedState;
while( 1 )
{
if( *p_ExpectedState != 0xFF )
{
v17 = *((unsigned int *)p_ExpectedState - 1);
DWORD1(v207) = *p_ExpectedState;
v18 = KeGetPrcb(v17);
LODWORD(Status) = PpmTestAndLockProcessor(v18, p_SecondaryProcessorMask, &Menu);
v11 = Status;
if( (int)Status < 0 )
break;
}
++v15;
p_ExpectedState += 8;
if( v15 >= DependencyUsed )
goto LABEL_14;
}
}
else
{
LABEL_14:
v20 = p_SecondaryProcessorMask->Bitmap[0];
v193 = v20;
v209 = 0i64;
v195 = 0;
v210 = 0i64;
v196 = 0;
v194 = 0;
v192 = p_SecondaryProcessorMask;
LABEL_15:
while( 1 )
{
v197 = 0;
v21 = p_SecondaryProcessorMask ? p_SecondaryProcessorMask->Count : v194 + 1;
if( !v20 )
break;
LABEL_21:
_BitScanForward64(&v22, v20);
v20 &= ~(1i64 << v22);
v197 = v22;
v193 = v20;
v23 = KeGetPrcb((unsigned int)KiProcessorNumberToIndexMappingTable[64 * v194 + (unsigned __int8)v22]);
v210 = (unsigned __int64)v23;
v24 = v23->PowerState.IdleStates;
*(_QWORD *)&v209 = 0i64;
*((_QWORD *)&v209 + 1) = PopIdleTransitionTimeout;
IdleIsHalted = v24->IdleIsHalted;
v26 = v24->PrepareInfo.Context;
BYTE12(v210) = 1;
if( !IdleIsHalted(v26) )
{
while( (v23->PowerState.Synchronization.AsLong & 0xFF000000) == 83886080 )
{
PpmIdleTransitionStall((__int64)&v209);
if( v24->IdleIsHalted(v24->PrepareInfo.Context) )
{
v20 = v193;
goto LABEL_15;
}
}
v11 = -1073741782;
LODWORD(Status) = -1073741782;
goto LABEL_27;
}
}
while( 1 )
{
v19 = ++v194;
if( v194 >= v21 )
break;
v193 = p_SecondaryProcessorMask->Bitmap[v194];
v20 = v193;
if( v193 )
goto LABEL_21;
}
v11 = 0;
LODWORD(Status) = 0;
}
LABEL_27:
if( v11 < 0 )
{
if( v225 )
PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, 0);
v27 = 0;
v28 = 1;
v185 = 1;
goto LABEL_303;
}
IdleStates = v180;
}
v19 = 0i64;
Count = IdleStates->SecondaryProcessorMask.Count;
v189 = &IdleStates->SecondaryProcessorMask;
if( Count )
{
while( !IdleStates->SecondaryProcessorMask.Bitmap[(unsigned __int16)v19] )
{
LOWORD(v19) = v19 + 1;
if( (unsigned __int16)v19 >= Count )
goto LABEL_37;
}
IdleStates->ReasonFlags |= 0x20u;
}
LABEL_37:
v30 = 0;
v31 = 0;
v32 = 0;
Constraint = 0i64;
v202 = 2i64;
if( PpmPerfQosEnabled && PpmPerfQosManageIdleProcessors && Prcb->PowerState.RequestedQosClass != KHeteroCpuQosLow )
{
Constraint = Prcb->PowerState.CheckContext.Constraint;
if( Constraint && Constraint->UseQosUpdateLock )
{
v31 = 1;
_disable();
v32 = (v224 & 0x200) != 0;
KxAcquireSpinLock(&Constraint->QosUpdateLock);
}
if( (Prcb->PowerState.QosEquivalencyMask & 4) == 0 )
{
v34 = __rdtsc();
v19 = v34 - Prcb->PowerState.LastQosTranstionTsc;
QosTransitionHysteresis = Prcb->PowerState.QosTransitionHysteresis;
if( v19 < QosTransitionHysteresis && !Prcb->PowerState.LongPriorQosPeriod )
{
v36.PrcbFlags = (volatile int)Prcb->PrcbFlags;
v30 = 1;
if( (v36.PrcbFlags & 0x300) == 0 )
{
LOBYTE(v8) = 1;
v37 = v36._bf_0 & 0xFFFFFCFF | 0x200;
LABEL_52:
Prcb->PrcbFlags._bf_0 = v37;
KeUpdatePendingQosRequest((INT64)Prcb);
goto LABEL_53;
}
goto LABEL_53;
}
Prcb->PowerState.LastQosTranstionTsc = v34;
Prcb->PowerState.LongPriorQosPeriod = v19 >= 2 * QosTransitionHysteresis;
}
Prcb->PowerState.RequestedQosClass = KHeteroCpuQosLow;
PpmPerfArbitratorApplyProcessorState((INT64)Prcb, 1u, 0, 512i64);
LOBYTE(Prcb->PrcbFlags.PrcbFlags) = 2;
}
v38.PrcbFlags = (volatile int)Prcb->PrcbFlags;
if( (v38.PrcbFlags & 0x300) != 0 )
{
v37 = v38._bf_0 & 0xFFFFFCFF;
goto LABEL_52;
}
LABEL_53:
if( v31 )
{
KxReleaseSpinLock(&Constraint->QosUpdateLock);
if( v32 )
_enable();
}
if( (_BYTE)v8 )
{
v8 = 0;
v11 = -1073741802;
v28 = 0;
v185 = 0;
LODWORD(Status) = -1073741802;
if( v225 )
PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, 0);
v10 = 0i64;
v27 = 0;
goto LABEL_302;
}
v39 = v173;
v40 = PlatformState;
v41 = v199;
Prcb->PowerState.NonInterruptibleTransition = v173;
Prcb->PowerState.TargetIdleState = v40;
if( v225 )
{
Prcb->PowerState.PepWokenTransition = *(_BYTE *)(v41 + 1058) == 0;
PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, 2u);
}
v42 = (__int64)v180;
if( v30 || v180->IdleDurationLimited || v180->IdleCheckLimited )
{
v43 = -1i64;
v177 = 1;
if( v180->IdleDurationLimited )
{
MaxIdleDuration = v180->PrepareInfo.Constraints.MaxIdleDuration;
if( MaxIdleDuration <= (unsigned int)KeMaximumIncrement )
MaxIdleDuration = (unsigned int)KeMaximumIncrement;
v43 = SynchronizedTransition + (unsigned int)KeMaximumIncrement + MaxIdleDuration;
}
if( v180->IdleCheckLimited )
{
v45 = *(_DWORD *)(2736i64 * *(&stru_140C23628 + 441) + *(&stru_140C00F40 + 365) + 192);
if( v43 >= SynchronizedTransition + (unsigned __int64)(unsigned int)(10 * v45) )
v43 = SynchronizedTransition + (unsigned __int64)(unsigned int)(10 * v45);
}
if( v30 && v43 >= SynchronizedTransition + PpmPerfQosIdleExpirationTimeout )
v43 = SynchronizedTransition + PpmPerfQosIdleExpirationTimeout;
Prcb->PowerState.IdleTimeExpiration = v43;
_interlockedbittestandset64((volatile signed __int32 *)&Prcb->ParentNode->IdleConstrainedSet, Prcb->GroupIndex);
}
if( *(_BYTE *)(v41 + 1057) || v30 )
goto LABEL_135;
GroupSetMember = Prcb->GroupSetMember;
ParentNode = Prcb->ParentNode;
v174 = 1;
_m_prefetchw(&ParentNode->DeepIdleSet);
v48 = _InterlockedOr64((volatile signed __int64 *)&ParentNode->DeepIdleSet, GroupSetMember);
v49 = Prcb->PowerState.IdleStates;
v50 = 0;
v51 = StateIndex;
v52 = v48;
Status = v48;
HIDWORD(v184) = 0;
if( v39 )
{
HIDWORD(v184) = 1;
}
else if( StateIndex == -1 )
{
v53 = 0;
if( v49->SecondaryProcessorMask.Count )
{
Bitmap = v49->SecondaryProcessorMask.Bitmap;
v55 = v49->SecondaryProcessorMask.Count;
do
{
v56 = *Bitmap++;
v53 += (unsigned int)((0x101010101010101i64
* ((((v56 - ((v56 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v56 - ((v56 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v56 - ((v56 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v56 - ((v56 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24;
--v55;
}
while( v55 );
v52 = Status;
v51 = StateIndex;
v42 = (__int64)v180;
}
if( v53 != (_DWORD)KeNumberProcessors_0 - 1 )
goto LABEL_95;
v39 = v173;
HIDWORD(v184) = 2;
}
ExitLatencyCountdown = v49->ExitLatencyCountdown;
if( !ExitLatencyCountdown || (v58 = ExitLatencyCountdown - 1, (v49->ExitLatencyCountdown = v58) == 0) )
{
ExitSamplingCountdown = PpmGetExitSamplingCountdown();
v50 = 0;
v49->ExitLatencyCountdown = ExitSamplingCountdown;
if( ExitSamplingCountdown )
v50 = v60;
}
if( v50 )
{
v49->ExitLatencyTraceEnabled = 1;
if( !v39 )
{
LABEL_95:
LODWORD(Concurrency) = 1;
goto LABEL_96;
}
v49->InitiateWakeStamp = -1i64;
}
if( !v39 )
goto LABEL_95;
LABEL_96:
v61 = ((__int64(__fastcall *)(_QWORD))off_140C00740[0])((unsigned int)Concurrency);
DpcQueueDepth = Prcb->DpcData[0].DpcQueueDepth;
v11 = v61;
LODWORD(Status) = v61;
if( DpcQueueDepth )
{
v11 = -2147483631;
goto LABEL_98;
}
if( v61 < 0 )
{
LABEL_99:
if( v225 )
PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, 0);
v8 = 0;
v28 = 0;
v185 = 0;
v27 = 0;
LABEL_292:
_interlockedbittestandreset64((volatile signed __int32 *)&Prcb->ParentNode->DeepIdleSet, Prcb->GroupIndex);
if( DeepSleep && Prcb->DeepSleep )
KeWakeProcessor();
if( (_BYTE)StateIndex_4 && v11 >= 0 )
p_TraceFlags = &TraceFlags;
else
p_TraceFlags = 0i64;
KeResumeClockTimerFromIdle(p_TraceFlags);
off_140C00750();
KeAccumulateTicks(Prcb, Prcb->LastTick, KUSER_SHARED_DATA.TickCount.LowPart, 0, 0);
goto LABEL_301;
}
if( *(_BYTE *)v42 == 1 )
{
v63 = Prcb->GroupSetMember | v52;
Group = Prcb->Group;
memset(&Affinity2, 0i64, sizeof(Affinity2));
v65 = PpmPlatformStates;
if( PpmPlatformStates )
{
*(_DWORD *)&Affinity2.Count = 1310721;
memset(&Affinity2.Reserved, 0i64, 0xA4u);
if( (_WORD)Group )
Affinity2.Count = Group + 1;
Affinity2.Bitmap[Group] |= v63;
v66 = 0;
v67 = (__int64)v180;
CoordinatedTracing = v180->CoordinatedTracing;
if( CoordinatedTracing->VetoedStates )
{
while( 1 )
{
if( CoordinatedTracing->VetoReason[v66] == -1 )
{
KeIsSubsetAffinityEx(
(_KAFFINITY_EX *)(v65 + 384i64 * *(unsigned int *)(*(_QWORD *)(v67 + 784) + 24i64 * v66 + 4) + 128),
&Affinity2);
if( v69 )
{
v11 = -1073741802;
LABEL_98:
LODWORD(Status) = v11;
goto LABEL_99;
}
v67 = (__int64)v180;
}
if( ++v66 >= CoordinatedTracing->VetoedStates )
goto LABEL_112;
}
}
v42 = (__int64)v180;
}
else
{
LABEL_112:
v42 = (__int64)v180;
}
}
if( v50 )
*(_WORD *)(v42 + 48) |= 0x200u;
v70 = v173;
if( v173 )
{
v178 = 1;
_InterlockedIncrement((_DWORD *)&WheapErrorSourceTable + 235);
CurrentPrcb = KeGetCurrentPrcb();
v72 = KiClockTimerOwner;
if( (CurrentPrcb->PendingTickFlags & 1) != 0 )
{
off_140C00888[0]();
CurrentPrcb->PendingTickFlags &= ~1u;
v70 = v173;
}
if( CurrentPrcb->Number == v72 )
++dword_140C31348;
if( CurrentPrcb->ClockOwner )
CurrentPrcb->ClockOwner = 0;
}
if( *(_BYTE *)(v42 + 540) )
{
if( v50 )
{
v73 = (unsigned __int8)StateIndex_4;
if( !v70 )
v73 = 1;
StateIndex_4 = v73;
}
if( (_BYTE)EnterTime && v51 != -1 && PpmDripsStateIndex != -1 )
{
v74 = (unsigned __int8)v187;
if( *(_BYTE *)v42 == 1 )
v74 = 1;
v187 = v74;
}
KePrepareClockTimerForIdle(EnterTime, (unsigned __int8)v187, *(_QWORD *)(v42 + 520));
}
v40 = PlatformState;
LABEL_135:
v75 = Prcb->PowerState.Concurrency;
Concurrency = v75;
if( v75 )
{
PpmIdleUpdateConcurrency(v75, InterruptTime, 1u, 1u);
ClassConcurrency = Prcb->PowerState.ClassConcurrency;
if( ClassConcurrency )
PpmIdleUpdateConcurrency(ClassConcurrency, InterruptTime, 1u, 1u);
}
*(_DWORD *)(v42 + 20) = v40;
v77 = __rdtsc();
if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
{
v78 = __readmsr(0xDB2u);
v8 = 0;
}
else
{
v8 = 0;
v78 = 0i64;
}
v79 = InterruptTime - Prcb->PowerState.PerfFeedback.LastUpdateTime;
_InterlockedExchangeAdd64(&Prcb->PowerState.PerfFeedback.UnaccountedTime, v79);
if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
Prcb->PowerState.PerfFeedback.StallTime += PpmConvertTime(
v79,
v77 - Prcb->PowerState.PerfFeedback.CyclesLast,
v78 - Prcb->PowerState.PerfFeedback.StallCyclesLast);
CyclesLast = Prcb->PowerState.PerfFeedback.CyclesLast;
Prcb->PowerState.PerfFeedback.LastUpdateTime = InterruptTime;
if( v77 > CyclesLast )
Prcb->PowerState.PerfFeedback.CyclesActive += v77 - CyclesLast;
Prcb->PowerState.PerfFeedback.CyclesLast = v77;
if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
Prcb->PowerState.PerfFeedback.StallCyclesLast = v78;
PpmUpdatePerformanceFeedback(Prcb, 0, 0, 1, 0i64);
if( *(&stru_140C23628 + 764) )
(*(&stru_140C23628 + 764))(Prcb->Number, 0i64, 0i64);
v84 = (__int64)v180;
_InterlockedExchange64((volatile __int64 *)&Prcb->PowerState.IdleTimeEntry, InterruptTime);
IdlePreExecute = v180->IdlePreExecute;
if( IdlePreExecute )
{
v11 = IdlePreExecute(
Context,
PlatformState,
StateIndex,
v180->CoordinatedSelection.SelectedStates,
v180->CoordinatedSelection.Selection);
LODWORD(Status) = v11;
}
if( v11 >= 0 )
{
v86 = StateIndex;
Selection = v180->CoordinatedSelection.Selection;
LODWORD(v88) = v180->CoordinatedSelection.SelectedStates;
v175 = 1;
if( StateIndex != -1 )
{
v89 = PpmPlatformStates + 384i64 * StateIndex;
PpmEventEnterPlatformIdleState(StateIndex);
if( !qword_140C4FD80[0] && StateIndex == (_DWORD)PlatformIdleStateIndex )
_InterlockedCompareExchange64(
qword_140C4FD80,
*(signed __int64 *)&KUSER_SHARED_DATA.InterruptTime.LowPart,
0i64);
if( (_BYTE)EnterTime )
{
*(_BYTE *)(PpmPlatformStates + 56) = 1;
++*(_DWORD *)(*(_QWORD *)(PpmPlatformStates + 48) + 8i64);
}
if( *(_BYTE *)(v89 + 120) )
{
KdPowerTransitionEx(2147483652i64, 1);
KdCallPowerHandlers(PowerDeviceD3);
}
v84 = (__int64)v180;
}
for( ; (_DWORD)v88; *(_DWORD *)(v90 + 320) = v91 & 0xF8FFFFFF | 0x4000000 )
{
v88 = (unsigned int)(v88 - 1);
v90 = PpmPlatformStates + 384i64 * Selection[v88];
*(_QWORD *)(v90 + 328) = InterruptTime;
v91 = *(_DWORD *)(v90 + 320);
if( !*(_DWORD *)(PpmPlatformStates + 4) )
v91 ^= ((unsigned __int16)v91 ^ (unsigned __int16)KeGetPcr()->Prcb.Number) & 0xFFF;
}
if( v86 != -1 )
*(_WORD *)(v84 + 48) |= 0x10u;
v212 = 0i64;
if( v225 )
PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, v176);
if( v174 )
{
DeepSleep = 0;
if( *(_BYTE *)(v199 + 1056) >= 2u )
{
v92 = byte_140C10DE0;
v211 = 0i64;
if( byte_140C10DE0 == -1 )
{
v93 = __cpuid(1, 0);
v92 = 0;
*(_QWORD *)&v211 = __PAIR64__(EBX(v93), EAX(v93));
*((_QWORD *)&v211 + 1) = __PAIR64__(EDX(v93), ECX(v93));
if( (SDWORD2(v211) & 0x80000000) != 0 )
{
v92 = 0;
v96 = __cpuid(1073741825, 0);
v95 = ECX(v96);
v94 = EDX(v96);
*(_QWORD *)&v211 = __PAIR64__(EBX(v96), EAX(v96));
if( (_DWORD)v211 == 1986945624 )
v92 = 1;
*((_QWORD *)&v211 + 1) = __PAIR64__(v94, v95);
}
byte_140C10DE0 = v92;
}
if( !v92 )
{
v97 = KeGetCurrentPrcb();
if( v97->CpuVendor == 1 )
{
DeepSleep = 0;
}
else
{
Number = v97->Number;
v97->DeepSleep = 1;
_InterlockedOr64(
(volatile signed __int64 *)(8i64 * ((unsigned int)KiProcessorIndexToNumberMappingTable[Number] >> 6)
+ 12759400
+ 0x140000000i64),
1i64 << (KiProcessorIndexToNumberMappingTable[Number] & 0x3F));
if( !v97->DeepSleep )
{
_InterlockedAnd64(
(volatile signed __int64 *)(8i64
* ((unsigned int)KiProcessorIndexToNumberMappingTable[v97->Number] >> 6)
+ 12759400
+ 0x140000000i64),
~(1i64 << (KiProcessorIndexToNumberMappingTable[v97->Number] & 0x3F)));
if( KiFlushPcid )
{
v99 = __readcr3();
__writecr3(v99);
if( !KeGetCurrentThread()->ApcState.Process->Pcb.AddressPolicy )
KiSetUserTbFlushPending();
}
else
{
v100 = __readcr4();
if( (v100 & 0x20080) != 0 )
{
__writecr4(v100 ^ 0x80);
__writecr4(v100);
}
else
{
v101 = __readcr3();
__writecr3(v101);
}
}
}
DeepSleep = v97->DeepSleep;
}
}
}
}
if( (Prcb->BpbFeatures & 1) != 0 && (BpbCurrentSpecCtrl = Prcb->BpbCurrentSpecCtrl) != 0 )
{
Prcb->BpbState |= 1u;
v103 = BpbCurrentSpecCtrl;
}
else
{
v103 = 0;
}
_m_prefetchw((char *)&Prcb->2 + 14);
v104 = Prcb->PairRegister & 4;
if( v104 )
{
if( (Prcb->BpbState & 1) != 0 )
{
v105 = Prcb->BpbCurrentSpecCtrl;
if( (v105 & 3) == 0 )
{
v103 |= 2u;
Prcb->BpbCurrentSpecCtrl = v105 | 2;
__writemsr(0x48u, v105 | 2u);
}
}
_InterlockedOr16(&Prcb->PairRegister, 2u);
PairPrcb = Prcb->PairPrcb;
_m_prefetchw((char *)&PairPrcb->2 + 14);
do
PairRegister = PairPrcb->PairRegister;
while( PairRegister != _InterlockedCompareExchange16(
&PairPrcb->PairRegister,
PairRegister & 0xFFE4 | 0xA,
PairRegister) );
}
v108 = (__int64)v180;
LODWORD(Status) = v180->IdleExecute(
Context,
v203,
PlatformState,
v86,
v103,
v180->CoordinatedSelection.SelectedStates,
v180->CoordinatedSelection.Selection);
v11 = Status;
if( v104 )
{
*((_QWORD *)&v81 + 1) = Prcb->PairPrcb;
_m_prefetchw((const void *)(*((_QWORD *)&v81 + 1) + 254i64));
do
v109 = *(_WORD *)(*((_QWORD *)&v81 + 1) + 254i64);
while( v109 != _InterlockedCompareExchange16(
(volatile signed __int16 *)(*((_QWORD *)&v81 + 1) + 254i64),
v109 & 0xFFF5 | 2,
v109) );
if( (Prcb->PairRegister & 0x10) == 0 )
{
v110 = Prcb->BpbCurrentSpecCtrl;
if( (v110 & 2) != 0 )
{
Prcb->BpbCurrentSpecCtrl = v110 & 0xFD;
*((_QWORD *)&v81 + 1) = 0i64;
__writemsr(0x48u, v110 & 0xFD);
}
}
}
Prcb->BpbState &= ~1u;
if( DeepSleep )
{
v111 = Prcb->DeepSleep;
DeepSleep = 0;
if( v111 )
{
*(_QWORD *)&v81 = KeGetCurrentPrcb();
v82 = 0x140000000ui64;
v112 = *(unsigned int *)(v81 + 36);
*(_BYTE *)(v81 + 32410) = 0;
*((_QWORD *)&v81 + 1) = (unsigned int)KiProcessorIndexToNumberMappingTable[v112];
_InterlockedAnd64(
(volatile signed __int64 *)&KeSleepingProcessors.Bitmap[(unsigned __int64)DWORD2(v81) >> 6],
~(1i64 << (KiProcessorIndexToNumberMappingTable[v112] & 0x3F)));
v113 = __readcr4();
if( (v113 & 0x20080) != 0 )
{
__writecr4(v113 ^ 0x80);
__writecr4(v113);
}
else
{
v114 = __readcr3();
__writecr3(v114);
}
}
}
if( *(int *)(v108 + 64) < 0 )
{
if( v11 >= 0 )
v11 = *(_DWORD *)(v108 + 64);
LODWORD(Status) = v11;
}
v200 = 0i64;
}
v115 = HalpPerformanceCounter;
if( *(_DWORD *)(HalpPerformanceCounter + 228) != 5 )
{
v129 = *(_DWORD *)(HalpPerformanceCounter + 220) == 64;
FromFrequency = *(_QWORD *)(HalpPerformanceCounter + 192);
if( v129 )
{
if( (*(_DWORD *)(HalpPerformanceCounter + 224) & 0x10000) != 0 )
v137 = *(_QWORD *)(HalpPerformanceCounter + 72)
+ *(_DWORD *)(HalpPerformanceCounter + 80) * KeGetPcr()->Prcb.Number;
else
v137 = *(_QWORD *)(HalpPerformanceCounter + 72);
*(_QWORD *)&v81 = (*(__int64(__fastcall **)(__int64))(HalpPerformanceCounter + 112))(v137);
QpcBias = *(_QWORD *)(v115 + 208);
*((_QWORD *)&v81 + 1) = v81;
}
else
{
do
{
QpcBias = *(_QWORD *)(v115 + 208);
do
{
v130 = *(_QWORD *)(v115 + 200);
HalpTimerGetInternalData((_KDPC *)v115, *((PVOID *)&v81 + 1), (PVOID)v82, v83);
v82 = (*(__int64(__fastcall **)(__int64))(v115 + 112))(v131);
_InterlockedOr(v166, 0);
*(_QWORD *)&v81 = *(_QWORD *)(v115 + 200);
}
while( v130 != (_QWORD)v81 );
}
while( QpcBias != *(_QWORD *)(v115 + 208) );
v132 = *(_DWORD *)(v115 + 220);
v133 = v130 ^ v82;
if( _bittest64((const __int64 *)&v133, (unsigned __int8)(v132 - 1)) )
{
v134 = 1i64 << v132;
v135 = -1i64;
if( v132 != 64 )
v135 = v134 - 1;
v136 = v130 & v135;
*((_QWORD *)&v81 + 1) = v82 | v130 ^ v136;
if( v82 < v136 )
*((_QWORD *)&v81 + 1) += v134;
_InterlockedCompareExchange64((volatile signed __int64 *)(v115 + 200), *((signed __int64 *)&v81 + 1), v81);
}
else if( v132 == 64 )
{
*((_QWORD *)&v81 + 1) = v82;
}
else
{
*((_QWORD *)&v81 + 1) = v82 | v130 & ~((1i64 << v132) - 1);
}
}
goto LABEL_254;
}
FromFrequency = 10000000i64;
if( HalpTimerReferencePage )
{
if( (*(_DWORD *)(HalpPerformanceCounter + 224) & 0x10000) != 0 )
v126 = *(_QWORD *)(HalpPerformanceCounter + 72)
+ *(_DWORD *)(HalpPerformanceCounter + 80) * KeGetPcr()->Prcb.Number;
else
v126 = *(_QWORD *)(HalpPerformanceCounter + 72);
v127 = (*(__int64(__fastcall **)(__int64))(HalpPerformanceCounter + 112))(v126);
QpcBias = KUSER_SHARED_DATA.QpcBias;
v81 = (unsigned __int64)v127 * (unsigned __int128)*((unsigned __int64 *)HalpTimerReferencePage + 1);
LABEL_254:
v125 = *((_QWORD *)&v81 + 1) + QpcBias;
v186 = v125;
goto LABEL_255;
}
if( *(_DWORD *)(HalpPerformanceCounter + 220) == 64 )
{
HalpTimerGetInternalData((_KDPC *)HalpPerformanceCounter, *((PVOID *)&v81 + 1), (PVOID)v82, v83);
*(_QWORD *)&v81 = (*(__int64(__fastcall **)(__int64))(v115 + 112))(v124);
v116 = *(_QWORD *)(v115 + 208);
*((_QWORD *)&v81 + 1) = v81;
}
else
{
do
{
v116 = *(_QWORD *)(v115 + 208);
do
{
v117 = *(_QWORD *)(v115 + 200);
HalpTimerGetInternalData((_KDPC *)v115, *((PVOID *)&v81 + 1), (PVOID)v82, v83);
v82 = (*(__int64(__fastcall **)(__int64))(v115 + 112))(v118);
_InterlockedOr(v166, 0);
*(_QWORD *)&v81 = *(_QWORD *)(v115 + 200);
}
while( v117 != (_QWORD)v81 );
}
while( v116 != *(_QWORD *)(v115 + 208) );
v119 = *(_DWORD *)(v115 + 220);
v120 = v117 ^ v82;
if( _bittest64((const __int64 *)&v120, (unsigned __int8)(v119 - 1)) )
{
v121 = 1i64 << v119;
v122 = -1i64;
if( v119 != 64 )
v122 = v121 - 1;
v123 = v122 & v117;
*((_QWORD *)&v81 + 1) = v82 | v117 ^ v122 & v117;
if( v82 < v123 )
*((_QWORD *)&v81 + 1) += v121;
_InterlockedCompareExchange64((volatile signed __int64 *)(v115 + 200), *((signed __int64 *)&v81 + 1), v81);
}
else if( v119 == 64 )
{
*((_QWORD *)&v81 + 1) = v82;
}
else
{
*((_QWORD *)&v81 + 1) = v82 | v117 & ~((1i64 << v119) - 1);
}
}
v125 = HalpTimerScaleCounter(v116 + *((_QWORD *)&v81 + 1), *(_QWORD *)(v115 + 192), 0x989680ui64);
v186 = v125;
LABEL_255:
if( v115 != HalpOriginalPerformanceCounter && HalpOriginalPerformanceCounter )
{
v138 = *(_QWORD *)(HalpOriginalPerformanceCounter + 192);
if( *(_DWORD *)(HalpOriginalPerformanceCounter + 228) == 5 )
v138 = 10000000i64;
v125 = HalpTimerScaleCounter(v125, FromFrequency, v138);
v186 = v125;
}
_InterlockedExchange64((volatile __int64 *)&Prcb->PowerState.IdleTimeEntry, 0i64);
if( Prcb->PowerState.PerfFeedback.CounterDiscardsIdleTime )
{
_disable();
v139 = (v224 & 0x200) != 0;
KxAcquireSpinLock(&Prcb->PowerState.PerfFeedback.Lock);
v140 = 2i64;
Counters = Prcb->PowerState.PerfFeedback.Counters;
do
{
v142 = (INT64)*Counters;
if( *Counters && *(_BYTE *)(v142 + 34) )
{
PpmPerfFeedbackCounterUpdate(v142);
v140 = v202;
}
++Counters;
v202 = --v140;
}
while( v140 );
KxReleaseSpinLock(&Prcb->PowerState.PerfFeedback.Lock);
if( v139 )
_enable();
}
v143 = __rdtsc();
if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
v144 = __readmsr(0xDB2u);
else
v144 = 0i64;
Prcb->PowerState.PerfFeedback.LastUpdateTime = v125;
Prcb->PowerState.PerfFeedback.CyclesLast = v143;
if( (Prcb->FeatureBits & 0x8000000000i64) != 0 )
Prcb->PowerState.PerfFeedback.StallCyclesLast = v144;
v19 = (unsigned __int64)Concurrency;
if( Concurrency )
{
PpmIdleUpdateConcurrency(Concurrency, v125, 0, 1u);
v19 = (unsigned __int64)Prcb->PowerState.ClassConcurrency;
if( v19 )
PpmIdleUpdateConcurrency((_PPM_CONCURRENCY_ACCOUNTING *)v19, v125, 0, 1u);
}
Prcb->PowerState.IdleTimeLast = v125 - InterruptTime;
if( v225 )
{
v145 = PpmIdleSetSynchronizationState((_PPM_IDLE_SYNCHRONIZATION_STATE *)&Prcb->PowerState.Synchronization, 0);
if( v11 >= 0 && v145 != 8 && v173 )
KeBugCheckEx(0xA0u, (PVOID)0x702, (PVOID)(unsigned int)PlatformState, (PVOID)v145, Prcb);
Prcb->PowerState.PepWokenTransition = 0;
}
v27 = v175;
if( v174 )
{
if( v175
&& v11 >= 0
&& PpmPlatformStates
&& *(_BYTE *)(PpmPlatformStates + 56)
&& PpmDripsStateIndex != -1
&& *(_DWORD *)(384i64 * (unsigned int)PpmDripsStateIndex + PpmPlatformStates + 320) )
{
v146 = KeQueryWakeSource(&v184, v213);
v147 = v184;
v28 = 3;
if( v146 < 0 )
v147 = 3;
LODWORD(v184) = v147;
}
else
{
v28 = 3;
}
goto LABEL_292;
}
v28 = 3;
LABEL_301:
v10 = v186;
LABEL_302:
p_SecondaryProcessorMask = v189;
LABEL_303:
LOBYTE(v19) = 1;
((void(__fastcall *)(unsigned __int64))off_140C009A8[0])(v19);
if( v177 )
{
_interlockedbittestandreset64((volatile signed __int32 *)&Prcb->ParentNode->IdleConstrainedSet, Prcb->GroupIndex);
Prcb->PowerState.IdleTimeExpiration = -1i64;
}
v149 = v27;
v150 = CoordinatedSelection;
v171 = v184;
LOBYTE(a5) = v28 != 3;
LODWORD(Concurrency) = PpmExitCoordinatedIdle(
Prcb,
CoordinatedSelection,
v149,
(unsigned int)v11,
a5,
v10,
EnterTime,
(INT64)v213);
if( v28 == 3 )
{
v180->IdleComplete(Context, PlatformState, (unsigned int)Concurrency, v150->SelectedStates, v150->Selection);
}
else if( !v180->InterfaceVersion )
{
v180->IdleCancel(Context, v28);
}
v151 = v150->Selection;
for( LODWORD(v150) = v150->SelectedStates;
(_DWORD)v150;
*(_DWORD *)(384i64 * v151[(_QWORD)v150] + PpmPlatformStates + 320) = 0 )
{
v150 = (PPM_COORDINATED_SELECTION *)(unsigned int)((_DWORD)v150 - 1);
}
if( v178 )
_InterlockedDecrement((_DWORD *)&WheapErrorSourceTable + 235);
*(_DWORD *)&Affinity.Count = 1310721;
memset(&Affinity.Reserved, 0i64, 0xA4u);
LODWORD(v10) = KeGetPcr()->Prcb.Number;
v152 = p_SecondaryProcessorMask->Bitmap[0];
v153 = 0;
while( 1 )
{
v198 = 0;
v154 = p_SecondaryProcessorMask ? p_SecondaryProcessorMask->Count : v153 + 1;
if( !v152 )
break;
LABEL_320:
_BitScanForward64(&v155, v152);
v152 &= ~(1i64 << v155);
v198 = v155;
v156 = KiProcessorNumberToIndexMappingTable[64 * v153 + (unsigned __int8)v155];
v157 = KeGetPrcb(v156);
v158 = v157->PowerState.IdleStates;
_m_prefetchw((const void *)&v157->PowerState.Synchronization);
AsLong = v157->PowerState.Synchronization.AsLong;
do
{
v160 = AsLong;
v161 = AsLong ^ (AsLong ^ (AsLong - 1)) & 0xFFFFFF;
if( (v161 & 0xFFFFFF) == 0 )
{
if( HIBYTE(AsLong) == 5 )
{
v161 = v161 & 0xFFFFFF | 0x4000000;
}
else if( HIBYTE(AsLong) == 7 )
{
v161 = v161 & 0xFFFFFF | 0x6000000;
}
}
AsLong = _InterlockedCompareExchange(&v157->PowerState.Synchronization.AsLong, v161, AsLong);
}
while( AsLong != v160 );
if( HIBYTE(v161) == 6 )
KeAddProcessorAffinityEx(&Affinity.Count, v156);
_InterlockedAnd64(
(volatile signed __int64 *)&v158->PrimaryProcessorMask.Bitmap[(unsigned __int64)(unsigned int)KiProcessorIndexToNumberMappingTable[v10] >> 6],
~(1i64 << (KiProcessorIndexToNumberMappingTable[v10] & 0x3F)));
p_SecondaryProcessorMask = v189;
KeRemoveProcessorAffinityEx(&v189->Count, v156);
v8 = 0;
}
while( ++v153 < v154 )
{
v152 = p_SecondaryProcessorMask->Bitmap[v153];
if( v152 )
goto LABEL_320;
}
v162 = (int)Concurrency;
v163 = Prcba;
if( Affinity.Count )
{
while( !Affinity.Bitmap[v8] )
{
if( ++v8 >= Affinity.Count )
goto LABEL_335;
}
HalRequestIpi(IpiAffinity, &Affinity);
}
LABEL_335:
v164 = (__int64)v180;
v165 = Status;
if( v180->ExitLatencyTraceEnabled )
{
LODWORD(a9) = v162;
*(_DWORD *)DeepSleepEnableda = PlatformState;
LODWORD(ExitTime) = HIDWORD(v184);
LODWORD(a5) = TraceFlags;
PpmIdleCompleteExitLatencyTrace(
v163,
(unsigned int)Status,
v173,
v186,
a5,
ExitTime,
*(UINT64 *)DeepSleepEnableda,
a9);
}
*(_DWORD *)(v164 + 68) = v185;
*(_DWORD *)(v164 + 64) = v165;
}Referenced by:
PoIdle