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
This commit is contained in:
Peter Tissen 2014-02-12 19:33:25 +01:00
parent f3ad989e34
commit bdc8eba3bb
9 changed files with 212 additions and 20 deletions

View File

@ -1,4 +1,6 @@
# Ignore everything in this directory # Ignore everything in this directory
* *
# Except this file # Except this file
!.gitignore !.gitignore
!cache
!cache/README.txt

1
bin/dev_hdd1/cache/README.txt vendored Normal file
View File

@ -0,0 +1 @@
every Folder in this directory gets cleared when cellSysCacheClear() is called, so don't store important data here

View File

@ -1592,7 +1592,6 @@ s64 SysCalls::DoFunc(const u32 id)
case 0x1d99c3ee: FUNC_LOG_ERROR("TODO: cellOskDialogGetInputText"); case 0x1d99c3ee: FUNC_LOG_ERROR("TODO: cellOskDialogGetInputText");
case 0x1dfbfdd6: FUNC_LOG_ERROR("TODO: cellSaveDataListLoad2"); case 0x1dfbfdd6: FUNC_LOG_ERROR("TODO: cellSaveDataListLoad2");
case 0x1dfcce99: FUNC_LOG_ERROR("TODO: cellSysutilGameDataExit"); case 0x1dfcce99: FUNC_LOG_ERROR("TODO: cellSysutilGameDataExit");
case 0x1e7bff94: FUNC_LOG_ERROR("TODO: cellSysCacheMount");
case 0x1e930eef: FUNC_LOG_ERROR("TODO: cellVideoOutGetDeviceInfo"); case 0x1e930eef: FUNC_LOG_ERROR("TODO: cellVideoOutGetDeviceInfo");
case 0x1f6629e4: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetErrorHook2"); case 0x1f6629e4: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetErrorHook2");
case 0x20543730: FUNC_LOG_ERROR("TODO: cellMsgDialogClose"); 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 0x6dfff31d: FUNC_LOG_ERROR("TODO: cellWebBrowserSetSystemCallbackUsrdata");
case 0x6e7264ed: FUNC_LOG_ERROR("TODO: cellSaveDataUserFixedLoad"); case 0x6e7264ed: FUNC_LOG_ERROR("TODO: cellSaveDataUserFixedLoad");
case 0x71acb8d3: FUNC_LOG_ERROR("TODO: cellSysutilAvcSetVideoMuting"); case 0x71acb8d3: FUNC_LOG_ERROR("TODO: cellSysutilAvcSetVideoMuting");
case 0x744c1544: FUNC_LOG_ERROR("TODO: cellSysCacheClear");
case 0x749c9b5f: FUNC_LOG_ERROR("TODO: cellWebBrowserInitialize"); case 0x749c9b5f: FUNC_LOG_ERROR("TODO: cellWebBrowserInitialize");
case 0x75bbb672: FUNC_LOG_ERROR("TODO: cellVideoOutGetNumberOfDevice"); case 0x75bbb672: FUNC_LOG_ERROR("TODO: cellVideoOutGetNumberOfDevice");
case 0x7603d3db: FUNC_LOG_ERROR("TODO: cellMsgDialogOpen2"); 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 0x0e2939e5: FUNC_LOG_ERROR("TODO: cellFsFtruncate");
case 0x103b8632: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaWithInitialData"); case 0x103b8632: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaWithInitialData");
case 0x190912f6: FUNC_LOG_ERROR("TODO: cellFsStReadGetCurrentAddr"); case 0x190912f6: FUNC_LOG_ERROR("TODO: cellFsStReadGetCurrentAddr");
case 0x1a108ab7: FUNC_LOG_ERROR("TODO: cellFsGetBlockSize");
case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber"); case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber");
case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit"); case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit");
case 0x27800c6b: FUNC_LOG_ERROR("TODO: cellFsStRead"); 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 0x5fdfb2fe: FUNC_LOG_ERROR("TODO: _sys_spu_printf_detach_group");
case 0x608212fc: FUNC_LOG_ERROR("TODO: sys_mempool_free_block"); case 0x608212fc: FUNC_LOG_ERROR("TODO: sys_mempool_free_block");
case 0x620e35a7: FUNC_LOG_ERROR("TODO: sys_game_get_system_sw_version"); 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 0x68b9b011: FUNC_LOG_ERROR("TODO: _sys_memset");
case 0x6bf66ea7: FUNC_LOG_ERROR("TODO: _sys_memcpy"); case 0x6bf66ea7: FUNC_LOG_ERROR("TODO: _sys_memcpy");
case 0x6e05231d: FUNC_LOG_ERROR("TODO: sys_game_watchdog_stop"); 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 0xf7f7fb20: FUNC_LOG_ERROR("TODO: _sys_free");
case 0xfa7f693d: FUNC_LOG_ERROR("TODO: _sys_vprintf"); case 0xfa7f693d: FUNC_LOG_ERROR("TODO: _sys_vprintf");
case 0xfb5db080: FUNC_LOG_ERROR("TODO: _sys_memcmp"); 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); ConLog.Error("Unknown func id: 0x%08x", id);

View File

@ -117,6 +117,20 @@ enum
CELL_MSGDIALOG_BUTTON_ESCAPE = 3, 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 enum CellMsgDialogType
{ {
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000, CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
@ -885,6 +899,73 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control)
return CELL_AUDIO_OUT_SUCCEEDED; return CELL_AUDIO_OUT_SUCCEEDED;
} }
typedef struct{
char cacheId[CELL_SYSCACHE_ID_SIZE];
char getCachePath[CELL_SYSCACHE_PATH_MAX];
mem_ptr_t<void> 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<CellSysCacheParam> 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() void cellSysutil_init()
{ {
cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt); cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt);
@ -913,4 +994,8 @@ void cellSysutil_init()
cellSysutil.AddFunc(0xe5e2b09d, cellAudioOutGetNumberOfDevice); cellSysutil.AddFunc(0xe5e2b09d, cellAudioOutGetNumberOfDevice);
cellSysutil.AddFunc(0xed5d96af, cellAudioOutGetConfiguration); cellSysutil.AddFunc(0xed5d96af, cellAudioOutGetConfiguration);
cellSysutil.AddFunc(0xc96e89e9, cellAudioOutSetCopyControl); cellSysutil.AddFunc(0xc96e89e9, cellAudioOutSetCopyControl);
cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount);
cellSysutil.AddFunc(0x744c1544, cellSysCacheClear);
} }

View File

@ -183,4 +183,8 @@ void sysPrxForUser_init()
sysPrxForUser.AddFunc(0xe9a1bd84, sys_lwcond_signal_all); sysPrxForUser.AddFunc(0xe9a1bd84, sys_lwcond_signal_all);
sysPrxForUser.AddFunc(0x52aadadf, sys_lwcond_signal_to); sysPrxForUser.AddFunc(0x52aadadf, sys_lwcond_signal_to);
sysPrxForUser.AddFunc(0x2a6d9d51, sys_lwcond_wait); sysPrxForUser.AddFunc(0x2a6d9d51, sys_lwcond_wait);
sysPrxForUser.AddFunc(0x67f9fedb, sys_game_process_exitspawn2);
sysPrxForUser.AddFunc(0xfc52a7a9, sys_game_process_exitspawn);
} }

View File

@ -239,4 +239,5 @@ void sys_fs_init()
sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); sys_fs.AddFunc(0xc1c507e7, cellFsAioRead);
sys_fs.AddFunc(0xdb869f20, cellFsAioInit); sys_fs.AddFunc(0xdb869f20, cellFsAioInit);
sys_fs.AddFunc(0x9f951810, cellFsAioFinish); sys_fs.AddFunc(0x9f951810, cellFsAioFinish);
sys_fs.AddFunc(0x1a108ab7, cellFsGetBlockSize);
} }

View File

@ -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_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_get_paramsfo(mem8_ptr_t buffer);
extern int sys_process_exit(int errorcode); extern int sys_process_exit(int errorcode);
extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr, extern void sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr,
u32 data, u32 data_size, int prio, u64 flags ); 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 //sys_event
extern int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> attr, u64 event_queue_key, int size); extern int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> 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 cellFsFtruncate(u32 fd, u64 size);
extern int cellFsTruncate(u32 path_addr, 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 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 //cellVideo
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr); extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);

View File

@ -42,7 +42,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
_oflags &= ~CELL_O_EXCL; _oflags &= ~CELL_O_EXCL;
o_mode = vfsWriteExcl; o_mode = vfsWriteExcl;
} }
else //if(flags & CELL_O_TRUNC) else //if (flags & CELL_O_TRUNC)
{ {
_oflags &= ~CELL_O_TRUNC; _oflags &= ~CELL_O_TRUNC;
o_mode = vfsWrite; 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: case CELL_O_RDWR:
_oflags &= ~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; o_mode = vfsReadWrite;
break; break;
} }
@ -397,3 +405,13 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
return CELL_OK; 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;
}

View File

@ -45,20 +45,103 @@ int sys_process_exit(int errorcode)
return CELL_OK; return CELL_OK;
} }
int sys_game_process_exitspawn( u32 path_addr, u32 argv_addr, u32 envp_addr, void sys_game_process_exitspawn(
u32 data, u32 data_size, int prio, u64 flags ) 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.Error("sys_game_process_exitspawn UNIMPLEMENTED");
sc_p.Log("path: %s", Memory.ReadString(path_addr).wx_str()); sc_p.Warning("path: %s", Memory.ReadString(path_addr).wx_str());
sc_p.Log("argv: 0x%x", Memory.Read32(argv_addr)); sc_p.Warning("argv: 0x%x", argv_addr);
sc_p.Log("envp: 0x%x", Memory.Read32(envp_addr)); sc_p.Warning("envp: 0x%x", envp_addr);
sc_p.Log("data: 0x%x", data); sc_p.Warning("data: 0x%x", data_addr);
sc_p.Log("data_size: 0x%x", data_size); sc_p.Warning("data_size: 0x%x", data_size);
sc_p.Log("prio: %d", prio); sc_p.Warning("prio: %d", prio);
sc_p.Log("flags: %d", flags); sc_p.Warning("flags: %d", flags);
return CELL_OK;
wxString path = Memory.ReadString(path_addr);
std::vector<wxString> argv;
std::vector<wxString> env;
mem_ptr_t<u32> argvp(argv_addr);
while (argvp.GetAddr() && argvp.IsGood() && *argvp)
{
argv.push_back(Memory.ReadString(Memory.Read32(argvp.GetAddr())));
argvp++;
}
mem_ptr_t<u32> 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 <path> 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<wxString> argv;
std::vector<wxString> env;
mem_ptr_t<u32> argvp(argv_addr);
while (argvp.GetAddr() && argvp.IsGood() && *argvp)
{
argv.push_back(Memory.ReadString(Memory.Read32(argvp.GetAddr())));
argvp++;
}
mem_ptr_t<u32> 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 <path> 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) 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)", sc_p.Warning("TODO: sys_process_get_number_of_object(object=%d, nump_addr=0x%x)",