mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-06 06:55:09 +00:00
LV2/cellPad: Implement priority-based connection updates
This commit is contained in:
parent
a2416bf7f5
commit
4bbe885f35
8 changed files with 226 additions and 68 deletions
|
|
@ -3,6 +3,10 @@
|
|||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Emu/Cell/lv2/sys_ppu_thread.h"
|
||||
#include "Emu/Cell/Modules/sysPrxForUser.h"
|
||||
|
||||
LOG_CHANNEL(sys_io);
|
||||
|
||||
extern void cellPad_init();
|
||||
|
|
@ -13,53 +17,114 @@ struct libio_sys_config
|
|||
{
|
||||
shared_mutex mtx;
|
||||
s32 init_ctr = 0;
|
||||
u32 stack_addr = 0;
|
||||
u32 ppu_id = 0;
|
||||
u32 queue_id = 0;
|
||||
|
||||
~libio_sys_config() noexcept
|
||||
{
|
||||
if (stack_addr)
|
||||
{
|
||||
ensure(vm::dealloc(stack_addr, vm::stack));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Only exists internally (has no name)
|
||||
extern void libio_sys_config_init()
|
||||
extern void cellPad_NotifyStateChange(u32 index, u32 state);
|
||||
|
||||
void config_event_entry(ppu_thread& ppu)
|
||||
{
|
||||
auto& cfg = g_fxo->get<libio_sys_config>();
|
||||
|
||||
// Ensure awake
|
||||
ppu.check_state();
|
||||
|
||||
while (!sys_event_queue_receive(ppu, cfg.queue_id, vm::null, 0))
|
||||
{
|
||||
if (ppu.is_stopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Some delay
|
||||
thread_ctrl::wait_for(10000);
|
||||
|
||||
// Wakeup
|
||||
ppu.check_state();
|
||||
|
||||
const u64 arg1 = ppu.gpr[5];
|
||||
const u64 arg2 = ppu.gpr[6];
|
||||
const u64 arg3 = ppu.gpr[7];
|
||||
|
||||
// TODO: Reverse-engineer proper event system
|
||||
|
||||
if (arg1 == 1)
|
||||
{
|
||||
cellPad_NotifyStateChange(arg2, arg3);
|
||||
}
|
||||
}
|
||||
|
||||
ppu_execute<&sys_ppu_thread_exit>(ppu, 0);
|
||||
}
|
||||
|
||||
extern void send_sys_io_connect_event(u32 index, u32 state)
|
||||
{
|
||||
auto& cfg = g_fxo->get<libio_sys_config>();
|
||||
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
if (cfg.init_ctr)
|
||||
{
|
||||
if (auto port = idm::get<lv2_obj, lv2_event_queue>(cfg.queue_id))
|
||||
{
|
||||
port->send(0, 1, index, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_code sys_config_start(ppu_thread& ppu)
|
||||
{
|
||||
sys_io.warning("sys_config_start()");
|
||||
|
||||
auto& cfg = g_fxo->get<libio_sys_config>();
|
||||
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
if (cfg.init_ctr++ == 0)
|
||||
{
|
||||
// Belongs to "_cfg_evt_hndlr" thread (8k stack)
|
||||
cfg.stack_addr = ensure(vm::alloc(0x2000, vm::stack, 4096));
|
||||
// Run thread
|
||||
vm::var<u64> _tid;
|
||||
vm::var<u32> queue_id;
|
||||
vm::var<char[]> _name = vm::make_str("_cfg_evt_hndlr");
|
||||
|
||||
vm::var<sys_event_queue_attribute_t> attr;
|
||||
attr->protocol = SYS_SYNC_PRIORITY;
|
||||
attr->type = SYS_PPU_QUEUE;
|
||||
attr->name_u64 = 0;
|
||||
|
||||
ensure(CELL_OK == sys_event_queue_create(ppu, queue_id, attr, 0, 0x20));
|
||||
ensure(CELL_OK == ppu_execute<&sys_ppu_thread_create>(ppu, +_tid, g_fxo->get<ppu_function_manager>().func_addr(FIND_FUNC(config_event_entry)), 0, 512, 0x2000, SYS_PPU_THREAD_CREATE_JOINABLE, +_name));
|
||||
|
||||
cfg.ppu_id = static_cast<u32>(*_tid);
|
||||
cfg.queue_id = *queue_id;
|
||||
}
|
||||
}
|
||||
|
||||
extern void libio_sys_config_end()
|
||||
{
|
||||
auto& cfg = g_fxo->get<libio_sys_config>();
|
||||
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
if (cfg.init_ctr-- == 1)
|
||||
{
|
||||
ensure(vm::dealloc(std::exchange(cfg.stack_addr, 0), vm::stack));
|
||||
}
|
||||
}
|
||||
|
||||
error_code sys_config_start()
|
||||
{
|
||||
sys_io.todo("sys_config_start()");
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_config_stop()
|
||||
error_code sys_config_stop(ppu_thread& ppu)
|
||||
{
|
||||
sys_io.todo("sys_config_stop()");
|
||||
sys_io.warning("sys_config_stop()");
|
||||
|
||||
auto& cfg = g_fxo->get<libio_sys_config>();
|
||||
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
if (cfg.init_ctr && cfg.init_ctr-- == 1)
|
||||
{
|
||||
ensure(CELL_OK == sys_event_queue_destroy(ppu, cfg.queue_id, SYS_EVENT_QUEUE_DESTROY_FORCE));
|
||||
ensure(CELL_OK == sys_ppu_thread_join(ppu, cfg.ppu_id, +vm::var<u64>{}));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Unknown error
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
@ -114,4 +179,6 @@ DECLARE(ppu_module_manager::sys_io)("sys_io", []()
|
|||
REG_FUNC(sys_io, sys_config_register_service);
|
||||
REG_FUNC(sys_io, sys_config_unregister_io_error_handler);
|
||||
REG_FUNC(sys_io, sys_config_unregister_service);
|
||||
|
||||
REG_HIDDEN_FUNC(config_event_entry);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue