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) {