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 109f937f9..286364018 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 e3ee705c3..e4b14417f 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 77cb7198c..096f4c697 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 019a9f7e7..6caca5a2b 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 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(*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 9105f0e5e..bcc371251 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 61734933b..b048e863f 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 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 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 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() { 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 b048e863f..2c569355a 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 2c569355a..f480f6362 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 a9632be42..38045a425 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 6cb90a48f..dbbc21c8c 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() {