mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-02-02 22:05:09 +01:00
kernel: sysctl: add AppInfo2
stub camera and devact ioctls stub sys_cpuset reduce log spam thanks ga2mer for investigation
This commit is contained in:
parent
6257c0f76d
commit
20303c903d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 = "/";
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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__);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue