From 2a5506dae6d0c01ee3c2a9855831277309e325e7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 21 Jul 2014 23:05:58 +0400 Subject: [PATCH] cellSyncBarrierInitialize implemented (SPU sample works) --- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 118 ++++++++++++++++++++++-- rpcs3/Emu/SysCalls/Modules/cellSync.h | 8 +- 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 68981edf65..9265e9decd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -10,9 +10,9 @@ //Module cellSync("cellSync", cellSync_init); Module *cellSync = nullptr; -int cellSyncMutexInitialize(mem_ptr_t mutex) +s32 cellSyncMutexInitialize(mem_ptr_t mutex) { - cellSync->Log("cellSyncMutexInitialize(mutex=0x%x)", mutex.GetAddr()); + cellSync->Log("cellSyncMutexInitialize(mutex_addr=0x%x)", mutex.GetAddr()); if (!mutex) { @@ -29,9 +29,9 @@ int cellSyncMutexInitialize(mem_ptr_t mutex) return CELL_OK; } -int cellSyncMutexLock(mem_ptr_t mutex) +s32 cellSyncMutexLock(mem_ptr_t mutex) { - cellSync->Log("cellSyncMutexLock(mutex=0x%x)", mutex.GetAddr()); + cellSync->Log("cellSyncMutexLock(mutex_addr=0x%x)", mutex.GetAddr()); if (!mutex) { @@ -58,10 +58,10 @@ int cellSyncMutexLock(mem_ptr_t mutex) // prx: wait until another u16 value == old value while (old_order != mutex->m_freed) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellSyncMutexLock(mutex=0x%x) aborted", mutex.GetAddr()); + LOG_WARNING(HLE, "cellSyncMutexLock(mutex_addr=0x%x) aborted", mutex.GetAddr()); break; } } @@ -71,9 +71,9 @@ int cellSyncMutexLock(mem_ptr_t mutex) return CELL_OK; } -int cellSyncMutexTryLock(mem_ptr_t mutex) +s32 cellSyncMutexTryLock(mem_ptr_t mutex) { - cellSync->Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr()); + cellSync->Log("cellSyncMutexTryLock(mutex_addr=0x%x)", mutex.GetAddr()); if (!mutex) { @@ -105,9 +105,9 @@ int cellSyncMutexTryLock(mem_ptr_t mutex) return CELL_OK; } -int cellSyncMutexUnlock(mem_ptr_t mutex) +s32 cellSyncMutexUnlock(mem_ptr_t mutex) { - cellSync->Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr()); + cellSync->Log("cellSyncMutexUnlock(mutex_addr=0x%x)", mutex.GetAddr()); if (!mutex) { @@ -133,10 +133,108 @@ int cellSyncMutexUnlock(mem_ptr_t mutex) return CELL_OK; } +s32 cellSyncBarrierInitialize(mem_ptr_t barrier, u16 total_count) +{ + cellSync->Log("cellSyncBarrierInitialize(barrier_addr=0x%x, total_count=%d)", barrier.GetAddr(), total_count); + + if (!barrier) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (barrier.GetAddr() % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + if (!total_count || total_count > 32767) + { + return CELL_SYNC_ERROR_INVAL; + } + + // prx: zeroize first u16, write total_count in second u16 and sync + barrier->m_value = 0; + barrier->m_count = total_count; + InterlockedCompareExchange(&barrier->m_data(), 0, 0); + return CELL_OK; +} + +s32 cellSyncBarrierNotify(mem_ptr_t barrier) +{ + cellSync->Todo("cellSyncBarrierNotify(barrier_addr=0x%x)", barrier.GetAddr()); + + if (!barrier) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (barrier.GetAddr() % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + + // TODO + return CELL_OK; +} + +s32 cellSyncBarrierTryNotify(mem_ptr_t barrier) +{ + cellSync->Todo("cellSyncBarrierTryNotify(barrier_addr=0x%x)", barrier.GetAddr()); + + if (!barrier) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (barrier.GetAddr() % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + + // TODO + return CELL_OK; +} + +s32 cellSyncBarrierWait(mem_ptr_t barrier) +{ + cellSync->Todo("cellSyncBarrierWait(barrier_addr=0x%x)", barrier.GetAddr()); + + if (!barrier) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (barrier.GetAddr() % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + + // TODO + return CELL_OK; +} + +s32 cellSyncBarrierTryWait(mem_ptr_t barrier) +{ + cellSync->Todo("cellSyncBarrierTryWait(barrier_addr=0x%x)", barrier.GetAddr()); + + if (!barrier) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (barrier.GetAddr() % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + + // TODO + return CELL_OK; +} + void cellSync_init() { cellSync->AddFunc(0xa9072dee, cellSyncMutexInitialize); cellSync->AddFunc(0x1bb675c2, cellSyncMutexLock); cellSync->AddFunc(0xd06918c4, cellSyncMutexTryLock); cellSync->AddFunc(0x91f2b7b0, cellSyncMutexUnlock); + + cellSync->AddFunc(0x07254fda, cellSyncBarrierInitialize); + cellSync->AddFunc(0xf06a6415, cellSyncBarrierNotify); + cellSync->AddFunc(0x268edd6d, cellSyncBarrierTryNotify); + cellSync->AddFunc(0x35f21355, cellSyncBarrierWait); + cellSync->AddFunc(0x6c272124, cellSyncBarrierTryWait); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.h b/rpcs3/Emu/SysCalls/Modules/cellSync.h index 36a768986e..c9dd86f607 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.h @@ -32,7 +32,13 @@ static_assert(sizeof(CellSyncMutex) == 4, "CellSyncMutex: wrong size"); struct CellSyncBarrier { - be_t m_data; + be_t m_value; + be_t m_count; + + volatile u32& m_data() + { + return *reinterpret_cast(this); + }; }; static_assert(sizeof(CellSyncBarrier) == 4, "CellSyncBarrier: wrong size"); \ No newline at end of file