HalpIvtProcessDrhdEntry

INT64 __fastcall HalpIvtProcessDrhdEntry(UINT64 a1, UINT64 a2){
  int ReservedDomainList; 
  char v5; 
  INT64 v6; 
  int Memory; 
  UINT64 v8; 
  LARGE_INTEGER v9; 
  int v10; 
  unsigned __int64 v11; 
  unsigned __int64 v12; 
  unsigned __int64 v13; 
  char v14; 
  int v15; 
  unsigned __int64 v16; 
  _BYTE *NextDrhdDeviceScope; 
  int v18; 
  __int64 v19; 
  _DWORD *v20; 
  int v21; 
  unsigned int v22; 
  void *v23; 
  INT64 v24; 
  UINT64 v25; 
  bool v26; 
  UINT64 v27; 
  INT64 v28; 
  int v30; 
  _DWORD v31[3]; 
  unsigned int Size; 
  int Size_4; 
  INT64 v34; 
  PVOID VirtualAddress; 
  INT64 arg1[2]; 
  int v37; 
  int v38; 
  INT64 *v39; 
  INT64 *v40; 
  int v41; 
  int v42; 
  int v43; 
  unsigned int v44; 
  int v45; 
  ULONG_PTR v46[2]; 
  INT64 result[18]; 
  INT64 v48[30]; 
  char v50; 
  char v51; 
  int v52; 
  *(_OWORD *)v46 = 0i64;
  memset((INT64)result, 0i64);
  memset((INT64)v48, 0i64);
  ReservedDomainList = 0;
  v34 = 0i64;
  v5 = 0;
  v52 = 0;
  *(_QWORD *)&v31[1] = 0i64;
  v51 = 0;
  v50 = 0;
  if( *(_WORD *)a2 )
    return(unsigned int)-1073741823;
  if( *(_WORD *)(a2 + 2) < 0x10u )
    return(unsigned int)-1073741811;
  if( !*(_QWORD *)(a2 + 8) )
    return(unsigned int)ReservedDomainList;
  if( (int)HalSocRequestApi(16i64, 0i64, 2i64, 0x10ui64, v46) < 0
    || !((unsigned __int8(__fastcall *)(_QWORD, _QWORD, _QWORD, char *))v46[0])(0i64, 0i64, 0i64, &v50) )
  {
    v50 = 0;
  }
  Memory = ExtEnvAllocateMemory(v6, 0x18ui64, (INT64 *)&v31[1]);
  v8 = *(_QWORD *)&v31[1];
  ReservedDomainList = Memory;
  if( Memory < 0 )
    goto LABEL_62;
  ReservedDomainList = DmrEnumerateRmrrDomains(a1, a2 + 4, *(INT64 *)&v31[1]);
  if( ReservedDomainList < 0 )
    goto LABEL_62;
  memset((INT64)arg1, 0i64);
  v9 = *(LARGE_INTEGER *)(a2 + 8);
  arg1[0] = 0x6800000001i64;
  VirtualAddress = HalMapIoSpace(v9, 0x220ui64, MmNonCached);
  if( !VirtualAddress )
  {
    ReservedDomainList = -1073741670;
LABEL_62:
    if( v8 )
    {
      DmrFreeRmrrTree(v8);
      ExtEnvFreeMemory(v28, v8);
    }
    return(unsigned int)ReservedDomainList;
  }
  ReservedDomainList = HalRegisterPermanentAddressUsage(v9, 0x220u);
  if( ReservedDomainList >= 0 )
  {
    v10 = *(unsigned __int16 *)(a2 + 2) - 16;
    arg1[1] = 0i64;
    Size = v10;
    v37 = v10 + 304;
    v39 = result;
    v40 = v48;
    result[0] = (INT64)IvtConfigureSettings;
    result[1] = (INT64)IvtInitializeIommu;
    result[4] = (INT64)IvtCreateDevice;
    result[5] = (INT64)IvtDeleteDevice;
    v48[13] = (INT64)IvtCheckForReservedRegion;
    v48[0] = (INT64)IvtFindDevice;
    v48[17] = (INT64)IvtEnumerateRmrrDevices;
    v42 = *(unsigned __int16 *)(a2 + 6);
    v41 = 2;
    v45 = 16;
    v38 = 4;
    v11 = *((_QWORD *)VirtualAddress + 1) & 0xFFFFFFFFFFFFEEFFui64;
    _BitScanReverse((unsigned int *)&v10, (v11 >> 8) & 0x1F);
    v52 = v10;
    v12 = *((_QWORD *)VirtualAddress + 2);
    v13 = 1i64 << (((unsigned __int8)(v12 >> 35) & 0x1Fu) + 1);
    if( v13 > 0x100000 )
      LODWORD(v13) = 0x100000;
    v14 = *(_BYTE *)(a1 + 37) & 3;
    v43 = v13;
    if( v14 == 1 && (v12 & 0x18) == 24 )
    {
      result[14] = (INT64)IvtUpdateRemappingTableEntry;
      v15 = 68;
      v38 = 68;
      result[15] = (INT64)IvtInvalidateRemappingTableEntry;
      result[16] = (INT64)IvtUpdateRemappingDestination;
    }
    else
    {
      v15 = v38;
    }
    if( v50 == 2
      && (v12 & 2) != 0
      && (v11 & 0x80u) == 0i64
      && (v12 & 0x40) != 0
      && ((v11 >> 8) & 0x1F) != 0
      && (v11 & 0x80000000000000i64) != 0
      && (v11 & 0x40000000000000i64) != 0
      && (v11 & 0x10) == 0 )
    {
      v31[0] = v52;
      result[9] = (INT64)IvtFlushDomainTb;
      result[10] = (INT64)xHalTimerWatchdogStop;
      result[11] = (INT64)xHalTimerWatchdogStop;
      result[7] = (INT64)IvtAttachDeviceDomain;
      result[8] = (INT64)IvtDetachDeviceDomain;
      v48[18] = (INT64)IvtProcessReservedDomains;
      _BitScanReverse64(&v16, (v11 >> 8) & 0x1F);
      v15 |= (((_DWORD)v16 << 12) + 4096) | 0x100;
      v38 = v15;
    }
    if( (v12 & 1) != 0 )
    {
      v15 |= 0x800u;
      v38 = v15;
    }
    NextDrhdDeviceScope = (_BYTE *)DmrGetNextDrhdDeviceScope(a2, 0i64);
    if( NextDrhdDeviceScope
      && *NextDrhdDeviceScope == 1
      && NextDrhdDeviceScope[1] == 8
      && !NextDrhdDeviceScope[5]
      && NextDrhdDeviceScope[6] == 2
      && !NextDrhdDeviceScope[7]
      && !*(_WORD *)(a2 + 6)
      && (v11 & 0x3F0000) < 0x2F0000 )
    {
      if( !HalpIommuEnableGpuIdentityMapping )
      {
        v15 &= ~0x100u;
        v38 = v15;
      }
      v19 = 0x400000000i64;
      if( v18 )
        v19 = 0x800000000i64;
      if( (v11 & v19) != 0 )
      {
        v5 = 1;
        v51 = 1;
      }
    }
    v30 = 0;
    v20 = (_DWORD *)((unsigned __int64)&v30 & -(__int64)(v5 != 0));
    v21 = 1 << (2 * (v11 & 7) + 4);
    if( v20 )
      *v20 = --v21;
    v8 = *(_QWORD *)&v31[1];
    Size_4 = v21 - 1;
    v22 = v21 - 1 - **(_DWORD **)&v31[1];
    v31[0] = **(_DWORD **)&v31[1];
    v44 = v22;
    if( (v15 & 0x20) != 0 || (v15 & 0x100) != 0 )
    {
      v15 |= 0x12u;
      v48[10] = (INT64)IvtEnableInterrupt;
      v48[11] = (INT64)IvtDisableInterrupt;
      v48[12] = (INT64)IvtHandleInterrupt;
      v48[9] = (INT64)IvtSetMessageInterruptRouting;
      v38 = v15;
    }
    if( (int)DmrValidateDeviceScope(a1, a2) < 0 && (v15 & 0x20) != 0 )
      KeBugCheckEx(0x5Cu, 0x500ui64, 3ui64, 0i64, 0i64);
    ReservedDomainList = ExtEnvRegisterIommu(arg1, v23);
    if( ReservedDomainList >= 0 )
    {
      v24 = v34;
      *(_QWORD *)v34 = *(_QWORD *)(a2 + 8);
      *(_DWORD *)(v24 + 212) = *(unsigned __int16 *)(a2 + 6);
      *(_QWORD *)(v24 + 176) = v11;
      v25 = Size;
      *(_QWORD *)(v24 + 184) = v12;
      *(_QWORD *)(v24 + 232) = v24 + 304;
      *(_DWORD *)(v24 + 216) = v25;
      v26 = (v38 & 0x20) == 0;
      *(_BYTE *)(v24 + 228) = *(_BYTE *)(a2 + 4) & 1;
      *(_DWORD *)(v24 + 220) = Size_4;
      *(_DWORD *)(v24 + 224) = v30;
      *(_DWORD *)(v24 + 208) = v52;
      *(_QWORD *)(v24 + 168) = 0i64;
      *(_QWORD *)(v24 + 200) = v24 + 192;
      *(_QWORD *)(v24 + 192) = v24 + 192;
      if( !v26 )
        *(_BYTE *)(v24 + 268) = 1;
      if( (v38 & 0x100) != 0 )
        *(_BYTE *)(v24 + 269) = 1;
      if( v51 )
        *(_BYTE *)(v24 + 270) = 1;
      v27 = v31[0];
      *(_QWORD *)(v24 + 288) = v8;
      ReservedDomainList = HalpIvtAllocateReservedDomainList(v24, v22, v27);
      if( ReservedDomainList >= 0 )
        memmove(*(UINT8 **)(v24 + 232), (UINT8 *)(a2 + 16), v25);
    }
  }
  HalpUnmapVirtualAddress(VirtualAddress, 1i64, 0);
  if( ReservedDomainList < 0 )
    goto LABEL_62;
  return(unsigned int)ReservedDomainList;
}

Referenced by:

HalpIvtProcessDmarTable