mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 20:15:27 +00:00
SPU LLVM: Add CRC check for cache
This commit is contained in:
parent
66b6bae596
commit
dd4840caf6
1 changed files with 46 additions and 12 deletions
|
@ -565,6 +565,21 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
|
|||
g_fxo->get<spu_cache>().precompile_funcs.push(std::move(obj));
|
||||
}
|
||||
|
||||
// For SPU cache validity check
|
||||
static u16 calculate_crc16(const uchar* data, usz length)
|
||||
{
|
||||
u16 crc = umax;
|
||||
|
||||
while (length--)
|
||||
{
|
||||
u8 x = (crc >> 8) ^ *data++;
|
||||
x ^= (x >> 4);
|
||||
crc = static_cast<u16>((crc << 8) ^ (x << 12) ^ (x << 5) ^ x);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
std::deque<spu_program> spu_cache::get()
|
||||
{
|
||||
std::deque<spu_program> result;
|
||||
|
@ -579,20 +594,29 @@ std::deque<spu_program> spu_cache::get()
|
|||
// TODO: signal truncated or otherwise broken file
|
||||
while (true)
|
||||
{
|
||||
be_t<u32> size;
|
||||
be_t<u32> addr;
|
||||
struct block_info_t
|
||||
{
|
||||
be_t<u16> crc;
|
||||
be_t<u16> size;
|
||||
be_t<u32> addr;
|
||||
} block_info{};
|
||||
|
||||
if (!m_file.read(block_info))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const u32 crc = block_info.crc;
|
||||
const u32 size = block_info.size;
|
||||
const u32 addr = block_info.addr;
|
||||
|
||||
if (utils::add_saturate<u32>(addr, size * 4) > SPU_LS_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<u32> func;
|
||||
|
||||
if (!m_file.read(size) || !m_file.read(addr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (utils::add_saturate<u32>(addr, utils::mul_saturate<u32>(size, 4)) > SPU_LS_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_file.read(func, size))
|
||||
{
|
||||
break;
|
||||
|
@ -604,6 +628,13 @@ std::deque<spu_program> spu_cache::get()
|
|||
continue;
|
||||
}
|
||||
|
||||
// CRC check is optional to be compatible with old format
|
||||
if (crc && std::max<u32>(calculate_crc16(reinterpret_cast<const uchar*>(func.data()), size * 4), 1) != crc)
|
||||
{
|
||||
// Invalid, but continue anyway
|
||||
continue;
|
||||
}
|
||||
|
||||
spu_program res;
|
||||
res.entry_point = addr;
|
||||
res.lower_bound = addr;
|
||||
|
@ -624,6 +655,9 @@ void spu_cache::add(const spu_program& func)
|
|||
be_t<u32> size = ::size32(func.data);
|
||||
be_t<u32> addr = func.entry_point;
|
||||
|
||||
// Add CRC (forced non-zero)
|
||||
size |= std::max<u32>(calculate_crc16(reinterpret_cast<const uchar*>(func.data.data()), size * 4), 1) << 16;
|
||||
|
||||
const fs::iovec_clone gather[3]
|
||||
{
|
||||
{&size, sizeof(size)},
|
||||
|
|
Loading…
Add table
Reference in a new issue