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