summaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-03-07 18:59:42 -0400
committerGravatar Fernando Sahmkow2020-06-27 11:35:37 -0400
commitcd1c38be8d15d3caf52f566a9e8dc20504c61068 (patch)
tree2fed02ffd4f2151dfca14ddb33ef1939eaee2fba /src/core/arm
parentSVC: WaitSynchronization add Termination Pending Result. (diff)
downloadyuzu-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.cpp66
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h6
-rw-r--r--src/core/arm/exclusive_monitor.h6
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
285DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; 301DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
286 302
287void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) { 303void 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
307void DynarmicExclusiveMonitor::SetExclusive16(std::size_t core_index, VAddr addr) {
308 monitor.Mark<u16>(core_index, addr, 2, [&]() -> u16 { return memory.Read16(addr); });
309}
310
311void DynarmicExclusiveMonitor::SetExclusive32(std::size_t core_index, VAddr addr) {
312 monitor.Mark<u32>(core_index, addr, 4, [&]() -> u32 { return memory.Read32(addr); });
313}
314
315void DynarmicExclusiveMonitor::SetExclusive64(std::size_t core_index, VAddr addr) {
316 monitor.Mark<u64>(core_index, addr, 8, [&]() -> u64 { return memory.Read64(addr); });
317}
318
319void 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
292void DynarmicExclusiveMonitor::ClearExclusive() { 328void DynarmicExclusiveMonitor::ClearExclusive() {
@@ -294,28 +330,32 @@ void DynarmicExclusiveMonitor::ClearExclusive() {
294} 330}
295 331
296bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { 332bool 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
300bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { 338bool 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
305bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { 344bool 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
310bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { 350bool 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
315bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { 356bool 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 {
18public: 18public:
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;