From 752449bbc005a5ef38191986c7fb8a42f6bc57cb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 2 Oct 2014 14:29:20 +0400 Subject: [PATCH] Small update --- Utilities/BEType.h | 10 +++ rpcs3/Emu/Cell/MFC.h | 1 - rpcs3/Emu/Cell/RawSPUThread.cpp | 2 +- rpcs3/Emu/Cell/SPUInterpreter.h | 2 +- rpcs3/Emu/Cell/SPURecompilerCore.cpp | 8 +- rpcs3/Emu/Cell/SPUThread.cpp | 97 +++++++++++++++++------- rpcs3/Emu/Cell/SPUThread.h | 3 +- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 95 +++++++++++++++++------ rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 28 +++---- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 3 +- 10 files changed, 173 insertions(+), 76 deletions(-) diff --git a/Utilities/BEType.h b/Utilities/BEType.h index ee5989f100..29848bc4ae 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -104,6 +104,16 @@ union u128 return ret; } + static u128 from32r(u32 _3, u32 _2 = 0, u32 _1 = 0, u32 _0 = 0) + { + u128 ret; + ret._u32[0] = _0; + ret._u32[1] = _1; + ret._u32[2] = _2; + ret._u32[3] = _3; + return ret; + } + static u128 fromBit(u32 bit) { u128 ret = {}; diff --git a/rpcs3/Emu/Cell/MFC.h b/rpcs3/Emu/Cell/MFC.h index 5669daabe9..a6c731d3da 100644 --- a/rpcs3/Emu/Cell/MFC.h +++ b/rpcs3/Emu/Cell/MFC.h @@ -61,5 +61,4 @@ enum struct DMAC { - u32 ls_offset; }; diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 0a8270e670..92e0425628 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -190,7 +190,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) void RawSPUThread::InitRegs() { - dmac.ls_offset = m_offset = (u32)GetStartAddr() + RAW_SPU_LS_OFFSET; + ls_offset = m_offset = (u32)GetStartAddr() + RAW_SPU_LS_OFFSET; SPUThread::InitRegs(); } diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index ac6e5df820..eb5b90eb7b 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -3,7 +3,7 @@ #define UNIMPLEMENTED() UNK(__FUNCTION__) #define MEM_AND_REG_HASH() \ - unsigned char mem_h[20]; sha1(vm::get_ptr(CPU.dmac.ls_offset), 256*1024, mem_h); \ + unsigned char mem_h[20]; sha1(vm::get_ptr(CPU.ls_offset), 256*1024, mem_h); \ unsigned char reg_h[20]; sha1((const unsigned char*)CPU.GPR, sizeof(CPU.GPR), reg_h); \ LOG_NOTICE(Log::SPU, "Mem hash: 0x%llx, reg hash: 0x%llx", *(u64*)mem_h, *(u64*)reg_h); diff --git a/rpcs3/Emu/Cell/SPURecompilerCore.cpp b/rpcs3/Emu/Cell/SPURecompilerCore.cpp index 68e929edf3..66c1181a34 100644 --- a/rpcs3/Emu/Cell/SPURecompilerCore.cpp +++ b/rpcs3/Emu/Cell/SPURecompilerCore.cpp @@ -49,7 +49,7 @@ void SPURecompilerCore::Compile(u16 pos) u64 time0 = 0; SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode); - dis_asm.offset = vm::get_ptr(CPU.dmac.ls_offset); + dis_asm.offset = vm::get_ptr(CPU.ls_offset); StringLogger stringLogger; stringLogger.setOption(kLoggerOptionBinaryForm, true); @@ -103,7 +103,7 @@ void SPURecompilerCore::Compile(u16 pos) while (true) { - const u32 opcode = vm::read32(CPU.dmac.ls_offset + pos * 4); + const u32 opcode = vm::read32(CPU.ls_offset + pos * 4); m_enc->do_finalize = false; if (opcode) { @@ -182,8 +182,8 @@ void SPURecompilerCore::Compile(u16 pos) u8 SPURecompilerCore::DecodeMemory(const u32 address) { - assert(CPU.dmac.ls_offset == address - CPU.PC); - const u32 m_offset = CPU.dmac.ls_offset; + assert(CPU.ls_offset == address - CPU.PC); + const u32 m_offset = CPU.ls_offset; const u16 pos = (u16)(CPU.PC >> 2); //ConLog.Write("DecodeMemory: pos=%d", pos); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 0ff0af3c6a..6d494b7ca0 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -80,7 +80,7 @@ void SPUThread::InitRegs() cfg.Reset(); - dmac.ls_offset = m_offset; + ls_offset = m_offset; SPU.Status.SetValue(SPU_STATUS_STOPPED); @@ -148,19 +148,27 @@ void SPUThread::DoClose() void SPUThread::FastCall(u32 ls_addr) { - // doesn't touch thread status (instead of PPUThread::FastCall2); - // can't be called from another thread (because it doesn't make sense); - // FastStop-like routine is not defined (TODO); + // can't be called from another thread (because it doesn't make sense) + WriteLS32(0x0, 2); auto old_PC = PC; - auto old_stack = GPR[1]; // only saved and restored (may be wrong) + auto old_LR = GPR[0]._u32[3]; + auto old_stack = GPR[1]._u32[3]; // only saved and restored (may be wrong) + m_status = Running; PC = ls_addr; + GPR[0]._u32[3] = 0x0; CPUThread::Task(); PC = old_PC; - GPR[1] = old_stack; + GPR[0]._u32[3] = old_LR; + GPR[1]._u32[3] = old_stack; +} + +void SPUThread::FastStop() +{ + m_status = Stopped; } void SPUThread::WriteSNR(bool number, u32 value) @@ -206,11 +214,11 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) if ((addr <= 0x3ffff) && (addr + size <= 0x40000)) { // LS access - ea = spu->dmac.ls_offset + addr; + ea = spu->ls_offset + addr; } else if ((cmd & MFC_PUT_CMD) && size == 4 && (addr == SYS_SPU_THREAD_SNR1 || addr == SYS_SPU_THREAD_SNR2)) { - spu->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, vm::read32(dmac.ls_offset + lsa)); + spu->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, vm::read32(ls_offset + lsa)); return; } else @@ -256,13 +264,13 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { case MFC_PUT_CMD: { - memcpy(vm::get_ptr(ea), vm::get_ptr(dmac.ls_offset + lsa), size); + memcpy(vm::get_ptr(ea), vm::get_ptr(ls_offset + lsa), size); return; } case MFC_GET_CMD: { - memcpy(vm::get_ptr(dmac.ls_offset + lsa), vm::get_ptr(ea), size); + memcpy(vm::get_ptr(ls_offset + lsa), vm::get_ptr(ea), size); return; } @@ -294,7 +302,7 @@ void SPUThread::ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFC for (u32 i = 0; i < list_size; i++) { - auto rec = vm::ptr::make(dmac.ls_offset + list_addr + i * 8); + auto rec = vm::ptr::make(ls_offset + list_addr + i * 8); u32 size = rec->ts; if (!(rec->s.ToBE() & se16(0x8000)) && size < 16 && size != 1 && size != 2 && size != 4 && size != 8) @@ -405,7 +413,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) for (u32 i = 0; i < 16; i++) { R_DATA[i] = vm::get_ptr(R_ADDR)[i]; - vm::get_ptr(dmac.ls_offset + lsa)[i] = R_DATA[i]; + vm::get_ptr(ls_offset + lsa)[i] = R_DATA[i]; } MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); } @@ -419,7 +427,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) u64 buf[16]; for (u32 i = 0; i < 16; i++) { - buf[i] = vm::get_ptr(dmac.ls_offset + lsa)[i]; + buf[i] = vm::get_ptr(ls_offset + lsa)[i]; if (buf[i] != R_DATA[i]) { changed++; @@ -464,8 +472,8 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) for (s32 i = (s32)PC; i < (s32)PC + 4 * 7; i += 4) { dis_asm.dump_pc = i; - dis_asm.offset = vm::get_ptr(dmac.ls_offset); - const u32 opcode = vm::read32(i + dmac.ls_offset); + dis_asm.offset = vm::get_ptr(ls_offset); + const u32 opcode = vm::read32(i + ls_offset); (*SPU_instr::rrr_list)(&dis_asm, opcode); if (i >= 0 && i < 0x40000) { @@ -526,18 +534,20 @@ bool SPUThread::CheckEvents() u32 SPUThread::GetChannelCount(u32 ch) { + u32 res = 0xdeafbeef; + switch (ch) { - case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount(); - case SPU_WrOutIntrMbox: return SPU.Out_IntrMBox.GetFreeCount(); - case SPU_RdInMbox: return SPU.In_MBox.GetCount(); - case MFC_RdTagStat: return MFC1.TagStatus.GetCount(); - case MFC_RdListStallStat: return StallStat.GetCount(); - case MFC_WrTagUpdate: return MFC1.TagStatus.GetCount(); // hack - case SPU_RdSigNotify1: return SPU.SNR[0].GetCount(); - case SPU_RdSigNotify2: return SPU.SNR[1].GetCount(); - case MFC_RdAtomicStat: return MFC1.AtomicStat.GetCount(); - case SPU_RdEventStat: return CheckEvents() ? 1 : 0; + case SPU_WrOutMbox: res = SPU.Out_MBox.GetFreeCount(); break; + case SPU_WrOutIntrMbox: res = SPU.Out_IntrMBox.GetFreeCount(); break; + case SPU_RdInMbox: res = SPU.In_MBox.GetCount(); break; + case MFC_RdTagStat: res = MFC1.TagStatus.GetCount(); break; + case MFC_RdListStallStat: res = StallStat.GetCount(); break; + case MFC_WrTagUpdate: res = MFC1.TagStatus.GetCount(); break;// hack + case SPU_RdSigNotify1: res = SPU.SNR[0].GetCount(); break; + case SPU_RdSigNotify2: res = SPU.SNR[1].GetCount(); break; + case MFC_RdAtomicStat: res = MFC1.AtomicStat.GetCount(); break; + case SPU_RdEventStat: res = CheckEvents() ? 1 : 0; break; default: { @@ -546,12 +556,17 @@ u32 SPUThread::GetChannelCount(u32 ch) return 0; } } + + //LOG_NOTICE(Log::SPU, "%s(%s) -> 0x%x", __FUNCTION__, spu_ch_name[ch], res); + return res; } void SPUThread::WriteChannel(u32 ch, const u128& r) { const u32 v = r._u32[3]; + //LOG_NOTICE(Log::SPU, "%s(%s): v=0x%x", __FUNCTION__, spu_ch_name[ch], v); + switch (ch) { case SPU_WrOutIntrMbox: @@ -908,13 +923,27 @@ void SPUThread::ReadChannel(u128& r, u32 ch) case SPU_RdSigNotify1: { - while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (cfg.value & 1) + { + while (!SPU.SNR[0].Pop_XCHG(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + else + { + while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } break; } case SPU_RdSigNotify2: { - while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (cfg.value & 2) + { + while (!SPU.SNR[1].Pop_XCHG(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + else + { + while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } break; } @@ -964,6 +993,8 @@ void SPUThread::ReadChannel(u128& r, u32 ch) } if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]); + + //LOG_NOTICE(Log::SPU, "%s(%s) -> 0x%x", __FUNCTION__, spu_ch_name[ch], v); } void SPUThread::StopAndSignal(u32 code) @@ -973,6 +1004,18 @@ void SPUThread::StopAndSignal(u32 code) switch (code) { + case 0x001: + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + break; + } + + case 0x002: + { + FastStop(); + break; + } + case 0x110: { /* ===== sys_spu_thread_receive_event ===== */ diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index d8df863bc6..f97c9b2cd6 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -420,7 +420,7 @@ public: struct { u32 EAH, EAL; }; }; - DMAC dmac; + u32 ls_offset; void ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size); @@ -510,6 +510,7 @@ public: virtual void InitRegs(); virtual void Task(); void FastCall(u32 ls_addr); + void FastStop(); protected: virtual void DoReset(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index cd91d4271c..f47af44642 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -102,14 +102,16 @@ s64 spursInit( { spurs->m.xC0[i] = -1; } + + // default or system workload: #ifdef PRX_DEBUG - spurs->m.unk7 = vm::read32(libsre_rtoc - 0x7EA4); // write 64-bit pointer to unknown data + spurs->m.wklSysG.pm.set(be_t::make(vm::read32(libsre_rtoc - 0x7EA4))); #else - spurs->m.unk7 = 0x7ull << 48 | 0x7; // wrong 64-bit address + spurs->m.wklSysG.pm.set(be_t::make(0x100)); // wrong 64-bit address #endif - spurs->m.unk8 = 0ull; - spurs->m.unk9 = 0x2200; - spurs->m.unk10 = -1; + spurs->m.wklSysG.data = 0; + spurs->m.wklSysG.size = 0x2200; + spurs->m.wklSysG.copy.write_relaxed(0xff); u32 sem; for (u32 i = 0; i < 0x10; i++) { @@ -161,13 +163,58 @@ s64 spursInit( name += "CellSpursKernel0"; for (s32 num = 0; num < nSpus; num++, name[name.size() - 1]++) { - spurs->m.spus[num] = spu_thread_initialize(tg, num, spurs->m.spuImg, name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, 0, 0, 0, 0, [spurs, num, isSecond](SPUThread& CPU) + spurs->m.spus[num] = spu_thread_initialize(tg, num, spurs->m.spuImg, name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, 0, 0, 0, 0, [spurs, num, isSecond](SPUThread& SPU) { -#ifdef PRX_DEBUG - CPU.GPR[3]._u32[3] = num; - CPU.GPR[4]._u64[1] = spurs.addr(); - return CPU.FastCall(CPU.PC); +#ifdef PRX_DEBUG_XXX + SPU.GPR[3]._u32[3] = num; + SPU.GPR[4]._u64[1] = spurs.addr(); + return SPU.FastCall(SPU.PC); #endif + SPU.WriteLS128(0x1c0, u128::from32r(0, spurs.addr(), num, 0x1f)); + + u32 wid = 0x20; + while (true) + { + if (Emu.IsStopped()) + { + cellSpurs->Warning("Spurs Kernel aborted"); + return; + } + + // get current workload info: + auto& wkl = wid <= 15 ? spurs->m.wklG1[wid] : (wid <= 31 && isSecond ? spurs->m.wklG2[wid & 0xf] : spurs->m.wklSysG); + + if (SPU.ReadLS64(0x1d0) != wkl.pm.addr()) + { + // load executable code: + memcpy(vm::get_ptr(SPU.ls_offset + 0xa00), wkl.pm.get_ptr(), wkl.size); + SPU.WriteLS64(0x1d0, wkl.pm.addr()); + SPU.WriteLS32(0x1d8, wkl.priority.ToLE() >> 24 & 0xff); // ??? + } + + if (!isSecond) SPU.WriteLS16(0x1e8, 0); + + // run workload: + SPU.GPR[1]._u32[3] = 0x3FFB0; + SPU.GPR[3]._u32[3] = 0x100; + SPU.GPR[4]._u64[1] = wkl.data; + SPU.GPR[5]._u32[3] = 0; + SPU.FastCall(0xa00); + + // check status: + auto status = SPU.SPU.Status.GetValue(); + if (status == SPU_STATUS_STOPPED_BY_STOP) + { + return; + } + else + { + assert(status == SPU_STATUS_RUNNING); + } + + // get workload id: + + } })->GetId(); } @@ -240,7 +287,7 @@ s64 spursInit( for (u32 i = 0; i < 16; i++) { if (spurs->m.wklStat1[i].read_relaxed() == 2 && - spurs->m.wklG1[i].wklPriority.ToBE() != 0 && + spurs->m.wklG1[i].priority.ToBE() != 0 && spurs->m.wklMaxCnt[i].read_relaxed() & 0xf ) { @@ -258,7 +305,7 @@ s64 spursInit( 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->m.wklG2[i].priority.ToBE() != 0 && spurs->m.wklMaxCnt[i].read_relaxed() & 0xf0 ) { @@ -951,10 +998,10 @@ s32 spursAddWorkload( spurs->m.wklStat1[wnum].write_relaxed(1); spurs->m.wklD1[wnum] = 0; spurs->m.wklE1[wnum] = 0; - spurs->m.wklG1[wnum].wklPm = pm; - spurs->m.wklG1[wnum].wklArg = data; - spurs->m.wklG1[wnum].wklSize = size; - spurs->m.wklG1[wnum].wklPriority = *(be_t*)priorityTable; + spurs->m.wklG1[wnum].pm = pm; + spurs->m.wklG1[wnum].data = data; + spurs->m.wklG1[wnum].size = size; + spurs->m.wklG1[wnum].priority = *(be_t*)priorityTable; spurs->m.wklH1[wnum].nameClass = nameClass; spurs->m.wklH1[wnum].nameInstance = nameInstance; memset(spurs->m.wklF1[wnum].unk0, 0, 0x20); // clear struct preserving semaphore id @@ -978,10 +1025,10 @@ s32 spursAddWorkload( spurs->m.wklStat2[index].write_relaxed(1); spurs->m.wklD2[index] = 0; spurs->m.wklE2[index] = 0; - spurs->m.wklG2[index].wklPm = pm; - spurs->m.wklG2[index].wklArg = data; - spurs->m.wklG2[index].wklSize = size; - spurs->m.wklG2[index].wklPriority = *(be_t*)priorityTable; + spurs->m.wklG2[index].pm = pm; + spurs->m.wklG2[index].data = data; + spurs->m.wklG2[index].size = size; + spurs->m.wklG2[index].priority = *(be_t*)priorityTable; spurs->m.wklH2[index].nameClass = nameClass; spurs->m.wklH2[index].nameInstance = nameInstance; memset(spurs->m.wklF2[index].unk0, 0, 0x20); // clear struct preserving semaphore id @@ -1034,21 +1081,21 @@ s32 spursAddWorkload( if (mask & m) { CellSpurs::_sub_str3& current = i <= 15 ? spurs->m.wklG1[i] : spurs->m.wklG2[i & 0xf]; - if (current.wklPm.addr() == wkl.wklPm.addr()) + if (current.pm.addr() == wkl.pm.addr()) { // if a workload with identical policy module found - res_wkl = current.wklCopy.read_relaxed(); + res_wkl = current.copy.read_relaxed(); break; } else { - k |= 0x80000000 >> current.wklCopy.read_relaxed(); + k |= 0x80000000 >> current.copy.read_relaxed(); res_wkl = cntlz32(~k); } } } - wkl.wklCopy.exchange((u8)res_wkl); + wkl.copy.exchange((u8)res_wkl); v = mask | (0x80000000u >> wnum); }); assert(res_wkl <= 31); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index 6ce2ae8ee1..4e72b50826 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -221,8 +221,6 @@ struct CellSpurs struct _sub_str1 { - static const uint size = 0x80; - u8 unk0[0x20]; be_t sem; // 0x20 u8 unk1[0x8]; @@ -231,10 +229,10 @@ struct CellSpurs u8 unk2[0x40]; }; + static_assert(sizeof(_sub_str1) == 0x80, "Wrong _sub_str1 size"); + struct _sub_str2 { - static const uint size = 0x80; - be_t unk0; be_t unk1; be_t unk2; @@ -243,17 +241,19 @@ struct CellSpurs u8 unk_[0x68]; }; + static_assert(sizeof(_sub_str2) == 0x80, "Wrong _sub_str2 size"); + struct _sub_str3 { - static const uint size = 0x20; - - vm::bptr wklPm; // policy module - be_t wklArg; // spu argument - be_t wklSize; - atomic_t wklCopy; - be_t wklPriority; + vm::bptr pm; // policy module + be_t data; // spu argument + be_t size; + atomic_t copy; + be_t priority; }; + static_assert(sizeof(_sub_str3) == 0x20, "Wrong _sub_str3 size"); + struct _sub_str4 { static const uint size = 0x10; @@ -315,11 +315,7 @@ struct CellSpurs be_t unk13; // 0x990 u8 unknown4[0xB00 - 0x998]; _sub_str3 wklG1[0x10]; // 0xB00 - be_t unk7; // 0xD00 - be_t unk8; // 0xD08 - be_t unk9; // 0xD10 - u8 unk10; // 0xD14 - u8 unknown5[0xD20 - 0xD15]; + _sub_str3 wklSysG; // 0xD00 be_t ppu0; // 0xD20 be_t ppu1; // 0xD28 be_t spuTG; // 0xD30 diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index adc2efb62a..94326ef56e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -236,6 +236,7 @@ s32 sys_spu_thread_group_start(u32 id) CPUThread* t = Emu.GetCPU().GetThread(group_info->list[i]); if (t) { + ((SPUThread*)t)->SPU.Status.SetValue(SPU_STATUS_RUNNING); t->Exec(); } } @@ -471,7 +472,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr> cause, vm::ptrlist[i])) { - if (!t->IsRunning()) + if (!t->IsAlive()) { if (((SPUThread*)t)->SPU.Status.GetValue() != SPU_STATUS_STOPPED_BY_STOP) {