From f3643aabf897acccd681859ec19971477337e24c Mon Sep 17 00:00:00 2001 From: DH Date: Wed, 15 Nov 2023 13:59:24 +0300 Subject: [PATCH] [rpcsx-os] simulate environment objects without vsh --- orbis-kernel/include/orbis/ipmi.hpp | 29 ++- orbis-kernel/src/ipmi.cpp | 43 +---- rpcsx-os/main.cpp | 276 +++++++++++++++++++++++++++- 3 files changed, 309 insertions(+), 39 deletions(-) diff --git a/orbis-kernel/include/orbis/ipmi.hpp b/orbis-kernel/include/orbis/ipmi.hpp index f0225e3a..fe6913fd 100644 --- a/orbis-kernel/include/orbis/ipmi.hpp +++ b/orbis-kernel/include/orbis/ipmi.hpp @@ -97,9 +97,34 @@ struct IpmiCreateServerConfig { static_assert(sizeof(IpmiCreateServerConfig) == 0x38); -ErrorCode ipmiCreateClient(Thread *thread, void *clientImpl, const char *name, +struct IpmiBufferInfo { + ptr data; + uint64_t size; +}; + +static_assert(sizeof(IpmiBufferInfo) == 0x10); + +struct IpmiDataInfo { + ptr data; + uint64_t size; + uint64_t capacity; //? +}; + +static_assert(sizeof(IpmiDataInfo) == 0x18); + +struct IpmiSyncMessageHeader { + orbis::ptr sessionImpl; + orbis::uint pid; + orbis::uint methodId; + orbis::uint numInData; + orbis::uint numOutData; +}; + +static_assert(sizeof(IpmiSyncMessageHeader) == 0x18); + +ErrorCode ipmiCreateClient(Process *proc, void *clientImpl, const char *name, void *config, Ref &result); -ErrorCode ipmiCreateServer(Thread *thread, void *serverImpl, const char *name, +ErrorCode ipmiCreateServer(Process *proc, void *serverImpl, const char *name, const IpmiCreateServerConfig &config, Ref &result); ErrorCode ipmiCreateSession(Thread *thread, void *sessionImpl, diff --git a/orbis-kernel/src/ipmi.cpp b/orbis-kernel/src/ipmi.cpp index 49498b6e..bb5e6784 100644 --- a/orbis-kernel/src/ipmi.cpp +++ b/orbis-kernel/src/ipmi.cpp @@ -3,24 +3,7 @@ #include "thread/Process.hpp" #include "utils/Logs.hpp" -namespace orbis { -struct IpmiBufferInfo { - ptr data; - uint64_t size; -}; - -static_assert(sizeof(IpmiBufferInfo) == 0x10); - -struct IpmiDataInfo { - ptr data; - uint64_t size; - uint64_t capacity; //? -}; - -static_assert(sizeof(IpmiDataInfo) == 0x18); -} // namespace orbis - -orbis::ErrorCode orbis::ipmiCreateClient(Thread *thread, void *clientImpl, +orbis::ErrorCode orbis::ipmiCreateClient(Process *proc, void *clientImpl, const char *name, void *config, Ref &result) { auto client = knew(name); @@ -30,12 +13,12 @@ orbis::ErrorCode orbis::ipmiCreateClient(Thread *thread, void *clientImpl, client->clientImpl = clientImpl; client->name = name; - client->pid = thread->tproc->pid; + client->pid = proc->pid; result = client; return {}; } -orbis::ErrorCode orbis::ipmiCreateServer(Thread *thread, void *serverImpl, +orbis::ErrorCode orbis::ipmiCreateServer(Process *proc, void *serverImpl, const char *name, const IpmiCreateServerConfig &config, Ref &result) { @@ -45,7 +28,7 @@ orbis::ErrorCode orbis::ipmiCreateServer(Thread *thread, void *serverImpl, server->serverImpl = serverImpl; server->userData = config.userData; server->eventHandler = config.eventHandler; - server->pid = thread->tproc->pid; + server->pid = proc->pid; result = server; return {}; } @@ -116,7 +99,7 @@ orbis::SysResult orbis::sysIpmiCreateClient(Thread *thread, ptr result, ORBIS_RET_ON_ERROR(uread(_params, ptr(params))); ORBIS_RET_ON_ERROR(ureadString(_name, sizeof(_name), _params.name)); ORBIS_RET_ON_ERROR( - ipmiCreateClient(thread, _params.clientImpl, _name, nullptr, client)); + ipmiCreateClient(thread->tproc, _params.clientImpl, _name, nullptr, client)); auto kid = thread->tproc->ipmiMap.insert(std::move(client)); @@ -152,7 +135,7 @@ orbis::SysResult orbis::sysIpmiCreateServer(Thread *thread, ptr result, ORBIS_RET_ON_ERROR(uread(_config, _params.config)); ORBIS_RET_ON_ERROR(ureadString(_name, sizeof(_name), _params.name)); ORBIS_RET_ON_ERROR( - ipmiCreateServer(thread, _params.serverImpl, _name, _config, server)); + ipmiCreateServer(thread->tproc, _params.serverImpl, _name, _config, server)); auto kid = thread->tproc->ipmiMap.insert(std::move(server)); if (kid == -1) { @@ -396,16 +379,6 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr result, uint kid, static_assert(sizeof(IpmiSyncCallParams) == 0x30); - struct MessageHeader { - ptr sessionImpl; - uint pid; - uint methodId; - uint numInData; - uint numOutData; - }; - - static_assert(sizeof(MessageHeader) == 0x18); - if (paramsSz != sizeof(IpmiSyncCallParams)) { return ErrorCode::INVAL; } @@ -463,12 +436,12 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr result, uint kid, outSize += data.size; } - auto size = sizeof(MessageHeader) + inSize + outSize + + auto size = sizeof(IpmiSyncMessageHeader) + inSize + outSize + _params.numInData * sizeof(uint32_t) + _params.numOutData * sizeof(uint32_t); kvector message(size); - auto msg = new (message.data()) MessageHeader; + auto msg = new (message.data()) IpmiSyncMessageHeader; msg->sessionImpl = session->sessionImpl; msg->pid = thread->tproc->pid; msg->methodId = _params.method; diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index 8171253a..82505344 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -11,9 +11,7 @@ #include "vm.hpp" #include -#include #include -#include #include #include #include @@ -30,9 +28,13 @@ #include #include +#include #include #include #include +#include +#include +#include static int g_gpuPid; @@ -610,6 +612,268 @@ static void runRpsxGpu() { } } +static orbis::Semaphore *createSemaphore(std::string_view name, uint32_t attrs, + uint64_t initCount, + uint64_t maxCount) { + return orbis::g_context + .createSemaphore(orbis::kstring(name), attrs, initCount, maxCount) + .first; +} + +static orbis::EventFlag *createEventFlag(std::string_view name, uint32_t attrs, + uint64_t initPattern) { + return orbis::g_context + .createEventFlag(orbis::kstring(name), attrs, initPattern) + .first; +} + +static void createShm(const char *name, uint32_t flags, uint32_t mode, + uint64_t size) { + orbis::Ref shm; + auto shmDevice = orbis::g_context.shmDevice.staticCast(); + shmDevice->open(&shm, "/SceAvSetting", flags, mode, nullptr); + shm->ops->truncate(shm.get(), 4096, nullptr); +} + +static orbis::Ref createIpmiServer( + orbis::Process *process, const char *name, + std::function + packetHandler) { + orbis::IpmiCreateServerConfig config{}; + orbis::Ref server; + orbis::ipmiCreateServer(process, nullptr, name, config, server); + std::thread{[server, packetHandler = std::move(packetHandler)] { + while (true) { + orbis::IpmiServer::Packet packet; + { + std::lock_guard lock(server->mutex); + + while (server->packets.empty()) { + server->receiveCv.wait(server->mutex); + } + + packet = std::move(server->packets.front()); + server->packets.pop_front(); + } + + if (packet.info.type == 1) { + std::lock_guard serverLock(server->mutex); + + for (auto it = server->connectionRequests.begin(); + it != server->connectionRequests.end(); ++it) { + auto &conReq = *it; + std::lock_guard clientLock(conReq.client->mutex); + if (conReq.client->session != nullptr) { + continue; + } + + auto session = orbis::knew(); + if (session == nullptr) { + break; + } + + session->client = conReq.client; + session->server = server; + conReq.client->session = session; + conReq.client->sessionCv.notify_all(conReq.client->mutex); + // server->connectionRequests.erase(it); + break; + } + + continue; + } + + if ((packet.info.type & ~0x8010) == 0x41) { + auto msgHeader = std::bit_cast( + packet.message.data()); + auto process = orbis::g_context.findProcessById(msgHeader->pid); + if (process == nullptr) { + continue; + } + auto client = process->ipmiMap.get(packet.info.clientKid) + .cast(); + if (client == nullptr) { + continue; + } + auto session = client->session; + if (session == nullptr) { + continue; + } + + packetHandler(client->session.get(), msgHeader); + continue; + } + + std::fprintf(stderr, "IPMI: Unhandled packet %s::%u\n", + server->name.c_str(), packet.info.type); + } + }}.detach(); + return server; +} + +static std::uint32_t +unimplementedIpmiServer(orbis::IpmiSession *session, + orbis::IpmiSyncMessageHeader *message) { + std::fprintf( + stderr, + "Unimplemented sync method %s::%x(inBufCount=%x, outBufCount=%x)\n", + session->server->name.c_str(), message->methodId, message->numInData, + message->numOutData); + + std::size_t inBufferOffset = 0; + auto bufLoc = std::bit_cast(message + 1); + for (unsigned i = 0; i < message->numInData; ++i) { + bufLoc += *std::bit_cast(bufLoc) + sizeof(orbis::uint); + } + + auto outSize = *std::bit_cast(bufLoc); + orbis::kvector output(outSize); + + std::lock_guard lock(session->mutex); + + session->messageResponses.push_front({ + .errorCode = 0, + .data = std::move(output), + }); + + session->responseCv.notify_one(session->mutex); + return 0; +} + +static void createSysAvControlObjects(orbis::Process *process) { + createIpmiServer(process, "SceAvSettingIpc", unimplementedIpmiServer); + + createEventFlag("SceAvSettingEvf", 0x121, 0xffff00000000); + + createShm("/SceAvSetting", 0xa02, 0x1a4, 4096); +} + +static void createSysCoreObjects(orbis::Process *process) { + createIpmiServer(process, "SceMbusIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceSysCoreApp", unimplementedIpmiServer); + createIpmiServer(process, "SceSysCoreApp2", unimplementedIpmiServer); + createIpmiServer(process, "SceMDBG0SRV", unimplementedIpmiServer); + + createSemaphore("SceSysCoreProcSpawnSema", 0x101, 0, 1); + createSemaphore("SceTraceMemorySem", 0x100, 1, 1); + createSemaphore("SceSysCoreEventSemaphore", 0x101, 0, 0x2d2); + createSemaphore("SceSysCoreProcSema", 0x101, 0, 1); + createSemaphore("AppmgrCoredumpHandlingEventSema", 0x101, 0, 4); + + createEventFlag("SceMdbgVrTriggerDump", 0x121, 0); +} + +static void createGnmCompositorObjects(orbis::Process *process) { + createEventFlag("SceCompositorCrashEventFlags", 0x122, 0); + createEventFlag("SceCompositorEventflag", 0x122, 0); + createEventFlag("SceCompositorResetStatusEVF", 0x122, 0); + + createShm("/tmp/SceHmd/Vr2d_shm_pass", 0xa02, 0x1b6, 16384); +} + +static void createShellCoreObjects(orbis::Process *process) { + + // FIXME: replace with fmt library + auto fmtHex = [](auto value, bool upperCase = false) { + std::stringstream ss; + ss << std::hex << std::setw(8) << std::setfill('0'); + if (upperCase) { + ss << std::uppercase; + } + ss << value; + return std::move(ss).str(); + }; + + createIpmiServer(process, "SceSystemLoggerService", unimplementedIpmiServer); + createIpmiServer(process, "SceLoginMgrServer", unimplementedIpmiServer); + createIpmiServer(process, "SceLncService", unimplementedIpmiServer); + createIpmiServer(process, "SceAppMessaging", unimplementedIpmiServer); + createIpmiServer(process, "SceShellCoreUtil", unimplementedIpmiServer); + createIpmiServer(process, "SceNetCtl", unimplementedIpmiServer); + createIpmiServer(process, "SceNpMgrIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceNpService", unimplementedIpmiServer); + createIpmiServer(process, "SceNpTrophyIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceNpUdsIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceLibNpRifMgrIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceNpPartner001", unimplementedIpmiServer); + createIpmiServer(process, "SceNpPartnerSubs", unimplementedIpmiServer); + createIpmiServer(process, "SceNpGameIntent", unimplementedIpmiServer); + createIpmiServer(process, "SceBgft", unimplementedIpmiServer); + createIpmiServer(process, "SceCntMgrService", unimplementedIpmiServer); + createIpmiServer(process, "ScePlayGo", unimplementedIpmiServer); + createIpmiServer(process, "SceCompAppProxyUtil", unimplementedIpmiServer); + createIpmiServer(process, "SceShareSpIpcService", unimplementedIpmiServer); + createIpmiServer(process, "SceRnpsAppMgr", unimplementedIpmiServer); + createIpmiServer(process, "SceUpdateService", unimplementedIpmiServer); + createIpmiServer(process, "ScePatchChecker", unimplementedIpmiServer); + createIpmiServer(process, "SceMorpheusUpdService", unimplementedIpmiServer); + createIpmiServer(process, "ScePsmSharedDmem", unimplementedIpmiServer); + createIpmiServer(process, "SceSaveData", unimplementedIpmiServer); + createIpmiServer(process, "SceStickerCoreServer", unimplementedIpmiServer); + createIpmiServer(process, "SceDbRecoveryShellCore", unimplementedIpmiServer); + createIpmiServer(process, "SceUserService", unimplementedIpmiServer); + createIpmiServer(process, "SceDbPreparationServer", unimplementedIpmiServer); + createIpmiServer(process, "SceScreenShot", unimplementedIpmiServer); + createIpmiServer(process, "SceAppDbIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceAppInst", unimplementedIpmiServer); + createIpmiServer(process, "SceAppContent", unimplementedIpmiServer); + createIpmiServer(process, "SceNpEntAccess", unimplementedIpmiServer); + createIpmiServer(process, "SceMwIPMIServer", unimplementedIpmiServer); + createIpmiServer(process, "SceAutoMounterIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceBackupRestoreUtil", unimplementedIpmiServer); + createIpmiServer(process, "SceDataTransfer", unimplementedIpmiServer); + createIpmiServer(process, "SceEventService", unimplementedIpmiServer); + createIpmiServer(process, "SceShareFactoryUtil", unimplementedIpmiServer); + createIpmiServer(process, "SceCloudConnectManager", unimplementedIpmiServer); + createIpmiServer(process, "SceHubAppUtil", unimplementedIpmiServer); + createIpmiServer(process, "SceTcIPMIServer", unimplementedIpmiServer); + + createSemaphore("SceLncSuspendBlock00000001", 0x101, 1, 1); + createSemaphore("SceAppMessaging00000001", 0x100, 0, 0x7fffffff); + + createEventFlag("SceAutoMountUsbMass", 0x120, 0); + createEventFlag("SceLoginMgrUtilityEventFlag", 0x112, 0); + createEventFlag("SceLoginMgrSharePlayEventFlag", 0x112, 0); + createEventFlag("SceLoginMgrServerHmdConnect", 0x112, 0); + createEventFlag("SceLoginMgrServerDialogRequest", 0x112, 0); + createEventFlag("SceLoginMgrServerDialogResponse", 0x112, 0); + createEventFlag("SceGameLiveStreamingSpectator", 0x120, 0x8000000000000000); + createEventFlag("SceGameLiveStreamingUserId", 0x120, 0x8000000000000000); + createEventFlag("SceGameLiveStreamingMsgCount", 0x120, 0x8000000000000000); + createEventFlag("SceGameLiveStreamingBCCtrl", 0x120, 0); + createEventFlag("SceGameLiveStreamingEvntArg", 0x120, 0); + createEventFlag("SceLncUtilSystemStatus", 0x120, 0); + createEventFlag("SceShellCoreUtilRunLevel", 0x100, 0); + createEventFlag("SceSystemStateMgrInfo", 0x120, 0x10000000a); + createEventFlag("SceSystemStateMgrStatus", 0x120, 0); + createEventFlag("SceAppInstallerEventFlag", 0x120, 0); + createEventFlag("SceShellCoreUtilPowerControl", 0x120, 0xffff); + createEventFlag("SceShellCoreUtilAppFocus", 0x120, -1); + createEventFlag("SceShellCoreUtilCtrlFocus", 0x120, -1); + createEventFlag("SceShellCoreUtilUIStatus", 0x120, 0x20001); + createEventFlag("SceShellCoreUtilDevIdxBehavior", 0x120, 0); + createEventFlag("SceNpMgrVshReq", 0x121, 0); + createEventFlag("SceNpIdMapperVshReq", 0x121, 0); + createEventFlag("SceRtcUtilTzdataUpdateFlag", 0x120, 0); + createEventFlag("SceDataTransfer", 0x120, 0); + createEventFlag("SceShellCoreUtilffffffff", 0x120, 0x3f8c); + + createEventFlag("SceSysLogPullEvt_" + fmtHex(process->pid, true), 0x110, 0); + createEventFlag("SceNpIdMapperEvf00" + fmtHex(process->pid), 0x121, 0); + createEventFlag("SceNpBasicPreseEvf00" + fmtHex(process->pid), 0x121, 0); + createEventFlag("SceNpPresenceEvf00" + fmtHex(process->pid), 0x121, 0); + createEventFlag("SceNpInGameMsgEvf00" + fmtHex(process->pid), 0x121, 0); + createEventFlag("SceNpPush2Evf00" + fmtHex(process->pid), 0x121, 0); + createEventFlag("SceUserServiceGetEvent_" + fmtHex(process->pid), 0x110, 0); + + createEventFlag("SceLncUtilAppStatus00000001", 0x100, 0); + createEventFlag("SceAppMessaging00000001", 0x120, 0); + + createShm("SceGlsSharedMemory", 0x202, 0x1a4, 262144); + createShm("SceShellCoreUtil", 0x202, 0x1a4, 16384); + createShm("SceNpTpip", 0x202, 0x1ff, 43008); +} + int main(int argc, const char *argv[]) { if (argc == 2) { if (std::strcmp(argv[1], "-h") == 0 || @@ -860,6 +1124,14 @@ int main(int argc, const char *argv[]) { executableModule->type == rx::linker::kElfTypeExec) { ps4InitDev(); ps4InitFd(mainThread); + + if (!isSystem) { + createSysAvControlObjects(initProcess); + createSysCoreObjects(initProcess); + createGnmCompositorObjects(initProcess); + createShellCoreObjects(initProcess); + } + std::vector ps4Argv(argv + argIndex, argv + argIndex + argc - argIndex); status = ps4Exec(mainThread, std::move(executableModule), ps4Argv, {});