IvtFlushTbInternal

CHAR __fastcall IvtFlushTbInternal(
        _QWORD *a1,
        INT64 a2,
        INT64 a3,
        CHAR a4,
        CHAR a5,
        INT64 a6,
        INT64 a7,
        INT64 a8,
        INT64 a9){
  CHAR v9; 
  int v10; 
  unsigned __int64 v12; 
  unsigned __int64 v13; 
  INT64 v14; 
  WORK_QUEUE_TYPE v15; 
  void *v16; 
  __int64 v17; 
  _QWORD *v18; 
  unsigned __int64 v19; 
  __int16 v20; 
  unsigned __int16 v21; 
  __int64 v22; 
  int v23; 
  unsigned __int64 v24; 
  __int64 v25; 
  unsigned __int64 v26; 
  unsigned int v27; 
  int v28; 
  unsigned __int64 v29; 
  unsigned int v30; 
  __int16 v31; 
  unsigned __int64 v32; 
  unsigned __int64 v33; 
  _QWORD *v34; 
  _BYTE *v35; 
  CHAR result; 
  struct _EX_RUNDOWN_REF *v37; 
  _BYTE *v38; 
  PEX_RUNDOWN_REF RunRef; 
  _QWORD a2a[2]; 
  __int64 a3a; 
  _QWORD *v42; 
  _QWORD v43[2]; 
  __int128 LockHandle; 
  __int64 LockHandle_16; 
  __int64 v46; 
  unsigned int v47; 
  int a4a; 
  v9 = a5;
  v10 = a8;
  LockHandle_16 = 0i64;
  RunRef = 0i64;
  v38 = 0i64;
  a4a = 0;
  *(_OWORD *)v43 = 0i64;
  a3a = 0i64;
  v12 = (-(__int64)(a5 != 0) & 0xFFFFFFFFFFFFFFFCui64) + 6;
  LockHandle = 0i64;
  *(_OWORD *)a2a = 0i64;
  if( !(_DWORD)a8 )
  {
    if( a4 )
    {
      if( a5 )
        v13 = v12 & 0xFFFFFFFFFFFFFFCFui64 | 0x10;
      else
        v13 = v12 & 0xFFFFFFFFFFFFFFCFui64;
    }
    else
    {
      if( a5 )
      {
        a2a[0] = v12 & 0xFFFFFFFF0000FFEFui64 | ((unsigned __int64)(unsigned __int16)a3 << 16) | 0x20;
        goto LABEL_10;
      }
      v13 = v12 & 0xFFF00000FFFFFFCFui64 | 0x20;
    }
    a2a[0] = v13;
LABEL_10:
    IvtIommuSendCommand(a1, a2a, 0i64);
    if( v9 )
      goto LABEL_48;
    v42 = 0i64;
    v43[1] = 0x8000000000000800ui64;
    *((_QWORD *)&LockHandle + 1) = a1 + 21;
    v17 = 8i64;
    *(_QWORD *)&LockHandle = 0i64;
    KxAcquireQueuedSpinLock((PIO_WORKITEM)&LockHandle, (PIO_WORKITEM_ROUTINE)(a1 + 21), v15, v16);
    v18 = (_QWORD *)a7;
    while( HalpIommuGetNextFlushDevice(v18, &v42, &a3a, &a4a, &RunRef, &v38) )
    {
      if( ExAcquireRundownProtection(RunRef) )
      {
        v19 = (unsigned __int64)(unsigned __int16)a3a << 12;
        *v38 = 1;
        v43[0] = v17 & 0xFFFFFFFF0000FE0Fui64 | (16 * (a4a & 0x1F | v19));
        IvtIommuSendCommand(a1, v43, 1i64);
        v17 = v43[0];
      }
    }
    KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
    goto LABEL_49;
  }
  v20 = a2a[1];
  if( a5 )
  {
    a3 = v12 ^ (v12 ^ (a3 << 16)) & 0xFFFF0000 | 0xF0;
    a2a[0] = a3;
  }
  else
  {
    a2a[0] = v12 & 0xFFF00000FFFFFFCFui64 | 0x30;
    v20 = LOWORD(a2a[1]) | 0x80;
  }
  *(_QWORD *)&LockHandle = 0i64;
  v21 = v20 & 0xFFBF;
  *((_QWORD *)&LockHandle + 1) = a1 + 21;
  KxAcquireQueuedSpinLock((PIO_WORKITEM)&LockHandle, (PIO_WORKITEM_ROUTINE)(a1 + 21), (WORK_QUEUE_TYPE)a3, (PVOID)a4);
  while( 2 )
  {
    v22 = (unsigned int)(v10 - 1);
    v23 = 0;
    LODWORD(a6) = 0;
    LODWORD(a8) = v22;
    v24 = *(_QWORD *)(a9 + 8 * v22);
    v25 = (v24 >> 10) & 3;
    if( ((v24 >> 10) & 3) != 0 )
    {
      v23 = 9 * v25;
      LODWORD(a6) = 9 * v25;
    }
    v26 = v24 & 0xFFFFFFFFFFFFF000ui64;
    v27 = (*(_DWORD *)(a9 + 8 * v22) & 0x3FF) + 1;
    v47 = v27;
    while( 1 )
    {
      v28 = 0;
      v29 = v26 ^ ((unsigned __int16)v26 ^ v21) & 0xFFF;
      if( v27 > 1 )
      {
        do
        {
          if( (((1 << (v23 + 13 + v28)) - 1) & (unsigned int)v26) != 0 )
            break;
          ++v28;
        }
        while( 1 << v28 < v27 );
      }
      v30 = v27 < 1 << v28 ? (1 << v28) - v27 : 0;
      if( v30 >= 0x1F || v23 == 9 && v30 )
        --v28;
      v46 = (unsigned int)(v28 + v23);
      a2a[1] = ((unsigned __int8)v29 ^ (unsigned __int8)(v28 + v23)) & 0x3F ^ v29;
      IvtIommuSendCommand(a1, a2a, 1i64);
      if( *(_QWORD *)a7 != a7 && !v9 )
      {
        v31 = 0;
        v32 = v26;
        v33 = 8i64;
        if( v28 || (_DWORD)a6 )
        {
          v31 = 2048;
          v32 = (unsigned int)~(1 << (v46 + 11)) & (v26 | (unsigned int)((1 << (v46 + 11)) - 1));
        }
        v34 = (_QWORD *)a7;
        v42 = 0i64;
        v43[1] = v32 ^ ((unsigned __int16)v32 ^ (unsigned __int16)v31) & 0xFFF;
        while( 1 )
        {
          while( 1 )
          {
            if( !HalpIommuGetNextFlushDevice(v34, &v42, &a3a, &a4a, &RunRef, &v38) )
            {
              v27 = v47;
              v9 = a5;
              goto LABEL_42;
            }
            v33 = v33 & 0xFFFFFFFF0000FE0Fui64 | (16 * (a4a & 0x1F | ((unsigned __int64)(unsigned __int16)a3a << 12)));
            v35 = v38;
            v43[0] = v33;
            if( !*v38 )
              break;
LABEL_40:
            *v35 = 1;
            IvtIommuSendCommand(a1, v43, 1i64);
            v33 = v43[0];
          }
          if( ExAcquireRundownProtection(RunRef) )
          {
            v35 = v38;
            goto LABEL_40;
          }
        }
      }
LABEL_42:
      if( v27 <= 1 << v28 )
        break;
      v27 -= 1 << v28;
      v47 = v27;
      v26 += 1i64 << ((unsigned __int8)v46 + 12);
      if( !v27 )
        break;
      v21 = a2a[1];
      v23 = a6;
    }
    v10 = a8;
    if( (_DWORD)a8 )
    {
      v21 = a2a[1];
      continue;
    }
    break;
  }
  KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
LABEL_48:
  v18 = (_QWORD *)a7;
LABEL_49:
  result = IvtIommuWaitCommand((INT64)a1, v14, 0i64);
  v42 = 0i64;
  if( !v9 )
  {
    while( 1 )
    {
      result = HalpIommuGetNextFlushDevice(v18, &v42, &a3a, &a4a, &RunRef, &v38);
      if( !result )
        break;
      if( *v38 )
      {
        v37 = RunRef;
        *v38 = 0;
        ExReleaseRundownProtection(v37);
      }
    }
  }
  return result;
}

Referenced by:

IvtAttachDeviceDomainInternal
IvtFlushDomainTb
IvtInitializeIommu