Abstract Memory class

This commit is contained in:
Alexandro Sánchez Bach 2016-04-12 00:26:01 +02:00
parent adddfb3294
commit a3bca742dd
10 changed files with 216 additions and 27 deletions

View file

@ -14,7 +14,7 @@
#include "nucleus/gpu/list.h"
#include "nucleus/filesystem/utils.h"
#include "nucleus/logger/logger.h"
#include "nucleus/memory/memory.h"
#include "nucleus/memory/list.h"
#include "nucleus/system/loader.h"
#include "nucleus/system/scei/self.h"
#include "nucleus/system/list.h"
@ -27,7 +27,7 @@ Emulator nucleus;
*/
bool Emulator::load_ps3(const std::string& path) {
// Initialize hardware
memory = std::make_shared<mem::Memory>();
memory = std::make_shared<mem::GuestVirtualMemory>(4_GB);
cpu = std::make_shared<cpu::Cell>(memory);
gpu = std::make_shared<gpu::RSX>(memory, graphics);
sys = std::make_shared<sys::LV2>(memory, sys::LV2_DEX);
@ -57,6 +57,7 @@ bool Emulator::load_ps3(const std::string& path) {
bool Emulator::load_ps4(const std::string& path) {
// Initialize hardware
memory = std::make_shared<mem::HostVirtualMemory>();
gpu = std::make_shared<gpu::R10XX>(graphics);
sys = std::make_shared<sys::OrbisOS>();

View file

@ -3,8 +3,7 @@
* Released under GPL v2 license. Read LICENSE for more details.
*/
#include "memory.h"
#include "nucleus/common.h"
#include "guest_virtual_memory.h"
#include "nucleus/logger/logger.h"
#ifdef NUCLEUS_TARGET_WINDOWS
@ -20,14 +19,14 @@
namespace mem {
Memory::Memory() {
GuestVirtualMemory::GuestVirtualMemory(Size amount) {
// Reserve 4 GB of memory for any 32-bit pointer in the PS3 memory
#if defined(NUCLEUS_TARGET_UWP)
m_base = nullptr;
#elif defined(NUCLEUS_TARGET_WINDOWS)
m_base = VirtualAlloc(nullptr, 0x100000000ULL, MEM_RESERVE, PAGE_NOACCESS);
m_base = VirtualAlloc(nullptr, amount, MEM_RESERVE, PAGE_NOACCESS);
#elif defined(NUCLEUS_TARGET_LINUX) || defined(NUCLEUS_TARGET_OSX)
m_base = ::mmap(nullptr, 0x100000000ULL, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
m_base = ::mmap(nullptr, amount, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
#endif
// Check errors

View file

@ -0,0 +1,65 @@
/**
* (c) 2014-2016 Alexandro Sanchez Bach. All rights reserved.
* Released under GPL v2 license. Read LICENSE for more details.
*/
#pragma once
#include "nucleus/common.h"
#include "nucleus/memory/guest_virtual/guest_virtual_segment.h"
namespace mem {
enum {
// Memory segments
SEG_MAIN_MEMORY = 0, // 0x00010000 to 0x2FFFFFFF
SEG_USER_MEMORY, // 0x10000000 to 0x1FFFFFFF
SEG_RSX_MAP_MEMORY, // 0x40000000 to 0x4FFFFFFF
SEG_MMAPPER_MEMORY, // 0xB0000000 to 0xBFFFFFFF
SEG_RSX_LOCAL_MEMORY, // 0xC0000000 to 0xCFFFFFFF
SEG_STACK, // 0xD0000000 to 0xDFFFFFFF
// Count of memory segments
_SEG_COUNT,
};
class GuestVirtualMemory : public Memory {
void* m_base;
Segment m_segments[_SEG_COUNT];
public:
GuestVirtualMemory(Size amount);
~GuestVirtualMemory();
U32 alloc(U32 size, U32 align=1);
void free(U32 addr);
bool check(U32 addr);
U08 read8(U32 addr);
U16 read16(U32 addr);
U32 read32(U32 addr);
U64 read64(U32 addr);
U128 read128(U32 addr);
void readLeft(U08* dst, U32 src, U32 size);
void readRight(U08* dst, U32 src, U32 size);
void write8(U32 addr, U08 value);
void write16(U32 addr, U16 value);
void write32(U32 addr, U32 value);
void write64(U32 addr, U64 value);
void write128(U32 addr, U128 value);
void writeLeft(U32 dst, U08* src, U32 size);
void writeRight(U32 dst, U08* src, U32 size);
void* getBaseAddr() { return m_base; }
Segment& getSegment(size_t id) { return m_segments[id]; }
template <typename T>
T& ref(U32 addr) { return *(T*)((U64)m_base + addr); }
template <typename T=void>
T* ptr(U32 addr) { return (T*)((U64)m_base + addr); }
};
} // namespace mem

View file

@ -0,0 +1,70 @@
/**
* (c) 2014-2016 Alexandro Sanchez Bach. All rights reserved.
* Released under GPL v2 license. Read LICENSE for more details.
*/
#include "host_virtual_memory.h"
#include "nucleus/logger/logger.h"
#include <malloc.h>
namespace mem {
HostVirtualMemory::HostVirtualMemory() {
}
HostVirtualMemory::~HostVirtualMemory() {
}
U64 HostVirtualMemory::alloc(U64 size, U32 alignment) {
#ifdef NUCLEUS_COMPILER_MSVC
void* address = _aligned_malloc(size, alignment);
#else
void* address = memalign(size, alignment);
#endif
return reinterpret_cast<U64>(address);
}
void HostVirtualMemory::free(U64 addr) {
void* address = reinterpret_cast<void*>(addr);
::free(address);
}
bool HostVirtualMemory::check(U64 addr) {
return (addr != 0);
}
// Memory reads
U08 HostVirtualMemory::read8(U64 addr) {
return *reinterpret_cast<U08*>(addr);
}
U16 HostVirtualMemory::read16(U64 addr) {
return *reinterpret_cast<U16*>(addr);
}
U32 HostVirtualMemory::read32(U64 addr) {
return *reinterpret_cast<U32*>(addr);
}
U64 HostVirtualMemory::read64(U64 addr) {
return *reinterpret_cast<U64*>(addr);
}
U128 HostVirtualMemory::read128(U64 addr) {
return *reinterpret_cast<U128*>(addr);
}
// Memory writes
void HostVirtualMemory::write8(U64 addr, U08 value) {
*reinterpret_cast<U08*>(addr) = value;
}
void HostVirtualMemory::write16(U64 addr, U16 value) {
*reinterpret_cast<U16*>(addr) = value;
}
void HostVirtualMemory::write32(U64 addr, U32 value) {
*reinterpret_cast<U32*>(addr) = value;
}
void HostVirtualMemory::write64(U64 addr, U64 value) {
*reinterpret_cast<U64*>(addr) = value;
}
void HostVirtualMemory::write128(U64 addr, U128 value) {
*reinterpret_cast<U128*>(addr) = value;
}
} // namespace mem

View file

@ -0,0 +1,41 @@
/**
* (c) 2014-2016 Alexandro Sanchez Bach. All rights reserved.
* Released under GPL v2 license. Read LICENSE for more details.
*/
#pragma once
#include "nucleus/common.h"
#include "nucleus/memory/memory.h"
namespace mem {
class HostVirtualMemory : public Memory {
public:
HostVirtualMemory();
~HostVirtualMemory();
virtual U64 alloc(U64 size, U32 align=1) override;
virtual void free(U64 addr) override;
virtual bool check(U64 addr) override;
virtual U08 read8(U64 addr) override;
virtual U16 read16(U64 addr) override;
virtual U32 read32(U64 addr) override;
virtual U64 read64(U64 addr) override;
virtual U128 read128(U64 addr) override;
virtual void write8(U64 addr, U08 value) override;
virtual void write16(U64 addr, U16 value) override;
virtual void write32(U64 addr, U32 value) override;
virtual void write64(U64 addr, U64 value) override;
virtual void write128(U64 addr, U128 value) override;
virtual void memcpy_h2h(void* destination, const void* source, Size num) override;
virtual void memcpy_h2g(U64 destination, const void* source, Size num) override;
virtual void memcpy_g2h(void* destination, U64 source, Size num) override;
virtual void memcpy_g2g(U64 destination, U64 source, Size num) override;
virtual void memset(U64 ptr, int value, Size num) override;
};
} // namespace mem

11
nucleus/memory/list.h Normal file
View file

@ -0,0 +1,11 @@
/**
* (c) 2014-2016 Alexandro Sanchez Bach. All rights reserved.
* Released under GPL v2 license. Read LICENSE for more details.
*/
#pragma once
#include "nucleus/common.h"
#include "nucleus/memory/guest_virtual/guest_virtual_memory.h"
#include "nucleus/memory/host_virtual/host_virtual_memory.h"

View file

@ -24,32 +24,31 @@ enum {
};
class Memory {
void* m_base;
Segment m_segments[_SEG_COUNT];
public:
Memory();
~Memory();
U32 alloc(U32 size, U32 align=1);
void free(U32 addr);
bool check(U32 addr);
virtual U64 alloc(U64 size, U32 align=1) = 0;
virtual void free(U64 addr) = 0;
virtual bool check(U64 addr) = 0;
U08 read8(U32 addr);
U16 read16(U32 addr);
U32 read32(U32 addr);
U64 read64(U32 addr);
U128 read128(U32 addr);
void readLeft(U08* dst, U32 src, U32 size);
void readRight(U08* dst, U32 src, U32 size);
virtual U08 read8(U64 addr) = 0;
virtual U16 read16(U64 addr) = 0;
virtual U32 read32(U64 addr) = 0;
virtual U64 read64(U64 addr) = 0;
virtual U128 read128(U64 addr) = 0;
void write8(U32 addr, U08 value);
void write16(U32 addr, U16 value);
void write32(U32 addr, U32 value);
void write64(U32 addr, U64 value);
void write128(U32 addr, U128 value);
void writeLeft(U32 dst, U08* src, U32 size);
void writeRight(U32 dst, U08* src, U32 size);
virtual void write8(U64 addr, U08 value) = 0;
virtual void write16(U64 addr, U16 value) = 0;
virtual void write32(U64 addr, U32 value) = 0;
virtual void write64(U64 addr, U64 value) = 0;
virtual void write128(U64 addr, U128 value) = 0;
virtual void memcpy_h2h(void* destination, const void* source, Size num) = 0;
virtual void memcpy_h2g(U64 destination, const void* source, Size num) = 0;
virtual void memcpy_g2h(void* destination, U64 source, Size num) = 0;
virtual void memcpy_g2g(U64 destination, U64 source, Size num) = 0;
virtual void memset(U64 ptr, int value, Size num) = 0;
void* getBaseAddr() { return m_base; }

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>