From ac9755306ca8482485f52d16c454826a84aa814d Mon Sep 17 00:00:00 2001 From: bamsbamx Date: Sat, 22 Jun 2019 18:21:50 +0200 Subject: [PATCH 1/4] cpu_core: Separate cpu_core and memory This makes cpu_core and memory being completely independent components inside the system, having a simpler and more understandable initialization process The thread which casues page table changes in memory will be responsible to notify the cpu_core too --- src/core/core.cpp | 1 - src/core/hle/kernel/thread.cpp | 1 + src/core/memory.cpp | 8 -------- src/core/memory.h | 3 --- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 109f937f99..2863640180 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -189,7 +189,6 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo } kernel->GetThreadManager().SetCPU(*cpu_core); - memory->SetCPU(*cpu_core); if (Settings::values.enable_dsp_lle) { dsp_core = std::make_unique(*memory, diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index e3ee705c31..e4b14417f4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -114,6 +114,7 @@ void ThreadManager::SwitchContext(Thread* new_thread) { kernel.SetCurrentProcess(SharedFrom(current_thread->owner_process)); kernel.memory.SetCurrentPageTable( ¤t_thread->owner_process->vm_manager.page_table); + cpu->PageTableChanged(); // notify the CPU the page table in memory has changed } cpu->LoadContext(new_thread->context); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 77cb7198c3..096f4c6977 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -66,22 +66,14 @@ public: RasterizerCacheMarker cache_marker; std::vector page_table_list; - ARM_Interface* cpu = nullptr; AudioCore::DspInterface* dsp = nullptr; }; MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; -void MemorySystem::SetCPU(ARM_Interface& cpu) { - impl->cpu = &cpu; -} - void MemorySystem::SetCurrentPageTable(PageTable* page_table) { impl->current_page_table = page_table; - if (impl->cpu != nullptr) { - impl->cpu->PageTableChanged(); - } } PageTable* MemorySystem::GetCurrentPageTable() const { diff --git a/src/core/memory.h b/src/core/memory.h index 019a9f7e79..6caca5a2ba 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -220,9 +220,6 @@ public: MemorySystem(); ~MemorySystem(); - /// Sets CPU to notify page table change - void SetCPU(ARM_Interface& cpu); - /** * Maps an allocated buffer onto a region of the emulated process address space. * From dbfd830695a040354f33a52c5ddcffe5d96928a7 Mon Sep 17 00:00:00 2001 From: bamsbamx Date: Wed, 26 Jun 2019 00:39:11 +0200 Subject: [PATCH 2/4] kernel: Let the kernel handle all page table changes when switching processes It will both change the page table in memory and notify the CPU about the change by itself. This way there is no need to call memory.SetCurrentPageTable() when kernel.setCurrentProcess() and the management is kept internally in the kernel --- src/core/core.cpp | 9 ++++----- src/core/core.h | 2 +- src/core/hle/kernel/kernel.cpp | 13 ++++++++++++- src/core/hle/kernel/kernel.h | 7 +++++++ src/core/hle/kernel/thread.cpp | 3 --- src/tests/core/arm/arm_test_common.cpp | 2 +- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 2863640180..a8abf9af15 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -141,7 +141,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st return ResultStatus::ErrorLoader; } } - memory->SetCurrentPageTable(&kernel->GetCurrentProcess()->vm_manager.page_table); cheat_engine = std::make_unique(*this); status = ResultStatus::Success; m_emu_window = &emu_window; @@ -179,16 +178,16 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 - cpu_core = std::make_unique(this, *memory, USER32MODE); + cpu_core = std::make_shared(this, *memory, USER32MODE); #else - cpu_core = std::make_unique(this, *memory, USER32MODE); + cpu_core = std::make_shared(this, *memory, USER32MODE); LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif } else { - cpu_core = std::make_unique(this, *memory, USER32MODE); + cpu_core = std::make_shared(this, *memory, USER32MODE); } - kernel->GetThreadManager().SetCPU(*cpu_core); + kernel->SetCPU(cpu_core); if (Settings::values.enable_dsp_lle) { dsp_core = std::make_unique(*memory, diff --git a/src/core/core.h b/src/core/core.h index 9105f0e5ee..bcc3712517 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -255,7 +255,7 @@ private: std::unique_ptr app_loader; /// ARM11 CPU core - std::unique_ptr cpu_core; + std::shared_ptr cpu_core; /// DSP core std::unique_ptr dsp_core; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 61734933b6..b048e863fe 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -47,7 +47,18 @@ std::shared_ptr KernelSystem::GetCurrentProcess() const { } void KernelSystem::SetCurrentProcess(std::shared_ptr process) { - current_process = std::move(process); + current_process = process; + SetCurrentMemPageTable(&process->vm_manager.page_table); +} + +void KernelSystem::SetCurrentMemPageTable(Memory::PageTable* page_table) { + memory.SetCurrentPageTable(page_table); + current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed +} + +void KernelSystem::SetCPU(std::shared_ptr cpu) { + current_cpu = cpu; + thread_manager->SetCPU(*cpu); } ThreadManager& KernelSystem::GetThreadManager() { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c51affac5e..a9632be42c 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -14,6 +14,7 @@ #include "common/common_types.h" #include "core/hle/kernel/memory.h" #include "core/hle/result.h" +#include "core/memory.h" namespace ConfigMem { class Handler; @@ -206,6 +207,10 @@ public: std::shared_ptr GetCurrentProcess() const; void SetCurrentProcess(std::shared_ptr process); + void SetCurrentMemPageTable(Memory::PageTable* page_table); + + void SetCPU(std::shared_ptr cpu); + ThreadManager& GetThreadManager(); const ThreadManager& GetThreadManager() const; @@ -233,6 +238,8 @@ public: /// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort std::unordered_map> named_ports; + std::shared_ptr current_cpu; + Memory::MemorySystem& memory; Core::Timing& timing; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index e4b14417f4..3b15ec35e0 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -112,9 +112,6 @@ void ThreadManager::SwitchContext(Thread* new_thread) { if (previous_process.get() != current_thread->owner_process) { kernel.SetCurrentProcess(SharedFrom(current_thread->owner_process)); - kernel.memory.SetCurrentPageTable( - ¤t_thread->owner_process->vm_manager.page_table); - cpu->PageTableChanged(); // notify the CPU the page table in memory has changed } cpu->LoadContext(new_thread->context); diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 3c8ac98784..6cb90a48f8 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -28,7 +28,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) memory->MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory); memory->MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory); - memory->SetCurrentPageTable(page_table); + kernel->SetCurrentMemPageTable(page_table); } TestEnvironment::~TestEnvironment() { From ed095f3bffc97e3a1bfa9947633a4bd471a61f4b Mon Sep 17 00:00:00 2001 From: bamsbamx Date: Wed, 26 Jun 2019 11:51:42 +0200 Subject: [PATCH 3/4] kernel: Nullability check for current_cpu when changing memory page table This attempts to fix segfault in some tests where page table is set before initializing cpu core (intended behaviour? might be worth a check...) see: src/tests/core/arm/arm_test_common.cpp see: src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp --- src/core/hle/kernel/kernel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b048e863fe..2c569355a9 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -53,7 +53,9 @@ void KernelSystem::SetCurrentProcess(std::shared_ptr process) { void KernelSystem::SetCurrentMemPageTable(Memory::PageTable* page_table) { memory.SetCurrentPageTable(page_table); - current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed + if (current_cpu != nullptr) { + current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed + } } void KernelSystem::SetCPU(std::shared_ptr cpu) { From 79b837afa7b1c1280c5818c952c3300518abf5d4 Mon Sep 17 00:00:00 2001 From: bamsbamx Date: Thu, 27 Jun 2019 16:33:55 +0200 Subject: [PATCH 4/4] kernel: Rename memory page table set function --- src/core/hle/kernel/kernel.cpp | 4 ++-- src/core/hle/kernel/kernel.h | 2 +- src/tests/core/arm/arm_test_common.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2c569355a9..f480f6362e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -48,10 +48,10 @@ std::shared_ptr KernelSystem::GetCurrentProcess() const { void KernelSystem::SetCurrentProcess(std::shared_ptr process) { current_process = process; - SetCurrentMemPageTable(&process->vm_manager.page_table); + SetCurrentMemoryPageTable(&process->vm_manager.page_table); } -void KernelSystem::SetCurrentMemPageTable(Memory::PageTable* page_table) { +void KernelSystem::SetCurrentMemoryPageTable(Memory::PageTable* 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 a9632be42c..38045a4255 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -207,7 +207,7 @@ public: std::shared_ptr GetCurrentProcess() const; void SetCurrentProcess(std::shared_ptr process); - void SetCurrentMemPageTable(Memory::PageTable* page_table); + void SetCurrentMemoryPageTable(Memory::PageTable* page_table); void SetCPU(std::shared_ptr cpu); diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 6cb90a48f8..dbbc21c8c6 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -28,7 +28,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) memory->MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory); memory->MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory); - kernel->SetCurrentMemPageTable(page_table); + kernel->SetCurrentMemoryPageTable(page_table); } TestEnvironment::~TestEnvironment() {