From dbfd830695a040354f33a52c5ddcffe5d96928a7 Mon Sep 17 00:00:00 2001 From: bamsbamx <anernaiz@gmail.com> Date: Wed, 26 Jun 2019 00:39:11 +0200 Subject: [PATCH] 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 286364018..a8abf9af1 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<Cheats::CheatEngine>(*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<ARM_Dynarmic>(this, *memory, USER32MODE); + cpu_core = std::make_shared<ARM_Dynarmic>(this, *memory, USER32MODE); #else - cpu_core = std::make_unique<ARM_DynCom>(this, *memory, USER32MODE); + cpu_core = std::make_shared<ARM_DynCom>(this, *memory, USER32MODE); LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif } else { - cpu_core = std::make_unique<ARM_DynCom>(this, *memory, USER32MODE); + cpu_core = std::make_shared<ARM_DynCom>(this, *memory, USER32MODE); } - kernel->GetThreadManager().SetCPU(*cpu_core); + kernel->SetCPU(cpu_core); if (Settings::values.enable_dsp_lle) { dsp_core = std::make_unique<AudioCore::DspLle>(*memory, diff --git a/src/core/core.h b/src/core/core.h index 9105f0e5e..bcc371251 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -255,7 +255,7 @@ private: std::unique_ptr<Loader::AppLoader> app_loader; /// ARM11 CPU core - std::unique_ptr<ARM_Interface> cpu_core; + std::shared_ptr<ARM_Interface> cpu_core; /// DSP core std::unique_ptr<AudioCore::DspInterface> dsp_core; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 61734933b..b048e863f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -47,7 +47,18 @@ std::shared_ptr<Process> KernelSystem::GetCurrentProcess() const { } void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> 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<ARM_Interface> 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 c51affac5..a9632be42 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<Process> GetCurrentProcess() const; void SetCurrentProcess(std::shared_ptr<Process> process); + void SetCurrentMemPageTable(Memory::PageTable* page_table); + + void SetCPU(std::shared_ptr<ARM_Interface> 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<std::string, std::shared_ptr<ClientPort>> named_ports; + std::shared_ptr<ARM_Interface> 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 e4b14417f..3b15ec35e 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 3c8ac9878..6cb90a48f 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() {