KeClockInterruptNotify
VOID __stdcall KeClockInterruptNotify(_KTRAP_FRAME *TrapFrame, UINT8 PreviousIrql){
struct _KPRCB *CurrentPrcb;
__int64 *v5;
UINT64 v6;
UINT64 v7;
int v8;
char v9;
int v10;
INT8 v11;
__int64 v12;
__int64 *v13;
bool v14;
unsigned __int8 CurrentIrql;
unsigned __int8 v16;
__int64 v17;
__int64 v18;
struct _KPRCB *v19;
__int16 v20;
unsigned int LowPart;
UINT64 v22;
unsigned __int64 *v23;
INT64 v24;
INT64 v25;
INT64 v26;
_KHETERO_CPU_POLICY v27;
_KNODE *v28;
int v29;
unsigned __int64 v30;
unsigned __int8 v31;
struct _KPRCB *v32;
bool v33;
unsigned int v34;
CHAR v35;
__int64 v36;
char v37;
unsigned __int64 v38;
unsigned __int8 v39;
UINT64 *PreferredSetOut;
UINT64 *AvailableSetOut;
UINT64 SpinCount;
UINT64 IdealSetOut;
INT64 a2;
INT64 v45;
UINT64 v46;
UINT64 v47;
__int64 CurrentQpc[2];
int v49;
char v50;
v45 = 0i64;
CurrentPrcb = KeGetCurrentPrcb();
v5 = 0i64;
CurrentQpc[0] = 0i64;
v50 = 0;
a2 = 0i64;
if( KiForceIdleDisabled )
{
LABEL_16:
v11 = TrapFrame->SegCs & 1;
if( *((_BYTE *)CurrentPrcb + 33) )
{
v12 = 3i64 * (unsigned int)KiClockTickTraceIndex;
KiClockTickTraceIndex = ((_BYTE)KiClockTickTraceIndex + 1) & 0xF;
v13 = &KiClockTickTraces[v12];
v14 = KiClockOwnerOneShotRequestState == 1;
v13[1] = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
if( v14 )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(0xFui64);
KiClockOwnerOneShotRequestState = 2;
KiClockOwnerOneShotRequest = 0i64;
__writecr8(CurrentIrql);
}
KiUpdateTime(v11, PreviousIrql);
if( KiClockOwnerOneShotRequestState == 2 )
{
v16 = KeGetCurrentIrql();
__writecr8(0xFui64);
KiSetClockIntervalToMinimumRequested();
__writecr8(v16);
}
*v13 = KUSER_SHARED_DATA.BaselineInterruptTimeQpc;
v17 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
if( KiClockState == 2 )
{
KiRestoreClockTickRate(*(INT64 *)&KUSER_SHARED_DATA.InterruptTime.LowPart, &a2);
_InterlockedExchange(&KiClockState, 0);
KiEventClockStateChange();
}
v18 = v17 + (unsigned int)KeTimeIncrement;
v13[2] = v17;
KiClockTimerNextTickTime = v18;
goto LABEL_83;
}
v19 = KeGetCurrentPrcb();
v20 = v49;
++*((_DWORD *)v19 + 3150);
++*((_DWORD *)v19 + 2920);
_disable();
LowPart = KUSER_SHARED_DATA.TickCount.LowPart;
if( (v20 & 0x200) != 0 )
_enable();
KeAccumulateTicks(v19, *((unsigned int *)v19 + 3149), KUSER_SHARED_DATA.TickCount.LowPart, PreviousIrql, v11);
v26 = *((_QWORD *)v19 + 1);
*((_DWORD *)v19 + 7928) = 1;
if( v26 != *((_QWORD *)v19 + 3) )
{
if( *(_QWORD *)(v26 + 72) >= *(_QWORD *)(v26 + 32) )
goto LABEL_69;
v27 = *(unsigned __int8 *)(v26 + 125);
v46 = 0i64;
IdealSetOut = 0i64;
v47 = 0i64;
if( v27 )
{
if( (unsigned int)v27 >= KHeteroCpuPolicyDynamic )
v27 = KiConvertDynamicHeteroPolicy((_KTHREAD *)v26, (_KHETERO_CPU_POLICY)v22, v19);
v28 = (_KNODE *)*((_QWORD *)v19 + 24);
KiGenerateHeteroSets(v28, *(_QWORD *)(v26 + 576), v27, &IdealSetOut, &v47, &v46);
if( (v46 & *((_QWORD *)v19 + 25)) == 0
|| KiIsQosGroupingActive()
&& (v22 & v24) != 0
&& (unsigned int)(unsigned __int8)*(_DWORD *)(v26 + 512) - 1 <= 1
&& (v22 & *((_QWORD *)v19 + 25)) == 0 )
{
goto LABEL_69;
}
if( (IdealSetOut & *((_QWORD *)v19 + 25)) == 0 )
{
v22 = IdealSetOut;
if( (v24 & v28->IdleSmtSet) != 0 )
v24 &= v28->IdleSmtSet;
if( (v24 & IdealSetOut) != 0 )
goto LABEL_69;
v22 = v24 & v47 & ~IdealSetOut;
if( (unsigned int)(v27 - 3) <= 1 )
v25 = *((unsigned __int8 *)v19 + 33210);
else
v25 = *((unsigned __int8 *)v19 + 33209);
if( v22 )
{
v29 = v28->Affinity.Group << 6;
do
{
_BitScanReverse64(&v30, v22);
HIDWORD(SpinCount) = v30;
v24 = (INT64)*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[(unsigned int)(v29 + v30)]);
v31 = (unsigned int)(v27 - 3) <= 1 ? *(_BYTE *)(v24 + 33210) : *(_BYTE *)(v24 + 33209);
if( v31 > (unsigned __int8)v25 )
goto LABEL_69;
v22 &= ~*(_QWORD *)(v24 + 200);
}
while( v22 );
}
}
}
v32 = KeGetCurrentPrcb();
v23 = (unsigned __int64 *)*((unsigned int *)v32 + 59);
if( ((unsigned __int16)v23 & 0x300) != 0 )
{
_disable();
v23 = (unsigned __int64 *)*((unsigned int *)v32 + 59);
v22 = *(unsigned int *)(v26 + 512);
v24 = *((_DWORD *)v32 + 59) & 0xFFFFFCFF;
v33 = (v20 & 0x200) != 0;
if( (unsigned __int8)v23 != *(_BYTE *)(v26 + 512) )
{
v34 = v24 | ((*(_DWORD *)(v26 + 512) & 3) << 8);
*((_DWORD *)v32 + 59) = v34;
v35 = PoSetProcessorQoS((INT64)v32, (v34 >> 8) & 3, v24, v25);
v24 = *((unsigned int *)v32 + 59);
if( !v35 )
{
LABEL_55:
if( (v24 & 0x300) == 0 )
KeUpdatePendingQosRequest((INT64)v32);
if( v33 )
_enable();
goto LABEL_61;
}
v24 = (unsigned int)v24 & 0xFFFFFCFF;
}
*((_DWORD *)v32 + 59) = v24;
goto LABEL_55;
}
if( (unsigned __int8)v23 != *(_BYTE *)(v26 + 512) )
KeCheckAndApplyBamQos((INT64)v32, v26, v24, v25);
}
LABEL_61:
if( KUSER_SHARED_DATA.TickCountQuad <= *((_QWORD *)v19 + 4203) )
{
v36 = *(_QWORD *)(v26 + 104);
if( !v36 || (v23 = (unsigned __int64 *)(*((unsigned int *)v19 + 54) + v36)) == 0i64 )
{
LABEL_77:
if( (int)(*((_DWORD *)v19 + 3151) - LowPart) < 0
&& (!KiShouldScanSharedReadyQueue((__int64)v19) || (*(_DWORD *)(*((_QWORD *)v19 + 4233) + 8i64) & 0x7FFE) == 0)
&& (*((_DWORD *)v19 + 7942) & 0x7FFE) == 0 )
{
*((_DWORD *)v19 + 3151) = LowPart + 75;
}
LABEL_83:
if( !v50 )
return;
goto LABEL_84;
}
while( 1 )
{
v22 = *((unsigned __int8 *)v23 + 112);
v24 = (INT64)v23 - *((unsigned int *)v19 + 54);
v37 = v22 & 0x10;
if( (v22 & 4) != 0 )
{
if( v37 )
goto LABEL_74;
if( (v22 & 2) == 0 )
{
if( *(__int64 *)(v24 + 48) <= 0 )
break;
LABEL_74:
v38 = v23[3];
LABEL_75:
if( *v23 >= v38 )
break;
}
}
else
{
if( v37 )
{
v38 = v23[1];
goto LABEL_75;
}
if( (v22 & 2) == 0 && *(__int64 *)(v24 + 48) <= 0 )
break;
}
v23 = (unsigned __int64 *)v23[51];
if( !v23 )
goto LABEL_77;
}
}
LABEL_69:
*((_BYTE *)v19 + 12585) = 1;
if( *((_BYTE *)v19 + 32) )
{
*((_BYTE *)v19 + 6) = 1;
}
else
{
LOBYTE(v23) = 2;
HalRequestSoftwareInterrupt(
v23,
v22,
(INT64 *)v24,
v25,
(INT64)PreferredSetOut,
(INT64)AvailableSetOut,
SpinCount,
IdealSetOut,
a2,
v45,
v46);
}
goto LABEL_83;
}
_disable();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&KiForceIdleLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( KiForceIdleLock );
}
if( *((_BYTE *)CurrentPrcb + 33) && KeIsForceIdleEngaged() )
{
LODWORD(v6) = RtlGetInterruptTimePrecise(CurrentQpc);
v7 = v6;
PoExecuteIdleCheck(v6);
if( KiForceIdleWatchdogResetCount == 32 )
{
off_140C008C0[0]();
v8 = 0;
}
else
{
v8 = KiForceIdleWatchdogResetCount + 1;
}
KiForceIdleWatchdogResetCount = v8;
if( v7 - KiForceIdleActiveLastStartTime <= 0x1312D00 )
{
++qword_140C31390;
v9 = 1;
v5 = &KiClockTickSkipTraces[2 * (unsigned int)KiClockTickSkipTraceIndex];
v50 = 1;
v10 = ((_BYTE)KiClockTickSkipTraceIndex + 1) & 0xF;
KiClockTickSkipTraceIndex = v10;
*(_BYTE *)v5 = 0;
v5[1] = v7;
goto LABEL_15;
}
KiResetForceIdle(2i64, 1);
}
v9 = 0;
LABEL_15:
_InterlockedAnd64(&KiForceIdleLock, 0i64);
_enable();
if( !v9 )
goto LABEL_16;
LABEL_84:
if( KiClockOwnerOneShotRequestState == 1 )
{
v39 = KeGetCurrentIrql();
__writecr8(0xFui64);
KiClockOwnerOneShotRequestState = 2;
KiSetClockIntervalToMinimumRequested();
__writecr8(v39);
if( v5 )
*(_BYTE *)v5 = 1;
++qword_140C31398;
}
}Referenced by:
HalpTimerAlwaysOnClockInterrupt
HalpTimerClockInterrupt
HalpTimerClockIpiRoutine