mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
* Replace `int` with `s32` as return type for syscalls. * Renamed `SC_Something.*` files with the proper lv2 name `sys_something.*`. * Moving away from the lv2, those functions and folders that doesn't correspond to lv2 functions. E.g. module functions from sys_io, sysPrxForUser, cellGcmSys. * Splitted some files (memory -> memory+mmapper) and merged other ones (event+event_flag ->event, spu+spu_thread -> spu), according to common sense, PSDevWiki docs, and checking firmware files. * Removed external functions from `SysCalls.h`. NOTE: What should we do about: cellGcmCallback? It's not a lv2 syscall but it appears on the sc_table and it is actually called in games. Is this some kind of hack?
111 lines
No EOL
2.1 KiB
C++
111 lines
No EOL
2.1 KiB
C++
#include "stdafx.h"
|
|
#include "Utilities/Log.h"
|
|
#include "Emu/Memory/Memory.h"
|
|
#include "Emu/System.h"
|
|
#include "Emu/Cell/PPUThread.h"
|
|
#include "Emu/Cell/RawSPUThread.h"
|
|
#include "Emu/SysCalls/SC_FUNC.h"
|
|
#include "Emu/SysCalls/Modules.h"
|
|
#include "Emu/SysCalls/SysCalls.h"
|
|
#include "sys_interrupt.h"
|
|
|
|
static SysCallBase sc_int("sys_interrupt");
|
|
|
|
s32 sys_interrupt_tag_destroy(u32 intrtag)
|
|
{
|
|
sc_int.Warning("sys_interrupt_tag_destroy(intrtag=%d)", intrtag);
|
|
|
|
u32 id = intrtag & 0xff;
|
|
u32 class_id = intrtag >> 8;
|
|
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
|
|
|
if (!t || class_id > 2 || class_id == 1)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
if (!t->m_intrtag[class_id].enabled)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
if (t->m_intrtag[class_id].thread)
|
|
{
|
|
return CELL_EBUSY;
|
|
}
|
|
|
|
t->m_intrtag[class_id].enabled = 0;
|
|
return CELL_OK;
|
|
}
|
|
|
|
s32 sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 arg)
|
|
{
|
|
sc_int.Warning("sys_interrupt_thread_establish(ih_addr=0x%x, intrtag=%d, intrthread=%lld, arg=0x%llx)", ih.GetAddr(), intrtag, intrthread, arg);
|
|
|
|
if (!ih.IsGood())
|
|
{
|
|
return CELL_EFAULT;
|
|
}
|
|
|
|
u32 id = intrtag & 0xff;
|
|
u32 class_id = intrtag >> 8;
|
|
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
|
|
|
if (!t || class_id > 2 || class_id == 1)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
if (!t->m_intrtag[class_id].enabled)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
if (t->m_intrtag[class_id].thread) // ???
|
|
{
|
|
return CELL_ESTAT;
|
|
}
|
|
|
|
CPUThread* it = Emu.GetCPU().GetThread(intrthread);
|
|
if (!it)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
if (it->m_has_interrupt || !it->m_is_interrupt)
|
|
{
|
|
return CELL_EAGAIN;
|
|
}
|
|
|
|
ih = (t->m_intrtag[class_id].thread = intrthread);
|
|
it->m_interrupt_arg = arg;
|
|
return CELL_OK;
|
|
}
|
|
|
|
s32 sys_interrupt_thread_disestablish(u32 ih)
|
|
{
|
|
sc_int.Error("sys_interrupt_thread_disestablish(ih=%d)", ih);
|
|
|
|
CPUThread* it = Emu.GetCPU().GetThread(ih);
|
|
if (!it)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
if (!it->m_has_interrupt || !it->m_is_interrupt)
|
|
{
|
|
return CELL_ESRCH;
|
|
}
|
|
|
|
// TODO: wait for sys_interrupt_thread_eoi() and destroy interrupt thread
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
void sys_interrupt_thread_eoi()
|
|
{
|
|
sc_int.Log("sys_interrupt_thread_eoi()");
|
|
|
|
GetCurrentPPUThread().Stop();
|
|
return;
|
|
} |