mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
sys_interrupt_thread_eoi fixed
thread_ctrl::interrupt improved BIND_FUNC improved: preparations
This commit is contained in:
parent
7ccdea7822
commit
a026d35c97
3 changed files with 20 additions and 9 deletions
|
@ -95,7 +95,7 @@ private:
|
|||
atomic_t<u32> m_joining{};
|
||||
|
||||
// Thread interrupt guard counter
|
||||
u32 m_guard = 0x80000000;
|
||||
volatile u32 m_guard = 0x80000000;
|
||||
|
||||
// Thread internals
|
||||
atomic_t<internal*> m_data{};
|
||||
|
|
|
@ -4,12 +4,18 @@
|
|||
|
||||
using ppu_function_t = void(*)(PPUThread&);
|
||||
|
||||
#define BIND_FUNC(func) static_cast<ppu_function_t>([](PPUThread& ppu){\
|
||||
// BIND_FUNC macro "converts" any appropriate HLE function to ppu_function_t, binding it to PPU thread context.
|
||||
// If function already has type ppu_function_t, it's handled specially and classified as "low-level HLE function".
|
||||
// 1) Low-level functions are bound directly so they don't save their name to ppu.last_function variable.
|
||||
// 2) Low-level functions don't install thread_guar, so they are very limited, and may be dangerous.
|
||||
// If you don't need "low-level function", be sure it's either `void()` or `void(PPUThread& ppu, PPUThread&)` for example.
|
||||
#define BIND_FUNC(func) (std::is_same<decltype(func), ppu_function_t>::value ? reinterpret_cast<ppu_function_t>(func) : static_cast<ppu_function_t>([](PPUThread& ppu){\
|
||||
const thread_guard guard(ppu);\
|
||||
const auto old_f = ppu.last_function;\
|
||||
ppu.last_function = #func;\
|
||||
ppu_func_detail::do_call(ppu, func);\
|
||||
ppu.last_function = old_f;\
|
||||
})
|
||||
}))
|
||||
|
||||
struct ppu_va_args_t
|
||||
{
|
||||
|
|
|
@ -156,13 +156,18 @@ s32 _sys_interrupt_thread_disestablish(PPUThread& ppu, u32 ih, vm::ptr<u64> r13)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
void sys_interrupt_thread_eoi(PPUThread& ppu)
|
||||
void sys_interrupt_thread_eoi(PPUThread& ppu) // Low-level PPU function example
|
||||
{
|
||||
sys_interrupt.trace("sys_interrupt_thread_eoi()");
|
||||
|
||||
// TODO: maybe it should actually unwind the stack of PPU thread?
|
||||
|
||||
ppu.GPR[1] = align(ppu.stack_addr + ppu.stack_size, 0x200) - 0x200; // supercrutch to bypass stack check
|
||||
// Low-level function body must guard all C++-ish calls and all objects with non-trivial destructors
|
||||
thread_guard{ppu}, sys_interrupt.trace("sys_interrupt_thread_eoi()");
|
||||
|
||||
ppu.state += cpu_state::ret;
|
||||
|
||||
// Throw if this syscall was not called directly by the SC instruction (hack)
|
||||
if (ppu.LR == 0 || ppu.GPR[11] != 88 || ppu.custom_task)
|
||||
{
|
||||
// Low-level function must disable interrupts before throwing (not related to sys_interrupt_*, it's rather coincidence)
|
||||
ppu->interrupt_disable();
|
||||
throw cpu_state::ret;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue