diff options
Diffstat (limited to 'src/core/arm/dynarmic')
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 32 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.h | 5 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 31 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 6 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_cp15.cpp | 31 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_cp15.h | 2 |
6 files changed, 79 insertions, 28 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index b8d2ce224..1638bc41d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -11,7 +11,6 @@ #include "common/logging/log.h" #include "common/page_table.h" #include "common/settings.h" -#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_32.h" #include "core/arm/dynarmic/arm_dynarmic_cp15.h" #include "core/arm/dynarmic/arm_exclusive_monitor.h" @@ -125,7 +124,9 @@ public: } void AddTicks(u64 ticks) override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + return; + } // 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 @@ -142,7 +143,12 @@ public: } u64 GetTicksRemaining() override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + if (!IsInterrupted()) { + return minimum_run_cycles; + } + return 0U; + } return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); } @@ -168,11 +174,15 @@ public: parent.jit.load()->HaltExecution(hr); } + bool IsInterrupted() { + return parent.system.Kernel().PhysicalCore(parent.core_index).IsInterrupted(); + } + ARM_Dynarmic_32& parent; Core::Memory::Memory& memory; std::size_t num_interpreted_instructions{}; bool debugger_enabled{}; - static constexpr u64 minimum_run_cycles = 1000U; + static constexpr u64 minimum_run_cycles = 10000U; }; std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* page_table) const { @@ -200,7 +210,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* // Timing config.wall_clock_cntpct = uses_wall_clock; - config.enable_cycle_counting = !uses_wall_clock; + config.enable_cycle_counting = true; // Code cache size config.code_cache_size = 512_MiB; @@ -311,11 +321,9 @@ void ARM_Dynarmic_32::RewindBreakpointInstruction() { LoadContext(breakpoint_context); } -ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, - bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, - std::size_t core_index_) - : ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_}, - cb(std::make_unique<DynarmicCallbacks32>(*this)), +ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, + ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) + : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks32>(*this)), cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index_}, exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, null_jit{MakeJit(nullptr)}, jit{null_jit.get()} {} @@ -394,6 +402,10 @@ void ARM_Dynarmic_32::SignalInterrupt() { jit.load()->HaltExecution(break_loop); } +void ARM_Dynarmic_32::ClearInterrupt() { + jit.load()->ClearHalt(break_loop); +} + void ARM_Dynarmic_32::ClearInstructionCache() { jit.load()->ClearCache(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 346e9abf8..d24ba2289 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -28,8 +28,8 @@ class System; class ARM_Dynarmic_32 final : public ARM_Interface { public: - ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_, - ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); + ARM_Dynarmic_32(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, + std::size_t core_index_); ~ARM_Dynarmic_32() override; void SetPC(u64 pc) override; @@ -56,6 +56,7 @@ public: void LoadContext(const ThreadContext64& ctx) override {} void SignalInterrupt() override; + void ClearInterrupt() 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 1a4d37cbc..921a5a734 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -10,7 +10,6 @@ #include "common/logging/log.h" #include "common/page_table.h" #include "common/settings.h" -#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/core.h" @@ -166,7 +165,9 @@ public: } void AddTicks(u64 ticks) override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + return; + } // 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 @@ -181,7 +182,12 @@ public: } u64 GetTicksRemaining() override { - ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled"); + if (parent.uses_wall_clock) { + if (!IsInterrupted()) { + return minimum_run_cycles; + } + return 0U; + } return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); } @@ -211,12 +217,16 @@ public: parent.jit.load()->HaltExecution(hr); } + bool IsInterrupted() { + return parent.system.Kernel().PhysicalCore(parent.core_index).IsInterrupted(); + } + ARM_Dynarmic_64& parent; Core::Memory::Memory& memory; u64 tpidrro_el0 = 0; u64 tpidr_el0 = 0; bool debugger_enabled{}; - static constexpr u64 minimum_run_cycles = 1000U; + static constexpr u64 minimum_run_cycles = 10000U; }; std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* page_table, @@ -260,7 +270,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* // Timing config.wall_clock_cntpct = uses_wall_clock; - config.enable_cycle_counting = !uses_wall_clock; + config.enable_cycle_counting = true; // Code cache size config.code_cache_size = 512_MiB; @@ -371,10 +381,9 @@ void ARM_Dynarmic_64::RewindBreakpointInstruction() { LoadContext(breakpoint_context); } -ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, - bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, - std::size_t core_index_) - : ARM_Interface{system_, interrupt_handlers_, uses_wall_clock_}, +ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, + ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_) + : ARM_Interface{system_, uses_wall_clock_}, cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index_}, exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor_)}, null_jit{MakeJit(nullptr, 48)}, jit{null_jit.get()} {} @@ -461,6 +470,10 @@ void ARM_Dynarmic_64::SignalInterrupt() { jit.load()->HaltExecution(break_loop); } +void ARM_Dynarmic_64::ClearInterrupt() { + jit.load()->ClearHalt(break_loop); +} + void ARM_Dynarmic_64::ClearInstructionCache() { jit.load()->ClearCache(); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index c77a83ad7..ed1a5eb96 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -20,14 +20,13 @@ class Memory; namespace Core { class DynarmicCallbacks64; -class CPUInterruptHandler; class DynarmicExclusiveMonitor; class System; class ARM_Dynarmic_64 final : public ARM_Interface { public: - ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, bool uses_wall_clock_, - ExclusiveMonitor& exclusive_monitor_, std::size_t core_index_); + ARM_Dynarmic_64(System& system_, bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, + std::size_t core_index_); ~ARM_Dynarmic_64() override; void SetPC(u64 pc) override; @@ -50,6 +49,7 @@ public: void LoadContext(const ThreadContext64& ctx) override; void SignalInterrupt() override; + void ClearInterrupt() override; void ClearExclusiveState() override; void ClearInstructionCache() override; diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp index e9123c13d..200efe4db 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp @@ -8,6 +8,10 @@ #include "core/core.h" #include "core/core_timing.h" +#ifdef _MSC_VER +#include <intrin.h> +#endif + using Callback = Dynarmic::A32::Coprocessor::Callback; using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord; using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords; @@ -47,12 +51,31 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1 switch (opc2) { case 4: // CP15_DATA_SYNC_BARRIER - // This is a dummy write, we ignore the value written here. - return &dummy_value; + return Callback{ + [](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t { +#ifdef _MSC_VER + _mm_mfence(); + _mm_lfence(); +#else + asm volatile("mfence\n\tlfence\n\t" : : : "memory"); +#endif + return 0; + }, + std::nullopt, + }; case 5: // CP15_DATA_MEMORY_BARRIER - // This is a dummy write, we ignore the value written here. - return &dummy_value; + return Callback{ + [](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t { +#ifdef _MSC_VER + _mm_mfence(); +#else + asm volatile("mfence\n\t" : : : "memory"); +#endif + return 0; + }, + std::nullopt, + }; } } diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.h b/src/core/arm/dynarmic/arm_dynarmic_cp15.h index 5b2a51636..d90b3e568 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_cp15.h +++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.h @@ -35,6 +35,8 @@ public: ARM_Dynarmic_32& parent; u32 uprw = 0; u32 uro = 0; + + friend class ARM_Dynarmic_32; }; } // namespace Core |