From 2ec3e141c7178c4ad570552bca4411946b88a22e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 18:50:38 -0700 Subject: [PATCH] bpc.mitm/exo: support pmic reboot/shutdown on mariko (thanks @CTCaer) --- .../source/secmon_user_power_management.cpp | 26 ++++++++++++++++--- .../source/secmon_user_power_management.hpp | 2 ++ .../program/source/smc/secmon_smc_info.cpp | 14 +++++----- .../stratosphere/ams/ams_exosphere_api.hpp | 1 + .../source/ams/ams_exosphere_api.cpp | 4 +++ .../source/bpc_mitm/bpc_ams_power_utils.cpp | 17 ++++++++++++ .../source/bpc_mitm/bpcmitm_module.cpp | 5 ---- 7 files changed, 54 insertions(+), 15 deletions(-) diff --git a/exosphere/program/source/secmon_user_power_management.cpp b/exosphere/program/source/secmon_user_power_management.cpp index 719dc427a..6f81af026 100644 --- a/exosphere/program/source/secmon_user_power_management.cpp +++ b/exosphere/program/source/secmon_user_power_management.cpp @@ -70,6 +70,15 @@ namespace ams::secmon { } + void PerformUserRebootByPmic() { + /* Ensure that i2c-5 is usable for communicating with the pmic. */ + clkrst::EnableI2c5Clock(); + i2c::Initialize(i2c::Port_5); + + /* Reboot. */ + pmic::ShutdownSystem(true); + } + void PerformUserRebootToRcm() { /* Configure the bootrom to boot to rcm. */ reg::Write(PMC + APBDEV_PMC_SCRATCH0, 0x2); @@ -100,11 +109,20 @@ namespace ams::secmon { } void PerformUserShutDown() { - /* Load our reboot stub to iram. */ - LoadRebootStub(RebootStubAction_ShutDown); + if (fuse::GetSocType() == fuse::SocType_Mariko) { + /* Ensure that i2c-5 is usable for communicating with the pmic. */ + clkrst::EnableI2c5Clock(); + i2c::Initialize(i2c::Port_5); - /* Reboot. */ - PerformPmcReboot(); + /* On Mariko shutdown via pmic. */ + pmic::ShutdownSystem(false); + } else /* if (fuse::GetSocType() == fuse::SocType_Erista) */ { + /* Load our reboot stub to iram. */ + LoadRebootStub(RebootStubAction_ShutDown); + + /* Reboot. */ + PerformPmcReboot(); + } } } diff --git a/exosphere/program/source/secmon_user_power_management.hpp b/exosphere/program/source/secmon_user_power_management.hpp index ab3e1e6a6..678ae3167 100644 --- a/exosphere/program/source/secmon_user_power_management.hpp +++ b/exosphere/program/source/secmon_user_power_management.hpp @@ -23,11 +23,13 @@ namespace ams::secmon { UserRebootType_ToRcm = 1, UserRebootType_ToPayload = 2, UserRebootType_ToFatalError = 3, + UserRebootType_ByPmic = 4, }; void PerformUserRebootToRcm(); void PerformUserRebootToPayload(); void PerformUserRebootToFatalError(); + void PerformUserRebootByPmic(); void PerformUserShutDown(); } diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 365d31f27..11f4a693a 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -357,6 +357,9 @@ namespace ams::secmon::smc { case UserRebootType_ToFatalError: PerformUserRebootToFatalError(); break; + case UserRebootType_ByPmic: + PerformUserRebootByPmic(); + break; default: return SmcResult::InvalidArgument; } @@ -365,18 +368,17 @@ namespace ams::secmon::smc { case UserRebootType_ToFatalError: PerformUserRebootToFatalError(); break; + case UserRebootType_ByPmic: + PerformUserRebootByPmic(); + break; default: return SmcResult::InvalidArgument; } } break; case ConfigItem::ExosphereNeedsShutdown: - if (soc_type == fuse::SocType_Erista) { - if (args.r[3] != 0) { - PerformUserShutDown(); - } - } else /* if (soc_type == fuse::SocType_Mariko) */ { - return SmcResult::NotSupported; + if (args.r[3] != 0) { + PerformUserShutDown(); } break; case ConfigItem::ExospherePayloadAddress: diff --git a/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp b/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp index 84cdfe9a9..2712b2b50 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp @@ -25,6 +25,7 @@ namespace ams::exosphere { void ForceRebootToRcm(); void ForceRebootToIramPayload(); void ForceRebootToFatalError(); + void ForceRebootByPmic(); void ForceShutdown(); bool IsRcmBugPatched(); diff --git a/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp b/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp index 6c2a7cccb..d48b0ce57 100644 --- a/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp +++ b/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp @@ -39,6 +39,10 @@ namespace ams::exosphere { R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 3)); } + void ForceRebootByPmic() { + R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 4)); + } + void ForceShutdown() { R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsShutdown, 1)); } diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp index 8ea3b9f28..12f8a0e7c 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp @@ -33,6 +33,7 @@ namespace ams::mitm::bpc { Standard, ToRcm, ToPayload, + ByPmic, }; /* Globals. */ @@ -93,6 +94,9 @@ namespace ams::mitm::bpc { void RebootSystem() { switch (g_reboot_type) { + case RebootType::ByPmic: + exosphere::ForceRebootByPmic(); + break; case RebootType::ToRcm: exosphere::ForceRebootToRcm(); break; @@ -113,6 +117,11 @@ namespace ams::mitm::bpc { } void SetRebootPayload(const void *payload, size_t payload_size) { + /* Mariko does not support reboot-to-payload. */ + if (spl::GetSocType() == spl::SocType_Mariko) { + return; + } + /* Clear payload buffer */ std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); @@ -131,6 +140,9 @@ namespace ams::mitm::bpc { } Result LoadRebootPayload() { + /* Mariko does not support reboot-to-payload. */ + R_SUCCEED_IF(spl::GetSocType() == spl::SocType_Mariko) + /* Clear payload buffer */ std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); @@ -163,6 +175,11 @@ namespace ams::mitm::bpc { g_reboot_type = RebootType::ToPayload; } + /* TODO: Should we actually allow control over this on mariko? */ + if (spl::GetSocType() == spl::SocType_Mariko) { + g_reboot_type = RebootType::ByPmic; + } + R_SUCCEED(); } diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp index 8776c9b50..da01abc46 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp @@ -67,11 +67,6 @@ namespace ams::mitm::bpc { /* Wait until initialization is complete. */ mitm::WaitInitialized(); - /* On Mariko, we can't reboot to payload/do exosphere-shutdown...so there is no point in bpc.mitm. */ - if (spl::GetSocType() == spl::SocType_Mariko) { - return; - } - /* Create bpc mitm. */ const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_2_0_0) ? MitmServiceName : DeprecatedMitmServiceName;