From 246ae84a521fa286b21beca30638f2150f52f5d9 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 20 Jan 2020 21:32:38 +0000 Subject: [PATCH] Pretty sure ARM/Thread serialization works now --- src/core/arm/arm_interface.h | 17 +++++++++++++++-- src/core/arm/dynarmic/arm_dynarmic.cpp | 14 +++++++++++--- src/core/arm/dynarmic/arm_dynarmic.h | 4 +++- src/core/arm/dyncom/arm_dyncom.cpp | 8 +++++++- src/core/arm/dyncom/arm_dyncom.h | 4 +++- src/core/core.cpp | 3 --- src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/thread.h | 1 - 8 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index e416a5f4c..8ef51519b 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -11,6 +11,10 @@ #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" +namespace Memory { +struct PageTable; +} + /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: @@ -111,7 +115,9 @@ 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 SetPageTable(const std::shared_ptr& page_table) = 0; + + virtual std::shared_ptr GetPageTable() const = 0; /** * Set the Program Counter to an address @@ -214,11 +220,15 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; + virtual void PurgeState() = 0; + private: friend class boost::serialization::access; template void save(Archive& ar, const unsigned int file_version) const { + auto page_table = GetPageTable(); + ar << page_table; for (auto i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; @@ -243,6 +253,10 @@ private: template void load(Archive& ar, const unsigned int file_version) { + PurgeState(); + std::shared_ptr page_table = nullptr; + ar >> page_table; + SetPageTable(page_table); u32 r; for (auto i = 0; i < 15; i++) { ar >> r; @@ -264,7 +278,6 @@ private: ar >> r; SetCP15Register(static_cast(i), r); } - ClearInstructionCache(); } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index b6494d40e..33bc03a4f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -167,7 +167,7 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, PrivilegeMode initial_mode) : system(*system), memory(memory), cb(std::make_unique(*this)) { interpreter_state = std::make_shared(system, memory, initial_mode); - PageTableChanged(); + SetPageTable(memory.GetCurrentPageTable()); } ARM_Dynarmic::~ARM_Dynarmic() = default; @@ -281,8 +281,12 @@ 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(); +std::shared_ptr ARM_Dynarmic::GetPageTable() const { + return current_page_table; +} + +void ARM_Dynarmic::SetPageTable(const std::shared_ptr& page_table) { + current_page_table = page_table; Dynarmic::A32::Context ctx{}; if (jit) { jit->SaveContext(ctx); @@ -309,3 +313,7 @@ std::unique_ptr ARM_Dynarmic::MakeJit() { config.define_unpredictable_behaviour = true; return std::make_unique(config); } + +void ARM_Dynarmic::PurgeState() { + ClearInstructionCache(); +} diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 690c1aa2e..c4d01835d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -51,7 +51,9 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void SetPageTable(const std::shared_ptr& page_table) override; + std::shared_ptr GetPageTable() const override; + void PurgeState() override; private: friend class DynarmicUserCallbacks; diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 6b67644e7..c069b428e 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -94,10 +94,16 @@ void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) { ClearInstructionCache(); } -void ARM_DynCom::PageTableChanged() { +void ARM_DynCom::SetPageTable(const std::shared_ptr& page_table) { ClearInstructionCache(); } +std::shared_ptr ARM_DynCom::GetPageTable() const { + return nullptr; +} + +void ARM_DynCom::PurgeState() {} + void ARM_DynCom::SetPC(u32 pc) { state->Reg[15] = pc; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 7497b765f..39d55a62a 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -29,7 +29,6 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; void SetPC(u32 pc) override; u32 GetPC() const override; @@ -48,7 +47,10 @@ public: void SaveContext(const std::unique_ptr& arg) override; void LoadContext(const std::unique_ptr& arg) override; + void SetPageTable(const std::shared_ptr& page_table) override; + std::shared_ptr GetPageTable() const override; void PrepareReschedule() override; + void PurgeState() override; private: void ExecuteInstructions(u64 num_instructions); diff --git a/src/core/core.cpp b/src/core/core.cpp index 03b64b04e..18c2e77e1 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -486,9 +486,6 @@ void System::Load(std::istream& stream) { } VideoCore::Load(stream); - // Flush state through: - Kernel().SetCurrentProcess(Kernel().GetCurrentProcess()); - } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 3c3dfc6c6..ea3da508e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -61,7 +61,7 @@ void KernelSystem::SetCurrentProcess(std::shared_ptr process) { void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { - current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed + current_cpu->SetPageTable(page_table); } } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0286e210d..c64e24071 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -172,7 +172,6 @@ private: ar& ready_queue; ar& wakeup_callback_table; ar& thread_list; - SwitchContext(current_thread.get()); } };