kernel: sysctl: add AppInfo2

stub camera and devact ioctls
stub sys_cpuset
reduce log spam

thanks ga2mer for investigation
This commit is contained in:
DH 2024-11-26 15:29:43 +03:00
parent 6257c0f76d
commit 20303c903d
9 changed files with 297 additions and 56 deletions

View file

@ -1,6 +1,7 @@
#pragma once
#include "orbis-config.hpp"
#include <array>
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

View file

@ -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 @@ public:
uint fwSdkVersion{};
uint safeMode{};
utils::RcIdMap<RcBase, sint, 4097, 1> ipmiMap;
RcIdMap<RcAppInfo> appInfos;
shared_mutex regMgrMtx;
kmap<std::uint32_t, std::uint32_t> regMgrInt;

View file

@ -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 = "/";

View file

@ -47,7 +47,7 @@ static cpu_set_t toHostCpuSet(orbis::cpuset cpuSet) {
}
orbis::SysResult orbis::sys_cpuset(Thread *thread, ptr<cpusetid_t> setid) {
return ErrorCode::NOSYS;
return {};
}
orbis::SysResult orbis::sys_cpuset_setid(Thread *thread, cpuwhich_t which,
id_t id, cpusetid_t setid) {

View file

@ -20,21 +20,10 @@
#include <sys/stat.h>
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<uint32_t> result;
};
@ -569,6 +558,9 @@ orbis::SysResult orbis::sys_osem_wait(Thread *thread, sint id, sint need,
ptr<uint> pTimeout) {
ORBIS_LOG_TRACE(__FUNCTION__, thread, id, need, pTimeout);
Ref<Semaphore> 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<void> a,
ptr<uint32_t> 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<budget>(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<RcAppInfo>();
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<uint32_t>(_info.result, handle);
}
orbis::SysResult orbis::sys_end_app_mount(Thread *thread /* TODO */) {
ORBIS_LOG_FATAL(__FUNCTION__);

View file

@ -201,7 +201,6 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> 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<sint> 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<sint> 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;
}
ORBIS_RET_ON_ERROR(uread(oldlen, oldlenp));
if (oldlen < sizeof(AppInfo)) {
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<AppInfo2>)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<AppInfo>)old, process->appInfo));
ORBIS_RET_ON_ERROR(uwrite(oldlenp, sizeof(AppInfo)));
} else {
return ErrorCode::INVAL;
}
if (auto errc = uwrite((ptr<AppInfo>)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;
}
if (newlen == sizeof(AppInfo2)) {
auto result = uread(process->appInfo2, (ptr<AppInfo2>)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);
auto result = uread(process->appInfo, (ptr<AppInfo>)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);
}
}
// 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<AppInfo>)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<sint> 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<uint32_t>(old), 5u));
ORBIS_RET_ON_ERROR(uwrite<size_t>(oldlenp, sizeof(uint32_t)));
}
if (new_) {
if (newlen != sizeof(uint32_t)) {
return ErrorCode::INVAL;
}
uint32_t appState;
ORBIS_RET_ON_ERROR(uread(appState, ptr<uint32_t>(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<AppInfo2>)old,
*static_cast<AppInfo2 *>(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<uint32_t>(old), sdkVersion));
ORBIS_LOG_ERROR("get ps5 sdk version by pid", name[3], sdkVersion);
return uwrite(oldlenp, sizeof(uint32_t));
}
}

View file

@ -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);
}

View file

@ -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<Args *>(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<azDevice *>(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 {

View file

@ -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 {};
}