mirror of https://github.com/RPCS3/rpcs3.git
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;
|
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)
|
switch (size0)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
*reinterpret_cast<u8*>(dst) = *reinterpret_cast<const u8*>(src);
|
*reinterpret_cast<u8*>(dst0) = *reinterpret_cast<const u8*>(src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
*reinterpret_cast<u16*>(dst) = *reinterpret_cast<const u16*>(src);
|
*reinterpret_cast<u16*>(dst0) = *reinterpret_cast<const u16*>(src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
*reinterpret_cast<u32*>(dst) = *reinterpret_cast<const u32*>(src);
|
*reinterpret_cast<u32*>(dst0) = *reinterpret_cast<const u32*>(src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 8:
|
case 8:
|
||||||
{
|
{
|
||||||
*reinterpret_cast<u64*>(dst) = *reinterpret_cast<const u64*>(src);
|
*reinterpret_cast<u64*>(dst0) = *reinterpret_cast<const u64*>(src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 128:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto _dst = dst;
|
auto dst1 = dst0;
|
||||||
auto _src = src;
|
auto src1 = src;
|
||||||
auto _size = size0;
|
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;
|
dst1 += 16;
|
||||||
_src += 16;
|
src1 += 16;
|
||||||
_size -= 16;
|
size1 -= 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue