From c439f81060c0eb5dacad559b50e182eddb1b5cb4 Mon Sep 17 00:00:00 2001 From: DH Date: Mon, 30 Oct 2023 21:55:47 +0300 Subject: [PATCH] [orbis-kernel] sysctl: implement more names --- orbis-kernel/src/sys/sys_sysctl.cpp | 230 +++++++++++++++++++++++++--- 1 file changed, 205 insertions(+), 25 deletions(-) diff --git a/orbis-kernel/src/sys/sys_sysctl.cpp b/orbis-kernel/src/sys/sys_sysctl.cpp index b202064f2..1314da838 100644 --- a/orbis-kernel/src/sys/sys_sysctl.cpp +++ b/orbis-kernel/src/sys/sys_sysctl.cpp @@ -1,5 +1,6 @@ #include "KernelContext.hpp" #include "sys/sysproto.hpp" +#include "utils/Logs.hpp" orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, uint namelen, ptr old, @@ -21,17 +22,33 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, proc_ptc, cpu_mode, rng_pseudo, + backup_restore_mode, }; enum sysctl_hw { pagesize = 7, + + // FIXME + config = 1000, }; + enum sysctl_vm { + // FIXME + swap_avail = 1000, + swap_total, + kern_heap_size, + }; + + enum sysctl_hw_config { chassis_info }; + enum sysctl_machdep { // FIXME - tsc_freq = 1000 + tsc_freq = 1000, + liverpool, }; + enum sysctl_machdep_liverpool { telemetry = 1000, icc_max }; + // for (unsigned int i = 0; i < namelen; ++i) { // std::fprintf(stderr, " name[%u] = %u\n", i, name[i]); // } @@ -39,7 +56,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, if (namelen == 3) { // 1 - 14 - 41 - debug flags? - if (name[0] == 1 && name[1] == 14 && name[2] == 41) { + if (name[0] == kern && name[1] == 14 && name[2] == 41) { // std::printf(" kern.14.41\n"); if (*oldlenp != 4 || new_ != nullptr || newlen != 0) { @@ -49,20 +66,83 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, *(uint32_t *)old = 0; return {}; } + + if (name[0] == kern && name[1] == 14 && name[2] == 42) { + // std::printf(" kern.14.42\n"); + + if ((oldlenp != nullptr && *oldlenp != 0) || new_ == nullptr || + newlen != 4) { + return ErrorCode::INVAL; + } + + // set record + auto record = *(uint32_t *)new_; + // ORBIS_LOG_WARNING("sys___sysctl: set record", record); + return {}; + } + + if (name[0] == kern && name[1] == 14 && name[2] == 8) { + // KERN_PROC_PROC + + struct ProcInfo { + char data[0x448]; + }; + + *oldlenp = 0; + return {}; + } + + if (name[0] == machdep && name[1] == liverpool && name[2] == telemetry) { + if (*oldlenp != 8 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + *(uint64_t *)old = 0; + return {}; + } + if (name[0] == machdep && name[1] == liverpool && name[2] == icc_max) { + if (*oldlenp != 4 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + *(uint32_t *)old = 0; + return {}; + } + + if (name[0] == hw && name[1] == config && name[2] == chassis_info) { + if (*oldlenp != 8 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + *(uint64_t *)old = 0; + return {}; + } } if (namelen == 4) { - // 1 - 14 - 35 - 2 - - // sceKernelGetAppInfo - struct app_info { - char unk[72]; - }; - if (name[0] == 1 && name[1] == 14 && name[2] == 35) { + // sceKernelGetAppInfo + struct app_info { + uint32_t appId; + uint32_t unk0; + uint32_t unk1; + uint32_t appType; + char titleId[10]; + uint16_t unk3; + slong unk5; + uint32_t unk6; + uint16_t unk7; + char unk_[26]; + }; + + // 1 - 14 - 35 - pid // std::printf(" kern.14.35.%u\n", name[3]); - memset(old, 0, sizeof(app_info)); - return {}; + app_info result{ + .appType = 0, + // .unk5 = slong(0x80000000'00000000), + }; + + return uwrite((ptr)old, result); } if (name[0] == 1 && name[1] == 14 && name[2] == 44) { @@ -77,7 +157,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, if (std::string_view("libkernel") == mod->moduleName) { dest[0] = (uint64_t)mod->segments[0].addr; dest[1] = mod->segments[0].size; - return{}; + return {}; } } } @@ -150,10 +230,70 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, dest[count++] = kern; dest[count++] = cpu_mode; + } else if (searchName == "kern.backup_restore_mode") { + if (*oldlenp < 2 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = kern; + dest[count++] = backup_restore_mode; + } else if (searchName == "hw.config.chassis_info") { + if (*oldlenp < 3 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = hw; + dest[count++] = config; + dest[count++] = chassis_info; + } else if (searchName == "machdep.liverpool.telemetry") { + if (*oldlenp < 3 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = machdep; + dest[count++] = liverpool; + dest[count++] = telemetry; + } else if (searchName == "machdep.liverpool.icc_max") { + if (*oldlenp < 3 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = machdep; + dest[count++] = liverpool; + dest[count++] = icc_max; + } else if (searchName == "vm.swap_avail") { + if (*oldlenp < 2 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = vm; + dest[count++] = swap_avail; + } else if (searchName == "vm.kern_heap_size") { + if (*oldlenp < 2 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = vm; + dest[count++] = kern_heap_size; + } else if (searchName == "vm.swap_total") { + if (*oldlenp < 2 * sizeof(uint32_t)) { + std::fprintf(stderr, " %s error\n", searchName.data()); + return ErrorCode::INVAL; + } + + dest[count++] = vm; + dest[count++] = swap_total; } if (count == 0) { - std::fprintf(stderr, " %s is unknown\n", searchName.data()); + std::fprintf(stderr, "sys___sysctl: %s is unknown\n", + searchName.data()); return ErrorCode::SRCH; } @@ -186,7 +326,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, } *(uint32_t *)old = 1; - return{}; + return {}; case sysctl_kern::sdk_version: { if (*oldlenp != 4 || new_ != nullptr || newlen != 0) { @@ -204,7 +344,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, std::printf("Reporting SDK version %x\n", *reinterpret_cast(sdkVersion)); *(uint32_t *)old = *reinterpret_cast(sdkVersion); - return{}; + return {}; } case sysctl_kern::sched_cpusetsize: @@ -213,16 +353,15 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, } *(std::uint32_t *)old = 4; - return{}; + return {}; case sysctl_kern::rng_pseudo: if (*oldlenp != 0x40 || new_ != nullptr || newlen != 0) { return ErrorCode::INVAL; } - std::memset(old, 0, 0x40); - return{}; + return {}; case sysctl_kern::kern_37: { struct kern37_value { @@ -237,7 +376,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, auto value = (kern37_value *)old; value->size = sizeof(kern37_value); - return{}; + return {}; } case sysctl_kern::proc_ptc: { @@ -246,7 +385,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, } *(std::uint64_t *)old = 1357; - return{}; + return {}; } case sysctl_kern::cpu_mode: { @@ -258,15 +397,54 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, // 1 - 7 cpu, low power // 5 - 7 cpu, normal *(std::uint32_t *)old = 5; - return{}; + return {}; } + case sysctl_kern::backup_restore_mode: + if (*oldlenp != 4 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + // 0 - normal + // 1 - backup + // 2 - restore + *(std::uint32_t *)old = 0; + return {}; + default: return ErrorCode::INVAL; } break; case sysctl_ctl::vm: + switch (name[1]) { + case sysctl_vm::kern_heap_size: + if (*oldlenp != 4 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + *(std::uint32_t *)old = (1 << 14) >> 14; + return {}; + + case sysctl_vm::swap_total: + if (*oldlenp != 8 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + *(std::uint64_t *)old = 0; + return {}; + + case sysctl_vm::swap_avail: + if (*oldlenp != 4 || new_ != nullptr || newlen != 0) { + return ErrorCode::INVAL; + } + + *(std::uint32_t *)old = (1 << 14) >> 14; + return {}; + + default: + break; + } case sysctl_ctl::vfs: case sysctl_ctl::net: case sysctl_ctl::debug: @@ -280,7 +458,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, } *(uint32_t *)old = 0x4000; - return{}; + return {}; default: break; @@ -298,11 +476,11 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, return {}; default: - return ErrorCode::INVAL; + break; } } case sysctl_ctl::user: - return ErrorCode::INVAL; + break; } } @@ -315,6 +493,8 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, concatName += std::to_string(name[i]); } - ORBIS_LOG_TODO(__FUNCTION__, concatName); + std::size_t oldLen = oldlenp ? *oldlenp : 0; + ORBIS_LOG_TODO(__FUNCTION__, concatName, oldLen, new_, newlen); + thread->where(); return {}; }