Pretty sure ARM/Thread serialization works now
This commit is contained in:
		| @@ -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<Memory::PageTable>& page_table) = 0; | ||||
|  | ||||
|     virtual std::shared_ptr<Memory::PageTable> 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 <class Archive> | ||||
|     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 <class Archive> | ||||
|     void load(Archive& ar, const unsigned int file_version) { | ||||
|         PurgeState(); | ||||
|         std::shared_ptr<Memory::PageTable> 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<CP15Register>(i), r); | ||||
|         } | ||||
|         ClearInstructionCache(); | ||||
|     } | ||||
|  | ||||
|     BOOST_SERIALIZATION_SPLIT_MEMBER() | ||||
|   | ||||
| @@ -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<DynarmicUserCallbacks>(*this)) { | ||||
|     interpreter_state = std::make_shared<ARMul_State>(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<Memory::PageTable> ARM_Dynarmic::GetPageTable() const { | ||||
|     return current_page_table; | ||||
| } | ||||
|  | ||||
| void ARM_Dynarmic::SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) { | ||||
|     current_page_table = page_table; | ||||
|     Dynarmic::A32::Context ctx{}; | ||||
|     if (jit) { | ||||
|         jit->SaveContext(ctx); | ||||
| @@ -309,3 +313,7 @@ std::unique_ptr<Dynarmic::A32::Jit> ARM_Dynarmic::MakeJit() { | ||||
|     config.define_unpredictable_behaviour = true; | ||||
|     return std::make_unique<Dynarmic::A32::Jit>(config); | ||||
| } | ||||
|  | ||||
| void ARM_Dynarmic::PurgeState() { | ||||
|     ClearInstructionCache(); | ||||
| } | ||||
|   | ||||
| @@ -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<Memory::PageTable>& page_table) override; | ||||
|     std::shared_ptr<Memory::PageTable> GetPageTable() const override; | ||||
|     void PurgeState() override; | ||||
|  | ||||
| private: | ||||
|     friend class DynarmicUserCallbacks; | ||||
|   | ||||
| @@ -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<Memory::PageTable>& page_table) { | ||||
|     ClearInstructionCache(); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<Memory::PageTable> ARM_DynCom::GetPageTable() const { | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
| void ARM_DynCom::PurgeState() {} | ||||
|  | ||||
| void ARM_DynCom::SetPC(u32 pc) { | ||||
|     state->Reg[15] = pc; | ||||
| } | ||||
|   | ||||
| @@ -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<ThreadContext>& arg) override; | ||||
|     void LoadContext(const std::unique_ptr<ThreadContext>& arg) override; | ||||
|  | ||||
|     void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) override; | ||||
|     std::shared_ptr<Memory::PageTable> GetPageTable() const override; | ||||
|     void PrepareReschedule() override; | ||||
|     void PurgeState() override; | ||||
|  | ||||
| private: | ||||
|     void ExecuteInstructions(u64 num_instructions); | ||||
|   | ||||
| @@ -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()); | ||||
|     } | ||||
|   | ||||
| @@ -61,7 +61,7 @@ void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> process) { | ||||
| void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr<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 | ||||
|         current_cpu->SetPageTable(page_table); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -172,7 +172,6 @@ private: | ||||
|         ar& ready_queue; | ||||
|         ar& wakeup_callback_table; | ||||
|         ar& thread_list; | ||||
|         SwitchContext(current_thread.get()); | ||||
|     } | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Hamish Milne
					Hamish Milne