From fa5311718eb700a641bfbdf896cbfd83e2c46c98 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 21 Jul 2014 22:35:44 +0400 Subject: [PATCH] Small SPU cleanup --- rpcs3/Emu/CPU/CPUThread.h | 2 +- rpcs3/Emu/Cell/MFC.h | 230 ------------------------------------- rpcs3/Emu/Cell/SPUThread.h | 94 +++++---------- 3 files changed, 30 insertions(+), 296 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index c7db9d1c0d..343f992d8f 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -12,7 +12,7 @@ struct reservation_struct // std::mutex doesn't work because it probably wakes up waiting threads in the most unwanted order // and doesn't give a chance to finish some work before losing the reservation u32 owner; // id of thread that got reservation - u32 addr; + u64 addr; u32 size; u32 data32; u64 data64; diff --git a/rpcs3/Emu/Cell/MFC.h b/rpcs3/Emu/Cell/MFC.h index f85e4eb9b3..9f93ce6104 100644 --- a/rpcs3/Emu/Cell/MFC.h +++ b/rpcs3/Emu/Cell/MFC.h @@ -60,237 +60,7 @@ enum MFC_SPU_MAX_QUEUE_SPACE = 0x10, }; -/*struct DMAC_Queue -{ - bool is_valid; - u64 ea; - u32 lsa; - u16 size; - u32 op; - u8 tag; - u8 rt; - u16 list_addr; - u16 list_size; - u32 dep_state; - u32 cmd; - u32 dep_type; -}; - -struct DMAC_Proxy -{ - u64 ea; - u32 lsa; - u16 size; - u32 op; - u8 tag; - u8 rt; - u16 list_addr; - u16 list_size; - u32 dep_state; - u32 cmd; - u32 dep_type; -}; - -template -class SPUReg -{ - u64 m_addr; - u32 m_pos; - -public: - static const size_t max_count = _max_count; - static const size_t size = max_count * 4; - - SPUReg() - { - Init(); - } - - void Init() - { - m_pos = 0; - } - - void SetAddr(u64 addr) - { - m_addr = addr; - } - - u64 GetAddr() const - { - return m_addr; - } - - __forceinline bool Pop(u32& res) - { - if(!m_pos) return false; - res = Memory.Read32(m_addr + m_pos--); - return true; - } - - __forceinline bool Push(u32 value) - { - if(m_pos >= max_count) return false; - Memory.Write32(m_addr + m_pos++, value); - return true; - } - - u32 GetCount() const - { - return m_pos; - } - - u32 GetFreeCount() const - { - return max_count - m_pos; - } - - void SetValue(u32 value) - { - Memory.Write32(m_addr, value); - } - - u32 GetValue() const - { - return Memory.Read32(m_addr); - } -};*/ - struct DMAC { u64 ls_offset; - - /*//DMAC_Queue queue[MFC_SPU_MAX_QUEUE_SPACE]; //not used yet - DMAC_Proxy proxy[MFC_PPU_MAX_QUEUE_SPACE+MFC_SPU_MAX_QUEUE_SPACE]; //temporarily 24 - u32 queue_pos; - u32 proxy_pos; - long queue_lock; - volatile std::atomic proxy_lock; - - bool ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) - { - //returns true if the command should be deleted from the queue - if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); - - switch(cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK)) - { - case MFC_PUT_CMD: - Memory.Copy(ea, ls_offset + lsa, size); - return true; - - case MFC_GET_CMD: - Memory.Copy(ls_offset + lsa, ea, size); - return true; - - default: - LOG_ERROR(HLE, "DMAC::ProcessCmd(): Unknown DMA cmd."); - return true; - } - } - - u32 Cmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) - { - if(!Memory.IsGoodAddr(ls_offset + lsa, size) || !Memory.IsGoodAddr(ea, size)) - { - return MFC_PPU_DMA_CMD_SEQUENCE_ERROR; - } - - if(proxy_pos >= MFC_PPU_MAX_QUEUE_SPACE) - { - return MFC_PPU_DMA_QUEUE_FULL; - } - - ProcessCmd(cmd, tag, lsa, ea, size); - - return MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL; - } - - void ClearCmd() - { - while (std::atomic_exchange(&proxy_lock, 1)); - _mm_lfence(); - memcpy(proxy, proxy + 1, --proxy_pos * sizeof(DMAC_Proxy)); - _mm_sfence(); - proxy_lock = 0; //release lock - } - - void DoCmd() - { - if(proxy_pos) - { - const DMAC_Proxy& p = proxy[0]; - if (ProcessCmd(p.cmd, p.tag, p.lsa, p.ea, p.size)) - { - ClearCmd(); - } - } - }*/ }; - -/*struct MFC -{ - SPUReg<1> MFC_LSA; - SPUReg<1> MFC_EAH; - SPUReg<1> MFC_EAL; - SPUReg<1> MFC_Size_Tag; - SPUReg<1> MFC_CMDStatus; - SPUReg<1> MFC_QStatus; - SPUReg<1> Prxy_QueryType; - SPUReg<1> Prxy_QueryMask; - SPUReg<1> Prxy_TagStatus; - SPUReg<1> SPU_Out_MBox; - SPUReg<4> SPU_In_MBox; - SPUReg<1> SPU_MBox_Status; - SPUReg<1> SPU_RunCntl; - SPUReg<1> SPU_Status; - SPUReg<1> SPU_NPC; - SPUReg<1> SPU_RdSigNotify1; - SPUReg<1> SPU_RdSigNotify2; - - DMAC dmac; - - void Handle() - { - u32 cmd = MFC_CMDStatus.GetValue(); - - if(cmd) - { - u16 op = cmd & MFC_MASK_CMD; - - switch(op) - { - case MFC_PUT_CMD: - case MFC_GET_CMD: - { - u32 lsa = MFC_LSA.GetValue(); - u64 ea = (u64)MFC_EAL.GetValue() | ((u64)MFC_EAH.GetValue() << 32); - u32 size_tag = MFC_Size_Tag.GetValue(); - u16 tag = (u16)size_tag; - u16 size = size_tag >> 16; - - LOG_WARNING(HLE, "RawSPU DMA %s:", op == MFC_PUT_CMD ? "PUT" : "GET"); - LOG_WARNING(HLE, "*** lsa = 0x%x", lsa); - LOG_WARNING(HLE, "*** ea = 0x%llx", ea); - LOG_WARNING(HLE, "*** tag = 0x%x", tag); - LOG_WARNING(HLE, "*** size = 0x%x", size); - LOG_WARNING(HLE, " "); - - MFC_CMDStatus.SetValue(dmac.Cmd(cmd, tag, lsa, ea, size)); - } - break; - - default: - LOG_ERROR(HLE, "Unknown MFC cmd. (opcode=0x%x, cmd=0x%x)", op, cmd); - break; - } - } - - if(Prxy_QueryType.GetValue() == 2) - { - Prxy_QueryType.SetValue(0); - u32 mask = Prxy_QueryMask.GetValue(); - // - MFC_QStatus.SetValue(mask); - } - } -};*/ diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index abc187e9c2..0598a55018 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -579,7 +579,7 @@ public: #define LOG_DMAC(type, text) type(Log::SPU, "DMAC::ProcessCmd(cmd=0x%x, tag=0x%x, lsa=0x%x, ea=0x%llx, size=0x%x): " text, cmd, tag, lsa, ea, size) - bool ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) + void ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); @@ -588,7 +588,8 @@ public: if (ea >= 0x100000000) { LOG_DMAC(LOG_ERROR, "Invalid external address"); - return false; + Emu.Pause(); + return; } else if (group) { @@ -597,7 +598,8 @@ public: if (num >= group->list.size() || !group->list[num]) { LOG_DMAC(LOG_ERROR, "Invalid thread (SPU Thread Group MMIO)"); - return false; + Emu.Pause(); + return; } SPUThread* spu = (SPUThread*)Emu.GetCPU().GetThread(group->list[num]); @@ -611,18 +613,20 @@ public: 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, Memory.Read32(dmac.ls_offset + lsa)); - return true; + return; } else { LOG_DMAC(LOG_ERROR, "Invalid register (SPU Thread Group MMIO)"); - return false; + Emu.Pause(); + return; } } else { LOG_DMAC(LOG_ERROR, "Thread group not set (SPU Thread Group MMIO)"); - return false; + Emu.Pause(); + return; } } else if (ea >= RAW_SPU_BASE_ADDR && size == 4) @@ -632,19 +636,20 @@ public: case MFC_PUT_CMD: { Memory.Write32(ea, ReadLS32(lsa)); - return true; + return; } case MFC_GET_CMD: { WriteLS32(lsa, Memory.Read32(ea)); - return true; + return; } default: { LOG_DMAC(LOG_ERROR, "Unknown DMA command"); - return false; + Emu.Pause(); + return; } } } @@ -653,53 +658,27 @@ public: { case MFC_PUT_CMD: { - if (Memory.Copy(ea, dmac.ls_offset + lsa, size)) - { - return true; - } - else - { - LOG_DMAC(LOG_ERROR, "PUT* cmd failed"); - return false; // TODO: page fault (?) - } + memcpy(Memory + ea, Memory + dmac.ls_offset + lsa, size); + return; } case MFC_GET_CMD: { - if (Memory.Copy(dmac.ls_offset + lsa, ea, size)) - { - return true; - } - else - { - LOG_DMAC(LOG_ERROR, "GET* cmd failed"); - return false; // TODO: page fault (?) - } + memcpy(Memory + dmac.ls_offset + lsa, Memory + ea, size); + return; } default: { LOG_DMAC(LOG_ERROR, "Unknown DMA command"); - return false; // ??? + Emu.Pause(); + return; } } } #undef LOG_CMD - u32 dmacCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) - { - /*if(proxy_pos >= MFC_PPU_MAX_QUEUE_SPACE) - { - return MFC_PPU_DMA_QUEUE_FULL; - }*/ - - if (ProcessCmd(cmd, tag, lsa, ea, size)) - return MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL; - else - return MFC_PPU_DMA_CMD_SEQUENCE_ERROR; - } - void ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFCArgs) { u32 list_addr = ea & 0x3ffff; @@ -713,7 +692,7 @@ public: be_t ea; // External Address Low }; - u32 result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; + u32 result = MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL; for (u32 i = 0; i < list_size; i++) { @@ -723,15 +702,12 @@ public: if (size < 16 && size != 1 && size != 2 && size != 4 && size != 8) { LOG_ERROR(Log::SPU, "DMA List: invalid transfer size(%d)", size); - return; + result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; + break; } u32 addr = rec->ea; - result = dmacCmd(cmd, tag, lsa | (addr & 0xf), addr, size); - if (result == MFC_PPU_DMA_CMD_SEQUENCE_ERROR) - { - break; - } + ProcessCmd(cmd, tag, lsa | (addr & 0xf), addr, size); if (Ini.HLELogging.GetValue() || rec->s) LOG_NOTICE(Log::SPU, "*** list element(%d/%d): s = 0x%x, ts = 0x%x, low ea = 0x%x (lsa = 0x%x)", @@ -746,6 +722,8 @@ public: if (StallList[tag].MFCArgs) { LOG_ERROR(Log::SPU, "DMA List: existing stalled list found (tag=%d)", tag); + result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; + break; } StallList[tag].MFCArgs = &MFCArgs; StallList[tag].cmd = cmd; @@ -753,7 +731,7 @@ public: StallList[tag].lsa = lsa; StallList[tag].size = (list_size - i - 1) * 8; - return; + break; } } @@ -784,7 +762,8 @@ public: (op & MFC_FENCE_MASK ? "F" : ""), lsa, ea, tag, size, cmd); - MFCArgs.CMDStatus.SetValue(dmacCmd(cmd, tag, lsa, ea, size)); + ProcessCmd(cmd, tag, lsa, ea, size); + MFCArgs.CMDStatus.SetValue(MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL); } break; @@ -871,21 +850,6 @@ public: { 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]) - { - last_d++; - } - else if (buf[last]._u32[last_d+1] == reservation.data[last]._u32[last_d+1]) - { - last_d; - } - else // full 64 bit - { - LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 64bit compare and swap"); - Emu.Pause(); - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - }*/ } } else