Use shared_ptr for PageTable
This commit is contained in:
parent
e4afa8e512
commit
96432589bd
2
TODO
2
TODO
|
@ -3,7 +3,7 @@
|
||||||
☐ Multiple slots etc.
|
☐ Multiple slots etc.
|
||||||
✔ CPU @done(19-08-13 15:41)
|
✔ CPU @done(19-08-13 15:41)
|
||||||
✔ Memory @done(19-08-13 15:41)
|
✔ Memory @done(19-08-13 15:41)
|
||||||
☐ Page tables
|
✔ Page tables @done(20-01-05 16:33)
|
||||||
Need to change uses to shared_ptr
|
Need to change uses to shared_ptr
|
||||||
✔ Skip N3DS RAM if unused @done(20-01-03 23:26)
|
✔ Skip N3DS RAM if unused @done(20-01-03 23:26)
|
||||||
✔ DSP @done(19-12-28 16:57)
|
✔ DSP @done(19-12-28 16:57)
|
||||||
|
|
|
@ -61,7 +61,7 @@ private:
|
||||||
std::unique_ptr<Dynarmic::A32::Jit> MakeJit();
|
std::unique_ptr<Dynarmic::A32::Jit> MakeJit();
|
||||||
|
|
||||||
Dynarmic::A32::Jit* jit = nullptr;
|
Dynarmic::A32::Jit* jit = nullptr;
|
||||||
Memory::PageTable* current_page_table = nullptr;
|
std::shared_ptr<Memory::PageTable> current_page_table = nullptr;
|
||||||
std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::A32::Jit>> jits;
|
std::map<std::shared_ptr<Memory::PageTable>, std::unique_ptr<Dynarmic::A32::Jit>> jits;
|
||||||
std::shared_ptr<ARMul_State> interpreter_state;
|
std::shared_ptr<ARMul_State> interpreter_state;
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,10 +52,10 @@ std::shared_ptr<Process> KernelSystem::GetCurrentProcess() const {
|
||||||
|
|
||||||
void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> process) {
|
void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> process) {
|
||||||
current_process = process;
|
current_process = process;
|
||||||
SetCurrentMemoryPageTable(&process->vm_manager.page_table);
|
SetCurrentMemoryPageTable(process->vm_manager.page_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelSystem::SetCurrentMemoryPageTable(Memory::PageTable* page_table) {
|
void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table) {
|
||||||
memory.SetCurrentPageTable(page_table);
|
memory.SetCurrentPageTable(page_table);
|
||||||
if (current_cpu != nullptr) {
|
if (current_cpu != nullptr) {
|
||||||
current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed
|
current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed
|
||||||
|
|
|
@ -214,7 +214,7 @@ public:
|
||||||
std::shared_ptr<Process> GetCurrentProcess() const;
|
std::shared_ptr<Process> GetCurrentProcess() const;
|
||||||
void SetCurrentProcess(std::shared_ptr<Process> process);
|
void SetCurrentProcess(std::shared_ptr<Process> process);
|
||||||
|
|
||||||
void SetCurrentMemoryPageTable(Memory::PageTable* page_table);
|
void SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table);
|
||||||
|
|
||||||
void SetCPU(std::shared_ptr<ARM_Interface> cpu);
|
void SetCPU(std::shared_ptr<ARM_Interface> cpu);
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
|
||||||
|
|
||||||
Kernel::Process::Process(KernelSystem& kernel)
|
Kernel::Process::Process(KernelSystem& kernel)
|
||||||
: Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) {
|
: Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) {
|
||||||
kernel.memory.RegisterPageTable(&vm_manager.page_table);
|
kernel.memory.RegisterPageTable(vm_manager.page_table);
|
||||||
}
|
}
|
||||||
Kernel::Process::~Process() {
|
Kernel::Process::~Process() {
|
||||||
// Release all objects this process owns first so that their potential destructor can do clean
|
// Release all objects this process owns first so that their potential destructor can do clean
|
||||||
|
@ -444,7 +444,7 @@ Kernel::Process::~Process() {
|
||||||
// memory etc.) even if they are still referenced by other processes.
|
// memory etc.) even if they are still referenced by other processes.
|
||||||
handle_table.Clear();
|
handle_table.Clear();
|
||||||
|
|
||||||
kernel.memory.UnregisterPageTable(&vm_manager.page_table);
|
kernel.memory.UnregisterPageTable(vm_manager.page_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Process> KernelSystem::GetProcessById(u32 process_id) const {
|
std::shared_ptr<Process> KernelSystem::GetProcessById(u32 process_id) const {
|
||||||
|
|
|
@ -37,7 +37,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VMManager::VMManager(Memory::MemorySystem& memory) : memory(memory) {
|
VMManager::VMManager(Memory::MemorySystem& memory)
|
||||||
|
: memory(memory), page_table(std::make_shared<Memory::PageTable>()) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ void VMManager::Reset() {
|
||||||
initial_vma.size = MAX_ADDRESS;
|
initial_vma.size = MAX_ADDRESS;
|
||||||
vma_map.emplace(initial_vma.base, initial_vma);
|
vma_map.emplace(initial_vma.base, initial_vma);
|
||||||
|
|
||||||
page_table.Clear();
|
page_table->Clear();
|
||||||
|
|
||||||
UpdatePageTableForVMA(initial_vma);
|
UpdatePageTableForVMA(initial_vma);
|
||||||
}
|
}
|
||||||
|
@ -348,13 +349,13 @@ VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) {
|
||||||
void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
|
void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
|
||||||
switch (vma.type) {
|
switch (vma.type) {
|
||||||
case VMAType::Free:
|
case VMAType::Free:
|
||||||
memory.UnmapRegion(page_table, vma.base, vma.size);
|
memory.UnmapRegion(*page_table, vma.base, vma.size);
|
||||||
break;
|
break;
|
||||||
case VMAType::BackingMemory:
|
case VMAType::BackingMemory:
|
||||||
memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory);
|
memory.MapMemoryRegion(*page_table, vma.base, vma.size, vma.backing_memory);
|
||||||
break;
|
break;
|
||||||
case VMAType::MMIO:
|
case VMAType::MMIO:
|
||||||
memory.MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler);
|
memory.MapIoRegion(*page_table, vma.base, vma.size, vma.mmio_handler);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ public:
|
||||||
|
|
||||||
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
||||||
/// is scheduled.
|
/// is scheduled.
|
||||||
Memory::PageTable page_table;
|
std::shared_ptr<Memory::PageTable> page_table;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using VMAIter = decltype(vma_map)::iterator;
|
using VMAIter = decltype(vma_map)::iterator;
|
||||||
|
|
|
@ -87,9 +87,9 @@ public:
|
||||||
std::unique_ptr<u8[]> vram = std::make_unique<u8[]>(Memory::VRAM_SIZE);
|
std::unique_ptr<u8[]> vram = std::make_unique<u8[]>(Memory::VRAM_SIZE);
|
||||||
std::unique_ptr<u8[]> n3ds_extra_ram = std::make_unique<u8[]>(Memory::N3DS_EXTRA_RAM_SIZE);
|
std::unique_ptr<u8[]> n3ds_extra_ram = std::make_unique<u8[]>(Memory::N3DS_EXTRA_RAM_SIZE);
|
||||||
|
|
||||||
PageTable* current_page_table = nullptr;
|
std::shared_ptr<PageTable> current_page_table = nullptr;
|
||||||
RasterizerCacheMarker cache_marker;
|
RasterizerCacheMarker cache_marker;
|
||||||
std::vector<PageTable*> page_table_list;
|
std::vector<std::shared_ptr<PageTable>> page_table_list;
|
||||||
|
|
||||||
AudioCore::DspInterface* dsp = nullptr;
|
AudioCore::DspInterface* dsp = nullptr;
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ private:
|
||||||
ar& cache_marker;
|
ar& cache_marker;
|
||||||
ar& page_table_list;
|
ar& page_table_list;
|
||||||
// dsp is set from Core::System at startup
|
// dsp is set from Core::System at startup
|
||||||
// TODO: current_page_table
|
ar& current_page_table;
|
||||||
ar& fcram_mem;
|
ar& fcram_mem;
|
||||||
ar& vram_mem;
|
ar& vram_mem;
|
||||||
ar& n3ds_extra_ram_mem;
|
ar& n3ds_extra_ram_mem;
|
||||||
|
@ -190,11 +190,11 @@ void MemorySystem::serialize(Archive& ar, const unsigned int file_version) {
|
||||||
|
|
||||||
SERIALIZE_IMPL(MemorySystem)
|
SERIALIZE_IMPL(MemorySystem)
|
||||||
|
|
||||||
void MemorySystem::SetCurrentPageTable(PageTable* page_table) {
|
void MemorySystem::SetCurrentPageTable(std::shared_ptr<PageTable> page_table) {
|
||||||
impl->current_page_table = page_table;
|
impl->current_page_table = page_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageTable* MemorySystem::GetCurrentPageTable() const {
|
std::shared_ptr<PageTable> MemorySystem::GetCurrentPageTable() const {
|
||||||
return impl->current_page_table;
|
return impl->current_page_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,11 +259,11 @@ MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemorySystem::RegisterPageTable(PageTable* page_table) {
|
void MemorySystem::RegisterPageTable(std::shared_ptr<PageTable> page_table) {
|
||||||
impl->page_table_list.push_back(page_table);
|
impl->page_table_list.push_back(page_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemorySystem::UnregisterPageTable(PageTable* page_table) {
|
void MemorySystem::UnregisterPageTable(std::shared_ptr<PageTable> page_table) {
|
||||||
impl->page_table_list.erase(
|
impl->page_table_list.erase(
|
||||||
std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table));
|
std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table));
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
|
bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = *process.vm_manager.page_table;
|
||||||
|
|
||||||
auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
|
auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
|
||||||
if (page_pointer)
|
if (page_pointer)
|
||||||
|
@ -486,7 +486,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached
|
||||||
for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
|
for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
|
||||||
for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) {
|
for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) {
|
||||||
impl->cache_marker.Mark(vaddr, cached);
|
impl->cache_marker.Mark(vaddr, cached);
|
||||||
for (PageTable* page_table : impl->page_table_list) {
|
for (auto page_table : impl->page_table_list) {
|
||||||
PageType& page_type = page_table->attributes[vaddr >> PAGE_BITS];
|
PageType& page_type = page_table->attributes[vaddr >> PAGE_BITS];
|
||||||
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
|
@ -608,7 +608,7 @@ u64 MemorySystem::Read64(const VAddr addr) {
|
||||||
|
|
||||||
void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr,
|
void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr,
|
||||||
void* dest_buffer, const std::size_t size) {
|
void* dest_buffer, const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = *process.vm_manager.page_table;
|
||||||
|
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = src_addr >> PAGE_BITS;
|
std::size_t page_index = src_addr >> PAGE_BITS;
|
||||||
|
@ -674,7 +674,7 @@ void MemorySystem::Write64(const VAddr addr, const u64 data) {
|
||||||
|
|
||||||
void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_addr,
|
void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_addr,
|
||||||
const void* src_buffer, const std::size_t size) {
|
const void* src_buffer, const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = *process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = dest_addr >> PAGE_BITS;
|
std::size_t page_index = dest_addr >> PAGE_BITS;
|
||||||
std::size_t page_offset = dest_addr & PAGE_MASK;
|
std::size_t page_offset = dest_addr & PAGE_MASK;
|
||||||
|
@ -722,7 +722,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a
|
||||||
|
|
||||||
void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_addr,
|
void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_addr,
|
||||||
const std::size_t size) {
|
const std::size_t size) {
|
||||||
auto& page_table = process.vm_manager.page_table;
|
auto& page_table = *process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = dest_addr >> PAGE_BITS;
|
std::size_t page_index = dest_addr >> PAGE_BITS;
|
||||||
std::size_t page_offset = dest_addr & PAGE_MASK;
|
std::size_t page_offset = dest_addr & PAGE_MASK;
|
||||||
|
@ -777,7 +777,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VA
|
||||||
void MemorySystem::CopyBlock(const Kernel::Process& dest_process,
|
void MemorySystem::CopyBlock(const Kernel::Process& dest_process,
|
||||||
const Kernel::Process& src_process, VAddr dest_addr, VAddr src_addr,
|
const Kernel::Process& src_process, VAddr dest_addr, VAddr src_addr,
|
||||||
std::size_t size) {
|
std::size_t size) {
|
||||||
auto& page_table = src_process.vm_manager.page_table;
|
auto& page_table = *src_process.vm_manager.page_table;
|
||||||
std::size_t remaining_size = size;
|
std::size_t remaining_size = size;
|
||||||
std::size_t page_index = src_addr >> PAGE_BITS;
|
std::size_t page_index = src_addr >> PAGE_BITS;
|
||||||
std::size_t page_offset = src_addr & PAGE_MASK;
|
std::size_t page_offset = src_addr & PAGE_MASK;
|
||||||
|
|
|
@ -316,8 +316,8 @@ public:
|
||||||
void UnmapRegion(PageTable& page_table, VAddr base, u32 size);
|
void UnmapRegion(PageTable& page_table, VAddr base, u32 size);
|
||||||
|
|
||||||
/// Currently active page table
|
/// Currently active page table
|
||||||
void SetCurrentPageTable(PageTable* page_table);
|
void SetCurrentPageTable(std::shared_ptr<PageTable> page_table);
|
||||||
PageTable* GetCurrentPageTable() const;
|
std::shared_ptr<PageTable> GetCurrentPageTable() const;
|
||||||
|
|
||||||
u8 Read8(VAddr addr);
|
u8 Read8(VAddr addr);
|
||||||
u16 Read16(VAddr addr);
|
u16 Read16(VAddr addr);
|
||||||
|
@ -367,10 +367,10 @@ public:
|
||||||
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached);
|
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached);
|
||||||
|
|
||||||
/// Registers page table for rasterizer cache marking
|
/// Registers page table for rasterizer cache marking
|
||||||
void RegisterPageTable(PageTable* page_table);
|
void RegisterPageTable(std::shared_ptr<PageTable> page_table);
|
||||||
|
|
||||||
/// Unregisters page table for rasterizer cache marking
|
/// Unregisters page table for rasterizer cache marking
|
||||||
void UnregisterPageTable(PageTable* page_table);
|
void UnregisterPageTable(std::shared_ptr<PageTable> page_table);
|
||||||
|
|
||||||
void SetDSP(AudioCore::DspInterface& dsp);
|
void SetDSP(AudioCore::DspInterface& dsp);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
namespace ArmTests {
|
namespace ArmTests {
|
||||||
|
|
||||||
static Memory::PageTable* page_table = nullptr;
|
static std::shared_ptr<Memory::PageTable> page_table = nullptr;
|
||||||
|
|
||||||
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
||||||
|
@ -20,7 +20,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, [] {}, 0);
|
kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, [] {}, 0);
|
||||||
|
|
||||||
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
|
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
|
||||||
page_table = &kernel->GetCurrentProcess()->vm_manager.page_table;
|
page_table = kernel->GetCurrentProcess()->vm_manager.page_table;
|
||||||
|
|
||||||
page_table->Clear();
|
page_table->Clear();
|
||||||
|
|
||||||
|
|
Reference in New Issue