diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 1933387e65..8c5b3adc9c 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -788,14 +788,11 @@ ppu_thread::ppu_thread(const ppu_thread_params& param, std::string_view name, u3 gpr[13] = param.tls_addr; - if (detached >= 0 && id != id_base) + if (detached >= 0) { - // Initialize thread entry point - cmd_list - ({ - {ppu_cmd::set_args, 2}, param.arg0, param.arg1, - {ppu_cmd::opd_call, 0}, std::bit_cast(entry_func), - }); + // Initialize thread args + gpr[3] = param.arg0; + gpr[4] = param.arg1; } // Trigger the scheduler diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp index c0e52ed59e..e17abbdbf3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp @@ -15,7 +15,7 @@ void lv2_int_serv::exec() ({ { ppu_cmd::reset_stack, 0 }, { ppu_cmd::set_args, 2 }, arg1, arg2, - { ppu_cmd::opd_call, 0 }, std::bit_cast(thread->entry_func), + { ppu_cmd::opd_call, 0 }, thread->entry_func, { ppu_cmd::sleep, 0 } }); diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index 07b6c8594d..078a183841 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -441,26 +441,37 @@ error_code sys_ppu_thread_start(ppu_thread& ppu, u32 thread_id) { sys_ppu_thread.trace("sys_ppu_thread_start(thread_id=0x%x)", thread_id); - const auto thread = idm::get>(thread_id, [&](ppu_thread& thread) + const auto thread = idm::get>(thread_id, [&](ppu_thread& thread) -> CellError { if (thread.joiner == ppu_join_status::exited) { - return false; + return CELL_ESRCH; + } + + if (!thread.state.test_and_reset(cpu_flag::stop)) + { + // Already started + return CELL_EBUSY; } lv2_obj::awake(&thread); - return true; + + thread.cmd_list + ({ + {ppu_cmd::opd_call, 0}, thread.entry_func + }); + + return {}; }); - if (!thread || !thread.ret) + if (!thread) { return CELL_ESRCH; } - if (!thread->state.test_and_reset(cpu_flag::stop)) + if (thread.ret) { - // TODO: what happens there? - return CELL_EPERM; + return thread.ret; } else {