HsaInitializeIommu

INT64 __fastcall HsaInitializeIommu(INT64 a1, INT64 a2, CHAR a3){
  int v3; 
  int v4; 
  INT64 result; 
  LARGE_INTEGER v7; 
  PVOID v8; 
  PVOID v9; 
  unsigned int v10; 
  __int64 *v11; 
  _QWORD *v12; 
  __int64 v13; 
  SIZE_T v14; 
  bool v15; 
  __int64 v16; 
  PVOID v17; 
  unsigned int v18; 
  __int64 v19; 
  INT64 a6; 
  INT16 v21; 
  INT16 BlockedDomain; 
  int v23; 
  __int128 v24; 
  _QWORD *v25; 
  unsigned __int64 v26; 
  __int64 v27; 
  unsigned int i; 
  __int64 v29; 
  __int16 v30; 
  char v31; 
  __int64 v32; 
  __int64 v33; 
  __int64 v34; 
  __int64 v35; 
  __int64 v36; 
  __int64 v37; 
  PHYSICAL_ADDRESS PhysicalAddress; 
  __int64 v39; 
  signed __int32 v40[8]; 
  INT64 a5; 
  CHAR v42; 
  char v43[12]; 
  int v44; 
  __int128 v45; 
  __int128 v46; 
  __int64 v47[4]; 
  v3 = *(_DWORD *)(a1 + 176);
  v4 = *(_DWORD *)(a1 + 172);
  v42 = a3;
  memset(v43, 0, sizeof(v43));
  v44 = v3;
  v45 = 0i64;
  v46 = 0i64;
  if( !(_DWORD)a2 )
  {
    result = HalSocRequestApi(a1, 0i64, 4i64, 8ui64, &HsaPhysicalMemoryApi);
    if( (int)result < 0 )
      return result;
    if( !v4 && !v3 )
      goto LABEL_38;
    if( v4 == 2 && !HsaBlockedPageTable )
    {
      v7.QuadPart = ((__int64(__fastcall *)(__int64, __int64))HsaPhysicalMemoryApi)(-1i64, 1i64);
      HsaBlockedPageTablePhysical = v7.QuadPart;
      if( !v7.QuadPart )
        return 3221225473i64;
      v8 = HalMapIoSpace(v7, 0x1000ui64, (MEMORY_CACHING_TYPE)((*(unsigned __int8 *)(a1 + 16) >> 5) & 1));
      HsaBlockedPageTable = (__int64)v8;
      if( !v8 )
        return 3221225473i64;
      memset((INT64)v8, 0i64);
    }
    result = HsaInitializeInterruptRemapping(a1);
    if( (int)result < 0 )
      return result;
    if( *(_QWORD *)a1
      || (v9 = HalMapIoSpace(*(LARGE_INTEGER *)(a1 + 8), 0x2040ui64, MmNonCached), (*(_QWORD *)a1 = v9) != 0i64) )
    {
      v10 = 0;
      v11 = v47;
      v12 = (_QWORD *)(a1 + 24);
      do
      {
        if( v10 )
        {
          if( v10 == 3 )
          {
            v13 = 2i64;
            v14 = 0x2000i64;
          }
          else
          {
            v13 = 1i64;
            v14 = 4096i64;
          }
        }
        else
        {
          v13 = 512i64;
          v14 = 0x200000i64;
        }
        v15 = *v12 == 0i64;
        v12[2] = v14;
        if( v15 )
        {
          v16 = ((__int64(__fastcall *)(__int64, __int64))HsaPhysicalMemoryApi)(-1i64, v13);
          v12[1] = v16;
          if( !v16 )
            return 3221225473i64;
          v17 = HalMapIoSpace(*(LARGE_INTEGER *)(a1 + 24i64 * v10 + 32), v14, MmNonCached);
          *v12 = v17;
          if( !v17 )
            return 3221225473i64;
          memset((INT64)v17, 0i64);
          v18 = 0;
          if( !v10 )
          {
            v19 = *(_QWORD *)(a1 + 24);
            *(_DWORD *)v43 = 0;
            do
            {
              a6 = 0i64;
              v21 = 0;
              *(_QWORD *)&v43[4] = 0i64;
              if( v4 == 2 )
              {
                BlockedDomain = HsaGetBlockedDomain(a1, (INT64 *)v43, (UINT64 *)&v43[4]);
                a6 = *(_QWORD *)&v43[4];
                v21 = BlockedDomain;
                v23 = 2;
              }
              else
              {
                v23 = 0;
              }
              LODWORD(a5) = v23;
              HsaBuildDeviceTableEntry(
                a1,
                0i64,
                0,
                v21,
                a5,
                a6,
                0i64,
                (INT64)&HsaSharedRemappingTable,
                v19 + 32i64 * v18++);
              *(_DWORD *)v43 = v18;
            }
            while( v18 < 0x10000 );
          }
        }
        ++v10;
        v24 = (__int64)v12[1];
        v12 += 3;
        *v11++ = (__int64)((WORD4(v24) & 0xFFF) + (_QWORD)v24) >> 12;
      }
      while( v10 < 4 );
      if( v4 != 2 || v42 || (int)HsaProcessDeviceExceptions(a1) >= 0 )
      {
        v25 = (_QWORD *)(a1 + 64);
        v26 = 0i64;
        v27 = 3i64;
        do
        {
          for( i = 15; i > 8; --i )
          {
            if( (unsigned __int64)(1i64 << i) <= *v25 >> 4 )
              break;
          }
          v25 += 3;
          v29 = *(_QWORD *)((char *)&v45 + v26 + 8) ^ (*(_QWORD *)((char *)&v45 + v26 + 8) ^ (v47[v26 / 8 + 1] << 12)) & 0xFFFFFFFFFF000i64;
          *(_QWORD *)((char *)&v45 + v26 + 8) = v29 ^ (v29 ^ ((unsigned __int64)i << 56)) & 0xF00000000000000i64;
          v26 += 8i64;
          --v27;
        }
        while( v27 );
        v3 = v44;
LABEL_38:
        **(_QWORD **)a1 = ((v47[0] & 0xFFFFFFFFFFi64) << 12) | ((unsigned __int16)(*(_QWORD *)(a1 + 40) >> 12)
                                                              + ((*(_QWORD *)(a1 + 40) & 0xFFFi64) != 0)
                                                              - 1) & 0x1FF;
        _InterlockedOr(v40, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8i64) = *((_QWORD *)&v45 + 1);
        _InterlockedOr(v40, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 16i64) = v46;
        _InterlockedOr(v40, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 0x2000i64) = 0i64;
        _InterlockedOr(v40, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8200i64) = 0i64;
        _InterlockedOr(v40, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8208i64) = 0i64;
        _InterlockedOr(v40, 0);
        *(_QWORD *)(*(_QWORD *)a1 + 8216i64) = 0i64;
        _InterlockedOr(v40, 0);
        v30 = *(_WORD *)(a1 + 18);
        if( (v30 & 8) != 0 )
        {
          *(_QWORD *)(*(_QWORD *)a1 + 56i64) = *((_QWORD *)&v46 + 1);
          _InterlockedOr(v40, 0);
          v30 = *(_WORD *)(a1 + 18);
        }
        v31 = *(_BYTE *)(a1 + 16);
        v32 = (2i64 * (v31 & 1) + 69637) | 0x100;
        if( (v31 & 2) == 0 )
          v32 = 2i64 * (*(_BYTE *)(a1 + 16) & 1) + 69637;
        v33 = v32 | 0x200;
        if( (*(_BYTE *)(a1 + 16) & 4) == 0 )
          v33 = v32;
        v34 = v33 | 0x400;
        if( (v31 & 0x20) == 0 )
          v34 = v33;
        v35 = v34 | 0x800;
        if( (v31 & 8) == 0 )
          v35 = v34;
        v36 = v35 | 0x800000A000i64;
        if( (v30 & 4) == 0 )
          v36 = v35;
        v37 = v36 | 0x60;
        if( !*(_QWORD *)(a1 + 128) )
        {
          PhysicalAddress = MmGetPhysicalAddress((PVOID)(a1 + 120));
          *(PHYSICAL_ADDRESS *)(a1 + 128) = PhysicalAddress;
          *(_QWORD *)(a1 + 136) = *(_QWORD *)(a1 + 136) & 0xFF0000000000002i64 | (8
                                                                                * ((PhysicalAddress.QuadPart >> 3) & 0x1FFFFFFFFFFFFi64)) | 0x1000000000000005i64;
        }
        v39 = v37 | 0xC000000020000i64;
        if( !v3 )
          v39 = v37;
        *(_QWORD *)(*(_QWORD *)a1 + 24i64) = v39;
        _InterlockedOr(v40, 0);
        if( (*(_BYTE *)(a1 + 18) & 0x10) != 0 )
        {
          *(_DWORD *)(*(_QWORD *)a1 + 364i64) = 0x2000;
          _InterlockedOr(v40, 0);
        }
        return 0i64;
      }
    }
    return 3221225473i64;
  }
  return 0i64;
}

Referenced by:

No references.