From 979eb86a48745307ddfaeb8a20355bf2dea901f6 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Thu, 19 Mar 2026 16:32:12 +0200 Subject: [PATCH] exosphere: automatically adjust dram id if needed Checks if programmed memory size matches the one from fused dram id. If not, adjust it properly so PCV can do proper training and not crash. --- .../program/source/smc/secmon_smc_info.cpp | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index e1a6044eb..a08543287 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -176,6 +176,27 @@ namespace ams::secmon::smc { return value.value; } + fuse::DramId GetDramIdAdjusted() { + const auto dram_id = fuse::GetDramId(); + AMS_ABORT_UNLESS(dram_id < fuse::DramId_Count); + + const auto fuse_mem_size = DramIdToMemorySize[dram_id]; + const auto phys_mem_size = GetPhysicalMemorySize(); + + AMS_ABORT_UNLESS(fuse_mem_size <= phys_mem_size); + + if (fuse_mem_size == phys_mem_size) { + return dram_id; + } + + /* Adjust Dram ID to match density/ranks. */ + if (GetSocType() == fuse::SocType_Erista) { + return fuse::DramId_IcosaSamsung6GB; + } else { /* fuse::SocType_Mariko */ + return fuse::DramId_IowaSamsung1y8GBX; + } + } + constinit u64 g_payload_address = 0; constinit bool g_set_true_target_firmware = false; @@ -185,7 +206,7 @@ namespace ams::secmon::smc { args.r[1] = GetBootConfig().signed_data.IsProgramVerificationDisabled(); break; case ConfigItem::DramId: - args.r[1] = fuse::GetDramId(); + args.r[1] = GetDramIdAdjusted(); /* Nintendo: fuse::GetDramId() */ break; case ConfigItem::SecurityEngineInterruptNumber: args.r[1] = SecurityEngineUserInterruptId; @@ -522,9 +543,18 @@ namespace ams::secmon::smc { /* For exosphere's usage. */ pkg1::MemorySize GetPhysicalMemorySize() { - const auto dram_id = fuse::GetDramId(); - AMS_ABORT_UNLESS(dram_id < fuse::DramId_Count); - return DramIdToMemorySize[dram_id]; + const uintptr_t MC = secmon::MemoryRegionVirtualDeviceMemoryController.GetAddress(); + const u32 mem_size = reg::Read(MC + MC_EMEM_CFG) & 0x3FFF; + + switch (mem_size >> 10) { + case 4: + default: + return pkg1::MemorySize_4GB; + case 6: + return pkg1::MemorySize_6GB; + case 8: + return pkg1::MemorySize_8GB; + } } }