PpmRegisterPerfStates
NTSTATUS __stdcall PpmRegisterPerfStates(INT64 a1, CHAR a2){
INT64 v3;
__int64 v4;
unsigned int v5;
VOID **v6;
unsigned int v7;
int v8;
unsigned int v9;
__int64 v10;
__int64 v11;
int v12;
__int64 *v13;
__int64 v14;
int v15;
__int64 v16;
_DWORD *v17;
int v18;
unsigned int v19;
size_t v20;
size_t v21;
bool v22;
size_t v23;
VOID **PoolWithTag;
__int64 v25;
char *v26;
__int64 v27;
__int64 v28;
unsigned int v29;
unsigned int v30;
__int64 v31;
char *v32;
__int64 v33;
__int64 v34;
unsigned int v35;
int v36;
__int64 v37;
UINT64 v38;
char v39;
__int64 *v40;
__int64 v41;
__int64 v42;
__int64 v43;
__int64 v44;
__int64 v45;
UINT16 v46;
UINT64 *v47;
unsigned int FirstSetRightGroupAffinity;
_KPRCB *Prcb;
UINT64 PerformanceCounter;
int v51;
__int64 v52;
int *v53;
char v54;
unsigned int v55;
int v56;
_DWORD *v57;
__int64 v58;
__int64 *v59;
__int64 v60;
__int64 *v61;
__int64 v62;
__int64 v63;
VOID ***v64;
char v65;
INT64 v66;
char v67;
char v68;
unsigned __int64 v70;
__int64 v71;
_DWORD *v72;
__int64 v73;
__int64 v74;
_QWORD *v75;
PVOID *v76;
int v77[8];
int v78;
int v79;
__int64 v80;
__int64 v81;
unsigned int v82;
int v83;
__int64 v84;
_PROC_PERF_CHECK_CONTEXT *p_CheckContext;
__int64 v86;
__int64 v87;
_QWORD Counters[3];
_KPRCB *v89;
INT64 v90;
__int128 Base;
_EXT_SET_PARAMETERS_V0 Parameters;
_KAFFINITY_EX Source;
_KAFFINITY_EX Affinity;
v90 = a1;
v3 = a1;
memset(&Affinity, 0i64, sizeof(Affinity));
Base = 0i64;
memset(Source.Bitmap, 0i64, sizeof(Source.Bitmap));
v4 = *(unsigned int *)(v3 + 16);
v5 = *(_DWORD *)(v3 + 36);
v6 = 0i64;
LOBYTE(v78) = 0;
v83 = *(_DWORD *)(v3 + 20);
LODWORD(v86) = v4;
*(_OWORD *)&Counters[1] = 0i64;
*(_DWORD *)&Source.Count = 1310721;
memset(&Source.Reserved, 0i64, 0xA4u);
KeQueryActiveProcessorAffinity((INT64)&Affinity);
v87 = 0i64;
v7 = 0;
v79 = 0;
if( !a2 )
PpmAcquireLock((_PPM_LOCK *)((char *)&stru_140C23628 + 1048));
v8 = -1;
v81 = -1i64;
v9 = 0;
if( v5 )
{
v10 = *(_QWORD *)(v3 + 408);
do
{
v11 = *(unsigned int *)(v10 + 24i64 * v9 + 12);
if( (unsigned int)v11 >= 2 )
goto LABEL_115;
if( *((_DWORD *)&v81 + v11) == -1 )
*((_DWORD *)&v81 + v11) = v9;
++v9;
}
while( v9 < v5 );
v8 = v81;
}
if( v8 == -1 && HIDWORD(v81) == -1 )
{
LABEL_115:
v36 = -1073741811;
goto LABEL_126;
}
v12 = 0;
v13 = &v81;
v14 = 2i64;
do
{
v22 = *(_DWORD *)v13 == -1;
v15 = v12 + 1;
v13 = (__int64 *)((char *)v13 + 4);
if( v22 )
v15 = v12;
v12 = v15;
--v14;
}
while( v14 );
LODWORD(v84) = v15;
if( (_DWORD)v4 )
{
v16 = v4;
v17 = (_DWORD *)(*(_QWORD *)(v3 + 416) + 28i64);
do
{
v22 = *v17 == 1;
v18 = v7 + 1;
v17 += 8;
if( !v22 )
v18 = v7;
v7 = v18;
--v16;
}
while( v16 );
v79 = v18;
}
v19 = (136 * v4 + 775) & 0xFFFFFFF8;
v20 = v19 + 48 * v12 * v4;
v21 = v20;
v22 = v7 == 0;
if( v7 )
{
v21 = v20 + (v7 << 7);
v22 = v7 == 0;
}
v23 = v21;
if( v22 )
v20 = 0;
PoolWithTag = ExAllocatePoolWithTag(0x200ui64, v21, 1884115024i64);
v6 = PoolWithTag;
if( !PoolWithTag )
{
v36 = -1073741670;
goto LABEL_126;
}
memset(PoolWithTag, 0i64, v23);
v25 = v20;
v26 = (char *)(v6 + 96);
v27 = 0i64;
v28 = (__int64)v6 + v25;
v29 = 0;
Counters[0] = (char *)v6 + v19;
v82 = 0;
v87 = v28;
if( *(_BYTE *)(v3 + 11) )
LODWORD(PpmPerfQosTransitionHysteresis) = *(_DWORD *)(v3 + 48);
v30 = 0;
LODWORD(v80) = 0;
if( !(_DWORD)v4 )
{
LABEL_47:
if( KeIsEmptyAffinityEx(&Source.Count) )
{
*((_DWORD *)v6 + 52) = 2;
v71 = 0i64;
if( (_DWORD)v4 )
{
v72 = v26 + 16;
while( *v72 != 1 )
{
v71 = (unsigned int)(v71 + 1);
v72 += 34;
if( (unsigned int)v71 >= (unsigned int)v4 )
goto LABEL_49;
}
v6[2] = *(VOID **)&v26[136 * v71];
*((_DWORD *)v6 + 52) = 1;
}
}
else
{
KeFirstGroupAffinityEx(&Base, (UINT8)&Source, v46, v47);
FirstSetRightGroupAffinity = KeFindFirstSetRightGroupAffinity((INT64)&Base);
Prcb = KeGetPrcb(FirstSetRightGroupAffinity);
v6[2] = &Prcb->PowerState.CheckContext;
*((_BYTE *)v6 + 204) = Prcb->PowerState.ArchitecturalEfficiencyClass;
}
LABEL_49:
KeCopyAffinityEx((_KAFFINITY_EX *)(v6 + 3), &Source);
v6[28] = *(VOID **)(v3 + 256);
v6[30] = *(VOID **)(v3 + 272);
v6[31] = *(VOID **)(v3 + 280);
v6[32] = *(VOID **)(v3 + 288);
v6[33] = *(VOID **)(v3 + 296);
v6[29] = *(VOID **)(v3 + 264);
v6[24] = *(VOID **)(v3 + 80);
v6[27] = v26;
*((_DWORD *)v6 + 137) = 1;
PerformanceCounter = KeQueryPerformanceCounter(0i64);
v51 = v83;
v52 = 5i64;
v6[94] = (VOID *)PerformanceCounter;
*((_DWORD *)v6 + 79) = v51;
*((_DWORD *)v6 + 50) = v4;
*((_DWORD *)v6 + 83) = *(_DWORD *)(v3 + 44);
*((_DWORD *)v6 + 80) = *(_DWORD *)(v3 + 24);
*((_DWORD *)v6 + 81) = *(_DWORD *)(v3 + 28);
*((_DWORD *)v6 + 82) = *(_DWORD *)(v3 + 32);
*((_BYTE *)v6 + 353) = *(_BYTE *)(v3 + 4);
v6[36] = *(VOID **)(v3 + 336);
v6[37] = *(VOID **)(v3 + 344);
v6[38] = *(VOID **)(v3 + 352);
v6[34] = *(VOID **)(v3 + 320);
v6[35] = *(VOID **)(v3 + 328);
*((_BYTE *)v6 + 359) = *(_BYTE *)(v3 + 52);
v53 = (int *)v6 + 141;
do
{
*(v53 - 1) = 100;
*v53 = v51;
v53 += 10;
--v52;
}
while( v52 );
*((_BYTE *)v6 + 354) = *(_BYTE *)(v3 + 6);
*((_BYTE *)v6 + 355) = *(_BYTE *)(v3 + 7);
*((_BYTE *)v6 + 356) = *(_BYTE *)(v3 + 8);
if( *(_WORD *)(v3 + 4) == 253 || (v54 = 1, *(_QWORD *)(v3 + 352)) )
v54 = 0;
*((_BYTE *)v6 + 358) = v54;
*((_BYTE *)v6 + 357) = *(_BYTE *)(v3 + 11);
if( PpmPerfQosManageIdleProcessors == -1 )
PpmPerfQosManageIdleProcessors = *(_BYTE *)(v3 + 12) != 0;
v6[42] = *(VOID **)(v3 + 56);
v6[43] = *(VOID **)(v3 + 64);
*((_BYTE *)v6 + 352) = 100;
if( *(&PopIrpWorkerControlEvent + 155) <= (unsigned __int64)*(unsigned int *)(v3 + 40) )
*(&PopIrpWorkerControlEvent + 155) = *(unsigned int *)(v3 + 40);
if( v6[31] )
*(&stru_140C23628 + 882) |= 0x40u;
if( v6[30] )
*(&stru_140C23628 + 882) |= 0x20u;
if( v6[29] )
*(&stru_140C23628 + 882) |= 0x200u;
if( v6[33] )
*(&stru_140C23628 + 882) |= 0x80u;
if( v6[32] )
*(&stru_140C23628 + 882) |= 0x100u;
if( *(_BYTE *)(v3 + 9) )
PpmPerfEppViaPerfControl = 1;
if( *(_BYTE *)(v3 + 10) )
PpmPerfAutonomousActivityWindowViaPerfControl = 1;
_InterlockedOr(v77, 0);
v55 = 0;
if( (_DWORD)v4 )
{
v56 = v84;
v57 = v6 + 98;
do
{
if( *v57 != 2 )
{
v58 = *((_QWORD *)v57 - 2);
v59 = &v81;
*(_OWORD *)&Counters[1] = 0i64;
*(_DWORD *)(v58 + 56) = 0x10000;
v60 = 2i64;
*(_QWORD *)v58 = v6;
*(_QWORD *)(v58 + 8) = &v6[17 * v55 + 96];
v61 = &Counters[1];
v62 = Counters[0] + 48i64 * v56 * v55;
do
{
if( *(_DWORD *)v59 != -1 )
{
*v61 = v62;
v62 += 48i64;
}
v59 = (__int64 *)((char *)v59 + 4);
++v61;
--v60;
}
while( v60 );
if( *v57 )
{
PpmPerfResizeHistory((_KPRCB *)v58);
v73 = 2i64;
v74 = v58 - (_QWORD)&Counters[1];
v75 = &Counters[1];
do
{
if( *v75 )
*(_QWORD *)((char *)v75 + v74 + 88) = *v75;
++v75;
--v73;
}
while( v73 );
}
else
{
PpmInstallFeedbackCounters((_KPRCB *)(v58 - 33128), (_PROC_FEEDBACK_COUNTER **)&Counters[1]);
}
}
++v55;
v57 += 34;
}
while( v55 < (unsigned int)v4 );
v3 = v90;
v27 = 0i64;
v7 = v79;
}
if( !*(&stru_140C23628 + 451) )
*(&stru_140C23628 + 451) = *(_QWORD *)(v3 + 72);
v63 = *(&stru_140C23628 + 450);
if( !*(&stru_140C23628 + 450) )
{
v63 = *(_QWORD *)(v3 + 360);
*(&stru_140C23628 + 450) = v63;
}
if( !*(&stru_140C23628 + 481) )
*(&stru_140C23628 + 481) = *(_QWORD *)(v3 + 368);
if( !*(&stru_140C23628 + 480) )
*(&stru_140C23628 + 480) = *(_QWORD *)(v3 + 376);
if( !*(&stru_140C23628 + 479) )
*(&stru_140C23628 + 479) = *(_QWORD *)(v3 + 384);
if( !*(&stru_140C23628 + 478) )
*(&stru_140C23628 + 478) = *(_QWORD *)(v3 + 392);
if( !*(&stru_140C23628 + 484) )
*(&stru_140C23628 + 484) = *(_QWORD *)(v3 + 400);
if( !*(&stru_140C23628 + 483) )
*(&stru_140C23628 + 483) = *(_QWORD *)(v3 + 304);
if( !*(&stru_140C23628 + 482) )
*(&stru_140C23628 + 482) = *(_QWORD *)(v3 + 312);
if( v63 )
*(&PopIrpWorkerControlEvent + 1248) = 1;
v64 = (VOID ***)qword_140CFB4F0;
++PpmPerfDomainCount;
if( *(INT64 **)qword_140CFB4F0 != &PpmPerfDomainHead )
__fastfail(3u);
*v6 = &PpmPerfDomainHead;
v65 = 1;
v6[1] = v64;
*v64 = v6;
v66 = PpmPerfDomainHead;
qword_140CFB4F0 = (__int64)v6;
LOBYTE(v78) = 1;
if( (INT64 *)PpmPerfDomainHead != &PpmPerfDomainHead )
{
do
{
v67 = *(_BYTE *)(v66 + 357);
v66 = *(_QWORD *)v66;
v65 = v67 != 0 ? v65 : 0;
}
while( (INT64 *)v66 != &PpmPerfDomainHead );
LOBYTE(v78) = v65;
}
KeOrAffinityEx((INT8 *)&Source, &PpmPerfStatesRegistered.Count, (INT8 *)&PpmPerfStatesRegistered);
*((_WORD *)v6 + 382) = 257;
PpmUpdateProcessorPolicy((_PPM_POLICY_ACTION_MASK *)&stru_140C23628 + 882);
PpmCheckResetProcessors((INT64)v6);
if( ((Source.Bitmap[(unsigned __int64)(unsigned int)KiProcessorIndexToNumberMappingTable[0] >> 6] >> (KiProcessorIndexToNumberMappingTable[0] & 0x3F)) & 1) != 0 )
PpmParkApplyPolicy();
PpmCheckReInit();
v6 = 0i64;
v36 = 0;
PpmPerfUpdateDomainPolicy(1);
goto LABEL_109;
}
v31 = 0i64;
v32 = (char *)v6 + 788;
while( 1 )
{
v33 = *(_QWORD *)(v3 + 416);
*((_DWORD *)v32 - 1) = *(_DWORD *)(v31 + v33 + 28);
v34 = *(unsigned int *)(v31 + v33);
if( !*(_DWORD *)(v31 + v33 + 28) )
break;
v35 = -1;
*(_DWORD *)v32 = v34;
v22 = *(_DWORD *)(v31 + v33 + 28) == 1;
LODWORD(p_CheckContext) = -1;
if( v22 )
{
v82 = v29 + 1;
v70 = v28 + ((unsigned __int64)v29 << 7);
*(_WORD *)(v70 + 54) = 100;
v36 = PpmAllocatePerfCheck((_KPRCB *)v70);
if( v36 < 0 )
goto LABEL_125;
*(_QWORD *)(v32 - 20) = v70;
v35 = (unsigned int)p_CheckContext;
goto LABEL_37;
}
LABEL_38:
*((_DWORD *)v32 + 7) = 100;
*(_QWORD *)(v32 - 12) = *(_QWORD *)(v31 + v33 + 8);
*((_DWORD *)v32 + 1) = *(_DWORD *)(v31 + v33 + 16);
*((_DWORD *)v32 + 2) = *(_DWORD *)(v31 + v33 + 20);
*((_DWORD *)v32 + 3) = *(_DWORD *)(v31 + v33 + 24);
*((_DWORD *)v32 + 14) = v83;
v39 = 0;
*(_QWORD *)(v32 + 108) = 0i64;
*((_DWORD *)v32 + 9) = 100;
*((_DWORD *)v32 + 13) = 100;
*((_DWORD *)v32 + 15) = 1;
*((_DWORD *)v32 + 16) = 100;
*((_DWORD *)v32 + 17) = 100;
*((_DWORD *)v32 + 24) = 100;
*((_DWORD *)v32 + 25) = 100;
if( !*(_BYTE *)(v3 + 7) && *(_BYTE *)(v3 + 11) )
v39 = 1;
v32[105] = v39;
if( *(_DWORD *)(v31 + v33 + 16) < 0x64u )
{
*(_QWORD *)(v32 + 20) = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
PopDiagTraceProcessorThrottlePerfTrack((unsigned int)(100 - *(_DWORD *)(v31 + v33 + 16)), v35);
}
v40 = &v81;
v41 = (unsigned int)v84 * v30;
v42 = 2i64;
v43 = Counters[0] + 48 * v41;
do
{
v44 = *(unsigned int *)v40;
if( (_DWORD)v44 != -1 )
{
v45 = *(_QWORD *)(v3 + 408);
*(_QWORD *)(v43 + 40) = *(_QWORD *)(*(_QWORD *)(v3 + 424) + 8i64 * (unsigned int)(v41 + v44));
*(_BYTE *)(v43 + 33) = *(_BYTE *)(v45 + 24 * v44 + 17);
*(_BYTE *)(v43 + 32) = *(_BYTE *)(v45 + 24 * v44 + 16);
*(_BYTE *)(v43 + 34) = *(_BYTE *)(v45 + 24 * v44 + 18);
*(_BYTE *)(v43 + 35) = *(_BYTE *)(v45 + 24 * v44 + 8);
*(_QWORD *)v43 = *(_QWORD *)(v45 + 24 * v44);
v43 += 48i64;
}
v40 = (__int64 *)((char *)v40 + 4);
--v42;
}
while( v42 );
LODWORD(v4) = v86;
v30 = v80 + 1;
v29 = v82;
v31 += 32i64;
v28 = v87;
v32 += 136;
LODWORD(v80) = v30;
if( v30 >= (unsigned int)v86 )
{
v7 = v79;
v26 = (char *)(v6 + 96);
v27 = 0i64;
goto LABEL_47;
}
}
v35 = *(_DWORD *)(v31 + v33);
if( (_DWORD)v34 != -1
&& ((PpmPerfStatesRegistered.Bitmap[(unsigned __int64)(unsigned int)KiProcessorIndexToNumberMappingTable[v34] >> 6] >> (KiProcessorIndexToNumberMappingTable[v34] & 0x3F)) & 1) == 0 )
{
v89 = KeGetPrcb((unsigned int)v34);
p_CheckContext = &v89->PowerState.CheckContext;
v36 = PpmAllocatePerfCheck((_KPRCB *)&v89->PowerState.CheckContext);
if( v36 < 0 )
goto LABEL_125;
KeAddProcessorAffinityEx(&Source.Count, v35);
v37 = (__int64)v89;
*(_QWORD *)(v32 - 20) = p_CheckContext;
v38 = (unsigned int)PpmPerfQosTransitionHysteresisOverride;
if( PpmPerfQosTransitionHysteresisOverride == -1 )
v38 = (unsigned int)PpmPerfQosTransitionHysteresis;
*(_QWORD *)(v37 + 33256) = PpmConvertTime(v38, 0xF4240ui64, 1000000i64 * *(unsigned int *)(v37 + 68));
LABEL_37:
v30 = v80;
goto LABEL_38;
}
v36 = -1073741811;
LABEL_125:
v7 = v79;
LABEL_126:
PpmReleaseLock((INT64 *)&stru_140C23628 + 131);
v27 = 0i64;
LABEL_109:
v68 = v78;
if( ((unsigned int)PpmPerfDomainCount > 1 || (_BYTE)v78)
&& KeIsEqualAffinityEx(&PpmPerfStatesRegistered.Count, &PpmCheckRegistered.Count) )
{
PpmAcquireLock((_PPM_LOCK *)((char *)&stru_140C23628 + 1048));
PpmPerfSchedulerDirectedPerfStatesSupported = v68;
PpmReinitializeHeteroEngine(1);
}
if( v6 )
{
if( v7 )
{
v76 = (PVOID *)(v87 + 16);
v27 = v7;
do
{
if( *v76 )
{
ExFreePoolWithTag(*v76, 0x704D5050u);
*v76 = 0i64;
}
v76 += 16;
--v27;
}
while( v27 );
}
ExFreePoolWithTag(v6, 0x704D5050u);
}
Parameters.NoWakeTolerance = -1i64;
*(_QWORD *)&Parameters.Version = v27;
KeSetTimer2((INT64)&stru_140C23628 + 3640, -36000000000i64, 36000000000i64, (INT64)&Parameters);
return v36;
}Referenced by:
PpmPerfRegisterNativePerfStates