From b83526378edca4cf22ea853d592b7f185acb092c Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:13:20 +0300 Subject: [PATCH] [IR:USER] Some more stubbing --- include/services/ir_user.hpp | 15 +++++- src/core/services/ir_user.cpp | 69 +++++++++++++++++++++++++-- src/core/services/service_manager.cpp | 7 ++- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/include/services/ir_user.hpp b/include/services/ir_user.hpp index 734bec44..2c7b1559 100644 --- a/include/services/ir_user.hpp +++ b/include/services/ir_user.hpp @@ -1,19 +1,32 @@ #pragma once +#include + #include "helpers.hpp" #include "kernel_types.hpp" #include "logger.hpp" #include "memory.hpp" #include "result/result.hpp" +// Circular dependencies in this project? Never +class Kernel; + class IRUserService { Handle handle = KernelHandles::IR_USER; Memory& mem; + Kernel& kernel; MAKE_LOG_FUNCTION(log, irUserLogger) // Service commands + void disconnect(u32 messagePointer); + void finalizeIrnop(u32 messagePointer); + void getConnectionStatusEvent(u32 messagePointer); + void initializeIrnopShared(u32 messagePointer); + void requireConnection(u32 messagePointer); + + std::optional connectionStatusEvent = std::nullopt; public: - IRUserService(Memory& mem) : mem(mem) {} + IRUserService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} void reset(); void handleSyncRequest(u32 messagePointer); }; \ No newline at end of file diff --git a/src/core/services/ir_user.cpp b/src/core/services/ir_user.cpp index 6a1a9c11..c8573182 100644 --- a/src/core/services/ir_user.cpp +++ b/src/core/services/ir_user.cpp @@ -1,15 +1,78 @@ -#include "ipc.hpp" #include "services/ir_user.hpp" +#include "ipc.hpp" +#include "kernel.hpp" + namespace IRUserCommands { - enum : u32 {}; + enum : u32 { + FinalizeIrnop = 0x00020000, + RequireConnection = 0x00060040, + Disconnect = 0x00090000, + GetConnectionStatusEvent = 0x000C0000, + InitializeIrnopShared = 0x00180182 + }; } -void IRUserService::reset() {} +void IRUserService::reset() { connectionStatusEvent = std::nullopt; } void IRUserService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { + case IRUserCommands::Disconnect: disconnect(messagePointer); break; + case IRUserCommands::FinalizeIrnop: finalizeIrnop(messagePointer); break; + case IRUserCommands::GetConnectionStatusEvent: getConnectionStatusEvent(messagePointer); break; + case IRUserCommands::InitializeIrnopShared: initializeIrnopShared(messagePointer); break; + case IRUserCommands::RequireConnection: requireConnection(messagePointer); break; default: Helpers::panic("ir:USER service requested. Command: %08X\n", command); } +} + +void IRUserService::initializeIrnopShared(u32 messagePointer) { + const u32 sharedMemSize = mem.read32(messagePointer + 4); + const u32 receiveBufferSize = mem.read32(messagePointer + 8); + const u32 receiveBufferPackageCount = mem.read32(messagePointer + 12); + const u32 sendBufferSize = mem.read32(messagePointer + 16); + const u32 sendBufferPackageCount = mem.read32(messagePointer + 20); + const u32 bitrate = mem.read32(messagePointer + 24); + const u32 descriptor = mem.read32(messagePointer + 28); + const u32 sharedMemHandle = mem.read32(messagePointer + 32); + + log("IR:USER: InitializeIrnopShared (shared mem size = %08X, sharedMemHandle = %X) (stubbed)\n", sharedMemSize, sharedMemHandle); + mem.write32(messagePointer, IPC::responseHeader(0x18, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} + +void IRUserService::finalizeIrnop(u32 messagePointer) { + log("IR:USER: FinalizeIrnop\n"); + + // This should disconnect any connected device de-initialize the shared memory + mem.write32(messagePointer, IPC::responseHeader(0x2, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} + +void IRUserService::getConnectionStatusEvent(u32 messagePointer) { + log("IR:USER: GetConnectionStatusEvent\n"); + + if (!connectionStatusEvent.has_value()) { + connectionStatusEvent = kernel.makeEvent(ResetType::OneShot); + } + + mem.write32(messagePointer, IPC::responseHeader(0xC, 1, 2)); + mem.write32(messagePointer + 4, Result::Success); + // TOOD: Descriptor here + mem.write32(messagePointer + 12, connectionStatusEvent.value()); +} + +void IRUserService::requireConnection(u32 messagePointer) { + const u8 deviceID = mem.read8(messagePointer + 4); + log("IR:USER: RequireConnection (device: %d)\n", deviceID); + + mem.write32(messagePointer, IPC::responseHeader(0x6, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} + +void IRUserService::disconnect(u32 messagePointer) { + log("IR:USER: Disconnect\n"); + mem.write32(messagePointer, IPC::responseHeader(0x9, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); } \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 6ac2478b..17fdf1da 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -6,10 +6,9 @@ #include "kernel.hpp" ServiceManager::ServiceManager(std::span regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel) - : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem), - cecd(mem, kernel), cfg(mem), dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), ir_user(mem), frd(mem), fs(mem, kernel), - gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), - ptm(mem), y2r(mem, kernel) {} + : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem), cecd(mem, kernel), cfg(mem), + dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), ir_user(mem, kernel), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, kernel, currentPID), + gsp_lcd(mem), ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {} static constexpr int MAX_NOTIFICATION_COUNT = 16;