Skip to content

Instantly share code, notes, and snippets.

@TuxSH
Last active March 9, 2017 20:33
Show Gist options
  • Save TuxSH/0ecfe7365280d82b3469858b589a9cf9 to your computer and use it in GitHub Desktop.
Save TuxSH/0ecfe7365280d82b3469858b589a9cf9 to your computer and use it in GitHub Desktop.
cache maintenance shit
bool *__fastcall CleanInvalidateDataCacheL2CRange(int a1, unsigned int a2, int a3, int a4)
{
unsigned int v4; // r9@1
int v5; // r1@1
int v6; // r2@1
unsigned int v7; // r5@1
unsigned int v8; // r7@1
AddressRange v9; // r2@3
unsigned int i; // r6@3
bool *result; // r0@12
int v12; // [sp+0h] [bp-20h]@1
v12 = a4;
v4 = a2;
v5 = L2C_CTRL;
v6 = a1 + v4 + 31;
v7 = a1 & 0xFFFFFFE0;
v8 = v6 & 0xFFFFFFE0;
if ( v5 & 1 )
{
if ( v4 >= 0x4000 )
{
KCacheMaintenanceInterruptEvent::EntireCacheOp((bool *)&v12, 1u);
__mcr(15, 0, 0, 7, 10, 0);
__mcr(15, 0, 0, 7, 10, 4);
KCacheMaintenanceInterruptEvent::Join((bool *)&v12);
}
else
{
v9.end = (void *)(v6 & 0xFFFFFFE0);
v9.begin = (void *)(a1 & 0xFFFFFFE0);
KCacheMaintenanceInterruptEvent::CacheRangeOp((bool *)&v12, 1u, v9);
for ( i = v7; i < v8; i += 32 )
__mcr(15, 0, i, 7, 10, 1);
KCacheMaintenanceInterruptEvent::Join((bool *)&v12);
__mcr(15, 0, 0, 7, 10, 4);
}
if ( v4 >= 0x700000 )
{
L2C_InvalidateAll();
goto LABEL_14;
}
sub_FFF1BD68(v7, v8);
}
if ( v4 >= 0x4000 )
{
LABEL_14:
KCacheMaintenanceInterruptEvent::EntireCacheOp((bool *)&v12, 2u);
__mcr(15, 0, 0, 7, 14, 0);
__mcr(15, 0, 0, 7, 10, 4);
return KCacheMaintenanceInterruptEvent::Join((bool *)&v12);
}
KCacheMaintenanceInterruptEvent::CacheRangeOp((bool *)&v12, 2u, (AddressRange)__PAIR__(v8, v7));
for ( ; v7 < v8; v7 += 32 )
__mcr(15, 0, v7, 7, 14, 1);
result = KCacheMaintenanceInterruptEvent::Join((bool *)&v12);
__mcr(15, 0, 0, 7, 10, 4);
return result;
}
bool *__fastcall KCacheMaintenanceInterruptEvent::CacheRangeOp(bool *out, u8 op, AddressRange range)
{
bool v4; // cf@1
bool v5; // zf@1
bool async; // r10@4
KThread *volatile operatingThread; // r5@6
char *v8; // r7@8
KThreadLinkedListNode *v9; // r1@9
KThreadLinkedListNode v10; // r0@12
KThreadLinkedListNode *v11; // r2@13
int v12; // r1@19
unsigned __int8 v13; // r1@19
unsigned int v14; // r2@20
signed int v15; // r3@21
u8 cacheOp; // [sp+0h] [bp-38h]@6
bool *v18; // [sp+4h] [bp-34h]@1
v18 = out;
v4 = (unsigned __int8)firmlaunchState >= 1u;
v5 = firmlaunchState == 1;
if ( firmlaunchState != 1 )
{
v4 = (unsigned int)(range.end - range.begin) >= 0x200;
v5 = (void *)(range.end - range.begin) == (void *)512;
}
if ( !v5 && v4 )
async = 1;
else
async = 0;
*out = async;
cacheOp = op | 4;
operatingThread = currentCoreCtx.objectContext.currentThread;
while ( 1 )
{
KRecursiveLock::Lock(&g_criticalSectionLock);
if ( !cacheMaintenanceStruct.cacheMaintenanceOperation )
break;
v8 = (char *)&cacheMaintenanceStruct.threadListNode;
operatingThread->preemptionList = (KThreadLinkedList *)&cacheMaintenanceStruct.threadListNode;
KThread::Reschedule(operatingThread, 0);
if ( cacheMaintenanceStruct.threadListNode )
v9 = cacheMaintenanceStruct.threadListNode + 20;
else
v9 = (KThreadLinkedListNode *)&cacheMaintenanceStruct.threadListNode;
operatingThread->threadListNode.prev = (KThread *)&cacheMaintenanceStruct.threadListNode->prev;
operatingThread->threadListNode.next = 0;
v9->next = operatingThread;
cacheMaintenanceStruct.threadListNode = (KThreadLinkedListNode *)operatingThread;
if ( operatingThread->shallTerminate )
{
v10 = operatingThread->threadListNode;
if ( v10.prev )
v11 = &v10.prev->threadListNode;
else
v11 = (KThreadLinkedListNode *)&cacheMaintenanceStruct.threadListNode;
if ( v10.next )
v8 = (char *)&v10.next->threadListNode;
v11->next = v10.next;
*(_DWORD *)v8 = v10.prev;
KThread::Reschedule(operatingThread, 1u);
operatingThread->preemptionList = 0;
}
KRecursiveLock::Unlock(&g_criticalSectionLock);
}
cacheMaintenanceStruct.async = async;
cacheMaintenanceStruct.operatingThread = operatingThread;
cacheMaintenanceStruct.addrRange = range;
cacheMaintenanceStruct.cacheMaintenanceOperation = cacheOp;
v12 = MPCORE_SCU_CFG;
v13 = v12 & 3;
do
v14 = __ldrex((unsigned __int8 *)&cacheMaintenanceStruct.remaining);
while ( __strex(v13, (unsigned __int8 *)&cacheMaintenanceStruct.remaining) );
__mcr(15, 0, 0, 7, 10, 4);
v15 = 1 << ((MPCORE_SCU_CFG & 3) + 1);
MPCORE_GID_SGI = ((v15 - (1 << (__mrc(15, 0, 0, 0, 5) & 3)) - 1) << 16) & 0xFF0000 | 7;
KRecursiveLock::Unlock(&g_criticalSectionLock);
return v18;
}
bool *__fastcall KCacheMaintenanceInterruptEvent::EntireCacheOp(bool *out, u8 op); // is similar to the above
// SGI 7 handler
KAsyncCacheMaintenanceInterruptEvent *__fastcall KCacheMaintenanceInterruptEvent::HandleInterrupt(KCacheMaintenanceInterruptEvent *this)
{
KAsyncCacheMaintenanceInterruptEvent *result; // r0@2
unsigned __int8 *v3; // r1@3
unsigned int v4; // r0@4
if ( this->async )
{
result = &this->asyncInterruptEventsPerCore[__mrc(15, 0, 0, 0, 5) & 3];
}
else
{
KCacheMaintenanceInterruptEvent::DoSyncCacheOperation((unsigned int)this);
v3 = (unsigned __int8 *)&this->remaining;
do
v4 = __ldrex(v3);
while ( __strex(v4 - 1, v3) );
if ( (_BYTE)v4 == 1 )
{
this->operatingThread = 0;
__mcr(15, 0, 0, 7, 10, 4);
this->cacheMaintenanceOperation = 0;
__mcr(15, 0, 0, 7, 10, 4);
}
result = 0;
}
return result;
}
KCacheMaintenanceInterruptEvent *__fastcall KCacheMaintenanceInterruptEvent::DoSyncCacheOperation(KCacheMaintenanceInterruptEvent *this)
{
void *v1; // t1@2
char *v2; // r1@2
unsigned int v3; // r3@2
int v4; // r12@2
unsigned int v5; // r1@2
unsigned int v6; // r12@2
bool v7; // cf@4
u8 *v8; // r1@11
KCacheMaintenanceInterruptEvent *v9; // r1@14
KCacheMaintenanceInterruptEvent *v10; // r1@17
switch ( this->cacheMaintenanceOperation )
{
case 8u:
v1 = this->addrRange.begin;
v2 = (char *)this->addrRange.end;
v3 = (unsigned int)v1 & 0xFFFFFFE0;
v4 = (int)(v2 + 31);
this = (KCacheMaintenanceInterruptEvent *)(((unsigned int)v1 + 31) & 0xFFFFFFE0);
v5 = (unsigned int)v2 & 0xFFFFFFE0;
v6 = v4 & 0xFFFFFFE0;
if ( ((unsigned int)v1 & 0xFFFFFFE0) < (unsigned int)this )
__mcr(15, 0, v3, 7, 14, 1);
v7 = (unsigned int)this >= v6;
if ( (unsigned int)this < v6 )
v7 = v5 >= v6;
if ( !v7 )
__mcr(15, 0, v5, 7, 14, 1);
for ( ; (unsigned int)this < v5; this = (KCacheMaintenanceInterruptEvent *)((char *)this + 32) )
__mcr(15, 0, (unsigned int)this, 7, 6, 1);
goto LABEL_22;
case 9u:
v8 = (u8 *)this->addrRange.begin;
for ( this = (KCacheMaintenanceInterruptEvent *)this->addrRange.end; v8 < (u8 *)this; v8 += 32 )
__mcr(15, 0, (unsigned int)v8, 7, 10, 1);
goto LABEL_22;
case 0xAu:
v9 = (KCacheMaintenanceInterruptEvent *)this->addrRange.begin;
for ( this = (KCacheMaintenanceInterruptEvent *)this->addrRange.end;
v9 < this;
v9 = (KCacheMaintenanceInterruptEvent *)((char *)v9 + 32) )
{
__mcr(15, 0, (unsigned int)v9, 7, 14, 1);
}
goto LABEL_22;
case 0xBu:
v10 = (KCacheMaintenanceInterruptEvent *)this->addrRange.begin;
for ( this = (KCacheMaintenanceInterruptEvent *)this->addrRange.end;
v10 < this;
v10 = (KCacheMaintenanceInterruptEvent *)((char *)v10 + 32) )
{
__mcr(15, 0, (unsigned int)v10, 7, 5, 1);
}
goto LABEL_19;
case 0xCu:
__mcr(15, 0, 0, 7, 6, 0);
goto LABEL_22;
case 0xDu:
__mcr(15, 0, 0, 7, 10, 0);
LABEL_22:
__mcr(15, 0, 0, 7, 10, 4);
break;
case 0xEu:
__mcr(15, 0, 0, 7, 14, 0);
__mcr(15, 0, 0, 7, 10, 4);
break;
case 0xFu:
__mcr(15, 0, 0, 7, 5, 0);
LABEL_19:
__mcr(15, 0, 0, 7, 5, 6);
__mcr(15, 0, 0, 7, 10, 4);
__mcr(15, 0, 0, 7, 5, 4);
break;
default:
return this;
}
return this;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment