mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 08:21:29 +12:00
sys_isolated_spu
This commit is contained in:
parent
921b1aadfb
commit
a3f2dfa232
10 changed files with 296 additions and 55 deletions
|
@ -17,7 +17,7 @@ inline void try_start(spu_thread& spu)
|
|||
return false;
|
||||
}
|
||||
|
||||
value.status = SPU_STATUS_RUNNING;
|
||||
value.status = SPU_STATUS_RUNNING | (value.status & SPU_STATUS_IS_ISOLATED);
|
||||
return true;
|
||||
}).second)
|
||||
{
|
||||
|
|
|
@ -1659,6 +1659,9 @@ void spu_recompiler::RDCH(spu_opcode_t op)
|
|||
{
|
||||
const XmmLink& vr = XmmAlloc();
|
||||
c->movzx(*addr, SPU_OFF_8(interrupts_enabled));
|
||||
c->movzx(arg1->r32(), SPU_OFF_8(is_isolated));
|
||||
c->shl(arg1->r32(), 1);
|
||||
c->or_(addr->r32(), arg1->r32());
|
||||
c->movd(vr, *addr);
|
||||
c->pslldq(vr, 12);
|
||||
c->movdqa(SPU_OFF_128(gpr, op.rt), vr);
|
||||
|
|
|
@ -5500,6 +5500,7 @@ public:
|
|||
case SPU_RdMachStat:
|
||||
{
|
||||
res.value = m_ir->CreateZExt(m_ir->CreateLoad(spu_ptr<u8>(&spu_thread::interrupts_enabled)), get_type<u32>());
|
||||
res.value = m_ir->CreateOr(res.value, m_ir->CreateShl(m_ir->CreateZExt(m_ir->CreateLoad(spu_ptr<u8>(&spu_thread::is_isolated)), get_type<u32>()), m_ir->getInt32(1)));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1131,8 +1131,8 @@ void spu_thread::cpu_init()
|
|||
mfc_prxy_write_state = {};
|
||||
}
|
||||
|
||||
status_npc.raw() = {is_isolated ? SPU_STATUS_IS_ISOLATED : 0, 0};
|
||||
run_ctrl.raw() = 0;
|
||||
status_npc.raw() = {};
|
||||
|
||||
int_ctrl[0].clear();
|
||||
int_ctrl[1].clear();
|
||||
|
@ -1218,7 +1218,7 @@ void spu_thread::cpu_task()
|
|||
name_cache = cpu->spu_tname.load();
|
||||
}
|
||||
|
||||
return fmt::format("%sSPU[0x%07x] Thread (%s) [0x%05x]", cpu->offset >= RAW_SPU_BASE_ADDR ? "Raw" : "", cpu->lv2_id, *name_cache.get(), cpu->pc);
|
||||
return fmt::format("%sSPU[0x%07x] Thread (%s) [0x%05x]", cpu->offset >= RAW_SPU_BASE_ADDR ? cpu->is_isolated ? "Iso" : "Raw" : "", cpu->lv2_id, *name_cache.get(), cpu->pc);
|
||||
};
|
||||
|
||||
if (jit)
|
||||
|
@ -1286,8 +1286,9 @@ spu_thread::~spu_thread()
|
|||
}
|
||||
}
|
||||
|
||||
spu_thread::spu_thread(vm::addr_t ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id)
|
||||
spu_thread::spu_thread(vm::addr_t ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated)
|
||||
: cpu_thread(idm::last_id())
|
||||
, is_isolated(is_isolated)
|
||||
, index(index)
|
||||
, offset(ls)
|
||||
, group(group)
|
||||
|
@ -2591,9 +2592,8 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
|
||||
case SPU_RdMachStat:
|
||||
{
|
||||
// HACK: "Not isolated" status
|
||||
// Return SPU Interrupt status in LSB
|
||||
return interrupts_enabled == true;
|
||||
return u32{interrupts_enabled} | (u32{is_isolated} << 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,14 +100,14 @@ enum : u64
|
|||
SPU_INT2_STAT_SPU_MAILBOX_THRESHOLD_INT = (1ull << 4),
|
||||
};
|
||||
|
||||
enum
|
||||
enum : u32
|
||||
{
|
||||
SPU_RUNCNTL_STOP_REQUEST = 0,
|
||||
SPU_RUNCNTL_RUN_REQUEST = 1,
|
||||
};
|
||||
|
||||
// SPU Status Register bits (not accurate)
|
||||
enum
|
||||
enum : u32
|
||||
{
|
||||
SPU_STATUS_STOPPED = 0x0,
|
||||
SPU_STATUS_RUNNING = 0x1,
|
||||
|
@ -115,6 +115,7 @@ enum
|
|||
SPU_STATUS_STOPPED_BY_HALT = 0x4,
|
||||
SPU_STATUS_WAITING_FOR_CHANNEL = 0x8,
|
||||
SPU_STATUS_SINGLE_STEP = 0x10,
|
||||
SPU_STATUS_IS_ISOLATED = 0x80,
|
||||
};
|
||||
|
||||
enum : u32
|
||||
|
@ -514,7 +515,7 @@ public:
|
|||
static const u32 id_step = 1;
|
||||
static const u32 id_count = 2048;
|
||||
|
||||
spu_thread(vm::addr_t ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id);
|
||||
spu_thread(vm::addr_t ls, lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated = false);
|
||||
|
||||
u32 pc = 0;
|
||||
|
||||
|
@ -592,8 +593,8 @@ public:
|
|||
u32 npc; // SPU Next Program Counter register
|
||||
};
|
||||
|
||||
const bool is_isolated;
|
||||
atomic_t<status_npc_sync_var> status_npc;
|
||||
|
||||
std::array<spu_int_ctrl_t, 3> int_ctrl; // SPU Class 0, 1, 2 Interrupt Management
|
||||
|
||||
std::array<std::pair<u32, std::weak_ptr<lv2_event_queue>>, 32> spuq; // Event Queue Keys for SPU Thread
|
||||
|
|
|
@ -289,17 +289,17 @@ const std::array<ppu_function_t, 1024> s_ppu_syscall_table
|
|||
null_func, null_func, null_func, null_func, null_func, //224 UNS
|
||||
null_func, null_func, null_func, null_func, null_func, //229 UNS?
|
||||
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_create) //230 (0x0E6) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_destroy) //231 (0x0E7) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_start) //232 (0x0E8) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_create_interrupt_tag) //233 (0x0E9) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_set_int_mask) //234 (0x0EA) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_get_int_mask) //235 (0x0EB) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_set_int_stat) //236 (0x0EC) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_get_int_stat) //237 (0x0ED) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_set_spu_cfg) //238 (0x0EE) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_get_spu_cfg) //239 (0x0EF) ROOT
|
||||
null_func,//BIND_FUNC(sys_isolated_spu_read_puint_mb) //240 (0x0F0) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_create), //230 (0x0E6) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_destroy), //231 (0x0E7) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_start), //232 (0x0E8) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_create_interrupt_tag), //233 (0x0E9) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_set_int_mask), //234 (0x0EA) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_get_int_mask), //235 (0x0EB) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_set_int_stat), //236 (0x0EC) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_get_int_stat), //237 (0x0ED) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_set_spu_cfg), //238 (0x0EE) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_get_spu_cfg), //239 (0x0EF) ROOT
|
||||
BIND_FUNC(sys_isolated_spu_read_puint_mb), //240 (0x0F0) ROOT
|
||||
uns_func, uns_func, uns_func, //241-243 ROOT UNS
|
||||
null_func,//BIND_FUNC(sys_spu_thread_group_system_set_next_group) //244 (0x0F4) ROOT
|
||||
null_func,//BIND_FUNC(sys_spu_thread_group_system_unset_next_group) //245 (0x0F5) ROOT
|
||||
|
@ -778,9 +778,9 @@ const std::array<ppu_function_t, 1024> s_ppu_syscall_table
|
|||
null_func,//BIND_FUNC(sys_ss_update_manager) //863 ROOT
|
||||
null_func,//BIND_FUNC(sys_ss_sec_hw_framework) //864 DBG
|
||||
BIND_FUNC(sys_ss_random_number_generator), //865 (0x361)
|
||||
null_func,//BIND_FUNC(sys_ss_secure_rtc) //866 ROOT
|
||||
BIND_FUNC(sys_ss_secure_rtc), //866 ROOT
|
||||
null_func,//BIND_FUNC(sys_ss_appliance_info_manager) //867 ROOT
|
||||
null_func,//BIND_FUNC(sys_ss_individual_info_manager) //868 ROOT / DBG AUTHID
|
||||
BIND_FUNC(sys_ss_individual_info_manager), //868 ROOT / DBG AUTHID
|
||||
null_func,//BIND_FUNC(sys_ss_factory_data_manager) //869 ROOT
|
||||
BIND_FUNC(sys_ss_get_console_id), //870 (0x366)
|
||||
BIND_FUNC(sys_ss_access_control_engine), //871 (0x367) DBG
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "sys_interrupt.h"
|
||||
#include "sys_process.h"
|
||||
|
@ -1684,22 +1685,86 @@ error_code sys_raw_spu_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<void> at
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
||||
error_code sys_isolated_spu_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<void> image, u64 arg1, u64 arg2, u64 arg3, u64 arg4)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.warning("sys_raw_spu_destroy(id=%d)", id);
|
||||
sys_spu.todo("sys_isolated_spu_create(id=*0x%x, image=*0x%x, arg1=0x%llx, arg2=0x%llx, arg3=0x%llx, arg4=0x%llx)", id, image, arg1, arg2, arg3, arg4);
|
||||
|
||||
// TODO: More accurate SPU image memory size calculation
|
||||
u32 max = image.addr() & -4096;
|
||||
|
||||
while (max != 0u - 4096 && vm::check_addr(max))
|
||||
{
|
||||
max += 4096;
|
||||
}
|
||||
|
||||
const auto obj = decrypt_self(fs::file{image.get_ptr(), max - image.addr()});
|
||||
|
||||
if (!obj)
|
||||
{
|
||||
return CELL_EAUTHFAIL;
|
||||
}
|
||||
|
||||
// TODO: check number set by sys_spu_initialize()
|
||||
|
||||
if (!spu_thread::g_raw_spu_ctr.try_inc(5))
|
||||
{
|
||||
return CELL_EAGAIN;
|
||||
}
|
||||
|
||||
u32 index = 0;
|
||||
|
||||
// Find free RawSPU ID
|
||||
while (!spu_thread::g_raw_spu_id[index].try_inc(1))
|
||||
{
|
||||
if (++index == 5)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
const vm::addr_t ls_addr{verify(HERE, vm::falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, 0x40000, vm::spu))};
|
||||
|
||||
const auto thread = idm::make_ptr<named_thread<spu_thread>>(fmt::format("IsoSPU[0x%x] Thread", index), ls_addr, nullptr, index, "", index, true);
|
||||
|
||||
thread->gpr[3] = v128::from64(0, arg1);
|
||||
thread->gpr[4] = v128::from64(0, arg2);
|
||||
thread->gpr[5] = v128::from64(0, arg3);
|
||||
thread->gpr[6] = v128::from64(0, arg4);
|
||||
|
||||
spu_thread::g_raw_spu_id[index] = verify("IsoSPU ID" HERE, thread->id);
|
||||
|
||||
sys_spu_image img;
|
||||
img.load(obj);
|
||||
|
||||
auto image_info = idm::get<lv2_obj, lv2_spu_image>(img.entry_point);
|
||||
img.deploy(ls_addr, image_info->segs.get_ptr(), image_info->nsegs);
|
||||
|
||||
thread->write_reg(ls_addr + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, image_info->e_entry);
|
||||
verify(HERE), idm::remove_verify<lv2_obj, lv2_spu_image>(img.entry_point, std::move(image_info));
|
||||
|
||||
*id = index;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_destroy(ppu_thread& ppu, u32 id)
|
||||
{
|
||||
const u32 idm_id = spu_thread::find_raw_spu(id);
|
||||
|
||||
auto thread = idm::get<named_thread<spu_thread>>(idm_id, [](named_thread<spu_thread>& thread)
|
||||
{
|
||||
if (thread.is_isolated != isolated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stop thread
|
||||
thread.state += cpu_flag::exit;
|
||||
thread = thread_state::aborting;
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || !thread.ret) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -1749,7 +1814,7 @@ error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
|||
|
||||
(*thread)();
|
||||
|
||||
if (!idm::remove_verify<named_thread<spu_thread>>(idm_id, std::move(thread)))
|
||||
if (!idm::remove_verify<named_thread<spu_thread>>(idm_id, std::move(thread.ptr)))
|
||||
{
|
||||
// Other thread destroyed beforehead
|
||||
return CELL_ESRCH;
|
||||
|
@ -1758,12 +1823,27 @@ error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_raw_spu_create_interrupt_tag(ppu_thread& ppu, u32 id, u32 class_id, u32 hwthread, vm::ptr<u32> intrtag)
|
||||
error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.warning("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag=*0x%x)", id, class_id, hwthread, intrtag);
|
||||
sys_spu.warning("sys_raw_spu_destroy(id=%d)", id);
|
||||
|
||||
return raw_spu_destroy(ppu, id);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_destroy(ppu_thread& ppu, u32 id)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_destroy(id=%d)", id);
|
||||
|
||||
return raw_spu_destroy<true>(ppu, id);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr<u32> intrtag)
|
||||
{
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
|
@ -1777,7 +1857,7 @@ error_code sys_raw_spu_create_interrupt_tag(ppu_thread& ppu, u32 id, u32 class_i
|
|||
|
||||
auto thread = idm::check_unlocked<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread || *thread == thread_state::aborting)
|
||||
if (!thread || *thread == thread_state::aborting || thread->is_isolated != isolated)
|
||||
{
|
||||
error = CELL_ESRCH;
|
||||
return result;
|
||||
|
@ -1805,12 +1885,27 @@ error_code sys_raw_spu_create_interrupt_tag(ppu_thread& ppu, u32 id, u32 class_i
|
|||
return error;
|
||||
}
|
||||
|
||||
error_code sys_raw_spu_set_int_mask(ppu_thread& ppu, u32 id, u32 class_id, u64 mask)
|
||||
error_code sys_raw_spu_create_interrupt_tag(ppu_thread& ppu, u32 id, u32 class_id, u32 hwthread, vm::ptr<u32> intrtag)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.trace("sys_raw_spu_set_int_mask(id=%d, class_id=%d, mask=0x%llx)", id, class_id, mask);
|
||||
sys_spu.warning("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag=*0x%x)", id, class_id, hwthread, intrtag);
|
||||
|
||||
return raw_spu_create_interrupt_tag(id, class_id, hwthread, intrtag);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_create_interrupt_tag(ppu_thread& ppu, u32 id, u32 class_id, u32 hwthread, vm::ptr<u32> intrtag)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag=*0x%x)", id, class_id, hwthread, intrtag);
|
||||
|
||||
return raw_spu_create_interrupt_tag<true>(id, class_id, hwthread, intrtag);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask)
|
||||
{
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
|
@ -1818,7 +1913,7 @@ error_code sys_raw_spu_set_int_mask(ppu_thread& ppu, u32 id, u32 class_id, u64 m
|
|||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -1828,12 +1923,28 @@ error_code sys_raw_spu_set_int_mask(ppu_thread& ppu, u32 id, u32 class_id, u64 m
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_raw_spu_get_int_mask(ppu_thread& ppu, u32 id, u32 class_id, vm::ptr<u64> mask)
|
||||
error_code sys_raw_spu_set_int_mask(ppu_thread& ppu, u32 id, u32 class_id, u64 mask)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.trace("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask=*0x%x)", id, class_id, mask);
|
||||
sys_spu.trace("sys_raw_spu_set_int_mask(id=%d, class_id=%d, mask=0x%llx)", id, class_id, mask);
|
||||
|
||||
return raw_spu_set_int_mask(id, class_id, mask);
|
||||
}
|
||||
|
||||
|
||||
error_code sys_isolated_spu_set_int_mask(ppu_thread& ppu, u32 id, u32 class_id, u64 mask)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_set_int_mask(id=%d, class_id=%d, mask=0x%llx)", id, class_id, mask);
|
||||
|
||||
return raw_spu_set_int_mask<true>(id, class_id, mask);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat)
|
||||
{
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
|
@ -1841,12 +1952,12 @@ error_code sys_raw_spu_get_int_mask(ppu_thread& ppu, u32 id, u32 class_id, vm::p
|
|||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
*mask = thread->int_ctrl[class_id].mask;
|
||||
thread->int_ctrl[class_id].clear(stat);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1857,6 +1968,21 @@ error_code sys_raw_spu_set_int_stat(ppu_thread& ppu, u32 id, u32 class_id, u64 s
|
|||
|
||||
sys_spu.trace("sys_raw_spu_set_int_stat(id=%d, class_id=%d, stat=0x%llx)", id, class_id, stat);
|
||||
|
||||
return raw_spu_set_int_stat(id, class_id, stat);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_set_int_stat(ppu_thread& ppu, u32 id, u32 class_id, u64 stat)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_set_int_stat(id=%d, class_id=%d, stat=0x%llx)", id, class_id, stat);
|
||||
|
||||
return raw_spu_set_int_stat<true>(id, class_id, stat);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_get_int_control(u32 id, u32 class_id, vm::ptr<u64> value, atomic_t<u64> spu_int_ctrl_t::* control)
|
||||
{
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
|
@ -1864,35 +1990,63 @@ error_code sys_raw_spu_set_int_stat(ppu_thread& ppu, u32 id, u32 class_id, u64 s
|
|||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
thread->int_ctrl[class_id].clear(stat);
|
||||
*value = thread->int_ctrl[class_id].*control;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_raw_spu_get_int_mask(ppu_thread& ppu, u32 id, u32 class_id, vm::ptr<u64> mask)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.trace("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask=*0x%x)", id, class_id, mask);
|
||||
|
||||
return raw_spu_get_int_control(id, class_id, mask, &spu_int_ctrl_t::mask);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_get_int_mask(ppu_thread& ppu, u32 id, u32 class_id, vm::ptr<u64> mask)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.trace("sys_isolated_spu_get_int_mask(id=%d, class_id=%d, mask=*0x%x)", id, class_id, mask);
|
||||
|
||||
return raw_spu_get_int_control<true>(id, class_id, mask, &spu_int_ctrl_t::mask);
|
||||
}
|
||||
|
||||
error_code sys_raw_spu_get_int_stat(ppu_thread& ppu, u32 id, u32 class_id, vm::ptr<u64> stat)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.trace("sys_raw_spu_get_int_stat(id=%d, class_id=%d, stat=*0x%x)", id, class_id, stat);
|
||||
|
||||
if (class_id != 0 && class_id != 2)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
return raw_spu_get_int_control(id, class_id, stat, &spu_int_ctrl_t::stat);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_get_int_stat(ppu_thread& ppu, u32 id, u32 class_id, vm::ptr<u64> stat)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_get_int_stat(id=%d, class_id=%d, stat=*0x%x)", id, class_id, stat);
|
||||
|
||||
return raw_spu_get_int_control<true>(id, class_id, stat, &spu_int_ctrl_t::stat);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_read_puint_mb(u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
*stat = thread->int_ctrl[class_id].stat;
|
||||
*value = thread->ch_out_intr_mbox.pop(*thread);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1903,14 +2057,34 @@ error_code sys_raw_spu_read_puint_mb(ppu_thread& ppu, u32 id, vm::ptr<u32> value
|
|||
|
||||
sys_spu.trace("sys_raw_spu_read_puint_mb(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
return raw_spu_read_puint_mb(id, value);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_read_puint_mb(ppu_thread& ppu, u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_read_puint_mb(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
return raw_spu_read_puint_mb<true>(id, value);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_set_spu_cfg(u32 id, u32 value)
|
||||
{
|
||||
if (value > 3)
|
||||
{
|
||||
fmt::throw_exception("Unexpected value (0x%x)" HERE, value);
|
||||
}
|
||||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
*value = thread->ch_out_intr_mbox.pop(*thread);
|
||||
thread->snr_config = value;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1921,19 +2095,29 @@ error_code sys_raw_spu_set_spu_cfg(ppu_thread& ppu, u32 id, u32 value)
|
|||
|
||||
sys_spu.trace("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value);
|
||||
|
||||
if (value > 3)
|
||||
{
|
||||
fmt::throw_exception("Unexpected value (0x%x)" HERE, value);
|
||||
}
|
||||
return raw_spu_set_spu_cfg(id, value);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_set_spu_cfg(ppu_thread& ppu, u32 id, u32 value)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_set_spu_cfg(id=%d, value=0x%x)", id, value);
|
||||
|
||||
return raw_spu_set_spu_cfg<true>(id, value);
|
||||
}
|
||||
|
||||
template <bool isolated = false>
|
||||
error_code raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
if (!thread || thread->is_isolated != isolated) [[unlikely]]
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
thread->snr_config = value;
|
||||
*value = static_cast<u32>(thread->snr_config);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1944,6 +2128,24 @@ error_code sys_raw_spu_get_spu_cfg(ppu_thread& ppu, u32 id, vm::ptr<u32> value)
|
|||
|
||||
sys_spu.trace("sys_raw_spu_get_spu_afg(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
return raw_spu_get_spu_cfg(id, value);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_get_spu_cfg(ppu_thread& ppu, u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_get_spu_afg(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
return raw_spu_get_spu_cfg<true>(id, value);
|
||||
}
|
||||
|
||||
error_code sys_isolated_spu_start(ppu_thread& ppu, u32 id)
|
||||
{
|
||||
vm::temporary_unlock(ppu);
|
||||
|
||||
sys_spu.todo("sys_isolated_spu_start(id=%d)", id);
|
||||
|
||||
const auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu(id));
|
||||
|
||||
if (!thread) [[unlikely]]
|
||||
|
@ -1951,7 +2153,7 @@ error_code sys_raw_spu_get_spu_cfg(ppu_thread& ppu, u32 id, vm::ptr<u32> value)
|
|||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
*value = static_cast<u32>(thread->snr_config);
|
||||
|
||||
// TODO: Can return ESTAT if called twice
|
||||
thread->write_reg(thread->offset + RAW_SPU_PROB_OFFSET + SPU_RunCntl_offs, SPU_RUNCNTL_RUN_REQUEST);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -380,3 +380,15 @@ error_code sys_raw_spu_read_puint_mb(ppu_thread&, u32 id, vm::ptr<u32> value);
|
|||
error_code sys_raw_spu_set_spu_cfg(ppu_thread&, u32 id, u32 value);
|
||||
error_code sys_raw_spu_get_spu_cfg(ppu_thread&, u32 id, vm::ptr<u32> value);
|
||||
error_code sys_raw_spu_recover_page_fault(ppu_thread&, u32 id);
|
||||
|
||||
error_code sys_isolated_spu_create(ppu_thread&, vm::ptr<u32> id, vm::ptr<void> image, u64 arg1, u64 arg2, u64 arg3, u64 arg4);
|
||||
error_code sys_isolated_spu_start(ppu_thread&, u32 id);
|
||||
error_code sys_isolated_spu_destroy(ppu_thread& ppu, u32 id);
|
||||
error_code sys_isolated_spu_create_interrupt_tag(ppu_thread&, u32 id, u32 class_id, u32 hwthread, vm::ptr<u32> intrtag);
|
||||
error_code sys_isolated_spu_set_int_mask(ppu_thread&, u32 id, u32 class_id, u64 mask);
|
||||
error_code sys_isolated_spu_get_int_mask(ppu_thread&, u32 id, u32 class_id, vm::ptr<u64> mask);
|
||||
error_code sys_isolated_spu_set_int_stat(ppu_thread&, u32 id, u32 class_id, u64 stat);
|
||||
error_code sys_isolated_spu_get_int_stat(ppu_thread&, u32 id, u32 class_id, vm::ptr<u64> stat);
|
||||
error_code sys_isolated_spu_read_puint_mb(ppu_thread&, u32 id, vm::ptr<u32> value);
|
||||
error_code sys_isolated_spu_set_spu_cfg(ppu_thread&, u32 id, u32 value);
|
||||
error_code sys_isolated_spu_get_spu_cfg(ppu_thread&, u32 id, vm::ptr<u32> value);
|
||||
|
|
|
@ -190,3 +190,24 @@ error_code sys_ss_virtual_trm_manager(u64 pkg_id, u64 a1, u64 a2, u64 a3, u64 a4
|
|||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_ss_individual_info_manager(u64 pkg_id, u64 a2, vm::ptr<u64> out_size, u64 a4, u64 a5, u64 a6)
|
||||
{
|
||||
sys_ss.todo("sys_ss_individual_info_manager(pkg=0x%llx, a2=0x%llx, out_size=*0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", pkg_id, a2, out_size, a4, a5, a6);
|
||||
|
||||
switch (pkg_id)
|
||||
{
|
||||
// Read EID
|
||||
case 0x17002:
|
||||
{
|
||||
// TODO
|
||||
vm::_ref<u64>(a5) = a4; // Write back size of buffer
|
||||
break;
|
||||
}
|
||||
// Get EID size
|
||||
case 0x17001: *out_size = 0x100; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
|
@ -29,3 +29,4 @@ error_code sys_ss_get_cache_of_flash_ext_flag(vm::ptr<u64> flag);
|
|||
error_code sys_ss_get_boot_device(vm::ptr<u64> dev);
|
||||
error_code sys_ss_update_manager(u64 pkg_id, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
|
||||
error_code sys_ss_virtual_trm_manager(u64 pkg_id, u64 a1, u64 a2, u64 a3, u64 a4);
|
||||
error_code sys_ss_individual_info_manager(u64 pkg_id, u64 a2, vm::ptr<u64> out_size, u64 a4, u64, u64 a5);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue