diff --git a/TODO b/TODO index 4bb80f8d53..9c77cec5b1 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ ☐ Multiple slots etc. ✔ CPU @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 ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index ff9a104b5c..690c1aa2e2 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -61,7 +61,7 @@ private: std::unique_ptr MakeJit(); Dynarmic::A32::Jit* jit = nullptr; - Memory::PageTable* current_page_table = nullptr; - std::map> jits; + std::shared_ptr current_page_table = nullptr; + std::map, std::unique_ptr> jits; std::shared_ptr interpreter_state; }; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 6fef2d4dee..968e905ac5 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -52,10 +52,10 @@ std::shared_ptr KernelSystem::GetCurrentProcess() const { void KernelSystem::SetCurrentProcess(std::shared_ptr 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 page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 0a527d8b42..c07bfdbcaf 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -214,7 +214,7 @@ public: std::shared_ptr GetCurrentProcess() const; void SetCurrentProcess(std::shared_ptr process); - void SetCurrentMemoryPageTable(Memory::PageTable* page_table); + void SetCurrentMemoryPageTable(std::shared_ptr page_table); void SetCPU(std::shared_ptr cpu); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c181bd01ad..ea3449c219 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -435,7 +435,7 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe Kernel::Process::Process(KernelSystem& 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() { // 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. handle_table.Clear(); - kernel.memory.UnregisterPageTable(&vm_manager.page_table); + kernel.memory.UnregisterPageTable(vm_manager.page_table); } std::shared_ptr KernelSystem::GetProcessById(u32 process_id) const { diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 1b9875ee2a..f1408235b2 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -37,7 +37,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { return true; } -VMManager::VMManager(Memory::MemorySystem& memory) : memory(memory) { +VMManager::VMManager(Memory::MemorySystem& memory) + : memory(memory), page_table(std::make_shared()) { Reset(); } @@ -51,7 +52,7 @@ void VMManager::Reset() { initial_vma.size = MAX_ADDRESS; vma_map.emplace(initial_vma.base, initial_vma); - page_table.Clear(); + page_table->Clear(); UpdatePageTableForVMA(initial_vma); } @@ -348,13 +349,13 @@ VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { switch (vma.type) { case VMAType::Free: - memory.UnmapRegion(page_table, vma.base, vma.size); + memory.UnmapRegion(*page_table, vma.base, vma.size); break; 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; 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; } } diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 880d9ec81f..3ca46d0691 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -209,7 +209,7 @@ public: /// Each VMManager has its own page table, which is set as the main one when the owning process /// is scheduled. - Memory::PageTable page_table; + std::shared_ptr page_table; private: using VMAIter = decltype(vma_map)::iterator; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index dd3a078043..ceb6aad4e1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -87,9 +87,9 @@ public: std::unique_ptr vram = std::make_unique(Memory::VRAM_SIZE); std::unique_ptr n3ds_extra_ram = std::make_unique(Memory::N3DS_EXTRA_RAM_SIZE); - PageTable* current_page_table = nullptr; + std::shared_ptr current_page_table = nullptr; RasterizerCacheMarker cache_marker; - std::vector page_table_list; + std::vector> page_table_list; AudioCore::DspInterface* dsp = nullptr; @@ -144,7 +144,7 @@ private: ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup - // TODO: current_page_table + ar& current_page_table; ar& fcram_mem; ar& vram_mem; ar& n3ds_extra_ram_mem; @@ -190,11 +190,11 @@ void MemorySystem::serialize(Archive& ar, const unsigned int file_version) { SERIALIZE_IMPL(MemorySystem) -void MemorySystem::SetCurrentPageTable(PageTable* page_table) { +void MemorySystem::SetCurrentPageTable(std::shared_ptr page_table) { impl->current_page_table = page_table; } -PageTable* MemorySystem::GetCurrentPageTable() const { +std::shared_ptr MemorySystem::GetCurrentPageTable() const { return impl->current_page_table; } @@ -259,11 +259,11 @@ MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) { UNREACHABLE(); } -void MemorySystem::RegisterPageTable(PageTable* page_table) { +void MemorySystem::RegisterPageTable(std::shared_ptr page_table) { impl->page_table_list.push_back(page_table); } -void MemorySystem::UnregisterPageTable(PageTable* page_table) { +void MemorySystem::UnregisterPageTable(std::shared_ptr page_table) { impl->page_table_list.erase( 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) { - 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]; 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 (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) { 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]; if (cached) { @@ -608,7 +608,7 @@ u64 MemorySystem::Read64(const VAddr addr) { void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr, 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 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, 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 page_index = dest_addr >> PAGE_BITS; 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, 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 page_index = dest_addr >> PAGE_BITS; 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, const Kernel::Process& src_process, VAddr dest_addr, VAddr src_addr, 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 page_index = src_addr >> PAGE_BITS; std::size_t page_offset = src_addr & PAGE_MASK; diff --git a/src/core/memory.h b/src/core/memory.h index 0dc98a4282..348fee3c90 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -316,8 +316,8 @@ public: void UnmapRegion(PageTable& page_table, VAddr base, u32 size); /// Currently active page table - void SetCurrentPageTable(PageTable* page_table); - PageTable* GetCurrentPageTable() const; + void SetCurrentPageTable(std::shared_ptr page_table); + std::shared_ptr GetCurrentPageTable() const; u8 Read8(VAddr addr); u16 Read16(VAddr addr); @@ -367,10 +367,10 @@ public: void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached); /// Registers page table for rasterizer cache marking - void RegisterPageTable(PageTable* page_table); + void RegisterPageTable(std::shared_ptr page_table); /// Unregisters page table for rasterizer cache marking - void UnregisterPageTable(PageTable* page_table); + void UnregisterPageTable(std::shared_ptr page_table); void SetDSP(AudioCore::DspInterface& dsp); diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 3f90482ec9..cf2ecf0d48 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -10,7 +10,7 @@ namespace ArmTests { -static Memory::PageTable* page_table = nullptr; +static std::shared_ptr page_table = nullptr; TestEnvironment::TestEnvironment(bool mutable_memory_) : mutable_memory(mutable_memory_), test_memory(std::make_shared(this)) { @@ -20,7 +20,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) kernel = std::make_unique(*memory, *timing, [] {}, 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();