diff --git a/kernel/orbis/include/orbis/Budget.hpp b/kernel/orbis/include/orbis/Budget.hpp index 9451b85f9..0bc352f06 100644 --- a/kernel/orbis/include/orbis/Budget.hpp +++ b/kernel/orbis/include/orbis/Budget.hpp @@ -1,9 +1,9 @@ #pragma once #include "orbis-config.hpp" -#include "rx/SharedMutex.hpp" #include "rx/BitSet.hpp" #include "rx/Rc.hpp" +#include "rx/SharedMutex.hpp" #include #include #include diff --git a/kernel/orbis/include/orbis/KernelAllocator.hpp b/kernel/orbis/include/orbis/KernelAllocator.hpp index c298b89e5..b8b8012f7 100644 --- a/kernel/orbis/include/orbis/KernelAllocator.hpp +++ b/kernel/orbis/include/orbis/KernelAllocator.hpp @@ -68,7 +68,8 @@ T *knew(Args &&...args) { utils::kalloc(sizeof(DynamicObject), alignof(DynamicObject))); return std::construct_at(loc, std::forward(args)...); } else { - static_assert(!std::is_polymorphic_v, "Polymorphic type should be derived from rx::RcBase"); + static_assert(!std::is_polymorphic_v, + "Polymorphic type should be derived from rx::RcBase"); auto loc = static_cast(utils::kalloc(sizeof(T), alignof(T))); return std::construct_at(loc, std::forward(args)...); diff --git a/kernel/orbis/include/orbis/KernelContext.hpp b/kernel/orbis/include/orbis/KernelContext.hpp index c2317dac4..a18ff027a 100644 --- a/kernel/orbis/include/orbis/KernelContext.hpp +++ b/kernel/orbis/include/orbis/KernelContext.hpp @@ -6,11 +6,11 @@ #include "ipmi.hpp" #include "orbis/note.hpp" #include "osem.hpp" +#include "rx/IdMap.hpp" +#include "rx/LinkedNode.hpp" #include "rx/SharedCV.hpp" #include "rx/SharedMutex.hpp" #include "thread/types.hpp" -#include "rx/IdMap.hpp" -#include "rx/LinkedNode.hpp" #include #include @@ -130,7 +130,8 @@ public: return {}; } - std::pair, ErrorCode> createIpmiServer(utils::kstring name) { + std::pair, ErrorCode> + createIpmiServer(utils::kstring name) { std::lock_guard lock(m_sem_mtx); auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr); @@ -214,8 +215,8 @@ public: bool isDevKit = false; rx::Ref createProcessTypeBudget(Budget::ProcessType processType, - std::string_view name, - std::span items) { + std::string_view name, + std::span items) { auto budget = orbis::knew(name, processType, items); processTypeBudgets[static_cast(processType)] = orbis::knew(name, processType, items); diff --git a/kernel/orbis/include/orbis/file.hpp b/kernel/orbis/include/orbis/file.hpp index 515769cdf..2b89c03fb 100644 --- a/kernel/orbis/include/orbis/file.hpp +++ b/kernel/orbis/include/orbis/file.hpp @@ -3,9 +3,9 @@ #include "KernelAllocator.hpp" #include "error/ErrorCode.hpp" #include "note.hpp" +#include "rx/Rc.hpp" #include "rx/SharedMutex.hpp" #include "stat.hpp" -#include "rx/Rc.hpp" #include namespace orbis { diff --git a/kernel/orbis/include/orbis/ipmi.hpp b/kernel/orbis/include/orbis/ipmi.hpp index b7de7a149..73f393afe 100644 --- a/kernel/orbis/include/orbis/ipmi.hpp +++ b/kernel/orbis/include/orbis/ipmi.hpp @@ -3,9 +3,9 @@ #include "KernelAllocator.hpp" #include "evf.hpp" #include "orbis-config.hpp" +#include "rx/Rc.hpp" #include "rx/SharedCV.hpp" #include "rx/SharedMutex.hpp" -#include "rx/Rc.hpp" #include #include diff --git a/kernel/orbis/include/orbis/pipe.hpp b/kernel/orbis/include/orbis/pipe.hpp index 985141cdb..ff7bd8239 100644 --- a/kernel/orbis/include/orbis/pipe.hpp +++ b/kernel/orbis/include/orbis/pipe.hpp @@ -2,9 +2,9 @@ #include "KernelAllocator.hpp" #include "file.hpp" +#include "rx/Rc.hpp" #include "rx/SharedCV.hpp" #include "rx/SharedMutex.hpp" -#include "rx/Rc.hpp" #include namespace orbis { diff --git a/kernel/orbis/src/pipe.cpp b/kernel/orbis/src/pipe.cpp index 36aa60587..6513b39a3 100644 --- a/kernel/orbis/src/pipe.cpp +++ b/kernel/orbis/src/pipe.cpp @@ -81,8 +81,7 @@ static orbis::FileOps pipe_ops = { .write = pipe_write, }; -std::pair, rx::Ref> -orbis::createPipe() { +std::pair, rx::Ref> orbis::createPipe() { auto a = knew(); auto b = knew(); a->event = knew(); diff --git a/orbis-kernel/include/orbis/KernelContext.hpp b/orbis-kernel/include/orbis/KernelContext.hpp deleted file mode 100644 index 3855ebb34..000000000 --- a/orbis-kernel/include/orbis/KernelContext.hpp +++ /dev/null @@ -1,260 +0,0 @@ -#pragma once -#include "AppInfo.hpp" -#include "Budget.hpp" -#include "KernelAllocator.hpp" -#include "evf.hpp" -#include "ipmi.hpp" -#include "orbis/note.hpp" -#include "osem.hpp" -#include "thread/types.hpp" -#include "utils/IdMap.hpp" -#include "utils/LinkedNode.hpp" -#include "utils/SharedCV.hpp" -#include "utils/SharedMutex.hpp" - -#include -#include -#include -#include -#include - -namespace orbis { -struct Process; -struct Thread; - -struct UmtxKey { - // TODO: may contain a reference to a shared memory - std::uintptr_t addr; - orbis::pid_t pid; - - auto operator<=>(const UmtxKey &) const = default; -}; - -struct UmtxCond { - Thread *thr; - rx::shared_cv cv; - - UmtxCond(Thread *thr) : thr(thr) {} -}; - -struct UmtxChain { - rx::shared_mutex mtx; - using queue_type = utils::kmultimap; - queue_type sleep_queue; - queue_type spare_queue; - - std::pair *enqueue(UmtxKey &key, Thread *thr); - void erase(std::pair *obj); - queue_type::iterator erase(queue_type::iterator it); - uint notify_one(const UmtxKey &key); - uint notify_all(const UmtxKey &key); - uint notify_n(const UmtxKey &key, sint count); -}; - -enum class FwType : std::uint8_t { - Unknown, - Ps4, - Ps5, -}; - -struct RcAppInfo : rx::RcBase, AppInfoEx { - orbis::uint32_t appState = 0; -}; - -class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { -public: - KernelContext(); - ~KernelContext(); - - Process *createProcess(pid_t pid); - void deleteProcess(Process *proc); - Process *findProcessById(pid_t pid) const; - Process *findProcessByHostId(std::uint64_t pid) const; - - rx::LinkedNode *getProcessList() { return m_processes; } - - long allocatePid() { - std::lock_guard lock(m_thread_id_mtx); - return m_thread_id_map.emplace(0).first; - } - - long getTscFreq(); - - void *kalloc(std::size_t size, - std::size_t align = __STDCPP_DEFAULT_NEW_ALIGNMENT__); - void kfree(void *ptr, std::size_t size); - - std::pair createEventFlag(utils::kstring name, - std::int32_t flags, - std::uint64_t initPattern) { - std::lock_guard lock(m_evf_mtx); - - auto [it, inserted] = m_event_flags.try_emplace(std::move(name), nullptr); - if (inserted) { - it->second = knew(flags, initPattern); - std::strncpy(it->second->name, it->first.c_str(), 32); - } - - return {it->second.get(), inserted}; - } - - rx::Ref findEventFlag(std::string_view name) { - std::lock_guard lock(m_evf_mtx); - - if (auto it = m_event_flags.find(name); it != m_event_flags.end()) { - return it->second; - } - - return {}; - } - - std::pair createSemaphore(utils::kstring name, - std::uint32_t attrs, - std::int32_t initCount, - std::int32_t maxCount) { - std::lock_guard lock(m_sem_mtx); - auto [it, inserted] = m_semaphores.try_emplace(std::move(name), nullptr); - if (inserted) { - it->second = knew(attrs, initCount, maxCount); - } - - return {it->second.get(), inserted}; - } - - rx::Ref findSemaphore(std::string_view name) { - std::lock_guard lock(m_sem_mtx); - if (auto it = m_semaphores.find(name); it != m_semaphores.end()) { - return it->second; - } - - return {}; - } - - std::pair, ErrorCode> createIpmiServer(utils::kstring name) { - std::lock_guard lock(m_sem_mtx); - auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr); - - if (!inserted) { - return {it->second, ErrorCode::EXIST}; - } - - it->second = knew(it->first); - - if (it->second == nullptr) { - mIpmiServers.erase(it); - return {nullptr, ErrorCode::NOMEM}; - } - - return {it->second, {}}; - } - - rx::Ref findIpmiServer(std::string_view name) { - std::lock_guard lock(m_sem_mtx); - if (auto it = mIpmiServers.find(name); it != mIpmiServers.end()) { - return it->second; - } - - return {}; - } - - std::tuple &, - std::unique_lock> - getKernelEnv() { - std::unique_lock lock(m_kenv_mtx); - return {m_kenv, std::move(lock)}; - } - - void setKernelEnv(std::string_view key, std::string_view value) { - auto &kenvValue = m_kenv[utils::kstring(key)]; - auto len = std::min(sizeof(kenvValue) - 1, value.size()); - std::memcpy(kenvValue, value.data(), len); - kenvValue[len] = '0'; - } - - enum { - c_golden_ratio_prime = 2654404609u, - c_umtx_chains = 512, - c_umtx_shifts = 23, - }; - - // Use getUmtxChain0 or getUmtxChain1 - std::tuple> - getUmtxChainIndexed(int i, Thread *t, uint32_t flags, void *ptr); - - // Internal Umtx: Wait/Cv/Sem - auto getUmtxChain0(Thread *t, uint32_t flags, void *ptr) { - return getUmtxChainIndexed(0, t, flags, ptr); - } - - // Internal Umtx: Mutex/Umtx/Rwlock - auto getUmtxChain1(Thread *t, uint32_t flags, void *ptr) { - return getUmtxChainIndexed(1, t, flags, ptr); - } - - rx::Ref deviceEventEmitter; - rx::Ref shmDevice; - rx::Ref dmemDevice; - rx::Ref blockpoolDevice; - rx::Ref gpuDevice; - rx::Ref dceDevice; - rx::shared_mutex gpuDeviceMtx; - uint sdkVersion{}; - uint fwSdkVersion{}; - uint safeMode{}; - utils::RcIdMap ipmiMap; - RcIdMap appInfos; - RcIdMap budgets; - rx::Ref processTypeBudgets[4]; - - rx::shared_mutex regMgrMtx; - kmap regMgrInt; - std::vector> dialogs{}; - - FwType fwType = FwType::Unknown; - bool isDevKit = false; - - rx::Ref createProcessTypeBudget(Budget::ProcessType processType, - std::string_view name, - std::span items) { - auto budget = orbis::knew(name, processType, items); - processTypeBudgets[static_cast(processType)] = - orbis::knew(name, processType, items); - return budget; - } - - rx::Ref getProcessTypeBudget(Budget::ProcessType processType) { - return processTypeBudgets[static_cast(processType)]; - } - -private: - rx::shared_mutex m_heap_mtx; - rx::shared_mutex m_heap_map_mtx; - void *m_heap_next = this + 1; - - utils::kmultimap m_free_heap; - utils::kmultimap m_used_node; - - UmtxChain m_umtx_chains[2][c_umtx_chains]{}; - - std::atomic m_tsc_freq{0}; - - rx::shared_mutex m_thread_id_mtx; - OwningIdMap m_thread_id_map; - mutable rx::shared_mutex m_proc_mtx; - utils::LinkedNode *m_processes = nullptr; - - rx::shared_mutex m_evf_mtx; - utils::kmap> m_event_flags; - - rx::shared_mutex m_sem_mtx; - utils::kmap> m_semaphores; - - rx::shared_mutex mIpmiServerMtx; - utils::kmap> mIpmiServers; - - rx::shared_mutex m_kenv_mtx; - utils::kmap m_kenv; // max size: 127 + '\0' -}; - -extern KernelContext &g_context; -} // namespace orbis diff --git a/orbis-kernel/src/ipmi.cpp b/orbis-kernel/src/ipmi.cpp deleted file mode 100644 index fe56efe54..000000000 --- a/orbis-kernel/src/ipmi.cpp +++ /dev/null @@ -1,1405 +0,0 @@ -#include "ipmi.hpp" -#include "KernelContext.hpp" -#include "thread/Process.hpp" -#include "thread/Thread.hpp" -#include "utils/Logs.hpp" -#include -#include -#include - -orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl, - const char *name, - const IpmiCreateClientConfig &config, - rx::Ref &result) { - auto client = knew(name); - if (client == nullptr) { - return ErrorCode::NOMEM; - } - - client->clientImpl = clientImpl; - client->name = name; - client->process = proc; - client->userData = config.userData; - client->eventFlags.resize(32); - client->messageQueues.resize(32); - result = client; - return {}; -} - -orbis::ErrorCode orbis::ipmiCreateServer(Process *proc, void *serverImpl, - const char *name, - const IpmiCreateServerConfig &config, - rx::Ref &result) { - auto [server, errorCode] = g_context.createIpmiServer(name); - ORBIS_RET_ON_ERROR(errorCode); - - server->serverImpl = serverImpl; - server->userData = config.userData; - server->eventHandler = config.eventHandler; - server->pid = proc->pid; - result = server; - return {}; -} - -orbis::ErrorCode orbis::ipmiCreateSession(Thread *thread, void *sessionImpl, - ptr userData, - rx::Ref &result) { - std::unique_lock ipmiMapLock(g_context.ipmiMap.mutex); - - for (auto [kid, obj] : g_context.ipmiMap) { - auto server = dynamic_cast(obj); - if (server == nullptr) { - continue; - } - - std::lock_guard serverLock(server->mutex); - for (auto &conReq : server->connectionRequests) { - if (conReq.serverTid != thread->tid || - conReq.client->session != nullptr || - conReq.client->name != server->name) { - continue; - } - - std::lock_guard clientLock(conReq.client->mutex); - if (conReq.client->session != nullptr) { - continue; - } - - auto session = knew(); - if (session == nullptr) { - return ErrorCode::NOMEM; - } - - result = session; - session->sessionImpl = sessionImpl; - session->userData = userData; - session->client = conReq.client; - session->server = server; - conReq.client->session = session; - conReq.client->sessionCv.notify_one(conReq.client->mutex); - - return {}; - } - } - - ORBIS_LOG_ERROR(__FUNCTION__, ": connection request not found"); - return ErrorCode::INVAL; -} - -orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr result, - ptr params, - uint64_t paramsSz) { - if (paramsSz != sizeof(IpmiCreateClientParams)) { - return ErrorCode::INVAL; - } - - IpmiCreateClientParams _params; - IpmiCreateClientConfig _config; - char _name[25]; - rx::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, - _config, client)); - - auto kid = g_context.ipmiMap.insert(std::move(client)); - - if (kid == -1) { - return ErrorCode::MFILE; - } - - ORBIS_LOG_ERROR(__FUNCTION__, kid, _name); - return uwrite(result, kid); -} - -orbis::SysResult orbis::sysIpmiCreateServer(Thread *thread, ptr result, - ptr params, - uint64_t paramsSz) { - struct IpmiCreateServerParams { - ptr serverImpl; - ptr name; - ptr config; - }; - - static_assert(sizeof(IpmiCreateServerParams) == 0x18); - - if (paramsSz != sizeof(IpmiCreateServerParams)) { - return ErrorCode::INVAL; - } - - IpmiCreateServerParams _params; - IpmiCreateServerConfig _config; - char _name[25]; - rx::Ref server; - - 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(ipmiCreateServer(thread->tproc, _params.serverImpl, _name, - _config, server)); - auto kid = g_context.ipmiMap.insert(std::move(server)); - - if (kid == -1) { - return ErrorCode::MFILE; - } - - ORBIS_LOG_ERROR(__FUNCTION__, kid, _name); - return uwrite(result, kid); -} - -orbis::SysResult orbis::sysIpmiCreateSession(Thread *thread, ptr result, - ptr params, - uint64_t paramsSz) { - struct IpmiSessionUserData { - uint64_t size; - ptr data; - }; - - static_assert(sizeof(IpmiSessionUserData) == 0x10); - - struct IpmiCreateSessionParams { - ptr sessionImpl; - ptr userData; - }; - - static_assert(sizeof(IpmiCreateSessionParams) == 0x10); - - if (paramsSz != sizeof(IpmiCreateSessionParams)) { - return ErrorCode::INVAL; - } - - IpmiCreateSessionParams _params; - IpmiSessionUserData _userData; - rx::Ref session; - - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - ORBIS_RET_ON_ERROR(uread(_userData, _params.userData)); - - if (_userData.size != sizeof(IpmiSessionUserData)) { - return ErrorCode::INVAL; - } - - ORBIS_RET_ON_ERROR( - ipmiCreateSession(thread, _params.sessionImpl, _userData.data, session)); - - auto kid = g_context.ipmiMap.insert(std::move(session)); - - if (kid == -1) { - return ErrorCode::MFILE; - } - - ORBIS_LOG_ERROR(__FUNCTION__, kid); - return uwrite(result, kid); -} - -orbis::SysResult orbis::sysIpmiDestroyClient(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz) { - ORBIS_LOG_TODO(__FUNCTION__); - return uwrite(result, 0); -} -orbis::SysResult orbis::sysIpmiDestroyServer(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz) { - ORBIS_LOG_TODO(__FUNCTION__); - return uwrite(result, 0); -} -orbis::SysResult orbis::sysIpmiDestroySession(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz) { - ORBIS_LOG_TODO(__FUNCTION__); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiServerReceivePacket(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiServerReceivePacketParams { - ptr buffer; - uint64_t bufferSize; - ptr receivePacketInfo; - ptr unk; - }; - - if (paramsSz != sizeof(IpmiServerReceivePacketParams)) { - return orbis::ErrorCode::INVAL; - } - - IpmiServerReceivePacketParams _params; - - ORBIS_RET_ON_ERROR( - uread(_params, ptr(params))); - - auto server = g_context.ipmiMap.get(kid).cast(); - - if (server == nullptr) { - return ErrorCode::INVAL; - } - - IpmiServer::Packet _packet; - - { - std::lock_guard lock(server->mutex); - while (server->packets.empty()) { - orbis::scoped_unblock unblock; - server->receiveCv.wait(server->mutex); - } - - _packet = std::move(server->packets.front()); - server->packets.pop_front(); - } - - if (_packet.info.type == 0x1) { - // on connection packet - - for (auto &conn : server->connectionRequests) { - if (conn.clientTid == _packet.info.inputSize) { - conn.serverTid = thread->tid; - _packet.info.inputSize = 0; - break; - } - } - } else if ((_packet.info.type & ~(0x10 | 0x8000)) == 0x41) { - auto syncMessage = (IpmiSyncMessageHeader *)_packet.message.data(); - ORBIS_LOG_ERROR(__FUNCTION__, server->name, syncMessage->methodId, - syncMessage->numInData, syncMessage->numOutData, - syncMessage->pid); - } else if ((_packet.info.type & ~0x10) == 0x43) { - auto asyncMessage = (IpmiAsyncMessageHeader *)_packet.message.data(); - ORBIS_LOG_ERROR(__FUNCTION__, server->name, asyncMessage->methodId, - asyncMessage->numInData, asyncMessage->pid); - } - - if (_params.bufferSize < _packet.message.size()) { - ORBIS_LOG_ERROR(__FUNCTION__, "too small buffer", _params.bufferSize, - _packet.message.size()); - return ErrorCode::INVAL; - } - - server->tidToClientTid[thread->tid] = _packet.clientTid; - - ORBIS_RET_ON_ERROR(uwriteRaw((ptr)_params.buffer, - _packet.message.data(), _packet.message.size())); - _params.bufferSize = _packet.message.size(); - _packet.info.eventHandler = server->eventHandler; - ORBIS_RET_ON_ERROR(uwrite(_params.receivePacketInfo, _packet.info)); - ORBIS_RET_ON_ERROR( - uwrite(ptr(params), _params)); - - return uwrite(result, 0); -} -orbis::SysResult orbis::sysIpmiSendConnectResult(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - if (paramsSz != sizeof(sint)) { - return ErrorCode::INVAL; - } - - ORBIS_LOG_NOTICE(__FUNCTION__, kid); - - auto ipmiObject = g_context.ipmiMap.get(kid); - if (ipmiObject == nullptr) { - return ErrorCode::INVAL; - } - - rx::Ref client; - if (auto result = ipmiObject.cast()) { - client = result->client; - } else if (auto result = ipmiObject.cast()) { - client = result; - } else if (auto result = ipmiObject.cast()) { - for (auto &request : result->connectionRequests) { - if (request.serverTid == thread->tid) { - client = request.client; - break; - } - } - } - - if (client == nullptr) { - ORBIS_LOG_FATAL(__FUNCTION__); - std::abort(); - } - - sint status; - ORBIS_RET_ON_ERROR(uread(status, ptr(params))); - - ORBIS_LOG_NOTICE(__FUNCTION__, kid, status); - std::lock_guard lock(client->mutex); - client->connectionStatus = status; - client->connectCv.notify_all(client->mutex); - client->sessionCv.notify_all(client->mutex); - return uwrite(result, 0u); -} -orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiRespondParams { - sint errorCode; - uint32_t bufferCount; - ptr buffers; - uint32_t flags; - uint32_t padding; - }; - - static_assert(sizeof(IpmiRespondParams) == 0x18); - if (paramsSz != sizeof(IpmiRespondParams)) { - return ErrorCode::INVAL; - } - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - IpmiRespondParams _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - kvector> buffers; - - // if ((_params.flags & 1) || _params.bufferCount != 1) { - auto count = _params.bufferCount; - buffers.reserve(count); - for (uint32_t i = 0; i < count; ++i) { - IpmiBufferInfo _buffer; - ORBIS_RET_ON_ERROR(uread(_buffer, _params.buffers + i)); - - auto &bufferData = buffers.emplace_back(); - bufferData.resize(_buffer.size); - ORBIS_RET_ON_ERROR(ureadRaw(bufferData.data(), _buffer.data, _buffer.size)); - } - // } - - std::lock_guard lock(session->mutex); - - std::uint32_t clientTid; - { - std::lock_guard serverLock(session->server->mutex); - clientTid = session->server->tidToClientTid.at(thread->tid); - } - - ORBIS_LOG_ERROR(__FUNCTION__, session->client->name, _params.errorCode); - - if (_params.errorCode != 0) { - ORBIS_LOG_ERROR(__FUNCTION__, session->client->name, _params.errorCode); - thread->where(); - } - - session->syncResponses.push_front({ - .errorCode = _params.errorCode, - .callerTid = clientTid, - .data = std::move(buffers), - }); - - session->responseCv.notify_all(session->mutex); - return uwrite(result, 0u); -} -orbis::SysResult orbis::sysIpmiClientInvokeAsyncMethod(Thread *thread, - ptr result, - uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiAsyncCallParams { - uint32_t method; - uint32_t evfIndex; - uint64_t evfValue; - 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 = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - IpmiAsyncCallParams _params; - ORBIS_RET_ON_ERROR(uread(_params, (ptr)params)); - - if (_params.flags > 1) { - return ErrorCode::INVAL; - } - - std::lock_guard clientLock(client->mutex); - auto session = client->session; - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - std::lock_guard sessionLock(session->mutex); - auto server = session->server; - - if (server == nullptr) { - return ErrorCode::INVAL; - } - - { - std::lock_guard serverLock(server->mutex); - - std::size_t inSize = 0; - for (auto &data : std::span(_params.pInData, _params.numInData)) { - inSize += data.size; - } - - auto size = sizeof(IpmiAsyncMessageHeader) + inSize + - _params.numInData * sizeof(uint32_t); - kvector message(size); - auto msg = new (message.data()) IpmiAsyncMessageHeader; - msg->sessionImpl = session->sessionImpl; - msg->pid = thread->tproc->pid; - msg->methodId = _params.method; - msg->numInData = _params.numInData; - - auto bufLoc = std::bit_cast(msg + 1); - - for (auto &data : std::span(_params.pInData, _params.numInData)) { - *std::bit_cast(bufLoc) = data.size; - bufLoc += sizeof(uint32_t); - ORBIS_RET_ON_ERROR(ureadRaw(bufLoc, data.data, data.size)); - bufLoc += data.size; - } - - uint type = 0x43; - - if ((_params.flags & 1) == 0) { - type |= 0x10; - } - - server->packets.push_back( - {{.type = type, .clientKid = kid}, 0, session, std::move(message)}); - server->receiveCv.notify_one(server->mutex); - } - - if (_params.evfIndex != -1 && _params.evfValue != 0) { - client->eventFlags[_params.evfIndex].set(_params.evfValue); - } - - ORBIS_RET_ON_ERROR(uwrite(_params.pResult, 0)); - return uwrite(result, 0u); -} - -orbis::SysResult orbis::sysImpiSessionRespondAsync(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiAsyncRespondParams { - uint method; - uint pid; - sint result; - uint32_t numOutData; - ptr pOutData; - uint32_t unk2; // == 1 - }; - - static_assert(sizeof(IpmiAsyncRespondParams) == 0x20); - - if (paramsSz != sizeof(IpmiAsyncRespondParams)) { - return ErrorCode::INVAL; - } - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - auto client = session->client; - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - IpmiAsyncRespondParams _params; - ORBIS_RET_ON_ERROR(uread(_params, (ptr)params)); - - kvector> outData; - outData.reserve(_params.numOutData); - for (auto data : std::span(_params.pOutData, _params.numOutData)) { - auto &elem = outData.emplace_back(); - elem.resize(data.size); - ORBIS_RET_ON_ERROR(ureadRaw(elem.data(), data.data, data.size)); - } - - { - std::lock_guard clientLock(client->mutex); - client->asyncResponses.push_back({ - .methodId = _params.method, - .errorCode = _params.result, - .data = std::move(outData), - }); - } - - client->asyncResponseCv.notify_all(client->mutex); - 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; - } - - IpmiTryGetResultParams _params; - ORBIS_RET_ON_ERROR(uread(_params, (ptr)params)); - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - while (true) { - std::lock_guard clientLock(client->mutex); - - for (auto it = client->asyncResponses.begin(); - it != client->asyncResponses.end(); ++it) { - if (it->methodId != _params.method) { - continue; - } - - auto response = std::move(*it); - client->asyncResponses.erase(it); - - ORBIS_RET_ON_ERROR(uwrite(_params.pResult, it->errorCode)); - - if (response.data.size() != _params.numOutData) { - ORBIS_LOG_ERROR(__FUNCTION__, "responses count mismatch", - response.data.size(), _params.numOutData); - } - - for (std::size_t i = 0; i < response.data.size(); ++i) { - if (response.data.size() > _params.numOutData) { - ORBIS_LOG_ERROR(__FUNCTION__, "too many responses", - response.data.size(), _params.numOutData); - break; - } - - IpmiBufferInfo _outData; - ORBIS_RET_ON_ERROR(uread(_outData, _params.pOutData + i)); - - auto &data = response.data[i]; - - if (_outData.capacity < data.size()) { - ORBIS_LOG_ERROR(__FUNCTION__, "too big response", _outData.capacity, - data.size()); - continue; - } - - _outData.size = data.size(); - ORBIS_RET_ON_ERROR(uwriteRaw(_outData.data, data.data(), data.size())); - ORBIS_RET_ON_ERROR(uwrite(_params.pOutData + i, _outData)); - } - - return uwrite(result, 0u); - } - - orbis::scoped_unblock unblock; - client->asyncResponseCv.wait(client->mutex); - } - - // return uwrite(result, 0x80020000 + static_cast(ErrorCode::AGAIN)); -} - -orbis::SysResult orbis::sysIpmiClientGetMessage(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct SceIpmiClientGetArgs { - uint32_t queueIndex; - 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 = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - SceIpmiClientGetArgs _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - std::lock_guard lock(client->mutex); - - if (_params.queueIndex >= client->messageQueues.size()) { - return ErrorCode::INVAL; - } - - auto &queue = client->messageQueues[_params.queueIndex]; - - using clock = std::chrono::high_resolution_clock; - - clock::time_point timeoutPoint = clock::time_point::max(); - if (_params.pTimeout != nullptr) { - std::uint32_t timeout{}; - ORBIS_RET_ON_ERROR(uread(timeout, _params.pTimeout)); - timeoutPoint = clock::now() + std::chrono::microseconds(timeout); - } - - if (queue.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); - - { - orbis::scoped_unblock unblock; - queue.messageCv.wait(client->mutex, waitTime.count()); - } - - if (!queue.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 (queue.messages.empty()) { - orbis::scoped_unblock unblock; - queue.messageCv.wait(client->mutex); - } - } - } - - auto &message = queue.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())); - queue.messages.pop_front(); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct SceIpmiClientTryGetArgs { - uint32_t queueIndex; - uint32_t padding; - ptr message; - ptr pSize; - uint64_t maxSize; - }; - - static_assert(sizeof(SceIpmiClientTryGetArgs) == 0x20); - - if (paramsSz != sizeof(SceIpmiClientTryGetArgs)) { - return ErrorCode::INVAL; - } - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - SceIpmiClientTryGetArgs _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - std::lock_guard lock(client->mutex); - - if (_params.queueIndex >= client->messageQueues.size()) { - return ErrorCode::INVAL; - } - - auto &queue = client->messageQueues[_params.queueIndex]; - - if (queue.messages.empty()) { - return uwrite(result, - 0x80020000 + static_cast(ErrorCode::AGAIN)); - } - - auto &message = queue.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())); - queue.messages.pop_front(); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiSessionTrySendMessage(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct SceIpmiClientTrySendArgs { - uint32_t queueIndex; - uint32_t padding; - ptr message; - uint64_t size; - }; - - static_assert(sizeof(SceIpmiClientTrySendArgs) == 0x18); - - if (paramsSz != sizeof(SceIpmiClientTrySendArgs)) { - return ErrorCode::INVAL; - } - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - SceIpmiClientTrySendArgs _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - std::lock_guard lock(session->mutex); - - if (session->client == nullptr) { - return ErrorCode::INVAL; - } - - auto client = session->client; - std::lock_guard lockClient(client->mutex); - - if (_params.queueIndex >= client->messageQueues.size()) { - return ErrorCode::INVAL; - } - - auto &queue = client->messageQueues[_params.queueIndex]; - - auto &message = queue.messages.emplace_back(); - message.resize(_params.size); - ORBIS_RET_ON_ERROR(ureadRaw(message.data(), _params.message, _params.size)); - queue.messageCv.notify_all(client->mutex); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiClientDisconnect(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct SceIpmiClientDisconnectArgs { - ptr status; - }; - - if (paramsSz != sizeof(SceIpmiClientDisconnectArgs)) { - return ErrorCode::INVAL; - } - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - SceIpmiClientDisconnectArgs _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - ORBIS_LOG_ERROR(__FUNCTION__, client->name, _params.status); - ORBIS_RET_ON_ERROR(uwrite(_params.status, 0)); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiSessionGetClientPid(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiGetClientPidParams { - ptr pid; - }; - - if (paramsSz != sizeof(IpmiGetClientPidParams)) { - return ErrorCode::INVAL; - } - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - IpmiGetClientPidParams _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - ORBIS_RET_ON_ERROR( - uwrite(_params.pid, session->client->process->pid)); - return uwrite(result, 0); -} - -orbis::SysResult -orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr result, uint kid, - ptr params, uint64_t paramsSz) { - if (paramsSz != sizeof(IpmiSyncCallParams)) { - return ErrorCode::INVAL; - } - - IpmiSyncCallParams _params; - ORBIS_RET_ON_ERROR(uread(_params, (ptr)params)); - - if (_params.flags > 1) { - return ErrorCode::INVAL; - } - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - auto session = client->session; - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - std::lock_guard sessionLock(session->mutex); - auto server = session->server; - - if (server == nullptr) { - return ErrorCode::INVAL; - } - - { - std::lock_guard serverLock(server->mutex); - - std::size_t inSize = 0; - for (auto &data : std::span(_params.pInData, _params.numInData)) { - inSize += data.size; - } - - auto headerSize = sizeof(IpmiSyncMessageHeader) + inSize + - _params.numInData * sizeof(uint32_t); - auto size = headerSize + _params.numOutData * sizeof(uint); - - kvector message(size); - auto msg = new (message.data()) IpmiSyncMessageHeader; - msg->sessionImpl = session->sessionImpl; - msg->pid = thread->tproc->pid; - msg->methodId = _params.method; - msg->numInData = _params.numInData; - msg->numOutData = _params.numOutData; - - auto bufLoc = std::bit_cast(msg + 1); - - for (auto &data : std::span(_params.pInData, _params.numInData)) { - *std::bit_cast(bufLoc) = data.size; - bufLoc += sizeof(uint32_t); - ORBIS_RET_ON_ERROR(ureadRaw(bufLoc, data.data, data.size)); - bufLoc += data.size; - } - - for (auto &data : std::span(_params.pOutData, _params.numOutData)) { - *std::bit_cast(bufLoc) = data.capacity; - bufLoc += sizeof(uint32_t); - } - - uint type = 0x41; - - if ((_params.flags & 1) == 0) { - type |= 0x10; - } - - if (server->pid == thread->tproc->pid) { - type |= 0x8000; - } - - server->packets.push_back( - {{.inputSize = headerSize, .type = type, .clientKid = kid}, - thread->tid, - session, - std::move(message)}); - server->receiveCv.notify_one(server->mutex); - } - - IpmiSession::SyncResponse response; - - while (true) { - { - orbis::scoped_unblock unblock; - session->responseCv.wait(session->mutex); - } - - bool found = false; - for (auto it = session->syncResponses.begin(); - it != session->syncResponses.end(); ++it) { - if (it->callerTid != thread->tid) { - continue; - } - - response = std::move(*it); - session->syncResponses.erase(it); - found = true; - break; - } - if (found) { - break; - } - } - - ORBIS_RET_ON_ERROR(uwrite(_params.pResult, response.errorCode)); - - if (response.data.size() != _params.numOutData) { - ORBIS_LOG_ERROR(__FUNCTION__, "responses amount mismatch", - response.data.size(), _params.numOutData); - } - - for (std::size_t i = 0; i < response.data.size(); ++i) { - if (response.data.size() > _params.numOutData) { - ORBIS_LOG_ERROR(__FUNCTION__, "too many responses", response.data.size(), - _params.numOutData); - break; - } - - IpmiBufferInfo _outData; - ORBIS_RET_ON_ERROR(uread(_outData, _params.pOutData + i)); - - auto &data = response.data[i]; - - if (_outData.capacity < data.size()) { - ORBIS_LOG_ERROR(__FUNCTION__, "too big response", _outData.capacity, - data.size()); - continue; - } - - // ORBIS_LOG_ERROR(__FUNCTION__, server->name, i, _outData.data, - // _outData.capacity, - // data.size()); - - _outData.size = data.size(); - ORBIS_RET_ON_ERROR(uwriteRaw(_outData.data, data.data(), data.size())); - ORBIS_RET_ON_ERROR(uwrite(_params.pOutData + i, _outData)); - } - - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiClientConnect(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz) { - if (paramsSz != sizeof(IpmiClientConnectParams)) { - return ErrorCode::INVAL; - } - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - if (client->session != nullptr) { - return ErrorCode::EXIST; - } - - IpmiClientConnectParams _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - auto server = g_context.findIpmiServer(client->name); - - if (server == nullptr) { - return SysResult::notAnError(ErrorCode::NOENT); - } - - std::lock_guard clientLock(client->mutex); - - decltype(server->connectionRequests)::iterator requestIt; - - { - std::lock_guard serverLock(server->mutex); - - for (auto &connReq : server->connectionRequests) { - if (connReq.client == client) { - return ErrorCode::EXIST; - } - } - - server->connectionRequests.push_front({ - .client = client, - .clientTid = thread->tid, - .clientPid = thread->tproc->pid, - }); - - requestIt = server->connectionRequests.begin(); - - struct QueueStats { - uint maxOutstanding; - uint unk; - ulong inDataSizeHardLimit; - ulong outDataSizeHardLimit; - }; - - struct ConnectMessageHeader { - uint32_t clientPid; - uint32_t clientKid; - QueueStats sync; - QueueStats async; - uint numEventFlag; - uint unk1; - uint numMsgQueue; - uint unk2; - ulong msgQueueSize[32]; - ulong memorySize; - }; - - static_assert(sizeof(ConnectMessageHeader) == 0x150); - - kvector message{ - sizeof(ConnectMessageHeader) + sizeof(uint) + - std::max(_params.userDataLen, 0x10)}; - auto header = new (message.data()) ConnectMessageHeader{}; - header->clientPid = thread->tproc->pid; - header->clientKid = kid; - - header->sync.maxOutstanding = 1; - header->sync.inDataSizeHardLimit = 0x10000; - header->sync.outDataSizeHardLimit = 0x10000; - header->async.maxOutstanding = 8; - header->async.inDataSizeHardLimit = 0x10000; - header->async.outDataSizeHardLimit = 0x10000; - - header->numEventFlag = client->eventFlags.size(); - header->numMsgQueue = client->messageQueues.size(); - - for (auto &size : header->msgQueueSize) { - size = 0x10000; - } - - if (_params.userDataLen != 0) { - auto bufLoc = std::bit_cast(header + 1); - *std::bit_cast(bufLoc) = _params.userDataLen; - ORBIS_RET_ON_ERROR(ureadRaw(bufLoc + sizeof(uint), _params.userData, - _params.userDataLen)); - } - - server->packets.push_back({{ - .inputSize = static_cast(thread->tid), - .type = 1, - .clientKid = kid, - }, - 0, - nullptr, - std::move(message)}); - server->receiveCv.notify_one(server->mutex); - } - - while (client->session == nullptr && !client->connectionStatus) { - orbis::scoped_unblock unblock; - client->sessionCv.wait(client->mutex); - } - - while (!client->connectionStatus) { - orbis::scoped_unblock unblock; - client->connectCv.wait(client->mutex); - } - - ORBIS_RET_ON_ERROR(uwrite(_params.status, *client->connectionStatus)); - - { - std::lock_guard serverLock(server->mutex); - server->connectionRequests.erase(requestIt); - } - - return uwrite(result, 0u); -} - -orbis::SysResult orbis::sysIpmiSessionGetClientAppId(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiGetUserDataParam { - ptr data; - }; - - if (paramsSz != sizeof(IpmiGetUserDataParam)) { - return ErrorCode::INVAL; - } - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - IpmiGetUserDataParam _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - ORBIS_RET_ON_ERROR( - uwrite(_params.data, session->client->process->appInfo.appId)); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiSessionGetUserData(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiGetUserDataParam { - ptr> data; - }; - - if (paramsSz != sizeof(IpmiGetUserDataParam)) { - return ErrorCode::INVAL; - } - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - IpmiGetUserDataParam _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - ORBIS_RET_ON_ERROR(uwrite(_params.data, session->userData)); - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiServerGetName(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz) { - struct IpmiGetServerNameParams { - ptr name; - }; - - if (paramsSz != sizeof(IpmiGetServerNameParams)) { - return ErrorCode::INVAL; - } - - auto server = g_context.ipmiMap.get(kid).cast(); - - if (server == nullptr) { - return ErrorCode::INVAL; - } - - IpmiGetServerNameParams _param; - ORBIS_RET_ON_ERROR(uread(_param, ptr(params))); - ORBIS_RET_ON_ERROR( - uwriteRaw(_param.name, server->name.c_str(), server->name.size() + 1)); - - return uwrite(result, 0); -} - -orbis::SysResult orbis::sysIpmiClientGetName(Thread *thread, ptr result, - uint kid, ptr params, - uint64_t paramsSz) { - struct IpmiGetClientNameParams { - ptr name; - }; - - if (paramsSz != sizeof(IpmiGetClientNameParams)) { - return ErrorCode::INVAL; - } - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - IpmiGetClientNameParams _param; - ORBIS_RET_ON_ERROR(uread(_param, ptr(params))); - ORBIS_RET_ON_ERROR( - uwriteRaw(_param.name, client->name.c_str(), client->name.size() + 1)); - - 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); - - if (paramsSz != sizeof(IpmiWaitEventFlagParam)) { - return ErrorCode::INVAL; - } - - IpmiWaitEventFlagParam _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - 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]; - ErrorCode waitResult; - - { - orbis::scoped_unblock unblock; - waitResult = evf.wait(thread, _params.mode, _params.patternSet, - _params.pTimeout != 0 ? &resultTimeout : nullptr); - } - - 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)); - } - if (waitResult == ErrorCode::TIMEDOUT) { - return SysResult::notAnError(ErrorCode::TIMEDOUT); - } - return waitResult; -} - -orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiPollEventFlagParam { - uint32_t index; - uint32_t padding0; - uint64_t patternSet; - uint32_t mode; - uint32_t padding1; - ptr pPatternSet; - }; - - static_assert(sizeof(IpmiPollEventFlagParam) == 0x20); - - if (paramsSz != sizeof(IpmiPollEventFlagParam)) { - return ErrorCode::INVAL; - } - - IpmiPollEventFlagParam _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - auto client = g_context.ipmiMap.get(kid).cast(); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - 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, - ptr result, uint kid, - ptr params, - uint64_t paramsSz) { - struct IpmiSetEventFlagParam { - uint32_t index; - uint32_t padding; - uint64_t patternSet; - }; - - static_assert(sizeof(IpmiSetEventFlagParam) == 0x10); - - if (paramsSz != sizeof(IpmiSetEventFlagParam)) { - return ErrorCode::INVAL; - } - - IpmiSetEventFlagParam _params; - ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); - - auto session = g_context.ipmiMap.get(kid).cast(); - - if (session == nullptr) { - return ErrorCode::INVAL; - } - - 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/rpcsx/gpu/Device.hpp b/rpcsx/gpu/Device.hpp index da7c1b9d6..86469cfe0 100644 --- a/rpcsx/gpu/Device.hpp +++ b/rpcsx/gpu/Device.hpp @@ -5,8 +5,8 @@ #include "Pipe.hpp" #include "amdgpu/tiler_vulkan.hpp" #include "orbis/KernelAllocator.hpp" -#include "rx/Rc.hpp" #include "rx/MemoryTable.hpp" +#include "rx/Rc.hpp" #include "rx/SharedMutex.hpp" #include "shader/SemanticInfo.hpp" #include "shader/SpvConverter.hpp" diff --git a/rpcsx/io-device.cpp b/rpcsx/io-device.cpp index e04d08dbe..557bdefe6 100644 --- a/rpcsx/io-device.cpp +++ b/rpcsx/io-device.cpp @@ -705,7 +705,7 @@ IoDevice *createHostIoDevice(orbis::kstring hostPath, } rx::Ref wrapSocket(int hostFd, orbis::kstring name, int dom, - int type, int prot) { + int type, int prot) { auto s = orbis::knew(); s->name = std::move(name); s->dom = dom; @@ -716,9 +716,8 @@ rx::Ref wrapSocket(int hostFd, orbis::kstring name, int dom, return s; } -orbis::ErrorCode createSocket(rx::Ref *file, - orbis::kstring name, int dom, int type, - int prot) { +orbis::ErrorCode createSocket(rx::Ref *file, orbis::kstring name, + int dom, int type, int prot) { // ORBIS_LOG_ERROR(__FUNCTION__, name, dom, type, prot); // *file = orbis::createPipe(); // return {}; diff --git a/rpcsx/io-device.hpp b/rpcsx/io-device.hpp index a8d0d9b58..16a9b2dc6 100644 --- a/rpcsx/io-device.hpp +++ b/rpcsx/io-device.hpp @@ -75,9 +75,9 @@ orbis::ErrorCode convertErrno(); IoDevice *createHostIoDevice(orbis::kstring hostPath, orbis::kstring virtualPath); rx::Ref wrapSocket(int hostFd, orbis::kstring name, int dom, - int type, int prot); -orbis::ErrorCode createSocket(rx::Ref *file, - orbis::kstring name, int dom, int type, int prot); + int type, int prot); +orbis::ErrorCode createSocket(rx::Ref *file, orbis::kstring name, + int dom, int type, int prot); orbis::File *createHostFile(int hostFd, rx::Ref device, bool alignTruncate = false); IoDevice *createFdWrapDevice(int fd); diff --git a/rpcsx/iodev/ajm.cpp b/rpcsx/iodev/ajm.cpp index 5dd571829..2ff692924 100644 --- a/rpcsx/iodev/ajm.cpp +++ b/rpcsx/iodev/ajm.cpp @@ -778,9 +778,9 @@ static const orbis::FileOps fileOps = { .ioctl = ajm_ioctl, }; -orbis::ErrorCode AjmDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode AjmDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->ops = &fileOps; newFile->device = this; diff --git a/rpcsx/iodev/aout.cpp b/rpcsx/iodev/aout.cpp index d850e242c..f7c849d0b 100644 --- a/rpcsx/iodev/aout.cpp +++ b/rpcsx/iodev/aout.cpp @@ -192,9 +192,9 @@ static const orbis::FileOps fileOps = { .write = aout_write, }; -orbis::ErrorCode AoutDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode AoutDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { ORBIS_LOG_FATAL("aout device open", path, flags, mode); auto newFile = orbis::knew(); newFile->ops = &fileOps; diff --git a/rpcsx/iodev/blockpool.hpp b/rpcsx/iodev/blockpool.hpp index f2ef7d3cd..047e08b15 100644 --- a/rpcsx/iodev/blockpool.hpp +++ b/rpcsx/iodev/blockpool.hpp @@ -3,8 +3,8 @@ #include "io-device.hpp" #include "orbis/error/ErrorCode.hpp" #include "orbis/file.hpp" -#include "rx/Rc.hpp" #include "rx/MemoryTable.hpp" +#include "rx/Rc.hpp" #include "rx/SharedMutex.hpp" #include diff --git a/rpcsx/iodev/dce.cpp b/rpcsx/iodev/dce.cpp index 4ac167bc8..d405cfce2 100644 --- a/rpcsx/iodev/dce.cpp +++ b/rpcsx/iodev/dce.cpp @@ -626,9 +626,9 @@ static void createGpu() { } } -orbis::ErrorCode DceDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode DceDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->device = this; newFile->ops = &ops; diff --git a/rpcsx/iodev/dmem.cpp b/rpcsx/iodev/dmem.cpp index 0cbc3b0cd..aefed276c 100644 --- a/rpcsx/iodev/dmem.cpp +++ b/rpcsx/iodev/dmem.cpp @@ -385,9 +385,9 @@ orbis::ErrorCode DmemDevice::queryMaxFreeChunkSize(std::uint64_t *start, return {}; } -orbis::ErrorCode DmemDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode DmemDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->device = this; newFile->ops = &ops; diff --git a/rpcsx/iodev/evlg.cpp b/rpcsx/iodev/evlg.cpp index 0f7e0302a..b00894b31 100644 --- a/rpcsx/iodev/evlg.cpp +++ b/rpcsx/iodev/evlg.cpp @@ -42,9 +42,9 @@ static const orbis::FileOps fileOps = { .write = evlg_write, }; -orbis::ErrorCode EvlgDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode EvlgDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->ops = &fileOps; newFile->device = this; diff --git a/rpcsx/iodev/hid.cpp b/rpcsx/iodev/hid.cpp index 61b6121fd..149a0812a 100644 --- a/rpcsx/iodev/hid.cpp +++ b/rpcsx/iodev/hid.cpp @@ -155,9 +155,9 @@ static const orbis::FileOps ops = { .ioctl = hid_ioctl, }; -orbis::ErrorCode HidDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode HidDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->device = this; newFile->ops = &ops; diff --git a/rpcsx/iodev/mbus.cpp b/rpcsx/iodev/mbus.cpp index 85ba02f49..5ae6455c6 100644 --- a/rpcsx/iodev/mbus.cpp +++ b/rpcsx/iodev/mbus.cpp @@ -52,9 +52,9 @@ void MBusDevice::emitEvent(const MBusEvent &event) { eventEmitter->emit(orbis::kEvFiltRead); } -orbis::ErrorCode MBusDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode MBusDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { ORBIS_LOG_FATAL("mbus device open"); auto newFile = orbis::knew(); newFile->ops = &fileOps; diff --git a/rpcsx/iodev/null.cpp b/rpcsx/iodev/null.cpp index b0d6b7f3f..5b9ba614f 100644 --- a/rpcsx/iodev/null.cpp +++ b/rpcsx/iodev/null.cpp @@ -22,9 +22,9 @@ static const orbis::FileOps ops = { .write = null_write, }; -orbis::ErrorCode NullDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode NullDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->device = this; newFile->ops = &ops; diff --git a/rpcsx/iodev/rng.cpp b/rpcsx/iodev/rng.cpp index 16bf1d366..99e441679 100644 --- a/rpcsx/iodev/rng.cpp +++ b/rpcsx/iodev/rng.cpp @@ -38,9 +38,9 @@ static const orbis::FileOps ops = { .mmap = rng_mmap, }; -orbis::ErrorCode RngDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode RngDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->device = this; newFile->ops = &ops; diff --git a/rpcsx/iodev/shm.cpp b/rpcsx/iodev/shm.cpp index c60c847a4..49239d7b2 100644 --- a/rpcsx/iodev/shm.cpp +++ b/rpcsx/iodev/shm.cpp @@ -17,9 +17,9 @@ struct ShmDevice : IoDevice { orbis::Thread *thread) override; }; -orbis::ErrorCode ShmDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode ShmDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { ORBIS_LOG_WARNING("shm_open", path, flags, mode); auto hostPath = rx::getShmGuestPath(path); auto realFlags = O_RDWR; // TODO diff --git a/rpcsx/iodev/zero.cpp b/rpcsx/iodev/zero.cpp index b091d2551..1cb954e79 100644 --- a/rpcsx/iodev/zero.cpp +++ b/rpcsx/iodev/zero.cpp @@ -25,9 +25,9 @@ static const orbis::FileOps ops = { .read = zero_read, }; -orbis::ErrorCode ZeroDevice::open(rx::Ref *file, - const char *path, std::uint32_t flags, - std::uint32_t mode, orbis::Thread *thread) { +orbis::ErrorCode ZeroDevice::open(rx::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) { auto newFile = orbis::knew(); newFile->device = this; newFile->ops = &ops; diff --git a/rpcsx/ops.cpp b/rpcsx/ops.cpp index e78f4c1fb..d7a26ed61 100644 --- a/rpcsx/ops.cpp +++ b/rpcsx/ops.cpp @@ -14,8 +14,8 @@ #include "orbis/uio.hpp" #include "orbis/umtx.hpp" #include "orbis/utils/Logs.hpp" -#include "rx/Rc.hpp" #include "orbis/vm.hpp" +#include "rx/Rc.hpp" #include "rx/watchdog.hpp" #include "thread.hpp" #include "vfs.hpp" diff --git a/rpcsx/vfs.cpp b/rpcsx/vfs.cpp index ad72128cf..987ca0744 100644 --- a/rpcsx/vfs.cpp +++ b/rpcsx/vfs.cpp @@ -159,8 +159,7 @@ orbis::SysResult vfs::mount(const std::filesystem::path &guestPath, } orbis::SysResult vfs::open(std::string_view path, int flags, int mode, - rx::Ref *file, - orbis::Thread *thread) { + rx::Ref *file, orbis::Thread *thread) { auto [device, devPath] = get(path); if (device == nullptr) { return orbis::ErrorCode::NOENT; diff --git a/rx/src/SharedAtomic.cpp b/rx/src/SharedAtomic.cpp index 201253dfb..87a1b2e83 100644 --- a/rx/src/SharedAtomic.cpp +++ b/rx/src/SharedAtomic.cpp @@ -3,6 +3,8 @@ using namespace rx; #ifdef __linux__ #include +#include +#include std::errc shared_atomic32::wait_impl(std::uint32_t oldValue, std::chrono::microseconds usec_timeout) {