diff --git a/orbis-kernel/include/orbis/ipmi.hpp b/orbis-kernel/include/orbis/ipmi.hpp index 97369a833..101e8983c 100644 --- a/orbis-kernel/include/orbis/ipmi.hpp +++ b/orbis-kernel/include/orbis/ipmi.hpp @@ -133,8 +133,21 @@ struct IpmiDataInfo { uint64_t size; }; -// static_assert(sizeof(IpmiBufferInfo) == 0x18); -// static_assert(sizeof(IpmiDataInfo) == 0x10); +static_assert(sizeof(IpmiBufferInfo) == 0x18); +static_assert(sizeof(IpmiDataInfo) == 0x10); + +struct IpmiSyncCallParams { + uint32_t method; + uint32_t numInData; + uint32_t numOutData; + uint32_t unk; + ptr pInData; + ptr pOutData; + ptr pResult; + uint32_t flags; +}; + +static_assert(sizeof(IpmiSyncCallParams) == 0x30); struct [[gnu::packed]] IpmiSyncMessageHeader { orbis::ptr sessionImpl; @@ -153,6 +166,23 @@ struct [[gnu::packed]] IpmiAsyncMessageHeader { static_assert(sizeof(IpmiSyncMessageHeader) == 0x18); +struct IpmiCreateClientParams { + ptr clientImpl; + ptr name; + ptr config; +}; + +static_assert(sizeof(IpmiCreateClientParams) == 0x18); + +struct IpmiClientConnectParams { + ptr userData; + ulong userDataLen; + ptr status; + ptr arg3; +}; + +static_assert(sizeof(IpmiClientConnectParams) == 0x20); + ErrorCode ipmiCreateClient(Process *proc, void *clientImpl, const char *name, const IpmiCreateClientConfig &config, Ref &result); diff --git a/orbis-kernel/src/ipmi.cpp b/orbis-kernel/src/ipmi.cpp index 08dc51103..7742abe24 100644 --- a/orbis-kernel/src/ipmi.cpp +++ b/orbis-kernel/src/ipmi.cpp @@ -3,8 +3,8 @@ #include "thread/Process.hpp" #include "utils/Logs.hpp" #include -#include #include +#include orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl, const char *name, @@ -88,14 +88,6 @@ orbis::ErrorCode orbis::ipmiCreateSession(Thread *thread, void *sessionImpl, orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr result, ptr params, uint64_t paramsSz) { - struct IpmiCreateClientParams { - ptr clientImpl; - ptr name; - ptr config; - }; - - static_assert(sizeof(IpmiCreateClientParams) == 0x18); - if (paramsSz != sizeof(IpmiCreateClientParams)) { return ErrorCode::INVAL; } @@ -887,22 +879,10 @@ orbis::SysResult orbis::sysIpmiSessionGetClientPid(Thread *thread, 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) { - struct IpmiSyncCallParams { - uint32_t method; - uint32_t numInData; - uint32_t numOutData; - uint32_t unk; - ptr pInData; - ptr pOutData; - ptr pResult; - uint32_t flags; - }; - - static_assert(sizeof(IpmiSyncCallParams) == 0x30); - if (paramsSz != sizeof(IpmiSyncCallParams)) { return ErrorCode::INVAL; } @@ -1050,15 +1030,6 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr result, uint kid, orbis::SysResult orbis::sysIpmiClientConnect(Thread *thread, ptr result, uint kid, ptr params, uint64_t paramsSz) { - struct IpmiClientConnectParams { - ptr userData; - ulong userDataLen; - ptr status; - ptr arg3; - }; - - static_assert(sizeof(IpmiClientConnectParams) == 0x20); - if (paramsSz != sizeof(IpmiClientConnectParams)) { return ErrorCode::INVAL; } diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index b37bd836a..136cba8e2 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -1595,6 +1595,104 @@ static void createShellCoreObjects(orbis::Process *process) { createSemaphore("SceNpTpip 0", 0x101, 0, 1); } +static orbis::Process *createGuestProcess() { + auto pid = orbis::g_context.allocatePid() * 10000 + 1; + return orbis::g_context.createProcess(pid); +} + +static orbis::Thread *createGuestThread() { + auto process = createGuestProcess(); + auto [baseId, thread] = process->threadsMap.emplace(); + thread->tproc = process; + thread->tid = process->pid + baseId; + thread->state = orbis::ThreadState::RUNNING; + return thread; +} + +struct IpmiClient { + orbis::Ref clientImpl; + orbis::uint kid; + orbis::Thread *thread; + + orbis::sint sendSyncMessage(std::uint32_t method, const void *data, + std::size_t size, + std::vector &outData) { + orbis::sint serverResult; + orbis::IpmiBufferInfo outBufferInfo = { + .data = outData.data(), + .capacity = outData.size(), + }; + + orbis::IpmiDataInfo inDataInfo = { + .data = orbis::ptr(data), + .size = size, + }; + + orbis::IpmiSyncCallParams params{ + .method = method, + .numInData = 1, + .numOutData = 1, + .pInData = &inDataInfo, + .pOutData = &outBufferInfo, + .pResult = &serverResult, + }; + + orbis::uint errorCode; + orbis::sysIpmiClientInvokeSyncMethod(thread, &errorCode, kid, ¶ms, + sizeof(params)); + + outData.resize(outBufferInfo.size); + return serverResult; + } + + template + orbis::sint sendSyncMessage(std::uint32_t method, const T &data, + std::vector &outData) { + return sendSyncMessage(method, &data, sizeof(data), outData); + } + + template + orbis::sint sendSyncMessage(std::uint32_t method, const T &data) { + std::vector outData; + return sendSyncMessage(method, &data, sizeof(data), outData); + } + + template + std::vector sendSyncMessage(std::uint32_t method, const T &data, + std::size_t outputCapacity) { + std::vector outData; + outData.resize(outputCapacity); + sendSyncMessage(method, &data, sizeof(data), outData); + return outData; + } +}; + +static IpmiClient createIpmiClient(orbis::Thread *thread, const char *name) { + orbis::Ref client; + orbis::IpmiCreateClientConfig config{ + .size = sizeof(orbis::IpmiCreateClientConfig), + }; + + orbis::uint kid; + + { + orbis::IpmiCreateClientParams params{ + .name = name, + .config = &config, + }; + + orbis::sysIpmiCreateClient(thread, &kid, ¶ms, sizeof(params)); + } + { + orbis::sint status; + orbis::IpmiClientConnectParams params{.status = &status}; + + orbis::uint result; + orbis::sysIpmiClientConnect(thread, &result, kid, ¶ms, sizeof(params)); + } + return {std::move(client), kid, thread}; +} + static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path, std::vector argv, std::vector envv) {