From 19db12e090021bc75d44a3453e399b3dba973c71 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 7 Jul 2014 03:36:07 +0400 Subject: [PATCH 01/15] Memory allocation changes --- Utilities/BEType.h | 1 + rpcs3/Emu/GS/RSXThread.cpp | 12 ++++--- rpcs3/Emu/Memory/Memory.cpp | 30 +++++++++++----- rpcs3/Emu/Memory/Memory.h | 66 ++++++++++++++++++++++++++++------ rpcs3/Emu/Memory/MemoryBlock.h | 20 ++++++++--- 5 files changed, 102 insertions(+), 27 deletions(-) diff --git a/Utilities/BEType.h b/Utilities/BEType.h index cecb4cd3a6..65fe524f89 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -11,6 +11,7 @@ using std::max; #define re64(val) MemoryBase::Reverse64(val) #define re32(val) MemoryBase::Reverse32(val) #define re16(val) MemoryBase::Reverse16(val) +#define re128(val) MemoryBase::Reverse128(val) template struct se_t; template struct se_t { static __forceinline void func(T& dst, const T src) { (u8&)dst = (u8&)src; } }; diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index a20fa52c21..403ae4b0f4 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -5,7 +5,8 @@ #include "RSXThread.h" #include "Emu/SysCalls/lv2/sys_time.h" -#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.GetStartAddr() + m_ctrl->get + (4*(x+1)))) +//#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.GetStartAddr() + m_ctrl->get + (4*(x+1)))) +#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + m_ctrl->get + (4*(x+1))))) u32 methodRegisters[0xffff]; @@ -2474,7 +2475,9 @@ void RSXThread::Task() } //ConLog.Write("addr = 0x%x", m_ioAddress + get); - const u32 cmd = Memory.Read32(Memory.RSXIOMem.GetStartAddr() + get); + u64 realAddr; + Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + get, realAddr); + const u32 cmd = Memory.Read32(realAddr); const u32 count = (cmd >> 18) & 0x7ff; //if(cmd == 0) continue; @@ -2489,7 +2492,6 @@ void RSXThread::Task() { m_call_stack.push(get + 4); u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; - u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); m_ctrl->get = offs; continue; @@ -2499,6 +2501,7 @@ void RSXThread::Task() //LOG_WARNING(RSX, "rsx return!"); u32 get = m_call_stack.top(); m_call_stack.pop(); + u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; //LOG_WARNING(RSX, "rsx return(0x%x)", get); m_ctrl->get = get; continue; @@ -2523,7 +2526,8 @@ void RSXThread::Task() methodRegisters[(cmd & 0xffff) + (i*4*inc)] = ARGS(i); } - mem32_ptr_t args(Memory.RSXIOMem.GetStartAddr() + get + 4); + Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + get + 4, realAddr); + mem32_ptr_t args((u32)realAddr); DoCmd(cmd, cmd & 0x3ffff, args, count); m_ctrl->get = get + (count + 1) * 4; diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 9f70616622..293a4f6234 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -31,14 +31,17 @@ void MemoryBlock::InitMemory() { if(!range_size) return; - if(mem) safe_free(mem); - mem = (u8*)malloc(range_size); + //if(mem) safe_free(mem); + if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); + //mem = (u8*)malloc(range_size); + mem = (u8*)VirtualAlloc((void*)((u64)Memory.GetBaseAddr() + range_start), range_size, MEM_COMMIT, PAGE_READWRITE); memset(mem, 0, range_size); } void MemoryBlock::Delete() { - if(mem) safe_free(mem); + //if(mem) safe_free(mem); + if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); Init(); } @@ -412,27 +415,38 @@ bool NullMemoryBlock::Write128(const u64 addr, const u128 value) //MemoryBase void MemoryBase::Write8(u64 addr, const u8 data) { - GetMemByAddr(addr).Write8(addr, data); + //GetMemByAddr(addr).Write8(addr, data); + *(u8*)((u64)GetBaseAddr() + addr) = data; } void MemoryBase::Write16(u64 addr, const u16 data) { - GetMemByAddr(addr).Write16(addr, data); + //GetMemByAddr(addr).Write16(addr, data); + *(u16*)((u64)GetBaseAddr() + addr) = re16(data); } void MemoryBase::Write32(u64 addr, const u32 data) { - GetMemByAddr(addr).Write32(addr, data); + if (addr < 0xE0000000 || (addr % 0x100000) < 0x40000) + { + *(u32*)((u64)GetBaseAddr() + addr) = re32(data); + } + else + { + GetMemByAddr(addr).Write32(addr, data); + } } void MemoryBase::Write64(u64 addr, const u64 data) { - GetMemByAddr(addr).Write64(addr, data); + //GetMemByAddr(addr).Write64(addr, data); + *(u64*)((u64)GetBaseAddr() + addr) = re64(data); } void MemoryBase::Write128(u64 addr, const u128 data) { - GetMemByAddr(addr).Write128(addr, data); + //GetMemByAddr(addr).Write128(addr, data); + *(u128*)((u64)GetBaseAddr() + addr) = re128(data); } bool MemoryBase::Write8NN(u64 addr, const u8 data) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 3a51f61b15..13808fdffb 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -15,6 +15,7 @@ enum MemoryType class MemoryBase { NullMemoryBlock NullMem; + void* m_base_addr; public: std::vector MemoryBlocks; @@ -57,6 +58,11 @@ public: Close(); } + void* GetBaseAddr() const + { + return m_base_addr; + } + static __forceinline u16 Reverse16(const u16 val) { return _byteswap_ushort(val); @@ -91,6 +97,14 @@ public: */ } + static __forceinline u128 Reverse128(const u128 val) + { + u128 ret; + ret.lo = re64(val.hi); + ret.hi = re64(val.lo); + return ret; + } + template static __forceinline u64 ReverseData(u64 val); template static __forceinline T Reverse(T val) @@ -117,28 +131,40 @@ public: bool Read8ByAddr(const u64 addr, u8 *value) { - for (auto block : MemoryBlocks) + *value = *(u8*)((u64)GetBaseAddr() + addr); + return true; + + /*for (auto block : MemoryBlocks) { if (block->Read8(addr, value)) return true; } - return NullMem.Read8(addr, value); + return NullMem.Read8(addr, value);*/ } bool Read16ByAddr(const u64 addr, u16 *value) { - for (auto block : MemoryBlocks) + *value = re16(*(u16*)((u64)GetBaseAddr() + addr)); + return true; + + /*for (auto block : MemoryBlocks) { if (block->Read16(addr, value)) return true; } - return NullMem.Read16(addr, value); + return NullMem.Read16(addr, value);*/ } bool Read32ByAddr(const u64 addr, u32 *value) { + if (addr < 0xE0000000 || (addr % 0x100000) < 0x40000) + { + *value = re32(*(u32*)((u64)GetBaseAddr() + addr)); + return true; + } + for (auto block : MemoryBlocks) { if (block->Read32(addr, value)) @@ -150,29 +176,36 @@ public: bool Read64ByAddr(const u64 addr, u64 *value) { - for (auto block : MemoryBlocks) + *value = re64(*(u64*)((u64)GetBaseAddr() + addr)); + return true; + + /*for (auto block : MemoryBlocks) { if (block->Read64(addr, value)) return true; } - return NullMem.Read64(addr, value); + return NullMem.Read64(addr, value);*/ } bool Read128ByAddr(const u64 addr, u128 *value) { - for (auto block : MemoryBlocks) + *value = re128(*(u128*)((u64)GetBaseAddr() + addr)); + return true; + + /*for (auto block : MemoryBlocks) { if (block->Read128(addr, value)) return true; } - return NullMem.Read128(addr, value); + return NullMem.Read128(addr, value);*/ } u8* GetMemFromAddr(const u64 addr) { - return GetMemByAddr(addr).GetMemFromAddr(addr); + //return GetMemByAddr(addr).GetMemFromAddr(addr); + return (u8*)GetBaseAddr() + addr; } void* VirtualToRealAddr(const u64 vaddr) @@ -211,7 +244,15 @@ public: if(m_inited) return; m_inited = true; - LOG_NOTICE(MEMORY, "Initing memory..."); + m_base_addr = VirtualAlloc(0, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); + if (!m_base_addr) + { + LOG_ERROR(MEMORY, "Initing memory: VirtualAlloc() failed"); + } + else + { + LOG_NOTICE(MEMORY, "Initing memory: m_base_addr = 0x%llx", (u64)m_base_addr); + } switch(type) { @@ -279,6 +320,11 @@ public: } MemoryBlocks.clear(); + + if (!VirtualFree(m_base_addr, 0, MEM_RELEASE)) + { + LOG_ERROR(MEMORY, "VirtualFree(0x%llx) failed", (u64)m_base_addr); + } } void Write8(const u64 addr, const u8 data); diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index e9a6e7c1d1..2e8173b3b0 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -22,13 +22,14 @@ struct MemBlockInfo : public MemInfo { void *mem; - MemBlockInfo(u64 _addr, u32 _size) + MemBlockInfo(u64 _addr, u32 _size, void* base_addr) : MemInfo(_addr, PAGE_4K(_size)) - , mem(_aligned_malloc(PAGE_4K(_size), 128)) + //, mem(_aligned_malloc(PAGE_4K(_size), 128)) + , mem(VirtualAlloc((void*)((u64)base_addr + _addr), PAGE_4K(_size), MEM_COMMIT, PAGE_READWRITE)) { if(!mem) { - LOG_ERROR(MEMORY, "Not enough free memory."); + LOG_ERROR(MEMORY, "Out of memory or VirtualAlloc() failed (_addr=0x%llx, _size=0x%llx)", _addr, _size); assert(0); } memset(mem, 0, size); @@ -43,7 +44,8 @@ struct MemBlockInfo : public MemInfo MemBlockInfo& operator =(MemBlockInfo &&other){ this->addr = other.addr; this->size = other.size; - if (this->mem) _aligned_free(mem); + //if (this->mem) _aligned_free(mem); + if (this->mem) VirtualFree(this->mem, this->size, MEM_DECOMMIT); this->mem = other.mem; other.mem = nullptr; return *this; @@ -51,7 +53,8 @@ struct MemBlockInfo : public MemInfo ~MemBlockInfo() { - if(mem) _aligned_free(mem); + //if(mem) _aligned_free(mem); + if (mem) VirtualFree(mem, size, MEM_DECOMMIT); mem = nullptr; } }; @@ -285,6 +288,13 @@ public: // return true for success bool getRealAddr(u64 addr, u64& result); + u64 RealAddr(u64 addr) + { + u64 realAddr = 0; + getRealAddr(addr, realAddr); + return realAddr; + } + // return the mapped address given a real address, if not mapped return 0 u64 getMappedAddress(u64 realAddress); }; From d1fff053c265a328726fb866fce0218bc231eaaa Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 7 Jul 2014 21:22:36 +0400 Subject: [PATCH 02/15] Some cleanup --- Utilities/Thread.cpp | 17 +- rpcs3/Emu/CPU/CPUThread.cpp | 102 +++--- rpcs3/Emu/Cell/PPCDecoder.cpp | 5 +- rpcs3/Emu/Cell/RawSPUThread.cpp | 224 ++----------- rpcs3/Emu/Cell/RawSPUThread.h | 8 - rpcs3/Emu/Cell/SPUThread.cpp | 3 +- rpcs3/Emu/Cell/SPUThread.h | 9 - rpcs3/Emu/GS/RSXThread.cpp | 2 +- rpcs3/Emu/Memory/DynamicMemoryBlockBase.h | 108 ++----- rpcs3/Emu/Memory/Memory.cpp | 146 +-------- rpcs3/Emu/Memory/Memory.h | 348 ++++++--------------- rpcs3/Emu/Memory/MemoryBlock.h | 4 - rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 5 +- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 5 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 57 +--- rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp | 47 +-- rpcs3/Emu/SysCalls/lv2/sys_process.cpp | 14 +- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 9 - rpcs3/emucore.vcxproj | 4 + rpcs3/emucore.vcxproj.filters | 3 + rpcs3/rpcs3.vcxproj | 4 +- 23 files changed, 278 insertions(+), 850 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index c11a48183f..38912a139a 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -52,7 +52,22 @@ void ThreadBase::Start() g_tls_this_thread = this; g_thread_count++; - Task(); + try + { + Task(); + } + catch (const std::string& e) + { + LOG_ERROR(GENERAL, "Exception: %s", e.c_str()); + } + catch (const char* e) + { + LOG_ERROR(GENERAL, "Exception: %s", e); + } + catch (int exitcode) + { + LOG_SUCCESS(GENERAL, "Exit Code: %d", exitcode); + } m_alive = false; g_thread_count--; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index b36970e4cf..cc21ba3c11 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -280,68 +280,72 @@ void CPUThread::ExecOnce() SendDbgCommand(DID_PAUSED_THREAD, this); } +void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) +{ + const u64 addr = (u64)Memory.GetBaseAddr() - (u64)pExp->ExceptionRecord->ExceptionAddress; + if (addr < 0x100000000 && u == EXCEPTION_ACCESS_VIOLATION) + { + // TODO: allow recovering from a page fault + //GetCurrentPPUThread().Stop(); + Emu.Pause(); + throw fmt::Format("Access violation: addr = 0x%x", (u32)addr); + } + else + { + // some fatal error (should crash) + return; + } +} + void CPUThread::Task() { if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s enter", CPUThread::GetFName().c_str()); const std::vector& bp = Emu.GetBreakPoints(); - try + for (uint i = 0; iDecodeMemory(PC + m_offset)); + + if (status == CPUThread_Step) + { + m_is_step = false; + break; + } + + for (uint i = 0; i < bp.size(); ++i) + { + if (bp[i] == PC) { Emu.Pause(); break; } } - - while(true) - { - int status = ThreadStatus(); - - if(status == CPUThread_Stopped || status == CPUThread_Break) - { - break; - } - - if(status == CPUThread_Sleeping) - { - Sleep(1); - continue; - } - - Step(); - NextPc(m_dec->DecodeMemory(PC + m_offset)); - - if(status == CPUThread_Step) - { - m_is_step = false; - break; - } - - for(uint i=0; iGetStartAddr() == GetStartAddr()) - { - Memory.MemoryBlocks.erase(Memory.MemoryBlocks.begin() + i); - break; - } - } - - //Close(); -} - -bool RawSPUThread::Read8(const u64 addr, u8* value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Read8(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read8(0x%x)", m_index, offset); - Emu.Pause(); - return false; -} - -bool RawSPUThread::Read16(const u64 addr, u16* value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Read16(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read16(0x%x)", m_index, offset); - Emu.Pause(); - return false; + Memory.CloseRawSPU(this, m_index); } bool RawSPUThread::Read32(const u64 addr, u32* value) @@ -88,7 +53,7 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) SPU.MBox_Status.SetValue((SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8)); *value = SPU.MBox_Status.GetValue(); break; - case SPU_RunCntl_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = SPU.RunCntl.GetValue(); break; + case SPU_RunCntl_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = (u32)IsRunning(); break; case SPU_Status_offs: //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_Status)", m_index); *value = SPU.Status.GetValue(); @@ -106,58 +71,6 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) return true; } -bool RawSPUThread::Read64(const u64 addr, u64* value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Read64(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read64(0x%x)", m_index, offset); - Emu.Pause(); - return false; -} - -bool RawSPUThread::Read128(const u64 addr, u128* value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Read128(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read128(0x%x)", m_index, offset); - Emu.Pause(); - return false; -} - -bool RawSPUThread::Write8(const u64 addr, const u8 value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Write8(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write8(0x%x, 0x%x)", m_index, offset, value); - Emu.Pause(); - return false; -} - -bool RawSPUThread::Write16(const u64 addr, const u16 value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Write16(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write16(0x%x, 0x%x)", m_index, offset, value); - Emu.Pause(); - return false; -} - bool RawSPUThread::Write32(const u64 addr, const u32 value) { if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) @@ -206,7 +119,25 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten 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: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RunCntl, 0x%x)", m_index, value); SPU.RunCntl.SetValue(value); break; + case SPU_RunCntl_offs: + { + if (value == SPU_RUNCNTL_RUNNABLE) + { + SPU.Status.SetValue(SPU_STATUS_RUNNING); + Exec(); + } + else if (value == SPU_RUNCNTL_STOP) + { + SPU.Status.SetValue(SPU_STATUS_STOPPED); + Stop(); + } + else + { + LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RunCtrl, 0x%x): unknown value", m_index, value); + Emu.Pause(); + } + 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); break; @@ -221,32 +152,6 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) return true; } -bool RawSPUThread::Write64(const u64 addr, const u64 value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Write64(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write64(0x%x, 0x%llx)", m_index, offset, value); - Emu.Pause(); - return false; -} - -bool RawSPUThread::Write128(const u64 addr, const u128 value) -{ - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Write128(addr, value); - } - - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write128(0x%x, 0x%llx_%llx)", m_index, offset, value._u64[1], value._u64[0]); - Emu.Pause(); - return false; -} - void RawSPUThread::InitRegs() { dmac.ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET; @@ -260,88 +165,9 @@ u32 RawSPUThread::GetIndex() const void RawSPUThread::Task() { - if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "%s enter", PPCThread::GetFName().c_str()); + PC = SPU.NPC.GetValue(); - const std::vector& bp = Emu.GetBreakPoints(); + CPUThread::Task(); - try - { - for(uint i=0; iDecodeMemory(PC + m_offset)); - - if(status == CPUThread_Step) - { - m_is_step = false; - continue; - } - - for(uint i=0; i Out_IntrMBox; Channel<4> In_MBox; Channel<1> MBox_Status; - Channel<1> RunCntl; Channel<1> Status; Channel<1> NPC; Channel<1> SNR[2]; diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 403ae4b0f4..023f641b5e 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -2492,6 +2492,7 @@ void RSXThread::Task() { m_call_stack.push(get + 4); u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; + u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); m_ctrl->get = offs; continue; @@ -2501,7 +2502,6 @@ void RSXThread::Task() //LOG_WARNING(RSX, "rsx return!"); u32 get = m_call_stack.top(); m_call_stack.pop(); - u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; //LOG_WARNING(RSX, "rsx return(0x%x)", get); m_ctrl->get = get; continue; diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h index 77ff450c96..0d86262059 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h @@ -41,7 +41,7 @@ bool DynamicMemoryBlockBase::IsMyAddress(const u64 addr) const u32 index = MemoryBlock::FixAddr(addr) >> 12; - return m_pages[index] && !m_locked[index]; + return m_pages[index] != nullptr; } template @@ -54,9 +54,7 @@ MemoryBlock* DynamicMemoryBlockBase::SetRange(const u64 start, const u32 siz const u32 page_count = m_max_size >> 12; m_pages.resize(page_count); - m_locked.resize(page_count); memset(m_pages.data(), 0, sizeof(u8*) * page_count); - memset(m_locked.data(), 0, sizeof(u8*) * page_count); return this; } @@ -70,7 +68,6 @@ void DynamicMemoryBlockBase::Delete() m_max_size = 0; m_pages.clear(); - m_locked.clear(); MemoryBlock::Delete(); } @@ -108,8 +105,7 @@ bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size) template void DynamicMemoryBlockBase::AppendMem(u64 addr, u32 size) /* private */ { - //u8* pointer = (u8*)m_allocated[m_allocated.Move(new MemBlockInfo(addr, size))].mem; - m_allocated.emplace_back(addr, size); + m_allocated.emplace_back(addr, size, Memory.GetBaseAddr()); u8* pointer = (u8*) m_allocated.back().mem; const u32 first = MemoryBlock::FixAddr(addr) >> 12; @@ -119,7 +115,6 @@ void DynamicMemoryBlockBase::AppendMem(u64 addr, u32 size) /* private */ for (u32 i = first; i <= last; i++) { m_pages[i] = pointer; - m_locked[i] = nullptr; pointer += 4096; } } @@ -195,16 +190,15 @@ bool DynamicMemoryBlockBase::Free(u64 addr) const u32 last = first + ((m_allocated[num].size - 1) >> 12); // check if locked: - for (u32 i = first; i <= last; i++) - { - if (!m_pages[i] || m_locked[i]) return false; - } + //for (u32 i = first; i <= last; i++) + //{ + // if (!m_pages[i]) return false; + //} // clear pointers: for (u32 i = first; i <= last; i++) { m_pages[i] = nullptr; - m_locked[i] = nullptr; } m_allocated.erase(m_allocated.begin() + num); @@ -217,6 +211,7 @@ bool DynamicMemoryBlockBase::Free(u64 addr) { LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size); } + assert(0); return false; } @@ -233,97 +228,34 @@ u8* DynamicMemoryBlockBase::GetMem(u64 addr) const // lock-free, addr is fix } } - LOG_ERROR(MEMORY, "GetMem(%llx) from not allocated address.", addr); + LOG_ERROR(MEMORY, "GetMem(0x%llx) from not allocated address.", addr); assert(0); return nullptr; } template -bool DynamicMemoryBlockBase::IsLocked(u64 addr) // lock-free +bool DynamicMemoryBlockBase::IsLocked(u64 addr) { - if (IsInMyRange(addr)) - { - const u32 index = MemoryBlock::FixAddr(addr) >> 12; - - if (index < m_locked.size()) - { - if (m_locked[index]) return true; - } - } - + // TODO + LOG_ERROR(MEMORY, "IsLocked(0x%llx) not implemented", addr); + assert(0); return false; } template bool DynamicMemoryBlockBase::Lock(u64 addr, u32 size) { - size = PAGE_4K(size); // align size - - addr &= ~4095; // align start address - - if (!IsInMyRange(addr, size)) - { - assert(0); - return false; - } - - if (IsMyAddress(addr) || IsMyAddress(addr + size - 1)) - { - return false; - } - - const u32 first = MemoryBlock::FixAddr(addr) >> 12; - - const u32 last = first + ((size - 1) >> 12); - - for (u32 i = first; i <= last; i++) - { - if (u8* pointer = m_pages[i]) - { - m_locked[i] = pointer; - m_pages[i] = nullptr; - } - else // already locked or empty - { - } - } - - return true; + // TODO + LOG_ERROR(MEMORY, "Lock(0x%llx, 0x%x) not implemented", addr, size); + assert(0); + return false; } template bool DynamicMemoryBlockBase::Unlock(u64 addr, u32 size) { - size = PAGE_4K(size); // align size - - addr &= ~4095; // align start address - - if (!IsInMyRange(addr, size)) - { - assert(0); - return false; - } - - if (IsMyAddress(addr) || IsMyAddress(addr + size - 1)) - { - return false; - } - - const u32 first = MemoryBlock::FixAddr(addr) >> 12; - - const u32 last = first + ((size - 1) >> 12); - - for (u32 i = first; i <= last; i++) - { - if (u8* pointer = m_locked[i]) - { - m_pages[i] = pointer; - m_locked[i] = nullptr; - } - else // already unlocked or empty - { - } - } - - return true; + // TODO + LOG_ERROR(MEMORY, "Unlock(0x%llx, 0x%x) not implemented", addr, size); + assert(0); + return false; } diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 293a4f6234..5395bd1089 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -31,16 +31,13 @@ void MemoryBlock::InitMemory() { if(!range_size) return; - //if(mem) safe_free(mem); if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); - //mem = (u8*)malloc(range_size); mem = (u8*)VirtualAlloc((void*)((u64)Memory.GetBaseAddr() + range_start), range_size, MEM_COMMIT, PAGE_READWRITE); memset(mem, 0, range_size); } void MemoryBlock::Delete() { - //if(mem) safe_free(mem); if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); Init(); } @@ -54,7 +51,6 @@ bool MemoryBlock::GetMemFromAddr(void* dst, const u64 addr, const u32 size) { if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; - // mem cpy(dst, GetMem(FixAddr(addr)), size); return Memory.CopyToReal(dst, (u32)addr, size); } @@ -62,7 +58,6 @@ bool MemoryBlock::SetMemFromAddr(void* src, const u64 addr, const u32 size) { if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; - // mem cpy(GetMem(FixAddr(addr)), src, size); return Memory.CopyFromReal((u32)addr, src, size); } @@ -121,7 +116,6 @@ bool MemoryBlock::Read8(const u64 addr, u8* value) return false; } - //*value = std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr))); *value = FastRead(FixAddr(addr)); return true; } @@ -134,7 +128,6 @@ bool MemoryBlock::Read16(const u64 addr, u16* value) return false; } - //se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); *value = FastRead(FixAddr(addr)); return true; } @@ -147,7 +140,6 @@ bool MemoryBlock::Read32(const u64 addr, u32* value) return false; } - //se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); *value = FastRead(FixAddr(addr)); return true; } @@ -160,7 +152,6 @@ bool MemoryBlock::Read64(const u64 addr, u64* value) return false; } - //se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); *value = FastRead(FixAddr(addr)); return true; } @@ -173,9 +164,6 @@ bool MemoryBlock::Read128(const u64 addr, u128* value) return false; } - //u64 f_addr = FixAddr(addr); - //se_t::func(value->lo, std::atomic_load((volatile std::atomic*)GetMem(f_addr))); - //se_t::func(value->hi, std::atomic_load((volatile std::atomic*)GetMem(f_addr + 8))); *value = FastRead(FixAddr(addr)); return true; } @@ -199,7 +187,6 @@ bool MemoryBlock::Write8(const u64 addr, const u8 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), value); FastWrite(FixAddr(addr), value); return true; } @@ -208,9 +195,6 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - //u16 re_value; - //se_t::func(re_value, value); - //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); FastWrite(FixAddr(addr), value); return true; } @@ -219,9 +203,6 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - //u32 re_value; - //se_t::func(re_value, value); - //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); FastWrite(FixAddr(addr), value); return true; } @@ -230,9 +211,6 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - //u64 re_value; - //se_t::func(re_value, value); - //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); FastWrite(FixAddr(addr), value); return true; } @@ -241,12 +219,6 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - //u64 f_addr = FixAddr(addr); - //u64 re_value; - //se_t::func(re_value, value.lo); - //std::atomic_store((std::atomic*)GetMem(f_addr), re_value); - //se_t::func(re_value, value.hi); - //std::atomic_store((std::atomic*)GetMem(f_addr + 8), re_value); FastWrite(FixAddr(addr), value); return true; } @@ -331,121 +303,36 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value) return true; } -//NullMemoryBlock -bool NullMemoryBlock::Read8(const u64 addr, u8* ) -{ - LOG_ERROR(MEMORY, "Read8 from null block: [%08llx]", addr); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Read16(const u64 addr, u16* ) -{ - LOG_ERROR(MEMORY, "Read16 from null block: [%08llx]", addr); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Read32(const u64 addr, u32* ) -{ - LOG_ERROR(MEMORY, "Read32 from null block: [%08llx]", addr); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Read64(const u64 addr, u64* ) -{ - LOG_ERROR(MEMORY, "Read64 from null block: [%08llx]", addr); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Read128(const u64 addr, u128* ) -{ - LOG_ERROR(MEMORY, "Read128 from null block: [%08llx]", addr); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Write8(const u64 addr, const u8 value) -{ - LOG_ERROR(MEMORY, "Write8 to null block: [%08llx]: %x", addr, value); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Write16(const u64 addr, const u16 value) -{ - LOG_ERROR(MEMORY, "Write16 to null block: [%08llx]: %x", addr, value); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Write32(const u64 addr, const u32 value) -{ - LOG_ERROR(MEMORY, "Write32 to null block: [%08llx]: %x", addr, value); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Write64(const u64 addr, const u64 value) -{ - LOG_ERROR(MEMORY, "Write64 to null block: [%08llx]: %llx", addr, value); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - -bool NullMemoryBlock::Write128(const u64 addr, const u128 value) -{ - LOG_ERROR(MEMORY, "Write128 to null block: [%08llx]: %llx_%llx", addr, value.hi, value.lo); - if (!Ini.CPUIgnoreRWErrors.GetValue()) - Emu.Pause(); - return false; -} - //MemoryBase void MemoryBase::Write8(u64 addr, const u8 data) { - //GetMemByAddr(addr).Write8(addr, data); *(u8*)((u64)GetBaseAddr() + addr) = data; } void MemoryBase::Write16(u64 addr, const u16 data) { - //GetMemByAddr(addr).Write16(addr, data); *(u16*)((u64)GetBaseAddr() + addr) = re16(data); } void MemoryBase::Write32(u64 addr, const u32 data) { - if (addr < 0xE0000000 || (addr % 0x100000) < 0x40000) + if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) { *(u32*)((u64)GetBaseAddr() + addr) = re32(data); } else { - GetMemByAddr(addr).Write32(addr, data); + RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data); } } void MemoryBase::Write64(u64 addr, const u64 data) { - //GetMemByAddr(addr).Write64(addr, data); *(u64*)((u64)GetBaseAddr() + addr) = re64(data); } void MemoryBase::Write128(u64 addr, const u128 data) { - //GetMemByAddr(addr).Write128(addr, data); *(u128*)((u64)GetBaseAddr() + addr) = re128(data); } @@ -486,37 +373,36 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data) u8 MemoryBase::Read8(u64 addr) { - u8 res; - Read8ByAddr(addr, &res); - return res; + return *(u8*)((u64)GetBaseAddr() + addr); } u16 MemoryBase::Read16(u64 addr) { - u16 res; - Read16ByAddr(addr, &res); - return res; + return re16(*(u16*)((u64)GetBaseAddr() + addr)); } u32 MemoryBase::Read32(u64 addr) { - u32 res; - Read32ByAddr(addr, &res); - return res; + if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + { + return re32(*(u32*)((u64)GetBaseAddr() + addr)); + } + else + { + u32 res; + RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res); + return res; + } } u64 MemoryBase::Read64(u64 addr) { - u64 res; - Read64ByAddr(addr, &res); - return res; + return re64(*(u64*)((u64)GetBaseAddr() + addr)); } u128 MemoryBase::Read128(u64 addr) { - u128 res; - Read128ByAddr(addr, &res); - return res; + return re128(*(u128*)((u64)GetBaseAddr() + addr)); } template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 13808fdffb..fb4db9349d 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -12,13 +12,21 @@ enum MemoryType Memory_PSP, }; +enum : u64 +{ + RAW_SPU_OFFSET = 0x0000000000100000, + RAW_SPU_BASE_ADDR = 0x00000000E0000000, + RAW_SPU_LS_OFFSET = 0x0000000000000000, + RAW_SPU_PROB_OFFSET = 0x0000000000040000, +}; + class MemoryBase { - NullMemoryBlock NullMem; void* m_base_addr; + std::vector MemoryBlocks; + std::mutex m_mutex; public: - std::vector MemoryBlocks; MemoryBlock* UserMemory; DynamicMemoryBlock MainMem; @@ -27,8 +35,7 @@ public: DynamicMemoryBlock MmaperMem; DynamicMemoryBlock RSXFBMem; DynamicMemoryBlock StackMem; - MemoryBlock SpuRawMem; - MemoryBlock SpuThrMem; + MemoryBlock* RawSPUMem[32]; VirtualMemoryBlock RSXIOMem; struct @@ -66,42 +73,23 @@ public: static __forceinline u16 Reverse16(const u16 val) { return _byteswap_ushort(val); - //return ((val >> 8) & 0xff) | ((val << 8) & 0xff00); } static __forceinline u32 Reverse32(const u32 val) { return _byteswap_ulong(val); - /* - return - ((val >> 24) & 0x000000ff) | - ((val >> 8) & 0x0000ff00) | - ((val << 8) & 0x00ff0000) | - ((val << 24) & 0xff000000); - */ } static __forceinline u64 Reverse64(const u64 val) { return _byteswap_uint64(val); - /* - return - ((val >> 56) & 0x00000000000000ff) | - ((val >> 40) & 0x000000000000ff00) | - ((val >> 24) & 0x0000000000ff0000) | - ((val >> 8) & 0x00000000ff000000) | - ((val << 8) & 0x000000ff00000000) | - ((val << 24) & 0x0000ff0000000000) | - ((val << 40) & 0x00ff000000000000) | - ((val << 56) & 0xff00000000000000); - */ } static __forceinline u128 Reverse128(const u128 val) { u128 ret; - ret.lo = re64(val.hi); - ret.hi = re64(val.lo); + ret.lo = _byteswap_uint64(val.hi); + ret.hi = _byteswap_uint64(val.lo); return ret; } @@ -112,99 +100,8 @@ public: return (T)ReverseData(val); }; - MemoryBlock& GetMemByNum(const u8 num) - { - if(num >= MemoryBlocks.size()) return NullMem; - return *MemoryBlocks[num]; - } - - MemoryBlock& GetMemByAddr(const u64 addr) - { - for (auto block : MemoryBlocks) - { - if (block->IsMyAddress(addr)) - return *block; - } - - return NullMem; - } - - bool Read8ByAddr(const u64 addr, u8 *value) - { - *value = *(u8*)((u64)GetBaseAddr() + addr); - return true; - - /*for (auto block : MemoryBlocks) - { - if (block->Read8(addr, value)) - return true; - } - - return NullMem.Read8(addr, value);*/ - } - - bool Read16ByAddr(const u64 addr, u16 *value) - { - *value = re16(*(u16*)((u64)GetBaseAddr() + addr)); - return true; - - /*for (auto block : MemoryBlocks) - { - if (block->Read16(addr, value)) - return true; - } - - return NullMem.Read16(addr, value);*/ - } - - bool Read32ByAddr(const u64 addr, u32 *value) - { - if (addr < 0xE0000000 || (addr % 0x100000) < 0x40000) - { - *value = re32(*(u32*)((u64)GetBaseAddr() + addr)); - return true; - } - - for (auto block : MemoryBlocks) - { - if (block->Read32(addr, value)) - return true; - } - - return NullMem.Read32(addr, value); - } - - bool Read64ByAddr(const u64 addr, u64 *value) - { - *value = re64(*(u64*)((u64)GetBaseAddr() + addr)); - return true; - - /*for (auto block : MemoryBlocks) - { - if (block->Read64(addr, value)) - return true; - } - - return NullMem.Read64(addr, value);*/ - } - - bool Read128ByAddr(const u64 addr, u128 *value) - { - *value = re128(*(u128*)((u64)GetBaseAddr() + addr)); - return true; - - /*for (auto block : MemoryBlocks) - { - if (block->Read128(addr, value)) - return true; - } - - return NullMem.Read128(addr, value);*/ - } - u8* GetMemFromAddr(const u64 addr) { - //return GetMemByAddr(addr).GetMemFromAddr(addr); return (u8*)GetBaseAddr() + addr; } @@ -215,36 +112,49 @@ public: u64 RealToVirtualAddr(const void* addr) { - const u64 raddr = (u64)addr; - for (auto block : MemoryBlocks) + const u64 res = (u64)addr - (u64)GetBaseAddr(); + + if (res < 0x100000000) { - MemoryBlock& b = *block; - const u64 baddr = (u64)b.GetMem(); - - if(raddr >= baddr && raddr < baddr + b.GetSize()) - { - return b.GetStartAddr() + (raddr - baddr); - } + return res; + } + else + { + return 0; } - - return 0; } - bool InitSpuRawMem(const u32 max_spu_raw) + void InitRawSPU(MemoryBlock* raw_spu, const u32 num) { - //if(SpuRawMem.GetSize()) return false; + std::lock_guard lock(m_mutex); - MemoryBlocks.push_back(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw)); + MemoryBlocks.push_back(raw_spu); + if (num < 32) RawSPUMem[num] = raw_spu; + } - return true; + void CloseRawSPU(MemoryBlock* raw_spu, const u32 num) + { + std::lock_guard lock(m_mutex); + + for (int i = 0; i < MemoryBlocks.size(); ++i) + { + if (MemoryBlocks[i] == raw_spu) + { + MemoryBlocks.erase(MemoryBlocks.begin() + i); + break; + } + } + if (num < 32) RawSPUMem[num] = nullptr; } void Init(MemoryType type) { + std::lock_guard lock(m_mutex); + if(m_inited) return; m_inited = true; - m_base_addr = VirtualAlloc(0, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); + m_base_addr = VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); if (!m_base_addr) { LOG_ERROR(MEMORY, "Initing memory: VirtualAlloc() failed"); @@ -254,6 +164,11 @@ public: LOG_NOTICE(MEMORY, "Initing memory: m_base_addr = 0x%llx", (u64)m_base_addr); } + for (u32 i = 0; i < 32; i++) + { + RawSPUMem[i] = nullptr; + } + switch(type) { case Memory_PS3: @@ -263,8 +178,6 @@ public: MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000)); MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000)); MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000)); - //MemoryBlocks.push_back(SpuRawMem.SetRange(0xE0000000, 0x10000000)); - //MemoryBlocks.push_back(SpuThrMem.SetRange(0xF0000000, 0x10000000)); break; case Memory_PSV: @@ -286,34 +199,68 @@ public: bool IsGoodAddr(const u64 addr) { - for (auto block : MemoryBlocks) + //std::lock_guard lock(m_mutex); + + __try { - if (block->IsMyAddress(addr)) - return true; + volatile const u8 test = *GetMemFromAddr(addr); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; } - return false; + return true; + + //for (auto block : MemoryBlocks) + //{ + // if (block->IsMyAddress(addr)) + // return true; + //} + + //return false; } bool IsGoodAddr(const u64 addr, const u32 size) { - const u64 end = addr + size - 1; - for (auto block : MemoryBlocks) + //std::lock_guard lock(m_mutex); + + __try { - if (block->IsMyAddress(addr) && block->IsMyAddress(end)) - return true; + volatile const u8 test1 = *GetMemFromAddr(addr); + volatile const u8 test2 = *GetMemFromAddr(addr + size - 1); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; } - return false; + return true; + + //const u64 end = addr + size - 1; + //for (auto block : MemoryBlocks) + //{ + // if (block->IsMyAddress(addr) && block->IsMyAddress(end)) + // return true; + //} + + //return false; } void Close() { + std::lock_guard lock(m_mutex); + if(!m_inited) return; m_inited = false; LOG_NOTICE(MEMORY, "Closing memory..."); + for (u32 i = 0; i < 32; i++) + { + RawSPUMem[i] = nullptr; + } + for (auto block : MemoryBlocks) { block->Delete(); @@ -345,78 +292,25 @@ public: u64 Read64(const u64 addr); u128 Read128(const u64 addr); - bool CopyToReal(void* real, u32 from, u32 count) // (4K pages) copy from virtual to real memory + bool CopyToReal(void* real, u32 from, u32 count) { if (!count) return true; - u8* to = (u8*)real; - - if (u32 frag = from & 4095) - { - if (!IsGoodAddr(from)) return false; - u32 num = 4096 - frag; - if (count < num) num = count; - memcpy(to, GetMemFromAddr(from), num); - to += num; - from += num; - count -= num; - } - - for (u32 page = count / 4096; page > 0; page--) - { - if (!IsGoodAddr(from)) return false; - memcpy(to, GetMemFromAddr(from), 4096); - to += 4096; - from += 4096; - count -= 4096; - } - - if (count) - { - if (!IsGoodAddr(from)) return false; - memcpy(to, GetMemFromAddr(from), count); - } + memcpy(real, GetMemFromAddr(from), count); return true; } - bool CopyFromReal(u32 to, const void* real, u32 count) // (4K pages) copy from real to virtual memory + bool CopyFromReal(u32 to, const void* real, u32 count) { if (!count) return true; - const u8* from = (const u8*)real; - - if (u32 frag = to & 4095) - { - if (!IsGoodAddr(to)) return false; - u32 num = 4096 - frag; - if (count < num) num = count; - memcpy(GetMemFromAddr(to), from, num); - to += num; - from += num; - count -= num; - } - - for (u32 page = count / 4096; page > 0; page--) - { - if (!IsGoodAddr(to)) return false; - memcpy(GetMemFromAddr(to), from, 4096); - to += 4096; - from += 4096; - count -= 4096; - } - - if (count) - { - if (!IsGoodAddr(to)) return false; - memcpy(GetMemFromAddr(to), from, count); - } + memcpy(GetMemFromAddr(to), real, count); return true; - } - bool Copy(u32 to, u32 from, u32 count) // (4K pages) copy from virtual to virtual memory through real + bool Copy(u32 to, u32 from, u32 count) { if (u8* buf = (u8*)malloc(count)) { @@ -447,54 +341,22 @@ public: void ReadLeft(u8* dst, const u64 addr, const u32 size) { - MemoryBlock& mem = GetMemByAddr(addr); - - if(mem.IsNULL()) - { - LOG_ERROR(MEMORY, "ReadLeft[%d] from null block (0x%llx)", size, addr); - return; - } - - for(u32 i=0; i void WriteData(const u64 addr, const T* data) @@ -521,12 +383,6 @@ public: void WriteString(const u64 addr, const std::string& str) { - if(!IsGoodAddr(addr, str.length())) - { - LOG_ERROR(MEMORY,"Memory::WriteString error: bad address (0x%llx)", addr); - return; - } - strcpy((char*)GetMemFromAddr(addr), str.c_str()); } @@ -567,6 +423,8 @@ public: bool Map(const u64 dst_addr, const u64 src_addr, const u32 size) { + std::lock_guard lock(m_mutex); + if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) { return false; @@ -579,6 +437,8 @@ public: bool Unmap(const u64 addr) { + std::lock_guard lock(m_mutex); + bool result = false; for(uint i=0; iaddr = other.addr; this->size = other.size; - //if (this->mem) _aligned_free(mem); if (this->mem) VirtualFree(this->mem, this->size, MEM_DECOMMIT); this->mem = other.mem; other.mem = nullptr; @@ -53,7 +51,6 @@ struct MemBlockInfo : public MemInfo ~MemBlockInfo() { - //if(mem) _aligned_free(mem); if (mem) VirtualFree(mem, size, MEM_DECOMMIT); mem = nullptr; } @@ -207,7 +204,6 @@ class DynamicMemoryBlockBase : public PT mutable std::mutex m_lock; std::vector m_allocated; // allocation info std::vector m_pages; // real addresses of every 4096 byte pages (array size should be fixed) - std::vector m_locked; // locked pages should be moved here u32 m_max_size; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 0b28f4d773..b1b74b4c76 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -315,17 +315,16 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) if (system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB) { cellGcmSys->Warning("cellGcmInit(): 512MB io address space used"); - Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0x50000000, 0x20000000/*512MB*/));//TODO: implement allocateAdressSpace in memoryBase + Memory.RSXIOMem.SetRange(0x50000000, 0x20000000 /*512MB*/); } else { cellGcmSys->Warning("cellGcmInit(): 256MB io address space used"); - Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0x50000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase + Memory.RSXIOMem.SetRange(0x50000000, 0x10000000 /*256MB*/); } if(cellGcmMapEaIoAddress(ioAddress, 0, ioSize) != CELL_OK) { - Memory.MemoryBlocks.pop_back(); cellGcmSys->Error("cellGcmInit : CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index fdd633f28d..e56b525835 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -1135,7 +1135,7 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t if(colorBuffers.GetAddr() % COLOR_BUFFER_ALIGNMENT || vertexArray.GetAddr() % VERTEX_BUFFER_ALIGNMENT || fragmentShader.GetAddr() % FRAGMENT_SHADER_ALIGNMENT) { - cellResc->Error("cellRescSetBufferAddress : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc->Error("cellRescSetBufferAddress : CELL_RESC_ERROR_BAD_ARGUMENT (alignment)"); return CELL_RESC_ERROR_BAD_ARGUMENT; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 9f70053a04..e657106523 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -335,9 +335,6 @@ int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 as return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT; } -extern std::atomic g_FsAioReadID; -extern std::atomic g_FsAioReadCur; - int cellSysutilCheckCallback() { cellSysutil->Log("cellSysutilCheckCallback()"); @@ -346,7 +343,7 @@ int cellSysutilCheckCallback() CPUThread& thr = Emu.GetCallbackThread(); - while (thr.IsAlive() || (g_FsAioReadCur < g_FsAioReadID)) + while (thr.IsAlive()) { Sleep(1); if (Emu.IsStopped()) diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index dc588d5d7e..09d75fcaa1 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -361,7 +361,7 @@ int cellSurMixerCreate(const mem_ptr_t config) break; } - if (mixcount > (port.tag + 15)) // preemptive buffer filling (probably hack) + if (mixcount > (port.tag + 14)) // preemptive buffer filling (probably hack) { Sleep(1); continue; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 63de40521f..9b08ead4d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -162,74 +162,35 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_tsize; u32 buf_addr = aio->buf_addr; - u32 res = 0; u32 error = CELL_OK; vfsStream& file = *(vfsStream*)orig_file; const u64 old_pos = file.Tell(); file.Seek((u64)aio->offset); - u32 count = nbytes; - if (nbytes != (u64)count) + // TODO: use code from cellFsRead or something + + u64 res = 0; + if (nbytes != (u32)nbytes) { error = CELL_ENOMEM; - goto fin; } - - if (!Memory.IsGoodAddr(buf_addr)) + else { - error = CELL_EFAULT; - goto fin; + res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; } - if (count) if (u32 frag = buf_addr & 4095) // memory page fragment - { - u32 req = std::min(count, 4096 - frag); - u32 read = file.Read(Memory + buf_addr, req); - buf_addr += req; - res += read; - count -= req; - if (read < req) goto fin; - } - - for (u32 pages = count / 4096; pages > 0; pages--) // full pages - { - if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT) - u32 read = file.Read(Memory + buf_addr, 4096); - buf_addr += 4096; - res += read; - count -= 4096; - if (read < 4096) goto fin; - } - - if (count) // last fragment - { - if (!Memory.IsGoodAddr(buf_addr)) goto fin; - res += file.Read(Memory + buf_addr, count); - } - -fin: file.Seek(old_pos); - LOG_WARNING(HLE, "*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])", - fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str()); + if (Ini.HLELogging.GetValue()) + LOG_NOTICE(HLE, "*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])", + fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str()); if (func) // start callback thread { func.async(aio, error, xid, res); } - /*CPUThread& thr = Emu.GetCallbackThread(); - while (thr.IsAlive()) - { - Sleep(1); - if (Emu.IsStopped()) - { - LOG_WARNING(HLE, "fsAioRead() aborted"); - break; - } - }*/ - g_FsAioReadCur++; } diff --git a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp b/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp index adebe91563..8546d26345 100644 --- a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp @@ -146,39 +146,11 @@ s32 cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread) if (nread.GetAddr() && !nread.IsGood()) return CELL_EFAULT; - u32 res = 0; - u32 count = nbytes; - if (nbytes != (u64)count) return CELL_ENOMEM; + if (nbytes != (u32)nbytes) return CELL_ENOMEM; - if (!Memory.IsGoodAddr(buf_addr)) return CELL_EFAULT; + // TODO: checks - if (count) if (u32 frag = buf_addr & 4095) // memory page fragment - { - u32 req = std::min(count, 4096 - frag); - u32 read = file->Read(Memory + buf_addr, req); - buf_addr += req; - res += read; - count -= req; - if (read < req) goto fin; - } - - for (u32 pages = count / 4096; pages > 0; pages--) // full pages - { - if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT) - u32 read = file->Read(Memory + buf_addr, 4096); - buf_addr += 4096; - res += read; - count -= 4096; - if (read < 4096) goto fin; - } - - if (count) // last fragment - { - if (!Memory.IsGoodAddr(buf_addr)) goto fin; - res += file->Read(Memory + buf_addr, count); - } - -fin: + const u64 res = nbytes ? file->Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; if (nread.GetAddr()) nread = res; // write value if not NULL @@ -192,16 +164,15 @@ s32 cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite) vfsStream* file; if(!sys_fs->CheckId(fd, file)) return CELL_ESRCH; - if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) - { - MemoryBlock& block = Memory.GetMemByAddr(buf_addr); - nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); - } + if (nwrite.GetAddr() && !nwrite.IsGood()) return CELL_EFAULT; + + if (nbytes != (u32)nbytes) return CELL_ENOMEM; + + // TODO: checks const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; - if(nwrite.IsGood()) - nwrite = res; + if (nwrite.GetAddr()) nwrite = res; // write value if not NULL return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index da26b14349..a5bd6933d7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -23,14 +23,16 @@ s32 sys_process_getppid() s32 sys_process_exit(s32 errorcode) { sc_p.Warning("sys_process_exit(%d)", errorcode); - Emu.Pause(); // Emu.Stop() does crash + Emu.Pause(); LOG_SUCCESS(HLE, "Process finished"); - - if (Ini.HLEExitOnStop.GetValue()) + wxGetApp().CallAfter([]() { - Ini.HLEExitOnStop.SetValue(false); - // TODO: Find a way of calling Emu.Stop() and/or exiting RPCS3 (that is, TheApp->Exit()) without crashes - } + Emu.Stop(); + if (Ini.HLEExitOnStop.GetValue()) + { + wxGetApp().Exit(); + } + }); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index e5492be6f5..1ce34a3c6b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -391,14 +391,6 @@ s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) return CELL_EINVAL; } - //if(!Memory.InitSpuRawMem(max_raw_spu)) - //{ - // return CELL_ENOMEM; - //} - - //Ini.HLELogging.SetValue(true); - //dump_enable = true; - return CELL_OK; } @@ -773,7 +765,6 @@ s32 sys_raw_spu_create(mem32_t id, u32 attr_addr) CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); id = ((RawSPUThread&)new_thread).GetIndex(); new_thread.Run(); - new_thread.Exec(); return CELL_OK; } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 20178ef443..0e9b70487d 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -312,6 +312,7 @@ + @@ -505,6 +506,7 @@ Use _UNICODE;UNICODE;%(PreprocessorDefinitions) stdafx.h + Async true @@ -518,6 +520,7 @@ Use _UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions) stdafx.h + Async true @@ -548,6 +551,7 @@ false Use stdafx.h + Async true diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index d791a5101e..aa9b035f34 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1093,5 +1093,8 @@ Emu\SysCalls\Modules + + Emu\Memory + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index ab655be438..1f8f08d77d 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -81,6 +81,7 @@ ProgramDatabase Use ..\wxWidgets\include\msvc + Async true @@ -104,6 +105,7 @@ Use ..\wxWidgets\include\msvc _UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions) + Async true @@ -131,7 +133,7 @@ false Use Speed - Sync + Async false true From 50b42f85932a454e8a0b0f2b5459472378a2df95 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 8 Jul 2014 18:26:49 +0400 Subject: [PATCH 03/15] ifdefs and linux (posix) version (not tested) --- rpcs3/Emu/CPU/CPUThread.cpp | 8 ++ rpcs3/Emu/Memory/DynamicMemoryBlockBase.h | 2 +- rpcs3/Emu/Memory/Memory.cpp | 67 ++++++++++++-- rpcs3/Emu/Memory/Memory.h | 104 +++++++++++----------- rpcs3/Emu/Memory/MemoryBlock.h | 20 ++--- 5 files changed, 131 insertions(+), 70 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index cc21ba3c11..c19d8f48e2 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -280,6 +280,7 @@ void CPUThread::ExecOnce() SendDbgCommand(DID_PAUSED_THREAD, this); } +#ifdef _WIN32 void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) { const u64 addr = (u64)Memory.GetBaseAddr() - (u64)pExp->ExceptionRecord->ExceptionAddress; @@ -296,6 +297,9 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) return; } } +#else +// TODO: linux version +#endif void CPUThread::Task() { @@ -312,7 +316,11 @@ void CPUThread::Task() } } +#ifdef _WIN32 _set_se_translator(_se_translator); +#else + // TODO: linux version +#endif while (true) { diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h index 0d86262059..77e50c8869 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h @@ -105,7 +105,7 @@ bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size) template void DynamicMemoryBlockBase::AppendMem(u64 addr, u32 size) /* private */ { - m_allocated.emplace_back(addr, size, Memory.GetBaseAddr()); + m_allocated.emplace_back(addr, size); u8* pointer = (u8*) m_allocated.back().mem; const u32 first = MemoryBlock::FixAddr(addr) >> 12; diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 5395bd1089..cd78fee7ad 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -8,8 +8,53 @@ MemoryBase Memory; +MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size) + : MemInfo(_addr, PAGE_4K(_size)) +{ + void* real_addr = (void*)((u64)Memory.GetBaseAddr() + _addr); +#ifdef _WIN32 + mem = VirtualAlloc(real_addr, size, MEM_COMMIT, PAGE_READWRITE); +#else + if (::mprotect(real_addr, size, PROT_READ | PROT_WRITE)) + { + mem = nullptr; + } + else + { + mem = real_addr; + } +#endif + if (mem != real_addr) + { + LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%llx, size=0x%llx)", addr, size); + Emu.Pause(); + } + else + { + Memory.RegisterPages(_addr, PAGE_4K(_size)); + memset(mem, 0, size); + } +} + +void MemBlockInfo::Free() +{ + if (mem) + { + Memory.UnregisterPages(addr, size); +#ifdef _WIN32 + if (!VirtualFree(mem, size, MEM_DECOMMIT)) +#else + if (::mprotect(mem, size, PROT_NONE)) +#endif + { + LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%llx, size=0x%llx)", addr, size); + Emu.Pause(); + } + } +} + //MemoryBlock -MemoryBlock::MemoryBlock() +MemoryBlock::MemoryBlock() : mem_inf(nullptr) { Init(); } @@ -29,16 +74,26 @@ void MemoryBlock::Init() void MemoryBlock::InitMemory() { - if(!range_size) return; + if (!range_size) return; - if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); - mem = (u8*)VirtualAlloc((void*)((u64)Memory.GetBaseAddr() + range_start), range_size, MEM_COMMIT, PAGE_READWRITE); - memset(mem, 0, range_size); + Free(); + mem_inf = new MemBlockInfo(range_start, range_size); + mem = (u8*)mem_inf->mem; +} + +void MemoryBlock::Free() +{ + if (mem_inf) + { + delete mem_inf; + mem_inf = nullptr; + } + mem = nullptr; } void MemoryBlock::Delete() { - if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); + Free(); Init(); } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index fb4db9349d..9f682a0c5f 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -24,6 +24,7 @@ class MemoryBase { void* m_base_addr; std::vector MemoryBlocks; + u32 m_pages[0x100000000 / 4096]; // information about every page std::mutex m_mutex; public: @@ -35,7 +36,7 @@ public: DynamicMemoryBlock MmaperMem; DynamicMemoryBlock RSXFBMem; DynamicMemoryBlock StackMem; - MemoryBlock* RawSPUMem[32]; + MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]; VirtualMemoryBlock RSXIOMem; struct @@ -70,6 +71,24 @@ public: return m_base_addr; } + void RegisterPages(u64 addr, u32 size) + { + for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) + { + if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break; + m_pages[i] = 1; // TODO: define page parameters + } + } + + void UnregisterPages(u64 addr, u32 size) + { + for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) + { + if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break; + m_pages[i] = 0; // TODO: define page parameters + } + } + static __forceinline u16 Reverse16(const u16 val) { return _byteswap_ushort(val); @@ -129,7 +148,7 @@ public: std::lock_guard lock(m_mutex); MemoryBlocks.push_back(raw_spu); - if (num < 32) RawSPUMem[num] = raw_spu; + if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = raw_spu; } void CloseRawSPU(MemoryBlock* raw_spu, const u32 num) @@ -144,7 +163,7 @@ public: break; } } - if (num < 32) RawSPUMem[num] = nullptr; + if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = nullptr; } void Init(MemoryType type) @@ -154,21 +173,26 @@ public: if(m_inited) return; m_inited = true; + memset(m_pages, 0, sizeof(m_pages)); + memset(RawSPUMem, 0, sizeof(RawSPUMem)); + +#ifdef _WIN32 m_base_addr = VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); if (!m_base_addr) +#else + m_base_addr = ::mmap(nullptr, 0x100000000, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + if (m_base_addr == (void*)-1) +#endif { - LOG_ERROR(MEMORY, "Initing memory: VirtualAlloc() failed"); + m_base_addr = nullptr; + LOG_ERROR(MEMORY, "Initing memory failed"); + assert(0); } else { LOG_NOTICE(MEMORY, "Initing memory: m_base_addr = 0x%llx", (u64)m_base_addr); } - for (u32 i = 0; i < 32; i++) - { - RawSPUMem[i] = nullptr; - } - switch(type) { case Memory_PS3: @@ -199,52 +223,30 @@ public: bool IsGoodAddr(const u64 addr) { - //std::lock_guard lock(m_mutex); - - __try - { - volatile const u8 test = *GetMemFromAddr(addr); - } - __except (EXCEPTION_EXECUTE_HANDLER) + if (addr >= 0x100000000 || !m_pages[addr / 4096]) // TODO: define page parameters { return false; } - - return true; - - //for (auto block : MemoryBlocks) - //{ - // if (block->IsMyAddress(addr)) - // return true; - //} - - //return false; + else + { + return true; + } } bool IsGoodAddr(const u64 addr, const u32 size) { - //std::lock_guard lock(m_mutex); - - __try - { - volatile const u8 test1 = *GetMemFromAddr(addr); - volatile const u8 test2 = *GetMemFromAddr(addr + size - 1); - } - __except (EXCEPTION_EXECUTE_HANDLER) + if (addr + size > 0x100000000) { return false; } - - return true; - - //const u64 end = addr + size - 1; - //for (auto block : MemoryBlocks) - //{ - // if (block->IsMyAddress(addr) && block->IsMyAddress(end)) - // return true; - //} - - //return false; + else + { + for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++) + { + if (!m_pages[i]) return false; // TODO: define page parameters + } + return true; + } } void Close() @@ -256,11 +258,6 @@ public: LOG_NOTICE(MEMORY, "Closing memory..."); - for (u32 i = 0; i < 32; i++) - { - RawSPUMem[i] = nullptr; - } - for (auto block : MemoryBlocks) { block->Delete(); @@ -268,10 +265,17 @@ public: MemoryBlocks.clear(); +#ifdef _WIN32 if (!VirtualFree(m_base_addr, 0, MEM_RELEASE)) { LOG_ERROR(MEMORY, "VirtualFree(0x%llx) failed", (u64)m_base_addr); } +#else + if (::munmap(m_base_addr, 0x100000000)) + { + LOG_ERROR(MEMORY, "::munmap(0x%llx) failed", (u64)m_base_addr); + } +#endif } void Write8(const u64 addr, const u8 data); diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 4917846e0c..d58f5d7f17 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -22,17 +22,9 @@ struct MemBlockInfo : public MemInfo { void *mem; - MemBlockInfo(u64 _addr, u32 _size, void* base_addr) - : MemInfo(_addr, PAGE_4K(_size)) - , mem(VirtualAlloc((void*)((u64)base_addr + _addr), PAGE_4K(_size), MEM_COMMIT, PAGE_READWRITE)) - { - if(!mem) - { - LOG_ERROR(MEMORY, "Out of memory or VirtualAlloc() failed (_addr=0x%llx, _size=0x%llx)", _addr, _size); - assert(0); - } - memset(mem, 0, size); - } + MemBlockInfo(u64 _addr, u32 _size); + + void Free(); MemBlockInfo(MemBlockInfo &other) = delete; MemBlockInfo(MemBlockInfo &&other) : MemInfo(other.addr,other.size) ,mem(other.mem) @@ -43,7 +35,7 @@ struct MemBlockInfo : public MemInfo MemBlockInfo& operator =(MemBlockInfo &&other){ this->addr = other.addr; this->size = other.size; - if (this->mem) VirtualFree(this->mem, this->size, MEM_DECOMMIT); + this->Free(); this->mem = other.mem; other.mem = nullptr; return *this; @@ -51,7 +43,7 @@ struct MemBlockInfo : public MemInfo ~MemBlockInfo() { - if (mem) VirtualFree(mem, size, MEM_DECOMMIT); + Free(); mem = nullptr; } }; @@ -85,7 +77,9 @@ public: virtual ~MemoryBlock(); private: + MemBlockInfo* mem_inf; void Init(); + void Free(); void InitMemory(); public: From 34590bc88469f5dc040b8fef5609a2932436a8bd Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 8 Jul 2014 21:08:56 +0400 Subject: [PATCH 04/15] Small fix --- rpcs3/Emu/Memory/DynamicMemoryBlockBase.h | 1 + rpcs3/Emu/Memory/Memory.h | 1 + 2 files changed, 2 insertions(+) diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h index 77e50c8869..fb45886bbf 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h @@ -87,6 +87,7 @@ bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size) if (IsMyAddress(addr) || IsMyAddress(addr + size - 1)) { + assert(0); return false; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 9f682a0c5f..bd06a5e56d 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -187,6 +187,7 @@ public: m_base_addr = nullptr; LOG_ERROR(MEMORY, "Initing memory failed"); assert(0); + return; } else { From 6e77f80d5f57511c110a433f24473e4d04b50d57 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 8 Jul 2014 21:18:12 +0400 Subject: [PATCH 05/15] Small fix 2 --- rpcs3/Emu/Memory/Memory.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index bd06a5e56d..4eea68c630 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -1,4 +1,9 @@ #pragma once + +#ifndef _WIN32 +#include +#endif + #include "Emu/SysCalls/Callback.h" #include "MemoryBlock.h" #include From 123c4ba1a8bd83230a047eb8941ac78ab7276184 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 9 Jul 2014 03:04:36 +0400 Subject: [PATCH 06/15] Some bugs fixed --- Utilities/Log.cpp | 2 +- rpcs3/Emu/Memory/DynamicMemoryBlockBase.h | 4 ++++ rpcs3/Emu/Memory/Memory.h | 18 ++++++++++++++---- rpcs3/Emu/Memory/MemoryBlock.h | 12 +++++++++--- rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp | 6 +++++- rpcs3/Emu/System.cpp | 5 ++++- rpcs3/Loader/ELF32.cpp | 2 +- 7 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index 180f77bff3..7f6b68fcb4 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -194,7 +194,7 @@ void LogManager::log(LogMessage msg) } if (NamedThreadBase* thr = GetCurrentNamedThread()) { - prefix += thr->GetThreadName(); + prefix += "{" + thr->GetThreadName() + "} "; } msg.mText.insert(0, prefix); msg.mText.append(1,'\n'); diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h index fb45886bbf..6bc225daca 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h @@ -161,6 +161,8 @@ u64 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align) addr = (addr + (align - 1)) & ~(align - 1); } + //LOG_NOTICE(MEMORY, "AllocAlign(size=0x%x) -> 0x%llx", size, addr); + AppendMem(addr, size); return addr; @@ -202,6 +204,8 @@ bool DynamicMemoryBlockBase::Free(u64 addr) m_pages[i] = nullptr; } + //LOG_NOTICE(MEMORY, "Free(0x%llx)", addr); + m_allocated.erase(m_allocated.begin() + num); return true; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 4eea68c630..c363528f3f 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -78,18 +78,32 @@ public: void RegisterPages(u64 addr, u32 size) { + std::lock_guard lock(m_mutex); + + //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size); for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) { if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break; + if (m_pages[i]) + { + LOG_ERROR(MEMORY, "Page already registered (page=0x%x)", i * 4096); + } m_pages[i] = 1; // TODO: define page parameters } } void UnregisterPages(u64 addr, u32 size) { + std::lock_guard lock(m_mutex); + + //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size); for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) { if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break; + if (!m_pages[i]) + { + LOG_ERROR(MEMORY, "Page not registered (page=0x%x)", i * 4096); + } m_pages[i] = 0; // TODO: define page parameters } } @@ -173,8 +187,6 @@ public: void Init(MemoryType type) { - std::lock_guard lock(m_mutex); - if(m_inited) return; m_inited = true; @@ -257,8 +269,6 @@ public: void Close() { - std::lock_guard lock(m_mutex); - if(!m_inited) return; m_inited = false; diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index d58f5d7f17..caac4efc56 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -27,15 +27,21 @@ struct MemBlockInfo : public MemInfo void Free(); MemBlockInfo(MemBlockInfo &other) = delete; - MemBlockInfo(MemBlockInfo &&other) : MemInfo(other.addr,other.size) ,mem(other.mem) + + MemBlockInfo(MemBlockInfo &&other) + : MemInfo(other.addr,other.size) + , mem(other.mem) { other.mem = nullptr; } + MemBlockInfo& operator =(MemBlockInfo &other) = delete; - MemBlockInfo& operator =(MemBlockInfo &&other){ + + MemBlockInfo& operator =(MemBlockInfo &&other) + { + this->Free(); this->addr = other.addr; this->size = other.size; - this->Free(); this->mem = other.mem; other.mem = nullptr; return *this; diff --git a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp b/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp index 8546d26345..ed40ca711e 100644 --- a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp @@ -144,7 +144,11 @@ s32 cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread) vfsStream* file; if(!sys_fs->CheckId(fd, file)) return CELL_ESRCH; - if (nread.GetAddr() && !nread.IsGood()) return CELL_EFAULT; + if (nread.GetAddr() && !nread.IsGood()) + { + sys_fs->Error("cellFsRead(): bad nread_addr(0x%x)", nread.GetAddr()); + return CELL_EFAULT; + } if (nbytes != (u32)nbytes) return CELL_ENOMEM; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 54254c4f62..b44a4000a4 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -201,6 +201,10 @@ void Emulator::Load() switch(l.GetMachine()) { case MACHINE_SPU: + Memory.Init(Memory_PS3); + Memory.MainMem.AllocFixed(Memory.MainMem.GetStartAddr(), 0x40000); + break; + case MACHINE_PPC64: Memory.Init(Memory_PS3); break; @@ -263,7 +267,6 @@ void Emulator::Load() LOG_NOTICE(LOADER, "offset = 0x%llx", Memory.MainMem.GetStartAddr()); LOG_NOTICE(LOADER, "max addr = 0x%x", l.GetMaxAddr()); thread.SetOffset(Memory.MainMem.GetStartAddr()); - Memory.MainMem.AllocFixed(Memory.MainMem.GetStartAddr() + l.GetMaxAddr(), 0xFFFFED - l.GetMaxAddr()); thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr()); break; diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 5765974566..4e736e34e2 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -236,7 +236,7 @@ bool ELF32Loader::LoadPhdrData(u64 _offset) switch(machine) { - case MACHINE_SPU: Memory.MainMem.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break; + case MACHINE_SPU: break; case MACHINE_MIPS: Memory.PSPMemory.RAM.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break; case MACHINE_ARM: Memory.PSVMemory.RAM.AllocFixed(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break; From bb0695e76c388ed55d368a70e3d5b0389ff75552 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 10 Jul 2014 00:02:21 +0400 Subject: [PATCH 07/15] Using recursive mutex --- rpcs3/Emu/Memory/Memory.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index c363528f3f..8a9376df3c 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -30,7 +30,7 @@ class MemoryBase void* m_base_addr; std::vector MemoryBlocks; u32 m_pages[0x100000000 / 4096]; // information about every page - std::mutex m_mutex; + std::recursive_mutex m_mutex; public: MemoryBlock* UserMemory; @@ -78,7 +78,7 @@ public: void RegisterPages(u64 addr, u32 size) { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size); for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) @@ -94,7 +94,7 @@ public: void UnregisterPages(u64 addr, u32 size) { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size); for (u32 i = addr / 4096; i < (addr + size) / 4096; i++) @@ -164,7 +164,7 @@ public: void InitRawSPU(MemoryBlock* raw_spu, const u32 num) { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); MemoryBlocks.push_back(raw_spu); if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = raw_spu; @@ -172,7 +172,7 @@ public: void CloseRawSPU(MemoryBlock* raw_spu, const u32 num) { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); for (int i = 0; i < MemoryBlocks.size(); ++i) { @@ -187,6 +187,8 @@ public: void Init(MemoryType type) { + std::lock_guard lock(m_mutex); + if(m_inited) return; m_inited = true; @@ -269,6 +271,8 @@ public: void Close() { + std::lock_guard lock(m_mutex); + if(!m_inited) return; m_inited = false; @@ -443,7 +447,7 @@ public: bool Map(const u64 dst_addr, const u64 src_addr, const u32 size) { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) { @@ -457,7 +461,7 @@ public: bool Unmap(const u64 addr) { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); bool result = false; for(uint i=0; i Date: Thu, 10 Jul 2014 04:13:04 +0400 Subject: [PATCH 08/15] Some cleanup 2 --- rpcs3/Emu/CPU/CPUThreadManager.cpp | 20 +-- rpcs3/Emu/Cell/RawSPUThread.cpp | 259 ++++++++++++++++++++++++----- rpcs3/Emu/Cell/SPUThread.h | 27 +-- rpcs3/Emu/GS/RSXThread.cpp | 22 +-- rpcs3/Emu/GS/RSXThread.h | 16 +- 5 files changed, 262 insertions(+), 82 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index e2e3ad886d..245e01875f 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -110,22 +110,14 @@ CPUThread* CPUThreadManager::GetThread(u32 id) RawSPUThread* CPUThreadManager::GetRawSPUThread(u32 num) { - std::lock_guard lock(m_mtx_thread); - - for (u32 i = 0; i < m_threads.size(); i++) + if (num < sizeof(Memory.RawSPUMem) / sizeof(Memory.RawSPUMem[0])) { - if (m_threads[i]->GetType() == CPU_THREAD_RAW_SPU) - { - RawSPUThread* t = (RawSPUThread*)m_threads[i]; - - if (t->GetIndex() == num) - { - return t; - } - } + return (RawSPUThread*)Memory.RawSPUMem[num]; + } + else + { + return nullptr; } - - return nullptr; } void CPUThreadManager::NotifyThread(const u32 id) diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 1521e35cea..2b0ab6c68e 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -28,44 +28,136 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) return MemoryBlock::Read32(addr, value); } - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; + const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; + switch(offset) { - case MFC_LSA_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_LSA)", m_index); *value = MFC2.LSA.GetValue(); break; - case MFC_EAH_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_EAH)", m_index); *value = MFC2.EAH.GetValue(); break; - case MFC_EAL_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_EAL)", m_index); *value = MFC2.EAL.GetValue(); break; - case MFC_Size_Tag_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_Size_Tag)", m_index); *value = MFC2.Size_Tag.GetValue(); break; - case MFC_CMDStatus_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_CMDStatus)", m_index); *value = MFC2.CMDStatus.GetValue(); break; + 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(); break; + *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(); + break; + } + case SPU_Out_MBox_offs: - //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index); - SPU.Out_MBox.PopUncond(*value); //if Out_MBox is empty yet, the result will be undefined - break; - case SPU_In_MBox_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); while(!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break; - case SPU_MBox_Status_offs: //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_MBox_Status)", m_index); + { + // if Out_MBox is empty, the result is undefined + 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()) Sleep(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(); break; - case SPU_RunCntl_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = (u32)IsRunning(); break; + } + + case SPU_RunCntl_offs: + { + LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); + *value = (u32)IsRunning(); + break; + } + case SPU_Status_offs: - //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_Status)", m_index); + { *value = SPU.Status.GetValue(); break; - case SPU_NPC_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_NPC)", m_index); *value = SPU.NPC.GetValue(); break; - case SPU_RdSigNotify1_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RdSigNotify1)", m_index); *value = SPU.SNR[0].GetValue(); break; - case SPU_RdSigNotify2_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RdSigNotify2)", m_index); *value = SPU.SNR[1].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(); - break; + return false; + } } return true; @@ -78,19 +170,48 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) return MemoryBlock::Write32(addr, value); } - u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; + const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch(offset) { - case MFC_LSA_offs: MFC2.LSA.SetValue(value); break; - case MFC_EAH_offs: MFC2.EAH.SetValue(value); break; - case MFC_EAL_offs: MFC2.EAL.SetValue(value); break; - case MFC_Size_Tag_offs: MFC2.Size_Tag.SetValue(value); break; + case MFC_LSA_offs: + { + MFC2.LSA.SetValue(value); + break; + } + + case MFC_EAH_offs: + { + MFC2.EAH.SetValue(value); + break; + } + + case MFC_EAL_offs: + { + MFC2.EAL.SetValue(value); + break; + } + + case MFC_Size_Tag_offs: + { + MFC2.Size_Tag.SetValue(value); + break; + } + case MFC_CMDStatus_offs: + { MFC2.CMDStatus.SetValue(value); EnqMfcCmd(MFC2); - break; - case MFC_QStatus_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); MFC2.QStatus.SetValue(value); break; + 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); @@ -109,16 +230,44 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) Prxy.QueryType.SetValue(0); MFC2.QStatus.SetValue(Prxy.QueryMask.GetValue()); + break; } - 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()) Sleep(1); 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()) Sleep(1); + break; + } + case SPU_In_MBox_offs: - //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value); - SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten - 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; + { + // if In_MBox is already full, the last message is overwritten + 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: { if (value == SPU_RUNCNTL_RUNNABLE) @@ -138,15 +287,41 @@ 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); break; - case SPU_RdSigNotify2_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify2, 0x%x)", m_index, value); SPU.SNR[1].SetValue(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); + break; + } + + case SPU_RdSigNotify2_offs: + { + LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify2, 0x%x)", m_index, value); + SPU.SNR[1].SetValue(value); + break; + } default: + { LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(0x%x, 0x%x)", m_index, offset, value); Emu.Pause(); - break; + break; + } } return true; diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 28e07cc603..cd98ac713e 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -581,19 +581,26 @@ public: DMAC dmac; +#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) { if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); if (ea >= SYS_SPU_THREAD_BASE_LOW) { - if (group) + if (ea >= 0x100000000) + { + LOG_DMAC(LOG_ERROR, "Invalid external address"); + return false; + } + else if (group) { // SPU Thread Group MMIO (LS and SNR) u32 num = (ea & SYS_SPU_THREAD_BASE_MASK) / SYS_SPU_THREAD_OFFSET; // thread number in group if (num >= group->list.size() || !group->list[num]) { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): SPU Thread Group MMIO Access (ea=0x%llx): invalid thread", ea); + LOG_DMAC(LOG_ERROR, "Invalid thread (SPU Thread Group MMIO)"); return false; } @@ -612,13 +619,13 @@ public: } else { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): SPU Thread Group MMIO Access (ea=0x%llx, size=%d, cmd=0x%x): invalid command", ea, size, cmd); + LOG_DMAC(LOG_ERROR, "Invalid register (SPU Thread Group MMIO)"); return false; } } else { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): SPU Thread Group MMIO Access (ea=0x%llx): group not set", ea); + LOG_DMAC(LOG_ERROR, "Thread group not set (SPU Thread Group MMIO)"); return false; } } @@ -640,14 +647,12 @@ public: default: { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): Unknown DMA cmd."); + LOG_DMAC(LOG_ERROR, "Unknown DMA command"); return false; } } } - //Sleep(1); // hack - switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) { case MFC_PUT_CMD: @@ -658,7 +663,7 @@ public: } else { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): PUT* cmd failed (ea=0x%llx, lsa=0x%x, size=%d)", ea, lsa, size); + LOG_DMAC(LOG_ERROR, "PUT* cmd failed"); return false; // TODO: page fault (?) } } @@ -671,19 +676,21 @@ public: } else { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): GET* cmd failed (ea=0x%llx, lsa=0x%x, size=%d)", ea, lsa, size); + LOG_DMAC(LOG_ERROR, "GET* cmd failed"); return false; // TODO: page fault (?) } } default: { - LOG_ERROR(Log::SPU, "DMAC::ProcessCmd(): Unknown DMA cmd."); + LOG_DMAC(LOG_ERROR, "Unknown DMA command"); return false; // ??? } } } +#undef LOG_CMD + u32 dmacCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { /*if(proxy_pos >= MFC_PPU_MAX_QUEUE_SPACE) diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index f1053be27e..3590fe4a72 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -5,8 +5,7 @@ #include "RSXThread.h" #include "Emu/SysCalls/lv2/sys_time.h" -//#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.GetStartAddr() + m_ctrl->get + (4*(x+1)))) -#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count) : Memory.Read32(Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + m_ctrl->get + (4*(x+1))))) +#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args) : args[x]) u32 methodRegisters[0xffff]; @@ -46,10 +45,7 @@ u32 GetAddress(u32 offset, u8 location) switch(location) { case CELL_GCM_LOCATION_LOCAL: return Memory.RSXFBMem.GetStartAddr() + offset; - case CELL_GCM_LOCATION_MAIN: - u64 realAddr; - Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset, realAddr); // TODO: Error Check? - return realAddr; + case CELL_GCM_LOCATION_MAIN: return Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + offset); // TODO: Error Check? } LOG_ERROR(RSX, "GetAddress(offset=0x%x, location=0x%x)", location); @@ -141,7 +137,7 @@ u32 RSXVertexData::GetTypeSize() #define CMD_LOG(...) #endif -u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count) +u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, mem32_ptr_t args) { std::string debug = GetMethodName(cmd); debug += "("; @@ -207,7 +203,7 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count) index = (cmd - a) / m; \ case a \ -void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count) +void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32 count) { #if CMD_DEBUG std::string debug = GetMethodName(cmd); @@ -2454,9 +2450,7 @@ void RSXThread::Task() } //ConLog.Write("addr = 0x%x", m_ioAddress + get); - u64 realAddr; - Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + get, realAddr); - const u32 cmd = Memory.Read32(realAddr); + const u32 cmd = ReadIO32(get); const u32 count = (cmd >> 18) & 0x7ff; //if(cmd == 0) continue; @@ -2471,7 +2465,7 @@ void RSXThread::Task() { m_call_stack.push(get + 4); u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; - u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; + //u32 addr = Memory.RSXIOMem.GetStartAddr() + offs; //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); m_ctrl->get = offs; continue; @@ -2500,13 +2494,13 @@ void RSXThread::Task() continue; } + mem32_ptr_t args((u32)Memory.RSXIOMem.RealAddr(Memory.RSXIOMem.GetStartAddr() + get + 4)); + for(u32 i=0; iget = get + (count + 1) * 4; diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 3dd6abbf58..e776af2214 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -593,8 +593,8 @@ protected: void Begin(u32 draw_mode); void End(); - u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count); - void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count); + u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, mem32_ptr_t args); + void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32 count); void nativeRescale(float width, float height); virtual void OnInit() = 0; @@ -634,4 +634,16 @@ public: OnInit(); ThreadBase::Start(); } + + u32 ReadIO32(u32 addr) + { + u32 value; + Memory.RSXIOMem.Read32(Memory.RSXIOMem.GetStartAddr() + addr, &value); + return value; + } + + void WriteIO32(u32 addr, u32 value) + { + Memory.RSXIOMem.Write32(Memory.RSXIOMem.GetStartAddr() + addr, value); + } }; From 0dfbb5de73bbe8c89d264619051997b526a65243 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 10 Jul 2014 18:29:38 +0400 Subject: [PATCH 09/15] Compilation fix --- rpcs3/Emu/GS/RSXThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 3590fe4a72..473b9e0464 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -5,7 +5,7 @@ #include "RSXThread.h" #include "Emu/SysCalls/lv2/sys_time.h" -#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args) : args[x]) +#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args) : args[x].ToLE()) u32 methodRegisters[0xffff]; From cb9c1030a9d3986f349bb84d12f2b4afdb0260ee Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 11 Jul 2014 10:01:23 +0400 Subject: [PATCH 10/15] Warning fix --- Utilities/SMutex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities/SMutex.h b/Utilities/SMutex.h index 9ca53ce0e9..fb29087c6b 100644 --- a/Utilities/SMutex.h +++ b/Utilities/SMutex.h @@ -123,7 +123,7 @@ public: default: return res; } - if (wait) wait(); + if (wait != nullptr) wait(); if (timeout && counter++ > timeout) { From 125359e30e9c445e167075b99dfdf968c2cc4c4b Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 11 Jul 2014 13:18:23 +0400 Subject: [PATCH 11/15] Some fixes --- rpcs3/Emu/Cell/SPUThread.h | 2 +- rpcs3/Emu/FS/vfsStreamMemory.cpp | 26 +++++++----- rpcs3/Emu/Memory/Memory.cpp | 4 +- rpcs3/Emu/Memory/Memory.h | 42 +++++--------------- rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 25 +----------- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 14 ++++++- rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp | 6 ++- rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp | 6 ++- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 30 +++++++++++--- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 9 +++-- rpcs3/Emu/SysCalls/lv2/lv2Fs.h | 4 +- rpcs3/Emu/SysCalls/lv2/sys_rwlock.h | 2 - rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 10 +++-- rpcs3/Emu/SysCalls/lv2/sys_timer.h | 2 - rpcs3/Emu/SysCalls/lv2/sys_vm.h | 2 +- 15 files changed, 94 insertions(+), 90 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 3df6c315a1..cd98ac713e 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -310,7 +310,7 @@ class SPUThread : public PPCThread public: SPU_GPR_hdr GPR[128]; //General-Purpose Register SPU_SPR_hdr SPR[128]; //Special-Purpose Registers -// FPSCR fpscr; //Unused + FPSCR FPSCR; SPU_SNRConfig_hdr cfg; //Signal Notification Registers Configuration (OR-mode enabled: 0x1 for SNR1, 0x2 for SNR2) EventPort SPUPs[64]; // SPU Thread Event Ports diff --git a/rpcs3/Emu/FS/vfsStreamMemory.cpp b/rpcs3/Emu/FS/vfsStreamMemory.cpp index 7f140bf35b..1608f5c1da 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.cpp +++ b/rpcs3/Emu/FS/vfsStreamMemory.cpp @@ -32,11 +32,14 @@ u64 vfsStreamMemory::Write(const void* src, u64 size) size = GetSize() - Tell(); } - if(!size || !Memory.IsGoodAddr(m_addr + Tell(), size)) return 0; - - Memory.CopyFromReal(m_addr + Tell(), (void*)src, size); - - return vfsStream::Write(src, size); + if (!Memory.CopyFromReal(m_addr + Tell(), (void*)src, size)) + { + return 0; + } + else + { + return vfsStream::Write(src, size); + } } u64 vfsStreamMemory::Read(void* dst, u64 size) @@ -46,9 +49,12 @@ u64 vfsStreamMemory::Read(void* dst, u64 size) size = GetSize() - Tell(); } - if(!size || !Memory.IsGoodAddr(m_addr + Tell(), size)) return 0; - - Memory.CopyToReal(dst, m_addr + Tell(), size); - - return vfsStream::Read(dst, size); + if (!Memory.CopyToReal(dst, m_addr + Tell(), size)) + { + return 0; + } + else + { + return vfsStream::Read(dst, size); + } } diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 6352cd735b..f6e39be85f 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -104,14 +104,14 @@ bool MemoryBlock::GetMemFromAddr(void* dst, const u64 addr, const u32 size) { if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; - return Memory.CopyToReal(dst, (u32)addr, size); + return Memory.CopyToReal(dst, addr, size); } bool MemoryBlock::SetMemFromAddr(void* src, const u64 addr, const u32 size) { if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; - return Memory.CopyFromReal((u32)addr, src, size); + return Memory.CopyFromReal(addr, src, size); } bool MemoryBlock::GetMemFFromAddr(void* dst, const u64 addr) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index ddadd97a5c..b0fee3bac6 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -318,51 +318,31 @@ public: u64 Read64(const u64 addr); u128 Read128(const u64 addr); - bool CopyToReal(void* real, u32 from, u32 count) + bool CopyToReal(void* real, u64 from, u32 count) { - if (!count) return true; + if (!IsGoodAddr(from, count)) return false; memcpy(real, GetMemFromAddr(from), count); return true; } - bool CopyFromReal(u32 to, const void* real, u32 count) + bool CopyFromReal(u64 to, const void* real, u32 count) { - if (!count) return true; + if (!IsGoodAddr(to, count)) return false; memcpy(GetMemFromAddr(to), real, count); return true; } - bool Copy(u32 to, u32 from, u32 count) + bool Copy(u64 to, u64 from, u32 count) { - if (u8* buf = (u8*)malloc(count)) - { - if (CopyToReal(buf, from, count)) - { - if (CopyFromReal(to, buf, count)) - { - free(buf); - return true; - } - else - { - free(buf); - return false; - } - } - else - { - free(buf); - return false; - } - } - else - { - return false; - } + if (!IsGoodAddr(to, count) || !IsGoodAddr(from, count)) return false; + + memmove(GetMemFromAddr(to), GetMemFromAddr(from), count); + + return true; } void ReadLeft(u8* dst, const u64 addr, const u32 size) @@ -797,7 +777,7 @@ public: u32 AppendRawBytes(const u8 *bytes, size_t count) { - Memory.CopyFromReal(this->m_addr, bytes, count); + memmove(Memory + this->m_addr, bytes, count); this->m_addr += count; return this->m_addr; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 560850d32a..60b52a6c2c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -724,33 +724,11 @@ int cellAdecGetPcm(u32 handle, u32 outBuffer_addr) if (!af.data) // fake: empty data { - /*u8* buf = (u8*)malloc(4096); - memset(buf, 0, 4096); - Memory.CopyFromReal(outBuffer_addr, buf, 4096); - free(buf);*/ return result; } + // copy data - SwrContext* swr = nullptr; - - /*swr = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_FLT, 48000, - frame->channel_layout, (AVSampleFormat)frame->format, frame->sample_rate, 0, NULL); - - if (!swr) - { - LOG_ERROR(HLE, "cellAdecGetPcm(%d): swr_alloc_set_opts() failed", handle); - Emu.Pause(); - free(out); - if (af.data) - { - av_frame_unref(af.data); - av_frame_free(&af.data); - } - return result; - }*/ u8* out = (u8*)malloc(af.size); - // something is wrong - //swr_convert(swr, &out, frame->nb_samples, (const u8**)frame->extended_data, frame->nb_samples); // reverse byte order, extract data: float* in_f[2]; @@ -770,7 +748,6 @@ int cellAdecGetPcm(u32 handle, u32 outBuffer_addr) } free(out); - if (swr) swr_free(&swr); if (af.data) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 6ebe0c0228..297d6e00cf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -494,7 +494,12 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) const s32 res = ctxt->current - ctxt->begin - ctrl.put; - if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); + if (res > 0 && !Memory.Copy(ctxt->begin, ctxt->current - res, res)) + { + cellGcmSys->Error("cellGcmSetPrepareFlip(): Memory.Copy(0x%x, 0x%x, 0x%x) failed", (u32)ctxt->begin, (u32)ctxt->current - res, res); + Emu.Pause(); + return CELL_EFAULT; + } ctxt->current = ctxt->begin + res; //InterlockedExchange64((volatile long long*)((u8*)&ctrl + offsetof(CellGcmControl, put)), (u64)(u32)re(res)); @@ -1160,7 +1165,12 @@ int cellGcmCallback(u32 context_addr, u32 count) const s32 res = ctx.current - ctx.begin - ctrl.put; - if(res > 0) Memory.Copy(ctx.begin, ctx.current - res, res); + if (res > 0 && !Memory.Copy(ctx.begin, ctx.current - res, res)) + { + cellGcmSys->Error("cellGcmCallback(): Memory.Copy(0x%x, 0x%x, 0x%x) failed", (u32)ctx.begin, (u32)ctx.current - res, res); + Emu.Pause(); + return CELL_EFAULT; + } ctx.current = ctx.begin + res; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index e0ccafb456..866d6d48dc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -182,7 +182,11 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m switch((u32)current_outParam.outputColorSpace) { case CELL_GIFDEC_RGBA: - Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); + if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size)) + { + cellGifDec->Error("cellGifDecDecodeData() failed (dataa_addr=0x%x)", data.GetAddr()); + return CELL_EFAULT; + } break; case CELL_GIFDEC_ARGB: diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 922321f9c9..c24fcc5f8e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -164,7 +164,11 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m case CELL_JPG_RGBA: case CELL_JPG_RGB: image_size *= current_outParam.outputColorSpace == CELL_JPG_RGBA ? 4 : 3; - Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); + if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size)) + { + cellJpgDec->Error("cellJpgDecDecodeData() failed (data_addr=0x%x)", data.GetAddr()); + return CELL_EFAULT; + } break; case CELL_JPG_ARGB: diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 5dda7675d1..1ab78ff7a0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -148,7 +148,11 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_tsrc.srcSelect.ToBE()) { case se32(CELL_PNGDEC_BUFFER): - Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize()); + if (!Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize())) + { + cellPngDec->Error("cellPngDecReadHeader() failed ()"); + return CELL_EFAULT; + } break; case se32(CELL_PNGDEC_FILE): cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr()); @@ -213,7 +217,11 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m switch(subHandle_data->src.srcSelect.ToLE()) { case CELL_PNGDEC_BUFFER: - Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize()); + if (!Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize())) + { + cellPngDec->Error("cellPngDecDecodeData() failed (I)"); + return CELL_EFAULT; + } break; case CELL_PNGDEC_FILE: cellFsLseek(fd, 0, CELL_SEEK_SET, pos.GetAddr()); @@ -249,12 +257,20 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m { const int dstOffset = i * bytesPerLine; const int srcOffset = width * nComponents * (flip ? height - i - 1 : i); - Memory.CopyFromReal(data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize); + if (!Memory.CopyFromReal(data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize)) + { + cellPngDec->Error("cellPngDecDecodeData() failed (II)"); + return CELL_EFAULT; + } } } else { - Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); + if (!Memory.CopyFromReal(data.GetAddr(), image.get(), image_size)) + { + cellPngDec->Error("cellPngDecDecodeData() failed (III)"); + return CELL_EFAULT; + } } } break; @@ -279,7 +295,11 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m output[j + 2] = image.get()[srcOffset + j + 1]; output[j + 3] = image.get()[srcOffset + j + 2]; } - Memory.CopyFromReal(data.GetAddr() + dstOffset, output, linesize); + if (!Memory.CopyFromReal(data.GetAddr() + dstOffset, output, linesize)) + { + cellPngDec->Error("cellPngDecDecodeData() failed (IV)"); + return CELL_EFAULT; + } } free(output); } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 2908525db2..6721a233c3 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -168,9 +168,12 @@ int sys_raw_spu_image_load(int id, mem_ptr_t img) { sysPrxForUser->Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.GetAddr()); - Memory.Copy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, (u32)img->segs_addr, 256 * 1024); - Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, - (u32)img->entry_point); + if (!Memory.Copy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, (u32)img->segs_addr, 256 * 1024)) + { + sysPrxForUser->Error("sys_raw_spu_image_load() failed"); + return CELL_EFAULT; + } + Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, (u32)img->entry_point); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/lv2Fs.h b/rpcs3/Emu/SysCalls/lv2/lv2Fs.h index 1ab23595b3..c2a4faf33f 100644 --- a/rpcs3/Emu/SysCalls/lv2/lv2Fs.h +++ b/rpcs3/Emu/SysCalls/lv2/lv2Fs.h @@ -71,7 +71,7 @@ enum cellFsStStatus }; -#pragma pack(4) +#pragma pack(push, 4) struct CellFsStat { @@ -98,7 +98,7 @@ struct CellFsDirent char d_name[CELL_MAX_FS_FILE_NAME_LENGTH + 1]; }; -#pragma pack() +#pragma pack(pop) struct CellFsAio { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h index 4097ff4cd5..0ca4a41dff 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h @@ -14,8 +14,6 @@ struct sys_rwlock_attribute_t }; }; -#pragma pack() - struct RWLock { std::mutex m_lock; // internal lock diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 1ce34a3c6b..39f39ee591 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -136,10 +136,14 @@ s32 sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< u64 a3 = arg->arg3; u64 a4 = arg->arg4; - CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU); //copy SPU image: - u32 spu_offset = Memory.MainMem.AllocAlign(256 * 1024); - Memory.CopyToReal(Memory + spu_offset, (u32)img->segs_addr, 256 * 1024); + auto spu_offset = Memory.MainMem.AllocAlign(256 * 1024); + if (!Memory.Copy(spu_offset, (u32)img->segs_addr, 256 * 1024)) + { + return CELL_EFAULT; + } + + CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU); //initialize from new place: new_thread.SetOffset(spu_offset); new_thread.SetEntry(spu_ep); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.h b/rpcs3/Emu/SysCalls/lv2/sys_timer.h index 16739e9542..def0f16c36 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.h @@ -20,8 +20,6 @@ struct timer sys_timer_information_t timer_information_t; }; -#pragma pack() - s32 sys_timer_create(mem32_t timer_id); s32 sys_timer_destroy(u32 timer_id); s32 sys_timer_get_information(u32 timer_id, mem_ptr_t info); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.h b/rpcs3/Emu/SysCalls/lv2/sys_vm.h index c4e7d74f36..04f3688b94 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.h @@ -1,4 +1,4 @@ -#pragma pack +#pragma once #define SYS_VM_TEST_INVALID 0x0000ULL #define SYS_VM_TEST_UNUSED 0x0001ULL From ad524798fa49017a55b7c65d623742c87db0a145 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 11 Jul 2014 13:39:51 +0400 Subject: [PATCH 12/15] Compilation fix --- rpcs3/Emu/Cell/SPUThread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index cd98ac713e..b0e70f8da2 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -310,7 +310,7 @@ class SPUThread : public PPCThread public: SPU_GPR_hdr GPR[128]; //General-Purpose Register SPU_SPR_hdr SPR[128]; //Special-Purpose Registers - FPSCR FPSCR; + //FPSCR FPSCR; SPU_SNRConfig_hdr cfg; //Signal Notification Registers Configuration (OR-mode enabled: 0x1 for SNR1, 0x2 for SNR2) EventPort SPUPs[64]; // SPU Thread Event Ports From 2fe52451e1deef66a56bbd05d55b9c329cf94c7a Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 11 Jul 2014 15:32:34 +0400 Subject: [PATCH 13/15] Exceptions fixed --- rpcs3/Emu/CPU/CPUThread.cpp | 2 +- rpcs3/Emu/Memory/Memory.cpp | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index c19d8f48e2..df917d11aa 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -283,7 +283,7 @@ void CPUThread::ExecOnce() #ifdef _WIN32 void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) { - const u64 addr = (u64)Memory.GetBaseAddr() - (u64)pExp->ExceptionRecord->ExceptionAddress; + const u64 addr = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr(); if (addr < 0x100000000 && u == EXCEPTION_ACCESS_VIOLATION) { // TODO: allow recovering from a page fault diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index f6e39be85f..dc6b77e0ef 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -359,19 +359,19 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value) //MemoryBase void MemoryBase::Write8(u64 addr, const u8 data) { - *(u8*)((u64)GetBaseAddr() + addr) = data; + *(u8*)((u64)GetBaseAddr() + (u32)addr) = data; } void MemoryBase::Write16(u64 addr, const u16 data) { - *(u16*)((u64)GetBaseAddr() + addr) = re16(data); + *(u16*)((u64)GetBaseAddr() + (u32)addr) = re16(data); } void MemoryBase::Write32(u64 addr, const u32 data) { - if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || addr >= 0x100000000 || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) { - *(u32*)((u64)GetBaseAddr() + addr) = re32(data); + *(u32*)((u64)GetBaseAddr() + (u32)addr) = re32(data); } else { @@ -381,12 +381,12 @@ void MemoryBase::Write32(u64 addr, const u32 data) void MemoryBase::Write64(u64 addr, const u64 data) { - *(u64*)((u64)GetBaseAddr() + addr) = re64(data); + *(u64*)((u64)GetBaseAddr() + (u32)addr) = re64(data); } void MemoryBase::Write128(u64 addr, const u128 data) { - *(u128*)((u64)GetBaseAddr() + addr) = re128(data); + *(u128*)((u64)GetBaseAddr() + (u32)addr) = re128(data); } bool MemoryBase::Write8NN(u64 addr, const u8 data) @@ -426,19 +426,19 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data) u8 MemoryBase::Read8(u64 addr) { - return *(u8*)((u64)GetBaseAddr() + addr); + return *(u8*)((u64)GetBaseAddr() + (u32)addr); } u16 MemoryBase::Read16(u64 addr) { - return re16(*(u16*)((u64)GetBaseAddr() + addr)); + return re16(*(u16*)((u64)GetBaseAddr() + (u32)addr)); } u32 MemoryBase::Read32(u64 addr) { - if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || addr >= 0x100000000 || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) { - return re32(*(u32*)((u64)GetBaseAddr() + addr)); + return re32(*(u32*)((u64)GetBaseAddr() + (u32)addr)); } else { @@ -450,12 +450,12 @@ u32 MemoryBase::Read32(u64 addr) u64 MemoryBase::Read64(u64 addr) { - return re64(*(u64*)((u64)GetBaseAddr() + addr)); + return re64(*(u64*)((u64)GetBaseAddr() + (u32)addr)); } u128 MemoryBase::Read128(u64 addr) { - return re128(*(u128*)((u64)GetBaseAddr() + addr)); + return re128(*(u128*)((u64)GetBaseAddr() + (u32)addr)); } template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; } From 2203cb1dcf37ec6d692333195fa3d5247449b871 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 11 Jul 2014 16:22:56 +0400 Subject: [PATCH 14/15] F|_|C|< the speed, we need some checks --- rpcs3/Emu/Memory/Memory.cpp | 117 +++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 16 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index dc6b77e0ef..8faf5b3fe9 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -359,34 +359,74 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value) //MemoryBase void MemoryBase::Write8(u64 addr, const u8 data) { - *(u8*)((u64)GetBaseAddr() + (u32)addr) = data; + if ((u32)addr == addr) + { + *(u8*)((u64)GetBaseAddr() + addr) = data; + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + } } void MemoryBase::Write16(u64 addr, const u16 data) { - *(u16*)((u64)GetBaseAddr() + (u32)addr) = re16(data); + if ((u32)addr == addr) + { + *(u16*)((u64)GetBaseAddr() + addr) = re16(data); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + } } void MemoryBase::Write32(u64 addr, const u32 data) { - if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || addr >= 0x100000000 || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + if ((u32)addr == addr) { - *(u32*)((u64)GetBaseAddr() + (u32)addr) = re32(data); + if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + { + *(u32*)((u64)GetBaseAddr() + addr) = re32(data); + } + else + { + RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data); + } } else { - RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data); + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); } } void MemoryBase::Write64(u64 addr, const u64 data) { - *(u64*)((u64)GetBaseAddr() + (u32)addr) = re64(data); + if ((u32)addr == addr) + { + *(u64*)((u64)GetBaseAddr() + addr) = re64(data); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + } } void MemoryBase::Write128(u64 addr, const u128 data) { - *(u128*)((u64)GetBaseAddr() + (u32)addr) = re128(data); + if ((u32)addr == addr) + { + *(u128*)((u64)GetBaseAddr() + addr) = re128(data); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + } } bool MemoryBase::Write8NN(u64 addr, const u8 data) @@ -426,36 +466,81 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data) u8 MemoryBase::Read8(u64 addr) { - return *(u8*)((u64)GetBaseAddr() + (u32)addr); + if ((u32)addr == addr) + { + return *(u8*)((u64)GetBaseAddr() + addr); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + return 0; + } } u16 MemoryBase::Read16(u64 addr) { - return re16(*(u16*)((u64)GetBaseAddr() + (u32)addr)); + if ((u32)addr == addr) + { + return re16(*(u16*)((u64)GetBaseAddr() + addr)); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + return 0; + } } u32 MemoryBase::Read32(u64 addr) { - if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || addr >= 0x100000000 || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + if ((u32)addr == addr) { - return re32(*(u32*)((u64)GetBaseAddr() + (u32)addr)); + if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]) + { + return re32(*(u32*)((u64)GetBaseAddr() + addr)); + } + else + { + u32 res; + RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res); + return res; + } } else { - u32 res; - RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res); - return res; + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + return 0; } } u64 MemoryBase::Read64(u64 addr) { - return re64(*(u64*)((u64)GetBaseAddr() + (u32)addr)); + if ((u32)addr == addr) + { + return re64(*(u64*)((u64)GetBaseAddr() + addr)); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + return 0; + } } u128 MemoryBase::Read128(u64 addr) { - return re128(*(u128*)((u64)GetBaseAddr() + (u32)addr)); + if ((u32)addr == addr) + { + return re128(*(u128*)((u64)GetBaseAddr() + addr)); + } + else + { + LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + Emu.Pause(); + return u128::From128(0, 0); + } } template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; } From c16daed87da994ab056a0bbb022c9f9dbf32411e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 11 Jul 2014 16:50:50 +0400 Subject: [PATCH 15/15] Compilation fix --- rpcs3/Emu/Memory/Memory.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 8faf5b3fe9..dc21cc5b7b 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -365,7 +365,7 @@ void MemoryBase::Write8(u64 addr, const u8 data) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); } } @@ -378,7 +378,7 @@ void MemoryBase::Write16(u64 addr, const u16 data) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); } } @@ -398,7 +398,7 @@ void MemoryBase::Write32(u64 addr, const u32 data) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); } } @@ -411,7 +411,7 @@ void MemoryBase::Write64(u64 addr, const u64 data) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); } } @@ -424,7 +424,7 @@ void MemoryBase::Write128(u64 addr, const u128 data) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); } } @@ -472,7 +472,7 @@ u8 MemoryBase::Read8(u64 addr) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); return 0; } @@ -486,7 +486,7 @@ u16 MemoryBase::Read16(u64 addr) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); return 0; } @@ -509,7 +509,7 @@ u32 MemoryBase::Read32(u64 addr) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); return 0; } @@ -523,7 +523,7 @@ u64 MemoryBase::Read64(u64 addr) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); return 0; } @@ -537,7 +537,7 @@ u128 MemoryBase::Read128(u64 addr) } else { - LOG_ERROR(MEMORY, __FUNCTION__ "(): invalid address (0x%llx)", addr); + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr); Emu.Pause(); return u128::From128(0, 0); }