mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-25 12:40:57 +00:00
Merge pull request #365 from Nekotekina/master
Work on RawSPU: interrupt mailbox
This commit is contained in:
commit
35b57fc78e
@ -130,6 +130,10 @@ public:
|
||||
u64 cycle;
|
||||
bool m_is_branch;
|
||||
|
||||
bool m_is_interrupt;
|
||||
bool m_has_interrupt;
|
||||
u64 m_interrupt_arg;
|
||||
|
||||
protected:
|
||||
CPUThread(CPUThreadType type);
|
||||
|
||||
|
@ -108,6 +108,26 @@ CPUThread* CPUThreadManager::GetThread(u32 id)
|
||||
return res;
|
||||
}
|
||||
|
||||
RawSPUThread* CPUThreadManager::GetRawSPUThread(u32 num)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_thread);
|
||||
|
||||
for (u32 i = 0; i < m_threads.size(); i++)
|
||||
{
|
||||
if (m_threads[i]->GetType() == CPU_THREAD_RAW_SPU)
|
||||
{
|
||||
RawSPUThread* t = (RawSPUThread*)m_threads[i];
|
||||
|
||||
if (t->GetIndex() == num)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CPUThreadManager::NotifyThread(const u32 id)
|
||||
{
|
||||
if (!id) return;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
class CPUThread;
|
||||
class RawSPUThread;
|
||||
enum CPUThreadType : unsigned char;
|
||||
|
||||
class CPUThreadManager
|
||||
@ -21,6 +22,7 @@ public:
|
||||
std::vector<CPUThread*>& GetThreads() { return m_threads; }
|
||||
s32 GetThreadNumById(CPUThreadType type, u32 id);
|
||||
CPUThread* GetThread(u32 id);
|
||||
RawSPUThread* GetRawSPUThread(u32 num);
|
||||
|
||||
void Exec();
|
||||
void Task();
|
||||
|
@ -79,7 +79,7 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
|
||||
case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_QueryMask)", m_index); *value = Prxy.QueryMask.GetValue(); break;
|
||||
case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); *value = Prxy.TagStatus.GetValue(); break;
|
||||
case SPU_Out_MBox_offs:
|
||||
ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index);
|
||||
//ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index);
|
||||
SPU.Out_MBox.PopUncond(*value); //if Out_MBox is empty yet, the result will be undefined
|
||||
break;
|
||||
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); while(!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break;
|
||||
@ -89,7 +89,10 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
|
||||
*value = SPU.MBox_Status.GetValue();
|
||||
break;
|
||||
case SPU_RunCntl_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = SPU.RunCntl.GetValue(); break;
|
||||
case SPU_Status_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Status)", m_index); *value = SPU.Status.GetValue(); break;
|
||||
case SPU_Status_offs:
|
||||
//ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Status)", m_index);
|
||||
*value = SPU.Status.GetValue();
|
||||
break;
|
||||
case SPU_NPC_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_NPC)", m_index); *value = SPU.NPC.GetValue(); break;
|
||||
case SPU_RdSigNotify1_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RdSigNotify1)", m_index); *value = SPU.SNR[0].GetValue(); break;
|
||||
case SPU_RdSigNotify2_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RdSigNotify2)", m_index); *value = SPU.SNR[1].GetValue(); break;
|
||||
@ -199,7 +202,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
|
||||
case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_TagStatus, 0x%x)", m_index, value); Prxy.TagStatus.SetValue(value); break;
|
||||
case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Out_MBox, 0x%x)", m_index, value); while(!SPU.Out_MBox.Push(value) && !Emu.IsStopped()) Sleep(1); break;
|
||||
case SPU_In_MBox_offs:
|
||||
ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value);
|
||||
//ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value);
|
||||
SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten
|
||||
break;
|
||||
case SPU_MBox_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); SPU.MBox_Status.SetValue(value); break;
|
||||
|
@ -679,7 +679,11 @@ private:
|
||||
//HGT uses signed values. HLGT uses unsigned values
|
||||
void HGT(u32 rt, s32 ra, s32 rb)
|
||||
{
|
||||
if(CPU.GPR[ra]._i32[3] > CPU.GPR[rb]._i32[3]) CPU.Stop();
|
||||
if (CPU.GPR[ra]._i32[3] > CPU.GPR[rb]._i32[3])
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
}
|
||||
}
|
||||
void CLZ(u32 rt, u32 ra)
|
||||
{
|
||||
@ -806,7 +810,11 @@ private:
|
||||
}
|
||||
void HLGT(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
if(CPU.GPR[ra]._u32[3] > CPU.GPR[rb]._u32[3]) CPU.Stop();
|
||||
if (CPU.GPR[ra]._u32[3] > CPU.GPR[rb]._u32[3])
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
}
|
||||
}
|
||||
void DFMA(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
@ -1018,7 +1026,11 @@ private:
|
||||
}
|
||||
void HEQ(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
if(CPU.GPR[ra]._i32[3] == CPU.GPR[rb]._i32[3]) CPU.Stop();
|
||||
if (CPU.GPR[ra]._i32[3] == CPU.GPR[rb]._i32[3])
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
//0 - 9
|
||||
@ -1373,7 +1385,11 @@ private:
|
||||
}
|
||||
void HGTI(u32 rt, u32 ra, s32 i10)
|
||||
{
|
||||
if(CPU.GPR[ra]._i32[3] > i10) CPU.Stop();
|
||||
if (CPU.GPR[ra]._i32[3] > i10)
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
}
|
||||
}
|
||||
void CLGTI(u32 rt, u32 ra, s32 i10)
|
||||
{
|
||||
@ -1396,7 +1412,11 @@ private:
|
||||
}
|
||||
void HLGTI(u32 rt, u32 ra, s32 i10)
|
||||
{
|
||||
if(CPU.GPR[ra]._u32[3] > (u32)i10) CPU.Stop();
|
||||
if (CPU.GPR[ra]._u32[3] > (u32)i10)
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
}
|
||||
}
|
||||
void MPYI(u32 rt, u32 ra, s32 i10)
|
||||
{
|
||||
@ -1425,7 +1445,11 @@ private:
|
||||
}
|
||||
void HEQI(u32 rt, u32 ra, s32 i10)
|
||||
{
|
||||
if(CPU.GPR[ra]._i32[3] == i10) CPU.Stop();
|
||||
if (CPU.GPR[ra]._i32[3] == i10)
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -232,6 +232,7 @@ u8 SPURecompilerCore::DecodeMemory(const u64 address)
|
||||
|
||||
if (res > 0xffff)
|
||||
{
|
||||
CPU.SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_HALT);
|
||||
CPU.Stop();
|
||||
res = ~res;
|
||||
}
|
||||
|
@ -295,6 +295,22 @@ public:
|
||||
EventManager SPUQs; // SPU Queue Mapping
|
||||
SpuGroupInfo* group; // associated SPU Thread Group (null for raw spu)
|
||||
|
||||
struct IntrTag
|
||||
{
|
||||
u32 enabled; // 1 == true
|
||||
u32 thread; // established interrupt PPU thread
|
||||
u64 mask;
|
||||
u64 stat;
|
||||
|
||||
IntrTag()
|
||||
: enabled(0)
|
||||
, thread(0)
|
||||
, mask(0)
|
||||
, stat(0)
|
||||
{
|
||||
}
|
||||
} m_intrtag[3];
|
||||
|
||||
template<size_t _max_count>
|
||||
class Channel
|
||||
{
|
||||
@ -510,6 +526,7 @@ public:
|
||||
struct
|
||||
{
|
||||
Channel<1> Out_MBox;
|
||||
Channel<1> Out_IntrMBox;
|
||||
Channel<4> In_MBox;
|
||||
Channel<1> MBox_Status;
|
||||
Channel<1> RunCntl;
|
||||
@ -544,7 +561,7 @@ public:
|
||||
{
|
||||
if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence();
|
||||
|
||||
if ((ea & 0xf0000000) == SYS_SPU_THREAD_BASE_LOW)
|
||||
if (ea >= SYS_SPU_THREAD_BASE_LOW)
|
||||
{
|
||||
if (group)
|
||||
{
|
||||
@ -902,9 +919,24 @@ public:
|
||||
case SPU_WrOutIntrMbox:
|
||||
if (!group) // if RawSPU
|
||||
{
|
||||
// TODO: run PPU interrupt thread
|
||||
ConLog.Error("SPU_WrOutIntrMbox interrupt unimplemented");
|
||||
Emu.Pause();
|
||||
if (Ini.HLELogging.GetValue()) ConLog.Write("SPU_WrOutIntrMbox: interrupt(v=0x%x)", v);
|
||||
SPU.Out_IntrMBox.PushUncond(v);
|
||||
m_intrtag[2].stat |= 1;
|
||||
if (CPUThread* t = Emu.GetCPU().GetThread(m_intrtag[2].thread))
|
||||
{
|
||||
while (t->IsAlive())
|
||||
{
|
||||
Sleep(1);
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
t->SetArg(0, t->m_interrupt_arg);
|
||||
t->Run();
|
||||
t->Exec();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1223,6 +1255,7 @@ public:
|
||||
// the real exit status
|
||||
ConLog.Write("sys_spu_thread_exit (status=0x%x)", SPU.Out_MBox.GetValue());
|
||||
}
|
||||
SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP);
|
||||
Stop();
|
||||
break;
|
||||
default:
|
||||
@ -1234,6 +1267,7 @@ public:
|
||||
{
|
||||
ConLog.Error("Unknown STOP code: 0x%x (message=0x%x)", code, SPU.Out_MBox.GetValue());
|
||||
}
|
||||
SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP);
|
||||
Stop();
|
||||
break;
|
||||
}
|
||||
|
@ -102,15 +102,15 @@ static func_caller* sc_table[kSyscallTableLength] =
|
||||
null_func,
|
||||
|
||||
null_func,//bind_func(sys_interrupt_tag_create) //80 (0x050)
|
||||
null_func,//bind_func(sys_interrupt_tag_destroy) //81 (0x051)
|
||||
bind_func(sys_interrupt_tag_destroy), //81 (0x051)
|
||||
bind_func(sys_event_flag_create), //82 (0x052)
|
||||
bind_func(sys_event_flag_destroy), //83 (0x053)
|
||||
null_func,//bind_func(sys_interrupt_thread_establish) //84 (0x054)
|
||||
bind_func(sys_interrupt_thread_establish), //84 (0x054)
|
||||
bind_func(sys_event_flag_wait), //85 (0x055)
|
||||
bind_func(sys_event_flag_trywait), //86 (0x056)
|
||||
bind_func(sys_event_flag_set), //87 (0x057)
|
||||
null_func,//bind_func(sys_interrupt_thread_eoi) //88 (0x058)
|
||||
null_func,//bind_func(sys_interrupt_thread_disestablish)//89 (0x059)
|
||||
bind_func(sys_interrupt_thread_eoi), //88 (0x058)
|
||||
bind_func(sys_interrupt_thread_disestablish), //89 (0x059)
|
||||
bind_func(sys_semaphore_create), //90 (0x05A)
|
||||
bind_func(sys_semaphore_destroy), //91 (0x05B)
|
||||
bind_func(sys_semaphore_wait), //92 (0x05C)
|
||||
@ -174,20 +174,20 @@ static func_caller* sc_table[kSyscallTableLength] =
|
||||
// Unused: 149
|
||||
null_func,
|
||||
|
||||
null_func,//bind_func(sys_raw_spu_create_interrupt_tag) //150 (0x096)
|
||||
null_func,//bind_func(sys_raw_spu_set_int_mask) //151 (0x097)
|
||||
null_func,//bind_func(sys_raw_spu_get_int_mask) //152 (0x098)
|
||||
null_func,//bind_func(sys_raw_spu_set_int_stat) //153 (0x099)
|
||||
null_func,//bind_func(sys_raw_spu_get_int_stat) //154 (0x09A)
|
||||
bind_func(sys_raw_spu_create_interrupt_tag), //150 (0x096)
|
||||
bind_func(sys_raw_spu_set_int_mask), //151 (0x097)
|
||||
bind_func(sys_raw_spu_get_int_mask), //152 (0x098)
|
||||
bind_func(sys_raw_spu_set_int_stat), //153 (0x099)
|
||||
bind_func(sys_raw_spu_get_int_stat), //154 (0x09A)
|
||||
null_func,//bind_func(sys_spu_image_get_information?) //155 (0x09B)
|
||||
bind_func(sys_spu_image_open), //156 (0x09C)
|
||||
null_func,//bind_func(sys_spu_image_import) //157 (0x09D)
|
||||
null_func,//bind_func(sys_spu_image_close) //158 (0x09E)
|
||||
null_func,//bind_func(sys_raw_spu_load) //159 (0x09F)
|
||||
bind_func(sys_raw_spu_create), //160 (0x0A0)
|
||||
null_func,//bind_func(sys_raw_spu_destroy) //161 (0x0A1)
|
||||
bind_func(sys_raw_spu_destroy), //161 (0x0A1)
|
||||
null_func, //
|
||||
null_func,//bind_func(sys_raw_spu_read_puint_mb) //163 (0x0A3)
|
||||
bind_func(sys_raw_spu_read_puint_mb), //163 (0x0A3)
|
||||
null_func, //
|
||||
bind_func(sys_spu_thread_get_exit_status), //165 (0x0A5)
|
||||
bind_func(sys_spu_thread_set_argument), //166 (0x0A6)
|
||||
@ -220,8 +220,8 @@ static func_caller* sc_table[kSyscallTableLength] =
|
||||
bind_func(sys_spu_thread_bind_queue), //193 (0x0C1)
|
||||
bind_func(sys_spu_thread_unbind_queue), //194 (0x0C2)
|
||||
null_func, //
|
||||
null_func,//bind_func(sys_raw_spu_set_spu_cfg) //196 (0x0C4)
|
||||
null_func,//bind_func(sys_raw_spu_get_spu_cfg) //197 (0x0C5)
|
||||
bind_func(sys_raw_spu_set_spu_cfg), //196 (0x0C4)
|
||||
bind_func(sys_raw_spu_get_spu_cfg), //197 (0x0C5)
|
||||
null_func,//bind_func(sys_spu_thread_recover_page_fault)//198 (0x0C6)
|
||||
null_func,//bind_func(sys_raw_spu_recover_page_fault) //199 (0x0C7)
|
||||
|
||||
|
@ -358,7 +358,6 @@ extern int sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et);
|
||||
extern int sys_spu_thread_group_disconnect_event(u32 id, u32 et);
|
||||
extern int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr);
|
||||
extern int sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup);
|
||||
extern int sys_raw_spu_create(mem32_t id, u32 attr_addr);
|
||||
extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
||||
extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
|
||||
extern int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type);
|
||||
@ -371,6 +370,22 @@ extern int sys_spu_thread_disconnect_event(u32 id, u32 event_type, u8 spup);
|
||||
extern int sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num);
|
||||
extern int sys_spu_thread_unbind_queue(u32 id, u32 spuq_num);
|
||||
extern int sys_spu_thread_get_exit_status(u32 id, mem32_t status);
|
||||
extern int sys_raw_spu_create(mem32_t id, u32 attr_addr);
|
||||
extern int sys_raw_spu_destroy(u32 id);
|
||||
extern int sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, mem32_t intrtag);
|
||||
extern int sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask);
|
||||
extern int sys_raw_spu_get_int_mask(u32 id, u32 class_id, mem64_t mask);
|
||||
extern int sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat);
|
||||
extern int sys_raw_spu_get_int_stat(u32 id, u32 class_id, mem64_t stat);
|
||||
extern int sys_raw_spu_read_puint_mb(u32 id, mem32_t value);
|
||||
extern int sys_raw_spu_set_spu_cfg(u32 id, u32 value);
|
||||
extern int sys_raw_spu_get_spu_cfg(u32 id, mem32_t value);
|
||||
|
||||
//sys_interrupt
|
||||
extern int sys_interrupt_tag_destroy(u32 intrtag);
|
||||
extern int sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 arg);
|
||||
extern int sys_interrupt_thread_disestablish(u32 ih);
|
||||
extern void sys_interrupt_thread_eoi();
|
||||
|
||||
//sys_time
|
||||
extern int sys_time_get_timezone(mem32_t timezone, mem32_t summertime);
|
||||
|
111
rpcs3/Emu/SysCalls/lv2/SC_Interrupt.cpp
Normal file
111
rpcs3/Emu/SysCalls/lv2/SC_Interrupt.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/ConLog.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 "SC_Interrupt.h"
|
||||
|
||||
static SysCallBase sc_int("sys_interrupt");
|
||||
|
||||
int sys_interrupt_tag_destroy(u32 intrtag)
|
||||
{
|
||||
sc_int.Error("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;
|
||||
}
|
||||
|
||||
int sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 arg)
|
||||
{
|
||||
sc_int.Error("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;
|
||||
}
|
||||
|
||||
int 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;
|
||||
}
|
1
rpcs3/Emu/SysCalls/lv2/SC_Interrupt.h
Normal file
1
rpcs3/Emu/SysCalls/lv2/SC_Interrupt.h
Normal file
@ -0,0 +1 @@
|
||||
#pragma once
|
@ -49,7 +49,7 @@ int sys_ppu_thread_yield()
|
||||
|
||||
int sys_ppu_thread_join(u64 thread_id, mem64_t vptr)
|
||||
{
|
||||
sysPrxForUser->Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr.GetAddr());
|
||||
sysPrxForUser->Warning("sys_ppu_thread_join(thread_id=%lld, vptr_addr=0x%x)", thread_id, vptr.GetAddr());
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if(!thr) return CELL_ESRCH;
|
||||
@ -70,7 +70,7 @@ int sys_ppu_thread_join(u64 thread_id, mem64_t vptr)
|
||||
|
||||
int sys_ppu_thread_detach(u64 thread_id)
|
||||
{
|
||||
sysPrxForUser->Error("sys_ppu_thread_detach(thread_id=%d)", thread_id);
|
||||
sysPrxForUser->Error("sys_ppu_thread_detach(thread_id=%lld)", thread_id);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if(!thr) return CELL_ESRCH;
|
||||
@ -90,7 +90,7 @@ void sys_ppu_thread_get_join_state(u32 isjoinable_addr)
|
||||
|
||||
int sys_ppu_thread_set_priority(u64 thread_id, int prio)
|
||||
{
|
||||
sysPrxForUser->Log("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio);
|
||||
sysPrxForUser->Log("sys_ppu_thread_set_priority(thread_id=%lld, prio=%d)", thread_id, prio);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if(!thr) return CELL_ESRCH;
|
||||
@ -102,7 +102,7 @@ int sys_ppu_thread_set_priority(u64 thread_id, int prio)
|
||||
|
||||
int sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr)
|
||||
{
|
||||
sysPrxForUser->Log("sys_ppu_thread_get_priority(thread_id=%d, prio_addr=0x%x)", thread_id, prio_addr);
|
||||
sysPrxForUser->Log("sys_ppu_thread_get_priority(thread_id=%lld, prio_addr=0x%x)", thread_id, prio_addr);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if(!thr) return CELL_ESRCH;
|
||||
@ -129,7 +129,7 @@ int sys_ppu_thread_get_stack_information(u32 info_addr)
|
||||
|
||||
int sys_ppu_thread_stop(u64 thread_id)
|
||||
{
|
||||
sysPrxForUser->Warning("sys_ppu_thread_stop(thread_id=%d)", thread_id);
|
||||
sysPrxForUser->Warning("sys_ppu_thread_stop(thread_id=%lld)", thread_id);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if(!thr) return CELL_ESRCH;
|
||||
@ -141,7 +141,7 @@ int sys_ppu_thread_stop(u64 thread_id)
|
||||
|
||||
int sys_ppu_thread_restart(u64 thread_id)
|
||||
{
|
||||
sysPrxForUser->Warning("sys_ppu_thread_restart(thread_id=%d)", thread_id);
|
||||
sysPrxForUser->Warning("sys_ppu_thread_restart(thread_id=%lld)", thread_id);
|
||||
|
||||
CPUThread* thr = Emu.GetCPU().GetThread(thread_id);
|
||||
if(!thr) return CELL_ESRCH;
|
||||
@ -158,12 +158,12 @@ int sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, int prio, u32 s
|
||||
if (Memory.IsGoodAddr(threadname_addr))
|
||||
{
|
||||
threadname = Memory.ReadString(threadname_addr);
|
||||
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
|
||||
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
|
||||
thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr, threadname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x)",
|
||||
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x)",
|
||||
thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr);
|
||||
if (threadname_addr != 0) return CELL_EFAULT;
|
||||
}
|
||||
@ -186,7 +186,6 @@ int sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, int prio, u32 s
|
||||
}
|
||||
case SYS_PPU_THREAD_CREATE_INTERRUPT:
|
||||
{
|
||||
sysPrxForUser->Error("sys_ppu_thread_create: unimplemented flag (SYS_PPU_THREAD_CREATE_INTERRUPT)");
|
||||
is_interrupt = true;
|
||||
break;
|
||||
}
|
||||
@ -201,12 +200,17 @@ int sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, int prio, u32 s
|
||||
new_thread.SetPrio(prio);
|
||||
new_thread.SetStackSize(stacksize);
|
||||
//new_thread.flags = flags;
|
||||
new_thread.m_has_interrupt = false;
|
||||
new_thread.m_is_interrupt = is_interrupt;
|
||||
new_thread.SetName(threadname);
|
||||
|
||||
ConLog.Write("*** New PPU Thread [%s] (flags=0x%llx, entry=0x%x): id = %d", new_thread.GetName().c_str(), flags, entry, new_thread.GetId());
|
||||
|
||||
if (!is_interrupt)
|
||||
{
|
||||
new_thread.Run();
|
||||
new_thread.Exec();
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -364,20 +364,6 @@ int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//160
|
||||
int sys_raw_spu_create(mem32_t id, u32 attr_addr)
|
||||
{
|
||||
sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id.GetAddr(), attr_addr);
|
||||
|
||||
//Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
|
||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU);
|
||||
id = ((RawSPUThread&)new_thread).GetIndex();
|
||||
new_thread.Run();
|
||||
new_thread.Exec();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//169
|
||||
int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
|
||||
{
|
||||
@ -760,3 +746,196 @@ int sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//160
|
||||
int sys_raw_spu_create(mem32_t id, u32 attr_addr)
|
||||
{
|
||||
sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id.GetAddr(), attr_addr);
|
||||
|
||||
//Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
|
||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU);
|
||||
id = ((RawSPUThread&)new_thread).GetIndex();
|
||||
new_thread.Run();
|
||||
new_thread.Exec();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_destroy(u32 id)
|
||||
{
|
||||
sc_spu.Error("sys_raw_spu_destroy(id=%d)", id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, mem32_t intrtag)
|
||||
{
|
||||
sc_spu.Error("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag_addr=0x%x)", id, class_id, hwthread, intrtag.GetAddr());
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (!intrtag.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
if (t->m_intrtag[class_id].enabled)
|
||||
{
|
||||
return CELL_EAGAIN;
|
||||
}
|
||||
|
||||
t->m_intrtag[class_id].enabled = 1;
|
||||
intrtag = (id & 0xff) | (class_id << 8);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask)
|
||||
{
|
||||
sc_spu.Warning("sys_raw_spu_set_int_mask(id=%d, class_id=%d, mask=0x%llx)", id, class_id, mask);
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
t->m_intrtag[class_id].mask = mask; // TODO: check this
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_get_int_mask(u32 id, u32 class_id, mem64_t mask)
|
||||
{
|
||||
sc_spu.Log("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask_addr=0x%x)", id, class_id, mask.GetAddr());
|
||||
|
||||
if (!mask.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
mask = t->m_intrtag[class_id].mask;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat)
|
||||
{
|
||||
sc_spu.Log("sys_raw_spu_set_int_stat(id=%d, class_id=%d, stat=0x%llx)", id, class_id, stat);
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
t->m_intrtag[class_id].stat = stat; // TODO: check this
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_get_int_stat(u32 id, u32 class_id, mem64_t stat)
|
||||
{
|
||||
sc_spu.Log("sys_raw_spu_get_int_stat(id=%d, class_id=%d, stat_addr=0xx)", id, class_id, stat.GetAddr());
|
||||
|
||||
if (!stat.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
stat = t->m_intrtag[class_id].stat;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_read_puint_mb(u32 id, mem32_t value)
|
||||
{
|
||||
sc_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value_addr=0x%x)", id, value.GetAddr());
|
||||
|
||||
if (!value.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
u32 v;
|
||||
t->SPU.Out_IntrMBox.PopUncond(v);
|
||||
value = v;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_set_spu_cfg(u32 id, u32 value)
|
||||
{
|
||||
sc_spu.Log("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value);
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
t->cfg.value = value;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_raw_spu_get_spu_cfg(u32 id, mem32_t value)
|
||||
{
|
||||
sc_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value_addr=0x%x)", id, value.GetAddr());
|
||||
|
||||
if (!value.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
|
||||
if (!t)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
value = t->cfg.value;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -97,6 +97,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_FileSystem.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_GCM.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Heap.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Interrupt.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Keyboard.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Lwcond.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Lwmutex.cpp" />
|
||||
@ -315,6 +316,7 @@
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Condition.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Event_flag.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_FileSystem.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Interrupt.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Lwcond.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Lwmutex.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Memory.h" />
|
||||
|
@ -578,6 +578,9 @@
|
||||
<ClCompile Include="..\Utilities\SSemaphore.cpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Interrupt.cpp">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
@ -1048,5 +1051,8 @@
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Semaphore.h">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\SysCalls\lv2\SC_Interrupt.h">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user