HsaIommuSendCommand

UINT64 __stdcall HsaIommuSendCommand(UINT64 *a1, UINT64 *a2, UINT8 *a3){
  unsigned __int8 CurrentIrql; 
  UINT64 v6; 
  UINT64 v7; 
  unsigned __int64 v8; 
  UINT64 v9; 
  __int64 v10; 
  unsigned int v11; 
  unsigned int v12; 
  UINT64 v13; 
  __int64 v14; 
  __int64 v15; 
  UINT64 result; 
  unsigned int v17; 
  int v18[8]; 
  _KLOCK_QUEUE_HANDLE LockQueue[3]; 
  UINT64 v20; 
  UINT64 v21; 
  int v22; 

  v22 = (int)a3;
  memset(LockQueue, 0, 24);
  if( (_DWORD)a3 )
  {
    CurrentIrql = 0;
  }
  else
  {
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(0xFui64);
    LockQueue[0].LockQueue.Next = 0i64;
    LockQueue[0].LockQueue.Lock = a1 + 19;
    KxAcquireQueuedSpinLock(&LockQueue[0].LockQueue, a1 + 19);
  }
  if( *a2 >> 60 == 1 )
  {
    v6 = a1[17];
    a1[15] = 1i64;
    *a2 = v6;
    a2[1] = a1[18];
  }
  v7 = *a1;
  v20 = *a1;
  v8 = *(_QWORD *)(*a1 + 8200);
  v9 = a1[6];
  v21 = v9;
  v10 = ((unsigned int)(v8 >> 4) & 0x7FFF) + 1;
  v11 = 0;
  v12 = 0;
  v13 = a1[8] >> 4;
  if( (_DWORD)v10 != (_DWORD)v13 )
    v12 = ((v8 >> 4) & 0x7FFF) + 1;
  v14 = v12;
  if( v12 == ((*(_QWORD *)(v7 + 0x2000) >> 4) & 0x7FFFi64) )
  {
    do
    {
      if( (++v11 & dword_140C4A13C) != 0 || !qword_140C4A140 )
      {
        _mm_pause();
      }
      else
      {
        qword_140C4A140(v11, v10, v13);
        v7 = v20;
      }
    }
    while( v14 == ((*(_QWORD *)(v7 + 0x2000) >> 4) & 0x7FFFi64) );
    v9 = v21;
  }
  v15 = 2 * ((v8 >> 4) & 0x7FFF);
  *(_QWORD *)(v9 + 8 * v15) = *a2;
  *(_QWORD *)(v9 + 8 * v15 + 8) = a2[1];
  *(_QWORD *)(v7 + 8200) = ((unsigned int)v8 ^ (16 * (_DWORD)v14)) & 0x7FFF0 ^ v8;
  _InterlockedOr(v18, 0);
  result = *a2 >> 60;
  if( (_BYTE)result == 1 )
  {
    v17 = 0;
    while( 1 )
    {
      result = a1[15];
      if( !result )
        break;
      if( (++v17 & dword_140C4A13C) != 0 || !qword_140C4A140 )
        _mm_pause();
      else
        qword_140C4A140(v17, v10, v13);
    }
  }
  if( !v22 )
  {
    KeReleaseInStackQueuedSpinLockFromDpcLevel(LockQueue);
    result = CurrentIrql;
    __writecr8(CurrentIrql);
  }
  return result;
}

Referenced by:

HsaDismissPageFault
HsaFlushDeviceTbOnly
HsaInvalidateDTE
HsaInvalidateRemappingTableEntries