HalpIommuMapLogicalRange

INT64 __fastcall 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; 
  UINT64 v15; 
  unsigned int v16; 
  unsigned __int64 v17; 
  __int64 v18; 
  __int64 v19; 
  unsigned __int64 v20; 
  unsigned __int8 v21; 
  unsigned __int64 v22; 
  void *v23; 
  PHYSICAL_ADDRESS PhysicalAddress; 
  void *v25; 
  unsigned int v26; 
  unsigned __int64 v27; 
  __int64 v28; 
  int v29; 
  UINT64 v30; 
  void *v31; 
  unsigned int v32; 
  UINT64 v33; 
  int v34; 
  __int64 v35; 
  __int64 v36; 
  char v38; 
  unsigned int v39; 
  unsigned int v40; 
  __int64 v41; 
  INT64 v42; 
  UINT64 v43; 
  unsigned __int64 v44; 
  INT64 v45; 
  PKSPIN_LOCK SpinLock; 
  INT64 v47; 
  __int128 v48[3]; 
  v6 = *(_DWORD *)(a2 + 28);
  v8 = a6;
  LODWORD(v9) = 0;
  v45 = a1;
  v10 = *(_QWORD *)(a2 + 16);
  v11 = a6 + ((a5 + 4095) & 0xFFFFFFFFFFFFF000ui64);
  v39 = a3;
  v38 = v6;
  v44 = v11;
  v47 = a6;
  v40 = 1 << v6;
  v48[0] = v10;
  v12 = a4 & -(__int64)((_DWORD)a3 != 0);
  v13 = 0i64;
  v42 = v12;
  v43 = 0i64;
  memset(&v48[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));
          v41 = v19;
          v20 = *(_QWORD *)(v17 + 8 * v19);
          if( !v20 )
          {
            SpinLock = (PKSPIN_LOCK)(a2 + 8);
            KeAcquireSpinLockRaiseToDpc((UINT64 *)(a2 + 8), v15);
            v22 = v21;
            if( !*(_QWORD *)(v17 + 8 * v19) )
            {
              v23 = (void *)HalpIommuAllocateAndZeroPageTable(a2, (unsigned int)(v9 + 1), v45);
              *(_QWORD *)(v17 + 8 * v19) = v23;
              if( !v23 )
              {
                KxReleaseSpinLock(SpinLock);
                __writecr8(v22);
                return 3221225626i64;
              }
              PhysicalAddress = MmGetPhysicalAddress(v23);
              v25 = (void *)(v10 + (unsigned int)((_DWORD)v19 << v38));
              (**(void(__fastcall ***)(void *, _QWORD, PHYSICAL_ADDRESS))(a2 + 88))(
                v25,
                (unsigned int)(*(_DWORD *)(a2 + 24) - v9 - 1),
                PhysicalAddress);
              if( !HalpIommuPageTableCacheCoherent )
                KeInvalidateRangeAllCachesNoIpi(v25, v40);
            }
            KxReleaseSpinLock((UINT64 *)(a2 + 8));
            __writecr8(v22);
            v14 = *(_DWORD *)(a2 + 24);
            LOBYTE(v6) = v38;
            v20 = *(_QWORD *)(v17 + 8 * v41);
          }
          v10 = v20;
          v9 = (unsigned int)(v9 + 1);
          v15 = (unsigned int)v9;
          *((_QWORD *)v48 + v9) = v20;
          if( (unsigned int)v9 >= v14 - 1 )
          {
            v13 = v43;
            v12 = v42;
            v11 = v44;
            LODWORD(a3) = v39;
            break;
          }
        }
      }
      v26 = *(_DWORD *)(a2 + 4i64 * (unsigned int)v9 + 36);
      if( (_DWORD)a3 )
      {
        if( v26 < 0x40 )
          v28 = (1i64 << v26) - 1;
        else
          LODWORD(v28) = -1;
        v29 = v28 & (v8 >> *(_DWORD *)(a2 + 4i64 * (unsigned int)v9 + 60));
        v30 = v11 - v8;
        v31 = (void *)(v10 + (unsigned int)(v29 << v6));
        v32 = (1 << *(_DWORD *)(a2 + 4i64 * (unsigned int)(v14 - 1) + 36)) - v29;
        v33 = v30 >> 12;
        if( (unsigned int)v33 <= v32 )
          v32 = v33;
        v34 = (*(__int64(__fastcall **)(unsigned __int64, INT64, _QWORD, _QWORD))(*(_QWORD *)(a2 + 88) + 8i64))(
                v10 + (unsigned int)(v29 << v6),
                v12,
                v39,
                v32);
        v13 += (unsigned int)(v34 << 12);
        v43 = v13;
        if( v34 != v32 )
        {
          HalpIommuUnmapLogicalRange(a2, &v43, v47);
          return 3221225485i64;
        }
        if( !HalpIommuPageTableCacheCoherent )
          KeInvalidateRangeAllCachesNoIpi(v31, v40 * v32);
        v35 = v32 << 12;
        v12 = (unsigned int)v35 + v42;
        v42 = v12;
        v27 = v35 + v8;
      }
      else
      {
        v27 = ~((1i64 << ((unsigned __int8)v26 + 12)) - 1) & ((1i64 << ((unsigned __int8)v26 + 12)) + v8);
      }
      if( (_DWORD)v9 )
      {
        do
        {
          v36 = (unsigned int)(v9 - 1);
          if( ((1i64 << *(_DWORD *)(a2 + 4 * v36 + 60)) & v27) == (v8 & (1i64 << *(_DWORD *)(a2 + 4 * v36 + 60))) )
            break;
          LODWORD(v9) = v9 - 1;
        }
        while( (_DWORD)v36 );
      }
      v11 = v44;
      v8 = v27;
      v10 = *((_QWORD *)v48 + (unsigned int)v9);
      if( v27 >= v44 )
        return 0i64;
      LOBYTE(v6) = v38;
      LODWORD(a3) = v39;
    }
  }
  return 0i64;
}

Referenced by:

HalpIommuConstructReservedPageTable
HalpIommuDomainMapLogicalRange
IommuMapIdentityRange
IommuMapLogicalRange