[orbis-kernel] sysctl: implement more names

This commit is contained in:
DH 2023-10-30 21:55:47 +03:00
parent 06a0910c80
commit c439f81060

View file

@ -1,5 +1,6 @@
#include "KernelContext.hpp"
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
uint namelen, ptr<void> old,
@ -21,17 +22,33 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> 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<sint> 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<sint> 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<app_info>)old, result);
}
if (name[0] == 1 && name[1] == 14 && name[2] == 44) {
@ -77,7 +157,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> 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<sint> 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<sint> 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<sint> name,
std::printf("Reporting SDK version %x\n",
*reinterpret_cast<uint32_t *>(sdkVersion));
*(uint32_t *)old = *reinterpret_cast<uint32_t *>(sdkVersion);
return{};
return {};
}
case sysctl_kern::sched_cpusetsize:
@ -213,16 +353,15 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> 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<sint> 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<sint> 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<sint> 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<sint> name,
}
*(uint32_t *)old = 0x4000;
return{};
return {};
default:
break;
@ -298,11 +476,11 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> 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<sint> 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 {};
}