From e90566e7def387d697ab73c76e6c9cf76848787b Mon Sep 17 00:00:00 2001 From: DH Date: Thu, 4 Jan 2024 03:53:58 +0300 Subject: [PATCH] [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 --- .../bridge/include/amdgpu/bridge/bridge.hpp | 3 +- hw/amdgpu/bridge/src/bridge.cpp | 2 +- orbis-kernel/include/orbis/evf.hpp | 7 +- orbis-kernel/include/orbis/ipmi.hpp | 34 +- orbis-kernel/include/orbis/pipe.hpp | 4 +- orbis-kernel/include/orbis/sys/sysproto.hpp | 9 +- orbis-kernel/include/orbis/thread/types.hpp | 2 + orbis-kernel/include/orbis/ucontext.hpp | 70 ++++ orbis-kernel/include/orbis/umtx.hpp | 2 +- orbis-kernel/src/ipmi.cpp | 309 ++++++++++++++++-- orbis-kernel/src/pipe.cpp | 14 +- orbis-kernel/src/sys/sys_descrip.cpp | 4 - orbis-kernel/src/sys/sys_exit.cpp | 37 ++- orbis-kernel/src/sys/sys_p1003_1b.cpp | 9 +- orbis-kernel/src/sys/sys_pipe.cpp | 6 +- orbis-kernel/src/sys/sys_resource.cpp | 9 +- orbis-kernel/src/sys/sys_sce.cpp | 58 +++- orbis-kernel/src/sys/sys_synch.cpp | 6 +- orbis-kernel/src/sys/sys_sysctl.cpp | 62 +++- orbis-kernel/src/sys/sys_umtx.cpp | 7 +- orbis-kernel/src/umtx.cpp | 59 ++-- rpcsx-os/iodev/ajm.cpp | 11 + rpcsx-os/iodev/av_control.cpp | 17 + rpcsx-os/iodev/hdmi.cpp | 2 + rpcsx-os/main.cpp | 14 +- rpcsx-os/ops.cpp | 15 +- 26 files changed, 625 insertions(+), 147 deletions(-) create mode 100644 orbis-kernel/include/orbis/ucontext.hpp diff --git a/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp b/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp index c5ec3e6df..4088f9969 100644 --- a/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp +++ b/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp @@ -223,7 +223,8 @@ private: } position = 0; - waitPuller(0); + header->push = position; + waitPuller(position); } return position; diff --git a/hw/amdgpu/bridge/src/bridge.cpp b/hw/amdgpu/bridge/src/bridge.cpp index 11e82ada7..8d159fa2b 100644 --- a/hw/amdgpu/bridge/src/bridge.cpp +++ b/hw/amdgpu/bridge/src/bridge.cpp @@ -7,7 +7,7 @@ static int gShmFd = -1; static constexpr std::size_t kShmSize = sizeof(amdgpu::bridge::BridgeHeader) + - (sizeof(std::uint64_t) * (1024 * 1024)); + (sizeof(std::uint64_t) * 256); std::uint32_t amdgpu::bridge::expGpuPid = 0; amdgpu::bridge::BridgeHeader * diff --git a/orbis-kernel/include/orbis/evf.hpp b/orbis-kernel/include/orbis/evf.hpp index 79c2fc646..9e265b087 100644 --- a/orbis-kernel/include/orbis/evf.hpp +++ b/orbis-kernel/include/orbis/evf.hpp @@ -24,9 +24,9 @@ struct EventFlag final { char name[32]; bool isDeleted = false; - std::uint8_t attrs; + std::uint8_t attrs = kEvfAttrMulti | kEvfAttrThFifo; std::atomic references{0}; - std::atomic value; + std::atomic value{0}; struct WaitingThread { Thread *thread; @@ -61,7 +61,8 @@ struct EventFlag final { enum class NotifyType { Set, Cancel, Destroy }; - explicit EventFlag(std::int32_t attrs, std::uint64_t initPattern) + EventFlag() = default; + EventFlag(std::int32_t attrs, std::uint64_t initPattern) : attrs(attrs), value(initPattern) {} ErrorCode wait(Thread *thread, std::uint8_t waitMode, diff --git a/orbis-kernel/include/orbis/ipmi.hpp b/orbis-kernel/include/orbis/ipmi.hpp index 5093ad0af..1472d4554 100644 --- a/orbis-kernel/include/orbis/ipmi.hpp +++ b/orbis-kernel/include/orbis/ipmi.hpp @@ -59,6 +59,7 @@ struct IpmiClient : RcBase { shared_cv sessionCv; sint pid; kdeque> messages; + kdeque eventFlags; shared_cv messageCv; explicit IpmiClient(kstring name) : name(std::move(name)) {} @@ -77,7 +78,6 @@ struct IpmiSession : RcBase { shared_mutex mutex; shared_cv responseCv; kdeque messageResponses; - EventFlag evf{0, 0}; shared_cv connectCv; bool expectedOutput = false; // TODO: verify sint connectionStatus{0}; @@ -98,12 +98,19 @@ struct IpmiCreateServerConfig { static_assert(sizeof(IpmiCreateServerConfig) == 0x38); +struct IpmiCreateClientConfig { + orbis::uint64_t size; + orbis::uint32_t unk[80]; + orbis::ptr userData; +}; + +static_assert(sizeof(IpmiCreateClientConfig) == 0x150); + struct IpmiBufferInfo { ptr data; uint64_t size; }; -static_assert(sizeof(IpmiBufferInfo) == 0x10); struct IpmiDataInfo { ptr data; @@ -111,6 +118,7 @@ struct IpmiDataInfo { uint64_t capacity; //? }; +static_assert(sizeof(IpmiBufferInfo) == 0x10); static_assert(sizeof(IpmiDataInfo) == 0x18); struct IpmiSyncMessageHeader { @@ -124,7 +132,7 @@ struct IpmiSyncMessageHeader { static_assert(sizeof(IpmiSyncMessageHeader) == 0x18); ErrorCode ipmiCreateClient(Process *proc, void *clientImpl, const char *name, - void *config, Ref &result); + const IpmiCreateClientConfig &config, Ref &result); ErrorCode ipmiCreateServer(Process *proc, void *serverImpl, const char *name, const IpmiCreateServerConfig &config, Ref &result); @@ -151,16 +159,21 @@ SysResult sysIpmiSendConnectResult(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); SysResult sysIpmiSessionRespondSync(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); +SysResult sysIpmiClientInvokeAsyncMethod(Thread *thread, ptr result, + uint kid, ptr params, + uint64_t paramsSz); +SysResult sysIpmiClientTryGetResult(Thread *thread, ptr result, + uint kid, ptr params, + uint64_t paramsSz); SysResult sysIpmiClientGetMessage(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); SysResult sysIpmiClientTryGetMessage(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); SysResult sysIpmiSessionTrySendMessage(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz); -SysResult sysIpmiClientDisconnect(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz); + uint kid, ptr params, + uint64_t paramsSz); +SysResult sysIpmiClientDisconnect(Thread *thread, ptr result, uint kid, + ptr params, uint64_t paramsSz); SysResult sysIpmiSessionGetClientPid(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); SysResult sysIpmiClientInvokeSyncMethod(Thread *thread, ptr result, @@ -172,11 +185,10 @@ SysResult sysIpmiSessionGetUserData(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); SysResult sysIpmiServerGetName(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); +SysResult sysIpmiClientWaitEventFlag(Thread *thread, ptr result, uint kid, + ptr params, uint64_t paramsSz); SysResult sysIpmiClientPollEventFlag(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); -SysResult sysIpmiSessionWaitEventFlag(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz); SysResult sysIpmiSessionSetEventFlag(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz); diff --git a/orbis-kernel/include/orbis/pipe.hpp b/orbis-kernel/include/orbis/pipe.hpp index 8dc9e637c..50ae1077c 100644 --- a/orbis-kernel/include/orbis/pipe.hpp +++ b/orbis-kernel/include/orbis/pipe.hpp @@ -5,12 +5,14 @@ #include "utils/Rc.hpp" #include "utils/SharedCV.hpp" #include "utils/SharedMutex.hpp" +#include namespace orbis { struct Pipe final : File { shared_cv cv; kvector data; + Ref other; }; -Ref createPipe(); +std::pair, Ref> createPipe(); } // namespace orbis diff --git a/orbis-kernel/include/orbis/sys/sysproto.hpp b/orbis-kernel/include/orbis/sys/sysproto.hpp index fcdeb9659..b86a450fa 100644 --- a/orbis-kernel/include/orbis/sys/sysproto.hpp +++ b/orbis-kernel/include/orbis/sys/sysproto.hpp @@ -21,6 +21,7 @@ struct Stat; struct stack_t; struct IoVec; struct BatchMapEntry; +struct UContext; SysResult nosys(Thread *thread); @@ -743,10 +744,10 @@ SysResult sys_mmap_dmem(Thread *thread, caddr_t addr, size_t len, SysResult sys_physhm_open(Thread *thread /* TODO */); SysResult sys_physhm_unlink(Thread *thread /* TODO */); SysResult sys_resume_internal_hdd(Thread *thread /* TODO */); -SysResult sys_thr_suspend_ucontext(Thread *thread /* TODO */); -SysResult sys_thr_resume_ucontext(Thread *thread /* TODO */); -SysResult sys_thr_get_ucontext(Thread *thread /* TODO */); -SysResult sys_thr_set_ucontext(Thread *thread /* TODO */); +SysResult sys_thr_suspend_ucontext(Thread *thread, lwpid_t tid); +SysResult sys_thr_resume_ucontext(Thread *thread, lwpid_t tid); +SysResult sys_thr_get_ucontext(Thread *thread, lwpid_t tid, ptr context); +SysResult sys_thr_set_ucontext(Thread *thread, lwpid_t tid, ptr context); SysResult sys_set_timezone_info(Thread *thread /* TODO */); SysResult sys_set_phys_fmem_limit(Thread *thread /* TODO */); SysResult sys_utc_to_localtime(Thread *thread, int64_t time, int64_t *localtime, diff --git a/orbis-kernel/include/orbis/thread/types.hpp b/orbis-kernel/include/orbis/thread/types.hpp index 33f576eb3..9985a6b2a 100644 --- a/orbis-kernel/include/orbis/thread/types.hpp +++ b/orbis-kernel/include/orbis/thread/types.hpp @@ -27,5 +27,7 @@ struct thr_param { // following flags: ptr rtp; // Real-time scheduling priority for the new thread. May be // NULL to inherit the priority from the creating thread + ptr name; + ptr spare[2]; }; } // namespace orbis diff --git a/orbis-kernel/include/orbis/ucontext.hpp b/orbis-kernel/include/orbis/ucontext.hpp new file mode 100644 index 000000000..2afb3e4fc --- /dev/null +++ b/orbis-kernel/include/orbis/ucontext.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include "orbis-config.hpp" +namespace orbis { + +struct MContext { + ulong onstack; + ulong rdi; + ulong rsi; + ulong rdx; + ulong rcx; + ulong r8; + ulong r9; + ulong rax; + ulong rbx; + ulong rbp; + ulong r10; + ulong r11; + ulong r12; + ulong r13; + ulong r14; + ulong r15; + uint trapno; + ushort fs; + ushort gs; + ulong addr; + uint flags; + ushort es; + ushort ds; + ulong err; + ulong rip; + ulong cs; + ulong rflags; + ulong rsp; + ulong ss; + ulong len; + ulong fpformat; + ulong ownedfp; + ulong lbrfrom; + ulong lbrto; + ulong aux1; + ulong aux2; + ulong fpstate[104]; + ulong fsbase; + ulong gsbase; + ulong spare[6]; +}; + +struct Stack { + ptr sp; + size_t size; + sint flags; + sint align; +}; + +struct SigSet { + ulong bits[2]; +}; + +struct UContext { + SigSet sigmask; + sint unk0[12]; + MContext mcontext; + ptr link; + Stack stack; + sint uc_flags; + sint spare[4]; + sint unk1[3]; +}; +} // namespace orbis diff --git a/orbis-kernel/include/orbis/umtx.hpp b/orbis-kernel/include/orbis/umtx.hpp index 4047ee546..fd1eaf29d 100644 --- a/orbis-kernel/include/orbis/umtx.hpp +++ b/orbis-kernel/include/orbis/umtx.hpp @@ -85,7 +85,7 @@ ErrorCode umtx_rw_wrlock(Thread *thread, ptr rwlock, ulong ut); ErrorCode umtx_rw_unlock(Thread *thread, ptr rwlock); ErrorCode umtx_wake_private(Thread *thread, ptr uaddr, sint n_wake); ErrorCode umtx_wait_umutex(Thread *thread, ptr m, std::uint64_t ut); -ErrorCode umtx_wake_umutex(Thread *thread, ptr m); +ErrorCode umtx_wake_umutex(Thread *thread, ptr m, sint wakeFlags); ErrorCode umtx_sem_wait(Thread *thread, ptr sem, std::uint64_t ut); ErrorCode umtx_sem_wake(Thread *thread, ptr sem); ErrorCode umtx_nwake_private(Thread *thread, ptr uaddrs, diff --git a/orbis-kernel/src/ipmi.cpp b/orbis-kernel/src/ipmi.cpp index b039c3af5..f81a4962f 100644 --- a/orbis-kernel/src/ipmi.cpp +++ b/orbis-kernel/src/ipmi.cpp @@ -2,9 +2,11 @@ #include "KernelContext.hpp" #include "thread/Process.hpp" #include "utils/Logs.hpp" +#include orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl, - const char *name, void *config, + const char *name, + const IpmiCreateClientConfig &config, Ref &result) { auto client = knew(name); if (client == nullptr) { @@ -14,6 +16,8 @@ orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl, client->clientImpl = clientImpl; client->name = name; client->pid = proc->pid; + client->userData = config.userData; + client->eventFlags.resize(32); result = client; return {}; } @@ -84,7 +88,7 @@ orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr result, struct IpmiCreateClientParams { ptr clientImpl; ptr name; - ptr config; // FIXME: describe + ptr config; }; static_assert(sizeof(IpmiCreateClientParams) == 0x18); @@ -94,13 +98,15 @@ orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr result, } IpmiCreateClientParams _params; + IpmiCreateClientConfig _config; char _name[25]; Ref client; ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); + ORBIS_RET_ON_ERROR(uread(_config, _params.config)); ORBIS_RET_ON_ERROR(ureadString(_name, sizeof(_name), _params.name)); ORBIS_RET_ON_ERROR(ipmiCreateClient(thread->tproc, _params.clientImpl, _name, - nullptr, client)); + _config, client)); auto kid = thread->tproc->ipmiMap.insert(std::move(client)); @@ -316,6 +322,7 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread, } ORBIS_LOG_ERROR(__FUNCTION__, session->client->name); + thread->where(); kvector data; @@ -340,22 +347,181 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread, session->responseCv.notify_one(session->mutex); return uwrite(result, 0u); } -orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { +orbis::SysResult orbis::sysIpmiClientInvokeAsyncMethod(Thread *thread, + ptr result, + uint kid, + ptr params, + uint64_t paramsSz) { + struct IpmiAsyncCallParams { + uint32_t method; + uint32_t unkNotifee0; + uint64_t unkNotifee1; + uint32_t numInData; + uint32_t padding1; + ptr pInData; + ptr pResult; + uint32_t flags; + }; + + static_assert(sizeof(IpmiAsyncCallParams) == 0x30); + + if (paramsSz != sizeof(IpmiAsyncCallParams)) { + return ErrorCode::INVAL; + } + auto client = thread->tproc->ipmiMap.get(kid).cast(); if (client == nullptr) { return ErrorCode::INVAL; } - ORBIS_LOG_ERROR(__FUNCTION__, client->name, client->messages.size(), - paramsSz); - while (true) { - std::this_thread::sleep_for(std::chrono::days(1)); + IpmiAsyncCallParams _params; + ORBIS_RET_ON_ERROR(uread(_params, (ptr)params)); + + ORBIS_LOG_TODO(__FUNCTION__, thread->tid, client->name, _params.method, + _params.unkNotifee0, _params.unkNotifee1, _params.numInData, + _params.padding1, _params.pInData, _params.pResult, + _params.flags); + thread->where(); + + if (_params.unkNotifee0 != -1) { + client->eventFlags[_params.unkNotifee0].set(1); + } + + ORBIS_RET_ON_ERROR(uwrite(_params.pResult, 0)); + return uwrite(result, 0u); +} + +orbis::SysResult orbis::sysIpmiClientTryGetResult(Thread *thread, + ptr result, uint kid, + ptr params, + uint64_t paramsSz) { + struct IpmiTryGetResultParams { + uint32_t method; + uint32_t unk; + ptr pResult; + uint32_t numOutData; + uint32_t padding; + ptr pOutData; + uint64_t padding2; + }; + + static_assert(sizeof(IpmiTryGetResultParams) == 0x28); + + if (paramsSz != sizeof(IpmiTryGetResultParams)) { + return ErrorCode::INVAL; } - return uwrite(result, 0x80020000 + static_cast(ErrorCode::AGAIN)); + + IpmiTryGetResultParams _params; + ORBIS_RET_ON_ERROR(uread(_params, (ptr)params)); + + auto client = thread->tproc->ipmiMap.get(kid).cast(); + + if (client == nullptr) { + return ErrorCode::INVAL; + } + + ORBIS_LOG_TODO(__FUNCTION__, thread->tid, client->name, _params.method, + _params.unk, _params.pResult, _params.numOutData, + _params.padding, _params.pOutData, _params.padding2); + thread->where(); + ORBIS_RET_ON_ERROR(uwrite(_params.pResult, 0)); + return uwrite(result, 0u); +} +orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread, + ptr result, uint kid, + ptr params, + uint64_t paramsSz) { + struct SceIpmiClientGetArgs { + uint32_t unk; // 0 + uint32_t padding; + ptr message; + ptr pSize; + uint64_t maxSize; + ptr pTimeout; + }; + + static_assert(sizeof(SceIpmiClientGetArgs) == 0x28); + + if (paramsSz != sizeof(SceIpmiClientGetArgs)) { + return ErrorCode::INVAL; + } + + auto client = thread->tproc->ipmiMap.get(kid).cast(); + + if (client == nullptr) { + return ErrorCode::INVAL; + } + + SceIpmiClientGetArgs _params; + ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); + + ORBIS_LOG_ERROR(__FUNCTION__, client->name, client->messages.size(), + _params.unk, _params.padding, _params.message, _params.pSize, + _params.maxSize, _params.pTimeout); + + std::lock_guard lock(client->mutex); + + using clock = std::chrono::high_resolution_clock; + + clock::time_point timeoutPoint = clock::time_point::max(); + if (_params.pTimeout != nullptr) { + std::uint32_t timeout{}; + ORBIS_LOG_ERROR(__FUNCTION__, timeout); + ORBIS_RET_ON_ERROR(uread(timeout, _params.pTimeout)); + timeoutPoint = clock::now() + std::chrono::microseconds(timeout); + } + + if (client->messages.empty()) { + if (timeoutPoint != clock::time_point::max()) { + while (true) { + auto now = clock::now(); + if (now >= timeoutPoint) { + ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, 0u)); + return uwrite( + result, 0x80020000 + static_cast(ErrorCode::TIMEDOUT)); + } + + auto waitTime = std::chrono::duration_cast( + timeoutPoint - now); + client->messageCv.wait(client->mutex, waitTime.count()); + + if (!client->messages.empty()) { + now = clock::now(); + + if (now >= timeoutPoint) { + ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, 0u)); + } else { + std::uint32_t restTime = + std::chrono::duration_cast( + timeoutPoint - now) + .count(); + ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, restTime)); + } + + break; + } + } + } else { + while (client->messages.empty()) { + client->messageCv.wait(client->mutex); + } + } + } + + auto &message = client->messages.front(); + + if (_params.maxSize < message.size()) { + ORBIS_LOG_ERROR(__FUNCTION__, "too small buffer"); + return uwrite(result, + 0x80020000 + static_cast(ErrorCode::INVAL)); + } + + ORBIS_RET_ON_ERROR(uwrite(_params.pSize, message.size())); + ORBIS_RET_ON_ERROR( + uwriteRaw(_params.message, message.data(), message.size())); + client->messages.pop_front(); + return uwrite(result, 0); } orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread, @@ -543,16 +709,18 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr result, uint kid, auto session = client->session; if (session == nullptr) { - ORBIS_LOG_TODO(__FUNCTION__, "waiting for connection", client->name, - _params.method); + // ORBIS_LOG_TODO(__FUNCTION__, "waiting for connection", client->name, + // _params.method); - while (session == nullptr) { - client->sessionCv.wait(client->mutex); - session = client->session; - } + // while (session == nullptr) { + // client->sessionCv.wait(client->mutex); + // session = client->session; + // } + return ErrorCode::INVAL; } ORBIS_LOG_ERROR(__FUNCTION__, client->name, "sync call", _params.method); + // thread->where(); std::lock_guard sessionLock(session->mutex); auto server = session->server; @@ -822,14 +990,70 @@ orbis::SysResult orbis::sysIpmiServerGetName(Thread *thread, ptr result, return uwrite(result, 0); } +orbis::SysResult orbis::sysIpmiClientWaitEventFlag(Thread *thread, + ptr result, uint kid, + ptr params, + uint64_t paramsSz) { + struct IpmiWaitEventFlagParam { + uint32_t index; + uint32_t padding0; + uint64_t patternSet; + uint32_t mode; + uint32_t padding1; + ptr pPatternSet; + ptr pTimeout; + }; + + static_assert(sizeof(IpmiWaitEventFlagParam) == 0x28); + + IpmiWaitEventFlagParam _params; + ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); + + auto client = thread->tproc->ipmiMap.get(kid).cast(); + + if (client == nullptr) { + return ErrorCode::INVAL; + } + + ORBIS_LOG_TODO(__FUNCTION__, thread->tid, kid, client->name, _params.index, + _params.padding0, _params.patternSet, _params.mode, + _params.padding1, _params.pPatternSet, _params.pTimeout); + + if (client->eventFlags.size() <= _params.index) { + return ErrorCode::INVAL; + } + + std::uint32_t resultTimeout{}; + + if (_params.pTimeout != nullptr) { + ORBIS_RET_ON_ERROR(uread(resultTimeout, _params.pTimeout)); + } + + auto &evf = client->eventFlags[_params.index]; + auto waitResult = + evf.wait(thread, _params.mode, _params.patternSet, &resultTimeout); + + // FIXME + // if (_params.pPatternSet != nullptr) { + // ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, thread->evfResultPattern)); + // } + ORBIS_RET_ON_ERROR(uwrite(result, 0u)); + if (_params.pTimeout != nullptr) { + ORBIS_RET_ON_ERROR(uwrite(_params.pTimeout, resultTimeout)); + } + return waitResult; +} + orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz) { struct IpmiPollEventFlagParam { - uint64_t index; + uint32_t index; + uint32_t padding0; uint64_t patternSet; - uint64_t mode; + uint32_t mode; + uint32_t padding1; ptr pPatternSet; }; @@ -848,21 +1072,23 @@ orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread, return ErrorCode::INVAL; } - // ORBIS_LOG_TODO(__FUNCTION__, client->name, _params.index, - // _params.patternSet, - // _params.mode, _params.pPatternSet); - ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, 0u)); - // client->evf.set(_params.a); - return SysResult::notAnError(ErrorCode::BUSY); -} + // ORBIS_LOG_TODO(__FUNCTION__, thread->tid, kid, client->name, _params.index, + // _params.padding0, _params.patternSet, _params.mode, + // _params.padding1, _params.pPatternSet); -orbis::SysResult orbis::sysIpmiSessionWaitEventFlag(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - ORBIS_LOG_TODO(__FUNCTION__, paramsSz); - thread->where(); - return uwrite(result, 0); + if (client->eventFlags.size() <= _params.index) { + return ErrorCode::INVAL; + } + + uint64_t patternSet; + ORBIS_RET_ON_ERROR(uread(patternSet, _params.pPatternSet)); + auto &evf = client->eventFlags[_params.index]; + auto waitResult = evf.tryWait(thread, _params.mode, patternSet); + + ORBIS_RET_ON_ERROR(uread(patternSet, _params.pPatternSet)); + ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, thread->evfResultPattern)); + ORBIS_RET_ON_ERROR(uwrite(result, 0u)); + return SysResult::notAnError(waitResult); } orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread, @@ -870,8 +1096,9 @@ orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread, ptr params, uint64_t paramsSz) { struct IpmiSetEventFlagParam { + uint32_t index; + uint32_t padding; uint64_t patternSet; - uint64_t index; }; static_assert(sizeof(IpmiSetEventFlagParam) == 0x10); @@ -891,6 +1118,16 @@ orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread, ORBIS_LOG_TODO(__FUNCTION__, session->client->name, _params.patternSet, _params.index); - session->evf.set(_params.patternSet); + auto client = session->client; + if (client == nullptr) { + return ErrorCode::INVAL; + } + + if (client->eventFlags.size() <= _params.index) { + return ErrorCode::INVAL; + } + + auto &evf = client->eventFlags[_params.index]; + evf.set(_params.patternSet); return uwrite(result, 0); } diff --git a/orbis-kernel/src/pipe.cpp b/orbis-kernel/src/pipe.cpp index fc2c7f155..ca207720a 100644 --- a/orbis-kernel/src/pipe.cpp +++ b/orbis-kernel/src/pipe.cpp @@ -53,7 +53,7 @@ static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio, static orbis::ErrorCode pipe_write(orbis::File *file, orbis::Uio *uio, orbis::Thread *thread) { - auto pipe = static_cast(file); + auto pipe = static_cast(file)->other; ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file); std::size_t cnt = 0; @@ -79,8 +79,12 @@ static orbis::FileOps pipe_ops = { .write = pipe_write, }; -orbis::Ref orbis::createPipe() { - auto result = knew(); - result->ops = &pipe_ops; - return result; +std::pair, orbis::Ref> orbis::createPipe() { + auto a = knew(); + auto b = knew(); + a->ops = &pipe_ops; + b->ops = &pipe_ops; + a->other = b; + b->other = a; + return {a, b}; } diff --git a/orbis-kernel/src/sys/sys_descrip.cpp b/orbis-kernel/src/sys/sys_descrip.cpp index 6156ba7de..d4288620b 100644 --- a/orbis-kernel/src/sys/sys_descrip.cpp +++ b/orbis-kernel/src/sys/sys_descrip.cpp @@ -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) { diff --git a/orbis-kernel/src/sys/sys_exit.cpp b/orbis-kernel/src/sys/sys_exit.cpp index 7ee4fc068..2eb984fed 100644 --- a/orbis-kernel/src/sys/sys_exit.cpp +++ b/orbis-kernel/src/sys/sys_exit.cpp @@ -2,10 +2,10 @@ #include "sys/sysproto.hpp" #include "utils/Logs.hpp" #include +#include #include #include #include -#include 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 status, } ::rusage hostUsage; - int stat; - int result = ::wait4(hostPid, &stat, options, &hostUsage); - if (result < 0) { - return static_cast(errno); + while (true) { + int stat; + int result = ::wait4(hostPid, &stat, options, &hostUsage); + if (result < 0) { + return static_cast(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 {}; } diff --git a/orbis-kernel/src/sys/sys_p1003_1b.cpp b/orbis-kernel/src/sys/sys_p1003_1b.cpp index e54ef6522..ca4a9bd2a 100644 --- a/orbis-kernel/src/sys/sys_p1003_1b.cpp +++ b/orbis-kernel/src/sys/sys_p1003_1b.cpp @@ -1,4 +1,5 @@ #include "sys/sysproto.hpp" +#include "utils/Logs.hpp" #include 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 interval) { diff --git a/orbis-kernel/src/sys/sys_pipe.cpp b/orbis-kernel/src/sys/sys_pipe.cpp index dd20008df..f14c62035 100644 --- a/orbis-kernel/src/sys/sys_pipe.cpp +++ b/orbis-kernel/src/sys/sys_pipe.cpp @@ -3,9 +3,9 @@ #include 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; diff --git a/orbis-kernel/src/sys/sys_resource.cpp b/orbis-kernel/src/sys/sys_resource.cpp index 52725f402..8b868f668 100644 --- a/orbis-kernel/src/sys/sys_resource.cpp +++ b/orbis-kernel/src/sys/sys_resource.cpp @@ -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 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, diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index bbb66f3b4..0a0f0e473 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -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()) { + ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, client->name, result, + params, paramsSz); + thread->where(); + return uwrite(result, 0u); + } + if (auto server = ipmi.cast()) { + ORBIS_LOG_TODO(__FUNCTION__, thread->tid, op, server->name, result, + params, paramsSz); + thread->where(); + return uwrite(result, 0u); + } + if (auto session = ipmi.cast(); 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 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 context) { + ORBIS_LOG_FATAL(__FUNCTION__, tid, context); return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_set_timezone_info(Thread *thread /* TODO */) { diff --git a/orbis-kernel/src/sys/sys_synch.cpp b/orbis-kernel/src/sys/sys_synch.cpp index 6d46ef023..5485d48b5 100644 --- a/orbis-kernel/src/sys/sys_synch.cpp +++ b/orbis-kernel/src/sys/sys_synch.cpp @@ -1,3 +1,7 @@ #include "sys/sysproto.hpp" +#include -orbis::SysResult orbis::sys_yield(Thread *thread) { return ErrorCode::NOSYS; } +orbis::SysResult orbis::sys_yield(Thread *thread) { + std::this_thread::yield(); + return {}; +} diff --git a/orbis-kernel/src/sys/sys_sysctl.cpp b/orbis-kernel/src/sys/sys_sysctl.cpp index a2b5d035d..60ccd2b96 100644 --- a/orbis-kernel/src/sys/sys_sysctl.cpp +++ b/orbis-kernel/src/sys/sys_sysctl.cpp @@ -10,8 +10,8 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr 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 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 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 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 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 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 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 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]; diff --git a/orbis-kernel/src/sys/sys_umtx.cpp b/orbis-kernel/src/sys/sys_umtx.cpp index 4b8a97d4c..df785d854 100644 --- a/orbis-kernel/src/sys/sys_umtx.cpp +++ b/orbis-kernel/src/sys/sys_umtx.cpp @@ -157,7 +157,7 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr obj, sint op, }); } case 18: - return umtx_wake_umutex(thread, (ptr)obj); + return umtx_wake_umutex(thread, (ptr)obj, 0); case 19: return with_timeout( [&](std::uint64_t ut) { @@ -171,8 +171,9 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr 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)obj); + ORBIS_LOG_ERROR("sys__umtx_op: unknown wake operation", op, val, uaddr1, uaddr2); + // thread->where(); + return umtx_wake_umutex(thread, (orbis::ptr)obj, val); } return ErrorCode::INVAL; diff --git a/orbis-kernel/src/umtx.cpp b/orbis-kernel/src/umtx.cpp index cb2beaf15..6bb52a03d 100644 --- a/orbis-kernel/src/umtx.cpp +++ b/orbis-kernel/src/umtx.cpp @@ -187,12 +187,12 @@ static ErrorCode do_lock_normal(Thread *thread, ptr m, uint flags, } static ErrorCode do_lock_pi(Thread *thread, ptr m, uint flags, std::uint64_t ut, umutex_lock_mode mode) { - ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode); + // ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode); return do_lock_normal(thread, m, flags, ut, mode); } static ErrorCode do_lock_pp(Thread *thread, ptr m, uint flags, std::uint64_t ut, umutex_lock_mode mode) { - ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode); + // ORBIS_LOG_TODO(__FUNCTION__, m, flags, ut, mode); return do_lock_normal(thread, m, flags, ut, mode); } static ErrorCode do_unlock_normal(Thread *thread, ptr m, uint flags) { @@ -576,17 +576,18 @@ orbis::ErrorCode orbis::umtx_rw_unlock(Thread *thread, ptr rwlock) { auto state = rwlock->state.load(std::memory_order::relaxed); if (state & kUrwLockWriteOwner) { - while (true) { - if (rwlock->state.compare_exchange_weak(state, state & ~kUrwLockWriteOwner)) { + while (true) { + if (rwlock->state.compare_exchange_weak(state, + state & ~kUrwLockWriteOwner)) { break; } if (!(state & kUrwLockWriteOwner)) { return ErrorCode::PERM; } - } - } else if ((state & kUrwLockMaxReaders) != 0) { - while (true) { + } + } else if ((state & kUrwLockMaxReaders) != 0) { + while (true) { if (rwlock->state.compare_exchange_weak(state, state - 1)) { break; } @@ -594,26 +595,26 @@ orbis::ErrorCode orbis::umtx_rw_unlock(Thread *thread, ptr rwlock) { if ((state & kUrwLockMaxReaders) == 0) { return ErrorCode::PERM; } - } - } else { - return ErrorCode::PERM; - } + } + } else { + return ErrorCode::PERM; + } unsigned count = 0; if (!(flags & kUrwLockPreferReader)) { - if (state & kUrwLockWriteWaiters) { - count = 1; - } else if (state & kUrwLockReadWaiters) { - count = UINT_MAX; - } - } else { - if (state & kUrwLockReadWaiters) { - count = UINT_MAX; - } else if (state & kUrwLockWriteWaiters) { - count = 1; - } - } + if (state & kUrwLockWriteWaiters) { + count = 1; + } else if (state & kUrwLockReadWaiters) { + count = UINT_MAX; + } + } else { + if (state & kUrwLockReadWaiters) { + count = UINT_MAX; + } else if (state & kUrwLockWriteWaiters) { + count = 1; + } + } if (count == 1) { chain.notify_one(key); @@ -655,7 +656,8 @@ orbis::ErrorCode orbis::umtx_wait_umutex(Thread *thread, ptr m, return ErrorCode::INVAL; } -orbis::ErrorCode orbis::umtx_wake_umutex(Thread *thread, ptr m) { +orbis::ErrorCode orbis::umtx_wake_umutex(Thread *thread, ptr m, + sint wakeFlags) { ORBIS_LOG_TRACE(__FUNCTION__, m); int owner = m->owner.load(std::memory_order::acquire); if ((owner & ~kUmutexContested) != 0) @@ -671,8 +673,13 @@ orbis::ErrorCode orbis::umtx_wake_umutex(Thread *thread, ptr m) { owner = kUmutexContested; m->owner.compare_exchange_strong(owner, kUmutexUnowned); } - if (count != 0 && (owner & ~kUmutexContested) == 0) - chain.notify_one(key); + if (count != 0 && (owner & ~kUmutexContested) == 0) { + if ((wakeFlags & 0x400) || (flags & 1)) { + chain.notify_all(key); + } else { + chain.notify_one(key); + } + } return {}; } diff --git a/rpcsx-os/iodev/ajm.cpp b/rpcsx-os/iodev/ajm.cpp index fb6f4b926..3d4066b01 100644 --- a/rpcsx-os/iodev/ajm.cpp +++ b/rpcsx-os/iodev/ajm.cpp @@ -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 AjmFile : orbis::File {}; @@ -8,7 +9,17 @@ struct AjmFile : orbis::File {}; static orbis::ErrorCode ajm_ioctl(orbis::File *file, std::uint64_t request, void *argp, orbis::Thread *thread) { + // 0xc0288903 - module register + // 0xc0288904 - module unregister + if (request == 0xc0288903 || request == 0xc0288904) { + auto arg = reinterpret_cast(argp)[2]; + ORBIS_LOG_ERROR(__FUNCTION__, request, arg); + *reinterpret_cast(argp) = 0; + // return{}; + } + ORBIS_LOG_FATAL("Unhandled AJM ioctl", request); + thread->where(); return {}; } diff --git a/rpcsx-os/iodev/av_control.cpp b/rpcsx-os/iodev/av_control.cpp index 328317a21..938cee317 100644 --- a/rpcsx-os/iodev/av_control.cpp +++ b/rpcsx-os/iodev/av_control.cpp @@ -1,6 +1,9 @@ #include "io-device.hpp" +#include "orbis-config.hpp" #include "orbis/KernelAllocator.hpp" +#include "orbis/error/ErrorCode.hpp" #include "orbis/file.hpp" +#include "orbis/thread/Thread.hpp" #include "orbis/utils/Logs.hpp" struct AVControlFile : orbis::File {}; @@ -8,7 +11,21 @@ struct AVControlFile : orbis::File {}; static orbis::ErrorCode av_control_ioctl(orbis::File *file, std::uint64_t request, void *argp, orbis::Thread *thread) { + if (request == 0xc0109a0e) { + struct Args { + orbis::sint unk; + orbis::sint padding; + orbis::ptr pResult; + }; + + Args _args; + ORBIS_RET_ON_ERROR(orbis::uread(_args, orbis::ptr(argp))); + + return orbis::uwrite(_args.pResult, 1); + } + ORBIS_LOG_FATAL("Unhandled av_control ioctl", request); + thread->where(); return {}; } diff --git a/rpcsx-os/iodev/hdmi.cpp b/rpcsx-os/iodev/hdmi.cpp index b892a75ea..57ec0b0c6 100644 --- a/rpcsx-os/iodev/hdmi.cpp +++ b/rpcsx-os/iodev/hdmi.cpp @@ -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 HDMIFile : orbis::File {}; @@ -9,6 +10,7 @@ static orbis::ErrorCode hdmi_ioctl(orbis::File *file, std::uint64_t request, void *argp, orbis::Thread *thread) { ORBIS_LOG_FATAL("Unhandled hdmi ioctl", request); + thread->where(); return {}; } diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index da88a12f9..85f003539 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -120,6 +120,10 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) { rx::vm::mapProtToString(origVmProt).c_str()); } + if (orbis::g_currentThread != nullptr) { + orbis::g_currentThread->tproc->event.emit(orbis::kEvFiltProc, orbis::kNoteExit, sig); + } + if (g_gpuPid > 0) { // stop gpu thread // ::kill(g_gpuPid, SIGINT); @@ -673,9 +677,12 @@ static void runRpsxGpu() { static orbis::Semaphore *createSemaphore(std::string_view name, uint32_t attrs, uint64_t initCount, uint64_t maxCount) { - return orbis::g_context + auto result = orbis::g_context .createSemaphore(orbis::kstring(name), attrs, initCount, maxCount) .first; + std::memcpy(result->name, name.data(), name.size()); + result->name[name.size()] = 0; + return result; } static orbis::EventFlag *createEventFlag(std::string_view name, uint32_t attrs, @@ -1653,7 +1660,10 @@ int main(int argc, const char *argv[]) { createGnmCompositorObjects(initProcess); createShellCoreObjects(initProcess); - createIpmiServer(initProcess, "SceCdlgRichProf"); // ? + // ? + createIpmiServer(initProcess, "SceCdlgRichProf"); + createIpmiServer(initProcess, "SceRemoteplayIpc"); + createIpmiServer(initProcess, "SceGlsIpc"); initProcess->cwd = "/app0/"; launchDaemon(mainThread, "/system/sys/orbis_audiod.elf", diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index 4762b7fc9..2ac410f83 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -369,6 +369,7 @@ orbis::SysResult socketPair(orbis::Thread *thread, orbis::sint domain, *a = wrapSocket(fds[0], "", domain, type, protocol); *b = wrapSocket(fds[1], "", domain, type, protocol); + return {}; } auto result = wrapSocket(-1, "", domain, type, protocol); @@ -551,8 +552,13 @@ SysResult thr_new(orbis::Thread *thread, orbis::ptr param, // FIXME: implement scheduler ORBIS_LOG_NOTICE("Starting child thread", childThread->tid, - childThread->stackStart); - + childThread->stackStart, _param.rtp, _param.name, + _param.spare[0], _param.spare[1]); + if (_param.rtp != 0) { + rtprio _rtp; + ORBIS_RET_ON_ERROR(uread(_rtp, _param.rtp)); + ORBIS_LOG_NOTICE(" rtp: ", _rtp.type, _rtp.prio); + } auto stdthr = std::thread{[=, childThread = Ref(childThread)] { static_cast( uwrite(_param.child_tid, slong(childThread->tid))); // TODO: verify @@ -712,9 +718,9 @@ SysResult processNeeded(Thread *thread) { } SysResult fork(Thread *thread, slong flags) { - ORBIS_LOG_TODO(__FUNCTION__, flags); - auto childPid = g_context.allocatePid() * 10000 + 1; + ORBIS_LOG_TODO(__FUNCTION__, flags, childPid, thread->tid); + thread->where(); auto flag = knew>(); *flag = false; @@ -790,6 +796,7 @@ SysResult fork(Thread *thread, slong flags) { SysResult execve(Thread *thread, ptr fname, ptr> argv, ptr> envv) { ORBIS_LOG_ERROR(__FUNCTION__, fname); + thread->where(); std::vector _argv; std::vector _envv;