From 5dd9816e3cf8a4d5793968759537d5b6d7372668 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Thu, 19 Mar 2026 16:35:36 +0200 Subject: [PATCH] exosphere: allow memory mode to be used on retail --- config_templates/exosphere.ini | 8 ++++++++ .../program/source/smc/secmon_smc_info.cpp | 19 ++++++++++++------- fusee/program/source/fusee_setup_horizon.cpp | 6 ++++++ .../secmon/secmon_monitor_context.hpp | 2 ++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/config_templates/exosphere.ini b/config_templates/exosphere.ini index 8df772ccf..f815b8cc7 100644 --- a/config_templates/exosphere.ini +++ b/config_templates/exosphere.ini @@ -15,6 +15,13 @@ # Desc: Controls whether userland has access to the PMU registers. # NOTE: It is unknown what effects this has on official code. +# Key: enable_mem_mode, default: 0. +# Desc: Controls whether boot config memory mode is taken into account +# for retail units. This does not affect development units. +# NOTE: On retail units max ram size is capped to 4GB. +# Enabling this will use the boot config memory mode parameter, +# which by default is auto and size gets set based on physical size. + # Key: blank_prodinfo_sysmmc, default: 0. # Desc: Controls whether PRODINFO should be blanked in sysmmc. # This will cause the system to see dummied out keys and @@ -51,6 +58,7 @@ debugmode=1 debugmode_user=0 disable_user_exception_handlers=0 enable_user_pmu_access=0 +enable_mem_mode=0 blank_prodinfo_sysmmc=0 blank_prodinfo_emummc=0 allow_writing_to_cal_sysmmc=0 diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 01fa3b93c..88cdeefe0 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -132,10 +132,13 @@ namespace ams::secmon::smc { } u32 GetMemoryMode() { - /* Unless development function is enabled, we're 4 GB. */ + /* Unless development function or forced boot config memory size is enabled, we're 4 GB. */ u32 memory_mode = pkg1::MemoryMode_4GB; - if (const auto &bcd = GetBootConfig().data; bcd.IsDevelopmentFunctionEnabled()) { + const auto &bcd = GetBootConfig().data; + const auto &sc = GetSecmonConfiguration(); /* Exosphere extensions */ + + if (bcd.IsDevelopmentFunctionEnabled() || sc.IsBootConfigMemoryModeEnabled()) { memory_mode = GetMemoryMode(bcd.GetMemoryMode()); } @@ -146,17 +149,19 @@ namespace ams::secmon::smc { pkg1::MemorySize memory_size = pkg1::MemorySize_4GB; util::BitPack32 value = {}; - if (const auto &bcd = GetBootConfig().data; bcd.IsDevelopmentFunctionEnabled()) { - memory_size = GetMemorySize(GetMemoryMode(bcd.GetMemoryMode())); + const auto &bcd = GetBootConfig().data; + const auto &sc = GetSecmonConfiguration(); /* Exosphere extensions */ + if (bcd.IsDevelopmentFunctionEnabled()) { value.Set(bcd.GetKernelFlags1()); value.Set(bcd.GetKernelFlags0()); } - value.Set(memory_size); + if (bcd.IsDevelopmentFunctionEnabled() || sc.IsBootConfigMemoryModeEnabled()) { + memory_size = GetMemorySize(GetMemoryMode(bcd.GetMemoryMode())); + } - /* Exosphere extensions. */ - const auto &sc = GetSecmonConfiguration(); + value.Set(memory_size); if (!sc.DisableUserModeExceptionHandlers()) { value.Set(true); diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 7ec68d4a3..cd0e31802 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -543,6 +543,12 @@ namespace ams::nxboot { } else { storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess; } + } else if (std::strcmp(entry.key, "enable_mem_mode") == 0) { + if (entry.value[0] == '1') { + storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled; + } else { + storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled; + } } else if (std::strcmp(entry.key, "blank_prodinfo_sysmmc") == 0) { if (!emummc_enabled) { if (entry.value[0] == '1') { diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp index c37b76c82..28517ea74 100644 --- a/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp +++ b/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp @@ -30,6 +30,7 @@ namespace ams::secmon { SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5), SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6), SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7), + SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled = (1u << 8), SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel, }; @@ -103,6 +104,7 @@ namespace ams::secmon { constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; } constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; } constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; } + constexpr bool IsBootConfigMemoryModeEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled) != 0; } constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); } };