From 68cdc95da57b95255ee461e79133e903885cc129 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 30 Sep 2014 02:28:02 +0400 Subject: [PATCH] Some fixes --- rpcs3/Emu/SysCalls/LogBase.cpp | 2 +- rpcs3/Emu/SysCalls/LogBase.h | 8 +- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 16 +-- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 10 +- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 149 ++++++++++++++++++---- rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 26 +++- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 4 +- 7 files changed, 168 insertions(+), 47 deletions(-) diff --git a/rpcs3/Emu/SysCalls/LogBase.cpp b/rpcs3/Emu/SysCalls/LogBase.cpp index 2afeb52bae..0f1a48edf4 100644 --- a/rpcs3/Emu/SysCalls/LogBase.cpp +++ b/rpcs3/Emu/SysCalls/LogBase.cpp @@ -6,7 +6,7 @@ bool LogBase::CheckLogging() const { - return Ini.HLELogging.GetValue(); + return Ini.HLELogging.GetValue() || m_logging; } void LogBase::LogOutput(LogType type, const char* info, const std::string& text) const diff --git a/rpcs3/Emu/SysCalls/LogBase.h b/rpcs3/Emu/SysCalls/LogBase.h index d3ba9cc16b..92848e7ba0 100644 --- a/rpcs3/Emu/SysCalls/LogBase.h +++ b/rpcs3/Emu/SysCalls/LogBase.h @@ -31,12 +31,12 @@ public: template __noinline void Notice(const u32 id, const char* fmt, Targs... args) const { - LogOutput(LogNotice, id, ": ", fmt::Format(fmt, args...)); + LogOutput(LogNotice, id, " : ", fmt::Format(fmt, args...)); } template __noinline void Notice(const char* fmt, Targs... args) const { - LogOutput(LogNotice, ": ", fmt::Format(fmt, args...)); + LogOutput(LogNotice, " : ", fmt::Format(fmt, args...)); } template __forceinline void Log(const char* fmt, Targs... args) const @@ -57,12 +57,12 @@ public: template __noinline void Success(const u32 id, const char* fmt, Targs... args) const { - LogOutput(LogSuccess, id, ": ", fmt::Format(fmt, args...)); + LogOutput(LogSuccess, id, " : ", fmt::Format(fmt, args...)); } template __noinline void Success(const char* fmt, Targs... args) const { - LogOutput(LogSuccess, ": ", fmt::Format(fmt, args...)); + LogOutput(LogSuccess, " : ", fmt::Format(fmt, args...)); } template __noinline void Warning(const u32 id, const char* fmt, Targs... args) const diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index ea76f998d2..609096d59c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -19,7 +19,7 @@ u32 libpngdec_rtoc; s32 pngDecCreate( vm::ptr mainHandle, vm::ptr param, - vm::ptr ext = {}) + vm::ptr ext = vm::ptr::make(0)) { // alloc memory (should probably use param->cbCtrlMallocFunc) auto dec = CellPngDecMainHandle::make(Memory.Alloc(sizeof(PngDecoder), 128)); @@ -60,8 +60,8 @@ s32 pngDecOpen( vm::ptr subHandle, vm::ptr src, vm::ptr openInfo, - vm::ptr cb = {}, - vm::ptr param = {}) + vm::ptr cb = vm::ptr::make(0), + vm::ptr param = vm::ptr::make(0)) { // alloc memory (should probably use dec->malloc) auto stream = CellPngDecSubHandle::make(Memory.Alloc(sizeof(PngStream), 128)); @@ -129,7 +129,7 @@ s32 pngDecClose(CellPngDecSubHandle stream) s32 pngReadHeader( CellPngDecSubHandle stream, vm::ptr info, - vm::ptr extInfo = {}) + vm::ptr extInfo = vm::ptr::make(0)) { CellPngDecInfo& current_info = stream->info; @@ -193,8 +193,8 @@ s32 pngDecSetParameter( CellPngDecSubHandle stream, vm::ptr inParam, vm::ptr outParam, - vm::ptr extInParam = {}, - vm::ptr extOutParam = {}) + vm::ptr extInParam = vm::ptr::make(0), + vm::ptr extOutParam = vm::ptr::make(0)) { CellPngDecInfo& current_info = stream->info; CellPngDecOutParam& current_outParam = stream->outParam; @@ -235,8 +235,8 @@ s32 pngDecodeData( vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo, - vm::ptr cbCtrlDisp = {}, - vm::ptr dispParam = {}) + vm::ptr cbCtrlDisp = vm::ptr::make(0), + vm::ptr dispParam = vm::ptr::make(0)) { dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP; diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 9c07072b33..8c7961e5b1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -603,7 +603,7 @@ void cellRescExit() if (IsPalTemporal()) { cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_DISABLE); - cellGcmSetVBlankHandler({}); + cellGcmSetVBlankHandler(vm::ptr::make(0)); //GcmSysTypePrefix::cellGcmSetSecondVHandler(NULL); if (IsPalInterpolate()) @@ -780,20 +780,20 @@ int cellRescSetDisplayMode(u32 displayMode) cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); //cellGcmSetVBlankHandler(IntrHandler50); //cellGcmSetSecondVHandler(IntrHandler60); - cellGcmSetFlipHandler({}); + cellGcmSetFlipHandler(vm::ptr::make(0)); } else if (IsPalDrop()) { //InitLabels(); cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); - cellGcmSetVBlankHandler({}); + cellGcmSetVBlankHandler(vm::ptr::make(0)); //cellGcmSetSecondVHandler(IntrHandler60Drop); - cellGcmSetFlipHandler({}); + cellGcmSetFlipHandler(vm::ptr::make(0)); } else if (IsPal60Hsync()) { cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); - cellGcmSetVBlankHandler({}); + cellGcmSetVBlankHandler(vm::ptr::make(0)); } if (s_rescInternalInstance->s_applicationVBlankHandler) SetVBlankHandler(s_rescInternalInstance->s_applicationVBlankHandler); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 82cff805eb..feb8651edc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Callback.h" @@ -92,7 +93,7 @@ s64 spursInit( if (!isSecond) { - spurs->m.wklMsk1.write_relaxed(be_t::make(0xffff)); + spurs->m.wklMskA.write_relaxed(be_t::make(0xffff)); } spurs->m.xCC = 0; spurs->m.xCD = 0; @@ -184,7 +185,7 @@ s64 spursInit( assert(lwmutex_create(spurs->m.mutex, SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, *(u64*)"_spuPrv") == CELL_OK); assert(lwcond_create(spurs->m.cond, spurs->m.mutex, *(u64*)"_spuPrv") == CELL_OK); - spurs->m.flags1 = (flags & SAF_EXIT_IF_NO_WORK) << 7 | (isSecond ? 0x40 : 0); + spurs->m.flags1 = (flags & SAF_EXIT_IF_NO_WORK ? SF1_EXIT_IF_NO_WORK : 0) | (isSecond ? SF1_IS_SECOND : 0); spurs->m.flagRecv.write_relaxed(0xff); spurs->m.wklFlag.flag.write_relaxed(be_t::make(-1)); spurs->_u8[0xD64] = 0; @@ -206,10 +207,110 @@ s64 spursInit( spurs->m.ppu0 = ppu_thread_create(0, 0, ppuPriority, 0x4000, true, false, name + "SpursHdlr0", [spurs](PPUThread& CPU) { -#ifdef PRX_DEBUG +#ifdef PRX_DEBUG_XXX return cb_call>(CPU, libsre + 0x9214, libsre_rtoc, spurs); #endif + if (spurs->m.flags & SAF_UNKNOWN_FLAG_30) + { + return; + } + while (true) + { + if (Emu.IsStopped()) + { + cellSpurs->Warning("SPURS Handler Thread 0 aborted"); + return; + } + + if (spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) + { + assert(sys_lwmutex_lock(spurs->get_lwmutex(), 0) == CELL_OK); + if (spurs->m.xD66.read_relaxed()) + { + assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == CELL_OK); + return; + } + else while (true) + { + spurs->m.xD64.exchange(0); + if (spurs->m.exception.ToBE() == 0) + { + bool do_break = false; + for (u32 i = 0; i < 16; i++) + { + if (spurs->m.wklStat1[i].read_relaxed() == 2 && + spurs->m.wklG1[i].wklPriority.ToBE() != 0 && + spurs->_u8[0x50 + i] & 0xf // check wklMaxCnt + ) + { + if (spurs->m.wklReadyCount[i].read_relaxed() || + spurs->m.wklSet1.read_relaxed() & (0x8000u >> i) || + spurs->m.wklFlag.flag.read_relaxed() == 0 && + spurs->m.flagRecv.read_relaxed() == (u8)i + ) + { + do_break = true; + break; + } + } + } + if (spurs->m.flags1 & SF1_IS_SECOND) for (u32 i = 0; i < 16; i++) + { + if (spurs->m.wklStat2[i].read_relaxed() == 2 && + spurs->m.wklG2[i].wklPriority.ToBE() != 0 && + spurs->_u8[0x50 + i] & 0xf0 // check wklMaxCnt + ) + { + if (spurs->m.wklReadyCount[i + 0x10].read_relaxed() || + spurs->m.wklSet2.read_relaxed() & (0x8000u >> i) || + spurs->m.wklFlag.flag.read_relaxed() == 0 && + spurs->m.flagRecv.read_relaxed() == (u8)i + 0x10 + ) + { + do_break = true; + break; + } + } + } + if (do_break) break; // from while + } + + spurs->m.xD65.exchange(1); + if (spurs->m.xD64.read_relaxed() == 0) + { + assert(sys_lwcond_wait(spurs->get_lwcond(), 0) == CELL_OK); + } + spurs->m.xD65.exchange(0); + if (spurs->m.xD66.read_relaxed()) + { + assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == CELL_OK); + return; + } + } + assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == CELL_OK); + } + + if (Emu.IsStopped()) continue; + + assert(sys_spu_thread_group_start(spurs->m.spuTG) == CELL_OK); + if (s32 res = sys_spu_thread_group_join(spurs->m.spuTG, vm::ptr>::make(0), vm::ptr>::make(0))) + { + if (res == CELL_ESTAT) + { + return; + } + assert(res == CELL_OK); + } + + if (Emu.IsStopped()) continue; + + if ((spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) == 0) + { + assert(spurs->m.xD66.read_relaxed() == 1 || Emu.IsStopped()); + return; + } + } })->GetId(); spurs->m.ppu1 = ppu_thread_create(0, 0, ppuPriority, 0x8000, true, false, name + "SpursHdlr1", [spurs](PPUThread& CPU) @@ -775,9 +876,9 @@ s64 spursWakeUp(vm::ptr spurs) spurs->m.xD64.exchange(1); if (spurs->m.xD65.read_sync()) { - assert(sys_lwmutex_lock(vm::ptr::make(spurs.addr() + 0xdb0), 0) == 0); - assert(sys_lwcond_signal(vm::ptr::make(spurs.addr() + 0xdc8)) == 0); - assert(sys_lwmutex_unlock(vm::ptr::make(spurs.addr() + 0xdb0)) == 0); + assert(sys_lwmutex_lock(spurs->get_lwmutex(), 0) == 0); + assert(sys_lwcond_signal(spurs->get_lwcond()) == 0); + assert(sys_lwmutex_unlock(spurs->get_lwmutex()) == 0); } return CELL_OK; } @@ -826,8 +927,8 @@ s32 spursAddWorkload( } u32 wnum; - const u32 wmax = spurs->m.flags1 & 0x40 ? 0x20 : 0x10; // check isSecond (TODO: check if can be changed) - spurs->m.wklMsk1.atomic_op([spurs, wmax, &wnum](be_t& value) + const u32 wmax = spurs->m.flags1 & SF1_IS_SECOND ? 0x20u : 0x10u; // TODO: check if can be changed + spurs->m.wklMskA.atomic_op([spurs, wmax, &wnum](be_t& value) { wnum = cntlz32(~(u32)value); // found empty position if (wnum < wmax) @@ -842,7 +943,7 @@ s32 spursAddWorkload( return CELL_SPURS_POLICY_MODULE_ERROR_AGAIN; } - u32 index = wnum % 0x10; + u32 index = wnum & 0xf; if (wnum <= 15) { assert((spurs->m.wklA[wnum] & 0xf) == 0); @@ -856,15 +957,15 @@ s32 spursAddWorkload( spurs->m.wklG1[wnum].wklPriority = *(be_t*)priorityTable; spurs->m.wklH1[wnum].nameClass = nameClass; spurs->m.wklH1[wnum].nameInstance = nameInstance; - memset(spurs->m.wklF1[wnum].unk0, 0, 0x18); // clear struct preserving semaphore id - memset(spurs->m.wklF1[wnum].unk1, 0, 0x60); + memset(spurs->m.wklF1[wnum].unk0, 0, 0x20); // clear struct preserving semaphore id + memset(spurs->m.wklF1[wnum].unk1, 0, 0x58); if (hook) { spurs->m.wklF1[wnum].hook = hook; spurs->m.wklF1[wnum].hookArg = hookArg; spurs->m.wklE1[wnum] |= 2; } - if ((spurs->m.flags1 & 0x40) == 0) + if ((spurs->m.flags1 & SF1_IS_SECOND) == 0) { spurs->m.wklReadyCount[wnum + 16].write_relaxed(0); spurs->m.wklMinCnt[wnum] = minContention > 8 ? 8 : minContention; @@ -883,8 +984,8 @@ s32 spursAddWorkload( spurs->m.wklG2[index].wklPriority = *(be_t*)priorityTable; spurs->m.wklH2[index].nameClass = nameClass; spurs->m.wklH2[index].nameInstance = nameInstance; - memset(spurs->m.wklF2[index].unk0, 0, 0x18); // clear struct preserving semaphore id - memset(spurs->m.wklF2[index].unk1, 0, 0x60); + memset(spurs->m.wklF2[index].unk0, 0, 0x20); // clear struct preserving semaphore id + memset(spurs->m.wklF2[index].unk1, 0, 0x58); if (hook) { spurs->m.wklF2[index].hook = hook; @@ -920,7 +1021,7 @@ s32 spursAddWorkload( u32 res_wkl; CellSpurs::_sub_str3& wkl = wnum <= 15 ? spurs->m.wklG1[wnum] : spurs->m.wklG2[wnum & 0xf]; - spurs->m.wklMsk2.atomic_op_sync([spurs, &wkl, wnum, &res_wkl](be_t& v) + spurs->m.wklMskB.atomic_op_sync([spurs, &wkl, wnum, &res_wkl](be_t& v) { const u32 mask = v.ToLE() & ~(0x80000000u >> wnum); res_wkl = 0; @@ -951,7 +1052,7 @@ s32 spursAddWorkload( spurs->wklStat(wnum).exchange(2); spurs->m.xBD.exchange(0xff); - spurs->m.x72.exchange(0); + spurs->m.x72.exchange(0xff); return CELL_OK; } @@ -981,10 +1082,10 @@ s64 cellSpursAddWorkload( *priorityTable, minContention, maxContention, - {}, - {}, - {}, - {}); + vm::ptr::make(0), + vm::ptr::make(0), + vm::ptr::make(0), + vm::ptr::make(0)); } s64 _cellSpursWorkloadAttributeInitialize( @@ -1162,11 +1263,11 @@ s64 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (wid >= (spurs->m.flags1 & 0x40 ? 0x20u : 0x10u)) + if (wid >= (spurs->m.flags1 & SF1_IS_SECOND ? 0x20u : 0x10u)) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if ((spurs->m.wklMsk1.read_relaxed().ToLE() & (0x80000000u >> wid)) == 0) + if ((spurs->m.wklMskA.read_relaxed().ToLE() & (0x80000000u >> wid)) == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; } @@ -1274,11 +1375,11 @@ s64 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (wid >= (spurs->m.flags1 & 0x40 ? 0x20u : 0x10u) || value > 0xff) + if (wid >= (spurs->m.flags1 & SF1_IS_SECOND ? 0x20u : 0x10u) || value > 0xff) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if ((spurs->m.wklMsk1.read_relaxed().ToLE() & (0x80000000u >> wid)) == 0) + if ((spurs->m.wklMskA.read_relaxed().ToLE() & (0x80000000u >> wid)) == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index 87a01466f1..873c14d6ca 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -141,8 +141,10 @@ struct CellSpurs; enum SpursAttrFlags : u32 { SAF_NONE = 0x0, + SAF_EXIT_IF_NO_WORK = 0x1, - SAF_SECOND_VERSION = 0x4, + SAF_UNKNOWN_FLAG_30 = 0x2, + SAF_SECOND_VERSION = 0x4, SAF_UNKNOWN_FLAG_9 = 0x00400000, SAF_UNKNOWN_FLAG_8 = 0x00800000, @@ -154,6 +156,14 @@ enum SpursAttrFlags : u32 SAF_UNKNOWN_FLAG_0 = 0x80000000, }; +enum SpursFlags1 : u8 +{ + SF1_NONE = 0x0, + + SF1_IS_SECOND = 0x40, + SF1_EXIT_IF_NO_WORK = 0x80, +}; + struct CellSpursAttribute { static const uint align = 8; @@ -279,8 +289,8 @@ struct CellSpurs atomic_t wklStat1[0x10]; // 0x80 u8 wklD1[0x10]; // 0x90 u8 wklE1[0x10]; // 0xA0 - atomic_t wklMsk1; // 0xB0 - atomic_t wklMsk2; // 0xB4 + atomic_t wklMskA; // 0xB0 + atomic_t wklMskB; // 0xB4 u8 xB8[5]; // 0xB8 atomic_t xBD; // 0xBD u8 xBE[2]; // 0xBE @@ -361,6 +371,16 @@ struct CellSpurs return m.wklStat1[wid & 0xf]; } } + + __forceinline vm::ptr get_lwmutex() + { + return vm::ptr::make(Memory.RealToVirtualAddr(&m.mutex)); + } + + __forceinline vm::ptr get_lwcond() + { + return vm::ptr::make(Memory.RealToVirtualAddr(&m.cond)); + } }; typedef CellSpurs CellSpurs2; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 5592521d18..4a0e1a3ccd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1087,7 +1087,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } } - assert(sys_event_queue_receive(queue->m_eq_id, {}, 0) == CELL_OK); + assert(sys_event_queue_receive(queue->m_eq_id, vm::ptr::make(0), 0) == CELL_OK); var1 = 1; } } @@ -1466,7 +1466,7 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i } } - assert(sys_event_queue_receive(queue->m_eq_id, {}, 0) == CELL_OK); + assert(sys_event_queue_receive(queue->m_eq_id, vm::ptr::make(0), 0) == CELL_OK); var1 = 1; } }