mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 01:08:39 +12:00
Bugfix
+sys_spu_thread_group_disconnect_event_all_threads
This commit is contained in:
parent
9e49a33b3c
commit
f22001d527
3 changed files with 121 additions and 75 deletions
|
@ -212,7 +212,7 @@ void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args)
|
||||||
}
|
}
|
||||||
else if ((cmd & MFC_PUT_CMD) && args.size == 4 && (offset == SYS_SPU_THREAD_SNR1 || offset == SYS_SPU_THREAD_SNR2))
|
else if ((cmd & MFC_PUT_CMD) && args.size == 4 && (offset == SYS_SPU_THREAD_SNR1 || offset == SYS_SPU_THREAD_SNR2))
|
||||||
{
|
{
|
||||||
spu.write_snr(SYS_SPU_THREAD_SNR2 == offset, vm::read32(offset + args.lsa));
|
spu.write_snr(SYS_SPU_THREAD_SNR2 == offset, read32(args.lsa));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -112,7 +112,12 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_array,
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queue->type != SYS_PPU_QUEUE || size < 0) // ???
|
if (size < 0)
|
||||||
|
{
|
||||||
|
throw __FUNCTION__;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue->type != SYS_PPU_QUEUE)
|
||||||
{
|
{
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,9 +166,8 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr<sys_spu_thread_argument> arg)
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
if (!t)
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU)
|
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -193,8 +192,9 @@ s32 sys_spu_thread_get_exit_status(u32 id, vm::ptr<u32> status)
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU)
|
|
||||||
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +208,7 @@ s32 sys_spu_thread_get_exit_status(u32 id, vm::ptr<u32> status)
|
||||||
}
|
}
|
||||||
|
|
||||||
*status = res;
|
*status = res;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +257,7 @@ s32 sys_spu_thread_group_destroy(u32 id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear threads
|
// clear threads
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -295,7 +296,7 @@ s32 sys_spu_thread_group_start(u32 id)
|
||||||
group->state = SPU_THREAD_GROUP_STATUS_RUNNING;
|
group->state = SPU_THREAD_GROUP_STATUS_RUNNING;
|
||||||
group->join_state = 0;
|
group->join_state = 0;
|
||||||
|
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -319,7 +320,7 @@ s32 sys_spu_thread_group_start(u32 id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -371,7 +372,7 @@ s32 sys_spu_thread_group_suspend(u32 id)
|
||||||
return CELL_ESTAT;
|
return CELL_ESTAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -417,7 +418,7 @@ s32 sys_spu_thread_group_resume(u32 id)
|
||||||
return CELL_ESTAT;
|
return CELL_ESTAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -471,7 +472,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value)
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -508,6 +509,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr<u32> cause, vm::ptr<u32> status)
|
||||||
|
|
||||||
if (group->join_state.fetch_or(STGJSF_IS_JOINING) & STGJSF_IS_JOINING)
|
if (group->join_state.fetch_or(STGJSF_IS_JOINING) & STGJSF_IS_JOINING)
|
||||||
{
|
{
|
||||||
|
// another PPU thread is joining this thread group
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +517,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr<u32> cause, vm::ptr<u32> status)
|
||||||
{
|
{
|
||||||
bool stopped = true;
|
bool stopped = true;
|
||||||
|
|
||||||
for (auto t : group->threads)
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -575,12 +577,11 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr<u32> cause, vm::ptr<u32> status)
|
||||||
|
|
||||||
s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
|
s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
|
||||||
{
|
{
|
||||||
sys_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=0x%x)",
|
sys_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=%d)", id, address, value, type);
|
||||||
id, address, value, type);
|
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -611,12 +612,11 @@ s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
|
||||||
|
|
||||||
s32 sys_spu_thread_read_ls(u32 id, u32 address, vm::ptr<u64> value, u32 type)
|
s32 sys_spu_thread_read_ls(u32 id, u32 address, vm::ptr<u64> value, u32 type)
|
||||||
{
|
{
|
||||||
sys_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value_addr=0x%x, type=0x%x)",
|
sys_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value=*0x%x, type=%d)", id, address, value, type);
|
||||||
id, address, value.addr(), type);
|
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -649,14 +649,16 @@ s32 sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
||||||
{
|
{
|
||||||
sys_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value);
|
sys_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value);
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> thr = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if(!thr || thr->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*(SPUThread*)thr.get()).ch_in_mbox.push_uncond(value);
|
auto& spu = static_cast<SPUThread&>(*t);
|
||||||
|
|
||||||
|
spu.ch_in_mbox.push_uncond(value);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -665,9 +667,9 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value)
|
||||||
{
|
{
|
||||||
sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value);
|
sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value);
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> thr = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if(!thr || thr->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -677,23 +679,27 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value)
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*(SPUThread*)thr.get()).snr_config = value;
|
auto& spu = static_cast<SPUThread&>(*t);
|
||||||
|
|
||||||
|
spu.snr_config = value;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 sys_spu_thread_get_spu_cfg(u32 id, vm::ptr<u64> value)
|
s32 sys_spu_thread_get_spu_cfg(u32 id, vm::ptr<u64> value)
|
||||||
{
|
{
|
||||||
sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value_addr=0x%x)", id, value.addr());
|
sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value=*0x%x)", id, value);
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> thr = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if(!thr || thr->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
*value = (*(SPUThread*)thr.get()).snr_config;
|
auto& spu = static_cast<SPUThread&>(*t);
|
||||||
|
|
||||||
|
*value = spu.snr_config;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -702,9 +708,9 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
|
||||||
{
|
{
|
||||||
sys_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value);
|
sys_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value);
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> thr = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if(!thr || thr->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -714,7 +720,9 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*(SPUThread*)thr.get()).write_snr(number ? true : false, value);
|
auto& spu = static_cast<SPUThread&>(*t);
|
||||||
|
|
||||||
|
spu.write_snr(number ? true : false, value);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -747,11 +755,11 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
std::shared_ptr<event_queue_t> queue;
|
std::shared_ptr<event_queue_t> queue;
|
||||||
|
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU || !Emu.GetIdManager().GetIDData(eq, queue))
|
if (!t || !Emu.GetIdManager().GetIDData(eq, queue))
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -772,6 +780,7 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
|
||||||
}
|
}
|
||||||
|
|
||||||
port = queue;
|
port = queue;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,9 +790,9 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup)
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -804,6 +813,7 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup)
|
||||||
}
|
}
|
||||||
|
|
||||||
port.reset();
|
port.reset();
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,11 +823,11 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num)
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
std::shared_ptr<event_queue_t> queue;
|
std::shared_ptr<event_queue_t> queue;
|
||||||
|
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU || !Emu.GetIdManager().GetIDData(spuq, queue))
|
if (!t || !Emu.GetIdManager().GetIDData(spuq, queue))
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -841,6 +851,7 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
spu.spuq[spuq_num] = queue;
|
spu.spuq[spuq_num] = queue;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,9 +861,9 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id);
|
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU);
|
||||||
|
|
||||||
if (!t || t->GetType() != CPU_THREAD_SPU)
|
if (!t)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
@ -866,6 +877,7 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
|
||||||
}
|
}
|
||||||
|
|
||||||
spu.spuq.erase(found);
|
spu.spuq.erase(found);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,13 +905,18 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm::
|
||||||
return CELL_ESTAT;
|
return CELL_ESTAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 port = 0; port < 64; port++) // port number
|
u8 port = 0; // SPU Port number
|
||||||
|
|
||||||
|
for (; port < 64; port++)
|
||||||
{
|
{
|
||||||
|
if (!(req & (1ull << port)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = true;
|
bool found = true;
|
||||||
|
|
||||||
if (req & (1ull << port))
|
for (auto& t : group->threads)
|
||||||
{
|
|
||||||
for (auto t : group->threads)
|
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -912,15 +929,19 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
for (auto t : group->threads)
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port == 64)
|
||||||
|
{
|
||||||
|
return CELL_EISCONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& t : group->threads)
|
||||||
{
|
{
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
@ -931,16 +952,36 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm::
|
||||||
}
|
}
|
||||||
|
|
||||||
*spup = port;
|
*spup = port;
|
||||||
return CELL_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CELL_EISCONN;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)
|
s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)
|
||||||
{
|
{
|
||||||
sys_spu.Todo("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup);
|
sys_spu.Warning("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup);
|
||||||
|
|
||||||
|
LV2_LOCK;
|
||||||
|
|
||||||
|
std::shared_ptr<spu_group_t> group;
|
||||||
|
if (!Emu.GetIdManager().GetIDData(id, group))
|
||||||
|
{
|
||||||
|
return CELL_ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spup > 63)
|
||||||
|
{
|
||||||
|
return CELL_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& t : group->threads)
|
||||||
|
{
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
auto& spu = static_cast<SPUThread&>(*t);
|
||||||
|
|
||||||
|
spu.spup[spup].reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue