SPU refactoring

This commit is contained in:
Nekotekina 2015-03-03 00:09:20 +03:00
parent bc94d92cba
commit 5f8cf18a5a
42 changed files with 271 additions and 202 deletions

View File

@ -1,5 +1,4 @@
#pragma once
#include "Emu/Memory/atomic_type.h"
static std::thread::id main_thread;

View File

@ -115,10 +115,6 @@ public:
u32 offset;
bool m_is_branch;
bool m_trace_enabled;
bool m_is_interrupt;
bool m_has_interrupt;
u64 m_interrupt_arg;
u64 m_last_syscall;
protected:

View File

@ -130,11 +130,11 @@ std::shared_ptr<CPUThread> CPUThreadManager::GetThread(u32 id, CPUThreadType typ
return res;
}
RawSPUThread* CPUThreadManager::GetRawSPUThread(u32 num)
std::shared_ptr<CPUThread> CPUThreadManager::GetRawSPUThread(u32 num)
{
if (num < sizeof(Memory.RawSPUMem) / sizeof(Memory.RawSPUMem[0]))
{
return (RawSPUThread*)Memory.RawSPUMem[num];
return GetThread(((RawSPUThread*)Memory.RawSPUMem[num])->GetId());
}
else
{

View File

@ -22,7 +22,7 @@ public:
s32 GetThreadNumById(CPUThreadType type, u32 id);
std::shared_ptr<CPUThread> GetThread(u32 id);
std::shared_ptr<CPUThread> GetThread(u32 id, CPUThreadType type);
RawSPUThread* GetRawSPUThread(u32 num);
std::shared_ptr<CPUThread> GetRawSPUThread(u32 num);
void Exec();
void Task();

View File

@ -53,8 +53,6 @@ void PPUThread::DoReset()
FPSCR.FPSCR = 0;
VSCR.VSCR = 0;
VRSAVE = 0;
cycle = 0;
}
void PPUThread::InitRegs()

View File

@ -116,11 +116,11 @@ private:
}
void RDCH(u32 rt, u32 ra)
{
CPU.GPR[rt]._u32[3] = CPU.get_ch_value(ra);
CPU.GPR[rt] = u128::from32r(CPU.get_ch_value(ra));
}
void RCHCNT(u32 rt, u32 ra)
{
CPU.GPR[rt]._u32[3] = CPU.get_ch_count(ra);
CPU.GPR[rt] = u128::from32r(CPU.get_ch_count(ra));
}
void SF(u32 rt, u32 ra, u32 rb)
{
@ -432,8 +432,7 @@ private:
}
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
CPU.GPR[rt] = u128::from32r(CPU.PC + 4);
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
@ -1622,8 +1621,7 @@ private:
void BRASL(u32 rt, s32 i16)
{
u32 target = branchTarget(0, i16);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
CPU.GPR[rt] = u128::from32r(CPU.PC + 4);
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
@ -1652,8 +1650,7 @@ private:
void BRSL(u32 rt, s32 i16)
{
u32 target = branchTarget(CPU.PC, i16);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
CPU.GPR[rt] = u128::from32r(CPU.PC + 4);
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}

View File

@ -380,7 +380,7 @@ private:
static void STOP(u32 code)
{
SPUThread& CPU = *(SPUThread*)GetCurrentNamedThread();
CPU.StopAndSignal(code);
CPU.stop_and_signal(code);
LOG2_OPCODE();
}
};
@ -418,7 +418,7 @@ private:
{
c.mov(cpu_dword(PC), CPU.PC);
WRAPPER_BEGIN(rt, ra, yy, zz);
CPU.ReadChannel(CPU.GPR[rt], ra);
CPU.GPR[rt] = u128::from32r(CPU.get_ch_value(ra));
WRAPPER_END(rt, ra, 0, 0);
// TODO
}
@ -426,8 +426,7 @@ private:
{
c.mov(cpu_dword(PC), CPU.PC);
WRAPPER_BEGIN(rt, ra, yy, zz);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = CPU.GetChannelCount(ra);
CPU.GPR[rt] = u128::from32r(CPU.get_ch_count(ra));
WRAPPER_END(rt, ra, 0, 0);
// TODO
}
@ -1034,7 +1033,7 @@ private:
{
c.mov(cpu_dword(PC), CPU.PC);
WRAPPER_BEGIN(ra, rt, yy, zz);
CPU.WriteChannel(ra, CPU.GPR[rt]);
CPU.set_ch_value(ra, CPU.GPR[rt]._u32[3]);
WRAPPER_END(ra, rt, 0, 0);
// TODO

View File

@ -3,7 +3,6 @@
#include "Utilities/Log.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/IdManager.h"
#include "Emu/CPU/CPUThreadManager.h"
@ -562,24 +561,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value)
}
int2.set(SPU_INT2_STAT_MAILBOX_INT);
throw "";
//if (std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(m_intrtag[2].thread))
//{
// if (t->GetType() == CPU_THREAD_PPU)
// {
// if (t->IsAlive())
// {
// LOG_ERROR(SPU, "%s(%s): interrupt thread was alive", __FUNCTION__, spu_ch_name[ch]);
// Emu.Pause();
// return;
// }
// PPUThread& ppu = *(PPUThread*)t.get();
// ppu.GPR[3] = ppu.m_interrupt_arg;
// ppu.FastCall2(vm::read32(ppu.entry), vm::read32(ppu.entry + 4));
// }
//}
//return;
return;
}
else
{
@ -914,8 +896,7 @@ void SPUThread::stop_and_signal(u32 code)
Stop();
int2.set(SPU_INT2_STAT_SPU_STOP_AND_SIGNAL_INT);
throw "STOP"; // TODO
return;
}
switch (code)
@ -1093,7 +1074,7 @@ void SPUThread::stop_and_signal(u32 code)
status |= SPU_STATUS_STOPPED_BY_STOP;
Stop();
break;
return;
}
}
@ -1127,8 +1108,7 @@ void SPUThread::halt()
Stop();
int2.set(SPU_INT2_STAT_SPU_HALT_OR_STEP_INT);
throw "HALT"; // TODO
return;
}
status |= SPU_STATUS_STOPPED_BY_HALT;

View File

@ -2,8 +2,7 @@
#include "Emu/Cell/Common.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/Cell/SPUContext.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_event.h"
#include "Emu/Event.h"
#include "MFC.h"
@ -282,15 +281,27 @@ public:
}
};
struct spu_interrupt_t
struct spu_interrupt_tag_t
{
atomic_le_t<u64> mask;
atomic_le_t<u64> stat;
atomic_le_t<s32> assigned;
std::mutex handler_mutex;
std::condition_variable cond;
public:
void set(u64 ints)
{
stat |= mask.read_relaxed() & ints;
// leave only enabled interrupts
ints &= mask.read_relaxed();
if (ints && ~stat._or(ints) & ints)
{
// notify if at least 1 bit was set
cond.notify_all();
}
}
void clear(u64 ints)
@ -300,8 +311,10 @@ public:
void clear()
{
mask.write_relaxed({});
stat.write_relaxed({});
mask.write_relaxed(0);
stat.write_relaxed(0);
assigned.write_relaxed(-1);
}
};
@ -488,8 +501,8 @@ public:
atomic_le_t<u32> status; // SPU Status register
atomic_le_t<u32> npc; // SPU Next Program Counter register
spu_interrupt_t int0; // SPU Class 0 Interrupt Management
spu_interrupt_t int2; // SPU Class 2 Interrupt Management
spu_interrupt_tag_t int0; // SPU Class 0 Interrupt Management
spu_interrupt_tag_t int2; // SPU Class 2 Interrupt Management
u32 tg_id; // SPU Thread Group Id

View File

@ -1,8 +1,7 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_event.h"
#include "Event.h"

View File

@ -85,7 +85,7 @@ public:
}
// write data without memory barrier
__forceinline void write_relaxed(const T& value) volatile
__forceinline void write_relaxed(const T& value)
{
data = (atomic_type&)(value);
}

View File

@ -1,7 +1,5 @@
#pragma once
#include "Emu/Memory/atomic_type.h"
enum
{
CELL_GCM_DISPLAY_HSYNC = 1,

View File

@ -490,6 +490,27 @@ bool patch_ppu_import(u32 addr, u32 index)
return true;
}
if (vm::check_addr(addr, 64) &&
data[0x0] == MFLR(r0) &&
data[0x1] == STD(r0, r1, 0x10) &&
data[0x2] == STDU(r1, r1, -0x80) &&
data[0x3] == STD(r2, r1, 0x70) &&
(data[0x4] & 0xffff0000) == LIS(r12, 0) &&
(data[0x5] & 0xffff0000) == LWZ(r12, r12, 0) &&
data[0x6] == LWZ(r0, r12, 0) &&
data[0x7] == LWZ(r2, r12, 4) &&
data[0x8] == MTCTR(r0) &&
data[0x9] == BCTRL() &&
data[0xa] == LD(r2, r1, 0x70) &&
data[0xb] == ADDI(r1, r1, 0x80) &&
data[0xc] == LD(r0, r1, 0x10) &&
data[0xd] == MTLR(r0) &&
data[0xe] == BLR())
{
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
return true;
}
if (vm::check_addr(addr, 56) &&
(data[0x0] & 0xffff0000) == LI_(r12, 0) &&
(data[0x1] & 0xffff0000) == ORIS(r12, r12, 0) &&

View File

@ -3,10 +3,9 @@
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/Callback.h"
#include "Emu/Memory/atomic_type.h"
#include "rpcs3/Ini.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_time.h"
#include "Emu/SysCalls/lv2/sys_event.h"
#include "Emu/Event.h"

View File

@ -3,10 +3,9 @@
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_lwmutex.h"
#include "Emu/SysCalls/lv2/sys_lwcond.h"
#include "Emu/SysCalls/lv2/sys_spu.h"

View File

@ -2,9 +2,8 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_lwmutex.h"
#include "Emu/SysCalls/lv2/sys_lwcond.h"
#include "Emu/SysCalls/lv2/sys_spu.h"

View File

@ -3,9 +3,8 @@
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_event.h"
#include "Emu/SysCalls/lv2/sys_process.h"
#include "Emu/Event.h"

View File

@ -4,10 +4,10 @@
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/FS/vfsFile.h"
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
#include "Emu/SysCalls/lv2/sleep_queue.h"
#include "Emu/SysCalls/lv2/sys_interrupt.h"
#include "Emu/SysCalls/lv2/sys_spu.h"
#include "Emu/SysCalls/lv2/sys_lwmutex.h"
#include "Emu/SysCalls/lv2/sys_spinlock.h"
@ -263,6 +263,15 @@ s64 _sys_process_at_Exitspawn()
return CELL_OK;
}
s32 sys_interrupt_thread_disestablish(PPUThread& CPU, u32 ih)
{
sysPrxForUser.Todo("sys_interrupt_thread_disestablish(ih=%d)", ih);
vm::stackvar<u64> r13(CPU);
return _sys_interrupt_thread_disestablish(ih, r13);
}
int sys_process_is_stack(u32 p)
{
sysPrxForUser.Log("sys_process_is_stack(p=0x%x)", p);
@ -329,7 +338,7 @@ int sys_raw_spu_load(s32 id, vm::ptr<const char> path, vm::ptr<u32> entry)
u32 _entry;
LoadSpuImage(f, _entry, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id);
*entry = _entry;
*entry = _entry | 1;
return CELL_OK;
}
@ -598,6 +607,8 @@ Module sysPrxForUser("sysPrxForUser", []()
REG_FUNC(sysPrxForUser, _sys_process_at_Exitspawn);
REG_FUNC(sysPrxForUser, sys_process_is_stack);
REG_FUNC(sysPrxForUser, sys_interrupt_thread_disestablish);
REG_FUNC(sysPrxForUser, sys_ppu_thread_create);
REG_FUNC(sysPrxForUser, sys_ppu_thread_get_id);
REG_FUNC(sysPrxForUser, sys_ppu_thread_exit);

View File

@ -10,7 +10,7 @@ namespace sys_libc_func
{
void memcpy(vm::ptr<void> dst, vm::ptr<const void> src, u32 size)
{
sys_libc.Warning("memcpy(dst=0x%x, src=0x%x, size=0x%x)", dst, src, size);
sys_libc.Log("memcpy(dst=0x%x, src=0x%x, size=0x%x)", dst, src, size);
::memcpy(dst.get_ptr(), src.get_ptr(), size);
}

View File

@ -4,7 +4,7 @@
#include "Emu/IdManager.h"
#include "Utilities/Thread.h"
#include "lv2/sleep_queue_type.h"
#include "lv2/sleep_queue.h"
#include "lv2/sys_lwmutex.h"
#include "lv2/sys_lwcond.h"
#include "lv2/sys_mutex.h"

View File

@ -5,10 +5,9 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "ModuleManager.h"
#include "Emu/Memory/atomic_type.h"
#include "lv2/cellFs.h"
#include "lv2/sleep_queue_type.h"
#include "lv2/sleep_queue.h"
#include "lv2/sys_lwmutex.h"
#include "lv2/sys_mutex.h"
#include "lv2/sys_cond.h"
@ -133,7 +132,7 @@ const ppu_func_caller sc_table[1024] =
bind_func(sys_event_flag_trywait), //86 (0x056)
bind_func(sys_event_flag_set), //87 (0x057)
bind_func(sys_interrupt_thread_eoi), //88 (0x058)
bind_func(sys_interrupt_thread_disestablish), //89 (0x059)
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)

View File

@ -3,11 +3,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
sleep_queue_t::~sleep_queue_t()
{

View File

@ -2,11 +2,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_mutex.h"
#include "sys_cond.h"

View File

@ -2,11 +2,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Event.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_process.h"
#include "sys_event.h"

View File

@ -2,11 +2,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_event_flag.h"
SysCallBase sys_event_flag("sys_event_flag");

View File

@ -2,38 +2,47 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/RawSPUThread.h"
#include "sys_interrupt.h"
static SysCallBase sys_interrupt("sys_interrupt");
SysCallBase sys_interrupt("sys_interrupt");
s32 sys_interrupt_tag_destroy(u32 intrtag)
{
sys_interrupt.Warning("sys_interrupt_tag_destroy(intrtag=%d)", intrtag);
u32 id = intrtag & 0xff;
u32 class_id = intrtag >> 8;
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
const u32 class_id = intrtag >> 8;
if (!t || class_id > 2 || class_id == 1)
if (class_id != 0 && class_id != 2)
{
return CELL_ESRCH;
}
if (!t->m_intrtag[class_id].enabled)
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff);
if (!t)
{
return CELL_ESRCH;
}
if (t->m_intrtag[class_id].thread)
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
auto& tag = class_id ? spu.int2 : spu.int0;
if (s32 old = tag.assigned.compare_and_swap(0, -1))
{
return CELL_EBUSY;
if (old > 0)
{
return CELL_EBUSY;
}
return CELL_ESRCH;
}
t->m_intrtag[class_id].enabled = 0;
return CELL_OK;
}
@ -41,58 +50,99 @@ s32 sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u64 intrthread,
{
sys_interrupt.Warning("sys_interrupt_thread_establish(ih_addr=0x%x, intrtag=%d, intrthread=%lld, arg=0x%llx)", ih.addr(), intrtag, intrthread, arg);
u32 id = intrtag & 0xff;
u32 class_id = intrtag >> 8;
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
const u32 class_id = intrtag >> 8;
if (!t || class_id > 2 || class_id == 1)
if (class_id != 0 && class_id != 2)
{
return CELL_ESRCH;
}
if (!t->m_intrtag[class_id].enabled)
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff);
if (!t)
{
return CELL_ESRCH;
}
if (t->m_intrtag[class_id].thread) // ???
{
return CELL_ESTAT;
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
auto& tag = class_id ? spu.int2 : spu.int0;
// CELL_ESTAT is never returned (can't detect exact condition)
std::shared_ptr<CPUThread> it = Emu.GetCPU().GetThread((u32)intrthread);
std::shared_ptr<CPUThread> it = Emu.GetCPU().GetThread(intrthread);
if (!it)
{
return CELL_ESRCH;
}
if (it->m_has_interrupt || !it->m_is_interrupt)
std::shared_ptr<interrupt_handler_t> handler(new interrupt_handler_t{ it });
PPUThread& ppu = static_cast<PPUThread&>(*it);
{
return CELL_EAGAIN;
LV2_LOCK(0);
if (ppu.custom_task)
{
return CELL_EAGAIN;
}
if (s32 res = tag.assigned.atomic_op<s32>(CELL_OK, [](s32& value) -> s32
{
if (value < 0)
{
return CELL_ESRCH;
}
value++;
return CELL_OK;
}))
{
return res;
}
ppu.custom_task = [t, &tag, arg](PPUThread& CPU)
{
auto func = vm::ptr<void(u64 arg)>::make(CPU.entry);
std::unique_lock<std::mutex> cond_lock(tag.handler_mutex);
while (!Emu.IsStopped())
{
if (tag.stat.read_relaxed())
{
func(CPU, arg); // call interrupt handler until int status is clear
}
tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1));
}
};
}
*ih = (t->m_intrtag[class_id].thread = intrthread);
it->m_interrupt_arg = arg;
*ih = sys_interrupt.GetNewId(handler, TYPE_INTR_SERVICE_HANDLE);
ppu.Exec();
return CELL_OK;
}
s32 sys_interrupt_thread_disestablish(u32 ih)
s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr<u64> r13)
{
sys_interrupt.Todo("sys_interrupt_thread_disestablish(ih=%d)", ih);
sys_interrupt.Todo("_sys_interrupt_thread_disestablish(ih=%d)", ih);
std::shared_ptr<CPUThread> it = Emu.GetCPU().GetThread(ih);
if (!it)
std::shared_ptr<interrupt_handler_t> handler;
if (!sys_interrupt.CheckId(ih, handler))
{
return CELL_ESRCH;
}
if (!it->m_has_interrupt || !it->m_is_interrupt)
{
return CELL_ESRCH;
}
PPUThread& ppu = static_cast<PPUThread&>(*handler->handler);
// TODO: wait for sys_interrupt_thread_eoi() and destroy interrupt thread
*r13 = ppu.GPR[13];
return CELL_OK;
}
@ -101,5 +151,4 @@ void sys_interrupt_thread_eoi()
sys_interrupt.Log("sys_interrupt_thread_eoi()");
GetCurrentPPUThread().FastStop();
return;
}

View File

@ -1,7 +1,14 @@
#pragma once
class PPUThread;
struct interrupt_handler_t
{
std::shared_ptr<CPUThread> handler;
};
// SysCalls
s32 sys_interrupt_tag_destroy(u32 intrtag);
s32 sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u64 intrthread, u64 arg);
s32 sys_interrupt_thread_disestablish(u32 ih);
s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr<u64> r13);
void sys_interrupt_thread_eoi();

View File

@ -2,10 +2,9 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_lwmutex.h"
#include "sys_lwcond.h"

View File

@ -2,11 +2,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_lwmutex.h"

View File

@ -2,11 +2,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_mutex.h"

View File

@ -3,13 +3,12 @@
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sys_ppu_thread.h"
static SysCallBase sys_ppu_thread("sys_ppu_thread");
SysCallBase sys_ppu_thread("sys_ppu_thread");
static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU/*UUUUUUUUUUuuuuuuuuuu~~~~~~~~*/;
@ -183,10 +182,9 @@ PPUThread* ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool i
new_thread.SetPrio(prio);
new_thread.SetStackSize(stacksize);
new_thread.SetJoinable(is_joinable);
new_thread.m_has_interrupt = false;
new_thread.m_is_interrupt = is_interrupt;
new_thread.SetName(name);
new_thread.custom_task = task;
new_thread.Run();
sys_ppu_thread.Notice("*** New PPU Thread [%s] (%s, entry=0x%x): id = %d", name.c_str(),
is_interrupt ? "interrupt" :
@ -194,16 +192,9 @@ PPUThread* ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool i
if (!is_interrupt)
{
new_thread.Run();
new_thread.GPR[3] = arg;
new_thread.Exec();
}
else
{
new_thread.InitStack();
new_thread.InitRegs();
new_thread.DoRun();
}
return &new_thread;
}

View File

@ -2,10 +2,9 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_rwlock.h"

View File

@ -2,11 +2,10 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "sleep_queue_type.h"
#include "sleep_queue.h"
#include "sys_time.h"
#include "sys_semaphore.h"

View File

@ -2,7 +2,6 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "sys_spinlock.h"

View File

@ -11,7 +11,7 @@
#include "Crypto/unself.h"
#include "sys_spu.h"
static SysCallBase sys_spu("sys_spu");
SysCallBase sys_spu("sys_spu");
void LoadSpuImage(vfsStream& stream, u32& spu_ep, u32 addr)
{
@ -498,7 +498,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr<u32> cause, vm::ptr<u32> status)
{
if (!t->IsAlive())
{
if (((SPUThread*)t.get())->status.read_sync() != SPU_STATUS_STOPPED_BY_STOP)
if ((((SPUThread*)t.get())->status.read_sync() & SPU_STATUS_STOPPED_BY_STOP) != SPU_STATUS_STOPPED_BY_STOP)
{
all_threads_exit = false;
}
@ -946,13 +946,15 @@ s32 sys_raw_spu_destroy(u32 id)
{
sys_spu.Warning("sys_raw_spu_destroy(id=%d)", id);
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
// TODO: check if busy
Emu.GetCPU().RemoveThread(t->GetId());
@ -968,21 +970,23 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr
return CELL_EINVAL;
}
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
if (t->m_intrtag[class_id].enabled)
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
auto& tag = class_id ? spu.int2 : spu.int0;
if (!tag.assigned.compare_and_swap_test(-1, 0))
{
return CELL_EAGAIN;
}
t->m_intrtag[class_id].enabled = 1;
*intrtag = (id & 0xff) | (class_id << 8);
return CELL_OK;
}
@ -990,94 +994,109 @@ s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask)
{
sys_spu.Log("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 (class_id != 0 && class_id != 2)
{
return CELL_EINVAL;
}
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
switch (class_id)
{
case 0: t->int0.mask.write_relaxed(mask); return CELL_OK;
case 2: t->int2.mask.write_relaxed(mask); return CELL_OK;
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
return CELL_EINVAL;
(class_id ? spu.int2 : spu.int0).mask.exchange(mask);
return CELL_OK;
}
s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, vm::ptr<u64> mask)
{
sys_spu.Log("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask_addr=0x%x)", id, class_id, mask.addr());
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
if (class_id != 0 && class_id != 2)
{
return CELL_EINVAL;
}
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
switch (class_id)
{
case 0: *mask = t->int0.mask.read_relaxed(); return CELL_OK;
case 2: *mask = t->int2.mask.read_relaxed(); return CELL_OK;
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
return CELL_EINVAL;
*mask = (class_id ? spu.int2 : spu.int0).mask.read_sync();
return CELL_OK;
}
s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat)
{
sys_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 (class_id != 0 && class_id != 2)
{
return CELL_EINVAL;
}
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
switch (class_id)
{
case 0: t->int0.clear(stat); return CELL_OK;
case 2: t->int2.clear(stat); return CELL_OK;
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
return CELL_EINVAL;
(class_id ? spu.int2 : spu.int0).clear(stat);
return CELL_OK;
}
s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr<u64> stat)
{
sys_spu.Log("sys_raw_spu_get_int_stat(id=%d, class_id=%d, stat_addr=0xx)", id, class_id, stat.addr());
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
if (class_id != 0 && class_id != 2)
{
return CELL_EINVAL;
}
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
switch (class_id)
{
case 0: *stat = t->int0.stat.read_relaxed(); return CELL_OK;
case 2: *stat = t->int2.stat.read_relaxed(); return CELL_OK;
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
return CELL_EINVAL;
*stat = (class_id ? spu.int2 : spu.int0).stat.read_sync();
return CELL_OK;
}
s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr<u32> value)
{
sys_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value_addr=0x%x)", id, value.addr());
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
*value = t->ch_out_intr_mbox.pop_uncond();
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
*value = spu.ch_out_intr_mbox.pop_uncond();
return CELL_OK;
}
@ -1085,19 +1104,22 @@ s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value)
{
sys_spu.Log("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value);
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
if (value > 3)
{
sys_spu.Fatal("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value);
}
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
if (value > 3)
{
sys_spu.Fatal("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value);
}
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
spu.snr_config = value;
t->snr_config = value;
return CELL_OK;
}
@ -1105,14 +1127,17 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value)
{
sys_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value_addr=0x%x)", id, value.addr());
RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id);
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetRawSPUThread(id);
if (!t)
{
return CELL_ESRCH;
}
*value = (u32)t->snr_config;
RawSPUThread& spu = static_cast<RawSPUThread&>(*t);
*value = (u32)spu.snr_config;
return CELL_OK;
}

View File

@ -2,7 +2,6 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Memory/atomic_type.h"
#include "Emu/Event.h"
#include "sys_timer.h"

View File

@ -73,7 +73,7 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUTh
s_panel_margin_x->AddSpacer(12);
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
t2_instr->SetValue(wxString::Format("%08x", vm::read32(CPU->GetOffset() + pc)));
t2_instr->SetValue(wxString::Format("%08x", vm::read32(CPU->offset + pc)));
this->SetSizerAndFit(s_panel_margin_x);
@ -83,7 +83,7 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUTh
if (!t2_instr->GetValue().ToULong(&opcode, 16))
wxMessageBox("This instruction could not be parsed.\nNo changes were made.","Error");
else
vm::write32(CPU->GetOffset() + pc, (u32)opcode);
vm::write32(CPU->offset + pc, (u32)opcode);
}
}

View File

@ -248,10 +248,10 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
}
else
{
disasm->offset = vm::get_ptr<u8>(CPU->GetOffset());
disasm->offset = vm::get_ptr<u8>(CPU->offset);
for(uint i=0, count = 4; i<m_item_count; ++i, PC += count)
{
if(!vm::check_addr(CPU->GetOffset() + PC, 4))
if(!vm::check_addr(CPU->offset + PC, 4))
{
m_list->SetItem(i, 0, wxString(IsBreakPoint(PC) ? ">>> " : " ") + wxString::Format("[%08llx] illegal address", PC));
count = 4;
@ -259,7 +259,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
}
disasm->dump_pc = PC;
count = decoder->DecodeMemory(CPU->GetOffset() + PC);
count = decoder->DecodeMemory(CPU->offset + PC);
if(IsBreakPoint(PC))
{

View File

@ -178,7 +178,7 @@
<ClCompile Include="Emu\SysCalls\FuncList.cpp" />
<ClCompile Include="Emu\SysCalls\LogBase.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\cellFs.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sleep_queue_type.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sleep_queue.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_cond.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_event.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\sys_event_flag.cpp" />
@ -410,7 +410,7 @@
<ClInclude Include="Emu\Io\PadHandler.h" />
<ClInclude Include="Emu\Memory\Memory.h" />
<ClInclude Include="Emu\Memory\MemoryBlock.h" />
<ClInclude Include="Emu\Memory\atomic_type.h" />
<ClInclude Include="Emu\Memory\atomic.h" />
<ClInclude Include="Emu\RSX\CgBinaryProgram.h" />
<ClInclude Include="Emu\RSX\GCM.h" />
<ClInclude Include="Emu\RSX\GL\GLBuffers.h" />
@ -440,7 +440,7 @@
<ClInclude Include="Emu\SysCalls\ErrorCodes.h" />
<ClInclude Include="Emu\SysCalls\LogBase.h" />
<ClInclude Include="Emu\SysCalls\lv2\cellFs.h" />
<ClInclude Include="Emu\SysCalls\lv2\sleep_queue_type.h" />
<ClInclude Include="Emu\SysCalls\lv2\sleep_queue.h" />
<ClInclude Include="Emu\SysCalls\lv2\sys_cond.h" />
<ClInclude Include="Emu\SysCalls\lv2\sys_event.h" />
<ClInclude Include="Emu\SysCalls\lv2\sys_event_flag.h" />

View File

@ -650,9 +650,6 @@
<ClCompile Include="Emu\ARMv7\Modules\sceLibm.cpp">
<Filter>Emu\CPU\ARMv7\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\lv2\sleep_queue_type.cpp">
<Filter>Emu\SysCalls\lv2</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\SyncPrimitivesManager.cpp">
<Filter>Emu\SysCalls</Filter>
</ClCompile>
@ -860,6 +857,9 @@
<ClCompile Include="Emu\SysCalls\Modules\sys_libc.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\lv2\sleep_queue.cpp">
<Filter>Emu\SysCalls\lv2</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1447,9 +1447,6 @@
<ClInclude Include="Emu\SysCalls\SyncPrimitivesManager.h">
<Filter>Emu\SysCalls</Filter>
</ClInclude>
<ClInclude Include="Emu\Memory\atomic_type.h">
<Filter>Emu\Memory</Filter>
</ClInclude>
<ClInclude Include="Crypto\ec.h">
<Filter>Crypto</Filter>
</ClInclude>
@ -1459,9 +1456,6 @@
<ClInclude Include="Emu\ARMv7\PSVFuncList.h">
<Filter>Emu\CPU\ARMv7</Filter>
</ClInclude>
<ClInclude Include="Emu\SysCalls\lv2\sleep_queue_type.h">
<Filter>Emu\SysCalls\lv2</Filter>
</ClInclude>
<ClInclude Include="Emu\SysCalls\lv2\cellFs.h">
<Filter>Emu\SysCalls\lv2</Filter>
</ClInclude>
@ -1540,5 +1534,11 @@
<ClInclude Include="Emu\Cell\SPUContext.h">
<Filter>Emu\CPU\Cell</Filter>
</ClInclude>
<ClInclude Include="Emu\SysCalls\lv2\sleep_queue.h">
<Filter>Emu\SysCalls\lv2</Filter>
</ClInclude>
<ClInclude Include="Emu\Memory\atomic.h">
<Filter>Emu\Memory</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -62,5 +62,7 @@ template<typename T> __forceinline T align(const T addr, int align)
#include "Utilities/BEType.h"
#include "Utilities/StrFmt.h"
#include "Emu/Memory/atomic.h"
#define _PRGNAME_ "RPCS3"
#define _PRGVER_ "0.0.0.5"