Pretty sure ARM/Thread serialization works now

This commit is contained in:
Hamish Milne 2020-01-20 21:32:38 +00:00 committed by zhupengfei
parent c983528862
commit 246ae84a52
8 changed files with 40 additions and 13 deletions

View File

@ -11,6 +11,10 @@
#include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/arm_regformat.h"
#include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h"
namespace Memory {
struct PageTable;
}
/// Generic ARM11 CPU interface /// Generic ARM11 CPU interface
class ARM_Interface : NonCopyable { class ARM_Interface : NonCopyable {
public: public:
@ -111,7 +115,9 @@ public:
virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0; virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0;
/// Notify CPU emulation that page tables have changed /// 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 * Set the Program Counter to an address
@ -214,11 +220,15 @@ public:
/// Prepare core for thread reschedule (if needed to correctly handle state) /// Prepare core for thread reschedule (if needed to correctly handle state)
virtual void PrepareReschedule() = 0; virtual void PrepareReschedule() = 0;
virtual void PurgeState() = 0;
private: private:
friend class boost::serialization::access; friend class boost::serialization::access;
template <class Archive> template <class Archive>
void save(Archive& ar, const unsigned int file_version) const { void save(Archive& ar, const unsigned int file_version) const {
auto page_table = GetPageTable();
ar << page_table;
for (auto i = 0; i < 15; i++) { for (auto i = 0; i < 15; i++) {
auto r = GetReg(i); auto r = GetReg(i);
ar << r; ar << r;
@ -243,6 +253,10 @@ private:
template <class Archive> template <class Archive>
void load(Archive& ar, const unsigned int file_version) { 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; u32 r;
for (auto i = 0; i < 15; i++) { for (auto i = 0; i < 15; i++) {
ar >> r; ar >> r;
@ -264,7 +278,6 @@ private:
ar >> r; ar >> r;
SetCP15Register(static_cast<CP15Register>(i), r); SetCP15Register(static_cast<CP15Register>(i), r);
} }
ClearInstructionCache();
} }
BOOST_SERIALIZATION_SPLIT_MEMBER() BOOST_SERIALIZATION_SPLIT_MEMBER()

View File

@ -167,7 +167,7 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory,
PrivilegeMode initial_mode) PrivilegeMode initial_mode)
: system(*system), memory(memory), cb(std::make_unique<DynarmicUserCallbacks>(*this)) { : system(*system), memory(memory), cb(std::make_unique<DynarmicUserCallbacks>(*this)) {
interpreter_state = std::make_shared<ARMul_State>(system, memory, initial_mode); interpreter_state = std::make_shared<ARMul_State>(system, memory, initial_mode);
PageTableChanged(); SetPageTable(memory.GetCurrentPageTable());
} }
ARM_Dynarmic::~ARM_Dynarmic() = default; 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); jit->InvalidateCacheRange(start_address, length);
} }
void ARM_Dynarmic::PageTableChanged() { std::shared_ptr<Memory::PageTable> ARM_Dynarmic::GetPageTable() const {
current_page_table = memory.GetCurrentPageTable(); 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{}; Dynarmic::A32::Context ctx{};
if (jit) { if (jit) {
jit->SaveContext(ctx); jit->SaveContext(ctx);
@ -309,3 +313,7 @@ std::unique_ptr<Dynarmic::A32::Jit> ARM_Dynarmic::MakeJit() {
config.define_unpredictable_behaviour = true; config.define_unpredictable_behaviour = true;
return std::make_unique<Dynarmic::A32::Jit>(config); return std::make_unique<Dynarmic::A32::Jit>(config);
} }
void ARM_Dynarmic::PurgeState() {
ClearInstructionCache();
}

View File

@ -51,7 +51,9 @@ public:
void ClearInstructionCache() override; void ClearInstructionCache() override;
void InvalidateCacheRange(u32 start_address, std::size_t length) 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: private:
friend class DynarmicUserCallbacks; friend class DynarmicUserCallbacks;

View File

@ -94,10 +94,16 @@ void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) {
ClearInstructionCache(); ClearInstructionCache();
} }
void ARM_DynCom::PageTableChanged() { void ARM_DynCom::SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) {
ClearInstructionCache(); ClearInstructionCache();
} }
std::shared_ptr<Memory::PageTable> ARM_DynCom::GetPageTable() const {
return nullptr;
}
void ARM_DynCom::PurgeState() {}
void ARM_DynCom::SetPC(u32 pc) { void ARM_DynCom::SetPC(u32 pc) {
state->Reg[15] = pc; state->Reg[15] = pc;
} }

View File

@ -29,7 +29,6 @@ public:
void ClearInstructionCache() override; void ClearInstructionCache() override;
void InvalidateCacheRange(u32 start_address, std::size_t length) override; void InvalidateCacheRange(u32 start_address, std::size_t length) override;
void PageTableChanged() override;
void SetPC(u32 pc) override; void SetPC(u32 pc) override;
u32 GetPC() const override; u32 GetPC() const override;
@ -48,7 +47,10 @@ public:
void SaveContext(const std::unique_ptr<ThreadContext>& arg) override; void SaveContext(const std::unique_ptr<ThreadContext>& arg) override;
void LoadContext(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 PrepareReschedule() override;
void PurgeState() override;
private: private:
void ExecuteInstructions(u64 num_instructions); void ExecuteInstructions(u64 num_instructions);

View File

@ -486,9 +486,6 @@ void System::Load(std::istream& stream) {
} }
VideoCore::Load(stream); VideoCore::Load(stream);
// Flush state through:
Kernel().SetCurrentProcess(Kernel().GetCurrentProcess());
} catch (const std::exception& e) { } catch (const std::exception& e) {
LOG_ERROR(Core, "Error loading: {}", e.what()); LOG_ERROR(Core, "Error loading: {}", e.what());
} }

View File

@ -61,7 +61,7 @@ void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> process) {
void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table) { void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table) {
memory.SetCurrentPageTable(page_table); memory.SetCurrentPageTable(page_table);
if (current_cpu != nullptr) { if (current_cpu != nullptr) {
current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed current_cpu->SetPageTable(page_table);
} }
} }

View File

@ -172,7 +172,6 @@ private:
ar& ready_queue; ar& ready_queue;
ar& wakeup_callback_table; ar& wakeup_callback_table;
ar& thread_list; ar& thread_list;
SwitchContext(current_thread.get());
} }
}; };