mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-24 09:39:55 +00:00
SPU: Validate reservation in GET commands (Accurate DMA) (#9062)
This commit is contained in:
parent
5bd5a382c0
commit
95c1443e30
@ -1378,57 +1378,82 @@ void spu_thread::do_dma_transfer(const spu_mfc_cmd& args)
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto cpu = static_cast<spu_thread*>(get_current_cpu_thread());
|
||||
|
||||
alignas(64) u8 temp[128];
|
||||
u8* dst0 = cpu && cpu->id_type() != 1 && (eal & -128) == cpu->raddr ? temp : dst;
|
||||
|
||||
if (dst0 == +temp && time0 != cpu->rtime)
|
||||
{
|
||||
// Validate rtime for read data
|
||||
cpu->set_events(SPU_EVENT_LR);
|
||||
cpu->raddr = 0;
|
||||
}
|
||||
|
||||
switch (size0)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
*reinterpret_cast<u8*>(dst) = *reinterpret_cast<const u8*>(src);
|
||||
*reinterpret_cast<u8*>(dst0) = *reinterpret_cast<const u8*>(src);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
*reinterpret_cast<u16*>(dst) = *reinterpret_cast<const u16*>(src);
|
||||
*reinterpret_cast<u16*>(dst0) = *reinterpret_cast<const u16*>(src);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
*reinterpret_cast<u32*>(dst) = *reinterpret_cast<const u32*>(src);
|
||||
*reinterpret_cast<u32*>(dst0) = *reinterpret_cast<const u32*>(src);
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
*reinterpret_cast<u64*>(dst) = *reinterpret_cast<const u64*>(src);
|
||||
*reinterpret_cast<u64*>(dst0) = *reinterpret_cast<const u64*>(src);
|
||||
break;
|
||||
}
|
||||
case 128:
|
||||
{
|
||||
mov_rdata(*reinterpret_cast<spu_rdata_t*>(dst), *reinterpret_cast<const spu_rdata_t*>(src));
|
||||
mov_rdata(*reinterpret_cast<spu_rdata_t*>(dst0), *reinterpret_cast<const spu_rdata_t*>(src));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
auto _dst = dst;
|
||||
auto _src = src;
|
||||
auto _size = size0;
|
||||
auto dst1 = dst0;
|
||||
auto src1 = src;
|
||||
auto size1 = size0;
|
||||
|
||||
while (_size)
|
||||
while (size1)
|
||||
{
|
||||
*reinterpret_cast<v128*>(_dst) = *reinterpret_cast<const v128*>(_src);
|
||||
*reinterpret_cast<v128*>(dst1) = *reinterpret_cast<const v128*>(src1);
|
||||
|
||||
_dst += 16;
|
||||
_src += 16;
|
||||
_size -= 16;
|
||||
dst1 += 16;
|
||||
src1 += 16;
|
||||
size1 -= 16;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (time0 != vm::reservation_acquire(eal, size0) || (size0 == 128 && !cmp_rdata(*reinterpret_cast<spu_rdata_t*>(dst), *reinterpret_cast<const spu_rdata_t*>(src))))
|
||||
if (time0 != vm::reservation_acquire(eal, size0) || (size0 == 128 && !cmp_rdata(*reinterpret_cast<spu_rdata_t*>(dst0), *reinterpret_cast<const spu_rdata_t*>(src))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dst0 == +temp)
|
||||
{
|
||||
// Write to LS
|
||||
std::memcpy(dst, dst0, size0);
|
||||
|
||||
// Validate data
|
||||
if (std::memcmp(dst0, &cpu->rdata[eal & 127], size0) != 0)
|
||||
{
|
||||
cpu->set_events(SPU_EVENT_LR);
|
||||
cpu->raddr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user