From ecbc9d1b080494342f5682937e93881f1590b49e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 20:10:18 +0400 Subject: [PATCH] RawSPU cleanup --- rpcs3/Emu/Cell/RawSPUThread.cpp | 183 ++++---------------------------- rpcs3/Emu/Cell/SPUThread.cpp | 6 +- rpcs3/Emu/Cell/SPUThread.h | 49 ++++----- rpcs3/Emu/Memory/Memory.h | 10 +- 4 files changed, 54 insertions(+), 194 deletions(-) diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 7255e31952..2337f6d0e1 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -22,75 +22,20 @@ RawSPUThread::~RawSPUThread() bool RawSPUThread::Read32(const u64 addr, u32* value) { - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Read32(addr, value); - } + const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - - switch(offset) + switch (offset) { - case MFC_LSA_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_LSA)", m_index); - *value = MFC2.LSA.GetValue(); - break; - } - - case MFC_EAH_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_EAH)", m_index); - *value = MFC2.EAH.GetValue(); - break; - } - - case MFC_EAL_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_EAL)", m_index); - *value = MFC2.EAL.GetValue(); - break; - } - - case MFC_Size_Tag_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_Size_Tag)", m_index); - *value = MFC2.Size_Tag.GetValue(); - break; - } - case MFC_CMDStatus_offs: { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_CMDStatus)", m_index); *value = MFC2.CMDStatus.GetValue(); break; } case MFC_QStatus_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_QStatus)", m_index); - *value = MFC2.QStatus.GetValue(); - break; - } - - case Prxy_QueryType_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(Prxy_QueryType)", m_index); - *value = Prxy.QueryType.GetValue(); - break; - } - - case Prxy_QueryMask_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(Prxy_QueryMask)", m_index); - *value = Prxy.QueryMask.GetValue(); - break; - } - - case Prxy_TagStatus_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); - *value = Prxy.TagStatus.GetValue(); + // TagStatus is not used: mask is written directly + *value = MFC2.QueryMask.GetValue(); break; } @@ -100,62 +45,23 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) SPU.Out_MBox.PopUncond(*value); break; } - - case SPU_In_MBox_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); - while (!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } case SPU_MBox_Status_offs: { - //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_MBox_Status)", m_index); - //SPU.MBox_Status.SetValue(SPU.Out_MBox.GetCount() ? SPU.MBox_Status.GetValue() | 1 : SPU.MBox_Status.GetValue() & ~1); - SPU.MBox_Status.SetValue((SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8)); - *value = SPU.MBox_Status.GetValue(); + *value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8); break; } - case SPU_RunCntl_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); - *value = (u32)IsRunning(); - break; - } - case SPU_Status_offs: { *value = SPU.Status.GetValue(); break; } - - case SPU_NPC_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_NPC)", m_index); - *value = SPU.NPC.GetValue(); - break; - } - - case SPU_RdSigNotify1_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RdSigNotify1)", m_index); - *value = SPU.SNR[0].GetValue(); - break; - } - - case SPU_RdSigNotify2_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RdSigNotify2)", m_index); - *value = SPU.SNR[1].GetValue(); - break; - } default: { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(0x%x)", m_index, offset); - Emu.Pause(); + // TODO: read value from LS if necessary (not important) + LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(0x%llx)", m_index, offset); return false; } } @@ -165,14 +71,9 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) bool RawSPUThread::Write32(const u64 addr, const u32 value) { - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Write32(addr, value); - } + const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - - switch(offset) + switch (offset) { case MFC_LSA_offs: { @@ -205,53 +106,26 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) break; } - case MFC_QStatus_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); - //MFC2.QStatus.SetValue(value); - break; - } - case Prxy_QueryType_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(Prxy_QueryType, 0x%x)", m_index, value); - Prxy.QueryType.SetValue(value); - switch(value) { - case 2: - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Prxy Query Immediate.", m_index); - break; + case 2: break; default: + { LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Unknown Prxy Query Type. (prxy_query=0x%x)", m_index, value); - break; + return false; + } } - Prxy.QueryType.SetValue(0); - MFC2.QStatus.SetValue(Prxy.QueryMask.GetValue()); + MFC2.QueryType.SetValue(value); // not used break; } case Prxy_QueryMask_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); - Prxy.QueryMask.SetValue(value); - break; - } - - case Prxy_TagStatus_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(Prxy_TagStatus, 0x%x)", m_index, value); - Prxy.TagStatus.SetValue(value); - break; - } - - case SPU_Out_MBox_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_Out_MBox, 0x%x)", m_index, value); - while (!SPU.Out_MBox.Push(value) && !Emu.IsStopped()) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + MFC2.QueryMask.SetValue(value); // TagStatus is not used break; } @@ -261,13 +135,6 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) SPU.In_MBox.PushUncond(value); break; } - - case SPU_MBox_Status_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); - SPU.MBox_Status.SetValue(value); - break; - } case SPU_RunCntl_offs: { @@ -289,39 +156,29 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) break; } - case SPU_Status_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); - SPU.Status.SetValue(value); - break; - } - case SPU_NPC_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_NPC, 0x%x)", m_index, value); SPU.NPC.SetValue(value); break; } case SPU_RdSigNotify1_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify1, 0x%x)", m_index, value); - SPU.SNR[0].SetValue(value); + WriteSNR(0, value); break; } case SPU_RdSigNotify2_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify2, 0x%x)", m_index, value); - SPU.SNR[1].SetValue(value); + WriteSNR(1, value); break; } default: { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(0x%x, 0x%x)", m_index, offset, value); - Emu.Pause(); - break; + // TODO: write value to LS if necessary (not important) + LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(0x%llx, 0x%x)", m_index, offset, value); + return false; } } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 9c020cb219..235b73700c 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -75,9 +75,13 @@ void SPUThread::InitRegs() dmac.queue_lock = 0;*/ SPU.Status.SetValue(SPU_STATUS_STOPPED); - Prxy.QueryType.SetValue(0); + + // TODO: check initialization if necessary + MFC2.QueryType.SetValue(0); // prxy MFC1.CMDStatus.SetValue(0); MFC2.CMDStatus.SetValue(0); + MFC1.TagStatus.SetValue(0); + MFC2.TagStatus.SetValue(0); //PC = SPU.NPC.GetValue(); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 5f38235859..abc187e9c2 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -523,16 +523,11 @@ public: Channel<1> EAL; Channel<1> Size_Tag; Channel<1> CMDStatus; - Channel<1> QStatus; - } MFC1, MFC2; - - struct - { - Channel<1> QueryType; + Channel<1> QueryType; // only for prxy Channel<1> QueryMask; Channel<1> TagStatus; Channel<1> AtomicStat; - } Prxy; + } MFC1, MFC2; struct StalledList { @@ -555,7 +550,6 @@ public: Channel<1> Out_MBox; Channel<1> Out_IntrMBox; Channel<4> In_MBox; - Channel<1> MBox_Status; Channel<1> Status; Channel<1> NPC; Channel<1> SNR[2]; @@ -831,7 +825,7 @@ public: reservation.data[i] = *(u128*)&Memory[(u32)ea + i * 16]; *(u128*)&Memory[dmac.ls_offset + lsa + i * 16] = reservation.data[i]; } - Prxy.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); } else if (op == MFC_PUTLLC_CMD) // store conditional { @@ -854,7 +848,7 @@ public: } if (changed == 0) // nothing changed? { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } else if (changed == 1) { @@ -862,7 +856,7 @@ public: { LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 128bit compare and swap"); Emu.Pause(); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } else { @@ -871,11 +865,11 @@ public: 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]) { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } else { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); } /*u32 last_d = last_q * 2; if (buf[last]._u32[last_d] == reservation.data[last]._u32[last_d] && buf[last]._u32[last_d+1] != reservation.data[last]._u32[last_d+1]) @@ -890,7 +884,7 @@ public: { LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 64bit compare and swap"); Emu.Pause(); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); }*/ } } @@ -900,18 +894,18 @@ public: 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(); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } } else { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); } reservation.clear(); } else // failed { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); } } else // store unconditional @@ -920,7 +914,7 @@ public: ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); if (op == MFC_PUTLLUC_CMD) { - Prxy.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); + 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)) @@ -944,12 +938,12 @@ public: { case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount(); case SPU_RdInMbox: return SPU.In_MBox.GetCount(); - case MFC_RdTagStat: return Prxy.TagStatus.GetCount(); + case MFC_RdTagStat: return MFC1.TagStatus.GetCount(); case MFC_RdListStallStat: return StallStat.GetCount(); - case MFC_WrTagUpdate: return Prxy.TagStatus.GetCount(); // hack + 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 Prxy.AtomicStat.GetCount(); + case MFC_RdAtomicStat: return MFC1.AtomicStat.GetCount(); default: { @@ -1115,14 +1109,14 @@ public: case MFC_WrTagMask: { //ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v); - Prxy.QueryMask.SetValue(v); + MFC1.QueryMask.SetValue(v); break; } case MFC_WrTagUpdate: { //ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v); - Prxy.TagStatus.PushUncond(Prxy.QueryMask.GetValue()); + MFC1.TagStatus.PushUncond(MFC1.QueryMask.GetValue()); break; } @@ -1184,7 +1178,7 @@ public: case SPU_WrDec: { - m_dec_start = get_system_time(); + m_dec_start = get_time(); m_dec_value = v; break; } @@ -1215,7 +1209,7 @@ public: case MFC_RdTagStat: { - while (!Prxy.TagStatus.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + while (!MFC1.TagStatus.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); //ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]); break; } @@ -1236,7 +1230,7 @@ public: case MFC_RdAtomicStat: { - while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + while (!MFC1.AtomicStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); break; } @@ -1248,8 +1242,7 @@ public: case SPU_RdDec: { - // decrementer freq is probably 80 MHz - v = m_dec_value - (u32)(get_system_time() - m_dec_start) * 80; + v = m_dec_value - (u32)(get_time() - m_dec_start); break; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 88cc1dea6d..c552fe2f7b 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -401,7 +401,10 @@ public: } else { - RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data); + if (!RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data)) + { + *(u32*)((u8*)GetBaseAddr() + addr) = re32(data); + } } } else @@ -474,7 +477,10 @@ public: else { u32 res; - RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res); + if (!RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res)) + { + res = re32(*(u32*)((u8*)GetBaseAddr() + addr)); + } return res; } }