From bdc8eba3bbcdfe23c80a3ac9f05d2737fbacbfdf Mon Sep 17 00:00:00 2001 From: Peter Tissen Date: Wed, 12 Feb 2014 19:33:25 +0100 Subject: [PATCH] Add cache support also added tentative blocksize and sys_game_procexit support added final cache support and improved the process chainloading error messages don't ignore cache directory in the .gitignore add warning for clearing cache --- bin/dev_hdd1/.gitignore | 4 +- bin/dev_hdd1/cache/README.txt | 1 + rpcs3/Emu/SysCalls/FuncList.cpp | 5 - rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 85 +++++++++++++++ rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 4 + rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 1 + rpcs3/Emu/SysCalls/SysCalls.h | 7 +- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 20 +++- rpcs3/Emu/SysCalls/lv2/SC_Process.cpp | 105 +++++++++++++++++-- 9 files changed, 212 insertions(+), 20 deletions(-) create mode 100644 bin/dev_hdd1/cache/README.txt diff --git a/bin/dev_hdd1/.gitignore b/bin/dev_hdd1/.gitignore index 86d0cb2726..5e4974bd2e 100644 --- a/bin/dev_hdd1/.gitignore +++ b/bin/dev_hdd1/.gitignore @@ -1,4 +1,6 @@ # Ignore everything in this directory * # Except this file -!.gitignore \ No newline at end of file +!.gitignore +!cache +!cache/README.txt \ No newline at end of file diff --git a/bin/dev_hdd1/cache/README.txt b/bin/dev_hdd1/cache/README.txt new file mode 100644 index 0000000000..9932cff1d7 --- /dev/null +++ b/bin/dev_hdd1/cache/README.txt @@ -0,0 +1 @@ +every Folder in this directory gets cleared when cellSysCacheClear() is called, so don't store important data here \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index 8ab729dd9c..4828964090 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -1592,7 +1592,6 @@ s64 SysCalls::DoFunc(const u32 id) case 0x1d99c3ee: FUNC_LOG_ERROR("TODO: cellOskDialogGetInputText"); case 0x1dfbfdd6: FUNC_LOG_ERROR("TODO: cellSaveDataListLoad2"); case 0x1dfcce99: FUNC_LOG_ERROR("TODO: cellSysutilGameDataExit"); - case 0x1e7bff94: FUNC_LOG_ERROR("TODO: cellSysCacheMount"); case 0x1e930eef: FUNC_LOG_ERROR("TODO: cellVideoOutGetDeviceInfo"); case 0x1f6629e4: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetErrorHook2"); case 0x20543730: FUNC_LOG_ERROR("TODO: cellMsgDialogClose"); @@ -1647,7 +1646,6 @@ s64 SysCalls::DoFunc(const u32 id) case 0x6dfff31d: FUNC_LOG_ERROR("TODO: cellWebBrowserSetSystemCallbackUsrdata"); case 0x6e7264ed: FUNC_LOG_ERROR("TODO: cellSaveDataUserFixedLoad"); case 0x71acb8d3: FUNC_LOG_ERROR("TODO: cellSysutilAvcSetVideoMuting"); - case 0x744c1544: FUNC_LOG_ERROR("TODO: cellSysCacheClear"); case 0x749c9b5f: FUNC_LOG_ERROR("TODO: cellWebBrowserInitialize"); case 0x75bbb672: FUNC_LOG_ERROR("TODO: cellVideoOutGetNumberOfDevice"); case 0x7603d3db: FUNC_LOG_ERROR("TODO: cellMsgDialogOpen2"); @@ -2458,7 +2456,6 @@ s64 SysCalls::DoFunc(const u32 id) case 0x0e2939e5: FUNC_LOG_ERROR("TODO: cellFsFtruncate"); case 0x103b8632: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaWithInitialData"); case 0x190912f6: FUNC_LOG_ERROR("TODO: cellFsStReadGetCurrentAddr"); - case 0x1a108ab7: FUNC_LOG_ERROR("TODO: cellFsGetBlockSize"); case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber"); case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit"); case 0x27800c6b: FUNC_LOG_ERROR("TODO: cellFsStRead"); @@ -3762,7 +3759,6 @@ s64 SysCalls::DoFunc(const u32 id) case 0x5fdfb2fe: FUNC_LOG_ERROR("TODO: _sys_spu_printf_detach_group"); case 0x608212fc: FUNC_LOG_ERROR("TODO: sys_mempool_free_block"); case 0x620e35a7: FUNC_LOG_ERROR("TODO: sys_game_get_system_sw_version"); - case 0x67f9fedb: FUNC_LOG_ERROR("TODO: sys_game_process_exitspawn2"); case 0x68b9b011: FUNC_LOG_ERROR("TODO: _sys_memset"); case 0x6bf66ea7: FUNC_LOG_ERROR("TODO: _sys_memcpy"); case 0x6e05231d: FUNC_LOG_ERROR("TODO: sys_game_watchdog_stop"); @@ -3838,7 +3834,6 @@ s64 SysCalls::DoFunc(const u32 id) case 0xf7f7fb20: FUNC_LOG_ERROR("TODO: _sys_free"); case 0xfa7f693d: FUNC_LOG_ERROR("TODO: _sys_vprintf"); case 0xfb5db080: FUNC_LOG_ERROR("TODO: _sys_memcmp"); - case 0xfc52a7a9: FUNC_LOG_ERROR("TODO: sys_game_process_exitspawn"); } ConLog.Error("Unknown func id: 0x%08x", id); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 4b13707b9a..79aab03149 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -117,6 +117,20 @@ enum CELL_MSGDIALOG_BUTTON_ESCAPE = 3, }; +enum{ + CELL_SYSCACHE_RET_OK_CLEARED = 0, + CELL_SYSCACHE_RET_OK_RELAYED = 1, + + CELL_SYSCACHE_ID_SIZE = 32, + CELL_SYSCACHE_PATH_MAX = 1055, + + CELL_SYSCACHE_ERROR_ACCESS_ERROR = 0x8002bc01,//I don't think we need this + CELL_SYSCACHE_ERROR_INTERNAL = 0x8002bc02,//not really useful, if we run out of HD space sysfs should handle that + + CELL_SYSCACHE_ERROR_PARAM = 0x8002bc03, + CELL_SYSCACHE_ERROR_NOTMOUNTED = 0x8002bc04,//we don't really need to simulate the mounting, so this is probably useless +}; + enum CellMsgDialogType { CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000, @@ -885,6 +899,73 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control) return CELL_AUDIO_OUT_SUCCEEDED; } + + + +typedef struct{ + char cacheId[CELL_SYSCACHE_ID_SIZE]; + char getCachePath[CELL_SYSCACHE_PATH_MAX]; + mem_ptr_t reserved; +} CellSysCacheParam; + + +class WxDirDeleteTraverser : public wxDirTraverser +{ +public: + virtual wxDirTraverseResult OnFile(const wxString& filename) + { + if (!wxRemoveFile(filename)){ + cellSysutil.Error("Couldn't delete File: %s", filename.wx_str()); + } + return wxDIR_CONTINUE; + } + virtual wxDirTraverseResult OnDir(const wxString& dirname) + { + wxDir dir(dirname); + dir.Traverse(*this); + if (!wxRmDir(dirname)){ + //this get triggered a few times while clearing folders + //but if this gets reimplented we should probably warn + //if directories can't be removed + } + return wxDIR_CONTINUE; + } +}; + +int cellSysCacheClear(void) +{ + //if some software expects CELL_SYSCACHE_ERROR_NOTMOUNTED we need to check whether + //it was mounted before, for that we would need to save the state which I don't know + //where to put + wxString localPath; + Emu.GetVFS().GetDevice(wxString("/dev_hdd1/cache/"), localPath); + if (wxDirExists(localPath)){ + WxDirDeleteTraverser deleter; + wxString f = wxFindFirstFile(localPath+"\*",wxDIR); + while (!f.empty()) + { + wxDir dir(f); + dir.Traverse(deleter); + f = wxFindNextFile(); + } + return CELL_SYSCACHE_RET_OK_CLEARED; + } + else{ + return CELL_SYSCACHE_ERROR_ACCESS_ERROR; + } +} + +int cellSysCacheMount(mem_ptr_t param) +{ + //TODO: implement + char id[CELL_SYSCACHE_ID_SIZE]; + strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE); + strncpy(param->getCachePath, ("/dev_hdd1/cache/" + std::string(id) + "/").c_str(), CELL_SYSCACHE_PATH_MAX); + Emu.GetVFS().Create(wxString(param->getCachePath)); + + return CELL_SYSCACHE_RET_OK_RELAYED; +} + void cellSysutil_init() { cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt); @@ -913,4 +994,8 @@ void cellSysutil_init() cellSysutil.AddFunc(0xe5e2b09d, cellAudioOutGetNumberOfDevice); cellSysutil.AddFunc(0xed5d96af, cellAudioOutGetConfiguration); cellSysutil.AddFunc(0xc96e89e9, cellAudioOutSetCopyControl); + + cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount); + cellSysutil.AddFunc(0x744c1544, cellSysCacheClear); + } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 18368540c1..9a3c233faa 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -183,4 +183,8 @@ void sysPrxForUser_init() sysPrxForUser.AddFunc(0xe9a1bd84, sys_lwcond_signal_all); sysPrxForUser.AddFunc(0x52aadadf, sys_lwcond_signal_to); sysPrxForUser.AddFunc(0x2a6d9d51, sys_lwcond_wait); + + sysPrxForUser.AddFunc(0x67f9fedb, sys_game_process_exitspawn2); + sysPrxForUser.AddFunc(0xfc52a7a9, sys_game_process_exitspawn); + } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index b1845e9ecc..1c8e07170d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -239,4 +239,5 @@ void sys_fs_init() sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); sys_fs.AddFunc(0xdb869f20, cellFsAioInit); sys_fs.AddFunc(0x9f951810, cellFsAioFinish); + sys_fs.AddFunc(0x1a108ab7, cellFsGetBlockSize); } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 08e75a648f..9570acf1b8 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -122,8 +122,10 @@ extern int sys_process_get_number_of_object(u32 object, mem32_t nump); extern int sys_process_get_id(u32 object, mem8_ptr_t buffer, u32 size, mem32_t set_size); extern int sys_process_get_paramsfo(mem8_ptr_t buffer); extern int sys_process_exit(int errorcode); -extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr, - u32 data, u32 data_size, int prio, u64 flags ); +extern void sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr, + u32 data_addr, u32 data_size, u32 prio, u64 flags ); +extern void sys_game_process_exitspawn2(u32 path_addr, u32 argv_addr, u32 envp_addr, + u32 data_addr, u32 data_size, u32 prio, u64 flags); //sys_event extern int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t attr, u64 event_queue_key, int size); @@ -254,6 +256,7 @@ extern int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos); extern int cellFsFtruncate(u32 fd, u64 size); extern int cellFsTruncate(u32 path_addr, u64 size); extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size); +extern int cellFsGetBlockSize(u32 path_addr, mem64_t sector_size, mem64_t block_size); //cellVideo extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index e4535c78dc..b4760efcf4 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -42,7 +42,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) _oflags &= ~CELL_O_EXCL; o_mode = vfsWriteExcl; } - else //if(flags & CELL_O_TRUNC) + else //if (flags & CELL_O_TRUNC) { _oflags &= ~CELL_O_TRUNC; o_mode = vfsWrite; @@ -51,6 +51,14 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) case CELL_O_RDWR: _oflags &= ~CELL_O_RDWR; + if (flags & CELL_O_TRUNC) + { + _oflags &= ~CELL_O_TRUNC; + //truncate file before opening it as read/write + vfsStream* stream = Emu.GetVFS().Open(ppath, vfsWrite); + stream->Close(); + delete stream; + } o_mode = vfsReadWrite; break; } @@ -397,3 +405,13 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size) return CELL_OK; } + +int cellFsGetBlockSize(u32 path_addr, mem64_t sector_size, mem64_t block_size) +{ + sys_fs.Log("cellFsGetBlockSize(file: %s, sector_size_addr: 0x%x, block_size_addr: 0x%x)", Memory.ReadString(path_addr).wx_str(), sector_size.GetAddr(), block_size.GetAddr()); + + sector_size = 4096; // ? + block_size = 4096; // ? + + return CELL_OK; +} diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp index 8ceab802c8..031686f098 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp @@ -45,20 +45,103 @@ int sys_process_exit(int errorcode) return CELL_OK; } -int sys_game_process_exitspawn( u32 path_addr, u32 argv_addr, u32 envp_addr, - u32 data, u32 data_size, int prio, u64 flags ) +void sys_game_process_exitspawn( + u32 path_addr, + u32 argv_addr, + u32 envp_addr, + u32 data_addr, + u32 data_size, + u32 prio, + u64 flags ) { - sc_p.Log("sys_game_process_exitspawn: "); - sc_p.Log("path: %s", Memory.ReadString(path_addr).wx_str()); - sc_p.Log("argv: 0x%x", Memory.Read32(argv_addr)); - sc_p.Log("envp: 0x%x", Memory.Read32(envp_addr)); - sc_p.Log("data: 0x%x", data); - sc_p.Log("data_size: 0x%x", data_size); - sc_p.Log("prio: %d", prio); - sc_p.Log("flags: %d", flags); - return CELL_OK; + sc_p.Error("sys_game_process_exitspawn UNIMPLEMENTED"); + sc_p.Warning("path: %s", Memory.ReadString(path_addr).wx_str()); + sc_p.Warning("argv: 0x%x", argv_addr); + sc_p.Warning("envp: 0x%x", envp_addr); + sc_p.Warning("data: 0x%x", data_addr); + sc_p.Warning("data_size: 0x%x", data_size); + sc_p.Warning("prio: %d", prio); + sc_p.Warning("flags: %d", flags); + + wxString path = Memory.ReadString(path_addr); + std::vector argv; + std::vector env; + + mem_ptr_t argvp(argv_addr); + while (argvp.GetAddr() && argvp.IsGood() && *argvp) + { + argv.push_back(Memory.ReadString(Memory.Read32(argvp.GetAddr()))); + argvp++; + } + mem_ptr_t envp(envp_addr); + while (envp.GetAddr() && envp.IsGood() && *envp) + { + env.push_back(Memory.ReadString(Memory.Read32(envp.GetAddr()))); + envp++; + } + + for (auto &arg : argv){ + sc_p.Log("argument: %s", arg.wx_str()); + } + for (auto &en : env){ + sc_p.Log("env_argument: %s", en.wx_str()); + } + //TODO: execute the file in with the args in argv + //and the environment parameters in envp and copy the data + //from data_addr into the adress space of the new process + //then kill the current process + return; } +void sys_game_process_exitspawn2( + u32 path_addr, + u32 argv_addr, + u32 envp_addr, + u32 data_addr, + u32 data_size, + u32 prio, + u64 flags) +{ + sc_p.Error("sys_game_process_exitspawn2 UNIMPLEMENTED"); + sc_p.Warning("path: %s", Memory.ReadString(path_addr).wx_str()); + sc_p.Warning("argv: 0x%x", argv_addr); + sc_p.Warning("envp: 0x%x", envp_addr); + sc_p.Warning("data: 0x%x", data_addr); + sc_p.Warning("data_size: 0x%x", data_size); + sc_p.Warning("prio: %d", prio); + sc_p.Warning("flags: %d", flags); + + wxString path = Memory.ReadString(path_addr); + std::vector argv; + std::vector env; + + mem_ptr_t argvp(argv_addr); + while (argvp.GetAddr() && argvp.IsGood() && *argvp) + { + argv.push_back(Memory.ReadString(Memory.Read32(argvp.GetAddr()))); + argvp++; + } + mem_ptr_t envp(envp_addr); + while (envp.GetAddr() && envp.IsGood() && *envp) + { + env.push_back(Memory.ReadString(Memory.Read32(envp.GetAddr()))); + envp++; + } + + for (auto &arg : argv){ + sc_p.Log("argument: %s", arg.wx_str()); + } + for (auto &en : env){ + sc_p.Log("env_argument: %s", en.wx_str()); + } + //TODO: execute the file in with the args in argv + //and the environment parameters in envp and copy the data + //from data_addr into the adress space of the new process + //then kill the current process + return; +} + + int sys_process_get_number_of_object(u32 object, mem32_t nump) { sc_p.Warning("TODO: sys_process_get_number_of_object(object=%d, nump_addr=0x%x)",