mirror of
https://github.com/AlexAltea/nucleus.git
synced 2024-05-31 18:38:01 -04:00
Abstract Memory class
This commit is contained in:
parent
adddfb3294
commit
a3bca742dd
|
@ -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>();
|
||||
|
||||
|
|
|
@ -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
|
65
nucleus/memory/guest_virtual/guest_virtual_memory.h
Normal file
65
nucleus/memory/guest_virtual/guest_virtual_memory.h
Normal 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
|
70
nucleus/memory/host_virtual/host_virtual_memory.cpp
Normal file
70
nucleus/memory/host_virtual/host_virtual_memory.cpp
Normal 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
|
41
nucleus/memory/host_virtual/host_virtual_memory.h
Normal file
41
nucleus/memory/host_virtual/host_virtual_memory.h
Normal 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
11
nucleus/memory/list.h
Normal 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"
|
|
@ -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; }
|
||||
|
||||
|
|
3
nucleus/memory/memory.vcxitems.filters
Normal file
3
nucleus/memory/memory.vcxitems.filters
Normal 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>
|
Loading…
Reference in a new issue