sys_isolated_spu

This commit is contained in:
Eladash 2020-04-15 12:55:01 +03:00 committed by Ani
parent 921b1aadfb
commit a3f2dfa232
10 changed files with 296 additions and 55 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);