HalpIrtAllocateIndex

INT64 __stdcall HalpIrtAllocateIndex(UINT64 *IrtIndex, INT64 a2){
  unsigned int v2; 
  unsigned int v3; 
  _DWORD *v4; 
  unsigned int v5; 
  int RemappingTableEntry; 
  ULONG v7; 
  unsigned int v9; 
  unsigned int v10; 
  __int64 v11; 
  RTL_BITMAP *v12; 
  ULONG ClearBitsAndSet; 
  UINT64 v14; 
  ULONG v15; 
  unsigned int NextForwardRunClear; 
  UINT64 v17; 
  _DWORD *a5; 
  char v20; 
  ULONG v21; 
  unsigned int v22; 
  unsigned int v23; 
  unsigned int v24; 
  INT64 v25; 
  CHAR v26; 
  _DWORD *StartingRunIndex; 
  v24 = v3;
  v23 = v2;
  v4 = StartingRunIndex;
  v5 = 0;
  RemappingTableEntry = 0;
  v20 = 0;
  v21 = 0;
  v7 = a2;
  if( StartingRunIndex )
    v9 = *StartingRunIndex;
  else
    v9 = 0;
  if( !HalpIrtTotalEntries )
  {
    *(_DWORD *)IrtIndex = 0;
    return(unsigned int)RemappingTableEntry;
  }
  if( (HalpIrtAllocationFlags & 4) != 0 )
  {
    RemappingTableEntry = HalpIrtAllocateDeviceAperture(v2, v3, (unsigned int)a2, v9, &v21);
    if( RemappingTableEntry < 0 )
      return(unsigned int)RemappingTableEntry;
    v5 = v21;
    v20 = 1;
  }
  v10 = v5 / HalpIrtAperturesPerRange;
  v22 = v5 / HalpIrtAperturesPerRange;
  ExAcquireFastMutex(&HalpIrtLock);
  v11 = 2i64 * v10;
  if( !*((_QWORD *)&HalpIrtRanges.Buffer + 2 * v10) )
  {
    KeReleaseGuardedMutex(&HalpIrtLock);
    RemappingTableEntry = HalpIrtExtendRemappingRange(v10);
    if( RemappingTableEntry < 0 )
      goto LABEL_30;
    ExAcquireFastMutex(&HalpIrtLock);
  }
  v12 = (RTL_BITMAP *)((char *)&HalpIrtRanges + 8 * v11);
  if( (HalpIrtAllocationFlags & 1) != 0 )
  {
    v14 = v5 * HalpIrtEntriesPerDeviceAperture % HalpIrtEntriesPerRange;
    v21 = v14 + HalpIrtEntriesPerDeviceAperture - 1;
    ClearBitsAndSet = -1;
    while( 1 )
    {
      LODWORD(StartingRunIndex) = v14;
      NextForwardRunClear = RtlFindNextForwardRunClear(v12, v14, (UINT64 *)&StartingRunIndex);
      if( !NextForwardRunClear )
        break;
      if( NextForwardRunClear >= v7 )
      {
        v15 = -v7 & (v7 + (_DWORD)StartingRunIndex - 1);
        if( v15 - (unsigned int)StartingRunIndex < NextForwardRunClear
          && NextForwardRunClear + (_DWORD)StartingRunIndex - v15 >= v7 )
        {
          if( v15 + v7 - 1 <= v21 )
          {
            RtlSetBits(v12, v15, v7);
            ClearBitsAndSet = v15;
          }
          break;
        }
        v14 = (unsigned int)StartingRunIndex + NextForwardRunClear;
      }
      else
      {
        v14 = (unsigned int)StartingRunIndex + NextForwardRunClear;
      }
    }
  }
  else
  {
    ClearBitsAndSet = RtlFindClearBitsAndSet(v12, v7, 0);
  }
  KeReleaseGuardedMutex(&HalpIrtLock);
  if( ClearBitsAndSet == -1 )
  {
    RemappingTableEntry = -1073741670;
  }
  else
  {
    RemappingTableEntry = 0;
    v17 = ClearBitsAndSet + v22 * HalpIrtEntriesPerRange;
    *(_DWORD *)IrtIndex = v17;
    if( v9 != 3 )
      return(unsigned int)RemappingTableEntry;
    if( (HalpIrtAllocationFlags & 2) == 0 )
      return(unsigned int)RemappingTableEntry;
    LODWORD(a5) = v4[14];
    RemappingTableEntry = HalpIommuAllocateRemappingTableEntry(v17, v7, v23, v24, (INT64)a5, v25, v26);
    if( RemappingTableEntry >= 0 )
      return(unsigned int)RemappingTableEntry;
    ExAcquireFastMutex(&HalpIrtLock);
    RtlClearBits(v12, ClearBitsAndSet, v7);
    KeReleaseGuardedMutex(&HalpIrtLock);
    *(_DWORD *)IrtIndex = -1;
  }
LABEL_30:
  if( v20 )
    HalpIrtReleaseDeviceAperture(v5, v7);
  return(unsigned int)RemappingTableEntry;
}

Referenced by:

HalpInterruptRemap
HalpInterruptRemapFixedLines