diff options
| author | 2020-03-07 18:59:42 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:37 -0400 | |
| commit | cd1c38be8d15d3caf52f566a9e8dc20504c61068 (patch) | |
| tree | 2fed02ffd4f2151dfca14ddb33ef1939eaee2fba /src/core/arm | |
| parent | SVC: WaitSynchronization add Termination Pending Result. (diff) | |
| download | yuzu-cd1c38be8d15d3caf52f566a9e8dc20504c61068.tar.gz yuzu-cd1c38be8d15d3caf52f566a9e8dc20504c61068.tar.xz yuzu-cd1c38be8d15d3caf52f566a9e8dc20504c61068.zip | |
ARM/Memory: Correct Exclusive Monitor and Implement Exclusive Memory Writes.
Diffstat (limited to 'src/core/arm')
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 66 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 6 | ||||
| -rw-r--r-- | src/core/arm/exclusive_monitor.h | 6 |
3 files changed, 63 insertions, 15 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 5e316ffd4..a22c22bf0 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -66,6 +66,22 @@ public: | |||
| 66 | memory.Write64(vaddr + 8, value[1]); | 66 | memory.Write64(vaddr + 8, value[1]); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | bool MemoryWriteExclusive8(u64 vaddr, std::uint8_t value, std::uint8_t expected) override { | ||
| 70 | return parent.system.Memory().WriteExclusive8(vaddr, value, expected); | ||
| 71 | } | ||
| 72 | bool MemoryWriteExclusive16(u64 vaddr, std::uint16_t value, std::uint16_t expected) override { | ||
| 73 | return parent.system.Memory().WriteExclusive16(vaddr, value, expected); | ||
| 74 | } | ||
| 75 | bool MemoryWriteExclusive32(u64 vaddr, std::uint32_t value, std::uint32_t expected) override { | ||
| 76 | return parent.system.Memory().WriteExclusive32(vaddr, value, expected); | ||
| 77 | } | ||
| 78 | bool MemoryWriteExclusive64(u64 vaddr, std::uint64_t value, std::uint64_t expected) override { | ||
| 79 | return parent.system.Memory().WriteExclusive64(vaddr, value, expected); | ||
| 80 | } | ||
| 81 | bool MemoryWriteExclusive128(u64 vaddr, Vector value, Vector expected) override { | ||
| 82 | return parent.system.Memory().WriteExclusive128(vaddr, value, expected); | ||
| 83 | } | ||
| 84 | |||
| 69 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { | 85 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { |
| 70 | LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, | 86 | LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, |
| 71 | num_instructions, MemoryReadCode(pc)); | 87 | num_instructions, MemoryReadCode(pc)); |
| @@ -284,9 +300,29 @@ DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory, std:: | |||
| 284 | 300 | ||
| 285 | DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; | 301 | DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; |
| 286 | 302 | ||
| 287 | void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) { | 303 | void DynarmicExclusiveMonitor::SetExclusive8(std::size_t core_index, VAddr addr) { |
| 288 | // Size doesn't actually matter. | 304 | monitor.Mark<u8>(core_index, addr, 1, [&]() -> u8 { return memory.Read8(addr); }); |
| 289 | monitor.Mark(core_index, addr, 16); | 305 | } |
| 306 | |||
| 307 | void DynarmicExclusiveMonitor::SetExclusive16(std::size_t core_index, VAddr addr) { | ||
| 308 | monitor.Mark<u16>(core_index, addr, 2, [&]() -> u16 { return memory.Read16(addr); }); | ||
| 309 | } | ||
| 310 | |||
| 311 | void DynarmicExclusiveMonitor::SetExclusive32(std::size_t core_index, VAddr addr) { | ||
| 312 | monitor.Mark<u32>(core_index, addr, 4, [&]() -> u32 { return memory.Read32(addr); }); | ||
| 313 | } | ||
| 314 | |||
| 315 | void DynarmicExclusiveMonitor::SetExclusive64(std::size_t core_index, VAddr addr) { | ||
| 316 | monitor.Mark<u64>(core_index, addr, 8, [&]() -> u64 { return memory.Read64(addr); }); | ||
| 317 | } | ||
| 318 | |||
| 319 | void DynarmicExclusiveMonitor::SetExclusive128(std::size_t core_index, VAddr addr) { | ||
| 320 | monitor.Mark<u128>(core_index, addr, 16, [&]() -> u128 { | ||
| 321 | u128 result; | ||
| 322 | result[0] = memory.Read64(addr); | ||
| 323 | result[1] = memory.Read64(addr + 8); | ||
| 324 | return result; | ||
| 325 | }); | ||
| 290 | } | 326 | } |
| 291 | 327 | ||
| 292 | void DynarmicExclusiveMonitor::ClearExclusive() { | 328 | void DynarmicExclusiveMonitor::ClearExclusive() { |
| @@ -294,28 +330,32 @@ void DynarmicExclusiveMonitor::ClearExclusive() { | |||
| 294 | } | 330 | } |
| 295 | 331 | ||
| 296 | bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { | 332 | bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { |
| 297 | return monitor.DoExclusiveOperation(core_index, vaddr, 1, [&] { memory.Write8(vaddr, value); }); | 333 | return monitor.DoExclusiveOperation<u8>(core_index, vaddr, 1, [&](u8 expected) -> bool { |
| 334 | return memory.WriteExclusive8(vaddr, value, expected); | ||
| 335 | }); | ||
| 298 | } | 336 | } |
| 299 | 337 | ||
| 300 | bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { | 338 | bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { |
| 301 | return monitor.DoExclusiveOperation(core_index, vaddr, 2, | 339 | return monitor.DoExclusiveOperation<u16>(core_index, vaddr, 2, [&](u16 expected) -> bool { |
| 302 | [&] { memory.Write16(vaddr, value); }); | 340 | return memory.WriteExclusive16(vaddr, value, expected); |
| 341 | }); | ||
| 303 | } | 342 | } |
| 304 | 343 | ||
| 305 | bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { | 344 | bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { |
| 306 | return monitor.DoExclusiveOperation(core_index, vaddr, 4, | 345 | return monitor.DoExclusiveOperation<u32>(core_index, vaddr, 4, [&](u32 expected) -> bool { |
| 307 | [&] { memory.Write32(vaddr, value); }); | 346 | return memory.WriteExclusive32(vaddr, value, expected); |
| 347 | }); | ||
| 308 | } | 348 | } |
| 309 | 349 | ||
| 310 | bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { | 350 | bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { |
| 311 | return monitor.DoExclusiveOperation(core_index, vaddr, 8, | 351 | return monitor.DoExclusiveOperation<u64>(core_index, vaddr, 8, [&](u64 expected) -> bool { |
| 312 | [&] { memory.Write64(vaddr, value); }); | 352 | return memory.WriteExclusive64(vaddr, value, expected); |
| 353 | }); | ||
| 313 | } | 354 | } |
| 314 | 355 | ||
| 315 | bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { | 356 | bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { |
| 316 | return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] { | 357 | return monitor.DoExclusiveOperation<u128>(core_index, vaddr, 16, [&](u128 expected) -> bool { |
| 317 | memory.Write64(vaddr + 0, value[0]); | 358 | return memory.WriteExclusive128(vaddr, value, expected); |
| 318 | memory.Write64(vaddr + 8, value[1]); | ||
| 319 | }); | 359 | }); |
| 320 | } | 360 | } |
| 321 | 361 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 9e94b58c2..3ead59f16 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h | |||
| @@ -82,7 +82,11 @@ public: | |||
| 82 | explicit DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count); | 82 | explicit DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count); |
| 83 | ~DynarmicExclusiveMonitor() override; | 83 | ~DynarmicExclusiveMonitor() override; |
| 84 | 84 | ||
| 85 | void SetExclusive(std::size_t core_index, VAddr addr) override; | 85 | void SetExclusive8(std::size_t core_index, VAddr addr) override; |
| 86 | void SetExclusive16(std::size_t core_index, VAddr addr) override; | ||
| 87 | void SetExclusive32(std::size_t core_index, VAddr addr) override; | ||
| 88 | void SetExclusive64(std::size_t core_index, VAddr addr) override; | ||
| 89 | void SetExclusive128(std::size_t core_index, VAddr addr) override; | ||
| 86 | void ClearExclusive() override; | 90 | void ClearExclusive() override; |
| 87 | 91 | ||
| 88 | bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override; | 92 | bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override; |
diff --git a/src/core/arm/exclusive_monitor.h b/src/core/arm/exclusive_monitor.h index ccd73b80f..2ee312eee 100644 --- a/src/core/arm/exclusive_monitor.h +++ b/src/core/arm/exclusive_monitor.h | |||
| @@ -18,7 +18,11 @@ class ExclusiveMonitor { | |||
| 18 | public: | 18 | public: |
| 19 | virtual ~ExclusiveMonitor(); | 19 | virtual ~ExclusiveMonitor(); |
| 20 | 20 | ||
| 21 | virtual void SetExclusive(std::size_t core_index, VAddr addr) = 0; | 21 | virtual void SetExclusive8(std::size_t core_index, VAddr addr) = 0; |
| 22 | virtual void SetExclusive16(std::size_t core_index, VAddr addr) = 0; | ||
| 23 | virtual void SetExclusive32(std::size_t core_index, VAddr addr) = 0; | ||
| 24 | virtual void SetExclusive64(std::size_t core_index, VAddr addr) = 0; | ||
| 25 | virtual void SetExclusive128(std::size_t core_index, VAddr addr) = 0; | ||
| 22 | virtual void ClearExclusive() = 0; | 26 | virtual void ClearExclusive() = 0; |
| 23 | 27 | ||
| 24 | virtual bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) = 0; | 28 | virtual bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) = 0; |