diff --git a/CMakeLists.txt b/CMakeLists.txt index 0466a643..d69da150 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,8 @@ set(SERVICE_SOURCE_FILES src/core/services/service_manager.cpp src/core/services src/core/services/fs.cpp src/core/services/gsp_gpu.cpp src/core/services/gsp_lcd.cpp src/core/services/ndm.cpp src/core/services/dsp.cpp src/core/services/cfg.cpp src/core/services/ptm.cpp src/core/services/mic.cpp src/core/services/cecd.cpp - src/core/services/ac.cpp src/core/services/boss.cpp src/core/services/frd.cpp + src/core/services/ac.cpp src/core/services/am.cpp src/core/services/boss.cpp + src/core/services/frd.cpp src/core/services/nim.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 @@ -82,7 +83,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp inc include/fs/archive_save_data.hpp include/fs/archive_sdmc.hpp include/services/ptm.hpp include/services/mic.hpp include/services/cecd.hpp include/renderer_gl/renderer_gl.hpp include/renderer_gl/surfaces.hpp include/renderer_gl/surface_cache.hpp include/services/ac.hpp - include/services/boss.hpp include/services/frd.hpp + include/services/am.hpp include/services/boss.hpp include/services/frd.hpp include/services/nim.hpp ) set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index 7735cacf..947f6589 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -10,7 +10,8 @@ namespace KernelHandles { // Hardcoded handles CurrentThread = 0xFFFF8000, // Used by the original kernel CurrentProcess = 0xFFFF8001, // Used by the original kernel - AC, // Something network related + AC, // Something network related + AM, // Application manager APT, // App Title something service? BOSS, // Streetpass stuff? CECD, // More Streetpass stuff? @@ -22,6 +23,7 @@ namespace KernelHandles { DSP, // DSP service (Used for audio decoding and output) LCD, // LCD service (Used for configuring the displays) MIC, // MIC service (Controls the microphone) + NIM, // Updates, DLC, etc NDM, // ????? PTM, // PTM service (Used for accessing various console info, such as battery, shell and pedometer state) diff --git a/include/logger.hpp b/include/logger.hpp index 8d6b406a..655a83ce 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -29,6 +29,7 @@ namespace Log { // Service loggers static Logger acLogger; + static Logger amLogger; static Logger aptLogger; static Logger bossLogger; static Logger cecdLogger; @@ -40,6 +41,7 @@ namespace Log { static Logger gspGPULogger; static Logger gspLCDLogger; static Logger micLogger; + static Logger nimLogger; static Logger ndmLogger; static Logger ptmLogger; static Logger srvLogger; diff --git a/include/services/am.hpp b/include/services/am.hpp new file mode 100644 index 00000000..e406b2ef --- /dev/null +++ b/include/services/am.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "helpers.hpp" +#include "kernel_types.hpp" +#include "logger.hpp" +#include "memory.hpp" + +class AMService { + Handle handle = KernelHandles::AM; + Memory& mem; + MAKE_LOG_FUNCTION(log, amLogger) + + // Service commands + void listTitleInfo(u32 messagePointer); + +public: + AMService(Memory& mem) : mem(mem) {} + void reset(); + void handleSyncRequest(u32 messagePointer); +}; \ No newline at end of file diff --git a/include/services/nim.hpp b/include/services/nim.hpp new file mode 100644 index 00000000..6d45b837 --- /dev/null +++ b/include/services/nim.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "helpers.hpp" +#include "kernel_types.hpp" +#include "logger.hpp" +#include "memory.hpp" + +class NIMService { + Handle handle = KernelHandles::NIM; + Memory& mem; + MAKE_LOG_FUNCTION(log, nimLogger) + + // Service commands + void initialize(u32 messagePointer); + +public: + NIMService(Memory& mem) : mem(mem) {} + 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 261ef9e8..a072b88a 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -5,6 +5,7 @@ #include "logger.hpp" #include "memory.hpp" #include "services/ac.hpp" +#include "services/am.hpp" #include "services/apt.hpp" #include "services/boss.hpp" #include "services/cecd.hpp" @@ -16,6 +17,7 @@ #include "services/gsp_gpu.hpp" #include "services/gsp_lcd.hpp" #include "services/mic.hpp" +#include "services/nim.hpp" #include "services/ndm.hpp" #include "services/ptm.hpp" @@ -32,6 +34,7 @@ class ServiceManager { MAKE_LOG_FUNCTION(log, srvLogger) ACService ac; + AMService am; APTService apt; BOSSService boss; CECDService cecd; @@ -43,6 +46,7 @@ class ServiceManager { GPUService gsp_gpu; LCDService gsp_lcd; MICService mic; + NIMService nim; NDMService ndm; PTMService ptm; diff --git a/src/core/services/am.cpp b/src/core/services/am.cpp new file mode 100644 index 00000000..5771f598 --- /dev/null +++ b/src/core/services/am.cpp @@ -0,0 +1,43 @@ +#include "services/am.hpp" + +namespace AMCommands { + enum : u32 { + ListTitleInfo = 0x10070102 + }; +} + +namespace Result { + enum : u32 { + Success = 0, + }; +} + +void AMService::reset() {} + +void AMService::handleSyncRequest(u32 messagePointer) { + const u32 command = mem.read32(messagePointer); + switch (command) { + case AMCommands::ListTitleInfo: listTitleInfo(messagePointer); break; + default: Helpers::panic("AM service requested. Command: %08X\n", command); + } +} + +void AMService::listTitleInfo(u32 messagePointer) { + log("AM::ListDLCOrLicenseTicketInfos\n"); // Yes this is the actual name + u32 ticketCount = mem.read32(messagePointer + 4); + u64 titleID = mem.read64(messagePointer + 8); + u32 pointer = mem.read32(messagePointer + 24); + + for (u32 i = 0; i < ticketCount; i++) { + mem.write64(pointer, titleID); // Title ID + mem.write64(pointer + 8, 0); // Ticket ID + mem.write16(pointer + 16, 0); // Version + mem.write16(pointer + 18, 0); // Padding + mem.write32(pointer + 20, 0); // Size + + pointer += 24; // = sizeof(TicketInfo) + } + + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, ticketCount); +} \ No newline at end of file diff --git a/src/core/services/nim.cpp b/src/core/services/nim.cpp new file mode 100644 index 00000000..a3c48fb4 --- /dev/null +++ b/src/core/services/nim.cpp @@ -0,0 +1,28 @@ +#include "services/nim.hpp" + +namespace NIMCommands { + enum : u32 { + Initialize = 0x00210000 + }; +} + +namespace Result { + enum : u32 { + Success = 0, + }; +} + +void NIMService::reset() {} + +void NIMService::handleSyncRequest(u32 messagePointer) { + const u32 command = mem.read32(messagePointer); + switch (command) { + case NIMCommands::Initialize: initialize(messagePointer); break; + default: Helpers::panic("NIM service requested. Command: %08X\n", command); + } +} + +void NIMService::initialize(u32 messagePointer) { + log("NIM::Initialize\n"); + 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 c9ec66b7..c960f461 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -2,24 +2,28 @@ #include "kernel.hpp" ServiceManager::ServiceManager(std::array& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel) - : regs(regs), mem(mem), kernel(kernel), ac(mem), boss(mem), apt(mem, kernel), cecd(mem), cfg(mem), dsp(mem), - hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, currentPID), gsp_lcd(mem), mic(mem), ndm(mem), ptm(mem) {} + : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), apt(mem, kernel), cecd(mem), cfg(mem), + dsp(mem), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, currentPID), gsp_lcd(mem), mic(mem), + nim(mem), ndm(mem), ptm(mem) {} static constexpr int MAX_NOTIFICATION_COUNT = 16; +// Reset every single service void ServiceManager::reset() { - ac.reset(); + ac.reset(); + am.reset(); apt.reset(); - boss.reset(); + boss.reset(); cecd.reset(); cfg.reset(); dsp.reset(); hid.reset(); - frd.reset(); + frd.reset(); fs.reset(); gsp_gpu.reset(); gsp_lcd.reset(); mic.reset(); + nim.reset(); ndm.reset(); ptm.reset(); @@ -85,6 +89,8 @@ void ServiceManager::getServiceHandle(u32 messagePointer) { if (service == "ac:u") { handle = KernelHandles::AC; + } else if (service == "am:app") { + handle = KernelHandles::AM; } else if (service == "APT:S") { // TODO: APT:A, APT:S and APT:U are slightly different handle = KernelHandles::APT; } else if (service == "APT:A") { @@ -113,6 +119,8 @@ void ServiceManager::getServiceHandle(u32 messagePointer) { handle = KernelHandles::MIC; } else if (service == "ndm:u") { handle = KernelHandles::NDM; + } else if (service == "nim:aoc") { + handle = KernelHandles::NIM; } else if (service == "ptm:u") { handle = KernelHandles::PTM; } else { @@ -154,6 +162,7 @@ void ServiceManager::subscribe(u32 messagePointer) { void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { switch (handle) { case KernelHandles::AC: ac.handleSyncRequest(messagePointer); break; + case KernelHandles::AM: am.handleSyncRequest(messagePointer); break; case KernelHandles::APT: apt.handleSyncRequest(messagePointer); break; case KernelHandles::BOSS: boss.handleSyncRequest(messagePointer); break; case KernelHandles::CECD: cecd.handleSyncRequest(messagePointer); break; @@ -165,6 +174,7 @@ void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { case KernelHandles::GPU: [[likely]] gsp_gpu.handleSyncRequest(messagePointer); break; case KernelHandles::LCD: gsp_lcd.handleSyncRequest(messagePointer); break; case KernelHandles::MIC: mic.handleSyncRequest(messagePointer); break; + case KernelHandles::NIM: nim.handleSyncRequest(messagePointer); break; case KernelHandles::NDM: ndm.handleSyncRequest(messagePointer); break; case KernelHandles::PTM: ptm.handleSyncRequest(messagePointer); break; default: Helpers::panic("Sent IPC message to unknown service %08X\n Command: %08X", handle, mem.read32(messagePointer));