From e2b82997ba89af3d114ed2ff221cbc36621d19bb Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:37:51 +0300 Subject: [PATCH 1/3] Add ConfigMem FIRM stuff and GetSystemInfo modes for DDLC --- include/kernel/config_mem.hpp | 7 +++++++ include/memory.hpp | 13 +++++++++++++ src/core/kernel/kernel.cpp | 17 +++++++++++++++++ src/core/memory.cpp | 8 ++++++++ 4 files changed, 45 insertions(+) diff --git a/include/kernel/config_mem.hpp b/include/kernel/config_mem.hpp index 062eb551..71f46390 100644 --- a/include/kernel/config_mem.hpp +++ b/include/kernel/config_mem.hpp @@ -9,6 +9,13 @@ namespace ConfigMem { SyscoreVer = 0x1FF80010, EnvInfo = 0x1FF80014, AppMemAlloc = 0x1FF80040, + FirmUnknown = 0x1FF80060, + FirmRevision = 0x1FF80061, + FirmVersionMinor = 0x1FF80062, + FirmVersionMajor = 0x1FF80063, + FirmSyscoreVer = 0x1FF80064, + FirmSdkVer = 0x1FF80068, + HardwareType = 0x1FF81004, Datetime0 = 0x1FF81020, WifiMac = 0x1FF81060, diff --git a/include/memory.hpp b/include/memory.hpp index 6f33d895..9c3f0cea 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -139,6 +139,19 @@ private: // Report a retail unit without JTAG static constexpr u32 envInfo = 1; + // Stored in Configuration Memory starting @ 0x1FF80060 + struct FirmwareInfo { + u8 unk; // Usually 0 according to 3DBrew + u8 revision; + u8 minor; + u8 major; + u32 syscoreVer; + u32 sdkVer; + }; + + // Values taken from 3DBrew and Citra + static constexpr FirmwareInfo firm{.unk = 0, .revision = 0, .minor = 0x34, .major = 2, .syscoreVer = 2, .sdkVer = 0x0000F297}; + public: u16 kernelVersion = 0; u32 usedUserMemory = u32(0_MB); // How much of the APPLICATION FCRAM range is used (allocated to the appcore) diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index a3aad0fd..6f3cf081 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -258,6 +258,7 @@ void Kernel::duplicateHandle() { namespace SystemInfoType { enum : u32 { + MemoryInformation = 0, // Gets information related to Citra (We don't implement this, we just report this emulator is not Citra) CitraInformation = 0x20000, // Gets information related to this emulator @@ -294,6 +295,22 @@ void Kernel::getSystemInfo() { regs[0] = Result::Success; switch (infoType) { + case SystemInfoType::MemoryInformation: { + switch (subtype) { + // Total used memory size in the APPLICATION memory region + case 1: + regs[1] = mem.getUsedUserMem(); + regs[2] = 0; + break; + + default: + Helpers::panic("GetSystemInfo: Unknown MemoryInformation subtype %x\n", subtype); + regs[0] = Result::FailurePlaceholder; + break; + } + break; + } + case SystemInfoType::CitraInformation: { switch (subtype) { case CitraInfoType::IsCitra: diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3b987507..d37f2eea 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -91,6 +91,12 @@ u8 Memory::read8(u32 vaddr) { case ConfigMem::NetworkState: return 2; // Report that we've got an internet connection case ConfigMem::HeadphonesConnectedMaybe: return 0; case ConfigMem::Unknown1086: return 1; // It's unknown what this is but some games want it to be 1 + + case ConfigMem::FirmUnknown: return firm.unk; + case ConfigMem::FirmRevision: return firm.revision; + case ConfigMem::FirmVersionMinor: return firm.minor; + case ConfigMem::FirmVersionMajor: return firm.major; + default: Helpers::panic("Unimplemented 8-bit read, addr: %08X", vaddr); } } @@ -138,6 +144,8 @@ u32 Memory::read32(u32 vaddr) { // 3D slider. Float in range 0.0 = off, 1.0 = max. case ConfigMem::SliderState3D: return Helpers::bit_cast(0.0f); + case ConfigMem::FirmUnknown: + return u32(read8(vaddr)) | (u32(read8(vaddr + 1)) << 8) | (u32(read8(vaddr + 2)) << 16) | (u32(read8(vaddr + 3)) << 24); default: if (vaddr >= VirtualAddrs::VramStart && vaddr < VirtualAddrs::VramStart + VirtualAddrs::VramSize) { From 3f29eb5f6cb212855a3d7c2380b1ea1de570acb3 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:42:18 +0300 Subject: [PATCH 2/3] Stub FS::ControlArchive mode 1 --- src/core/services/fs.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 7b64b234..c5b69c0e 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -499,6 +499,12 @@ void FSService::controlArchive(u32 messagePointer) { case 0: // Commit save data changes. Shouldn't need us to do anything mem.write32(messagePointer + 4, Result::Success); break; + + case 1: // Retrieves a file's last-modified timestamp. Seen in DDLC, stubbed for the moment + Helpers::warn("FS::ControlArchive: Tried to retrieve a file's last-modified timestamp"); + mem.write32(messagePointer + 4, Result::Success); + break; + default: Helpers::panic("Unimplemented action for ControlArchive (action = %X)\n", action); break; From 26bb05bd8ea1b24df793a4853e9c47b8da96caf8 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:56:10 +0300 Subject: [PATCH 3/3] Start separating CFG:U and CFG:I --- include/kernel/handles.hpp | 6 ++++-- include/services/cfg.hpp | 1 - src/core/services/service_manager.cpp | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index 8731ee33..256ae02b 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -17,7 +17,8 @@ namespace KernelHandles { BOSS, // Streetpass stuff? CAM, // Camera service CECD, // More Streetpass stuff? - CFG, // CFG service (Console & region info) + CFG_U, // CFG service (Console & region info) + CFG_I, DLP_SRVR, // Download Play: Server. Used for network play. DSP, // DSP service (Used for audio decoding and output) HID, // HID service (Handles input-related things including gyro. Does NOT handle New3DS controls or CirclePadPro) @@ -67,7 +68,8 @@ namespace KernelHandles { case BOSS: return "BOSS"; case CAM: return "CAM"; case CECD: return "CECD"; - case CFG: return "CFG"; + case CFG_U: return "CFG:U"; + case CFG_I: return "CFG:I"; case DSP: return "DSP"; case DLP_SRVR: return "DLP::SRVR"; case HID: return "HID"; diff --git a/include/services/cfg.hpp b/include/services/cfg.hpp index 666e8b23..c8c8adde 100644 --- a/include/services/cfg.hpp +++ b/include/services/cfg.hpp @@ -7,7 +7,6 @@ #include "result/result.hpp" class CFGService { - Handle handle = KernelHandles::CFG; Memory& mem; CountryCodes country = CountryCodes::US; // Default to USA MAKE_LOG_FUNCTION(log, cfgLogger) diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index f63d7ff5..56ae6637 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -97,7 +97,8 @@ static std::map serviceMap = { { "boss:U", KernelHandles::BOSS }, { "cam:u", KernelHandles::CAM }, { "cecd:u", KernelHandles::CECD }, - { "cfg:u", KernelHandles::CFG }, + { "cfg:u", KernelHandles::CFG_U }, + { "cfg:i", KernelHandles::CFG_I }, { "dlp:SRVR", KernelHandles::DLP_SRVR }, { "dsp::DSP", KernelHandles::DSP }, { "hid:USER", KernelHandles::HID }, @@ -184,7 +185,7 @@ void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { case KernelHandles::BOSS: boss.handleSyncRequest(messagePointer); break; case KernelHandles::CAM: cam.handleSyncRequest(messagePointer); break; case KernelHandles::CECD: cecd.handleSyncRequest(messagePointer); break; - case KernelHandles::CFG: cfg.handleSyncRequest(messagePointer); break; + case KernelHandles::CFG_U: cfg.handleSyncRequest(messagePointer); break; case KernelHandles::DLP_SRVR: dlp_srvr.handleSyncRequest(messagePointer); break; case KernelHandles::HID: hid.handleSyncRequest(messagePointer); break; case KernelHandles::HTTP: http.handleSyncRequest(messagePointer); break;