SPURS: Implement some SPU thread functions used by the system service module

This commit is contained in:
S Gopal Rajagopal 2015-01-31 01:32:07 +05:30
parent 507638e6d8
commit f7b7c234b7
2 changed files with 89 additions and 0 deletions

View file

@ -1099,3 +1099,86 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value)
*value = (u32)t->cfg.value; *value = (u32)t->cfg.value;
return CELL_OK; return CELL_OK;
} }
void sys_spu_thread_exit(SPUThread & spu, s32 status)
{
// Cancel any pending status update requests
u128 r;
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(0));
while (spu.GetChannelCount(MFC_RdTagStat) != 1);
spu.ReadChannel(r, MFC_RdTagStat);
// Wait for all pending DMA operations to complete
spu.WriteChannel(MFC_WrTagMask, u128::from32r(0xFFFFFFFF));
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(MFC_TAG_UPDATE_ALL));
spu.ReadChannel(r, MFC_RdTagStat);
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(status));
spu.StopAndSignal(0x102);
}
void sys_spu_thread_group_exit(SPUThread & spu, s32 status)
{
// Cancel any pending status update requests
u128 r;
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(0));
while (spu.GetChannelCount(MFC_RdTagStat) != 1);
spu.ReadChannel(r, MFC_RdTagStat);
// Wait for all pending DMA operations to complete
spu.WriteChannel(MFC_WrTagMask, u128::from32r(0xFFFFFFFF));
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(MFC_TAG_UPDATE_ALL));
spu.ReadChannel(r, MFC_RdTagStat);
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(status));
spu.StopAndSignal(0x101);
}
s32 sys_spu_thread_send_event(SPUThread & spu, u8 spup, u32 data0, u32 data1)
{
if (spup > 0x3F)
{
return CELL_EINVAL;
}
if (spu.GetChannelCount(SPU_RdInMbox))
{
return CELL_EBUSY;
}
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(data1));
spu.WriteChannel(SPU_WrOutIntrMbox, u128::from32r((spup << 24) | (data0 & 0x00FFFFFF)));
u128 r;
spu.ReadChannel(r, SPU_RdInMbox);
return r._u32[3];
}
s32 sys_spu_thread_switch_system_module(SPUThread & spu, u32 status)
{
if (spu.GetChannelCount(SPU_RdInMbox))
{
return CELL_EBUSY;
}
// Cancel any pending status update requests
u128 r;
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(0));
while (spu.GetChannelCount(MFC_RdTagStat) != 1);
spu.ReadChannel(r, MFC_RdTagStat);
// Wait for all pending DMA operations to complete
spu.WriteChannel(MFC_WrTagMask, u128::from32r(0xFFFFFFFF));
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(MFC_TAG_UPDATE_ALL));
spu.ReadChannel(r, MFC_RdTagStat);
do
{
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(status));
spu.StopAndSignal(0x120);
spu.ReadChannel(r, SPU_RdInMbox);
}
while (r._u32[3] == CELL_EBUSY);
return r._u32[3];
}

View file

@ -204,3 +204,9 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr<u64> stat);
s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr<u32> value); s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr<u32> value);
s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value); s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value);
s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value); s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value);
// SPU Calls
void sys_spu_thread_exit(SPUThread & spu, s32 status);
void sys_spu_thread_group_exit(SPUThread & spu, s32 status);
s32 sys_spu_thread_send_event(SPUThread & spu, u8 spup, u32 data0, u32 data1);
s32 sys_spu_thread_switch_system_module(SPUThread & spu, u32 status);