Skip to content

Commit

Permalink
Prefetch mfc list elemets to protect from overwriting
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Dec 30, 2018
1 parent d1be115 commit 4641efd
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 23 deletions.
7 changes: 7 additions & 0 deletions rpcs3/Emu/Cell/MFC.h
Expand Up @@ -87,3 +87,10 @@ struct alignas(16) spu_mfc_cmd
u32 eal;
u32 eah;
};

struct list_element
{
be_t<u16> sb; // Stall-and-Notify bit (0x8000)
be_t<u16> ts; // List Transfer Size
be_t<u32> ea; // External Address Low
};
44 changes: 21 additions & 23 deletions rpcs3/Emu/Cell/SPUThread.cpp
Expand Up @@ -963,35 +963,18 @@ bool spu_thread::do_dma_check(const spu_mfc_cmd& args)

bool spu_thread::do_list_transfer(spu_mfc_cmd& args)
{
struct list_element
{
be_t<u16> sb; // Stall-and-Notify bit (0x8000)
be_t<u16> ts; // List Transfer Size
be_t<u32> ea; // External Address Low
} item{};
// Prefetch list elements
std::memcpy(mfc_list_items, _ptr<void>(args.eal & 0x3fff8), args.size);
u32 index = 0;

while (args.size)
{
if (UNLIKELY(item.sb & 0x8000))
{
ch_stall_mask |= (1u << args.tag);

if (!ch_stall_stat.get_count())
{
ch_event_stat |= SPU_EVENT_SN;
}

ch_stall_stat.set_value((1u << args.tag) | ch_stall_stat.get_value());
return false;
}
const u32 size = mfc_list_items[index].ts & 0x7fff;
const u32 addr = mfc_list_items[index].ea;

args.lsa &= 0x3fff0;
item = _ref<list_element>(args.eal & 0x3fff8);

const u32 size = item.ts & 0x7fff;
const u32 addr = item.ea;

LOG_TRACE(SPU, "LIST: addr=0x%x, size=0x%x, lsa=0x%05x, sb=0x%x", addr, size, args.lsa | (addr & 0xf), item.sb);
LOG_TRACE(SPU, "LIST: addr=0x%x, size=0x%x, lsa=0x%05x, sb=0x%x", addr, size, args.lsa | (addr & 0xf), mfc_list_items[index].sb);

if (size)
{
Expand All @@ -1010,6 +993,21 @@ bool spu_thread::do_list_transfer(spu_mfc_cmd& args)

args.eal += 8;
args.size -= 8;

if (UNLIKELY(mfc_list_items[index].sb & 0x8000 && args.size))
{
ch_stall_mask |= (1u << args.tag);

if (!ch_stall_stat.get_count())
{
ch_event_stat |= SPU_EVENT_SN;
}

ch_stall_stat.set_value((1u << args.tag) | ch_stall_stat.get_value());
return false;
}

index++;
}

return true;
Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/Cell/SPUThread.h
Expand Up @@ -524,6 +524,7 @@ class spu_thread : public cpu_thread

// MFC command data
spu_mfc_cmd ch_mfc_cmd;
list_element mfc_list_items[0x4000 / 8];

// MFC command queue
spu_mfc_cmd mfc_queue[16]{};
Expand Down

0 comments on commit 4641efd

Please sign in to comment.