Pretty sure ARM/Thread serialization works now
This commit is contained in:
parent
c983528862
commit
246ae84a52
8 changed files with 40 additions and 13 deletions
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue