From 0c596e682f5c825e02831c87915093f97b3c12ea Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 21 Jul 2021 18:21:38 -0700 Subject: [PATCH] exo/daybreak: advertise (and check against) supported hos version --- .../program/source/smc/secmon_smc_info.cpp | 8 ++++- .../program/source/smc/secmon_smc_info.hpp | 23 +++++++------- .../board/nintendo/nx/kern_secure_monitor.hpp | 22 +++++++------- .../include/stratosphere/spl/spl_types.hpp | 23 +++++++------- troposphere/daybreak/Makefile | 2 +- troposphere/daybreak/source/ui.cpp | 30 ++++++++++++++++--- 6 files changed, 70 insertions(+), 38 deletions(-) diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 68efc2990..6b7fa0864 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -243,7 +243,7 @@ namespace ams::secmon::smc { (static_cast(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 48) | (static_cast(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 40) | (static_cast(GetKeyGeneration()) << 32) | - (static_cast(GetTargetFirmware()) << 00); + (static_cast(GetTargetFirmware()) << 0); break; case ConfigItem::ExosphereNeedsReboot: /* We are executing, so we aren't in the process of rebooting. */ @@ -290,6 +290,12 @@ namespace ams::secmon::smc { /* Get whether usb 3.0 should be force-enabled. */ args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled(); break; + case ConfigItem::ExosphereSupportedHosVersion: + /* Get information about the supported hos version. */ + args.r[1] = (static_cast(ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR & 0xFF) << 24) | + (static_cast(ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR & 0xFF) << 16) | + (static_cast(ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO & 0xFF) << 8); + break; default: return SmcResult::InvalidArgument; } diff --git a/exosphere/program/source/smc/secmon_smc_info.hpp b/exosphere/program/source/smc/secmon_smc_info.hpp index c7481775f..fbe7917ae 100644 --- a/exosphere/program/source/smc/secmon_smc_info.hpp +++ b/exosphere/program/source/smc/secmon_smc_info.hpp @@ -40,17 +40,18 @@ namespace ams::secmon::smc { Package2Hash = 17, /* Extension config items for exosphere. */ - ExosphereApiVersion = 65000, - ExosphereNeedsReboot = 65001, - ExosphereNeedsShutdown = 65002, - ExosphereGitCommitHash = 65003, - ExosphereHasRcmBugPatch = 65004, - ExosphereBlankProdInfo = 65005, - ExosphereAllowCalWrites = 65006, - ExosphereEmummcType = 65007, - ExospherePayloadAddress = 65008, - ExosphereLogConfiguration = 65009, - ExosphereForceEnableUsb30 = 65010, + ExosphereApiVersion = 65000, + ExosphereNeedsReboot = 65001, + ExosphereNeedsShutdown = 65002, + ExosphereGitCommitHash = 65003, + ExosphereHasRcmBugPatch = 65004, + ExosphereBlankProdInfo = 65005, + ExosphereAllowCalWrites = 65006, + ExosphereEmummcType = 65007, + ExospherePayloadAddress = 65008, + ExosphereLogConfiguration = 65009, + ExosphereForceEnableUsb30 = 65010, + ExosphereSupportedHosVersion = 65011, }; SmcResult SmcGetConfigUser(SmcArguments &args); diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp index 22233b78f..757323a39 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -55,16 +55,18 @@ namespace ams::kern::board::nintendo::nx::smc { Package2Hash = 17, /* Extension config items for exosphere. */ - ExosphereApiVersion = 65000, - ExosphereNeedsReboot = 65001, - ExosphereNeedsShutdown = 65002, - ExosphereGitCommitHash = 65003, - ExosphereHasRcmBugPatch = 65004, - ExosphereBlankProdInfo = 65005, - ExosphereAllowCalWrites = 65006, - ExosphereEmummcType = 65007, - ExospherePayloadAddress = 65008, - ExosphereLogConfiguration = 65009, + ExosphereApiVersion = 65000, + ExosphereNeedsReboot = 65001, + ExosphereNeedsShutdown = 65002, + ExosphereGitCommitHash = 65003, + ExosphereHasRcmBugPatch = 65004, + ExosphereBlankProdInfo = 65005, + ExosphereAllowCalWrites = 65006, + ExosphereEmummcType = 65007, + ExospherePayloadAddress = 65008, + ExosphereLogConfiguration = 65009, + ExosphereForceEnableUsb30 = 65010, + ExosphereSupportedHosVersion = 65011, }; enum class SmcResult { diff --git a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp index fa510ab53..dcff9b721 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp @@ -223,17 +223,18 @@ namespace ams::spl { Package2Hash = 17, /* Extension config items for exosphere. */ - ExosphereApiVersion = 65000, - ExosphereNeedsReboot = 65001, - ExosphereNeedsShutdown = 65002, - ExosphereGitCommitHash = 65003, - ExosphereHasRcmBugPatch = 65004, - ExosphereBlankProdInfo = 65005, - ExosphereAllowCalWrites = 65006, - ExosphereEmummcType = 65007, - ExospherePayloadAddress = 65008, - ExosphereLogConfiguration = 65009, - ExosphereForceEnableUsb30 = 65010, + ExosphereApiVersion = 65000, + ExosphereNeedsReboot = 65001, + ExosphereNeedsShutdown = 65002, + ExosphereGitCommitHash = 65003, + ExosphereHasRcmBugPatch = 65004, + ExosphereBlankProdInfo = 65005, + ExosphereAllowCalWrites = 65006, + ExosphereEmummcType = 65007, + ExospherePayloadAddress = 65008, + ExosphereLogConfiguration = 65009, + ExosphereForceEnableUsb30 = 65010, + ExosphereSupportedHosVersion = 65011, }; } diff --git a/troposphere/daybreak/Makefile b/troposphere/daybreak/Makefile index 0e7a3fa9f..f9455f4cd 100644 --- a/troposphere/daybreak/Makefile +++ b/troposphere/daybreak/Makefile @@ -61,7 +61,7 @@ CFLAGS := -g -gdwarf-4 -Wall -O2 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__SWITCH__ -CXXFLAGS := $(CFLAGS) -std=gnu++17 -fno-exceptions -fno-rtti +CXXFLAGS := $(CFLAGS) -std=gnu++20 -fno-exceptions -fno-rtti ASFLAGS := -g -gdwarf-4 $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map) diff --git a/troposphere/daybreak/source/ui.cpp b/troposphere/daybreak/source/ui.cpp index 2dc96f32f..c59b638e9 100644 --- a/troposphere/daybreak/source/ui.cpp +++ b/troposphere/daybreak/source/ui.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "ui.hpp" #include "ui_util.hpp" @@ -29,6 +30,7 @@ namespace dbk { static constexpr u32 ExosphereApiVersionConfigItem = 65000; static constexpr u32 ExosphereHasRcmBugPatch = 65004; static constexpr u32 ExosphereEmummcType = 65007; + static constexpr u32 ExosphereSupportedHosVersion = 65011; /* Insets of content within windows. */ static constexpr float HorizontalInset = 20.0f; @@ -46,6 +48,8 @@ namespace dbk { u32 g_screen_width; u32 g_screen_height; + constinit u32 g_supported_version = std::numeric_limits::max(); + std::shared_ptr g_current_menu; bool g_initialized = false; bool g_exit_requested = false; @@ -137,6 +141,10 @@ namespace dbk { return rc; } + u32 EncodeVersion(u32 major, u32 minor, u32 micro, u32 relstep = 0) { + return ((major & 0xFF) << 24) | ((minor & 0xFF) << 16) | ((micro & 0xFF) << 8) | ((relstep & 0xFF) << 8); + } + } void Menu::AddButton(u32 id, const char *text, float x, float y, float w, float h) { @@ -884,13 +892,22 @@ namespace dbk { g_use_exfat = false; } + /* Create the next menu. */ + std::shared_ptr next_menu = std::make_shared(g_current_menu); + /* Warn the user if they're updating with exFAT supposed to be supported but not present/corrupted. */ if (m_update_info.exfat_supported && R_FAILED(m_validation_info.exfat_result)) { - ChangeMenu(std::make_shared(g_current_menu, std::make_shared(g_current_menu), "Warning: exFAT firmware is missing or corrupt", "Are you sure you want to proceed?")); - } else { - ChangeMenu(std::make_shared(g_current_menu)); + next_menu = std::make_shared(g_current_menu, next_menu, "Warning: exFAT firmware is missing or corrupt", "Are you sure you want to proceed?"); } + /* Warn the user if they're updating to a version higher than supported. */ + const u32 version = m_validation_info.invalid_key.version; + if (EncodeVersion((version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf) > g_supported_version) { + next_menu = std::make_shared(g_current_menu, next_menu, "Warning: firmware is too new and not known to be supported", "Are you sure you want to proceed?"); + } + + /* Change to the next menu. */ + ChangeMenu(next_menu); return; } } @@ -1228,12 +1245,17 @@ namespace dbk { const u32 version_major = (version >> 56) & 0xff; /* Validate the exosphere version. */ - const bool ams_supports_sysupdate_api = version_major >= 0 && version_minor >= 14 && version_micro >= 0; + const bool ams_supports_sysupdate_api = EncodeVersion(version_major, version_minor, version_micro) >= EncodeVersion(0, 14, 0); if (!ams_supports_sysupdate_api) { ChangeMenu(std::make_shared("Outdated Atmosphere version", "Daybreak requires Atmosphere 0.14.0 or later.", rc)); return; } + /* Attempt to get the supported version. */ + if (R_SUCCEEDED(rc = splGetConfig(static_cast(ExosphereSupportedHosVersion), &version))) { + g_supported_version = static_cast(version); + } + /* Initialize ams:su. */ if (R_FAILED(rc = amssuInitialize())) { fatalThrow(rc);