mirror of https://github.com/RPCS3/rpcs3.git
ifdefs and linux (posix) version (not tested)
This commit is contained in:
parent
d1fff053c2
commit
50b42f8593
|
@ -280,6 +280,7 @@ void CPUThread::ExecOnce()
|
||||||
SendDbgCommand(DID_PAUSED_THREAD, this);
|
SendDbgCommand(DID_PAUSED_THREAD, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
||||||
{
|
{
|
||||||
const u64 addr = (u64)Memory.GetBaseAddr() - (u64)pExp->ExceptionRecord->ExceptionAddress;
|
const u64 addr = (u64)Memory.GetBaseAddr() - (u64)pExp->ExceptionRecord->ExceptionAddress;
|
||||||
|
@ -296,6 +297,9 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// TODO: linux version
|
||||||
|
#endif
|
||||||
|
|
||||||
void CPUThread::Task()
|
void CPUThread::Task()
|
||||||
{
|
{
|
||||||
|
@ -312,7 +316,11 @@ void CPUThread::Task()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
_set_se_translator(_se_translator);
|
_set_se_translator(_se_translator);
|
||||||
|
#else
|
||||||
|
// TODO: linux version
|
||||||
|
#endif
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,7 +105,7 @@ bool DynamicMemoryBlockBase<PT>::AllocFixed(u64 addr, u32 size)
|
||||||
template<typename PT>
|
template<typename PT>
|
||||||
void DynamicMemoryBlockBase<PT>::AppendMem(u64 addr, u32 size) /* private */
|
void DynamicMemoryBlockBase<PT>::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;
|
u8* pointer = (u8*) m_allocated.back().mem;
|
||||||
|
|
||||||
const u32 first = MemoryBlock::FixAddr(addr) >> 12;
|
const u32 first = MemoryBlock::FixAddr(addr) >> 12;
|
||||||
|
|
|
@ -8,8 +8,53 @@
|
||||||
|
|
||||||
MemoryBase Memory;
|
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::MemoryBlock() : mem_inf(nullptr)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -29,16 +74,26 @@ void MemoryBlock::Init()
|
||||||
|
|
||||||
void MemoryBlock::InitMemory()
|
void MemoryBlock::InitMemory()
|
||||||
{
|
{
|
||||||
if(!range_size) return;
|
if (!range_size) return;
|
||||||
|
|
||||||
if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT);
|
Free();
|
||||||
mem = (u8*)VirtualAlloc((void*)((u64)Memory.GetBaseAddr() + range_start), range_size, MEM_COMMIT, PAGE_READWRITE);
|
mem_inf = new MemBlockInfo(range_start, range_size);
|
||||||
memset(mem, 0, range_size);
|
mem = (u8*)mem_inf->mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryBlock::Free()
|
||||||
|
{
|
||||||
|
if (mem_inf)
|
||||||
|
{
|
||||||
|
delete mem_inf;
|
||||||
|
mem_inf = nullptr;
|
||||||
|
}
|
||||||
|
mem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryBlock::Delete()
|
void MemoryBlock::Delete()
|
||||||
{
|
{
|
||||||
if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT);
|
Free();
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class MemoryBase
|
||||||
{
|
{
|
||||||
void* m_base_addr;
|
void* m_base_addr;
|
||||||
std::vector<MemoryBlock*> MemoryBlocks;
|
std::vector<MemoryBlock*> MemoryBlocks;
|
||||||
|
u32 m_pages[0x100000000 / 4096]; // information about every page
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -35,7 +36,7 @@ public:
|
||||||
DynamicMemoryBlock MmaperMem;
|
DynamicMemoryBlock MmaperMem;
|
||||||
DynamicMemoryBlock RSXFBMem;
|
DynamicMemoryBlock RSXFBMem;
|
||||||
DynamicMemoryBlock StackMem;
|
DynamicMemoryBlock StackMem;
|
||||||
MemoryBlock* RawSPUMem[32];
|
MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET];
|
||||||
VirtualMemoryBlock RSXIOMem;
|
VirtualMemoryBlock RSXIOMem;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -70,6 +71,24 @@ public:
|
||||||
return m_base_addr;
|
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)
|
static __forceinline u16 Reverse16(const u16 val)
|
||||||
{
|
{
|
||||||
return _byteswap_ushort(val);
|
return _byteswap_ushort(val);
|
||||||
|
@ -129,7 +148,7 @@ public:
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
MemoryBlocks.push_back(raw_spu);
|
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)
|
void CloseRawSPU(MemoryBlock* raw_spu, const u32 num)
|
||||||
|
@ -144,7 +163,7 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num < 32) RawSPUMem[num] = nullptr;
|
if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(MemoryType type)
|
void Init(MemoryType type)
|
||||||
|
@ -154,21 +173,26 @@ public:
|
||||||
if(m_inited) return;
|
if(m_inited) return;
|
||||||
m_inited = true;
|
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);
|
m_base_addr = VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS);
|
||||||
if (!m_base_addr)
|
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
|
else
|
||||||
{
|
{
|
||||||
LOG_NOTICE(MEMORY, "Initing memory: m_base_addr = 0x%llx", (u64)m_base_addr);
|
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)
|
switch(type)
|
||||||
{
|
{
|
||||||
case Memory_PS3:
|
case Memory_PS3:
|
||||||
|
@ -199,52 +223,30 @@ public:
|
||||||
|
|
||||||
bool IsGoodAddr(const u64 addr)
|
bool IsGoodAddr(const u64 addr)
|
||||||
{
|
{
|
||||||
//std::lock_guard<std::mutex> lock(m_mutex);
|
if (addr >= 0x100000000 || !m_pages[addr / 4096]) // TODO: define page parameters
|
||||||
|
|
||||||
__try
|
|
||||||
{
|
|
||||||
volatile const u8 test = *GetMemFromAddr(addr);
|
|
||||||
}
|
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return true;
|
{
|
||||||
|
return true;
|
||||||
//for (auto block : MemoryBlocks)
|
}
|
||||||
//{
|
|
||||||
// if (block->IsMyAddress(addr))
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsGoodAddr(const u64 addr, const u32 size)
|
bool IsGoodAddr(const u64 addr, const u32 size)
|
||||||
{
|
{
|
||||||
//std::lock_guard<std::mutex> lock(m_mutex);
|
if (addr + size > 0x100000000)
|
||||||
|
|
||||||
__try
|
|
||||||
{
|
|
||||||
volatile const u8 test1 = *GetMemFromAddr(addr);
|
|
||||||
volatile const u8 test2 = *GetMemFromAddr(addr + size - 1);
|
|
||||||
}
|
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return true;
|
{
|
||||||
|
for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++)
|
||||||
//const u64 end = addr + size - 1;
|
{
|
||||||
//for (auto block : MemoryBlocks)
|
if (!m_pages[i]) return false; // TODO: define page parameters
|
||||||
//{
|
}
|
||||||
// if (block->IsMyAddress(addr) && block->IsMyAddress(end))
|
return true;
|
||||||
// return true;
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
//return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close()
|
void Close()
|
||||||
|
@ -256,11 +258,6 @@ public:
|
||||||
|
|
||||||
LOG_NOTICE(MEMORY, "Closing memory...");
|
LOG_NOTICE(MEMORY, "Closing memory...");
|
||||||
|
|
||||||
for (u32 i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
RawSPUMem[i] = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto block : MemoryBlocks)
|
for (auto block : MemoryBlocks)
|
||||||
{
|
{
|
||||||
block->Delete();
|
block->Delete();
|
||||||
|
@ -268,10 +265,17 @@ public:
|
||||||
|
|
||||||
MemoryBlocks.clear();
|
MemoryBlocks.clear();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
if (!VirtualFree(m_base_addr, 0, MEM_RELEASE))
|
if (!VirtualFree(m_base_addr, 0, MEM_RELEASE))
|
||||||
{
|
{
|
||||||
LOG_ERROR(MEMORY, "VirtualFree(0x%llx) failed", (u64)m_base_addr);
|
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);
|
void Write8(const u64 addr, const u8 data);
|
||||||
|
|
|
@ -22,17 +22,9 @@ struct MemBlockInfo : public MemInfo
|
||||||
{
|
{
|
||||||
void *mem;
|
void *mem;
|
||||||
|
|
||||||
MemBlockInfo(u64 _addr, u32 _size, void* base_addr)
|
MemBlockInfo(u64 _addr, u32 _size);
|
||||||
: MemInfo(_addr, PAGE_4K(_size))
|
|
||||||
, mem(VirtualAlloc((void*)((u64)base_addr + _addr), PAGE_4K(_size), MEM_COMMIT, PAGE_READWRITE))
|
void Free();
|
||||||
{
|
|
||||||
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(MemBlockInfo &other) = delete;
|
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)
|
||||||
|
@ -43,7 +35,7 @@ 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) VirtualFree(this->mem, this->size, MEM_DECOMMIT);
|
this->Free();
|
||||||
this->mem = other.mem;
|
this->mem = other.mem;
|
||||||
other.mem = nullptr;
|
other.mem = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -51,7 +43,7 @@ struct MemBlockInfo : public MemInfo
|
||||||
|
|
||||||
~MemBlockInfo()
|
~MemBlockInfo()
|
||||||
{
|
{
|
||||||
if (mem) VirtualFree(mem, size, MEM_DECOMMIT);
|
Free();
|
||||||
mem = nullptr;
|
mem = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -85,7 +77,9 @@ public:
|
||||||
virtual ~MemoryBlock();
|
virtual ~MemoryBlock();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MemBlockInfo* mem_inf;
|
||||||
void Init();
|
void Init();
|
||||||
|
void Free();
|
||||||
void InitMemory();
|
void InitMemory();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue