mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
Memory allocation changes
This commit is contained in:
parent
d0b7c9a9af
commit
19db12e090
@ -11,6 +11,7 @@ using std::max;
|
|||||||
#define re64(val) MemoryBase::Reverse64(val)
|
#define re64(val) MemoryBase::Reverse64(val)
|
||||||
#define re32(val) MemoryBase::Reverse32(val)
|
#define re32(val) MemoryBase::Reverse32(val)
|
||||||
#define re16(val) MemoryBase::Reverse16(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, 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; } };
|
template<typename T> struct se_t<T, 1> { static __forceinline void func(T& dst, const T src) { (u8&)dst = (u8&)src; } };
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#include "RSXThread.h"
|
#include "RSXThread.h"
|
||||||
#include "Emu/SysCalls/lv2/sys_time.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];
|
u32 methodRegisters[0xffff];
|
||||||
|
|
||||||
@ -2474,7 +2475,9 @@ void RSXThread::Task()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ConLog.Write("addr = 0x%x", m_ioAddress + get);
|
//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;
|
const u32 count = (cmd >> 18) & 0x7ff;
|
||||||
//if(cmd == 0) continue;
|
//if(cmd == 0) continue;
|
||||||
|
|
||||||
@ -2489,7 +2492,6 @@ void RSXThread::Task()
|
|||||||
{
|
{
|
||||||
m_call_stack.push(get + 4);
|
m_call_stack.push(get + 4);
|
||||||
u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
|
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);
|
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get);
|
||||||
m_ctrl->get = offs;
|
m_ctrl->get = offs;
|
||||||
continue;
|
continue;
|
||||||
@ -2499,6 +2501,7 @@ void RSXThread::Task()
|
|||||||
//LOG_WARNING(RSX, "rsx return!");
|
//LOG_WARNING(RSX, "rsx return!");
|
||||||
u32 get = m_call_stack.top();
|
u32 get = m_call_stack.top();
|
||||||
m_call_stack.pop();
|
m_call_stack.pop();
|
||||||
|
u32 addr = Memory.RSXIOMem.GetStartAddr() + offs;
|
||||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
||||||
m_ctrl->get = get;
|
m_ctrl->get = get;
|
||||||
continue;
|
continue;
|
||||||
@ -2523,7 +2526,8 @@ void RSXThread::Task()
|
|||||||
methodRegisters[(cmd & 0xffff) + (i*4*inc)] = ARGS(i);
|
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);
|
DoCmd(cmd, cmd & 0x3ffff, args, count);
|
||||||
|
|
||||||
m_ctrl->get = get + (count + 1) * 4;
|
m_ctrl->get = get + (count + 1) * 4;
|
||||||
|
@ -31,14 +31,17 @@ void MemoryBlock::InitMemory()
|
|||||||
{
|
{
|
||||||
if(!range_size) return;
|
if(!range_size) return;
|
||||||
|
|
||||||
if(mem) safe_free(mem);
|
//if(mem) safe_free(mem);
|
||||||
mem = (u8*)malloc(range_size);
|
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);
|
memset(mem, 0, range_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryBlock::Delete()
|
void MemoryBlock::Delete()
|
||||||
{
|
{
|
||||||
if(mem) safe_free(mem);
|
//if(mem) safe_free(mem);
|
||||||
|
if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT);
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,27 +415,38 @@ bool NullMemoryBlock::Write128(const u64 addr, const u128 value)
|
|||||||
//MemoryBase
|
//MemoryBase
|
||||||
void MemoryBase::Write8(u64 addr, const u8 data)
|
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)
|
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)
|
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)
|
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)
|
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)
|
bool MemoryBase::Write8NN(u64 addr, const u8 data)
|
||||||
|
@ -15,6 +15,7 @@ enum MemoryType
|
|||||||
class MemoryBase
|
class MemoryBase
|
||||||
{
|
{
|
||||||
NullMemoryBlock NullMem;
|
NullMemoryBlock NullMem;
|
||||||
|
void* m_base_addr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<MemoryBlock*> MemoryBlocks;
|
std::vector<MemoryBlock*> MemoryBlocks;
|
||||||
@ -57,6 +58,11 @@ public:
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* GetBaseAddr() const
|
||||||
|
{
|
||||||
|
return m_base_addr;
|
||||||
|
}
|
||||||
|
|
||||||
static __forceinline u16 Reverse16(const u16 val)
|
static __forceinline u16 Reverse16(const u16 val)
|
||||||
{
|
{
|
||||||
return _byteswap_ushort(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<int size> static __forceinline u64 ReverseData(u64 val);
|
||||||
|
|
||||||
template<typename T> static __forceinline T Reverse(T val)
|
template<typename T> static __forceinline T Reverse(T val)
|
||||||
@ -117,28 +131,40 @@ public:
|
|||||||
|
|
||||||
bool Read8ByAddr(const u64 addr, u8 *value)
|
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))
|
if (block->Read8(addr, value))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NullMem.Read8(addr, value);
|
return NullMem.Read8(addr, value);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Read16ByAddr(const u64 addr, u16 *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))
|
if (block->Read16(addr, value))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NullMem.Read16(addr, value);
|
return NullMem.Read16(addr, value);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Read32ByAddr(const u64 addr, u32 *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)
|
for (auto block : MemoryBlocks)
|
||||||
{
|
{
|
||||||
if (block->Read32(addr, value))
|
if (block->Read32(addr, value))
|
||||||
@ -150,29 +176,36 @@ public:
|
|||||||
|
|
||||||
bool Read64ByAddr(const u64 addr, u64 *value)
|
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))
|
if (block->Read64(addr, value))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NullMem.Read64(addr, value);
|
return NullMem.Read64(addr, value);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Read128ByAddr(const u64 addr, u128 *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))
|
if (block->Read128(addr, value))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NullMem.Read128(addr, value);
|
return NullMem.Read128(addr, value);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* GetMemFromAddr(const u64 addr)
|
u8* GetMemFromAddr(const u64 addr)
|
||||||
{
|
{
|
||||||
return GetMemByAddr(addr).GetMemFromAddr(addr);
|
//return GetMemByAddr(addr).GetMemFromAddr(addr);
|
||||||
|
return (u8*)GetBaseAddr() + addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* VirtualToRealAddr(const u64 vaddr)
|
void* VirtualToRealAddr(const u64 vaddr)
|
||||||
@ -211,7 +244,15 @@ public:
|
|||||||
if(m_inited) return;
|
if(m_inited) return;
|
||||||
m_inited = true;
|
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)
|
switch(type)
|
||||||
{
|
{
|
||||||
@ -279,6 +320,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
MemoryBlocks.clear();
|
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);
|
void Write8(const u64 addr, const u8 data);
|
||||||
|
@ -22,13 +22,14 @@ struct MemBlockInfo : public MemInfo
|
|||||||
{
|
{
|
||||||
void *mem;
|
void *mem;
|
||||||
|
|
||||||
MemBlockInfo(u64 _addr, u32 _size)
|
MemBlockInfo(u64 _addr, u32 _size, void* base_addr)
|
||||||
: MemInfo(_addr, PAGE_4K(_size))
|
: 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)
|
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);
|
assert(0);
|
||||||
}
|
}
|
||||||
memset(mem, 0, size);
|
memset(mem, 0, size);
|
||||||
@ -43,7 +44,8 @@ struct MemBlockInfo : public MemInfo
|
|||||||
MemBlockInfo& operator =(MemBlockInfo &&other){
|
MemBlockInfo& operator =(MemBlockInfo &&other){
|
||||||
this->addr = other.addr;
|
this->addr = other.addr;
|
||||||
this->size = other.size;
|
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;
|
this->mem = other.mem;
|
||||||
other.mem = nullptr;
|
other.mem = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
@ -51,7 +53,8 @@ struct MemBlockInfo : public MemInfo
|
|||||||
|
|
||||||
~MemBlockInfo()
|
~MemBlockInfo()
|
||||||
{
|
{
|
||||||
if(mem) _aligned_free(mem);
|
//if(mem) _aligned_free(mem);
|
||||||
|
if (mem) VirtualFree(mem, size, MEM_DECOMMIT);
|
||||||
mem = nullptr;
|
mem = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -285,6 +288,13 @@ public:
|
|||||||
// return true for success
|
// return true for success
|
||||||
bool getRealAddr(u64 addr, u64& result);
|
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
|
// return the mapped address given a real address, if not mapped return 0
|
||||||
u64 getMappedAddress(u64 realAddress);
|
u64 getMappedAddress(u64 realAddress);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user