diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 7012678dcc..f37464a794 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -47,12 +47,6 @@ int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5) return CELL_OK; } -s64 sys_prx_register_library(u32 lib_addr) -{ - sysPrxForUser->Error("sys_prx_register_library(lib_addr=0x%x)", lib_addr); - return CELL_OK; -} - s64 sys_prx_exitspawn_with_level() { sysPrxForUser->Log("sys_prx_exitspawn_with_level()"); @@ -162,7 +156,16 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0x45fe2fce, sys_spu_printf_initialize); + sysPrxForUser->AddFunc(0x26090058, sys_prx_load_module); + sysPrxForUser->AddFunc(0x9f18429d, sys_prx_start_module); + sysPrxForUser->AddFunc(0x80fb0c19, sys_prx_stop_module); + sysPrxForUser->AddFunc(0xf0aece0d, sys_prx_unload_module); sysPrxForUser->AddFunc(0x42b23552, sys_prx_register_library); + sysPrxForUser->AddFunc(0xd0ea47a7, sys_prx_unregister_library); + sysPrxForUser->AddFunc(0xa5d06bf0, sys_prx_get_module_list); + sysPrxForUser->AddFunc(0x84bb6774, sys_prx_get_module_info); + sysPrxForUser->AddFunc(0xe0998dbf, sys_prx_get_module_id_by_name); + sysPrxForUser->AddFunc(0xaa6d9bff, sys_prx_load_module_on_memcontainer); sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); sysPrxForUser->AddFunc(0x2d36462b, sys_strlen); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index e745ae995b..1c502457c5 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -342,10 +342,28 @@ static func_caller* sc_table[kSyscallTableLength] = null_func, null_func, null_func, null_func, null_func, //469 null_func, null_func, null_func, null_func, null_func, //474 null_func, null_func, null_func, null_func, null_func, //479 - null_func, null_func, null_func, null_func, null_func, //484 - null_func, null_func, null_func, null_func, null_func, //489 - null_func, null_func, null_func, null_func, null_func, //494 - null_func, null_func, null_func, null_func, null_func, //499 + + 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) + null_func, //492 (0x1EC) + null_func,//sys_prx_dbg_get_module_info //493 (0x1ED) + 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, null_func, null_func, null_func, null_func, //504 null_func, null_func, null_func, null_func, null_func, //509 null_func, null_func, null_func, null_func, null_func, //514 diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 584d9f1aa4..47ec3c25b7 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -1,6 +1,7 @@ #pragma once #include "ErrorCodes.h" #include "lv2/SC_Process.h" +#include "lv2/SC_PRX.h" #include "lv2/SC_FileSystem.h" #include "lv2/SC_Memory.h" #include "lv2/SC_Timer.h" diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PRX.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PRX.cpp new file mode 100644 index 0000000000..962d67fb37 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_PRX.cpp @@ -0,0 +1,190 @@ +#include "stdafx.h" +#include "Emu/ConLog.h" +#include "Emu/Memory/Memory.h" +#include "Emu/System.h" +#include "Emu/SysCalls/SysCalls.h" +#include "SC_PRX.h" + +SysCallBase sys_prx("sys_prx"); + +s32 sys_prx_load_module(u32 path_addr, u64 flags, mem_ptr_t pOpt) +{ + if (!Memory.IsGoodAddr(path_addr)) + return CELL_PRX_ERROR_INVAL; + + std::string path = Memory.ReadString(path_addr); + sys_prx.Error("TODO: sys_prx_load_module(path=\"%s\", flags=0x%llx, pOpt=0x%x)", path.c_str(), flags, pOpt.GetAddr()); + + vfsFile f(path); + if (!f.IsOpened()) { + return CELL_PRX_ERROR_UNKNOWN_MODULE; + } + + // Load the PRX into memory + u64 prx_size = f.GetSize(); + u32 prx_address = Memory.Alloc(prx_size, 4); + f.Read(Memory.VirtualToRealAddr(prx_address), prx_size); + + // Create the PRX object and return its id + sys_prx_t* prx = new sys_prx_t(prx_size, prx_address); + u32 id = sys_prx.GetNewId(prx); + return id; +} + +s32 sys_prx_load_module_on_memcontainer() +{ + sys_prx.Error("TODO: sys_prx_load_module_on_memcontainer()"); + return CELL_OK; +} + +s32 sys_prx_load_module_by_fd() +{ + sys_prx.Error("TODO: sys_prx_load_module_by_fd()"); + return CELL_OK; +} + +s32 sys_prx_load_module_on_memcontainer_by_fd() +{ + sys_prx.Error("TODO: sys_prx_load_module_on_memcontainer_by_fd()"); + return CELL_OK; +} + +s32 sys_prx_start_module(s32 id, u32 args, u32 argp_addr, mem32_t modres, u64 flags, mem_ptr_t pOpt) +{ + sys_prx.Error("TODO: sys_prx_start_module(id=%d, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", + id, args, argp_addr, modres.GetAddr(), flags, pOpt.GetAddr()); + + if (!modres.IsGood()) + return CELL_EINVAL; + + sys_prx_t* prx; + if (!Emu.GetIdManager().GetIDData(id, prx)) + return CELL_ESRCH; + + if (prx->isStarted) + return CELL_PRX_ERROR_ALREADY_STARTED; + + return CELL_OK; +} + +s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, mem32_t modres, u64 flags, mem_ptr_t pOpt) +{ + sys_prx.Error("TODO: sys_prx_stop_module(id=%d, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", + id, args, argp_addr, modres.GetAddr(), flags, pOpt.GetAddr()); + + if (!modres.IsGood()) + return CELL_EINVAL; + + sys_prx_t* prx; + if (!Emu.GetIdManager().GetIDData(id, prx)) + return CELL_ESRCH; + + if (!prx->isStarted) + return CELL_PRX_ERROR_ALREADY_STOPPED; + + return CELL_OK; +} + +s32 sys_prx_unload_module(s32 id, u64 flags, mem_ptr_t pOpt) +{ + sys_prx.Error("TODO: sys_prx_unload_module(id=%d, flags=0x%llx, pOpt=0x%x)", id, flags, pOpt.GetAddr()); + + // Get the PRX, free the used memory and delete the object and its ID + sys_prx_t* prx; + if (!Emu.GetIdManager().GetIDData(id, prx)) + return CELL_ESRCH; + Memory.Free(prx->address); + Emu.GetIdManager().RemoveID(id); + + return CELL_OK; +} + +s32 sys_prx_get_module_list() +{ + sys_prx.Error("TODO: sys_prx_get_module_list()"); + return CELL_OK; +} + +s32 sys_prx_get_my_module_id() +{ + sys_prx.Error("TODO: sys_prx_get_my_module_id()"); + return CELL_OK; +} + +s32 sys_prx_get_module_id_by_address() +{ + sys_prx.Error("TODO: sys_prx_get_module_id_by_address()"); + return CELL_OK; +} + +s32 sys_prx_get_module_id_by_name() +{ + sys_prx.Error("TODO: sys_prx_get_module_id_by_name()"); + return CELL_OK; +} + +s32 sys_prx_get_module_info() +{ + sys_prx.Error("TODO: sys_prx_get_module_info()"); + return CELL_OK; +} + +s32 sys_prx_register_library(u32 lib_addr) +{ + sys_prx.Error("TODO: sys_prx_register_library(lib_addr=0x%x)", lib_addr); + return CELL_OK; +} + +s32 sys_prx_unregister_library() +{ + sys_prx.Error("TODO: sys_prx_unregister_library()"); + return CELL_OK; +} + +s32 sys_prx_get_ppu_guid() +{ + sys_prx.Error("TODO: sys_prx_get_ppu_guid()"); + return CELL_OK; +} + +s32 sys_prx_register_module() +{ + sys_prx.Error("TODO: sys_prx_register_module()"); + return CELL_OK; +} + +s32 sys_prx_query_module() +{ + sys_prx.Error("TODO: sys_prx_query_module()"); + return CELL_OK; +} + +s32 sys_prx_link_library() +{ + sys_prx.Error("TODO: sys_prx_link_library()"); + return CELL_OK; +} + +s32 sys_prx_unlink_library() +{ + sys_prx.Error("TODO: sys_prx_unlink_library()"); + return CELL_OK; +} + +s32 sys_prx_query_library() +{ + sys_prx.Error("TODO: sys_prx_query_library()"); + return CELL_OK; +} + +s32 sys_prx_start() +{ + sys_prx.Error("TODO: sys_prx_start()"); + return CELL_OK; +} + +s32 sys_prx_stop() +{ + sys_prx.Error("TODO: sys_prx_stop()"); + return CELL_OK; +} diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PRX.h b/rpcs3/Emu/SysCalls/lv2/SC_PRX.h new file mode 100644 index 0000000000..523ccc82cc --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_PRX.h @@ -0,0 +1,89 @@ +#pragma once + +// Return codes +enum +{ + CELL_PRX_ERROR_ERROR = 0x80011001, // Error state + CELL_PRX_ERROR_ILLEGAL_PERM = 0x800110d1, // No permission to execute API + CELL_PRX_ERROR_UNKNOWN_MODULE = 0x8001112e, // Specified PRX could not be found + CELL_PRX_ERROR_ALREADY_STARTED = 0x80011133, // Specified PRX is already started + CELL_PRX_ERROR_NOT_STARTED = 0x80011134, // Specified PRX is not started + CELL_PRX_ERROR_ALREADY_STOPPED = 0x80011135, // Specified PRX is already stopped + CELL_PRX_ERROR_CAN_NOT_STOP = 0x80011136, // Specified PRX must not be stopped + CELL_PRX_ERROR_NOT_REMOVABLE = 0x80011138, // Specified PRX must not be deleted + CELL_PRX_ERROR_LIBRARY_NOT_YET_LINKED = 0x8001113a, // Called unlinked function + CELL_PRX_ERROR_LIBRARY_FOUND = 0x8001113b, // Specified library is already registered + CELL_PRX_ERROR_LIBRARY_NOTFOUND = 0x8001113c, // Specified library is not registered + CELL_PRX_ERROR_ILLEGAL_LIBRARY = 0x8001113d, // Library structure is invalid + CELL_PRX_ERROR_LIBRARY_INUSE = 0x8001113e, // Library cannot be deleted because it is linked + CELL_PRX_ERROR_ALREADY_STOPPING = 0x8001113f, // Specified PRX is in the process of stopping + CELL_PRX_ERROR_UNSUPPORTED_PRX_TYPE = 0x80011148, // Specified PRX format is invalid and cannot be loaded + CELL_PRX_ERROR_INVAL = 0x80011324, // Argument value is invalid + CELL_PRX_ERROR_ILLEGAL_PROCESS = 0x80011801, // Specified process does not exist + CELL_PRX_ERROR_NO_LIBLV2 = 0x80011881, // liblv2.sprx does not exist + CELL_PRX_ERROR_UNSUPPORTED_ELF_TYPE = 0x80011901, // ELF type of specified file is not supported + CELL_PRX_ERROR_UNSUPPORTED_ELF_CLASS = 0x80011902, // ELF class of specified file is not supported + CELL_PRX_ERROR_UNDEFINED_SYMBOL = 0x80011904, // References undefined symbols + CELL_PRX_ERROR_UNSUPPORTED_RELOCATION_TYPE = 0x80011905, // Uses unsupported relocation type + CELL_PRX_ERROR_ELF_IS_REGISTERED = 0x80011910, // Fixed ELF is already registered +}; + +// Data types +struct sys_prx_load_module_option_t +{ + be_t size; + be_t base_addr; // void* +}; + +struct sys_prx_start_module_option_t +{ + be_t size; +}; + +struct sys_prx_stop_module_option_t +{ + be_t size; +}; + +struct sys_prx_unload_module_option_t +{ + be_t size; +}; + +// Auxiliary data types +struct sys_prx_t { + u32 size; + u32 address; + bool isStarted; + + sys_prx_t(u32 prx_size, u32 prx_address) + : size(prx_size) + , address(prx_address) + , isStarted(false) + { + } +}; + +// SysCalls +s32 sys_prx_load_module(u32 path_addr, u64 flags, mem_ptr_t pOpt); +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, u32 args, u32 argp_addr, mem32_t modres, u64 flags, mem_ptr_t pOpt); +s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, mem32_t modres, u64 flags, mem_ptr_t pOpt); +s32 sys_prx_unload_module(s32 id, u64 flags, mem_ptr_t pOpt); +s32 sys_prx_get_module_list(); +s32 sys_prx_get_my_module_id(); +s32 sys_prx_get_module_id_by_address(); +s32 sys_prx_get_module_id_by_name(); +s32 sys_prx_get_module_info(); +s32 sys_prx_register_library(u32 lib_addr); +s32 sys_prx_unregister_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(); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index be81c1885c..fde02246a6 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -107,6 +107,7 @@ + @@ -321,6 +322,8 @@ + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index ef24a74336..398e3f933e 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -581,6 +581,9 @@ Emu\SysCalls\lv2 + + Emu\SysCalls\lv2 + @@ -1054,5 +1057,11 @@ Emu\SysCalls\lv2 + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + \ No newline at end of file