diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.cpp b/src/core/arm/dynarmic/arm_exclusive_monitor.cpp index fa0c48b25f..2eb519682d 100644 --- a/src/core/arm/dynarmic/arm_exclusive_monitor.cpp +++ b/src/core/arm/dynarmic/arm_exclusive_monitor.cpp @@ -70,4 +70,55 @@ bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr v }); } +DynarmicExclusiveMonitorNoLocking::DynarmicExclusiveMonitorNoLocking(Memory::Memory& memory, + std::size_t num_cores) + : monitor{core_count_}, memory{memory_} {} + +DynarmicExclusiveMonitorNoLocking::~DynarmicExclusiveMonitorNoLocking() = default; + +u8 DynarmicExclusiveMonitorNoLocking::ExclusiveRead8(std::size_t, VAddr addr) { + return memory.Read8(addr); +} + +u16 DynarmicExclusiveMonitorNoLocking::ExclusiveRead16(std::size_t, VAddr addr) { + return memory.Read16(addr); +} + +u32 DynarmicExclusiveMonitorNoLocking::ExclusiveRead32(std::size_t, VAddr addr) { + return memory.Read32(addr); +} + +u64 DynarmicExclusiveMonitorNoLocking::ExclusiveRead64(std::size_t, VAddr addr) { + return memory.Read64(addr); +} + +u128 DynarmicExclusiveMonitorNoLocking::ExclusiveRead128(std::size_t, VAddr addr) { + u128 result; + result[0] = memory.Read64(addr); + result[1] = memory.Read64(addr + 8); + return result; +} + +void DynarmicExclusiveMonitorNoLocking::ClearExclusive(std::size_t) {} + +bool DynarmicExclusiveMonitorNoLocking::ExclusiveWrite8(std::size_t, VAddr vaddr, u8 value) { + return memory.WriteExclusive8(vaddr, value, expected); +} + +bool DynarmicExclusiveMonitorNoLocking::ExclusiveWrite16(std::size_t, VAddr vaddr, u16 value) { + return memory.WriteExclusive16(vaddr, value, expected); +} + +bool DynarmicExclusiveMonitorNoLocking::ExclusiveWrite32(std::size_t, VAddr vaddr, u32 value) { + return memory.WriteExclusive32(vaddr, value, expected); +} + +bool DynarmicExclusiveMonitorNoLocking::ExclusiveWrite64(std::size_t, VAddr vaddr, u64 value) { + return memory.WriteExclusive64(vaddr, value, expected); +} + +bool DynarmicExclusiveMonitorNoLocking::ExclusiveWrite128(std::size_t, VAddr vaddr, u128 value) { + return memory.WriteExclusive128(vaddr, value, expected); +} + } // namespace Core diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.h b/src/core/arm/dynarmic/arm_exclusive_monitor.h index 57e6dd0d0b..f297488f5b 100644 --- a/src/core/arm/dynarmic/arm_exclusive_monitor.h +++ b/src/core/arm/dynarmic/arm_exclusive_monitor.h @@ -41,4 +41,29 @@ private: Core::Memory::Memory& memory; }; +class DynarmicExclusiveMonitorNoLocking final : public ExclusiveMonitor { +public: + explicit DynarmicExclusiveMonitorNoLocking(Memory::Memory& memory, std::size_t num_cores); + ~DynarmicExclusiveMonitorNoLocking() override; + + u8 ExclusiveRead8(std::size_t core_index, VAddr addr) override; + u16 ExclusiveRead16(std::size_t core_index, VAddr addr) override; + u32 ExclusiveRead32(std::size_t core_index, VAddr addr) override; + u64 ExclusiveRead64(std::size_t core_index, VAddr addr) override; + u128 ExclusiveRead128(std::size_t core_index, VAddr addr) override; + void ClearExclusive(std::size_t core_index) override; + + bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override; + bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) override; + bool ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) override; + bool ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) override; + bool ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) override; + +private: + friend class ARM_Dynarmic_32; + friend class ARM_Dynarmic_64; + Dynarmic::ExclusiveMonitor monitor; + Core::Memory::Memory& memory; +}; + } // namespace Core diff --git a/src/core/arm/exclusive_monitor.cpp b/src/core/arm/exclusive_monitor.cpp index 20550faeb3..80e54da6ad 100644 --- a/src/core/arm/exclusive_monitor.cpp +++ b/src/core/arm/exclusive_monitor.cpp @@ -14,6 +14,12 @@ ExclusiveMonitor::~ExclusiveMonitor() = default; std::unique_ptr MakeExclusiveMonitor(Memory::Memory& memory, std::size_t num_cores) { #if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) + const bool no_locking = + Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Auto || + (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe && + Settings::values.cpuopt_unsafe_ignore_global_monitor); + if (no_locking) + return std::make_unique(memory, num_cores); return std::make_unique(memory, num_cores); #else // TODO(merry): Passthrough exclusive monitor