From 6ba0ad08320c040a4d234772891c4d65013614ea Mon Sep 17 00:00:00 2001 From: DH Date: Wed, 27 Dec 2023 20:07:30 +0300 Subject: [PATCH] [rpcsx-os] implement fw simulation implement impi messages --- .../bridge/include/amdgpu/bridge/bridge.hpp | 9 +- hw/amdgpu/bridge/src/bridge.cpp | 2 + orbis-kernel/include/orbis/ipmi.hpp | 9 +- orbis-kernel/src/ipmi.cpp | 48 ++ orbis-kernel/src/sys/sys_sce.cpp | 50 +- rpcsx-gpu/main.cpp | 12 +- rpcsx-os/main.cpp | 538 ++++++++++++++---- rpcsx-os/ops.cpp | 1 - 8 files changed, 516 insertions(+), 153 deletions(-) diff --git a/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp b/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp index cde00b69..434436a9 100644 --- a/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp +++ b/hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp @@ -1,6 +1,5 @@ #pragma once -#include "orbis/utils/SharedMutex.hpp" #include #include #include @@ -8,6 +7,8 @@ #include namespace amdgpu::bridge { +extern std::uint32_t expGpuPid; + struct PadState { std::uint64_t timestamp; std::uint32_t unk; @@ -149,21 +150,21 @@ struct BridgePusher { void sendMemoryProtect(std::uint32_t pid, std::uint64_t address, std::uint64_t size, std::uint32_t prot) { - if (pid == 50001) { + if (pid == expGpuPid) { sendCommand(CommandId::ProtectMemory, {pid, address, size, prot}); } } void sendCommandBuffer(std::uint32_t pid, std::uint64_t queue, std::uint64_t address, std::uint64_t size) { - if (pid == 50001) { + if (pid == expGpuPid) { sendCommand(CommandId::CommandBuffer, {pid, queue, address, size}); } } void sendFlip(std::uint32_t pid, std::uint32_t bufferIndex, std::uint64_t arg) { - if (pid == 50001) { + if (pid == expGpuPid) { sendCommand(CommandId::Flip, {pid, bufferIndex, arg}); } } diff --git a/hw/amdgpu/bridge/src/bridge.cpp b/hw/amdgpu/bridge/src/bridge.cpp index 63bb1fd1..11e82ada 100644 --- a/hw/amdgpu/bridge/src/bridge.cpp +++ b/hw/amdgpu/bridge/src/bridge.cpp @@ -8,6 +8,8 @@ static int gShmFd = -1; static constexpr std::size_t kShmSize = sizeof(amdgpu::bridge::BridgeHeader) + (sizeof(std::uint64_t) * (1024 * 1024)); +std::uint32_t amdgpu::bridge::expGpuPid = 0; + amdgpu::bridge::BridgeHeader * amdgpu::bridge::createShmCommandBuffer(const char *name) { if (gShmFd != -1) { diff --git a/orbis-kernel/include/orbis/ipmi.hpp b/orbis-kernel/include/orbis/ipmi.hpp index fe6913fd..cfd2dce1 100644 --- a/orbis-kernel/include/orbis/ipmi.hpp +++ b/orbis-kernel/include/orbis/ipmi.hpp @@ -58,6 +58,8 @@ struct IpmiClient : RcBase { shared_mutex mutex; shared_cv sessionCv; sint pid; + kdeque> messages; + shared_cv messageCv; explicit IpmiClient(kstring name) : name(std::move(name)) {} }; @@ -150,6 +152,8 @@ 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 sysIpmiClientTryGetMessage(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, @@ -161,9 +165,8 @@ 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 sysIpmiClientPollEventFlag(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); diff --git a/orbis-kernel/src/ipmi.cpp b/orbis-kernel/src/ipmi.cpp index 2a59e301..bb86a189 100644 --- a/orbis-kernel/src/ipmi.cpp +++ b/orbis-kernel/src/ipmi.cpp @@ -341,6 +341,54 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread, return uwrite(result, 0u); } +orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread, + ptr result, uint kid, + ptr params, + uint64_t paramsSz) { + struct SceIpmiClientTryGetArgs { + uint32_t unk; // 0 + uint32_t padding; + ptr message; + ptr pSize; + uint64_t maxSize; + }; + + static_assert(sizeof(SceIpmiClientTryGetArgs) == 0x20); + + if (paramsSz != sizeof(SceIpmiClientTryGetArgs)) { + return ErrorCode::INVAL; + } + + auto client = thread->tproc->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 (client->messages.empty()) { + return uwrite(result, + 0x80020000 + static_cast(ErrorCode::AGAIN)); + } + + 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::sysIpmiSessionGetClientPid(Thread *thread, ptr result, uint kid, ptr params, diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index 95412460..ddea76e0 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -950,25 +950,26 @@ orbis::SysResult orbis::sys_get_self_auth_info(Thread *thread, ORBIS_LOG_ERROR(__FUNCTION__, path, result); thread->where(); - return uwrite( - result, { - .unk0 = 0x3100000000000001, - .caps = - { - ~0ull, ~0ull, ~0ull, ~0ull, - // 0x2000038000000000, - // 0x000000000000FF00, - // 0x0000000000000000, - // 0x0000000000000000, - }, - .attrs = - { - 0x4000400040000000, - 0x4000000000000000, - 0x0080000000000004, // lower byte is application type - 0xF0000000FFFF4000, - }, - }); + char _path[512]; + ORBIS_RET_ON_ERROR(ureadString(_path, sizeof(_path), path)); + + struct Result { + std::uint64_t authorityId; + std::uint64_t programType; + std::uint64_t programVersion; + std::uint64_t systemVersion; + char contentId[32]; + char hash[32]; + }; + + Result _result{}; + _result.authorityId = 0x1000; + _result.programType = 1; + _result.programVersion = 1; + _result.systemVersion = 1; + _result.contentId[24] = 4; + + return uwrite((ptr)result, _result); return {}; } @@ -1095,8 +1096,7 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid, case 0x232: return sysIpmiSessionRespondSync(thread, result, kid, params, paramsSz); case 0x252: - // TODO: try get message - return uwrite(result, 0x80020023); + return sysIpmiClientTryGetMessage(thread, result, kid, params, paramsSz); case 0x302: return sysIpmiSessionGetClientPid(thread, result, kid, params, paramsSz); case 0x320: @@ -1225,8 +1225,8 @@ orbis::SysResult orbis::sys_get_kernel_mem_statistics(Thread *thread /* TODO */) { return ErrorCode::NOSYS; } -orbis::SysResult -orbis::sys_get_sdk_compiled_version(Thread *thread, ptr path) { +orbis::SysResult orbis::sys_get_sdk_compiled_version(Thread *thread, + ptr path) { ORBIS_LOG_ERROR(__FUNCTION__, path); thread->retval[0] = g_context.sdkVersion; return {}; @@ -1244,8 +1244,8 @@ orbis::SysResult orbis::sys_dynlib_get_obj_member(Thread *thread, return ErrorCode::NOSYS; } -orbis::SysResult -orbis::sys_budget_get_ptype_of_budget(Thread *thread, sint budgetId) { +orbis::SysResult orbis::sys_budget_get_ptype_of_budget(Thread *thread, + sint budgetId) { ORBIS_LOG_WARNING(__FUNCTION__, budgetId); thread->retval[0] = budgetId; return {}; diff --git a/rpcsx-gpu/main.cpp b/rpcsx-gpu/main.cpp index e3a70b80..7f5cfcf5 100644 --- a/rpcsx-gpu/main.cpp +++ b/rpcsx-gpu/main.cpp @@ -92,7 +92,7 @@ int main(int argc, const char *argv[]) { } const char *cmdBridgeName = "/rpcsx-gpu-cmds"; - const char *shmName = "/rpcsx-os-memory-50001"; + const char *shmName = "/rpcsx-os-memory"; unsigned long gpuIndex = 0; auto presenter = PresenterMode::Window; bool enableValidation = false; @@ -945,25 +945,15 @@ int main(int argc, const char *argv[]) { for (auto cmd : std::span(commandsBuffer, pulledCount)) { switch (cmd.id) { case amdgpu::bridge::CommandId::ProtectMemory: - if (cmd.memoryProt.pid != 50001) { - continue; - } device.handleProtectMemory(cmd.memoryProt.address, cmd.memoryProt.size, cmd.memoryProt.prot); break; case amdgpu::bridge::CommandId::CommandBuffer: - if (cmd.memoryProt.pid != 50001) { - continue; - } device.handleCommandBuffer(cmd.commandBuffer.queue, cmd.commandBuffer.address, cmd.commandBuffer.size); break; case amdgpu::bridge::CommandId::Flip: { - if (cmd.memoryProt.pid != 50001) { - continue; - } - if (!isImageAcquired) { Verify() << vkAcquireNextImageKHR(vkDevice, swapchain, UINT64_MAX, presentCompleteSemaphore, nullptr, diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index 82505344..b43695cc 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -35,6 +35,7 @@ #include #include #include +#include static int g_gpuPid; @@ -631,36 +632,201 @@ 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); + shmDevice->open(&shm, name, flags, mode, nullptr); shm->ops->truncate(shm.get(), 4096, nullptr); } -static orbis::Ref createIpmiServer( - orbis::Process *process, const char *name, - std::function - packetHandler) { +struct IpmiServer { + orbis::Ref serverImpl; + + std::unordered_map< + std::uint32_t, + std::function> &outData, + const std::vector> &inData)>> + syncHandlers; + std::vector> messages; + + IpmiServer &createSyncHandler(std::uint32_t methodId, + std::function handler) { + syncHandlers[methodId] = + [=](std::int32_t &errorCode, std::vector> &outData, + const std::vector> &inData) + -> orbis::ErrorCode { + if (!outData.empty() || !inData.empty()) { + return orbis::ErrorCode::INVAL; + } + + errorCode = handler(); + return {}; + }; + return *this; + } + + IpmiServer &createSyncHandler( + std::uint32_t methodId, + std::function handler) { + syncHandlers[methodId] = + [=](std::int32_t &errorCode, std::vector> &outData, + const std::vector> &inData) + -> orbis::ErrorCode { + if (outData.size() != 1) { + return orbis::ErrorCode::INVAL; + } + + std::uint64_t size = outData[0].size(); + errorCode = handler(outData[0].data(), size); + outData[0] = outData[0].subspan(0, size); + return {}; + }; + return *this; + } + + template + IpmiServer &createSyncHandler( + std::uint32_t methodId, + std::function + handler) { + syncHandlers[methodId] = + [=](std::int32_t &errorCode, std::vector> &outData, + const std::vector> &inData) + -> orbis::ErrorCode { + if (outData.size() != 1 || inData.size() != 1) { + return orbis::ErrorCode::INVAL; + } + + if (inData[0].size() != sizeof(T)) { + return orbis::ErrorCode::INVAL; + } + + std::uint64_t size = outData[0].size(); + errorCode = handler(outData[0].data(), size, + *reinterpret_cast(inData[0].data())); + outData[0] = outData[0].subspan(0, size); + return {}; + }; + return *this; + } + + template + IpmiServer & + createSyncHandler(std::uint32_t methodId, + std::function handler) { + syncHandlers[methodId] = + [=](std::int32_t &errorCode, std::vector> &outData, + const std::vector> &inData) + -> orbis::ErrorCode { + if (inData.size() != 1 || !outData.empty()) { + return orbis::ErrorCode::INVAL; + } + + if (inData[0].size() != sizeof(T)) { + return orbis::ErrorCode::INVAL; + } + + errorCode = handler(*reinterpret_cast(inData[0].data())); + return {}; + }; + return *this; + } + + template IpmiServer &sendMsg(const T &data) { + std::vector message(sizeof(T)); + std::memcpy(message.data(), &data, sizeof(T)); + messages.push_back(std::move(message)); + return *this; + } + + orbis::ErrorCode handle(orbis::IpmiSession *session, + orbis::IpmiSyncMessageHeader *message) { + std::size_t inBufferOffset = 0; + auto bufLoc = std::bit_cast(message + 1); + std::vector> inData; + std::vector> outData; + for (unsigned i = 0; i < message->numInData; ++i) { + auto size = *std::bit_cast(bufLoc); + bufLoc += sizeof(orbis::uint); + inData.push_back({bufLoc, size}); + bufLoc += size; + } + + for (unsigned i = 0; i < message->numOutData; ++i) { + auto size = *std::bit_cast(bufLoc); + bufLoc += sizeof(orbis::uint); + outData.push_back({bufLoc, size}); + bufLoc += size; + } + + if (auto it = syncHandlers.find(message->methodId); + it != syncHandlers.end()) { + auto &handler = it->second; + + std::int32_t errorCode = 0; + auto result = handler(errorCode, outData, inData); + + if (outData.empty()) { + session->messageResponses.push_front({ + .errorCode = errorCode, + .data = {}, + }); + } else { + session->messageResponses.push_front({ + .errorCode = errorCode, + .data = orbis::kvector( + outData[0].data(), outData[0].data() + outData[0].size()), + }); + } + + session->responseCv.notify_one(session->mutex); + return {}; + } + + 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::lock_guard lock(session->mutex); + + session->messageResponses.push_front({ + .errorCode = 0, + .data = orbis::kvector( + message->numOutData ? outData[0].size() : 0), + }); + + session->responseCv.notify_one(session->mutex); + return {}; + } +}; + +static IpmiServer &createIpmiServer(orbis::Process *process, const char *name) { orbis::IpmiCreateServerConfig config{}; - orbis::Ref server; - orbis::ipmiCreateServer(process, nullptr, name, config, server); - std::thread{[server, packetHandler = std::move(packetHandler)] { + orbis::Ref serverImpl; + orbis::ipmiCreateServer(process, nullptr, name, config, serverImpl); + auto server = std::make_shared(); + server->serverImpl = serverImpl; + + std::thread{[server, serverImpl] { while (true) { orbis::IpmiServer::Packet packet; { - std::lock_guard lock(server->mutex); + std::lock_guard lock(serverImpl->mutex); - while (server->packets.empty()) { - server->receiveCv.wait(server->mutex); + while (serverImpl->packets.empty()) { + serverImpl->receiveCv.wait(serverImpl->mutex); } - packet = std::move(server->packets.front()); - server->packets.pop_front(); + packet = std::move(serverImpl->packets.front()); + serverImpl->packets.pop_front(); } if (packet.info.type == 1) { - std::lock_guard serverLock(server->mutex); + std::lock_guard serverLock(serverImpl->mutex); - for (auto it = server->connectionRequests.begin(); - it != server->connectionRequests.end(); ++it) { + for (auto it = serverImpl->connectionRequests.begin(); + it != serverImpl->connectionRequests.end(); ++it) { auto &conReq = *it; std::lock_guard clientLock(conReq.client->mutex); if (conReq.client->session != nullptr) { @@ -673,8 +839,13 @@ static orbis::Ref createIpmiServer( } session->client = conReq.client; - session->server = server; + session->server = serverImpl; conReq.client->session = session; + + for (auto &message : server->messages) { + conReq.client->messages.push_back(orbis::kvector(message.data(), message.data() + message.size())); + } + conReq.client->sessionCv.notify_all(conReq.client->mutex); // server->connectionRequests.erase(it); break; @@ -700,59 +871,59 @@ static orbis::Ref createIpmiServer( continue; } - packetHandler(client->session.get(), msgHeader); + server->handle(client->session.get(), msgHeader); continue; } std::fprintf(stderr, "IPMI: Unhandled packet %s::%u\n", - server->name.c_str(), packet.info.type); + serverImpl->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), - }); + return *server; +} - session->responseCv.notify_one(session->mutex); - return 0; +static void createMiniSysCoreObjects(orbis::Process *process) { + createEventFlag("SceBootStatusFlags", 0x121, 0x2408); } static void createSysAvControlObjects(orbis::Process *process) { - createIpmiServer(process, "SceAvSettingIpc", unimplementedIpmiServer); + createIpmiServer(process, "SceAvSettingIpc"); createEventFlag("SceAvSettingEvf", 0x121, 0xffff00000000); createShm("/SceAvSetting", 0xa02, 0x1a4, 4096); } +struct SceMbusIpcAddHandleByUserIdMethodArgs { + orbis::uint32_t unk; // 0 + orbis::uint32_t deviceId; + orbis::uint32_t userId; + orbis::uint32_t type; + orbis::uint32_t index; + orbis::uint32_t reserved; + orbis::uint32_t pid; +}; + +static_assert(sizeof(SceMbusIpcAddHandleByUserIdMethodArgs) == 0x1c); + +struct SceUserServiceEvent { + std::uint32_t eventType; // 0 - login, 1 - logout + std::uint32_t user; +}; + static void createSysCoreObjects(orbis::Process *process) { - createIpmiServer(process, "SceMbusIpc", unimplementedIpmiServer); - createIpmiServer(process, "SceSysCoreApp", unimplementedIpmiServer); - createIpmiServer(process, "SceSysCoreApp2", unimplementedIpmiServer); - createIpmiServer(process, "SceMDBG0SRV", unimplementedIpmiServer); + createIpmiServer(process, "SceMbusIpc") + .createSyncHandler( + 0xce110007, [](const auto &args) -> std::int32_t { + ORBIS_LOG_TODO("IPMI: SceMbusIpcAddHandleByUserId", args.unk, + args.deviceId, args.userId, args.type, args.index, + args.reserved, args.pid); + return 1; + }); + createIpmiServer(process, "SceSysCoreApp"); + createIpmiServer(process, "SceSysCoreApp2"); + createIpmiServer(process, "SceMDBG0SRV"); createSemaphore("SceSysCoreProcSpawnSema", 0x101, 0, 1); createSemaphore("SceTraceMemorySem", 0x100, 1, 1); @@ -784,52 +955,94 @@ static void createShellCoreObjects(orbis::Process *process) { 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); + createIpmiServer(process, "SceSystemLoggerService"); + createIpmiServer(process, "SceLoginMgrServer"); + createIpmiServer(process, "SceLncService") + .createSyncHandler(0x30013, + [](void *out, std::uint64_t &size) -> std::int32_t { + struct SceLncServiceAppStatus { + std::uint32_t unk0; + std::uint32_t unk1; + std::uint32_t unk2; + }; + + if (size < sizeof(SceLncServiceAppStatus)) { + return -1; + } + + *(SceLncServiceAppStatus *)out = { + .unk0 = 1, + .unk1 = 1, + .unk2 = 1, + }; + + size = sizeof(SceLncServiceAppStatus); + return 0; + }); + createIpmiServer(process, "SceAppMessaging"); + createIpmiServer(process, "SceShellCoreUtil"); + createIpmiServer(process, "SceNetCtl"); + createIpmiServer(process, "SceNpMgrIpc") + .createSyncHandler( + 0, [=](void *out, std::uint64_t &size) -> std::int32_t { + std::string_view result = "SceNpMgrEvf"; + std::strncpy((char *)out, result.data(), result.size() + 1); + size = result.size() + 1; + orbis::g_context.createEventFlag("SceNpMgrEvf", 0x200, 0); + return 0; + }); + createIpmiServer(process, "SceNpService"); + createIpmiServer(process, "SceNpTrophyIpc"); + createIpmiServer(process, "SceNpUdsIpc"); + createIpmiServer(process, "SceLibNpRifMgrIpc"); + createIpmiServer(process, "SceNpPartner001"); + createIpmiServer(process, "SceNpPartnerSubs"); + createIpmiServer(process, "SceNpGameIntent"); + createIpmiServer(process, "SceBgft"); + createIpmiServer(process, "SceCntMgrService"); + createIpmiServer(process, "ScePlayGo"); + createIpmiServer(process, "SceCompAppProxyUtil"); + createIpmiServer(process, "SceShareSpIpcService"); + createIpmiServer(process, "SceRnpsAppMgr"); + createIpmiServer(process, "SceUpdateService"); + createIpmiServer(process, "ScePatchChecker"); + createIpmiServer(process, "SceMorpheusUpdService"); + createIpmiServer(process, "ScePsmSharedDmem"); + createIpmiServer(process, "SceSaveData"); + createIpmiServer(process, "SceStickerCoreServer"); + createIpmiServer(process, "SceDbRecoveryShellCore"); + createIpmiServer(process, "SceUserService") + .sendMsg(SceUserServiceEvent{.eventType = 0, .user = 1}) + .createSyncHandler( + 0x30011, + [](void *ptr, std::uint64_t size, uint32_t data) -> std::int32_t { + ORBIS_LOG_TODO("SceUserService: get_initial_user_id"); + + if (size != sizeof(orbis::uint32_t)) { + return 0x8000'0000; + } + + *(uint32_t *)ptr = 1; + return 0; + }); + createIpmiServer(process, "SceDbPreparationServer"); + createIpmiServer(process, "SceScreenShot"); + createIpmiServer(process, "SceAppDbIpc"); + createIpmiServer(process, "SceAppInst"); + createIpmiServer(process, "SceAppContent"); + createIpmiServer(process, "SceNpEntAccess"); + createIpmiServer(process, "SceMwIPMIServer"); + createIpmiServer(process, "SceAutoMounterIpc"); + createIpmiServer(process, "SceBackupRestoreUtil"); + createIpmiServer(process, "SceDataTransfer"); + createIpmiServer(process, "SceEventService"); + createIpmiServer(process, "SceShareFactoryUtil"); + createIpmiServer(process, "SceCloudConnectManager"); + createIpmiServer(process, "SceHubAppUtil"); + createIpmiServer(process, "SceTcIPMIServer"); createSemaphore("SceLncSuspendBlock00000001", 0x101, 1, 1); - createSemaphore("SceAppMessaging00000001", 0x100, 0, 0x7fffffff); + createSemaphore("SceAppMessaging00000001", 0x100, 1, 0x7fffffff); createEventFlag("SceAutoMountUsbMass", 0x120, 0); createEventFlag("SceLoginMgrUtilityEventFlag", 0x112, 0); @@ -847,31 +1060,132 @@ static void createShellCoreObjects(orbis::Process *process) { 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("SceShellCoreUtilPowerControl", 0x120, 0x400000); + createEventFlag("SceShellCoreUtilAppFocus", 0x120, 1); + createEventFlag("SceShellCoreUtilCtrlFocus", 0x120, 0); 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("SceLncUtilAppStatus1", 0x100, 0); + createEventFlag("SceAppMessaging1", 0x120, 1); + createEventFlag("SceShellCoreUtil1", 0x120, 0x3f8c); - createEventFlag("SceLncUtilAppStatus00000001", 0x100, 0); - createEventFlag("SceAppMessaging00000001", 0x120, 0); + createSemaphore("SceAppMessaging1", 0x101, 1, 0x7fffffff); + createSemaphore("SceLncSuspendBlock1", 0x101, 1, 10000); createShm("SceGlsSharedMemory", 0x202, 0x1a4, 262144); createShm("SceShellCoreUtil", 0x202, 0x1a4, 16384); createShm("SceNpTpip", 0x202, 0x1ff, 43008); + + createShm("vmicDdShmAin", 0x202, 0x1b6, 43008); + + createSemaphore("SceNpTpip 0", 0x101, 0, 1); +} + +static orbis::SysResult launchDaemon(orbis::Thread *thread, std::string path, + std::vector argv, + std::vector envv) { + auto childPid = orbis::g_context.allocatePid() * 10000 + 1; + auto flag = orbis::knew>(); + *flag = false; + + int hostPid = ::fork(); + + if (hostPid) { + while (*flag == false) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + orbis::kfree(flag, sizeof(*flag)); + return {}; + } + + auto process = orbis::g_context.createProcess(childPid); + auto logFd = ::open(("log-" + std::to_string(childPid) + ".txt").c_str(), + O_CREAT | O_TRUNC | O_WRONLY, 0666); + + dup2(logFd, 1); + dup2(logFd, 2); + + process->sysent = thread->tproc->sysent; + process->onSysEnter = thread->tproc->onSysEnter; + process->onSysExit = thread->tproc->onSysExit; + process->ops = thread->tproc->ops; + process->parentProcess = thread->tproc; + process->appInfo = { + .unk4 = orbis::slong(0x80000000'00000000), + }; + + process->authInfo = { + .unk0 = 0x3100000000000001, + .caps = + { + -1ul, + -1ul, + -1ul, + -1ul, + }, + .attrs = + { + 0x4000400040000000, + 0x4000000000000000, + 0x0080000000000002, + 0xF0000000FFFF4000, + }, + }; + process->budgetId = 0; + process->isInSandbox = false; + + rx::vm::fork(childPid); + rx::vfs::fork(); + + *flag = true; + + auto [baseId, newThread] = process->threadsMap.emplace(); + newThread->tproc = process; + newThread->tid = process->pid + baseId; + newThread->state = orbis::ThreadState::RUNNING; + newThread->context = thread->context; + newThread->fsBase = thread->fsBase; + + orbis::g_currentThread = newThread; + thread = orbis::g_currentThread; + + setupSigHandlers(); + rx::thread::initialize(); + rx::thread::setupThisThread(); + + ORBIS_LOG_ERROR(__FUNCTION__, path); + + { + orbis::Ref file; + auto result = rx::vfs::open(path, kOpenFlagReadOnly, 0, &file, thread); + if (result.isError()) { + return result; + } + } + + rx::vm::reset(); + + thread->tproc->nextTlsSlot = 1; + auto executableModule = rx::linker::loadModuleFile(path, thread); + + executableModule->id = thread->tproc->modulesMap.insert(executableModule); + thread->tproc->processParam = executableModule->processParam; + thread->tproc->processParamSize = executableModule->processParamSize; + + thread->tproc->event.emit(orbis::kEvFiltProc, orbis::kNoteExec); + + std::thread([&] { + rx::thread::setupSignalStack(); + rx::thread::setupThisThread(); + ps4Exec(thread, executableModule, argv, envv); + }).join(); + std::abort(); } int main(int argc, const char *argv[]) { @@ -1055,6 +1369,7 @@ int main(int argc, const char *argv[]) { }; if (isSystem) { + amdgpu::bridge::expGpuPid = 50001; initProcess->authInfo = { .unk0 = 0x3100000000000001, .caps = @@ -1075,6 +1390,7 @@ int main(int argc, const char *argv[]) { initProcess->budgetId = 0; initProcess->isInSandbox = false; } else { + amdgpu::bridge::expGpuPid = initProcess->pid; initProcess->authInfo = { .unk0 = 0x3100000000000001, .caps = @@ -1126,10 +1442,14 @@ int main(int argc, const char *argv[]) { ps4InitFd(mainThread); if (!isSystem) { + createMiniSysCoreObjects(initProcess); createSysAvControlObjects(initProcess); createSysCoreObjects(initProcess); createGnmCompositorObjects(initProcess); createShellCoreObjects(initProcess); + + launchDaemon(mainThread, "/system/sys/orbis_audiod.elf", + {"/system/sys/orbis_audiod.elf"}, {}); } std::vector ps4Argv(argv + argIndex, diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index c3edd9ce..ada8f23a 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -834,7 +834,6 @@ SysResult execve(Thread *thread, ptr fname, ptr> argv, std::thread([&] { rx::thread::setupSignalStack(); rx::thread::setupThisThread(); - ORBIS_LOG_ERROR(__FUNCTION__, "exec"); ps4Exec(thread, executableModule, _argv, _envv); }).join(); std::abort();