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