SPURS: Use atomic ops to implement some portions of event flags and trace

Conflicts:
	rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp
	rpcs3/Emu/SysCalls/Modules/cellSpurs.h
	rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp
This commit is contained in:
S Gopal Rajagopal 2015-03-08 19:18:29 +05:30 committed by Nekotekina
parent dc92a79fcc
commit fe67504ffc
3 changed files with 730 additions and 647 deletions

File diff suppressed because it is too large Load Diff

View File

@ -320,7 +320,7 @@ struct set_alignment(16) CellSpursTraceInfo
be_t<u32> count[8]; // 0x20
be_t<u32> spuThreadGroup; // 0x40
be_t<u32> numSpus; // 0x44
u8 padding[56];
u8 padding[56];
};
CHECK_SIZE_ALIGN(CellSpursTraceInfo, 128, 16);
@ -460,7 +460,7 @@ struct set_alignment(128) CellSpurs
struct _sub_str4
{
vm::bcptr<char, u64> nameClass;
vm::bcptr<char, u64> nameInstance;
vm::bcptr<char, u64> nameInstance;
};
atomic_be_t<u8> wklReadyCount1[0x10]; // 0x00 Number of SPUs requested by each workload (0..15 wids).
@ -494,10 +494,17 @@ struct set_alignment(128) CellSpurs
u8 spuPort; // 0xC9
u8 xCA; // 0xCA
u8 xCB; // 0xCB
u8 xCC; // 0xCC
u8 xCD; // 0xCD
u8 sysSrvMsgUpdateTrace; // 0xCE
u8 xCF; // 0xCF
struct SrvTraceSyncVar
{
u8 sysSrvTraceInitialised; // 0xCC
u8 sysSrvNotifyUpdateTraceComplete; // 0xCD
u8 sysSrvMsgUpdateTrace; // 0xCE
u8 xCF;
};
atomic_be_t<SrvTraceSyncVar> sysSrvTrace; // 0xCC
atomic_be_t<u8> wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_*
u8 wklStatus2[0x10]; // 0xE0
atomic_be_t<u8> wklEvent2[0x10]; // 0xF0
@ -599,11 +606,21 @@ CHECK_SIZE_ALIGN(CellSpursWorkloadAttribute, 512, 8);
struct set_alignment(128) CellSpursEventFlag
{
be_t<u16> events; // 0x00 Event bits
be_t<u16> spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks
be_t<u16> ppuWaitMask; // 0x04 Wait mask for blocked PPU thread
u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread
u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked
struct ControlSyncVar
{
be_t<u16> events; // 0x00 Event bits
be_t<u16> spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks
be_t<u16> ppuWaitMask; // 0x04 Wait mask for blocked PPU thread
u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread
u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked
};
union
{
atomic_be_t<ControlSyncVar> ctrl;// 0x00
atomic_be_t<u16> events; // 0x00
};
be_t<u16> spuTaskUsedWaitSlots; // 0x08 A bit is set to 1 if the wait slot corresponding to the bit is used by an SPU task and 0 otherwise
be_t<u16> spuTaskWaitMode; // 0x0A A bit is set to 1 if the wait mode for the SPU task corresponding to the bit is AND and 0 otherwise
u8 spuPort; // 0x0C

View File

@ -54,7 +54,7 @@ static void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext
// TODO: Deactivate workload
static void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelContext * ctxt, u32 wklShutdownBitSet);
static void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt);
static void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 arg4);
static void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 forceNotify);
// TODO: Deactivate trace
// TODO: System workload entry
static void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelContext * ctxt);
@ -808,7 +808,7 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt)
}
// Update trace message
if (spurs->sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) {
if (spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) {
updateTrace = true;
}
@ -954,27 +954,27 @@ void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt) {
}
/// Update trace control
void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 arg4) {
void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 forceNotify) {
bool notify;
u8 sysSrvMsgUpdateTrace;
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() {
auto spurs = ctxt->spurs.priv_ptr();
sysSrvMsgUpdateTrace = spurs->sysSrvMsgUpdateTrace;
spurs->sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum);
spurs->xCC &= ~(1 << ctxt->spuNum);
spurs->xCC |= arg2 << ctxt->spuNum;
sysSrvMsgUpdateTrace = spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace;
spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum);
spurs->sysSrvTrace.data.sysSrvTraceInitialised &= ~(1 << ctxt->spuNum);
spurs->sysSrvTrace.data.sysSrvTraceInitialised |= arg2 << ctxt->spuNum;
notify = false;
if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) && (spurs->sysSrvMsgUpdateTrace == 0) && (spurs->xCD != 0)) {
spurs->xCD = 0;
notify = true;
if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) && (spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace == 0) && (spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete != 0)) {
spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete = 0;
notify = true;
}
if (arg4 && spurs->xCD != 0) {
spurs->xCD = 0;
notify = true;
if (forceNotify && spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete != 0) {
spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete = 0;
notify = true;
}
memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128);