Some fixes

This commit is contained in:
Nekotekina 2014-08-20 04:32:25 +04:00
parent 0a0ccb54bf
commit ffa258d334
4 changed files with 56 additions and 69 deletions

View file

@ -13,10 +13,7 @@ struct reservation_struct
// and doesn't give a chance to finish some work before losing the reservation // and doesn't give a chance to finish some work before losing the reservation
u32 owner; // id of thread that got reservation u32 owner; // id of thread that got reservation
u64 addr; u64 addr;
u32 size; u64 data[16];
u32 data32;
u64 data64;
u128 data[8];
__forceinline void clear() __forceinline void clear()
{ {

View file

@ -778,68 +778,48 @@ public:
SMutexLockerR lock(reservation.mutex); SMutexLockerR lock(reservation.mutex);
reservation.owner = lock.tid; reservation.owner = lock.tid;
reservation.addr = ea; reservation.addr = ea;
reservation.size = 128; for (u32 i = 0; i < 16; i++)
for (u32 i = 0; i < 8; i++)
{ {
reservation.data[i] = *(u128*)&Memory[(u32)ea + i * 16]; reservation.data[i] = *(u64*)&Memory[(u32)ea + i * 8];
*(u128*)&Memory[dmac.ls_offset + lsa + i * 16] = reservation.data[i]; *(u64*)&Memory[dmac.ls_offset + lsa + i * 8] = reservation.data[i];
} }
MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS);
} }
else if (op == MFC_PUTLLC_CMD) // store conditional else if (op == MFC_PUTLLC_CMD) // store conditional
{ {
SMutexLockerR lock(reservation.mutex); SMutexLockerR lock(reservation.mutex);
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS);
if (reservation.owner == lock.tid) // succeeded 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; 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]) if (buf[i] != reservation.data[i])
{ {
changed++; changed++;
last = i; last = i;
mask |= (0xf << (i * 4)); mask |= (0x3 << (i * 2));
}
}
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);
if (InterlockedCompareExchange64((volatile long long*)(Memory + ((u32)ea + last * 16 + last_q * 8)), if (InterlockedCompareExchange64((volatile long long*)(Memory + ((u32)ea + last * 8)), buf[last], reservation.data[last]) != reservation.data[last])
buf[last]._u64[last_q], reservation.data[last]._u64[last_q]) == reservation.data[last]._u64[last_q])
{
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS);
}
else
{ {
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); 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 else
{ {
@ -860,8 +840,7 @@ public:
{ {
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS);
} }
if ((reservation.addr + reservation.size > ea && reservation.addr <= ea + size) || if (reservation.addr == ea)
(ea + size > reservation.addr && ea <= reservation.addr + reservation.size))
{ {
reservation.clear(); reservation.clear();
} }
@ -1135,7 +1114,7 @@ public:
default: 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; break;
} }
} }

View file

@ -18,9 +18,12 @@ u32 libsre_rtoc;
void fix_import(Module* module, u32 func, u32 addr) void fix_import(Module* module, u32 func, u32 addr)
{ {
Memory.Write32((addr), 0x3d600000 | (func >> 16)); /* lis r11, (func_id >> 16) */ Memory.Write32(addr + 0x0, 0x3d600000 | (func >> 16)); /* lis r11, (func_id >> 16) */
Memory.Write32((addr) + 4, 0x616b0000 | (func & 0xffff)); /* ori r11, (func_id & 0xffff) */ Memory.Write32(addr + 0x4, 0x616b0000 | (func & 0xffff)); /* ori r11, (func_id & 0xffff) */
Memory.Write64((addr) + 8, 0x440000024e800020ull); /* sc + blr */ 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); module->Load(func);
} }
@ -1513,8 +1516,6 @@ s32 _cellSyncLFQueuePushBody(mem_ptr_t<CellSyncLFQueue> queue, u32 buffer_addr,
// cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 // 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); 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) if (!queue || !buffer_addr)
{ {
return CELL_SYNC_ERROR_NULL_POINTER; return CELL_SYNC_ERROR_NULL_POINTER;
@ -2226,6 +2227,9 @@ void cellSync_init()
extern Module* sysPrxForUser; 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_strncmp , libsre + 0x1D5FC);
FIX_IMPORT(sysPrxForUser, _sys_strcat , libsre + 0x1D61C); FIX_IMPORT(sysPrxForUser, _sys_strcat , libsre + 0x1D61C);
FIX_IMPORT(sysPrxForUser, _sys_vsnprintf , libsre + 0x1D63C); 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_lwcond_signal , libsre + 0x1D95C);
FIX_IMPORT(sysPrxForUser, _sys_vprintf , libsre + 0x1D97C); FIX_IMPORT(sysPrxForUser, _sys_vprintf , libsre + 0x1D97C);
FIX_IMPORT(sysPrxForUser, _sys_memcmp , libsre + 0x1D99C); 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 #endif
} }

View file

@ -16,18 +16,18 @@
//Module sysPrxForUser("sysPrxForUser", sysPrxForUser_init); //Module sysPrxForUser("sysPrxForUser", sysPrxForUser_init);
Module *sysPrxForUser = nullptr; 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)); u32 heap_id = sysPrxForUser->GetNewId(new HeapInfo(heap_addr, align, size));
sysPrxForUser->Warning("*** sys_heap created: id = %d", heap_id); sysPrxForUser->Warning("*** sys_heap created: id = %d", heap_id);
return 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; HeapInfo* heap;
if(!sysPrxForUser->CheckId(heap_id, heap)) return CELL_ESRCH; if(!sysPrxForUser->CheckId(heap_id, heap)) return CELL_ESRCH;
@ -50,15 +50,15 @@ void sys_initialize_tls()
sysPrxForUser->Log("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; 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; 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()); 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; return CELL_OK;
} }
@ -235,8 +235,8 @@ void sysPrxForUser_init()
sysPrxForUser->AddFunc(0x8461e528, sys_time_get_system_time); sysPrxForUser->AddFunc(0x8461e528, sys_time_get_system_time);
sysPrxForUser->AddFunc(0xe6f2c1e7, sys_process_exit); sysPrxForUser->AddFunc(0xe6f2c1e7, sys_process_exit);
sysPrxForUser->AddFunc(0x2c847572, sys_process_atexitspawn); sysPrxForUser->AddFunc(0x2c847572, _sys_process_atexitspawn);
sysPrxForUser->AddFunc(0x96328741, sys_process_at_Exitspawn); sysPrxForUser->AddFunc(0x96328741, _sys_process_at_Exitspawn);
sysPrxForUser->AddFunc(0x4f7172c9, sys_process_is_stack); sysPrxForUser->AddFunc(0x4f7172c9, sys_process_is_stack);
sysPrxForUser->AddFunc(0x24a1ea07, sys_ppu_thread_create); sysPrxForUser->AddFunc(0x24a1ea07, sys_ppu_thread_create);
@ -244,7 +244,7 @@ void sysPrxForUser_init()
sysPrxForUser->AddFunc(0xaff080a4, sys_ppu_thread_exit); sysPrxForUser->AddFunc(0xaff080a4, sys_ppu_thread_exit);
sysPrxForUser->AddFunc(0xa3e3be68, sys_ppu_thread_once); 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(0x26090058, sys_prx_load_module);
sysPrxForUser->AddFunc(0x9f18429d, sys_prx_start_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(0xaa6d9bff, sys_prx_load_module_on_memcontainer);
sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level);
sysPrxForUser->AddFunc(0x35168520, sys_heap_malloc); sysPrxForUser->AddFunc(0x35168520, _sys_heap_malloc);
//sysPrxForUser->AddFunc(0xaede4b03, sys_heap_free); //sysPrxForUser->AddFunc(0xaede4b03, _sys_heap_free);
//sysPrxForUser->AddFunc(0x8a561d92, sys_heap_delete_heap); //sysPrxForUser->AddFunc(0x8a561d92, _sys_heap_delete_heap);
sysPrxForUser->AddFunc(0xb2fcf2c8, sys_heap_create_heap); sysPrxForUser->AddFunc(0xb2fcf2c8, _sys_heap_create_heap);
sysPrxForUser->AddFunc(0x44265c08, _sys_heap_memalign); sysPrxForUser->AddFunc(0x44265c08, _sys_heap_memalign);
sysPrxForUser->AddFunc(0xb257540b, sys_mmapper_allocate_memory); sysPrxForUser->AddFunc(0xb257540b, sys_mmapper_allocate_memory);
@ -300,5 +300,6 @@ void sysPrxForUser_init()
REG_FUNC(sysPrxForUser, _sys_strncmp); REG_FUNC(sysPrxForUser, _sys_strncmp);
REG_FUNC(sysPrxForUser, _sys_strcat); REG_FUNC(sysPrxForUser, _sys_strcat);
REG_FUNC(sysPrxForUser, _sys_strncat); REG_FUNC(sysPrxForUser, _sys_strncat);
REG_FUNC(sysPrxForUser, _sys_strcpy);
REG_FUNC(sysPrxForUser, _sys_strncpy); REG_FUNC(sysPrxForUser, _sys_strncpy);
} }