IommupHvInitializeLibrary

INT64 __stdcall IommupHvInitializeLibrary(){
  int v0; 
  int v1; 
  __int64 v2; 
  char *PoolWithTag; 
  char *v4; 
  INT64 v6; 
  unsigned int v7; 
  _QWORD *v8; 
  char *ContiguousNodeMemory; 
  PHYSICAL_ADDRESS PhysicalAddress; 
  char *v11; 
  __int64 v12; 
  unsigned int i; 
  PVOID *v14; 
  UINT64 Protect; 
  UINT64 PreferredNode; 
  unsigned int v17; 
  __int128 v18; 
  __int64 v19; 
  v17 = 0;
  v18 = 0i64;
  v19 = 0i64;
  v0 = 0;
  if( !qword_140C4A218 )
    return 3221225659i64;
  qword_140C4A218(&v18);
  if( (v18 & 1) == 0 )
    return 3221225659i64;
  v1 = DWORD2(v18);
  if( HIDWORD(v19) && HIDWORD(v19) < DWORD2(v18) )
    v1 = HIDWORD(v19);
  v2 = v19;
  if( !(_DWORD)v19 )
    v2 = 1i64;
  PoolWithTag = (char *)ExAllocatePoolWithTag(NonPagedPoolNx, (unsigned int)((_DWORD)v2 << 6), 0x496C6148ui64);
  v4 = PoolWithTag;
  if( !PoolWithTag )
    return 3221225626i64;
  memset((INT64)PoolWithTag, 0i64);
  v7 = 0;
  if( (_DWORD)v2 )
  {
    v8 = v4 + 16;
    while( 1 )
    {
      LODWORD(PreferredNode) = 0x80000000;
      LODWORD(Protect) = 4;
      *((_DWORD *)v8 - 4) = v7;
      ContiguousNodeMemory = (char *)MmAllocateContiguousNodeMemory(
                                       0x2000ui64,
                                       0i64,
                                       (LARGE_INTEGER)-1i64,
                                       0i64,
                                       Protect,
                                       PreferredNode);
      *(v8 - 1) = ContiguousNodeMemory;
      if( !ContiguousNodeMemory )
        break;
      *v8 = ContiguousNodeMemory + 4096;
      PhysicalAddress = MmGetPhysicalAddress(ContiguousNodeMemory);
      v0 = ((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD, _QWORD, _DWORD))qword_140C4A268)(
             v7,
             102i64,
             (PHYSICAL_ADDRESS)PhysicalAddress.QuadPart,
             206i64,
             0);
      if( v0 < 0 )
        goto LABEL_20;
      ++v17;
      ++v7;
      v8 += 8;
      if( v7 >= (unsigned int)v2 )
        goto LABEL_15;
    }
    v0 = -1073741670;
LABEL_20:
    for( i = 0; i < v17; ++i )
      ((void(__fastcall *)(_QWORD))qword_140C4A270)(i);
    v14 = (PVOID *)(v4 + 8);
    do
    {
      if( *v14 )
        MmFreeContiguousMemory(*v14);
      v14 += 8;
      --v2;
    }
    while( v2 );
    ExFreePoolWithTag(v4, 0x496C6148u);
  }
  else
  {
LABEL_15:
    IommupHvSvmEnabled = 1;
    IommupHvMaximumAsids = v1;
    IommupHvPageRequestQueueCount = v2;
    IommupHvPageRequestQueues = (__int64)v4;
    if( (_DWORD)v2 )
    {
      v11 = v4 + 32;
      v12 = (unsigned int)v2;
      do
      {
        *((_QWORD *)v11 - 1) = 0i64;
        *(_QWORD *)v11 = 0i64;
        *((_DWORD *)v11 + 2) = 0;
        *((_QWORD *)v11 + 2) = IommupHvGetPageFault;
        *((_QWORD *)v11 + 3) = IommupHvDismissPageFault;
        *((_DWORD *)v11 + 3) = 40;
        v11 += 64;
        --v12;
      }
      while( v12 );
    }
    HalpInterruptSetIdtEntry(0xCEui64, IommupHvInterruptRoutine, 12, v6, (UINT64 *)0xFFFFFFFFFFFFFFFFi64);
  }
  return(unsigned int)v0;
}

Referenced by:

IommuInitializeLibrary