SPU: Fix extremely rare bug of GETLLAR (#9011)

This commit is contained in:
Eladash 2020-10-03 11:31:28 +03:00 committed by GitHub
parent bddfa76b2e
commit 493e57837b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 6 deletions

View File

@ -2179,9 +2179,15 @@ bool spu_thread::process_mfc_cmd()
std::this_thread::yield(); std::this_thread::yield();
} }
auto& dst = _ref<spu_rdata_t>(ch_mfc_cmd.lsa & 0x3ff80); alignas(64) spu_rdata_t temp;
u64 ntime; u64 ntime;
if (raddr)
{
// Save rdata from previous reservation
mov_rdata(temp, rdata);
}
for (u64 i = 0;; [&]() for (u64 i = 0;; [&]()
{ {
if (state & cpu_flag::pause) if (state & cpu_flag::pause)
@ -2216,7 +2222,7 @@ bool spu_thread::process_mfc_cmd()
continue; continue;
} }
mov_rdata(dst, data); mov_rdata(rdata, data);
if (u64 time0 = vm::reservation_acquire(addr, 128); if (u64 time0 = vm::reservation_acquire(addr, 128);
ntime != time0) ntime != time0)
@ -2226,7 +2232,7 @@ bool spu_thread::process_mfc_cmd()
continue; continue;
} }
if (g_cfg.core.spu_accurate_getllar && !cmp_rdata(dst, data)) if (g_cfg.core.spu_accurate_getllar && !cmp_rdata(rdata, data))
{ {
i += 2; i += 2;
continue; continue;
@ -2238,7 +2244,7 @@ bool spu_thread::process_mfc_cmd()
if (raddr && raddr != addr) if (raddr && raddr != addr)
{ {
// Last check for event before we replace the reservation with a new one // Last check for event before we replace the reservation with a new one
if ((vm::reservation_acquire(raddr, 128) & (-128 | vm::dma_lockb)) != rtime || !cmp_rdata(rdata, vm::_ref<spu_rdata_t>(raddr))) if ((vm::reservation_acquire(raddr, 128) & (-128 | vm::dma_lockb)) != rtime || !cmp_rdata(temp, vm::_ref<spu_rdata_t>(raddr)))
{ {
set_events(SPU_EVENT_LR); set_events(SPU_EVENT_LR);
} }
@ -2246,7 +2252,7 @@ bool spu_thread::process_mfc_cmd()
else if (raddr == addr) else if (raddr == addr)
{ {
// Lost previous reservation on polling // Lost previous reservation on polling
if (ntime != rtime || !cmp_rdata(rdata, dst)) if (ntime != rtime || !cmp_rdata(rdata, temp))
{ {
set_events(SPU_EVENT_LR); set_events(SPU_EVENT_LR);
} }
@ -2254,7 +2260,7 @@ bool spu_thread::process_mfc_cmd()
raddr = addr; raddr = addr;
rtime = ntime; rtime = ntime;
mov_rdata(rdata, dst); mov_rdata(_ref<spu_rdata_t>(ch_mfc_cmd.lsa & 0x3ff80), rdata);
ch_atomic_stat.set_value(MFC_GETLLAR_SUCCESS); ch_atomic_stat.set_value(MFC_GETLLAR_SUCCESS);
return true; return true;