From f8b8af47ad9d414ce19c4801d702a6c52ae6e82e Mon Sep 17 00:00:00 2001 From: merry Date: Sun, 3 Apr 2022 16:29:05 +0100 Subject: dynarmic: Better interrupts --- src/core/arm/arm_interface.h | 3 +++ src/core/arm/dynarmic/arm_dynarmic_32.cpp | 22 +++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_32.h | 1 + src/core/arm/dynarmic/arm_dynarmic_64.cpp | 21 ++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_64.h | 1 + 5 files changed, 26 insertions(+), 22 deletions(-) (limited to 'src/core/arm') diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index c60322442..dce2f4195 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -171,6 +171,9 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; + /// Signal an interrupt and ask the core to halt as soon as possible. + virtual void SignalInterrupt() = 0; + struct BacktraceEntry { std::string module; u64 address; diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 286976623..3437eed0e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -88,9 +88,8 @@ public: } void AddTicks(u64 ticks) override { - if (parent.uses_wall_clock) { - return; - } + ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off // if not all cores are doing a similar amount of work. Instead of doing this, we should @@ -106,12 +105,8 @@ public: } u64 GetTicksRemaining() override { - if (parent.uses_wall_clock) { - if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) { - return minimum_run_cycles; - } - return 0U; - } + ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + return std::max(parent.system.CoreTiming().GetDowncount(), 0); } @@ -146,6 +141,7 @@ std::shared_ptr ARM_Dynarmic_32::MakeJit(Common::PageTable* // Timing config.wall_clock_cntpct = uses_wall_clock; + config.enable_cycle_counting = !uses_wall_clock; // Code cache size config.code_cache_size = 512_MiB; @@ -222,13 +218,13 @@ std::shared_ptr ARM_Dynarmic_32::MakeJit(Common::PageTable* void ARM_Dynarmic_32::Run() { while (true) { - jit->Run(); + const auto hr = jit->Run(); if (!svc_called) { break; } svc_called = false; Kernel::Svc::Call(system, svc_swi); - if (shutdown) { + if (shutdown || Has(hr, Dynarmic::HaltReason::UserDefined2)) { break; } } @@ -318,6 +314,10 @@ void ARM_Dynarmic_32::PrepareReschedule() { shutdown = true; } +void ARM_Dynarmic_32::SignalInterrupt() { + jit->HaltExecution(Dynarmic::HaltReason::UserDefined2); +} + void ARM_Dynarmic_32::ClearInstructionCache() { jit->ClearCache(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 5d47b600d..6712c777f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -57,6 +57,7 @@ public: void LoadContext(const ThreadContext64& ctx) override {} void PrepareReschedule() override; + void SignalInterrupt() override; void ClearExclusiveState() override; void ClearInstructionCache() override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 24107f9f6..c94b122c5 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -130,9 +130,7 @@ public: } void AddTicks(u64 ticks) override { - if (parent.uses_wall_clock) { - return; - } + ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off @@ -147,12 +145,8 @@ public: } u64 GetTicksRemaining() override { - if (parent.uses_wall_clock) { - if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) { - return minimum_run_cycles; - } - return 0U; - } + ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + return std::max(parent.system.CoreTiming().GetDowncount(), 0); } @@ -208,6 +202,7 @@ std::shared_ptr ARM_Dynarmic_64::MakeJit(Common::PageTable* // Timing config.wall_clock_cntpct = uses_wall_clock; + config.enable_cycle_counting = !uses_wall_clock; // Code cache size config.code_cache_size = 512_MiB; @@ -284,13 +279,13 @@ std::shared_ptr ARM_Dynarmic_64::MakeJit(Common::PageTable* void ARM_Dynarmic_64::Run() { while (true) { - jit->Run(); + const auto hr = jit->Run(); if (!svc_called) { break; } svc_called = false; Kernel::Svc::Call(system, svc_swi); - if (shutdown) { + if (shutdown || Has(hr, Dynarmic::HaltReason::UserDefined2)) { break; } } @@ -385,6 +380,10 @@ void ARM_Dynarmic_64::PrepareReschedule() { shutdown = true; } +void ARM_Dynarmic_64::SignalInterrupt() { + jit->HaltExecution(Dynarmic::HaltReason::UserDefined2); +} + void ARM_Dynarmic_64::ClearInstructionCache() { jit->ClearCache(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 0c4e46c64..528050db6 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -51,6 +51,7 @@ public: void LoadContext(const ThreadContext64& ctx) override; void PrepareReschedule() override; + void SignalInterrupt() override; void ClearExclusiveState() override; void ClearInstructionCache() override; -- cgit v1.2.3 From a5d040df3d98006827083d18906e36b56dbd65bb Mon Sep 17 00:00:00 2001 From: merry Date: Sun, 3 Apr 2022 18:20:11 +0100 Subject: arm_dynarmic: Use HaltReason for svc calls and reschedules --- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 19 +++++++++---------- src/core/arm/dynarmic/arm_dynarmic_32.h | 3 --- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 21 ++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_64.h | 3 --- 4 files changed, 19 insertions(+), 27 deletions(-) (limited to 'src/core/arm') diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 3437eed0e..224a30170 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -25,6 +25,9 @@ namespace Core { using namespace Common::Literals; +constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2; +constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3; + class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { public: explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) @@ -82,9 +85,8 @@ public: } void CallSVC(u32 swi) override { - parent.svc_called = true; parent.svc_swi = swi; - parent.jit->HaltExecution(); + parent.jit->HaltExecution(svc_call); } void AddTicks(u64 ticks) override { @@ -219,12 +221,10 @@ std::shared_ptr ARM_Dynarmic_32::MakeJit(Common::PageTable* void ARM_Dynarmic_32::Run() { while (true) { const auto hr = jit->Run(); - if (!svc_called) { - break; + if (Has(hr, svc_call)) { + Kernel::Svc::Call(system, svc_swi); } - svc_called = false; - Kernel::Svc::Call(system, svc_swi); - if (shutdown || Has(hr, Dynarmic::HaltReason::UserDefined2)) { + if (Has(hr, break_loop)) { break; } } @@ -310,12 +310,11 @@ void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) { } void ARM_Dynarmic_32::PrepareReschedule() { - jit->HaltExecution(); - shutdown = true; + jit->HaltExecution(break_loop); } void ARM_Dynarmic_32::SignalInterrupt() { - jit->HaltExecution(Dynarmic::HaltReason::UserDefined2); + jit->HaltExecution(break_loop); } void ARM_Dynarmic_32::ClearInstructionCache() { diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 6712c777f..3f68a4ff1 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -84,9 +84,6 @@ private: // SVC callback u32 svc_swi{}; - bool svc_called{}; - - bool shutdown{}; }; } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index c94b122c5..1966d6e56 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -26,6 +26,9 @@ namespace Core { using Vector = Dynarmic::A64::Vector; using namespace Common::Literals; +constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2; +constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3; + class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { public: explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) @@ -105,7 +108,7 @@ public: break; } - parent.jit->HaltExecution(); + parent.jit->HaltExecution(Dynarmic::HaltReason::CacheInvalidation); } void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { @@ -124,9 +127,8 @@ public: } void CallSVC(u32 swi) override { - parent.svc_called = true; parent.svc_swi = swi; - parent.jit->HaltExecution(); + parent.jit->HaltExecution(svc_call); } void AddTicks(u64 ticks) override { @@ -280,12 +282,10 @@ std::shared_ptr ARM_Dynarmic_64::MakeJit(Common::PageTable* void ARM_Dynarmic_64::Run() { while (true) { const auto hr = jit->Run(); - if (!svc_called) { - break; + if (Has(hr, svc_call)) { + Kernel::Svc::Call(system, svc_swi); } - svc_called = false; - Kernel::Svc::Call(system, svc_swi); - if (shutdown || Has(hr, Dynarmic::HaltReason::UserDefined2)) { + if (Has(hr, break_loop)) { break; } } @@ -376,12 +376,11 @@ void ARM_Dynarmic_64::LoadContext(const ThreadContext64& ctx) { } void ARM_Dynarmic_64::PrepareReschedule() { - jit->HaltExecution(); - shutdown = true; + jit->HaltExecution(break_loop); } void ARM_Dynarmic_64::SignalInterrupt() { - jit->HaltExecution(Dynarmic::HaltReason::UserDefined2); + jit->HaltExecution(break_loop); } void ARM_Dynarmic_64::ClearInstructionCache() { diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 528050db6..58bc7fbec 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -78,9 +78,6 @@ private: // SVC callback u32 svc_swi{}; - bool svc_called{}; - - bool shutdown{}; }; } // namespace Core -- cgit v1.2.3