Memory allocation changes

This commit is contained in:
Nekotekina 2014-07-07 03:36:07 +04:00
parent d0b7c9a9af
commit 19db12e090
5 changed files with 102 additions and 27 deletions

View File

@ -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<typename T, int size = sizeof(T)> struct se_t;
template<typename T> struct se_t<T, 1> { static __forceinline void func(T& dst, const T src) { (u8&)dst = (u8&)src; } };

View File

@ -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;

View File

@ -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)

View File

@ -15,6 +15,7 @@ enum MemoryType
class MemoryBase
{
NullMemoryBlock NullMem;
void* m_base_addr;
public:
std::vector<MemoryBlock*> 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<int size> static __forceinline u64 ReverseData(u64 val);
template<typename T> 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);

View File

@ -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);
};