s32 sys_spu_thread_switch_system_module(SPUThread & spu, u32 status) { if (spu.get_ch_count(SPU_RdInMbox)) { return CELL_EBUSY; } // Cancel any pending status update requests spu.set_ch_value(MFC_WrTagUpdate, 0); while (spu.get_ch_count(MFC_RdTagStat) != 1); spu.get_ch_value(MFC_RdTagStat); // Wait for all pending DMA operations to complete spu.set_ch_value(MFC_WrTagMask, 0xFFFFFFFF); spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_ALL); spu.get_ch_value(MFC_RdTagStat); s32 result; do { spu.set_ch_value(SPU_WrOutMbox, status); spu.stop_and_signal(0x120); } while ((result = spu.get_ch_value(SPU_RdInMbox)) == CELL_EBUSY); return result; }
void sys_spu_thread_group_exit(SPUThread & spu, s32 status) { // Cancel any pending status update requests spu.set_ch_value(MFC_WrTagUpdate, 0); while (spu.get_ch_count(MFC_RdTagStat) != 1); spu.get_ch_value(MFC_RdTagStat); // Wait for all pending DMA operations to complete spu.set_ch_value(MFC_WrTagMask, 0xFFFFFFFF); spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_ALL); spu.get_ch_value(MFC_RdTagStat); spu.set_ch_value(SPU_WrOutMbox, status); spu.stop_and_signal(0x101); }
s32 sys_spu_thread_send_event(SPUThread & spu, u8 spup, u32 data0, u32 data1) { if (spup > 0x3F) { return CELL_EINVAL; } if (spu.get_ch_count(SPU_RdInMbox)) { return CELL_EBUSY; } spu.set_ch_value(SPU_WrOutMbox, data1); spu.set_ch_value(SPU_WrOutIntrMbox, (spup << 24) | (data0 & 0x00FFFFFF)); return spu.get_ch_value(SPU_RdInMbox); }
void spu_interpreter::RDCH(SPUThread& CPU, spu_opcode_t op) { CPU.GPR[op.rt] = u128::from32r(CPU.get_ch_value(op.ra)); }