ipmi: implement fake client API

This commit is contained in:
DH 2024-09-26 20:23:52 +03:00
parent 7eaf1188a2
commit af62ee04dd
3 changed files with 132 additions and 33 deletions

View file

@ -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<IpmiDataInfo> pInData;
ptr<IpmiBufferInfo> pOutData;
ptr<sint> pResult;
uint32_t flags;
};
static_assert(sizeof(IpmiSyncCallParams) == 0x30);
struct [[gnu::packed]] IpmiSyncMessageHeader {
orbis::ptr<void> sessionImpl;
@ -153,6 +166,23 @@ struct [[gnu::packed]] IpmiAsyncMessageHeader {
static_assert(sizeof(IpmiSyncMessageHeader) == 0x18);
struct IpmiCreateClientParams {
ptr<void> clientImpl;
ptr<const char> name;
ptr<IpmiCreateClientConfig> config;
};
static_assert(sizeof(IpmiCreateClientParams) == 0x18);
struct IpmiClientConnectParams {
ptr<void> userData;
ulong userDataLen;
ptr<sint> status;
ptr<sint> arg3;
};
static_assert(sizeof(IpmiClientConnectParams) == 0x20);
ErrorCode ipmiCreateClient(Process *proc, void *clientImpl, const char *name,
const IpmiCreateClientConfig &config,
Ref<IpmiClient> &result);

View file

@ -3,8 +3,8 @@
#include "thread/Process.hpp"
#include "utils/Logs.hpp"
#include <chrono>
#include <sys/mman.h>
#include <span>
#include <sys/mman.h>
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<uint> result,
ptr<void> params,
uint64_t paramsSz) {
struct IpmiCreateClientParams {
ptr<void> clientImpl;
ptr<const char> name;
ptr<IpmiCreateClientConfig> config;
};
static_assert(sizeof(IpmiCreateClientParams) == 0x18);
if (paramsSz != sizeof(IpmiCreateClientParams)) {
return ErrorCode::INVAL;
}
@ -887,22 +879,10 @@ orbis::SysResult orbis::sysIpmiSessionGetClientPid(Thread *thread,
uwrite<uint32_t>(_params.pid, session->client->process->pid));
return uwrite<uint>(result, 0);
}
orbis::SysResult
orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz) {
struct IpmiSyncCallParams {
uint32_t method;
uint32_t numInData;
uint32_t numOutData;
uint32_t unk;
ptr<IpmiDataInfo> pInData;
ptr<IpmiBufferInfo> pOutData;
ptr<sint> 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<uint> result, uint kid,
orbis::SysResult orbis::sysIpmiClientConnect(Thread *thread, ptr<uint> result,
uint kid, ptr<void> params,
uint64_t paramsSz) {
struct IpmiClientConnectParams {
ptr<void> userData;
ulong userDataLen;
ptr<sint> status;
ptr<sint> arg3;
};
static_assert(sizeof(IpmiClientConnectParams) == 0x20);
if (paramsSz != sizeof(IpmiClientConnectParams)) {
return ErrorCode::INVAL;
}

View file

@ -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<orbis::IpmiClient> clientImpl;
orbis::uint kid;
orbis::Thread *thread;
orbis::sint sendSyncMessage(std::uint32_t method, const void *data,
std::size_t size,
std::vector<std::byte> &outData) {
orbis::sint serverResult;
orbis::IpmiBufferInfo outBufferInfo = {
.data = outData.data(),
.capacity = outData.size(),
};
orbis::IpmiDataInfo inDataInfo = {
.data = orbis::ptr<void>(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, &params,
sizeof(params));
outData.resize(outBufferInfo.size);
return serverResult;
}
template <typename T>
orbis::sint sendSyncMessage(std::uint32_t method, const T &data,
std::vector<std::byte> &outData) {
return sendSyncMessage(method, &data, sizeof(data), outData);
}
template <typename T>
orbis::sint sendSyncMessage(std::uint32_t method, const T &data) {
std::vector<std::byte> outData;
return sendSyncMessage(method, &data, sizeof(data), outData);
}
template <typename T>
std::vector<std::byte> sendSyncMessage(std::uint32_t method, const T &data,
std::size_t outputCapacity) {
std::vector<std::byte> outData;
outData.resize(outputCapacity);
sendSyncMessage(method, &data, sizeof(data), outData);
return outData;
}
};
static IpmiClient createIpmiClient(orbis::Thread *thread, const char *name) {
orbis::Ref<orbis::IpmiClient> client;
orbis::IpmiCreateClientConfig config{
.size = sizeof(orbis::IpmiCreateClientConfig),
};
orbis::uint kid;
{
orbis::IpmiCreateClientParams params{
.name = name,
.config = &config,
};
orbis::sysIpmiCreateClient(thread, &kid, &params, sizeof(params));
}
{
orbis::sint status;
orbis::IpmiClientConnectParams params{.status = &status};
orbis::uint result;
orbis::sysIpmiClientConnect(thread, &result, kid, &params, sizeof(params));
}
return {std::move(client), kid, thread};
}
static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path,
std::vector<std::string> argv,
std::vector<std::string> envv) {