[rpcsx-os/orbis-kernel] random fixes

fix pipe
fix socketpair
fix bridge
fix evf_wait with timeout
fix umtx_op(0x17)
implement ipmi evf
stub sched_get_priority_max/min
stub sys_rtprio_thread
implement sys_yield
emit event on signal
stub ajm register/unregister ioctls
stub av_control ioctl
hack removal
This commit is contained in:
DH 2024-01-04 03:53:58 +03:00
parent bbfcda5f10
commit e90566e7de
26 changed files with 625 additions and 147 deletions

View file

@ -27,10 +27,6 @@ orbis::SysResult orbis::sys_dup(Thread *thread, uint fd) {
orbis::SysResult orbis::sys_fcntl(Thread *thread, sint fd, sint cmd,
slong arg) {
ORBIS_LOG_TODO(__FUNCTION__, fd, cmd, arg);
if (cmd == 0xb) {
// TODO: hack
std::this_thread::sleep_for(std::chrono::seconds(10));
}
return {};
}
orbis::SysResult orbis::sys_close(Thread *thread, sint fd) {

View file

@ -2,10 +2,10 @@
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <chrono>
#include <sys/resource.h>
#include <sys/wait.h>
#include <thread>
#include <unistd.h>
#include <sys/resource.h>
orbis::SysResult orbis::sys_exit(Thread *thread, sint status) {
if (auto exit = thread->tproc->ops->exit) {
@ -33,22 +33,27 @@ orbis::SysResult orbis::sys_wait4(Thread *thread, sint pid, ptr<sint> status,
}
::rusage hostUsage;
int stat;
int result = ::wait4(hostPid, &stat, options, &hostUsage);
if (result < 0) {
return static_cast<ErrorCode>(errno);
while (true) {
int stat;
int result = ::wait4(hostPid, &stat, options, &hostUsage);
if (result < 0) {
return static_cast<ErrorCode>(errno);
}
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
auto process = g_context.findProcessByHostId(result);
if (process == nullptr) {
ORBIS_LOG_ERROR("host process not found", result);
continue;
}
if (status != nullptr) {
ORBIS_RET_ON_ERROR(uwrite(status, stat));
}
thread->retval[0] = process->pid;
break;
}
ORBIS_LOG_ERROR(__FUNCTION__, pid, status, options, rusage, result, stat);
auto process = g_context.findProcessByHostId(result);
if (process == nullptr) {
std::abort();
}
if (status != nullptr) {
ORBIS_RET_ON_ERROR(uwrite(status, stat));
}
thread->retval[0] = process->pid;
return {};
}

View file

@ -1,4 +1,5 @@
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
#include <thread>
orbis::SysResult
@ -24,11 +25,15 @@ orbis::SysResult orbis::sys_sched_yield(Thread *thread) {
}
orbis::SysResult orbis::sys_sched_get_priority_max(Thread *thread,
sint policy) {
return ErrorCode::NOSYS;
ORBIS_LOG_ERROR(__FUNCTION__, policy);
thread->retval[0] = 90;
return {};
}
orbis::SysResult orbis::sys_sched_get_priority_min(Thread *thread,
sint policy) {
return ErrorCode::NOSYS;
ORBIS_LOG_ERROR(__FUNCTION__, policy);
thread->retval[0] = 10;
return {};
}
orbis::SysResult orbis::sys_sched_rr_get_interval(Thread *thread, pid_t pid,
ptr<timespec> interval) {

View file

@ -3,9 +3,9 @@
#include <pipe.hpp>
orbis::SysResult orbis::sys_pipe(Thread *thread) {
auto pipe = createPipe();
auto fd0 = thread->tproc->fileDescriptors.insert(pipe);
auto fd1 = thread->tproc->fileDescriptors.insert(pipe);
auto [a, b] = createPipe();
auto fd0 = thread->tproc->fileDescriptors.insert(a);
auto fd1 = thread->tproc->fileDescriptors.insert(b);
ORBIS_LOG_ERROR(__FUNCTION__, fd0, fd1);
thread->retval[0] = fd0;
thread->retval[1] = fd1;

View file

@ -1,4 +1,5 @@
#include "sys/sysproto.hpp"
#include "utils/Logs.hpp"
namespace orbis {
struct rlimit {
@ -7,7 +8,6 @@ struct rlimit {
};
} // namespace orbis
orbis::SysResult orbis::sys_getpriority(Thread *thread, sint which, sint who) {
return ErrorCode::NOSYS;
}
@ -18,7 +18,12 @@ orbis::SysResult orbis::sys_setpriority(Thread *thread, sint which, sint who,
orbis::SysResult orbis::sys_rtprio_thread(Thread *thread, sint function,
lwpid_t lwpid,
ptr<struct rtprio> rtp) {
std::printf("sys_rtprio_thread: unimplemented\n");
ORBIS_LOG_ERROR(__FUNCTION__, function, lwpid, rtp->prio, rtp->type);
thread->where();
if (function == 0) {
rtp->type = 2;
rtp->prio = 10;
}
return {};
}
orbis::SysResult orbis::sys_rtprio(Thread *thread, sint function, pid_t pid,

View file

@ -281,11 +281,13 @@ orbis::SysResult orbis::sys_evf_wait(Thread *thread, sint id,
}
std::uint32_t resultTimeout{};
if (pTimeout != nullptr) {
ORBIS_RET_ON_ERROR(uread(resultTimeout, pTimeout));
}
auto result = evf->wait(thread, mode, patternSet,
pTimeout != nullptr ? &resultTimeout : nullptr);
ORBIS_LOG_TRACE("sys_evf_wait wakeup", thread->tid, thread->evfResultPattern);
if (pPatternSet != nullptr) {
ORBIS_RET_ON_ERROR(uwrite(pPatternSet, thread->evfResultPattern));
}
@ -336,7 +338,7 @@ orbis::SysResult orbis::sys_evf_set(Thread *thread, sint id, uint64_t value) {
return ErrorCode::SRCH;
}
ORBIS_LOG_TRACE(__FUNCTION__, evf->name, thread->tid, id, value);
// ORBIS_LOG_TRACE(__FUNCTION__, evf->name, thread->tid, id, value);
evf->set(value);
return {};
}
@ -960,7 +962,7 @@ orbis::SysResult orbis::sys_mdbg_service(Thread *thread, uint32_t op,
}
case 0x14: {
std::this_thread::sleep_for(std::chrono::years(1));
// std::this_thread::sleep_for(std::chrono::years(1));
break;
}
@ -1184,6 +1186,11 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
return sysIpmiSendConnectResult(thread, result, kid, params, paramsSz);
case 0x232:
return sysIpmiSessionRespondSync(thread, result, kid, params, paramsSz);
case 0x241:
return sysIpmiClientInvokeAsyncMethod(thread, result, kid, params,
paramsSz);
case 0x243:
return sysIpmiClientTryGetResult(thread, result, kid, params, paramsSz);
case 0x251:
return sysIpmiClientGetMessage(thread, result, kid, params, paramsSz);
case 0x252:
@ -1202,12 +1209,35 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
return sysIpmiSessionGetUserData(thread, result, kid, params, paramsSz);
case 0x46a:
return sysIpmiServerGetName(thread, result, kid, params, paramsSz);
case 0x490:
return sysIpmiClientWaitEventFlag(thread, result, kid, params, paramsSz);
case 0x491:
return sysIpmiClientPollEventFlag(thread, result, kid, params, paramsSz);
case 0x493:
return sysIpmiSessionSetEventFlag(thread, result, kid, params, paramsSz);
}
if (auto ipmi = thread->tproc->ipmiMap.get(kid)) {
if (auto client = ipmi.cast<IpmiClient>()) {
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, client->name, result,
params, paramsSz);
thread->where();
return uwrite(result, 0u);
}
if (auto server = ipmi.cast<IpmiServer>()) {
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, server->name, result,
params, paramsSz);
thread->where();
return uwrite(result, 0u);
}
if (auto session = ipmi.cast<IpmiSession>(); session && session->client) {
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, session->client->name,
result, params, paramsSz);
thread->where();
return uwrite(result, 0u);
}
}
ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, kid, result, params, paramsSz);
thread->where();
return uwrite(result, 0u);
@ -1247,16 +1277,22 @@ orbis::SysResult orbis::sys_physhm_unlink(Thread *thread /* TODO */) {
orbis::SysResult orbis::sys_resume_internal_hdd(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_thr_suspend_ucontext(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
orbis::SysResult orbis::sys_thr_suspend_ucontext(Thread *thread, lwpid_t tid) {
// ORBIS_LOG_FATAL(__FUNCTION__, tid);
return {};
}
orbis::SysResult orbis::sys_thr_resume_ucontext(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
orbis::SysResult orbis::sys_thr_resume_ucontext(Thread *thread, lwpid_t tid) {
// ORBIS_LOG_FATAL(__FUNCTION__, tid);
return {};
}
orbis::SysResult orbis::sys_thr_get_ucontext(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
orbis::SysResult orbis::sys_thr_get_ucontext(Thread *thread, lwpid_t tid,
ptr<UContext> context) {
// ORBIS_LOG_FATAL(__FUNCTION__, tid, context);
return {};
}
orbis::SysResult orbis::sys_thr_set_ucontext(Thread *thread /* TODO */) {
orbis::SysResult orbis::sys_thr_set_ucontext(Thread *thread, lwpid_t tid,
ptr<UContext> context) {
ORBIS_LOG_FATAL(__FUNCTION__, tid, context);
return ErrorCode::NOSYS;
}
orbis::SysResult orbis::sys_set_timezone_info(Thread *thread /* TODO */) {

View file

@ -1,3 +1,7 @@
#include "sys/sysproto.hpp"
#include <thread>
orbis::SysResult orbis::sys_yield(Thread *thread) { return ErrorCode::NOSYS; }
orbis::SysResult orbis::sys_yield(Thread *thread) {
std::this_thread::yield();
return {};
}

View file

@ -10,8 +10,8 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
enum sysctl_kern {
usrstack = 33,
kern_14 = 14,
kern_37 = 37,
proc = 14,
arnd = 37,
// FIXME
smp_cpus = 1000,
@ -39,15 +39,25 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
kern_heap_size,
};
enum sysctl_hw_config { chassis_info };
enum sysctl_hw_config {
chassis_info,
optical_out = 1000,
};
enum sysctl_machdep {
// FIXME
tsc_freq = 1000,
liverpool,
bootparams,
};
enum sysctl_machdep_liverpool { telemetry = 1000, icc_max };
enum sysctl_machdep_liverpool {
telemetry = 1000,
icc_max,
};
enum sysctl_machdep_bootparams {
is_main_on_standby = 1000,
};
struct ProcInfo {
char data[0x448];
@ -60,7 +70,17 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
if (namelen == 3) {
// 1 - 14 - 41 - debug flags?
if (name[0] == kern && name[1] == 14 && name[2] == 41) {
if (name[0] == machdep && name[1] == bootparams &&
name[2] == is_main_on_standby) {
if (*oldlenp != 4 || new_ != nullptr || newlen != 0) {
return ErrorCode::INVAL;
}
*(uint32_t *)old = 0;
return {};
}
if (name[0] == kern && name[1] == proc && name[2] == 41) {
// std::printf(" kern.14.41\n");
if (*oldlenp != 4 || new_ != nullptr || newlen != 0) {
@ -71,7 +91,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
return {};
}
if (name[0] == kern && name[1] == 14 && name[2] == 42) {
if (name[0] == kern && name[1] == proc && name[2] == 42) {
// std::printf(" kern.14.42\n");
if ((oldlenp != nullptr && *oldlenp != 0) || new_ == nullptr ||
@ -85,8 +105,10 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
return {};
}
if (name[0] == kern && name[1] == 14 && name[2] == 8) {
if (name[0] == kern && name[1] == proc && name[2] == 8) {
// KERN_PROC_PROC
ORBIS_LOG_ERROR("KERN_PROC_PROC");
thread->where();
std::memset(old, 0, sizeof(ProcInfo));
*oldlenp = sizeof(ProcInfo);
return {};
@ -120,13 +142,15 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
}
if (namelen == 4) {
if (name[0] == kern && name[1] == 14 && name[2] == 1) {
if (name[0] == kern && name[1] == proc && name[2] == 1) {
ORBIS_LOG_ERROR("KERN_PROC_PROC 2");
std::memset(old, 0, sizeof(ProcInfo));
*oldlenp = sizeof(ProcInfo);
return {};
}
if (name[0] == 1 && name[1] == 14 && name[2] == 35) {
if (name[0] == 1 && name[1] == proc && name[2] == 35) {
// AppInfo get/set
// 1 - 14 - 35 - pid
@ -346,6 +370,24 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
dest[count++] = vm;
dest[count++] = swap_total;
} else if (searchName == "machdep.bootparams.is_main_on_standby") {
if (*oldlenp < 3 * sizeof(uint32_t)) {
std::fprintf(stderr, " %s error\n", searchName.data());
return ErrorCode::INVAL;
}
dest[count++] = machdep;
dest[count++] = bootparams;
dest[count++] = is_main_on_standby;
} else if (searchName == "hw.config.optical_out") {
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++] = optical_out;
}
if (count == 0) {
@ -411,7 +453,7 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr<sint> name,
std::memset(old, 0, 0x40);
return {};
case sysctl_kern::kern_37: {
case sysctl_kern::arnd: {
struct kern37_value {
std::uint64_t size;
std::uint64_t unk[7];

View file

@ -157,7 +157,7 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr<void> obj, sint op,
});
}
case 18:
return umtx_wake_umutex(thread, (ptr<umutex>)obj);
return umtx_wake_umutex(thread, (ptr<umutex>)obj, 0);
case 19:
return with_timeout(
[&](std::uint64_t ut) {
@ -171,8 +171,9 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr<void> obj, sint op,
case 22:
return umtx_wake2_umutex(thread, obj, val, uaddr1, uaddr2);
case 23:
ORBIS_LOG_ERROR("sys__umtx_op: unknown wake operation", op);
return umtx_wake_umutex(thread, (orbis::ptr<orbis::umutex>)obj);
ORBIS_LOG_ERROR("sys__umtx_op: unknown wake operation", op, val, uaddr1, uaddr2);
// thread->where();
return umtx_wake_umutex(thread, (orbis::ptr<orbis::umutex>)obj, val);
}
return ErrorCode::INVAL;