HalpIommuMapLogicalRange

NTSTATUS __stdcall HalpIommuMapLogicalRange(INT64 a1, INT64 a2, UINT64 a3, INT64 a4, INT64 a5, UINT64 a6){
  int v6; 
  UINT64 v8; 
  __int64 v9; 
  unsigned __int64 v10; 
  UINT64 v11; 
  INT64 v12; 
  UINT64 v13; 
  int v14; 
  __int64 v15; 
  unsigned int v16; 
  unsigned __int64 v17; 
  __int64 v18; 
  __int64 v19; 
  unsigned __int64 v20; 
  unsigned __int64 v21; 
  UINT64 v22; 
  __int64 v23; 
  VOID *v24; 
  unsigned int v25; 
  unsigned __int64 v26; 
  __int64 v27; 
  int v28; 
  UINT64 v29; 
  VOID *v30; 
  unsigned int v31; 
  UINT64 v32; 
  int v33; 
  __int64 v34; 
  __int64 v35; 
  char v37; 
  unsigned int v38; 
  unsigned int Length; 
  __int64 v40; 
  INT64 v41; 
  UINT64 v42; 
  unsigned __int64 v43; 
  INT64 v44; 
  UINT64 *SpinLock; 
  INT64 v46; 
  __int128 v47[3]; 

  v6 = *(_DWORD *)(a2 + 28);
  v8 = a6;
  LODWORD(v9) = 0;
  v44 = a1;
  v10 = *(_QWORD *)(a2 + 16);
  v11 = a6 + ((a5 + 4095) & 0xFFFFFFFFFFFFF000ui64);
  v38 = a3;
  v37 = v6;
  v43 = v11;
  v46 = a6;
  Length = 1 << v6;
  v47[0] = v10;
  v12 = a4 & -(__int64)((_DWORD)a3 != 0);
  v13 = 0i64;
  v41 = v12;
  v42 = 0i64;
  memset(&v47[1], 0, 32);
  if( a6 < v11 )
  {
    while( 1 )
    {
      v14 = *(_DWORD *)(a2 + 24);
      if( (unsigned int)v9 < v14 - 1 )
      {
        v15 = (unsigned int)v9;
        while( 1 )
        {
          v16 = *(_DWORD *)(a2 + 4 * v15 + 36);
          v17 = v10 + (1 << v16 << v6);
          if( v16 < 0x40 )
            v18 = (1i64 << v16) - 1;
          else
            LODWORD(v18) = -1;
          v19 = (unsigned int)v18 & (unsigned int)(v8 >> *(_DWORD *)(a2 + 4 * v15 + 60));
          v40 = v19;
          v20 = *(_QWORD *)(v17 + 8 * v19);
          if( !v20 )
          {
            SpinLock = (UINT64 *)(a2 + 8);
            v21 = (unsigned __int8)KeAcquireSpinLockRaiseToDpc((UINT64 *)(a2 + 8));
            if( !*(_QWORD *)(v17 + 8 * v19) )
            {
              LODWORD(v22) = HalpIommuAllocateAndZeroPageTable(a2, (unsigned int)(v9 + 1), v44);
              *(_QWORD *)(v17 + 8 * v19) = v22;
              if( !v22 )
              {
                KxReleaseSpinLock(SpinLock);
                __writecr8(v21);
                return -1073741670;
              }
              LODWORD(v23) = MmGetPhysicalAddress(v22);
              v24 = (VOID *)(v10 + (unsigned int)((_DWORD)v19 << v37));
              (**(void(__fastcall ***)(VOID *, _QWORD, __int64))(a2 + 88))(
                v24,
                (unsigned int)(*(_DWORD *)(a2 + 24) - v9 - 1),
                v23);
              if( !byte_140C49BF1 )
                KeInvalidateRangeAllCachesNoIpi(v24, Length);
            }
            KxReleaseSpinLock((UINT64 *)(a2 + 8));
            __writecr8(v21);
            v14 = *(_DWORD *)(a2 + 24);
            LOBYTE(v6) = v37;
            v20 = *(_QWORD *)(v17 + 8 * v40);
          }
          v10 = v20;
          v9 = (unsigned int)(v9 + 1);
          v15 = (unsigned int)v9;
          *((_QWORD *)v47 + v9) = v20;
          if( (unsigned int)v9 >= v14 - 1 )
          {
            v13 = v42;
            v12 = v41;
            v11 = v43;
            LODWORD(a3) = v38;
            break;
          }
        }
      }
      v25 = *(_DWORD *)(a2 + 4i64 * (unsigned int)v9 + 36);
      if( (_DWORD)a3 )
      {
        if( v25 < 0x40 )
          v27 = (1i64 << v25) - 1;
        else
          LODWORD(v27) = -1;
        v28 = v27 & (v8 >> *(_DWORD *)(a2 + 4i64 * (unsigned int)v9 + 60));
        v29 = v11 - v8;
        v30 = (VOID *)(v10 + (unsigned int)(v28 << v6));
        v31 = (1 << *(_DWORD *)(a2 + 4i64 * (unsigned int)(v14 - 1) + 36)) - v28;
        v32 = v29 >> 12;
        if( (unsigned int)v32 <= v31 )
          v31 = v32;
        v33 = (*(__int64(__fastcall **)(unsigned __int64, INT64, _QWORD, _QWORD))(*(_QWORD *)(a2 + 88) + 8i64))(
                v10 + (unsigned int)(v28 << v6),
                v12,
                v38,
                v31);
        v13 += (unsigned int)(v33 << 12);
        v42 = v13;
        if( v33 != v31 )
        {
          HalpIommuUnmapLogicalRange(a2, &v42, v46);
          return -1073741811;
        }
        if( !byte_140C49BF1 )
          KeInvalidateRangeAllCachesNoIpi(v30, Length * v31);
        v34 = v31 << 12;
        v12 = (unsigned int)v34 + v41;
        v41 = v12;
        v26 = v34 + v8;
      }
      else
      {
        v26 = ~((1i64 << ((unsigned __int8)v25 + 12)) - 1) & ((1i64 << ((unsigned __int8)v25 + 12)) + v8);
      }
      if( (_DWORD)v9 )
      {
        do
        {
          v35 = (unsigned int)(v9 - 1);
          if( ((1i64 << *(_DWORD *)(a2 + 4 * v35 + 60)) & v26) == (v8 & (1i64 << *(_DWORD *)(a2 + 4 * v35 + 60))) )
            break;
          LODWORD(v9) = v9 - 1;
        }
        while( (_DWORD)v35 );
      }
      v11 = v43;
      v8 = v26;
      v10 = *((_QWORD *)v47 + (unsigned int)v9);
      if( v26 >= v43 )
        return 0;
      LOBYTE(v6) = v37;
      LODWORD(a3) = v38;
    }
  }
  return 0;
}

Referenced by:

HalpIommuConstructReservedPageTable
HalpIommuDomainMapLogicalRange
IommuMapIdentityRange
IommuMapLogicalRange