diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 2ecd40ad4a..0ee177d9e0 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -13,10 +13,7 @@ struct reservation_struct // and doesn't give a chance to finish some work before losing the reservation u32 owner; // id of thread that got reservation u64 addr; - u32 size; - u32 data32; - u64 data64; - u128 data[8]; + u64 data[16]; __forceinline void clear() { diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 1b3386bf06..3e2df02763 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -778,68 +778,48 @@ public: SMutexLockerR lock(reservation.mutex); reservation.owner = lock.tid; reservation.addr = ea; - reservation.size = 128; - for (u32 i = 0; i < 8; i++) + for (u32 i = 0; i < 16; i++) { - reservation.data[i] = *(u128*)&Memory[(u32)ea + i * 16]; - *(u128*)&Memory[dmac.ls_offset + lsa + i * 16] = reservation.data[i]; + reservation.data[i] = *(u64*)&Memory[(u32)ea + i * 8]; + *(u64*)&Memory[dmac.ls_offset + lsa + i * 8] = reservation.data[i]; } MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); } else if (op == MFC_PUTLLC_CMD) // store conditional { SMutexLockerR lock(reservation.mutex); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + if (reservation.owner == lock.tid) // succeeded { - if (reservation.addr == ea && reservation.size == 128) + if (reservation.addr == ea) { - u128 buf[8]; // data being written newly + u64 buf[16]; // data being written newly u32 changed = 0, mask = 0, last = 0; - for (u32 i = 0; i < 8; i++) + for (u32 i = 0; i < 16; i++) { - buf[i] = *(u128*)&Memory[dmac.ls_offset + lsa + i * 16]; + buf[i] = *(u64*)&Memory[dmac.ls_offset + lsa + i * 8]; if (buf[i] != reservation.data[i]) { changed++; last = i; - mask |= (0xf << (i * 4)); - } - } - if (changed == 0) // nothing changed? - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - else if (changed == 1) - { - if (buf[last].hi != reservation.data[last].hi && buf[last].lo != reservation.data[last].lo) - { - LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 128bit compare and swap"); - Emu.Pause(); - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - else - { - const u32 last_q = (buf[last].hi == reservation.data[last].hi); + mask |= (0x3 << (i * 2)); - if (InterlockedCompareExchange64((volatile long long*)(Memory + ((u32)ea + last * 16 + last_q * 8)), - buf[last]._u64[last_q], reservation.data[last]._u64[last_q]) == reservation.data[last]._u64[last_q]) - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - else + if (InterlockedCompareExchange64((volatile long long*)(Memory + ((u32)ea + last * 8)), buf[last], reservation.data[last]) != reservation.data[last]) { MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + + if (changed > 1) + { + LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Reservation Error: impossibru (~ 8x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", + changed, mask, op, cmd, lsa, ea, tag, size); + Emu.Pause(); + } + + break; } } } - else - { - ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); - LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Reservation Error: impossibru (~ 16x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", - changed, mask, op, cmd, lsa, ea, tag, size); - Emu.Pause(); - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } } else { @@ -860,8 +840,7 @@ public: { MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); } - if ((reservation.addr + reservation.size > ea && reservation.addr <= ea + size) || - (ea + size > reservation.addr && ea <= reservation.addr + reservation.size)) + if (reservation.addr == ea) { reservation.clear(); } @@ -1135,7 +1114,7 @@ public: default: { - LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); + LOG_ERROR(Log::SPU, "%s error (v=0x%x): unknown/illegal channel (%d [%s]).", __FUNCTION__, v, ch, spu_ch_name[ch]); break; } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 4598057f82..db11e00f77 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -18,9 +18,12 @@ u32 libsre_rtoc; void fix_import(Module* module, u32 func, u32 addr) { - Memory.Write32((addr), 0x3d600000 | (func >> 16)); /* lis r11, (func_id >> 16) */ - Memory.Write32((addr) + 4, 0x616b0000 | (func & 0xffff)); /* ori r11, (func_id & 0xffff) */ - Memory.Write64((addr) + 8, 0x440000024e800020ull); /* sc + blr */ + Memory.Write32(addr + 0x0, 0x3d600000 | (func >> 16)); /* lis r11, (func_id >> 16) */ + Memory.Write32(addr + 0x4, 0x616b0000 | (func & 0xffff)); /* ori r11, (func_id & 0xffff) */ + Memory.Write32(addr + 0x8, 0x60000000); /* nop */ + // leave rtoc saving at 0xC + Memory.Write64(addr + 0x10, 0x440000024e800020ull); /* sc + blr */ + Memory.Write64(addr + 0x18, 0x6000000060000000ull); /* nop + nop */ module->Load(func); } @@ -1513,8 +1516,6 @@ s32 _cellSyncLFQueuePushBody(mem_ptr_t queue, u32 buffer_addr, // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.GetAddr(), buffer_addr, isBlocking); - //return GetCurrentPPUThread().FastCall2(libsre + 0x1674, libsre_rtoc); // test - if (!queue || !buffer_addr) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -2226,6 +2227,9 @@ void cellSync_init() extern Module* sysPrxForUser; + FIX_IMPORT(sysPrxForUser, cellUserTraceRegister , libsre + 0x1D5BC); // ??? + FIX_IMPORT(sysPrxForUser, cellUserTraceUnregister , libsre + 0x1D5DC); // ??? + FIX_IMPORT(sysPrxForUser, _sys_strncmp , libsre + 0x1D5FC); FIX_IMPORT(sysPrxForUser, _sys_strcat , libsre + 0x1D61C); FIX_IMPORT(sysPrxForUser, _sys_vsnprintf , libsre + 0x1D63C); @@ -2256,6 +2260,12 @@ void cellSync_init() FIX_IMPORT(sysPrxForUser, sys_lwcond_signal , libsre + 0x1D95C); FIX_IMPORT(sysPrxForUser, _sys_vprintf , libsre + 0x1D97C); FIX_IMPORT(sysPrxForUser, _sys_memcmp , libsre + 0x1D99C); + + // fix xrefs + for (u32 i = libsre + 0x30EAC; i < libsre + 0x31EE0; i += 4) + { + Memory.Write32(i, Memory.Read32(i) + libsre); + } }); #endif } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 4dfa98be25..c93f029405 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -16,18 +16,18 @@ //Module sysPrxForUser("sysPrxForUser", sysPrxForUser_init); Module *sysPrxForUser = nullptr; -int sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size) +int _sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size) { - sysPrxForUser->Warning("sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); + sysPrxForUser->Warning("_sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); u32 heap_id = sysPrxForUser->GetNewId(new HeapInfo(heap_addr, align, size)); sysPrxForUser->Warning("*** sys_heap created: id = %d", heap_id); return heap_id; } -int sys_heap_malloc(const u32 heap_id, const u32 size) +int _sys_heap_malloc(const u32 heap_id, const u32 size) { - sysPrxForUser->Warning("sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size); + sysPrxForUser->Warning("_sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size); HeapInfo* heap; if(!sysPrxForUser->CheckId(heap_id, heap)) return CELL_ESRCH; @@ -50,15 +50,15 @@ void sys_initialize_tls() sysPrxForUser->Log("sys_initialize_tls()"); } -s64 sys_process_atexitspawn() +s64 _sys_process_atexitspawn() { - sysPrxForUser->Log("sys_process_atexitspawn()"); + sysPrxForUser->Log("_sys_process_atexitspawn()"); return CELL_OK; } -s64 sys_process_at_Exitspawn() +s64 _sys_process_at_Exitspawn() { - sysPrxForUser->Log("sys_process_at_Exitspawn"); + sysPrxForUser->Log("_sys_process_at_Exitspawn"); return CELL_OK; } @@ -70,9 +70,9 @@ int sys_process_is_stack(u32 p) return (int)(bool)(p >= Memory.StackMem.GetStartAddr() && p <= Memory.StackMem.GetEndAddr()); } -int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5) +int _sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5) { - sysPrxForUser->Warning("sys_spu_printf_initialize(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", a1, a2, a3, a4, a5); + sysPrxForUser->Todo("_sys_spu_printf_initialize(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", a1, a2, a3, a4, a5); return CELL_OK; } @@ -235,8 +235,8 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0x8461e528, sys_time_get_system_time); sysPrxForUser->AddFunc(0xe6f2c1e7, sys_process_exit); - sysPrxForUser->AddFunc(0x2c847572, sys_process_atexitspawn); - sysPrxForUser->AddFunc(0x96328741, sys_process_at_Exitspawn); + sysPrxForUser->AddFunc(0x2c847572, _sys_process_atexitspawn); + sysPrxForUser->AddFunc(0x96328741, _sys_process_at_Exitspawn); sysPrxForUser->AddFunc(0x4f7172c9, sys_process_is_stack); sysPrxForUser->AddFunc(0x24a1ea07, sys_ppu_thread_create); @@ -244,7 +244,7 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0xaff080a4, sys_ppu_thread_exit); sysPrxForUser->AddFunc(0xa3e3be68, sys_ppu_thread_once); - sysPrxForUser->AddFunc(0x45fe2fce, sys_spu_printf_initialize); + sysPrxForUser->AddFunc(0x45fe2fce, _sys_spu_printf_initialize); sysPrxForUser->AddFunc(0x26090058, sys_prx_load_module); sysPrxForUser->AddFunc(0x9f18429d, sys_prx_start_module); @@ -258,10 +258,10 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0xaa6d9bff, sys_prx_load_module_on_memcontainer); sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); - sysPrxForUser->AddFunc(0x35168520, sys_heap_malloc); - //sysPrxForUser->AddFunc(0xaede4b03, sys_heap_free); - //sysPrxForUser->AddFunc(0x8a561d92, sys_heap_delete_heap); - sysPrxForUser->AddFunc(0xb2fcf2c8, sys_heap_create_heap); + sysPrxForUser->AddFunc(0x35168520, _sys_heap_malloc); + //sysPrxForUser->AddFunc(0xaede4b03, _sys_heap_free); + //sysPrxForUser->AddFunc(0x8a561d92, _sys_heap_delete_heap); + sysPrxForUser->AddFunc(0xb2fcf2c8, _sys_heap_create_heap); sysPrxForUser->AddFunc(0x44265c08, _sys_heap_memalign); sysPrxForUser->AddFunc(0xb257540b, sys_mmapper_allocate_memory); @@ -300,5 +300,6 @@ void sysPrxForUser_init() REG_FUNC(sysPrxForUser, _sys_strncmp); REG_FUNC(sysPrxForUser, _sys_strcat); REG_FUNC(sysPrxForUser, _sys_strncat); + REG_FUNC(sysPrxForUser, _sys_strcpy); REG_FUNC(sysPrxForUser, _sys_strncpy); }