HalpIommuMapLogical
INT64 __fastcall HalpIommuMapLogical(INT64 a1, INT64 a2, INT64 a3, INT64 a4, UINT64 a5, INT64 a6){
int v6;
unsigned __int64 v7;
unsigned int v8;
unsigned __int64 v9;
UINT64 v10;
int v11;
__int64 v12;
int v14;
UINT64 v15;
unsigned int v16;
unsigned __int64 v17;
__int64 v18;
__int64 v19;
unsigned __int64 v20;
unsigned __int8 v21;
unsigned __int64 v22;
void *v23;
PHYSICAL_ADDRESS PhysicalAddress;
void *v25;
unsigned int v26;
__int64 v27;
int v28;
void *v29;
unsigned int v30;
int v31;
INT64 v32;
__int64 v33;
unsigned int v35;
char v36;
unsigned int v37;
unsigned __int64 BaseAddress;
PVOID BaseAddressa;
UINT64 v40;
INT64 v41;
INT64 v42;
__int128 v43[3];
v6 = *(_DWORD *)(a2 + 28);
v7 = *(_QWORD *)(a2 + 16);
v8 = 0;
v9 = a6;
v10 = 0i64;
v41 = a4;
v36 = v6;
v11 = 1 << v6;
LODWORD(v12) = 0;
v37 = 1 << v6;
v43[0] = v7;
memset(&v43[1], 0, 32);
v35 = 0;
v42 = a6;
v40 = 0i64;
if( !a5 )
return 0i64;
while( 1 )
{
v14 = *(_DWORD *)(a2 + 24);
if( (unsigned int)v12 < v14 - 1 )
{
v15 = (unsigned int)v12;
while( 1 )
{
v16 = *(_DWORD *)(a2 + 4 * v15 + 36);
v17 = v7 + (1 << v16 << v6);
if( v16 < 0x40 )
v18 = (1i64 << v16) - 1;
else
LODWORD(v18) = -1;
v19 = (unsigned int)v18 & (unsigned int)(v9 >> *(_DWORD *)(a2 + 4 * v15 + 60));
BaseAddress = (unsigned int)v19;
v20 = *(_QWORD *)(v17 + 8 * v19);
if( !v20 )
{
KeAcquireSpinLockRaiseToDpc((UINT64 *)(a2 + 8), v15);
v22 = v21;
if( !*(_QWORD *)(v17 + 8i64 * (unsigned int)v19) )
{
v23 = (void *)HalpIommuAllocateAndZeroPageTable(a2, (unsigned int)(v12 + 1), 0i64);
*(_QWORD *)(v17 + 8i64 * (unsigned int)v19) = v23;
if( !v23 )
{
KxReleaseSpinLock((UINT64 *)(a2 + 8));
__writecr8(v22);
return 3221225626i64;
}
PhysicalAddress = MmGetPhysicalAddress(v23);
v25 = (void *)(v7 + (unsigned int)((_DWORD)v19 << v36));
(**(void(__fastcall ***)(void *, _QWORD, PHYSICAL_ADDRESS))(a2 + 88))(
v25,
(unsigned int)(*(_DWORD *)(a2 + 24) - v12 - 1),
PhysicalAddress);
if( !HalpIommuPageTableCacheCoherent )
KeInvalidateRangeAllCachesNoIpi(v25, v37);
}
KxReleaseSpinLock((UINT64 *)(a2 + 8));
__writecr8(v22);
v14 = *(_DWORD *)(a2 + 24);
LOBYTE(v6) = v36;
v20 = *(_QWORD *)(v17 + 8 * BaseAddress);
}
v9 = a6;
v12 = (unsigned int)(v12 + 1);
v7 = v20;
v15 = (unsigned int)v12;
*((_QWORD *)v43 + v12) = v20;
if( (unsigned int)v12 >= v14 - 1 )
{
v10 = v40;
v11 = v37;
v8 = v35;
break;
}
}
}
v26 = *(_DWORD *)(a2 + 4i64 * (unsigned int)v12 + 36);
if( v26 < 0x40 )
v27 = (1i64 << v26) - 1;
else
LODWORD(v27) = -1;
v28 = v27 & (v9 >> *(_DWORD *)(a2 + 4i64 * (unsigned int)v12 + 60));
v29 = (void *)(v7 + (unsigned int)(v28 << v6));
v30 = (1 << *(_DWORD *)(a2 + 4i64 * (unsigned int)(v14 - 1) + 36)) - v28;
BaseAddressa = v29;
if( (unsigned int)a5 - v8 <= v30 )
v30 = a5 - v8;
v31 = (*(__int64(__fastcall **)(void *, INT64, __int64, _QWORD))(*(_QWORD *)(a2 + 88) + 16i64))(
v29,
v41 + 8i64 * v8,
3i64,
v30);
v10 += (unsigned int)(v31 << 12);
v40 = v10;
if( v31 != v30 )
break;
if( !HalpIommuPageTableCacheCoherent )
KeInvalidateRangeAllCachesNoIpi(BaseAddressa, v11 * v30);
v8 = v30 + v35;
v32 = v9 + ((unsigned __int64)v30 << 12);
v35 += v30;
if( (_DWORD)v12 )
{
do
{
v33 = (unsigned int)(v12 - 1);
if( ((1i64 << *(_DWORD *)(a2 + 4 * v33 + 60)) & v32) == (v9 & (1i64 << *(_DWORD *)(a2 + 4 * v33 + 60))) )
break;
LODWORD(v12) = v12 - 1;
}
while( (_DWORD)v33 );
}
v9 += (unsigned __int64)v30 << 12;
a6 = v32;
v7 = *((_QWORD *)v43 + (unsigned int)v12);
if( v8 >= a5 )
return 0i64;
LOBYTE(v6) = v36;
}
HalpIommuUnmapLogicalRange(a2, &v40, v42);
return 3221225485i64;
}Referenced by:
HalpIommuDomainMapLogical