- sceSaveDataMount
- Create2 mode (50)
- slight change in error handling (testing for now)
- log to print message when fd = 1 in sceKernelWrite (to avoid crash and move forward, not a file)
- mount savedata at emu start for CUSA00402 - Crimsonland (only case, needs testing)
- sceSaveDataGetMountInfo

- scePthreadGetthreadid
- posix_getpid
- posix_pthread_attr_setdetachstate
- posix_pthread_attr_destroy
- posix_pthread_detach
- scePthreadSetschedparam(partial)
- posix_pthread_setschedparam (partial)
- posix_sched_get_priority_max
This commit is contained in:
raziel1000 2024-05-26 22:12:38 -06:00
parent 5cf24a8be3
commit cbf6a62ef5
8 changed files with 194 additions and 28 deletions

View File

@ -82,6 +82,15 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, void* buf, size_t nbytes) {
if (buf == nullptr) {
return SCE_KERNEL_ERROR_EFAULT;
}
if (d == 1) {
// temp, just to print the message. not a file?
// CUSA00402 - Crimsonland and probably other games.
char* msg = reinterpret_cast<char*>(buf);
size_t length = std::strlen(msg);
LOG_INFO(Kernel_Fs, "sceKernelWrite fd = 1, str = {}, length = {}", msg, length);
return length;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
if (file == nullptr) {
@ -159,7 +168,12 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) {
return SCE_KERNEL_ERROR_EEXIST;
}
if (!std::filesystem::create_directory(dir_name)) {
if (!std::filesystem::create_directories(dir_name)) {
// check me on saveDataMount.
// CUSA02456: calls sceSaveDataMount then mkdir
// CUSA00402: calls mkdir first before sceSaveDataMount
// maybe consider mounting save data at emu start? (added in main)
return SCE_KERNEL_ERROR_EIO;
}

View File

@ -23,6 +23,7 @@
#include <windows.h>
#else
#include <sys/mman.h>
#include <unistd.h>
#endif
#include <core/file_format/psf.h>
@ -217,6 +218,18 @@ int PS4_SYSV_ABI sceKernelGetCpumode() {
return SCE_KERNEL_CPUMODE_7CPU_NORMAL;
}
int PS4_SYSV_ABI scePthreadGetthreadid() {
#ifdef _WIN64
return GetCurrentProcessId();
#else
return getpid();
#endif
}
int PS4_SYSV_ABI posix_getpid() {
return scePthreadGetthreadid();
}
void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
// obj
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
@ -250,6 +263,8 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
LIB_FUNCTION("VOx8NGmHXTs", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCpumode);
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, scePthreadGetthreadid);
LIB_FUNCTION("HoLVWNanBBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpid);
Libraries::Kernel::fileSystemSymbolsRegister(sym);
Libraries::Kernel::timeSymbolsRegister(sym);

View File

@ -177,6 +177,22 @@ int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachst
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
}
int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(ScePthreadAttr* attr, int detachstate) {
int result = scePthreadAttrSetdetachstate(attr, detachstate);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_attr_destroy(ScePthreadAttr* attr) {
int result = scePthreadAttrDestroy(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched) {
if (attr == nullptr || *attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
@ -899,7 +915,13 @@ void PS4_SYSV_ABI scePthreadYield() {
}
int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) {
LOG_INFO(Kernel_Pthread, "thread create name = {}", thread->name);
LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name);
thread->is_detached = true;
return ORBIS_OK;
}
int PS4_SYSV_ABI posix_pthread_detach(ScePthread thread) {
LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name);
thread->is_detached = true;
return ORBIS_OK;
}
@ -965,6 +987,31 @@ int PS4_SYSV_ABI posix_pthread_setspecific(pthread_key_t key, void* ptr) {
}
}
int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy,
const SceKernelSchedParam* param) {
int ppolicy;
if (policy != SCHED_OTHER)
ppolicy = SCHED_OTHER;
int result = pthread_setschedparam(thread->pth, ppolicy, param);
// 0 only on win?
LOG_INFO(Kernel_Pthread, "Todo? scePthreadSetschedparam: policy = {}, result = {}", policy,
result);
return result;
}
int PS4_SYSV_ABI posix_pthread_setschedparam(ScePthread thread, int policy,
const SceKernelSchedParam* param) {
int result = scePthreadSetschedparam(thread, policy, param);
LOG_INFO(Kernel_Pthread, "Todo? posix_pthread_setschedparam: policy = {}, result = {}", policy,
result);
return result;
}
int PS4_SYSV_ABI posix_sched_get_priority_max(int algo) {
LOG_INFO(Kernel_Pthread, "posix_sched_get_priority_max: algo = {}", algo);
return SCE_KERNEL_PRIO_FIFO_HIGHEST;
}
int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
if (cond == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
@ -1381,6 +1428,9 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetaffinity);
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetstacksize);
LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_attr_setdetachstate);
LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_destroy);
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual);
@ -1391,9 +1441,13 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("6UgtwV+0zb4", "libkernel", 1, "libkernel", 1, 1, scePthreadCreate);
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, scePthreadYield);
LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, scePthreadKeyCreate);
LIB_FUNCTION("oIRFTjoILbg", "libkernel", 1, "libkernel", 1, 1, scePthreadSetschedparam);
LIB_FUNCTION("mqULNdimTn0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_create);
LIB_FUNCTION("mqULNdimTn0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_key_create);
LIB_FUNCTION("WrOLvHU0yQM", "libkernel", 1, "libkernel", 1, 1, posix_pthread_setspecific);
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
LIB_FUNCTION("CBNtXOoef-E", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_max);
LIB_FUNCTION("+U1R4WtXvoc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_detach);
// mutex calls
LIB_FUNCTION("cmo1RIYva9o", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexInit);

View File

@ -17,6 +17,13 @@ class SymbolsResolver;
namespace Libraries::Kernel {
/* sceKernelSchedGetPriorityMax/Min */
constexpr int SCE_KERNEL_SCHED_FIFO = SCHED_FIFO;
constexpr int SCE_KERNEL_SCHED_RR = SCHED_RR;
constexpr int SCE_KERNEL_PRIO_FIFO_DEFAULT = 700;
constexpr int SCE_KERNEL_PRIO_FIFO_HIGHEST = 256;
constexpr int SCE_KERNEL_PRIO_FIFO_LOWEST = 767;
struct PthreadInternal;
struct PthreadAttrInternal;
struct PthreadMutexInternal;

View File

@ -4,5 +4,7 @@
#pragma once
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMETER = 0x809f0000;
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED =
0x809f0001; // save data library not initialized yet
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809f0008; // save data doesn't exist
constexpr int ORBIS_SAVE_DATA_ERROR_EXISTS = 0x809f0007; // save data directory,same name exists

View File

@ -13,7 +13,7 @@
#include "error_codes.h"
namespace Libraries::SaveData {
static bool initialized = false;
static std::string g_mount_point = "/savedata0"; // temp mount point (todo)
int PS4_SYSV_ABI sceSaveDataAbort() {
@ -241,8 +241,11 @@ int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataGetMountInfo() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
int PS4_SYSV_ABI sceSaveDataGetMountInfo(OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataMountInfo* info) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called, mount = {}", mountPoint->data);
info->blocks = 100000;
info->freeBlocks = 100000;
return ORBIS_OK;
}
@ -296,17 +299,20 @@ int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataInitialize() {
int PS4_SYSV_ABI sceSaveDataInitialize(const OrbisSaveDataInitParams* initParam) {
initialized = true; // todo.
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataInitialize2() {
int PS4_SYSV_ABI sceSaveDataInitialize2(const OrbisSaveDataInitParams* initParam) {
initialized = true; // todo.
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataInitialize3() {
int PS4_SYSV_ABI sceSaveDataInitialize3(const OrbisSaveDataInitParams* initParam) {
initialized = true; // todo.
LOG_ERROR(Lib_SaveData, "(DUMMY) called");
return ORBIS_OK;
}
@ -331,32 +337,25 @@ int PS4_SYSV_ABI sceSaveDataLoadIcon() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataMount() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
OrbisSaveDataMountResult* mount_result) {
LOG_INFO(Lib_SaveData, "called user_id = {} dir_name = {} blocks = {} mount_mode = {}",
mount->user_id, mount->dir_name->data, mount->blocks, mount->mount_mode);
auto* param_sfo = Common::Singleton<PSF>::Instance();
std::string id(param_sfo->GetString("CONTENT_ID"), 7, 9);
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(mount->user_id) / "savedata" / id /
std::string(mount->dir_name->data);
switch (mount->mount_mode) {
std::to_string(user_id) / "savedata" / id / dir_name;
switch (mount_mode) {
case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: {
if (!std::filesystem::exists(mount_dir)) {
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
if (!initialized /* !std::filesystem::exists(mount_dir)*/) {
// check this. example: CUSA02456
return ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED;
}
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, g_mount_point);
mount_result->mount_status = 0;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
LOG_ERROR(Lib_SaveData, "mount = {}", mount_result->mount_point.data);
} break;
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
@ -372,6 +371,18 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
mount_result->mount_status = 1;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
} break;
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: {
if (!std::filesystem::exists(mount_dir)) {
std::filesystem::create_directories(mount_dir);
}
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, g_mount_point);
mount_result->mount_status = 1;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
} break;
default:
UNREACHABLE();
}
@ -380,6 +391,28 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
OrbisSaveDataMountResult* mount_result) {
if (mount == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
}
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data,
mount->mount_mode, mount->blocks);
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode,
mount_result);
}
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
OrbisSaveDataMountResult* mount_result) {
if (mount == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
}
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data,
mount->mount_mode, mount->blocks);
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode,
mount_result);
}
int PS4_SYSV_ABI sceSaveDataMount5() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;

View File

@ -29,6 +29,30 @@ struct OrbisSaveDataMount2 {
s32 unk2;
};
constexpr int SCE_SAVE_DATA_TITLE_ID_DATA_SIZE = 10;
typedef struct OrbisSaveDataTitleId {
char data[SCE_SAVE_DATA_TITLE_ID_DATA_SIZE];
char padding[6];
} OrbisSaveDataTitleId;
constexpr int SCE_SAVE_DATA_FINGERPRINT_DATA_SIZE = 65;
typedef struct OrbisSaveDataFingerprint {
char data[SCE_SAVE_DATA_FINGERPRINT_DATA_SIZE];
char padding[15];
} OrbisSaveDataFingerprint;
typedef struct OrbisSaveDataMount {
s32 user_id;
s32 pad;
const OrbisSaveDataTitleId* titleId;
const OrbisSaveDataDirName* dir_name;
const OrbisSaveDataFingerprint* fingerprint;
u64 blocks;
u32 mount_mode;
u8 reserved[32];
} OrbisSaveDataMount;
struct OrbisSaveDataMountPoint {
char data[ORBIS_SAVE_DATA_MOUNT_POINT_DATA_MAXSIZE];
};
@ -42,6 +66,14 @@ struct OrbisSaveDataMountResult {
s32 unk1;
};
typedef struct OrbisSaveDataMountInfo {
u64 blocks; // total num of blocks
u64 freeBlocks; // free num of blocks
uint8_t reserved[32];
} OrbisSaveDataMountInfo;
typedef struct _OrbisSaveDataInitParams OrbisSaveDataInitParams;
// savedataMount2 mountModes (ORed values)
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1;
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDWR = 2;
@ -95,7 +127,8 @@ int PS4_SYSV_ABI sceSaveDataGetEventInfo();
int PS4_SYSV_ABI sceSaveDataGetEventResult();
int PS4_SYSV_ABI sceSaveDataGetFormat();
int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount();
int PS4_SYSV_ABI sceSaveDataGetMountInfo();
int PS4_SYSV_ABI sceSaveDataGetMountInfo(OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataMountInfo* info);
int PS4_SYSV_ABI sceSaveDataGetParam();
int PS4_SYSV_ABI sceSaveDataGetProgress();
int PS4_SYSV_ABI sceSaveDataGetSaveDataCount();
@ -106,14 +139,15 @@ int PS4_SYSV_ABI sceSaveDataGetSaveDataRootPath();
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootUsbPath();
int PS4_SYSV_ABI sceSaveDataGetSavePoint();
int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount();
int PS4_SYSV_ABI sceSaveDataInitialize();
int PS4_SYSV_ABI sceSaveDataInitialize2();
int PS4_SYSV_ABI sceSaveDataInitialize3();
int PS4_SYSV_ABI sceSaveDataInitialize(const OrbisSaveDataInitParams* initParam);
int PS4_SYSV_ABI sceSaveDataInitialize2(const OrbisSaveDataInitParams* initParam);
int PS4_SYSV_ABI sceSaveDataInitialize3(const OrbisSaveDataInitParams* initParam);
int PS4_SYSV_ABI sceSaveDataInitializeForCdlg();
int PS4_SYSV_ABI sceSaveDataIsDeletingUsbDb();
int PS4_SYSV_ABI sceSaveDataIsMounted();
int PS4_SYSV_ABI sceSaveDataLoadIcon();
int PS4_SYSV_ABI sceSaveDataMount();
int PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
OrbisSaveDataMountResult* mount_result);
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
OrbisSaveDataMountResult* mount_result);
int PS4_SYSV_ABI sceSaveDataMount5();

View File

@ -63,6 +63,13 @@ int main(int argc, char* argv[]) {
u32 fw_version = param_sfo->GetInteger("SYSTEM_VER");
std::string app_version = param_sfo->GetString("APP_VER");
LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version);
// Just testing for now.
// Working fine, one case only so far (CUSA00402 - Crimsonland)
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
"1" / "savedata" / id;
mnt->Mount(mount_dir, "/savedata0");
} else if (entry.path().filename() == "pic0.png" ||
entry.path().filename() == "pic1.png") {
auto* splash = Common::Singleton<Splash>::Instance();