diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 22443295b..6595b53c4 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -11,6 +11,10 @@ #include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/core_timing.h" +namespace Memory { +struct PageTable; +}; + /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: @@ -73,7 +77,7 @@ public: virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0; /// Notify CPU emulation that page tables have changed - virtual void PageTableChanged() = 0; + virtual void PageTableChanged(Memory::PageTable* new_page_table) = 0; /** * Set the Program Counter to an address diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 55da53b14..df5de7131 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -153,7 +153,7 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, u std::shared_ptr timer) : ARM_Interface(id, timer), system(*system), memory(memory), cb(std::make_unique(*this)) { - PageTableChanged(); + PageTableChanged(memory.GetCurrentPageTable()); } ARM_Dynarmic::~ARM_Dynarmic() = default; @@ -287,8 +287,8 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) { jit->InvalidateCacheRange(start_address, length); } -void ARM_Dynarmic::PageTableChanged() { - current_page_table = memory.GetCurrentPageTable(); +void ARM_Dynarmic::PageTableChanged(Memory::PageTable* new_page_table) { + current_page_table = new_page_table; auto iter = jits.find(current_page_table); if (iter != jits.end()) { diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index c403f438e..44f2ee375 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -52,7 +52,7 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void PageTableChanged(Memory::PageTable* new_page_table) override; private: void ServeBreak(); diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index fa1aa598d..c2c291df0 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -95,7 +95,7 @@ void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) { ClearInstructionCache(); } -void ARM_DynCom::PageTableChanged() { +void ARM_DynCom::PageTableChanged(Memory::PageTable*) { ClearInstructionCache(); } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index f5360b307..38659eac0 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -30,7 +30,7 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void PageTableChanged(Memory::PageTable* new_page_table) override; void SetPC(u32 pc) override; u32 GetPC() const override; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 995cfc658..8b2d89ead 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -67,13 +67,15 @@ void KernelSystem::SetCurrentProcessForCPU(std::shared_ptr process, u32 SetCurrentMemoryPageTable(&process->vm_manager.page_table); } else { stored_processes[core_id] = process; + thread_managers[core_id]->cpu->PageTableChanged(&process->vm_manager.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 + // Notify the CPU the page table in memory has changed + current_cpu->PageTableChanged(page_table); } } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c86a0fb86..b2255c226 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -75,11 +75,13 @@ void Thread::Stop() { void ThreadManager::SwitchContext(Thread* new_thread) { Thread* previous_thread = GetCurrentThread(); + Process* previous_process = nullptr; Core::Timing& timing = kernel.timing; // Save context for previous thread if (previous_thread) { + previous_process = previous_thread->owner_process; previous_thread->last_running_ticks = timing.GetGlobalTicks(); cpu->SaveContext(previous_thread->context); @@ -99,14 +101,12 @@ void ThreadManager::SwitchContext(Thread* new_thread) { // Cancel any outstanding wakeup events for this thread timing.UnscheduleEvent(ThreadWakeupEventType, new_thread->thread_id); - auto previous_process = kernel.GetCurrentProcess(); - current_thread = SharedFrom(new_thread); ready_queue.remove(new_thread->current_priority, new_thread); new_thread->status = ThreadStatus::Running; - if (previous_process.get() != current_thread->owner_process) { + if (previous_process != current_thread->owner_process) { kernel.SetCurrentProcessForCPU(SharedFrom(current_thread->owner_process), cpu->GetID()); }