diff --git a/rpcs3/Emu/Cell/Modules/sys_prx_.cpp b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp index 1d8ddc7aa9..1aaed756de 100644 --- a/rpcs3/Emu/Cell/Modules/sys_prx_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp @@ -7,21 +7,254 @@ extern logs::channel sysPrxForUser; -s64 sys_prx_exitspawn_with_level() +// Convert the array of 32-bit pointers to 64-bit pointers using stack allocation +static auto convert_path_list(vm::cpptr path_list, s32 count) { - sysPrxForUser.trace("sys_prx_exitspawn_with_level()"); + vm::var[]> result(count); + + for (s32 i = 0; i < count; i++) + { + result[i] = path_list[i]; + } + + return std::move(result); +} + +// Execute start or stop module function +static void entryx(ppu_thread& ppu, vm::ptr opt, u32 args, vm::ptr argp, vm::ptr res) +{ + if (opt->entry2.addr() != -1) + { + *res = opt->entry2(ppu, opt->entry, args, argp); + return; + } + + if (opt->entry.addr() != -1) + { + *res = opt->entry(ppu, args, argp); + return; + } +} + +error_code sys_prx_load_module(vm::cptr path, u64 flags, vm::ptr pOpt) +{ + sysPrxForUser.warning("sys_prx_load_module(path=%s, flags=0x%x, pOpt=*0x%x)", path, flags, pOpt); + + // TODO + return _sys_prx_load_module(path, flags, pOpt); +} + +error_code sys_prx_load_module_by_fd(s32 fd, u64 offset, u64 flags, vm::ptr pOpt) +{ + sysPrxForUser.warning("sys_prx_load_module_by_fd(fd=%d, offset=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, flags, pOpt); + + // TODO + return _sys_prx_load_module_by_fd(fd, offset, flags, pOpt); +} + +error_code sys_prx_load_module_on_memcontainer(vm::cptr path, u32 mem_ct, u64 flags, vm::ptr pOpt) +{ + sysPrxForUser.warning("sys_prx_load_module_on_memcontainer(path=%s, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x)", path, mem_ct, flags, pOpt); + + // TODO + return _sys_prx_load_module_on_memcontainer(path, mem_ct, flags, pOpt); +} + +error_code sys_prx_load_module_on_memcontainer_by_fd(s32 fd, u64 offset, u32 mem_ct, u64 flags, vm::ptr pOpt) +{ + sysPrxForUser.warning("sys_prx_load_module_on_memcontainer_by_fd(fd=%d, offset=0x%x, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, mem_ct, flags, pOpt); + + // TODO + return _sys_prx_load_module_on_memcontainer_by_fd(fd, offset, mem_ct, flags, pOpt); +} + +error_code sys_prx_load_module_list(s32 count, vm::cpptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list) +{ + sysPrxForUser.todo("sys_prx_load_module_list(count=%d, path_list=**0x%x, flags=0x%x, pOpt=*0x%x, id_list=*0x%x)", count, path_list, flags, pOpt, id_list); + + // TODO + return _sys_prx_load_module_list(count, convert_path_list(path_list, count), flags, pOpt, id_list); +} + +error_code sys_prx_load_module_list_on_memcontainer(s32 count, vm::cpptr path_list, u32 mem_ct, u64 flags, vm::ptr pOpt, vm::ptr id_list) +{ + sysPrxForUser.todo("sys_prx_load_module_list_on_memcontainer(count=%d, path_list=**0x%x, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x, id_list=*0x%x)", count, path_list, mem_ct, flags, pOpt, id_list); + + // TODO + return _sys_prx_load_module_list_on_memcontainer(count, convert_path_list(path_list, count), mem_ct, flags, pOpt, id_list); +} + +error_code sys_prx_start_module(ppu_thread& ppu, u32 id, u32 args, vm::ptr argp, vm::ptr result, u64 flags, vm::ptr pOpt) +{ + sysPrxForUser.warning("sys_prx_start_module(id=0x%x, args=%u, argp=*0x%x, result=*0x%x, flags=0x%x, pOpt=*0x%x)", id, args, argp, result, flags, pOpt); + + if (!result) + { + return CELL_EINVAL; + } + + // TODO + + vm::var opt; + opt->size = opt.size(); + opt->cmd = 1; + opt->entry2.set(-1); + + const error_code res = _sys_prx_start_module(id, flags, opt); + + if (res < 0) + { + return res; + } + + entryx(ppu, opt, args, argp, result); + + opt->cmd = 2; + opt->res = *result; + + _sys_prx_start_module(id, flags, opt); + return CELL_OK; } -s32 sys_prx_load_module_list_on_memcontainer() +error_code sys_prx_stop_module(ppu_thread& ppu, u32 id, u32 args, vm::ptr argp, vm::ptr result, u64 flags, vm::ptr pOpt) { - fmt::throw_exception("Unimplemented" HERE); + sysPrxForUser.warning("sys_prx_stop_module(id=0x%x, args=%u, argp=*0x%x, result=*0x%x, flags=0x%x, pOpt=*0x%x)", id, args, argp, result, flags, pOpt); + + if (!result) + { + return CELL_EINVAL; + } + + // TODO + + vm::var opt; + opt->size = opt.size(); + opt->cmd = 1; + opt->entry2.set(-1); + + const error_code res = _sys_prx_stop_module(id, flags, opt); + + if (res < 0) + { + return res; + } + + entryx(ppu, opt, args, argp, result); + + opt->cmd = 2; + opt->res = *result; + + _sys_prx_stop_module(id, flags, opt); + + return CELL_OK; +} + +error_code sys_prx_unload_module(u32 id, u64 flags, vm::ptr pOpt) +{ + sysPrxForUser.warning("sys_prx_unload_module(id=0x%x, flags=0x%x, pOpt=*0x%x)", id, flags, pOpt); + + // TODO + return _sys_prx_unload_module(id, flags, pOpt); +} + +error_code sys_prx_register_library(vm::ptr lib_entry) +{ + sysPrxForUser.warning("sys_prx_register_library(lib_entry=*0x%x)", lib_entry); + + // TODO + return _sys_prx_register_library(lib_entry); +} + +error_code sys_prx_unregister_library(vm::ptr lib_entry) +{ + sysPrxForUser.warning("sys_prx_unregister_library(lib_entry=*0x%x)", lib_entry); + + // TODO + return _sys_prx_unregister_library(lib_entry); +} + +error_code sys_prx_get_module_list(ppu_thread& ppu, u64 flags, vm::ptr info) +{ + sysPrxForUser.trace("sys_prx_get_module_list(flags=0x%x, info=*0x%x)", flags, info); + + if (!info || !info->idlist) + { + return CELL_EINVAL; + } + + // Initialize params + vm::var opt; + opt->size = opt.size(); + opt->max = info->max; + opt->count = 0; + opt->idlist = info->idlist; + opt->unk = 0; + + // Call the syscall + const s32 res = _sys_prx_get_module_list(2, opt); + + info->max = opt->max; + info->count = opt->count; + + return not_an_error(res); +} + +error_code sys_prx_get_module_info(ppu_thread& ppu, u32 id, u64 flags, vm::ptr info) +{ + sysPrxForUser.trace("sys_prx_get_module_info(id=0x%x, flags=0x%x, info=*0x%x)", id, flags, info); + + if (!info) + { + return CELL_EINVAL; + } + + // Initialize params + vm::var opt; + opt->size = opt.size(); + opt->info = info; + + // Call the syscall + return _sys_prx_get_module_info(id, 0, opt); +} + +error_code sys_prx_get_module_id_by_name(vm::cptr name, u64 flags, vm::ps3::ptr pOpt) +{ + sysPrxForUser.trace("sys_prx_get_module_id_by_name(name=%s, flags=0x%x, pOpt=*0x%x)", name, flags, pOpt); + + if (flags || pOpt) + { + return CELL_EINVAL; + } + + // Call the syscall + return _sys_prx_get_module_id_by_name(name, u64{0}, vm::null); +} + +error_code sys_prx_get_module_id_by_address(u32 addr) +{ + sysPrxForUser.trace("sys_prx_get_module_id_by_address()"); + + // Call the syscall + return _sys_prx_get_module_id_by_address(addr); +} + +error_code sys_prx_exitspawn_with_level() +{ + sysPrxForUser.todo("sys_prx_exitspawn_with_level()"); + return CELL_OK; +} + +error_code sys_prx_get_my_module_id(ppu_thread& ppu, ppu_thread& _do, ppu_thread& _not, ppu_thread& _call) +{ + sysPrxForUser.trace("sys_prx_get_my_module_id()"); + + // Call the syscall using the LR + return _sys_prx_get_module_id_by_address(static_cast(ppu.lr)); } void sysPrxForUser_sys_prx_init() { - // TODO: split syscalls and liblv2 functions - REG_FUNC(sysPrxForUser, sys_prx_load_module); REG_FUNC(sysPrxForUser, sys_prx_load_module_by_fd); REG_FUNC(sysPrxForUser, sys_prx_load_module_on_memcontainer); diff --git a/rpcs3/Emu/Cell/PPUFunction.cpp b/rpcs3/Emu/Cell/PPUFunction.cpp index a443b59349..dc0777e529 100644 --- a/rpcs3/Emu/Cell/PPUFunction.cpp +++ b/rpcs3/Emu/Cell/PPUFunction.cpp @@ -278,30 +278,30 @@ extern std::string ppu_get_syscall_name(u64 code) case 457: return "sys_overlay_get_module_dbg_info"; case 458: return "sys_overlay_get_module_dbg_info"; case 460: return "sys_prx_dbg_get_module_id_list"; - case 461: return "sys_prx_get_module_id_by_address"; - case 463: return "sys_prx_load_module_by_fd"; - case 464: return "sys_prx_load_module_on_memcontainer_by_fd"; - case 465: return "sys_prx_load_module_list"; - case 466: return "sys_prx_load_module_list_on_memcontainer"; + case 461: return "_sys_prx_get_module_id_by_address"; + case 463: return "_sys_prx_load_module_by_fd"; + case 464: return "_sys_prx_load_module_on_memcontainer_by_fd"; + case 465: return "_sys_prx_load_module_list"; + case 466: return "_sys_prx_load_module_list_on_memcontainer"; case 467: return "sys_prx_get_ppu_guid"; - case 480: return "sys_prx_load_module"; - case 481: return "sys_prx_start_module"; - case 482: return "sys_prx_stop_module"; - case 483: return "sys_prx_unload_module"; - case 484: return "sys_prx_register_module"; - case 485: return "sys_prx_query_module"; - case 486: return "sys_prx_register_library"; - case 487: return "sys_prx_unregister_library"; - case 488: return "sys_prx_link_library"; - case 489: return "sys_prx_unlink_library"; - case 490: return "sys_prx_query_library"; + case 480: return "_sys_prx_load_module"; + case 481: return "_sys_prx_start_module"; + case 482: return "_sys_prx_stop_module"; + case 483: return "_sys_prx_unload_module"; + case 484: return "_sys_prx_register_module"; + case 485: return "_sys_prx_query_module"; + case 486: return "_sys_prx_register_library"; + case 487: return "_sys_prx_unregister_library"; + case 488: return "_sys_prx_link_library"; + case 489: return "_sys_prx_unlink_library"; + case 490: return "_sys_prx_query_library"; case 493: return "sys_prx_dbg_get_module_info"; - case 494: return "sys_prx_get_module_list"; - case 495: return "sys_prx_get_module_info"; - case 496: return "sys_prx_get_module_id_by_name"; - case 497: return "sys_prx_load_module_on_memcontainer"; - case 498: return "sys_prx_start"; - case 499: return "sys_prx_stop"; + case 494: return "_sys_prx_get_module_list"; + case 495: return "_sys_prx_get_module_info"; + case 496: return "_sys_prx_get_module_id_by_name"; + case 497: return "_sys_prx_load_module_on_memcontainer"; + case 498: return "_sys_prx_start"; + case 499: return "_sys_prx_stop"; case 500: return "sys_hid_manager_open"; case 501: return "sys_hid_manager_close"; case 502: return "sys_hid_manager_read"; diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 5b540041f4..47a32fbaae 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -444,13 +444,13 @@ std::array g_ppu_syscall_table null_func,//BIND_FUNC(sys_overlay_get_module_dbg_info) //458 (0x1CA) null_func, //459 (0x1CB) UNS null_func,//BIND_FUNC(sys_prx_dbg_get_module_id_list) //460 (0x1CC) ROOT - null_func,//BIND_FUNC(sys_prx_get_module_id_by_address) //461 (0x1CD) + BIND_FUNC(_sys_prx_get_module_id_by_address), //461 (0x1CD) null_func, //462 (0x1CE) UNS - null_func,//BIND_FUNC(sys_prx_load_module_by_fd) //463 (0x1CF) - null_func,//BIND_FUNC(sys_prx_load_module_on_memcontainer_by_fd) //464 (0x1D0) - BIND_FUNC(sys_prx_load_module_list), //465 (0x1D1) - null_func,//BIND_FUNC(sys_prx_load_module_list_on_memcontainer) //466 (0x1D2) - null_func,//BIND_FUNC(sys_prx_get_ppu_guid) //467 (0x1D3) + BIND_FUNC(_sys_prx_load_module_by_fd), //463 (0x1CF) + BIND_FUNC(_sys_prx_load_module_on_memcontainer_by_fd), //464 (0x1D0) + BIND_FUNC(_sys_prx_load_module_list), //465 (0x1D1) + BIND_FUNC(_sys_prx_load_module_list_on_memcontainer), //466 (0x1D2) + BIND_FUNC(sys_prx_get_ppu_guid), //467 (0x1D3) null_func,//BIND_FUNC(sys_...) //468 (0x1D4) ROOT null_func, //469 (0x1D5) UNS null_func,//BIND_FUNC(sys_...) //470 (0x1D6) ROOT @@ -463,26 +463,26 @@ std::array g_ppu_syscall_table null_func, null_func, null_func, //477-479 UNS - BIND_FUNC(sys_prx_load_module), //480 (0x1E0) - BIND_FUNC(sys_prx_start_module), //481 (0x1E1) - BIND_FUNC(sys_prx_stop_module), //482 (0x1E2) - BIND_FUNC(sys_prx_unload_module), //483 (0x1E3) - BIND_FUNC(sys_prx_register_module), //484 (0x1E4) - BIND_FUNC(sys_prx_query_module), //485 (0x1E5) - BIND_FUNC(sys_prx_register_library), //486 (0x1E6) - BIND_FUNC(sys_prx_unregister_library), //487 (0x1E7) - BIND_FUNC(sys_prx_link_library), //488 (0x1E8) - BIND_FUNC(sys_prx_unlink_library), //489 (0x1E9) - BIND_FUNC(sys_prx_query_library), //490 (0x1EA) + BIND_FUNC(_sys_prx_load_module), //480 (0x1E0) + BIND_FUNC(_sys_prx_start_module), //481 (0x1E1) + BIND_FUNC(_sys_prx_stop_module), //482 (0x1E2) + BIND_FUNC(_sys_prx_unload_module), //483 (0x1E3) + BIND_FUNC(_sys_prx_register_module), //484 (0x1E4) + BIND_FUNC(_sys_prx_query_module), //485 (0x1E5) + BIND_FUNC(_sys_prx_register_library), //486 (0x1E6) + BIND_FUNC(_sys_prx_unregister_library), //487 (0x1E7) + BIND_FUNC(_sys_prx_link_library), //488 (0x1E8) + BIND_FUNC(_sys_prx_unlink_library), //489 (0x1E9) + BIND_FUNC(_sys_prx_query_library), //490 (0x1EA) null_func, //491 (0x1EB) UNS null_func,//BIND_FUNC(sys_...) //492 (0x1EC) DBG null_func,//BIND_FUNC(sys_prx_dbg_get_module_info) //493 (0x1ED) DBG - null_func,//BIND_FUNC(sys_prx_get_module_list), //494 (0x1EE) - null_func,//BIND_FUNC(sys_prx_get_module_info), //495 (0x1EF) - null_func,//BIND_FUNC(sys_prx_get_module_id_by_name), //496 (0x1F0) - null_func,//BIND_FUNC(sys_prx_load_module_on_memcontainer),//497 (0x1F1) - BIND_FUNC(sys_prx_start), //498 (0x1F2) - BIND_FUNC(sys_prx_stop), //499 (0x1F3) + BIND_FUNC(_sys_prx_get_module_list), //494 (0x1EE) + BIND_FUNC(_sys_prx_get_module_info), //495 (0x1EF) + BIND_FUNC(_sys_prx_get_module_id_by_name), //496 (0x1F0) + BIND_FUNC(_sys_prx_load_module_on_memcontainer), //497 (0x1F1) + BIND_FUNC(_sys_prx_start), //498 (0x1F2) + BIND_FUNC(_sys_prx_stop), //499 (0x1F3) null_func,//BIND_FUNC(sys_hid_manager_open) //500 (0x1F4) null_func,//BIND_FUNC(sys_hid_manager_close) //501 (0x1F5) null_func,//BIND_FUNC(sys_hid_manager_read) //502 (0x1F6) ROOT diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index bacccaeb80..55827b740d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -16,9 +16,89 @@ extern void ppu_initialize(const ppu_module&); logs::channel sys_prx("sys_prx", logs::level::notice); -s32 prx_load_module(std::string path, u64 flags, vm::ptr pOpt) +static const std::unordered_map s_prx_ignore { - sys_prx.warning("prx_load_module(path='%s', flags=0x%llx, pOpt=*0x%x)", path.c_str(), flags, pOpt); + { "/dev_flash/sys/external/libad_async.sprx", 0 }, + { "/dev_flash/sys/external/libad_billboard_util.sprx", 0 }, + { "/dev_flash/sys/external/libad_core.sprx", 0 }, + { "/dev_flash/sys/external/libaudio.sprx", 0 }, + { "/dev_flash/sys/external/libbeisobmf.sprx", 0 }, + { "/dev_flash/sys/external/libcamera.sprx", 0 }, + { "/dev_flash/sys/external/libfs.sprx", 0 }, + { "/dev_flash/sys/external/libfs_155.sprx", 0 }, + { "/dev_flash/sys/external/libgcm_sys.sprx", 0 }, + { "/dev_flash/sys/external/libgem.sprx", 0 }, + { "/dev_flash/sys/external/libio.sprx", 0 }, + { "/dev_flash/sys/external/libmedi.sprx", 0 }, + { "/dev_flash/sys/external/libmic.sprx", 0 }, + { "/dev_flash/sys/external/libnet.sprx", 0 }, + { "/dev_flash/sys/external/libnetctl.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_ap.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_authdialog.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_avc_ext.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_avc2.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_avconf_ext.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_bgdl.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_cross_controller.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_dec_psnvideo.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_dtcp_ip.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_game.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_game_exec.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_imejp.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_misc.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_music.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_music_decode.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_music_export.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_clans.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_commerce2.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_eula.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_installer.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_sns.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_trophy.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_tus.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np_util.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_np2.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_oskdialog_ext.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_pesm.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_photo_decode.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_photo_export.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_photo_export2.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_photo_import.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_photo_network_sharing.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_print.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_rec.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_remoteplay.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_rtcalarm.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_screenshot.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_search.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_storagedata.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_subdisplay.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_syschat.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_sysconf_ext.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_userinfo.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_video_export.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_video_player.sprx", 0 }, + { "/dev_flash/sys/external/libsysutil_video_upload.sprx", 0 }, + { "/dev_flash/sys/external/libusbd.sprx", 0 }, + { "/dev_flash/sys/external/libusbpspcm.sprx", 0 }, + { "/dev_flash/sys/external/libvdec.sprx", 0 }, + { "/dev_flash/sys/external/libvoice.sprx", 0 }, +}; + +error_code prx_load_module(std::string path, u64 flags, vm::ptr pOpt) +{ + if (s_prx_ignore.count(path)) + { + sys_prx.warning("Ignored module: %s", path); + + const auto prx = idm::make_ptr(); + + prx->name = path.substr(path.find_last_of('/') + 1); + + return not_an_error(idm::last_id()); + } const auto loadedkeys = fxm::get_always(); @@ -38,25 +118,38 @@ s32 prx_load_module(std::string path, u64 flags, vm::ptr path, u64 flags, vm::ptr pOpt) +error_code sys_prx_get_ppu_guid() { - sys_prx.warning("sys_prx_load_module(path=%s, flags=0x%llx, pOpt=*0x%x)", path, flags, pOpt); - - return prx_load_module(path.get_ptr(), flags, pOpt); + sys_prx.todo("sys_prx_get_ppu_guid()"); + return CELL_OK; } -s32 sys_prx_load_module_list(s32 count, vm::cpptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list) +error_code _sys_prx_load_module_by_fd(s32 fd, u64 offset, u64 flags, vm::ptr pOpt) { - sys_prx.warning("sys_prx_load_module_list(count=%d, path_list=*0x%x, flags=0x%llx, pOpt=*0x%x, id_list=*0x%x)", count, path_list, flags, pOpt, id_list); + sys_prx.todo("_sys_prx_load_module_by_fd(fd=%d, offset=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, flags, pOpt); + return CELL_OK; +} + +error_code _sys_prx_load_module_on_memcontainer_by_fd(s32 fd, u64 offset, u32 mem_ct, u64 flags, vm::ptr pOpt) +{ + sys_prx.todo("_sys_prx_load_module_on_memcontainer_by_fd(fd=%d, offset=0x%x, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, mem_ct, flags, pOpt); + return CELL_OK; +} + +error_code _sys_prx_load_module_list(s32 count, vm::cpptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list) +{ + sys_prx.warning("_sys_prx_load_module_list(count=%d, path_list=**0x%x, flags=0x%x, pOpt=*0x%x, id_list=*0x%x)", count, path_list, flags, pOpt, id_list); for (s32 i = 0; i < count; ++i) { auto path = path_list[i]; std::string name = path.get_ptr(); - s32 result = prx_load_module(name, flags, pOpt); + error_code result = prx_load_module(name, flags, pOpt); if (result < 0) return result; @@ -67,27 +160,29 @@ s32 sys_prx_load_module_list(s32 count, vm::cpptr path_list, u64 flags, vm return CELL_OK; } -s32 sys_prx_load_module_on_memcontainer() +error_code _sys_prx_load_module_list_on_memcontainer(s32 count, vm::cpptr path_list, u32 mem_ct, u64 flags, vm::ptr pOpt, vm::ptr id_list) { - sys_prx.todo("sys_prx_load_module_on_memcontainer()"); + sys_prx.todo("_sys_prx_load_module_list_on_memcontainer(count=%d, path_list=**0x%x, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x, id_list=*0x%x)", count, path_list, mem_ct, flags, pOpt, id_list); + return CELL_OK; } -s32 sys_prx_load_module_by_fd() +error_code _sys_prx_load_module_on_memcontainer(vm::cptr path, u32 mem_ct, u64 flags, vm::ptr pOpt) { - sys_prx.todo("sys_prx_load_module_by_fd()"); + sys_prx.todo("_sys_prx_load_module_on_memcontainer(path=%s, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x)", path, mem_ct, flags, pOpt); return CELL_OK; } -s32 sys_prx_load_module_on_memcontainer_by_fd() +error_code _sys_prx_load_module(vm::cptr path, u64 flags, vm::ptr pOpt) { - sys_prx.todo("sys_prx_load_module_on_memcontainer_by_fd()"); - return CELL_OK; + sys_prx.warning("_sys_prx_load_module(path=%s, flags=0x%x, pOpt=*0x%x)", path, flags, pOpt); + + return prx_load_module(path.get_ptr(), flags, pOpt); } -s32 sys_prx_start_module(s32 id, u64 flags, vm::ptr pOpt) +error_code _sys_prx_start_module(u32 id, u64 flags, vm::ptr pOpt) { - sys_prx.warning("sys_prx_start_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt); + sys_prx.warning("_sys_prx_start_module(id=0x%x, flags=0x%x, pOpt=*0x%x)", id, flags, pOpt); const auto prx = idm::get(id); @@ -100,14 +195,14 @@ s32 sys_prx_start_module(s32 id, u64 flags, vm::ptris_started = true; - pOpt->entry_point.set(prx->start ? prx->start.addr() : ~0ull); + pOpt->entry.set(prx->start ? prx->start.addr() : ~0ull); return CELL_OK; } -s32 sys_prx_stop_module(s32 id, u64 flags, vm::ptr pOpt) +error_code _sys_prx_stop_module(u32 id, u64 flags, vm::ptr pOpt) { - sys_prx.warning("sys_prx_stop_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt); + sys_prx.warning("_sys_prx_stop_module(id=0x%x, flags=0x%x, pOpt=*0x%x)", id, flags, pOpt); const auto prx = idm::get(id); @@ -120,14 +215,14 @@ s32 sys_prx_stop_module(s32 id, u64 flags, vm::ptr // return CELL_PRX_ERROR_ALREADY_STOPPED; //prx->is_started = false; - pOpt->entry_point.set(prx->stop ? prx->stop.addr() : -1); + pOpt->entry.set(prx->stop ? prx->stop.addr() : ~0ull); return CELL_OK; } -s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr pOpt) +error_code _sys_prx_unload_module(u32 id, u64 flags, vm::ptr pOpt) { - sys_prx.warning("sys_prx_unload_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt); + sys_prx.todo("_sys_prx_unload_module(id=0x%x, flags=0x%x, pOpt=*0x%x)", id, flags, pOpt); // Get the PRX, free the used memory and delete the object and its ID const auto prx = idm::withdraw(id); @@ -144,95 +239,119 @@ s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr pInfo) +error_code _sys_prx_register_module() { - sys_prx.todo("sys_prx_get_module_list(flags=%d, pInfo=*0x%x)", flags, pInfo); + sys_prx.todo("_sys_prx_register_module()"); return CELL_OK; } -s32 sys_prx_get_my_module_id() +error_code _sys_prx_query_module() { - sys_prx.todo("sys_prx_get_my_module_id()"); + sys_prx.todo("_sys_prx_query_module()"); return CELL_OK; } -s32 sys_prx_get_module_id_by_address() +error_code _sys_prx_register_library(vm::ptr library) { - sys_prx.todo("sys_prx_get_module_id_by_address()"); + sys_prx.todo("_sys_prx_register_library(library=*0x%x)", library); return CELL_OK; } -s32 sys_prx_get_module_id_by_name(vm::cptr name, u64 flags, vm::ptr pOpt) +error_code _sys_prx_unregister_library(vm::ptr library) { - sys_prx.todo("sys_prx_get_module_id_by_name(name=%s, flags=%d, pOpt=*0x%x)", name, flags, pOpt); + sys_prx.todo("_sys_prx_unregister_library(library=*0x%x)", library); + return CELL_OK; +} + +error_code _sys_prx_link_library() +{ + sys_prx.todo("_sys_prx_link_library()"); + return CELL_OK; +} + +error_code _sys_prx_unlink_library() +{ + sys_prx.todo("_sys_prx_unlink_library()"); + return CELL_OK; +} + +error_code _sys_prx_query_library() +{ + sys_prx.todo("_sys_prx_query_library()"); + return CELL_OK; +} + +error_code _sys_prx_get_module_list(u64 flags, vm::ptr pInfo) +{ + sys_prx.todo("_sys_prx_get_module_list(flags=%d, pInfo=*0x%x)", flags, pInfo); + return CELL_OK; +} + +error_code _sys_prx_get_module_info(u32 id, u64 flags, vm::ptr pOpt) +{ + sys_prx.todo("_sys_prx_get_module_info(id=%d, flags=%d, pOpt=*0x%x)", id, flags, pOpt); + return CELL_OK; +} + +error_code _sys_prx_get_module_id_by_name(vm::cptr name, u64 flags, vm::ptr pOpt) +{ + sys_prx.todo("_sys_prx_get_module_id_by_name(name=%s, flags=%d, pOpt=*0x%x)", name, flags, pOpt); //if (realName == "?") ... return CELL_PRX_ERROR_UNKNOWN_MODULE; } -s32 sys_prx_get_module_info(s32 id, u64 flags, vm::ptr info) +error_code _sys_prx_get_module_id_by_address(u32 addr) { - sys_prx.todo("sys_prx_get_module_info(id=%d, flags=%d, info=*0x%x)", id, flags, info); + sys_prx.todo("_sys_prx_get_module_id_by_address(addr=0x%x)", addr); return CELL_OK; } -s32 sys_prx_register_library(vm::ptr library) -{ - sys_prx.todo("sys_prx_register_library(library=*0x%x)", library); - return CELL_OK; -} - -s32 sys_prx_unregister_library(vm::ptr library) -{ - sys_prx.todo("sys_prx_unregister_library(library=*0x%x)", library); - return CELL_OK; -} - -s32 sys_prx_get_ppu_guid() -{ - sys_prx.todo("sys_prx_get_ppu_guid()"); - return CELL_OK; -} - -s32 sys_prx_register_module() -{ - sys_prx.todo("sys_prx_register_module()"); - return CELL_OK; -} - -s32 sys_prx_query_module() -{ - sys_prx.todo("sys_prx_query_module()"); - return CELL_OK; -} - -s32 sys_prx_link_library() -{ - sys_prx.todo("sys_prx_link_library()"); - return CELL_OK; -} - -s32 sys_prx_unlink_library() -{ - sys_prx.todo("sys_prx_unlink_library()"); - return CELL_OK; -} - -s32 sys_prx_query_library() -{ - sys_prx.todo("sys_prx_query_library()"); - return CELL_OK; -} - -s32 sys_prx_start() +error_code _sys_prx_start() { sys_prx.todo("sys_prx_start()"); return CELL_OK; } -s32 sys_prx_stop() +error_code _sys_prx_stop() { sys_prx.todo("sys_prx_stop()"); return CELL_OK; } + +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](CellPrxError value) + { + switch (value) + { + STR_CASE(CELL_PRX_ERROR_ERROR); + STR_CASE(CELL_PRX_ERROR_ILLEGAL_PERM); + STR_CASE(CELL_PRX_ERROR_UNKNOWN_MODULE); + STR_CASE(CELL_PRX_ERROR_ALREADY_STARTED); + STR_CASE(CELL_PRX_ERROR_NOT_STARTED); + STR_CASE(CELL_PRX_ERROR_ALREADY_STOPPED); + STR_CASE(CELL_PRX_ERROR_CAN_NOT_STOP); + STR_CASE(CELL_PRX_ERROR_NOT_REMOVABLE); + STR_CASE(CELL_PRX_ERROR_LIBRARY_NOT_YET_LINKED); + STR_CASE(CELL_PRX_ERROR_LIBRARY_FOUND); + STR_CASE(CELL_PRX_ERROR_LIBRARY_NOTFOUND); + STR_CASE(CELL_PRX_ERROR_ILLEGAL_LIBRARY); + STR_CASE(CELL_PRX_ERROR_LIBRARY_INUSE); + STR_CASE(CELL_PRX_ERROR_ALREADY_STOPPING); + STR_CASE(CELL_PRX_ERROR_UNSUPPORTED_PRX_TYPE); + STR_CASE(CELL_PRX_ERROR_INVAL); + STR_CASE(CELL_PRX_ERROR_ILLEGAL_PROCESS); + STR_CASE(CELL_PRX_ERROR_NO_LIBLV2); + STR_CASE(CELL_PRX_ERROR_UNSUPPORTED_ELF_TYPE); + STR_CASE(CELL_PRX_ERROR_UNSUPPORTED_ELF_CLASS); + STR_CASE(CELL_PRX_ERROR_UNDEFINED_SYMBOL); + STR_CASE(CELL_PRX_ERROR_UNSUPPORTED_RELOCATION_TYPE); + STR_CASE(CELL_PRX_ERROR_ELF_IS_REGISTERED); + } + + return unknown; + }); +} diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.h b/rpcs3/Emu/Cell/lv2/sys_prx.h index 11e2bf2d40..2aa6185936 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.h +++ b/rpcs3/Emu/Cell/lv2/sys_prx.h @@ -4,7 +4,7 @@ #include "sys_sync.h" // Return codes -enum +enum CellPrxError : u32 { CELL_PRX_ERROR_ERROR = 0x80011001, // Error state CELL_PRX_ERROR_ILLEGAL_PERM = 0x800110d1, // No permission to execute API @@ -44,20 +44,45 @@ struct sys_prx_load_module_option_t }; struct sys_prx_segment_info_t;// TODO -struct sys_prx_module_info_t;// TODO + +struct sys_prx_module_info_t +{ + be_t size; + char name[30]; + char version[2]; + be_t modattribute; + be_t start_entry; + be_t stop_entry; + be_t all_segments_num; + vm::ps3::bptr filename; + be_t filename_size; + vm::ps3::bptr segments; + be_t segments_num; +}; + +struct sys_prx_module_info_option_t +{ + be_t size; // 0x10 + vm::ps3::bptr info; +}; struct sys_prx_start_module_option_t { be_t size; - be_t put; - vm::ps3::bptr argv), u64> entry_point; }; struct sys_prx_stop_module_option_t { be_t size; - be_t put; - vm::ps3::bptr argv), u64> entry_point; +}; + +struct sys_prx_start_stop_module_option_t +{ + be_t size; + be_t cmd; + vm::ps3::bptr argv), u64> entry; + be_t res; + vm::ps3::bptr), u64>, u32 argc, vm::ps3::ptr argv), u64> entry2; }; struct sys_prx_unload_module_option_t @@ -70,7 +95,17 @@ struct sys_prx_get_module_list_t be_t size; be_t max; be_t count; - vm::ps3::bptr idlist; + vm::ps3::bptr idlist; +}; + +struct sys_prx_get_module_list_option_t +{ + be_t size; // 0x20 + be_t pad; + be_t max; + be_t count; + vm::ps3::bptr idlist; + be_t unk; // 0 }; struct lv2_prx final : lv2_obj, ppu_module @@ -81,32 +116,33 @@ struct lv2_prx final : lv2_obj, ppu_module std::unordered_map specials; - vm::ps3::ptr argv)> start = vm::null; - vm::ps3::ptr argv)> stop = vm::null; + vm::ps3::ptr argv)> start = vm::null; + vm::ps3::ptr argv)> stop = vm::null; vm::ps3::ptr exit = vm::null; }; // SysCalls -s32 sys_prx_load_module(vm::ps3::cptr path, u64 flags, vm::ps3::ptr pOpt); -s32 sys_prx_load_module_list(s32 count, vm::ps3::cpptr path_list, u64 flags, vm::ps3::ptr pOpt, vm::ps3::ptr id_list); -s32 sys_prx_load_module_on_memcontainer(); -s32 sys_prx_load_module_by_fd(); -s32 sys_prx_load_module_on_memcontainer_by_fd(); -s32 sys_prx_start_module(s32 id, u64 flags, vm::ps3::ptr pOpt); -s32 sys_prx_stop_module(s32 id, u64 flags, vm::ps3::ptr pOpt); -s32 sys_prx_unload_module(s32 id, u64 flags, vm::ps3::ptr pOpt); -s32 sys_prx_get_module_list(u64 flags, vm::ps3::ptr pInfo); -s32 sys_prx_get_my_module_id(); -s32 sys_prx_get_module_id_by_address(); -s32 sys_prx_get_module_id_by_name(vm::ps3::cptr name, u64 flags, vm::ps3::ptr pOpt); -s32 sys_prx_get_module_info(s32 id, u64 flags, vm::ps3::ptr info); -s32 sys_prx_register_library(vm::ps3::ptr library); -s32 sys_prx_unregister_library(vm::ps3::ptr library); -s32 sys_prx_get_ppu_guid(); -s32 sys_prx_register_module(); -s32 sys_prx_query_module(); -s32 sys_prx_link_library(); -s32 sys_prx_unlink_library(); -s32 sys_prx_query_library(); -s32 sys_prx_start(); -s32 sys_prx_stop(); + +error_code sys_prx_get_ppu_guid(); +error_code _sys_prx_load_module_by_fd(s32 fd, u64 offset, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_load_module_on_memcontainer_by_fd(s32 fd, u64 offset, u32 mem_ct, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_load_module_list(s32 count, vm::ps3::cpptr path_list, u64 flags, vm::ps3::ptr pOpt, vm::ps3::ptr id_list); +error_code _sys_prx_load_module_list_on_memcontainer(s32 count, vm::ps3::cpptr path_list, u32 mem_ct, u64 flags, vm::ps3::ptr pOpt, vm::ps3::ptr id_list); +error_code _sys_prx_load_module_on_memcontainer(vm::ps3::cptr path, u32 mem_ct, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_load_module(vm::ps3::cptr path, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_start_module(u32 id, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_stop_module(u32 id, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_unload_module(u32 id, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_register_module(); +error_code _sys_prx_query_module(); +error_code _sys_prx_register_library(vm::ps3::ptr library); +error_code _sys_prx_unregister_library(vm::ps3::ptr library); +error_code _sys_prx_link_library(); +error_code _sys_prx_unlink_library(); +error_code _sys_prx_query_library(); +error_code _sys_prx_get_module_list(u64 flags, vm::ps3::ptr pInfo); +error_code _sys_prx_get_module_info(u32 id, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_get_module_id_by_name(vm::ps3::cptr name, u64 flags, vm::ps3::ptr pOpt); +error_code _sys_prx_get_module_id_by_address(u32 addr); +error_code _sys_prx_start(); +error_code _sys_prx_stop();