mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
ifdefs and linux (posix) version (not tested)
This commit is contained in:
parent
d1fff053c2
commit
50b42f8593
5 changed files with 131 additions and 70 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -105,7 +105,7 @@ bool DynamicMemoryBlockBase<PT>::AllocFixed(u64 addr, u32 size)
|
|||
template<typename PT>
|
||||
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;
|
||||
|
||||
const u32 first = MemoryBlock::FixAddr(addr) >> 12;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ class MemoryBase
|
|||
{
|
||||
void* m_base_addr;
|
||||
std::vector<MemoryBlock*> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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);
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue