From 20303c903d648806f6be85699b1d0e5e89339618 Mon Sep 17 00:00:00 2001 From: DH Date: Tue, 26 Nov 2024 15:29:43 +0300 Subject: [PATCH] kernel: sysctl: add AppInfo2 stub camera and devact ioctls stub sys_cpuset reduce log spam thanks ga2mer for investigation --- orbis-kernel/include/orbis/AppInfo.hpp | 20 ++ orbis-kernel/include/orbis/KernelContext.hpp | 6 + orbis-kernel/include/orbis/thread/Process.hpp | 1 + orbis-kernel/src/sys/sys_cpuset.cpp | 2 +- orbis-kernel/src/sys/sys_sce.cpp | 76 +++++-- orbis-kernel/src/sys/sys_sysctl.cpp | 194 +++++++++++++++--- rpcsx/io-device.cpp | 4 +- rpcsx/iodev/camera.cpp | 35 +++- rpcsx/iodev/devact.cpp | 19 ++ 9 files changed, 299 insertions(+), 58 deletions(-) diff --git a/orbis-kernel/include/orbis/AppInfo.hpp b/orbis-kernel/include/orbis/AppInfo.hpp index be5482c0..97423a6a 100644 --- a/orbis-kernel/include/orbis/AppInfo.hpp +++ b/orbis-kernel/include/orbis/AppInfo.hpp @@ -1,6 +1,7 @@ #pragma once #include "orbis-config.hpp" +#include namespace orbis { struct AppInfo { @@ -18,4 +19,23 @@ struct AppInfo { slong unk8; }; static_assert(sizeof(AppInfo) == 72); + +struct AppInfo2 { + uint32_t appId; + uint32_t unk0; + uint32_t unk1; + uint32_t appType; + char titleId[10]; + uint16_t unk2; + uint32_t unk3; + slong unk4; + slong unk5; + slong unk6; + slong unk7; + slong unk8; + slong unk9; + slong unk10; +}; + +static_assert(sizeof(AppInfo2) == 88); } // namespace orbis diff --git a/orbis-kernel/include/orbis/KernelContext.hpp b/orbis-kernel/include/orbis/KernelContext.hpp index 239b64f1..86315d4d 100644 --- a/orbis-kernel/include/orbis/KernelContext.hpp +++ b/orbis-kernel/include/orbis/KernelContext.hpp @@ -1,4 +1,5 @@ #pragma once +#include "AppInfo.hpp" #include "KernelAllocator.hpp" #include "evf.hpp" #include "ipmi.hpp" @@ -54,6 +55,10 @@ enum class FwType : std::uint8_t { Ps5, }; +struct RcAppInfo : RcBase, AppInfo2 { + orbis::uint32_t appState = 0; +}; + class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { public: KernelContext(); @@ -195,6 +200,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { uint fwSdkVersion{}; uint safeMode{}; utils::RcIdMap ipmiMap; + RcIdMap appInfos; shared_mutex regMgrMtx; kmap regMgrInt; diff --git a/orbis-kernel/include/orbis/thread/Process.hpp b/orbis-kernel/include/orbis/thread/Process.hpp index 9bc984b9..f3f1aeb7 100644 --- a/orbis-kernel/include/orbis/thread/Process.hpp +++ b/orbis-kernel/include/orbis/thread/Process.hpp @@ -69,6 +69,7 @@ struct Process final { uint64_t processParamSize = 0; const ProcessOps *ops = nullptr; AppInfo appInfo{}; + AppInfo2 appInfo2{}; AuthInfo authInfo{}; kstring cwd; kstring root = "/"; diff --git a/orbis-kernel/src/sys/sys_cpuset.cpp b/orbis-kernel/src/sys/sys_cpuset.cpp index 557cc8ab..5852e068 100644 --- a/orbis-kernel/src/sys/sys_cpuset.cpp +++ b/orbis-kernel/src/sys/sys_cpuset.cpp @@ -47,7 +47,7 @@ static cpu_set_t toHostCpuSet(orbis::cpuset cpuSet) { } orbis::SysResult orbis::sys_cpuset(Thread *thread, ptr setid) { - return ErrorCode::NOSYS; + return {}; } orbis::SysResult orbis::sys_cpuset_setid(Thread *thread, cpuwhich_t which, id_t id, cpusetid_t setid) { diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index ec5e6981..03c2f42e 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -20,21 +20,10 @@ #include struct orbis::AppMountInfo { - uint64_t unk0; // 8 - uint32_t unk1; - uint32_t unk2; - char titleId[10]; - uint8_t unk3[6]; - uint64_t unk4; - uint64_t unk5; - uint64_t unk6; - uint64_t unk7; - uint64_t unk8; - uint64_t unk9; - uint64_t unk10; - uint64_t unk11; - uint64_t unk12; - uint64_t unk13; + AppInfo2 appInfo; + uint64_t unk0; + uint64_t unk1; + uint64_t unk2; ptr result; }; @@ -569,6 +558,9 @@ orbis::SysResult orbis::sys_osem_wait(Thread *thread, sint id, sint need, ptr pTimeout) { ORBIS_LOG_TRACE(__FUNCTION__, thread, id, need, pTimeout); Ref sem = thread->tproc->semMap.get(id); + if (sem == nullptr) { + return ErrorCode::BADF; + } if (need < 1 || need > sem->maxValue) return ErrorCode::INVAL; @@ -753,6 +745,30 @@ orbis::SysResult orbis::sys_budget_delete(Thread *thread /* TODO */) { } orbis::SysResult orbis::sys_budget_get(Thread *thread, sint id, ptr a, ptr count) { + ORBIS_LOG_ERROR(__FUNCTION__, id, a, count); + + struct budget { + uint32_t id; + uint32_t unk0; + uint64_t unk1; + uint64_t unk2; + }; + + static_assert(sizeof(budget) == 0x18); + + if (g_context.fwType == FwType::Ps5 && id == 1) { + std::uint32_t _count; + ORBIS_RET_ON_ERROR(orbis::uread(_count, count)); + + if (_count == 0) { + ORBIS_RET_ON_ERROR(orbis::uwrite(count, 1u)); + return {}; + } + + ptr(a)->id = 4; + + ORBIS_RET_ON_ERROR(orbis::uwrite(count, 1u)); + } return {}; } orbis::SysResult orbis::sys_budget_set(Thread *thread, slong budget) { @@ -1714,13 +1730,29 @@ orbis::SysResult orbis::sys_begin_app_mount(Thread *thread, AppMountInfo _info; ORBIS_RET_ON_ERROR(uread(_info, info)); ORBIS_LOG_FATAL(__FUNCTION__, _info.unk0, _info.unk1, _info.unk2, - _info.titleId, int(_info.unk3[0]), int(_info.unk3[1]), - int(_info.unk3[2]), int(_info.unk3[3]), int(_info.unk3[4]), - int(_info.unk3[5]), int(_info.unk3[6]), _info.unk4, - _info.unk5, _info.unk6, _info.unk7, _info.unk8, _info.unk9, - _info.unk10, _info.unk11, _info.unk12, _info.unk13, - _info.result); - return orbis::uwrite(_info.result, 0u); + _info.result, _info.appInfo.appId, _info.appInfo.unk0, + _info.appInfo.unk1, _info.appInfo.appType, + _info.appInfo.titleId, _info.appInfo.unk2, _info.appInfo.unk3, + _info.appInfo.unk4, _info.appInfo.unk5, _info.appInfo.unk6, + _info.appInfo.unk7, _info.appInfo.unk8, _info.appInfo.unk9, + _info.appInfo.unk10); + + orbis::Ref appInfo = orbis::knew(); + + AppInfo2 *appInfoData = appInfo.get(); + auto handle = g_context.appInfos.insert(appInfo); + ORBIS_LOG_TODO(__FUNCTION__, handle); + thread->where(); + if (handle == decltype(g_context.appInfos)::npos) { + return ErrorCode::DOOFUS; + } + + std::memcpy(appInfoData, &_info, sizeof(AppInfo2)); + std::memcpy(&thread->tproc->appInfo2, &_info, sizeof(AppInfo2)); + thread->tproc->appInfo2.appId = handle; + appInfoData->appId = handle; + + return orbis::uwrite(_info.result, handle); } orbis::SysResult orbis::sys_end_app_mount(Thread *thread /* TODO */) { ORBIS_LOG_FATAL(__FUNCTION__); diff --git a/orbis-kernel/src/sys/sys_sysctl.cpp b/orbis-kernel/src/sys/sys_sysctl.cpp index ab7d162f..8d37a41a 100644 --- a/orbis-kernel/src/sys/sys_sysctl.cpp +++ b/orbis-kernel/src/sys/sys_sysctl.cpp @@ -201,7 +201,6 @@ SysResult kern_sysctl(Thread *thread, ptr name, uint namelen, return {}; } - if (name[0] == vm && name[1] == budgets && name[2] == mlock_avail) { if (*oldlenp != 16 || new_ != nullptr || newlen != 0) { return ErrorCode::INVAL; @@ -283,7 +282,6 @@ SysResult kern_sysctl(Thread *thread, ptr name, uint namelen, // AppInfo get/set // 1 - 14 - 35 - pid - Process *process = thread->tproc; if (process->pid != name[3] && name[3] != -1) { process = g_context.findProcessById(name[3]); @@ -294,48 +292,73 @@ SysResult kern_sysctl(Thread *thread, ptr name, uint namelen, } } + ORBIS_LOG_ERROR("1.14.35", name[3]); + thread->where(); + if (old) { size_t oldlen; - if (auto errc = uread(oldlen, oldlenp); errc != ErrorCode{}) { - return errc; - } - - if (oldlen < sizeof(AppInfo)) { + ORBIS_RET_ON_ERROR(uread(oldlen, oldlenp)); + + ORBIS_LOG_ERROR("1.14.35", name[3], oldlen); + + if (oldlen == sizeof(AppInfo2)) { + ORBIS_LOG_ERROR("get AppInfo2", process->appInfo2.appId, + process->appInfo2.unk0, process->appInfo2.unk1, + process->appInfo2.appType, process->appInfo2.titleId, + process->appInfo2.unk2, process->appInfo2.unk3, + process->appInfo2.unk5, process->appInfo2.unk6, + process->appInfo2.unk7, process->appInfo2.unk8); + + ORBIS_RET_ON_ERROR(uwrite((ptr)old, process->appInfo2)); + ORBIS_RET_ON_ERROR(uwrite(oldlenp, sizeof(AppInfo2))); + } else if (oldlen == sizeof(AppInfo)) { + ORBIS_LOG_ERROR("get AppInfo", process->appInfo.appId, + process->appInfo.unk0, process->appInfo.unk1, + process->appInfo.appType, process->appInfo.titleId, + process->appInfo.unk2, process->appInfo.unk3, + process->appInfo.unk5, process->appInfo.unk6, + process->appInfo.unk7, process->appInfo.unk8); + + ORBIS_RET_ON_ERROR(uwrite((ptr)old, process->appInfo)); + ORBIS_RET_ON_ERROR(uwrite(oldlenp, sizeof(AppInfo))); + } else { return ErrorCode::INVAL; } - - if (auto errc = uwrite((ptr)old, process->appInfo); - errc != ErrorCode{}) { - return errc; - } - - if (auto errc = uwrite(oldlenp, sizeof(AppInfo)); errc != ErrorCode{}) { - return errc; - } } if (new_) { - if (newlen != sizeof(AppInfo)) { - return ErrorCode::INVAL; - } - - auto result = uread(process->appInfo, (ptr)new_); - if (result == ErrorCode{}) { - auto &appInfo = process->appInfo; - ORBIS_LOG_ERROR("set AppInfo", appInfo.appId, appInfo.unk0, - appInfo.unk1, appInfo.appType, appInfo.titleId, - appInfo.unk2, appInfo.unk3, appInfo.unk5, - appInfo.unk6, appInfo.unk7, appInfo.unk8); + if (newlen == sizeof(AppInfo2)) { + auto result = uread(process->appInfo2, (ptr)new_); + if (result == ErrorCode{}) { + auto &appInfo = process->appInfo; + ORBIS_LOG_ERROR("set AppInfo2", appInfo.appId, appInfo.unk0, + appInfo.unk1, appInfo.appType, appInfo.titleId, + appInfo.unk2, appInfo.unk3, appInfo.unk5, + appInfo.unk6, appInfo.unk7, appInfo.unk8); + + // HACK + if (appInfo.appId == 0 && appInfo.unk4 == 0) { + appInfo.unk4 = orbis::slong(0x80000000'00000000); + } + } - // HACK - if (appInfo.appId == 0 && appInfo.unk4 == 0) { - appInfo.unk4 = orbis::slong(0x80000000'00000000); + return result; + } else if (newlen == sizeof(AppInfo)) { + auto result = uread(process->appInfo, (ptr)new_); + if (result == ErrorCode{}) { + auto &appInfo = process->appInfo; + ORBIS_LOG_ERROR("set AppInfo", appInfo.appId, appInfo.unk0, + appInfo.unk1, appInfo.appType, appInfo.titleId, + appInfo.unk2, appInfo.unk3, appInfo.unk5, + appInfo.unk6, appInfo.unk7, appInfo.unk8); + + // HACK + if (appInfo.appId == 0 && appInfo.unk4 == 0) { + appInfo.unk4 = orbis::slong(0x80000000'00000000); + } } } - - return result; } - return {}; } @@ -354,6 +377,111 @@ SysResult kern_sysctl(Thread *thread, ptr name, uint namelen, return {}; } } + + return ErrorCode::SRCH; + } + + if (name[0] == kern && name[1] == proc && name[2] == 64) { + auto appInfo = g_context.appInfos.get(name[3]); + if (appInfo == nullptr) { + return ErrorCode::SRCH; // ? + } + + if (old) { + size_t oldlen; + ORBIS_RET_ON_ERROR(uread(oldlen, oldlenp)); + if (oldlen < sizeof(uint32_t)) { + return ErrorCode::INVAL; + } + + ORBIS_LOG_TODO("1.14.64 get", name[3], appInfo->appState); + + ORBIS_RET_ON_ERROR(uwrite(ptr(old), 5u)); + ORBIS_RET_ON_ERROR(uwrite(oldlenp, sizeof(uint32_t))); + } + + if (new_) { + if (newlen != sizeof(uint32_t)) { + return ErrorCode::INVAL; + } + + uint32_t appState; + ORBIS_RET_ON_ERROR(uread(appState, ptr(new_))); + ORBIS_LOG_TODO("1.14.64 set", name[3], appState); + appInfo->appState = appState; + } + return {}; + } + + if (name[0] == 1 && name[1] == proc && name[2] == 65) { + // AppInfo by appId get/set + // 1 - 14 - 65 - appId + auto appInfo = g_context.appInfos.get(name[3]); + if (appInfo == nullptr) { + ORBIS_LOG_ERROR("appinfo appId not found", name[3], thread->tproc->pid); + return ErrorCode::SRCH; + } + + if (old) { + size_t oldlen; + ORBIS_RET_ON_ERROR(uread(oldlen, oldlenp)); + + ORBIS_LOG_ERROR("1.14.65", name[3], oldlen); + + if (oldlen < sizeof(AppInfo2)) { + return ErrorCode::INVAL; + } + + ORBIS_LOG_ERROR("get AppInfo2", appInfo->appId, appInfo->unk0, + appInfo->unk1, appInfo->appType, appInfo->titleId, + appInfo->unk2, appInfo->unk3, appInfo->unk5, + appInfo->unk6, appInfo->unk7, appInfo->unk8); + + if (auto errc = uwrite((ptr)old, + *static_cast(appInfo.get())); + errc != ErrorCode{}) { + return errc; + } + + if (auto errc = uwrite(oldlenp, sizeof(AppInfo2)); + errc != ErrorCode{}) { + return errc; + } + } + + if (new_) { + return ErrorCode::INVAL; + } + + return {}; + } + + if (name[0] == kern && name[1] == proc && name[2] == 68) { + Process *process = thread->tproc; + if (process->pid != name[3]) { + process = g_context.findProcessById(name[3]); + if (process == nullptr) { + ORBIS_LOG_ERROR("get ps5 sdk version by pid: process not found", + name[3], thread->tproc->pid); + return ErrorCode::SRCH; + } + } + + size_t oldlen; + ORBIS_RET_ON_ERROR(uread(oldlen, oldlenp)); + + if (oldlen < sizeof(uint32_t)) { + return ErrorCode::INVAL; + } + + auto sdkVersion = process->sdkVersion; + if (sdkVersion == 0) { + sdkVersion = g_context.fwSdkVersion; + } + + ORBIS_RET_ON_ERROR(uwrite(ptr(old), sdkVersion)); + ORBIS_LOG_ERROR("get ps5 sdk version by pid", name[3], sdkVersion); + return uwrite(oldlenp, sizeof(uint32_t)); } } diff --git a/rpcsx/io-device.cpp b/rpcsx/io-device.cpp index 1c4eb939..abf81a09 100644 --- a/rpcsx/io-device.cpp +++ b/rpcsx/io-device.cpp @@ -467,7 +467,9 @@ static orbis::ErrorCode socket_read(orbis::File *file, orbis::Uio *uio, return orbis::ErrorCode::INVAL; } - ORBIS_LOG_FATAL(__FUNCTION__, file, uio->iov->len); + if (uio->iov->len) { + ORBIS_LOG_FATAL(__FUNCTION__, file, uio->iov->len); + } return host_fd_read(socket->hostFd, uio); } diff --git a/rpcsx/iodev/camera.cpp b/rpcsx/iodev/camera.cpp index b7253f9c..4c6f2d50 100644 --- a/rpcsx/iodev/camera.cpp +++ b/rpcsx/iodev/camera.cpp @@ -1,19 +1,52 @@ #include "io-device.hpp" #include "orbis/KernelAllocator.hpp" #include "orbis/file.hpp" +#include "orbis/thread/Thread.hpp" +#include "orbis/uio.hpp" #include "orbis/utils/Logs.hpp" struct CameraFile : orbis::File {}; static orbis::ErrorCode camera_ioctl(orbis::File *file, std::uint64_t request, - void *argp, orbis::Thread *thread) { + void *argp, orbis::Thread *thread) { + if (request == 0xc0308e14) { + struct Args { + orbis::uint32_t unk0; + orbis::uint32_t unk1; + orbis::uint32_t unk2; + orbis::uint32_t unk3; + orbis::int32_t unk4; + orbis::uint32_t unk5; + orbis::uint32_t unk6; + }; + auto args = reinterpret_cast(argp); + args->unk0 = 0xff; + args->unk1 = 0; + args->unk2 = 0; + args->unk3 = 0; + args->unk4 = 0; + args->unk6 = 0x1337; + return {}; + } ORBIS_LOG_FATAL("Unhandled camera ioctl", request); return {}; } +static orbis::ErrorCode camera_write(orbis::File *file, orbis::Uio *uio, + orbis::Thread *thread) { + // auto device = static_cast(file->device.get()); + std::uint64_t totalSize = 0; + for (auto vec : std::span(uio->iov, uio->iovcnt)) { + totalSize += vec.len; + } + thread->retval[0] = totalSize; + return {}; +} + static const orbis::FileOps fileOps = { .ioctl = camera_ioctl, + .write = camera_write, }; struct CameraDevice : IoDevice { diff --git a/rpcsx/iodev/devact.cpp b/rpcsx/iodev/devact.cpp index ae51e5f3..5958b54f 100644 --- a/rpcsx/iodev/devact.cpp +++ b/rpcsx/iodev/devact.cpp @@ -1,6 +1,7 @@ #include "io-device.hpp" #include "orbis/KernelAllocator.hpp" #include "orbis/file.hpp" +#include "orbis/thread/Thread.hpp" #include "orbis/utils/Logs.hpp" struct DevActFile : orbis::File {}; @@ -21,7 +22,25 @@ static orbis::ErrorCode devact_ioctl(orbis::File *file, std::uint64_t request, param->unk0 = 1; return{}; } + + if (request == 0x40144401) { + // is expired + struct Param { + std::uint32_t unk0; + std::uint32_t unk1; + std::uint32_t unk2; + std::uint32_t unk3; + std::uint32_t unk4; + std::uint32_t unk5; + }; + auto param = (Param *)argp; + *param = {}; + param->unk1 = 1; + return{}; + } + ORBIS_LOG_FATAL("Unhandled devact ioctl", request); + thread->where(); return {}; }