2013-12-31 12:10:24 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Emu/SysCalls/SysCalls.h"
|
|
|
|
|
#include "Emu/SysCalls/SC_FUNC.h"
|
|
|
|
|
|
|
|
|
|
void cellSync_init();
|
|
|
|
|
Module cellSync(0x0054, cellSync_init);
|
|
|
|
|
|
|
|
|
|
// Return Codes
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
CELL_SYNC_ERROR_AGAIN = 0x80410101,
|
|
|
|
|
CELL_SYNC_ERROR_INVAL = 0x80410102,
|
|
|
|
|
CELL_SYNC_ERROR_NOMEM = 0x80410104,
|
|
|
|
|
CELL_SYNC_ERROR_DEADLK = 0x80410108,
|
|
|
|
|
CELL_SYNC_ERROR_PERM = 0x80410109,
|
|
|
|
|
CELL_SYNC_ERROR_BUSY = 0x8041010A,
|
|
|
|
|
CELL_SYNC_ERROR_STAT = 0x8041010F,
|
|
|
|
|
CELL_SYNC_ERROR_ALIGN = 0x80410110,
|
|
|
|
|
CELL_SYNC_ERROR_NULL_POINTER = 0x80410111,
|
|
|
|
|
CELL_SYNC_ERROR_NOT_SUPPORTED_THREAD = 0x80410112,
|
|
|
|
|
CELL_SYNC_ERROR_NO_NOTIFIER = 0x80410113,
|
|
|
|
|
CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int cellSyncMutexInitialize(mem32_t mutex)
|
|
|
|
|
{
|
|
|
|
|
const u32 mutex_addr = mutex.GetAddr();
|
|
|
|
|
if (!mutex_addr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
if (mutex_addr % 4)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_ALIGN;
|
|
|
|
|
}
|
|
|
|
|
mutex = 0;
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cellSyncMutexLock(mem32_t mutex)
|
|
|
|
|
{
|
|
|
|
|
const u32 mutex_addr = mutex.GetAddr();
|
|
|
|
|
if (!mutex_addr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
if (mutex_addr % 4)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_ALIGN;
|
|
|
|
|
}
|
2014-01-05 00:58:03 +01:00
|
|
|
while (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24));
|
|
|
|
|
//need to check how does SPU work with these mutexes, also obtainment order is not guaranteed
|
2013-12-31 12:10:24 +01:00
|
|
|
_mm_lfence();
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cellSyncMutexTryLock(mem32_t mutex)
|
|
|
|
|
{
|
|
|
|
|
const u32 mutex_addr = mutex.GetAddr();
|
|
|
|
|
if (!mutex_addr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
if (mutex_addr % 4)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_ALIGN;
|
|
|
|
|
}
|
2014-01-05 00:58:03 +01:00
|
|
|
//check cellSyncMutexLock
|
|
|
|
|
if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24))
|
2013-12-31 12:10:24 +01:00
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_BUSY;
|
|
|
|
|
}
|
|
|
|
|
_mm_lfence();
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cellSyncMutexUnlock(mem32_t mutex)
|
|
|
|
|
{
|
|
|
|
|
const u32 mutex_addr = mutex.GetAddr();
|
|
|
|
|
if (!mutex_addr)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
if (mutex_addr % 4)
|
|
|
|
|
{
|
|
|
|
|
return CELL_SYNC_ERROR_ALIGN;
|
|
|
|
|
}
|
2014-01-05 00:58:03 +01:00
|
|
|
//check cellSyncMutexLock
|
2013-12-31 12:10:24 +01:00
|
|
|
_mm_sfence();
|
2014-01-05 00:58:03 +01:00
|
|
|
_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0);
|
2013-12-31 12:10:24 +01:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cellSync_init()
|
|
|
|
|
{
|
|
|
|
|
cellSync.AddFunc(0xa9072dee, cellSyncMutexInitialize);
|
|
|
|
|
cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock);
|
|
|
|
|
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
|
|
|
|
|
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
|
|
|
|
|
}
|