Use shared_ptr for PageTable

This commit is contained in:
Hamish Milne 2020-01-05 16:35:01 +00:00 committed by zhupengfei
parent e4afa8e512
commit 96432589bd
10 changed files with 34 additions and 33 deletions

2
TODO
View file

@ -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)

View file

@ -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;
}; };

View file

@ -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

View file

@ -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);

View file

@ -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 {

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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();