From 1078253f6c27bbc44395652ea03a7bfc253c945c Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Tue, 21 Mar 2023 22:34:29 +0200 Subject: [PATCH] [APT/CFG/Kernel] Smash Bros stuff --- include/memory.hpp | 2 ++ include/services/apt.hpp | 7 +++++++ src/core/kernel/kernel.cpp | 7 +++++++ src/core/services/apt.cpp | 22 +++++++++++++--------- src/core/services/cfg.cpp | 3 +++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/include/memory.hpp b/include/memory.hpp index c10e0649..b15cac62 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -235,4 +235,6 @@ public: u8* getDSPMem() { return dspRam; } u8* getDSPDataMem() { return &dspRam[DSP_DATA_MEMORY_OFFSET]; } u8* getDSPCodeMem() { return &dspRam[DSP_CODE_MEMORY_OFFSET]; } + + u32 getUsedUserMem() { return usedUserMemory; } }; \ No newline at end of file diff --git a/include/services/apt.hpp b/include/services/apt.hpp index 255699ef..a3c703d3 100644 --- a/include/services/apt.hpp +++ b/include/services/apt.hpp @@ -8,6 +8,10 @@ // Yay, more circular dependencies class Kernel; +enum class ConsoleModel : u32 { + Old3DS, New3DS +}; + class APTService { Handle handle = KernelHandles::APT; Memory& mem; @@ -17,6 +21,8 @@ class APTService { std::optional notificationEvent = std::nullopt; std::optional resumeEvent = std::nullopt; + ConsoleModel model = ConsoleModel::Old3DS; + MAKE_LOG_FUNCTION(log, aptLogger) // Service commands @@ -34,6 +40,7 @@ class APTService { void replySleepQuery(u32 messagePointer); void setApplicationCpuTimeLimit(u32 messagePointer); void setScreencapPostPermission(u32 messagePointer); + void theSmashBrosFunction(u32 messagePointer); // Percentage of the syscore available to the application, between 5% and 89% u32 cpuTimeLimit; diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index 82a59fbe..f22ab051 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -194,6 +194,13 @@ void Kernel::getProcessInfo() { } switch (type) { + // According to 3DBrew: Amount of private (code, data, heap) memory used by the process + total supervisor-mode + // stack size + page-rounded size of the external handle table + case 2: + regs[1] = mem.getUsedUserMem(); + regs[2] = 0; + break; + case 20: // Returns 0x20000000 - regs[1] = PhysicalAddrs::FCRAM - mem.getLinearHeapVaddr(); regs[2] = 0; diff --git a/src/core/services/apt.cpp b/src/core/services/apt.cpp index e650a3b2..3aa0bae7 100644 --- a/src/core/services/apt.cpp +++ b/src/core/services/apt.cpp @@ -16,14 +16,8 @@ namespace APTCommands { GetApplicationCpuTimeLimit = 0x00500040, SetScreencapPostPermission = 0x00550040, CheckNew3DSApp = 0x01010000, - CheckNew3DS = 0x01020000 - }; -} - -namespace Model { - enum : u8 { - Old3DS = 0, - New3DS = 1 + CheckNew3DS = 0x01020000, + TheSmashBrosFunction = 0x01030000 }; } @@ -61,6 +55,7 @@ void APTService::handleSyncRequest(u32 messagePointer) { case APTCommands::ReplySleepQuery: replySleepQuery(messagePointer); break; case APTCommands::SetApplicationCpuTimeLimit: setApplicationCpuTimeLimit(messagePointer); break; case APTCommands::SetScreencapPostPermission: setScreencapPostPermission(messagePointer); break; + case APTCommands::TheSmashBrosFunction: theSmashBrosFunction(messagePointer); break; default: Helpers::panic("APT service requested. Command: %08X\n", command); } } @@ -79,7 +74,7 @@ void APTService::appletUtility(u32 messagePointer) { void APTService::checkNew3DS(u32 messagePointer) { log("APT::CheckNew3DS\n"); mem.write32(messagePointer + 4, Result::Success); - mem.write8(messagePointer + 8, Model::Old3DS); // u8, Status (0 = Old 3DS, 1 = New 3DS) + mem.write8(messagePointer + 8, (model == ConsoleModel::New3DS) ? 1 : 0); // u8, Status (0 = Old 3DS, 1 = New 3DS) } // TODO: Figure out the slight way this differs from APT::CheckNew3DS @@ -193,4 +188,13 @@ void APTService::getSharedFont(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); mem.write32(messagePointer + 8, fontVaddr); mem.write32(messagePointer + 16, KernelHandles::FontSharedMemHandle); +} + +// This function is entirely undocumented. We know Smash Bros uses it and that it normally writes 2 to cmdreply[2] on New 3DS +// And that writing 1 stops it from accessing the ir:USER service for New 3DS HID use +void APTService::theSmashBrosFunction(u32 messagePointer) { + log("APT: Called the elusive Smash Bros function\n"); + + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, (model == ConsoleModel::New3DS) ? 2 : 1); } \ No newline at end of file diff --git a/src/core/services/cfg.cpp b/src/core/services/cfg.cpp index d064cd4f..48496a78 100644 --- a/src/core/services/cfg.cpp +++ b/src/core/services/cfg.cpp @@ -87,6 +87,9 @@ void CFGService::getConfigInfoBlk2(u32 messagePointer) { } else if (size == 4 && blockID == 0xB0003) { // Coordinates (latidude and longtitude) as s16 mem.write16(output, 0); // Latitude mem.write16(output + 2, 0); // Longtitude + } else if (size == 2 && blockID == 0xA0001) { // Birthday + mem.write8(output, 5); // Month (May) + mem.write8(output + 1, 5); // Day (Fifth) } else if (size == 8 && blockID == 0x30001) { // User time offset printf("Read from user time offset field in NAND. TODO: What is this\n"); mem.write64(output, 0);