From 19db12e090021bc75d44a3453e399b3dba973c71 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 7 Jul 2014 03:36:07 +0400 Subject: [PATCH] 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); };