PopHandleNextState

void __fastcall PopHandleNextState(__int64 a1, __int64 a2, _KDPC *a3, INT64 *a4){
  struct _KPRCB *CurrentPrcb; 
  int v7; 
  int v8; 
  unsigned __int8 CurrentIrql; 
  int v10; 
  int v11; 
  int v12; 
  __int64 v13; 
  INT64 v14; 
  __int16 v15; 
  CurrentPrcb = KeGetCurrentPrcb();
  v7 = 0;
  while( *(_DWORD *)(a1 + 56) == *(_DWORD *)a2 )
  {
    ++v7;
    _mm_pause();
  }
  v8 = *(_DWORD *)(a1 + 56);
  *(_DWORD *)a2 = v8;
  switch( v8 )
  {
    case 2:
      PopFxNotifySystemStateTransition((INT64)CurrentPrcb, 1, (unsigned int)TargetState);
      break;
    case 3:
      KeSaveIptStateBeforeProcessorGoesOffline();
      *(_BYTE *)(a2 + 5) = 0;
      if( ((KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledSupervisorFeatures) & 0xFFFFFFFFFFFFFFFCui64) != 0 )
        *(_BYTE *)(a2 + 5) = (int)KeSaveExtendedAndSupervisorState(
                                    (KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledSupervisorFeatures) & 0xFFFFFFFFFFFFFFFCui64,
                                    (XSTATE_SAVE *)(a2 + 8)) >= 0;
      *(_QWORD *)(a2 + 120) = KeGetPcr();
      break;
    case 4:
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(0xFui64);
      *(_BYTE *)(a2 + 7) = CurrentIrql;
      _disable();
      *(_BYTE *)(a2 + 4) = (v15 & 0x200) != 0;
      KeSuspendClockTimer();
      break;
    case 5:
      if( *((PEPROCESS *)KeGetCurrentThread() + 23) != PsInitialSystemProcess )
      {
        *(_BYTE *)(a2 + 6) = 1;
        KeForceAttachProcess(PsInitialSystemProcess);
      }
      break;
    case 6:
      if( (*(_DWORD *)PopSimulate & 0x800000) != 0 && *(_QWORD *)(a1 + 8) )
      {
        PoResumeFromHibernate = 1;
        *(_DWORD *)(a2 + 112) = 0;
      }
      else
      {
        if( !*((_DWORD *)CurrentPrcb + 9) && !*(_QWORD *)(a1 + 8) )
          KdPowerTransition(PowerDeviceD3);
        v10 = (*(__int64(__fastcall **)(_QWORD, _QWORD, _QWORD, _QWORD, __int64))(*(_QWORD *)a1 + 8i64))(
                *(_QWORD *)(*(_QWORD *)a1 + 16i64),
                *(_QWORD *)(a1 + 8),
                *(_QWORD *)(a1 + 16),
                *(unsigned int *)(a1 + 48),
                a1 + 60);
        v11 = *((_DWORD *)CurrentPrcb + 9);
        v12 = v10;
        if( !v11 )
        {
          if( !PoResumeFromHibernate )
          {
            KdPowerTransition(PowerDeviceD0);
            v11 = *((_DWORD *)CurrentPrcb + 9);
          }
          if( !v11 )
            qword_140C238A0 = __rdtsc();
        }
        *(_DWORD *)(a2 + 112) = v12;
      }
      break;
    case 7:
      HvlEnlightenProcessor(1, a2, (INT64)a3, a4);
      break;
    case 8:
      KeRestoreProcessorSpecificFeatures((_KTIMER *)0x140000000i64, (_LARGE_INTEGER)a2, a3);
      break;
    case 9:
      PopRestoreHiberContext(*(_QWORD *)(a1 + 24));
      break;
    case 10:
      KeFlushCurrentTbImmediately();
      __wbinvd();
      break;
    case 11:
      if( *(_BYTE *)(a2 + 6) )
      {
        KeForceDetachProcess((KAPC_STATE *)(a2 + 64), 1);
        *(_BYTE *)(a2 + 6) = 0;
      }
      break;
    case 12:
      v13 = *(_QWORD *)(a1 + 32);
      if( *(_QWORD *)v13 )
        (*(void(__fastcall **)(_QWORD, _QWORD, _QWORD))v13)(
          *(unsigned int *)(a1 + 40),
          *(_QWORD *)(v13 + 8),
          *(unsigned __int8 *)(a1 + 44));
      break;
    case 13:
      KeResumeClockTimer();
      PpmResetPerfEngineForProcessorEx((INT64)CurrentPrcb, 0i64);
      if( *(_BYTE *)(a2 + 4) )
        _enable();
      __writecr8(*(unsigned __int8 *)(a2 + 7));
      break;
    case 14:
      PopFxNotifySystemStateTransition((INT64)CurrentPrcb, 0, (unsigned int)TargetState);
      break;
    case 15:
      if( *(_BYTE *)(a2 + 5) )
        KeRestoreExtendedAndSupervisorState((XSTATE_SAVE *)(a2 + 8));
      KeRestoreIptStateAfterProcessorComesOnline();
      LOBYTE(v14) = 1;
      PpmResetPerfEngineForProcessorEx((INT64)CurrentPrcb, v14);
      break;
    default:
      break;
  }
  _InterlockedIncrement((volatile signed __int32 *)(a1 + 52));
}

Referenced by:

PopInvokeStateHandlerTargetProcessor
PopIssueNextState