IvtInitializeIommu

NTSTATUS __stdcall IvtInitializeIommu(INT64 a1, INT64 a2, CHAR a3){
  int v3; 
  int v4; 
  CHAR v5; 
  INT64 v7; 
  INT64 v8; 
  VOID *v9; 
  UINT64 v10; 
  NTSTATUS result; 
  UINT8 v12; 
  UINT64 v13; 
  int v14; 
  _LARGE_INTEGER v15; 
  UINT8 v16; 
  UINT64 v17; 
  _LARGE_INTEGER v18; 
  UINT8 v19; 
  VOID *v20; 
  CHAR ContextEntryType; 
  INT64 v22; 
  INT64 *v23; 
  INT64 v24; 
  INT64 v25; 
  INT64 v26; 
  __int64 v27; 
  INT64 v28; 
  INT64 *v29; 
  INT64 v30; 
  INT64 v31; 
  __int64 v32; 
  _LARGE_INTEGER v33; 
  UINT8 v34; 
  UINT64 v35; 
  __int64 *v36; 
  __int64 v37; 
  unsigned __int64 i; 
  __int64 v39; 
  __int64 *v40; 
  _LARGE_INTEGER v41; 
  UINT8 v42; 
  VOID *v43; 
  unsigned int v44; 
  __int128 *v45; 
  _QWORD *v46; 
  __int64 v47; 
  UINT8 v48; 
  VOID *v49; 
  unsigned int v50; 
  _LARGE_INTEGER v51; 
  UINT8 v52; 
  VOID *v53; 
  unsigned int v54; 
  __int64 v55; 
  __int64 v56; 
  __int64 v57; 
  int v58; 
  signed __int32 v59[8]; 
  INT64 v60; 
  INT64 v61; 
  unsigned int v62; 
  INT64 v63; 
  INT64 v64[2]; 
  INT64 v65[2]; 
  __int128 v66; 
  INT64 v67[2]; 
  __int128 v68; 
  int v69; 
  unsigned int v70; 
  int v72; 

  v3 = *(_DWORD *)(a1 + 260);
  v70 = *(_DWORD *)(a1 + 256);
  v4 = *(_DWORD *)(a1 + 264);
  v72 = v4;
  v5 = a3;
  v62 = 0;
  v69 = v3;
  v7 = 0x10000i64;
  v63 = 0i64;
  v66 = 0i64;
  *(_OWORD *)v65 = 0i64;
  *(_OWORD *)v67 = 0i64;
  v68 = 0i64;
  if( !(_DWORD)a2 )
  {
    result = HalSocRequestApi(a1, 0i64, 4i64, 8ui64, (char *)&CmpDummyThreadEvent + 3576);
    if( result < 0 )
      return result;
    v13 = *(_QWORD *)(a1 + 8);
    if( !v13 )
    {
      v13 = HalMapIoSpace(*(_LARGE_INTEGER *)a1, 0x220ui64, MmNonCached, v12);
      *(_QWORD *)(a1 + 8) = v13;
      if( !v13 )
        return -1073741823;
    }
    *(_DWORD *)(v13 + 56) = 0x80000000;
    _InterlockedOr(v59, 0);
    IvtUpdateGlobalCommand(a1, 0x4000000ui64, 0);
    v14 = *(_DWORD *)(*(_QWORD *)(a1 + 8) + 52i64);
    if( v14 )
    {
      *(_DWORD *)(*(_QWORD *)(a1 + 8) + 52i64) = v14;
      _InterlockedOr(v59, 0);
    }
    IvtUpdateGlobalCommand(a1, 0x2000000ui64, 0);
    if( !v3 )
      goto LABEL_65;
    if( *(_BYTE *)(a1 + 270) && !*(_QWORD *)(a1 + 280) && IvtInitializeIdentityMappings(a1) < 0 )
      return -1073741823;
    if( *(_QWORD *)(a1 + 40) )
    {
LABEL_47:
      if( !*(_QWORD *)(a1 + 16) )
      {
        v33.QuadPart = (*(&CmpDummyThreadEvent + 447))(-1i64, 1i64);
        *(_LARGE_INTEGER *)(a1 + 24) = v33;
        if( !v33.QuadPart )
          return -1073741823;
        v35 = HalMapIoSpace(v33, 0x1000ui64, (_MEMORY_CACHING_TYPE)((*(_BYTE *)(a1 + 184) & 1) != 0), v34);
        *(_QWORD *)(a1 + 16) = v35;
        if( !v35 )
          return -1073741823;
        v36 = *(__int64 **)(a1 + 16);
        v37 = ((*(_QWORD *)(a1 + 48) / 4096i64) << 12) | 1;
        for( i = (unsigned __int64)(v36 + 512); (unsigned __int64)v36 < i; i = *(_QWORD *)(a1 + 16) + 4096i64 )
        {
          *v36 = v37;
          v39 = *(_QWORD *)(a1 + 184) & 0x1000000i64;
          if( (*(_QWORD *)(a1 + 184) & 0x1000000) == 0 )
            v36[1] = 0i64;
          v40 = v36 + 1;
          if( v39 )
            v40 = v36;
          v36 = v40 + 1;
        }
      }
      if( !*(_QWORD *)(a1 + 32) )
      {
        v41.QuadPart = (*(&CmpDummyThreadEvent + 447))(-1i64, 1i64);
        if( !v41.QuadPart )
          return -1073741823;
        v43 = (VOID *)HalMapIoSpace(v41, 0x1000ui64, MmCached, v42);
        *(_QWORD *)(a1 + 32) = v43;
        if( !v43 )
          return -1073741823;
        memset(v43, 0i64, 0x1000u);
      }
      if( v3 == 2 && !v5 && IvtProcessDeviceExceptions(a1) < 0 )
        return -1073741823;
      *(_QWORD *)(*(_QWORD *)(a1 + 8) + 32i64) = (*(_DWORD *)(a1 + 184) >> 13) & 0x800 | (unsigned __int64)((*(_QWORD *)(a1 + 24) / 4096i64) << 12);
      _InterlockedOr(v59, 0);
      IvtUpdateGlobalCommand(a1, 0x40000000ui64, 1);
LABEL_65:
      v44 = 0;
      v45 = &v66;
      v46 = (_QWORD *)(a1 + 72);
      do
      {
        if( v44 != 1 || v69 )
        {
          v46[2] = 4096i64;
          if( !*v46 )
          {
            v47 = (*(&CmpDummyThreadEvent + 447))(-1i64, 1i64);
            v46[1] = v47;
            if( !v47 )
              return -1073741823;
            v49 = (VOID *)HalMapIoSpace(*(_LARGE_INTEGER *)(32i64 * v44 + a1 + 80), 0x1000ui64, MmCached, v48);
            *v46 = v49;
            if( !v49 )
              return -1073741823;
            memset(v49, 0i64, 0x1000u);
          }
          *(_QWORD *)v45 = *(_DWORD *)v45 & 0xFF8 | (unsigned __int64)((v46[1] / 4096i64) << 12);
        }
        ++v44;
        v46 += 4;
        v45 = (__int128 *)((char *)v45 + 8);
      }
      while( v44 < 2 );
      *(_QWORD *)(*(_QWORD *)(a1 + 8) + 136i64) = 0i64;
      _InterlockedOr(v59, 0);
      *(_QWORD *)(*(_QWORD *)(a1 + 8) + 144i64) = v66;
      _InterlockedOr(v59, 0);
      if( v72 )
      {
        if( v72 == 1 )
          *(_LIST_ENTRY *)(a1 + 240) = *(_LIST_ENTRY *)((char *)&CmpDummyThreadEvent + 3560);
        if( !*(_QWORD *)(a1 + 240) )
        {
          v50 = (16 * v70 + 4095) & 0xFFFFF000;
          v51.QuadPart = (*(&CmpDummyThreadEvent + 447))(-1i64, v50 >> 12);
          *(_LARGE_INTEGER *)(a1 + 248) = v51;
          if( !v51.QuadPart )
            return -1073741823;
          v53 = (VOID *)HalMapIoSpace(v51, v50, (_MEMORY_CACHING_TYPE)((*(_BYTE *)(a1 + 184) & 1) != 0), v52);
          *(_QWORD *)(a1 + 240) = v53;
          if( !v53 )
            return -1073741823;
          memset(v53, 0i64, v50);
          *(_DWORD *)(a1 + 256) = v70;
          if( v72 == 1 && !*(&CmpDummyThreadEvent + 445) )
            *(_LIST_ENTRY *)((char *)&CmpDummyThreadEvent + 3560) = *(_LIST_ENTRY *)(a1 + 240);
        }
        _BitScanReverse(&v54, v70);
        v55 = (*(_QWORD *)(a1 + 248) / 4096i64) << 12;
        v62 = v54;
        v56 = ((_BYTE)v54 - 1) & 0xF | (unsigned __int64)v55 | 0x800;
        *(_QWORD *)(*(_QWORD *)(a1 + 8) + 184i64) = v56;
        _InterlockedOr(v59, 0);
        KeStallExecutionProcessor(0x64u);
        if( *(_QWORD *)(*(_QWORD *)(a1 + 8) + 184i64) != v56 )
          KeBugCheckEx(0x5Cu, (PVOID)0x7000, 0i64, 0i64, 0i64);
        IvtUpdateGlobalCommand(a1, 0x1000000ui64, 1);
      }
      if( v69 )
      {
        *(_QWORD *)(*(_QWORD *)(a1 + 8) + 192i64) = 0i64;
        _InterlockedOr(v59, 0);
        *(_QWORD *)(*(_QWORD *)(a1 + 8) + 200i64) = 0i64;
        _InterlockedOr(v59, 0);
        *(_QWORD *)(*(_QWORD *)(a1 + 8) + 208i64) = *((_QWORD *)&v66 + 1);
        _InterlockedOr(v59, 0);
        IvtInitializeMTRR(a1);
      }
      if( !*(_QWORD *)(a1 + 144) )
      {
        LODWORD(v57) = MmGetPhysicalAddress(a1 + 136);
        v58 = *(_DWORD *)(a1 + 160);
        *(_QWORD *)(a1 + 144) = v57;
        *(_QWORD *)(a1 + 160) = v58 & 3 | v57 & 0xFFFFFFFFFFFFFFFCui64;
        *(_QWORD *)(a1 + 152) = *(_QWORD *)(a1 + 152) & 0xFFFFFFFFFFFFFF90ui64 | 0x65;
      }
      v10 = 0x4000000i64;
      goto LABEL_92;
    }
    v15.QuadPart = (*(&CmpDummyThreadEvent + 447))(-1i64, 1i64);
    *(_LARGE_INTEGER *)(a1 + 48) = v15;
    if( !v15.QuadPart )
      return -1073741823;
    v17 = HalMapIoSpace(v15, 0x1000ui64, (_MEMORY_CACHING_TYPE)((*(_BYTE *)(a1 + 184) & 1) != 0), v16);
    *(_QWORD *)(a1 + 40) = v17;
    if( !v17 )
      return -1073741823;
    if( !IvtBlockedPageTable )
    {
      v18.QuadPart = (*(&CmpDummyThreadEvent + 447))(-1i64, 1i64);
      *(&CmpDummyThreadEvent + 444) = v18.QuadPart;
      if( !v18.QuadPart )
        return -1073741823;
      v20 = (VOID *)HalMapIoSpace(v18, 0x1000ui64, (_MEMORY_CACHING_TYPE)(*(_DWORD *)(a1 + 184) & 1), v19);
      IvtBlockedPageTable = (__int64)v20;
      if( !v20 )
        return -1073741823;
      memset(v20, 0i64, 0x1000u);
    }
    ContextEntryType = 0;
    if( v3 == 1 )
    {
      if( *(_BYTE *)(a1 + 270) )
      {
        ContextEntryType = IvtGetContextEntryType(0, 1);
        LODWORD(v22) = IvtGetIdentityMappedDomain(a1, &v63);
        goto LABEL_31;
      }
      ContextEntryType = IvtGetContextEntryType(0, 0);
    }
    if( v3 != 2 )
    {
LABEL_32:
      if( (*(_DWORD *)(a1 + 184) & 0x1000000) != 0 )
      {
        IvtBuildExtendedContextEntry(a1, ContextEntryType, 0i64, 0, 0, v7, v63, (INT64)v67);
        v23 = *(INT64 **)(a1 + 40);
        if( v23 < v23 + 512 )
        {
          v24 = v67[0];
          v25 = *((_QWORD *)&v68 + 1);
          v26 = v68;
          v27 = v67[0] & 1;
          v28 = v67[1];
          do
          {
            if( v27 )
            {
              v23[3] = v25;
              v23[2] = v26;
              v23[1] = v28;
              *v23 = v24;
            }
            else
            {
              *v23 = 0i64;
              v23[1] = 0i64;
              v23[2] = 0i64;
              v23[3] = 0i64;
            }
            v23 += 4;
          }
          while( (unsigned __int64)v23 < *(_QWORD *)(a1 + 40) + 4096i64 );
        }
      }
      else
      {
        IvtBuildContextEntry(a1, ContextEntryType, v7, v63, v65);
        v29 = *(INT64 **)(a1 + 40);
        if( v29 < v29 + 512 )
        {
          v30 = v65[0];
          v31 = v65[1];
          v32 = v65[0] & 1;
          do
          {
            if( v32 )
            {
              v29[1] = v31;
              *v29 = v30;
            }
            else
            {
              *v29 = 0i64;
              v29[1] = 0i64;
            }
            v29 += 2;
          }
          while( (unsigned __int64)v29 < *(_QWORD *)(a1 + 40) + 4096i64 );
        }
      }
      v5 = a3;
      goto LABEL_47;
    }
    ContextEntryType = IvtGetContextEntryType(0, 1);
    LODWORD(v22) = IvtGetBlockedDomain(a1, 0i64, (UINT64 *)&v63);
LABEL_31:
    v7 = v22;
    goto LABEL_32;
  }
  if( (_DWORD)a2 != 1 )
    return -1073741823;
  if( v4 )
  {
    IvtInvalidateRemappingTableEntries((_QWORD *)a1, 0i64);
    IvtUpdateGlobalCommand(a1, 0x2000000ui64, 1);
  }
  if( !v3 )
    return 0;
  IvtInvalidateAllContextEntries((_QWORD *)a1);
  v64[1] = (INT64)v64;
  v64[0] = (INT64)v64;
  if( (*(_DWORD *)(a1 + 184) & 0x1000000) != 0 )
  {
    LODWORD(v61) = 0;
    LOBYTE(v9) = 1;
    IvtFlushTbInternal(a1, v8, 0i64, v9, 0, v60, (INT64)v64, v61, 0i64);
  }
  LODWORD(v61) = 0;
  LOBYTE(v9) = 1;
  IvtFlushTbInternal(a1, v8, 0i64, v9, 1, v60, (INT64)v64, v61, 0i64);
  v10 = 0x80000000i64;
LABEL_92:
  IvtUpdateGlobalCommand(a1, v10, 1);
  return 0;
}

Referenced by:

No references.