diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f72ff16..55b8760b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,7 @@ set(SERVICE_SOURCE_FILES src/core/services/service_manager.cpp src/core/services src/core/services/act.cpp src/core/services/nfc.cpp src/core/services/dlp_srvr.cpp src/core/services/ir_user.cpp src/core/services/http.cpp src/core/services/soc.cpp src/core/services/ssl.cpp src/core/services/news_u.cpp src/core/services/amiibo_device.cpp - src/core/services/csnd.cpp + src/core/services/csnd.cpp src/core/services/nwm_uds.cpp ) set(PICA_SOURCE_FILES src/core/PICA/gpu.cpp src/core/PICA/regs.cpp src/core/PICA/shader_unit.cpp src/core/PICA/shader_interpreter.cpp src/core/PICA/dynapica/shader_rec.cpp @@ -182,7 +182,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp include/fs/romfs.hpp include/fs/ivfc.hpp include/discord_rpc.hpp include/services/http.hpp include/result/result_cfg.hpp include/applets/applet.hpp include/applets/mii_selector.hpp include/math_util.hpp include/services/soc.hpp include/services/news_u.hpp include/applets/software_keyboard.hpp include/applets/applet_manager.hpp include/fs/archive_user_save_data.hpp - include/services/amiibo_device.hpp include/services/nfc_types.hpp include/swap.hpp include/services/csnd.hpp + include/services/amiibo_device.hpp include/services/nfc_types.hpp include/swap.hpp include/services/csnd.hpp include/services/nwm_uds.hpp ) cmrc_add_resource_library( diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index 4d7adcf0..749534b8 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -35,6 +35,7 @@ namespace KernelHandles { NFC, // NFC (Duh), used for Amiibo NIM, // Updates, DLC, etc NDM, // ????? + NWM_UDS, // Local multiplayer NEWS_U, // This service literally has 1 command (AddNotification) and I don't even understand what it does PTM, // PTM service (Used for accessing various console info, such as battery, shell and pedometer state) SOC, // Socket service @@ -90,6 +91,7 @@ namespace KernelHandles { case MIC: return "MIC"; case NDM: return "NDM"; case NEWS_U: return "NEWS_U"; + case NWM_UDS: return "nwm::UDS"; case NFC: return "NFC"; case NIM: return "NIM"; case PTM: return "PTM"; diff --git a/include/services/nwm_uds.hpp b/include/services/nwm_uds.hpp new file mode 100644 index 00000000..bf116bcf --- /dev/null +++ b/include/services/nwm_uds.hpp @@ -0,0 +1,28 @@ +#pragma once +#include + +#include "helpers.hpp" +#include "kernel_types.hpp" +#include "logger.hpp" +#include "memory.hpp" + +// More circular dependencies +class Kernel; + +class NwmUdsService { + Handle handle = KernelHandles::NWM_UDS; + Memory& mem; + Kernel& kernel; + MAKE_LOG_FUNCTION(log, nwmUdsLogger) + + bool initialized = false; + std::optional eventHandle = std::nullopt; + + // Service commands + void initializeWithVersion(u32 messagePointer); + + public: + NwmUdsService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {} + void reset(); + void handleSyncRequest(u32 messagePointer); +}; \ No newline at end of file diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 855585e8..5d1b37ce 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -28,6 +28,7 @@ #include "services/mcu/mcu_hwc.hpp" #include "services/mic.hpp" #include "services/ndm.hpp" +#include "services/nwm_uds.hpp" #include "services/news_u.hpp" #include "services/nfc.hpp" #include "services/nim.hpp" @@ -72,6 +73,7 @@ class ServiceManager { NDMService ndm; NewsUService news_u; NFCService nfc; + NwmUdsService nwm_uds; NIMService nim; PTMService ptm; SOCService soc; diff --git a/src/core/services/cfg.cpp b/src/core/services/cfg.cpp index bcb095ca..dd133a3f 100644 --- a/src/core/services/cfg.cpp +++ b/src/core/services/cfg.cpp @@ -121,6 +121,8 @@ void CFGService::getConfigInfoBlk2(u32 messagePointer) { } } else if (size == 4 && blockID == 0x170000) { // Miiverse access key mem.write32(output, 0); + } else if (size == 8 && blockID == 0x00090000) { + mem.write64(output, 0); // Some sort of key used with nwm::UDS::InitializeWithVersion } else { Helpers::panic("Unhandled GetConfigInfoBlk2 configuration. Size = %d, block = %X", size, blockID); } diff --git a/src/core/services/nwm_uds.cpp b/src/core/services/nwm_uds.cpp new file mode 100644 index 00000000..c9af393b --- /dev/null +++ b/src/core/services/nwm_uds.cpp @@ -0,0 +1,43 @@ +#include "ipc.hpp" +#include "kernel.hpp" +#include "result/result.hpp" +#include "services/nwm_uds.hpp" + +namespace NWMCommands { + enum : u32 { + InitializeWithVersion = 0x001B0302, + }; +} + +void NwmUdsService::reset() { + eventHandle = std::nullopt; + initialized = false; +} + +void NwmUdsService::handleSyncRequest(u32 messagePointer) { + const u32 command = mem.read32(messagePointer); + + switch (command) { + case NWMCommands::InitializeWithVersion: initializeWithVersion(messagePointer); break; + default: Helpers::panic("LCD service requested. Command: %08X\n", command); + } +} + +void NwmUdsService::initializeWithVersion(u32 messagePointer) { + Helpers::warn("Initializing NWM::UDS (Local multiplayer, unimplemented)\n"); + log("NWM::UDS::InitializeWithVersion\n"); + + if (!eventHandle.has_value()) { + eventHandle = kernel.makeEvent(ResetType::OneShot); + } + + if (initialized) { + printf("NWM::UDS initialized twice\n"); + } + + initialized = true; + + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, 0); + mem.write32(messagePointer + 12, eventHandle.value()); +} \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 52cadb9e..0fbcdac4 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -9,7 +9,7 @@ ServiceManager::ServiceManager(std::span regs, Memory& mem, GPU& gpu, u : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel), cfg(mem), csnd(mem, kernel), dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), http(mem), ir_user(mem, kernel), frd(mem), fs(mem, kernel, config), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mcu_hwc(mem, config), mic(mem, kernel), nfc(mem, kernel), nim(mem), ndm(mem), - news_u(mem), ptm(mem, config), soc(mem), ssl(mem), y2r(mem, kernel) {} + news_u(mem), nwm_uds(mem, kernel), ptm(mem, config), soc(mem), ssl(mem), y2r(mem, kernel) {} static constexpr int MAX_NOTIFICATION_COUNT = 16; @@ -121,12 +121,13 @@ static std::map serviceMap = { { "ndm:u", KernelHandles::NDM }, { "news:u", KernelHandles::NEWS_U }, { "nfc:u", KernelHandles::NFC }, + { "nwm::UDS", KernelHandles::NWM_UDS }, { "nim:aoc", KernelHandles::NIM }, { "ptm:u", KernelHandles::PTM }, // TODO: ptm:u and ptm:sysm have very different command sets { "ptm:sysm", KernelHandles::PTM }, { "soc:U", KernelHandles::SOC }, { "ssl:C", KernelHandles::SSL }, - { "y2r:u", KernelHandles::Y2R } + { "y2r:u", KernelHandles::Y2R }, }; // clang-format on @@ -219,6 +220,7 @@ void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { case KernelHandles::NIM: nim.handleSyncRequest(messagePointer); break; case KernelHandles::NDM: ndm.handleSyncRequest(messagePointer); break; case KernelHandles::NEWS_U: news_u.handleSyncRequest(messagePointer); break; + case KernelHandles::NWM_UDS: nwm_uds.handleSyncRequest(messagePointer); break; case KernelHandles::PTM: ptm.handleSyncRequest(messagePointer); break; case KernelHandles::SOC: soc.handleSyncRequest(messagePointer); break; case KernelHandles::SSL: ssl.handleSyncRequest(messagePointer); break;