memory Save/Restore
This commit is contained in:
parent
aa7919bd89
commit
432e32f7c2
|
@ -14,6 +14,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
@ -436,6 +437,35 @@ void Memory::DumpMap() {
|
||||||
XELOGE("");
|
XELOGE("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Memory::Save(ByteStream* stream) {
|
||||||
|
XELOGD("Serializing memory...");
|
||||||
|
heaps_.v00000000.Save(stream);
|
||||||
|
heaps_.v40000000.Save(stream);
|
||||||
|
heaps_.v80000000.Save(stream);
|
||||||
|
heaps_.v90000000.Save(stream);
|
||||||
|
heaps_.physical.Save(stream);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Memory::Restore(ByteStream* stream) {
|
||||||
|
heaps_.v00000000.Restore(stream);
|
||||||
|
heaps_.v40000000.Restore(stream);
|
||||||
|
heaps_.v80000000.Restore(stream);
|
||||||
|
heaps_.v90000000.Restore(stream);
|
||||||
|
heaps_.physical.Restore(stream);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Memory::Reset() {
|
||||||
|
heaps_.v00000000.Reset();
|
||||||
|
heaps_.v40000000.Reset();
|
||||||
|
heaps_.v80000000.Reset();
|
||||||
|
heaps_.v90000000.Reset();
|
||||||
|
heaps_.physical.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
xe::memory::PageAccess ToPageAccess(uint32_t protect) {
|
xe::memory::PageAccess ToPageAccess(uint32_t protect) {
|
||||||
if ((protect & kMemoryProtectRead) && !(protect & kMemoryProtectWrite)) {
|
if ((protect & kMemoryProtectRead) && !(protect & kMemoryProtectWrite)) {
|
||||||
return xe::memory::PageAccess::kReadOnly;
|
return xe::memory::PageAccess::kReadOnly;
|
||||||
|
@ -522,6 +552,82 @@ void BaseHeap::DumpMap() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseHeap::Save(ByteStream* stream) {
|
||||||
|
XELOGD("Heap %.8X-%.8X", heap_base_, heap_base_ + heap_size_);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < page_table_.size(); i++) {
|
||||||
|
auto& page = page_table_[i];
|
||||||
|
stream->Write(page.qword);
|
||||||
|
if (!page.state) {
|
||||||
|
// Unallocated.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Write compressed
|
||||||
|
if (page.state & kMemoryAllocationCommit &&
|
||||||
|
page.current_protect & kMemoryProtectRead) {
|
||||||
|
stream->Write((void*)(membase_ + heap_base_ + i * page_size_),
|
||||||
|
page_size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseHeap::Restore(ByteStream* stream) {
|
||||||
|
for (size_t i = 0; i < page_table_.size(); i++) {
|
||||||
|
auto& page = page_table_[i];
|
||||||
|
page.qword = stream->Read<uint64_t>();
|
||||||
|
if (!page.state) {
|
||||||
|
// Unallocated.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory::AllocationType alloc_type;
|
||||||
|
memory::PageAccess page_access = memory::PageAccess::kNoAccess;
|
||||||
|
if ((page.state & (kMemoryAllocationReserve | kMemoryAllocationCommit)) ==
|
||||||
|
3) {
|
||||||
|
alloc_type = memory::AllocationType::kReserveCommit;
|
||||||
|
} else if (page.state & kMemoryAllocationCommit) {
|
||||||
|
alloc_type = memory::AllocationType::kCommit;
|
||||||
|
} else if (page.state & kMemoryAllocationReserve) {
|
||||||
|
alloc_type = memory::AllocationType::kReserve;
|
||||||
|
}
|
||||||
|
if ((page.current_protect & (kMemoryProtectRead | kMemoryProtectWrite)) ==
|
||||||
|
3) {
|
||||||
|
page_access = memory::PageAccess::kReadWrite;
|
||||||
|
} else if (page.current_protect & kMemoryProtectRead) {
|
||||||
|
page_access = memory::PageAccess::kReadOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blah allocate on page granularity for now
|
||||||
|
if ((uint32_t)alloc_type & (uint32_t)memory::AllocationType::kCommit) {
|
||||||
|
xe::memory::AllocFixed(membase_ + heap_base_ + i * page_size_, page_size_,
|
||||||
|
alloc_type, page_access);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page.state & kMemoryAllocationCommit &&
|
||||||
|
page.current_protect & kMemoryProtectRead) {
|
||||||
|
if (!xe::memory::Protect(membase_ + heap_base_ + i * page_size_,
|
||||||
|
page_size_, page_access, nullptr)) {
|
||||||
|
assert_always();
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->Read((void*)(membase_ + heap_base_ + i * page_size_), page_size_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseHeap::Reset() {
|
||||||
|
// TODO: Protect pages
|
||||||
|
for (size_t i = 0; i < page_table_.size(); i++) {
|
||||||
|
auto& page = page_table_[i];
|
||||||
|
page.qword = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool BaseHeap::Alloc(uint32_t size, uint32_t alignment,
|
bool BaseHeap::Alloc(uint32_t size, uint32_t alignment,
|
||||||
uint32_t allocation_type, uint32_t protect, bool top_down,
|
uint32_t allocation_type, uint32_t protect, bool top_down,
|
||||||
uint32_t* out_address) {
|
uint32_t* out_address) {
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/cpu/mmio_handler.h"
|
#include "xenia/cpu/mmio_handler.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
class ByteStream;
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
enum SystemHeapFlag : uint32_t {
|
enum SystemHeapFlag : uint32_t {
|
||||||
|
@ -144,6 +148,11 @@ class BaseHeap {
|
||||||
// This is only valid if the page is backed by a physical allocation.
|
// This is only valid if the page is backed by a physical allocation.
|
||||||
uint32_t GetPhysicalAddress(uint32_t address);
|
uint32_t GetPhysicalAddress(uint32_t address);
|
||||||
|
|
||||||
|
bool Save(ByteStream* stream);
|
||||||
|
bool Restore(ByteStream* stream);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseHeap();
|
BaseHeap();
|
||||||
|
|
||||||
|
@ -320,6 +329,11 @@ class Memory {
|
||||||
// Dumps a map of all allocated memory to the log.
|
// Dumps a map of all allocated memory to the log.
|
||||||
void DumpMap();
|
void DumpMap();
|
||||||
|
|
||||||
|
bool Save(ByteStream* stream);
|
||||||
|
bool Restore(ByteStream* stream);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int MapViews(uint8_t* mapping_base);
|
int MapViews(uint8_t* mapping_base);
|
||||||
void UnmapViews();
|
void UnmapViews();
|
||||||
|
|
Loading…
Reference in New Issue