HsaInitializeIommu

NTSTATUS __stdcall HsaInitializeIommu(INT64 a1, INT64 a2, CHAR a3){
  int v3; 
  int v4; 
  NTSTATUS result; 
  _LARGE_INTEGER v7; 
  UINT8 v8; 
  VOID *v9; 
  UINT8 v10; 
  UINT64 v11; 
  unsigned int v12; 
  __int64 *v13; 
  _QWORD *v14; 
  __int64 v15; 
  UINT64 v16; 
  bool v17; 
  __int64 v18; 
  UINT8 v19; 
  VOID *v20; 
  unsigned int v21; 
  __int64 v22; 
  __int64 v23; 
  __int16 v24; 
  __int16 BlockedDomain; 
  int v26; 
  __int128 v27; 
  _QWORD *v28; 
  unsigned __int64 v29; 
  __int64 v30; 
  unsigned int i; 
  __int64 v32; 
  __int16 v33; 
  char v34; 
  __int64 v35; 
  __int64 v36; 
  __int64 v37; 
  __int64 v38; 
  __int64 v39; 
  __int64 v40; 
  __int64 v41; 
  __int64 v42; 
  signed __int32 v43[8]; 
  CHAR v44; 
  char v45[12]; 
  int v46; 
  __int128 v47; 
  __int128 v48; 
  __int64 v49[4]; 

  v3 = *(_DWORD *)(a1 + 176);
  v4 = *(_DWORD *)(a1 + 172);
  v44 = a3;
  memset(v45, 0, sizeof(v45));
  v46 = v3;
  v47 = 0i64;
  v48 = 0i64;
  if( !(_DWORD)a2 )
  {
    result = HalSocRequestApi(a1, 0i64, 4i64, 8ui64, (char *)&CmpDummyThreadEvent + 3248);
    if( result < 0 )
      return result;
    if( !v4 && !v3 )
      goto LABEL_38;
    if( v4 == 2 && !HsaBlockedPageTable )
    {
      v7.QuadPart = (*(&CmpDummyThreadEvent + 406))(-1i64, 1i64);
      *(&CmpDummyThreadEvent + 407) = v7.QuadPart;
      if( !v7.QuadPart )
        return -1073741823;
      v9 = (VOID *)HalMapIoSpace(v7, 0x1000ui64, (_MEMORY_CACHING_TYPE)((*(unsigned __int8 *)(a1 + 16) >> 5) & 1), v8);
      HsaBlockedPageTable = (__int64)v9;
      if( !v9 )
        return -1073741823;
      memset(v9, 0i64, 0x1000u);
    }
    result = HsaInitializeInterruptRemapping(a1);
    if( result < 0 )
      return result;
    if( *(_QWORD *)a1
      || (v11 = HalMapIoSpace(*(_LARGE_INTEGER *)(a1 + 8), 0x2040ui64, MmNonCached, v10), (*(_QWORD *)a1 = v11) != 0i64) )
    {
      v12 = 0;
      v13 = v49;
      v14 = (_QWORD *)(a1 + 24);
      do
      {
        if( v12 )
        {
          if( v12 == 3 )
          {
            v15 = 2i64;
            v16 = 0x2000i64;
          }
          else
          {
            v15 = 1i64;
            v16 = 4096i64;
          }
        }
        else
        {
          v15 = 512i64;
          v16 = 0x200000i64;
        }
        v17 = *v14 == 0i64;
        v14[2] = v16;
        if( v17 )
        {
          v18 = (*(&CmpDummyThreadEvent + 406))(-1i64, v15);
          v14[1] = v18;
          if( !v18 )
            return -1073741823;
          v20 = (VOID *)HalMapIoSpace(*(_LARGE_INTEGER *)(a1 + 24i64 * v12 + 32), v16, MmNonCached, v19);
          *v14 = v20;
          if( !v20 )
            return -1073741823;
          memset(v20, 0i64, v16);
          v21 = 0;
          if( !v12 )
          {
            v22 = *(_QWORD *)(a1 + 24);
            *(_DWORD *)v45 = 0;
            do
            {
              v23 = 0i64;
              v24 = 0;
              *(_QWORD *)&v45[4] = 0i64;
              if( v4 == 2 )
              {
                BlockedDomain = HsaGetBlockedDomain(a1, (INT64 *)v45, (UINT64 *)&v45[4]);
                v23 = *(_QWORD *)&v45[4];
                v24 = BlockedDomain;
                v26 = 2;
              }
              else
              {
                v26 = 0;
              }
              HsaBuildDeviceTableEntry(
                a1,
                0i64,
                0,
                v24,
                v26,
                v23,
                0i64,
                (INT64)&CmpDummyThreadEvent + 3168,
                v22 + 32i64 * v21++);
              *(_DWORD *)v45 = v21;
            }
            while( v21 < 0x10000 );
          }
        }
        ++v12;
        v27 = (__int64)v14[1];
        v14 += 3;
        *v13++ = (__int64)((WORD4(v27) & 0xFFF) + (_QWORD)v27) >> 12;
      }
      while( v12 < 4 );
      if( v4 != 2 || v44 || HsaProcessDeviceExceptions(a1) >= 0 )
      {
        v28 = (_QWORD *)(a1 + 64);
        v29 = 0i64;
        v30 = 3i64;
        do
        {
          for( i = 15; i > 8; --i )
          {
            if( (unsigned __int64)(1i64 << i) <= *v28 >> 4 )
              break;
          }
          v28 += 3;
          v32 = *(_QWORD *)((char *)&v47 + v29 + 8) ^ (*(_QWORD *)((char *)&v47 + v29 + 8) ^ (v49[v29 / 8 + 1] << 12)) & 0xFFFFFFFFFF000i64;
          *(_QWORD *)((char *)&v47 + v29 + 8) = v32 ^ (v32 ^ ((unsigned __int64)i << 56)) & 0xF00000000000000i64;
          v29 += 8i64;
          --v30;
        }
        while( v30 );
        v3 = v46;
LABEL_38:
        **(_QWORD **)a1 = ((v49[0] & 0xFFFFFFFFFFi64) << 12) | ((unsigned __int16)(*(_QWORD *)(a1 + 40) >> 12)
                                                              + ((*(_QWORD *)(a1 + 40) & 0xFFFi64) != 0)
                                                              - 1) & 0x1FF;
        _InterlockedOr(v43, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8i64) = *((_QWORD *)&v47 + 1);
        _InterlockedOr(v43, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 16i64) = v48;
        _InterlockedOr(v43, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 0x2000i64) = 0i64;
        _InterlockedOr(v43, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8200i64) = 0i64;
        _InterlockedOr(v43, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8208i64) = 0i64;
        _InterlockedOr(v43, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8216i64) = 0i64;
        _InterlockedOr(v43, 0);
        v33 = *(_WORD *)(a1 + 18);
        if( (v33 & 8) != 0 )
        {
          *(_QWORD *)(*(_QWORD *)a1 + 56i64) = *((_QWORD *)&v48 + 1);
          _InterlockedOr(v43, 0);
          v33 = *(_WORD *)(a1 + 18);
        }
        v34 = *(_BYTE *)(a1 + 16);
        v35 = (2i64 * (v34 & 1) + 69637) | 0x100;
        if( (v34 & 2) == 0 )
          v35 = 2i64 * (*(_BYTE *)(a1 + 16) & 1) + 69637;
        v36 = v35 | 0x200;
        if( (*(_BYTE *)(a1 + 16) & 4) == 0 )
          v36 = v35;
        v37 = v36 | 0x400;
        if( (v34 & 0x20) == 0 )
          v37 = v36;
        v38 = v37 | 0x800;
        if( (v34 & 8) == 0 )
          v38 = v37;
        v39 = v38 | 0x800000A000i64;
        if( (v33 & 4) == 0 )
          v39 = v38;
        v40 = v39 | 0x60;
        if( !*(_QWORD *)(a1 + 128) )
        {
          LODWORD(v41) = MmGetPhysicalAddress(a1 + 120);
          *(_QWORD *)(a1 + 128) = v41;
          *(_QWORD *)(a1 + 136) = *(_QWORD *)(a1 + 136) & 0xFF0000000000002i64 | (8 * ((v41 >> 3) & 0x1FFFFFFFFFFFFi64)) | 0x1000000000000005i64;
        }
        v42 = v40 | 0xC000000020000i64;
        if( !v3 )
          v42 = v40;
        *(_QWORD *)(*(_QWORD *)a1 + 24i64) = v42;
        _InterlockedOr(v43, 0);
        if( (*(_BYTE *)(a1 + 18) & 0x10) != 0 )
        {
          *(_DWORD *)(*(_QWORD *)a1 + 364i64) = 0x2000;
          _InterlockedOr(v43, 0);
        }
        return 0;
      }
    }
    return -1073741823;
  }
  return 0;
}

Referenced by:

No references.