HalpIommuProcessIvhdEntry

INT64 __fastcall HalpIommuProcessIvhdEntry(INT64 a1, INT64 a2, CHAR *a3){
  CHAR v6; 
  bool v7; 
  __int64 *v8; 
  unsigned __int64 v9; 
  __int16 v10; 
  __int16 v11; 
  __int16 v12; 
  INT64 ReservedDomainList; 
  INT64 v14; 
  INT64 v15; 
  INT64 v16; 
  unsigned int v17; 
  int v18; 
  unsigned int *v19; 
  UINT64 v20; 
  void *v21; 
  INT64 v22; 
  _QWORD *v23; 
  _QWORD *v24; 
  INT64 v25; 
  unsigned int *a4; 
  INT64 v27[2]; 
  INT64 arg1[2]; 
  int v29; 
  unsigned int v30; 
  INT64 *v31; 
  INT64 *v32; 
  int v33; 
  int v34; 
  int v35; 
  int v36; 
  int v37; 
  int v38; 
  int v39; 
  INT64 result[2]; 
  INT64 v41[16]; 
  INT64 v42[28]; 
  char a3a; 
  BYTE v44; 
  INT64 v45; 
  v6 = 0;
  v25 = 0i64;
  memset((INT64)result, 0i64);
  memset((INT64)v42, 0i64);
  v7 = *(_WORD *)(a2 + 2) < 0x28u;
  v27[0] = 0i64;
  v45 = 0i64;
  a4 = 0i64;
  *a3 = 0;
  v44 = 0;
  a3a = 0;
  if( v7 || *(_BYTE *)a2 != 17 && *(_BYTE *)a2 != 64 )
    return 3221225485i64;
  v8 = (__int64 *)HsaIvhdList;
  if( (__int64 *)HsaIvhdList != &HsaIvhdList )
  {
    while( v8[2] != *(_QWORD *)(a2 + 8) )
    {
      v8 = (__int64 *)*v8;
      if( v8 == &HsaIvhdList )
        goto LABEL_7;
    }
    return 0i64;
  }
LABEL_7:
  v9 = *(_QWORD *)(a2 + 24);
  v10 = (4 * *(_WORD *)(a2 + 24)) & 8 | (16 * ((v9 >> 45) & 1)) | 1;
  if( (*(_BYTE *)(a2 + 1) & 0x10) == 0 || (v9 & 0x600000000008i64) != 0x600000000008i64 )
    v10 = (4 * *(_WORD *)(a2 + 24)) & 8 | (16 * ((v9 >> 45) & 1));
  v11 = v10 | 4;
  if( (v11 & 1) == 0
    || (v9 & 0x12) != 18
    || (v9 & 0xC000) == 0
    || (v9 & 0x20000000000i64) == 0
    || (BYTE4(v9) & 0x1Fu) < 8 )
  {
    v11 &= ~4u;
  }
  v12 = v11 | 2;
  if( (v9 & 0x84) != 0x84 )
    v12 = v11;
  if( (v12 & 3) == 0 )
    return 0i64;
  ReservedDomainList = HsaProcessIvmd(a2, a1 + *(unsigned int *)(a1 + 4), &a3a, &a4);
  if( (int)ReservedDomainList >= 0 )
  {
    ReservedDomainList = ExtEnvAllocateMemory(v14, 0xF0ui64, &v45);
    if( (int)ReservedDomainList >= 0 )
    {
      v15 = v45;
      memset(v45, 0i64);
      memset((INT64)v41, 0i64);
      *(_QWORD *)(v15 + 232) = v15 + 224;
      *(_QWORD *)(v15 + 224) = v15 + 224;
      *(_BYTE *)(v15 + 16) = *(_BYTE *)(a2 + 1);
      *(_WORD *)(v15 + 18) = v12;
      *(_QWORD *)(v15 + 8) = *(_QWORD *)(a2 + 8);
      *(_DWORD *)(v15 + 160) = *(unsigned __int16 *)(a2 + 16);
      *(_DWORD *)(v15 + 164) = *(unsigned __int8 *)(a2 + 5);
      *(_DWORD *)(v15 + 168) ^= (*(_DWORD *)(v15 + 168) ^ (*(unsigned __int16 *)(a2 + 4) >> 3)) & 0x1F;
      v16 = *(_DWORD *)(v15 + 168) ^ ((unsigned __int8)*(_DWORD *)(v15 + 168) ^ (unsigned __int8)(32 * *(_WORD *)(a2 + 4))) & 0xE0u;
      *(_DWORD *)(v15 + 168) = v16;
      ReservedDomainList = ExtEnvAllocateMemory(v16, 0x2000ui64, &v25);
      if( (int)ReservedDomainList >= 0 )
      {
        *(_QWORD *)(v15 + 192) = v25;
        *(_DWORD *)(v15 + 184) = 0x10000;
        RtlClearBits((RTL_BITMAP *)(v15 + 184), 0i64, 0x10000ui64);
        *(_QWORD *)(v15 + 152) = 0i64;
        ReservedDomainList = HalpIommuProcessDeviceEntries(v15, a2, &v44);
        if( (int)ReservedDomainList >= 0 )
        {
          LODWORD(ReservedDomainList) = HalRegisterPermanentAddressUsage(*(LARGE_INTEGER *)(v15 + 8), 0x2040u);
          if( (int)ReservedDomainList >= 0 )
          {
            memset((INT64)arg1, 0i64);
            v34 = *(_DWORD *)(v15 + 160);
            v17 = 2076;
            v35 = *(_DWORD *)(v15 + 164);
            v36 = *(_DWORD *)(v15 + 168);
            v31 = result;
            v32 = v42;
            result[0] = (INT64)HsaConfigureSettings;
            result[1] = (INT64)HsaInitializeIommu;
            arg1[0] = 0x6800000001i64;
            arg1[1] = v15;
            v29 = 0;
            v33 = 1;
            v39 = 16;
            v30 = 2076;
            if( (v12 & 1) != 0 )
            {
              v41[2] = (INT64)HsaCreateDevice;
              v41[3] = (INT64)IvtDeleteDevice;
              v42[0] = (INT64)HsaFindDevice;
              v42[5] = (INT64)HsaFlushTb;
              v42[6] = (INT64)HsaFlushDeviceTbOnly;
              v42[19] = (INT64)HsaQueryAcpiDeviceMapping;
              v42[20] = (INT64)HsaGetRidAcpiMapCount;
              if( !a3a )
              {
                v17 = 2332;
                v42[17] = (INT64)HsaEnumerateIvmdDevices;
                v42[18] = (INT64)HsaProcessReservedDomains;
                v41[5] = (INT64)HsaAttachDeviceDomain;
                v41[6] = (INT64)HsaDetachDeviceDomain;
              }
              v17 |= 0x3000u;
              v41[7] = (INT64)HsaFlushDomainTb;
              v41[8] = (INT64)xHalTimerWatchdogStop;
              v41[9] = (INT64)xHalTimerWatchdogStop;
              v30 = v17;
            }
            v18 = 0x40000;
            if( (unsigned int)((1 << ((BYTE4(v9) & 0x1F) + 1)) - 1) < 0x40000 )
              v18 = (1 << ((BYTE4(v9) & 0x1F) + 1)) - 1;
            v37 = v18;
            if( (v12 & 4) != 0 )
            {
              v17 |= 0x20u;
              v42[1] = (INT64)HsaSetDeviceSvmCapabilities;
              v42[2] = (INT64)HsaSetDevicePasidTable;
              v42[3] = (INT64)HsaGrowPasidTable;
              v42[4] = (INT64)HsaSetPasidAddressSpace;
              v42[7] = (INT64)HsaDismissPageFault;
              v42[8] = (INT64)HsaGetPageFault;
              v42[14] = (INT64)HsaMarkHiberRegions;
              v30 = v17;
            }
            if( (v12 & 2) != 0 )
            {
              v41[12] = (INT64)HsaUpdateRemappingTableEntry;
              v17 = v17 & 0xFFFFFFAF | 0x40;
              v30 = v17;
              v41[13] = (INT64)HsaInvalidateRemappingTableEntry;
              v41[14] = (INT64)HsaUpdateRemappingDestination;
              v41[10] = (INT64)HsaAllocateRemappingTableEntry;
              v41[11] = (INT64)HsaFreeRemappingTableEntry;
            }
            if( (v12 & 4) != 0 )
            {
              v42[9] = (INT64)HsaSetMessageInterruptRouting;
              v42[10] = (INT64)HsaEnableInterrupt;
              v42[11] = (INT64)HsaDisableInterrupt;
              v42[12] = (INT64)HsaHandleInterrupt;
              v30 = v17 | 2;
            }
            v19 = a4;
            v20 = *a4;
            v38 = 65534 - v20;
            ReservedDomainList = HalpHsaAllocateReservedDomainList(v15, (unsigned int)(65534 - v20), v20);
            if( (int)ReservedDomainList >= 0 )
            {
              *(_DWORD *)(v15 + 200) = 65534;
              *(_QWORD *)(v15 + 208) = v19;
              LODWORD(ReservedDomainList) = ExtEnvRegisterIommu(arg1, v21);
              if( (int)ReservedDomainList >= 0 )
              {
                ReservedDomainList = ExtEnvAllocateMemory(v22, 0x18ui64, v27);
                if( (int)ReservedDomainList >= 0 )
                {
                  v23 = (_QWORD *)v27[0];
                  *(_OWORD *)v27[0] = 0i64;
                  v23[2] = 0i64;
                  v23[2] = *(_QWORD *)(a2 + 8);
                  v24 = (_QWORD *)qword_140C486E8;
                  if( *(__int64 **)qword_140C486E8 != &HsaIvhdList )
                    __fastfail(3u);
                  *v23 = &HsaIvhdList;
                  v23[1] = v24;
                  *v24 = v23;
                  qword_140C486E8 = (__int64)v23;
                  if( a3a || v44 )
                    v6 = 1;
                  *a3 = v6;
                  return 0i64;
                }
              }
            }
          }
        }
      }
    }
  }
  return ReservedDomainList;
}

Referenced by:

HalpIommuHsaDiscover