bpc.mitm/exo: support pmic reboot/shutdown on mariko (thanks @CTCaer)

This commit is contained in:
Michael Scire 2023-10-11 18:50:38 -07:00
parent 0569392faf
commit 89a7b2df35
7 changed files with 54 additions and 15 deletions

View file

@ -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() { void PerformUserRebootToRcm() {
/* Configure the bootrom to boot to rcm. */ /* Configure the bootrom to boot to rcm. */
reg::Write(PMC + APBDEV_PMC_SCRATCH0, 0x2); reg::Write(PMC + APBDEV_PMC_SCRATCH0, 0x2);
@ -100,11 +109,20 @@ namespace ams::secmon {
} }
void PerformUserShutDown() { void PerformUserShutDown() {
/* Load our reboot stub to iram. */ if (fuse::GetSocType() == fuse::SocType_Mariko) {
LoadRebootStub(RebootStubAction_ShutDown); /* Ensure that i2c-5 is usable for communicating with the pmic. */
clkrst::EnableI2c5Clock();
i2c::Initialize(i2c::Port_5);
/* Reboot. */ /* On Mariko shutdown via pmic. */
PerformPmcReboot(); pmic::ShutdownSystem(false);
} else /* if (fuse::GetSocType() == fuse::SocType_Erista) */ {
/* Load our reboot stub to iram. */
LoadRebootStub(RebootStubAction_ShutDown);
/* Reboot. */
PerformPmcReboot();
}
} }
} }

View file

@ -23,11 +23,13 @@ namespace ams::secmon {
UserRebootType_ToRcm = 1, UserRebootType_ToRcm = 1,
UserRebootType_ToPayload = 2, UserRebootType_ToPayload = 2,
UserRebootType_ToFatalError = 3, UserRebootType_ToFatalError = 3,
UserRebootType_ByPmic = 4,
}; };
void PerformUserRebootToRcm(); void PerformUserRebootToRcm();
void PerformUserRebootToPayload(); void PerformUserRebootToPayload();
void PerformUserRebootToFatalError(); void PerformUserRebootToFatalError();
void PerformUserRebootByPmic();
void PerformUserShutDown(); void PerformUserShutDown();
} }

View file

@ -357,6 +357,9 @@ namespace ams::secmon::smc {
case UserRebootType_ToFatalError: case UserRebootType_ToFatalError:
PerformUserRebootToFatalError(); PerformUserRebootToFatalError();
break; break;
case UserRebootType_ByPmic:
PerformUserRebootByPmic();
break;
default: default:
return SmcResult::InvalidArgument; return SmcResult::InvalidArgument;
} }
@ -365,18 +368,17 @@ namespace ams::secmon::smc {
case UserRebootType_ToFatalError: case UserRebootType_ToFatalError:
PerformUserRebootToFatalError(); PerformUserRebootToFatalError();
break; break;
case UserRebootType_ByPmic:
PerformUserRebootByPmic();
break;
default: default:
return SmcResult::InvalidArgument; return SmcResult::InvalidArgument;
} }
} }
break; break;
case ConfigItem::ExosphereNeedsShutdown: case ConfigItem::ExosphereNeedsShutdown:
if (soc_type == fuse::SocType_Erista) { if (args.r[3] != 0) {
if (args.r[3] != 0) { PerformUserShutDown();
PerformUserShutDown();
}
} else /* if (soc_type == fuse::SocType_Mariko) */ {
return SmcResult::NotSupported;
} }
break; break;
case ConfigItem::ExospherePayloadAddress: case ConfigItem::ExospherePayloadAddress:

View file

@ -25,6 +25,7 @@ namespace ams::exosphere {
void ForceRebootToRcm(); void ForceRebootToRcm();
void ForceRebootToIramPayload(); void ForceRebootToIramPayload();
void ForceRebootToFatalError(); void ForceRebootToFatalError();
void ForceRebootByPmic();
void ForceShutdown(); void ForceShutdown();
bool IsRcmBugPatched(); bool IsRcmBugPatched();

View file

@ -39,6 +39,10 @@ namespace ams::exosphere {
R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 3)); R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 3));
} }
void ForceRebootByPmic() {
R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 4));
}
void ForceShutdown() { void ForceShutdown() {
R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsShutdown, 1)); R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsShutdown, 1));
} }

View file

@ -33,6 +33,7 @@ namespace ams::mitm::bpc {
Standard, Standard,
ToRcm, ToRcm,
ToPayload, ToPayload,
ByPmic,
}; };
/* Globals. */ /* Globals. */
@ -93,6 +94,9 @@ namespace ams::mitm::bpc {
void RebootSystem() { void RebootSystem() {
switch (g_reboot_type) { switch (g_reboot_type) {
case RebootType::ByPmic:
exosphere::ForceRebootByPmic();
break;
case RebootType::ToRcm: case RebootType::ToRcm:
exosphere::ForceRebootToRcm(); exosphere::ForceRebootToRcm();
break; break;
@ -113,6 +117,11 @@ namespace ams::mitm::bpc {
} }
void SetRebootPayload(const void *payload, size_t payload_size) { 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 */ /* Clear payload buffer */
std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload));
@ -131,6 +140,9 @@ namespace ams::mitm::bpc {
} }
Result LoadRebootPayload() { Result LoadRebootPayload() {
/* Mariko does not support reboot-to-payload. */
R_SUCCEED_IF(spl::GetSocType() == spl::SocType_Mariko)
/* Clear payload buffer */ /* Clear payload buffer */
std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload));
@ -163,6 +175,11 @@ namespace ams::mitm::bpc {
g_reboot_type = RebootType::ToPayload; 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(); R_SUCCEED();
} }

View file

@ -67,11 +67,6 @@ namespace ams::mitm::bpc {
/* Wait until initialization is complete. */ /* Wait until initialization is complete. */
mitm::WaitInitialized(); 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. */ /* Create bpc mitm. */
const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_2_0_0) ? MitmServiceName : DeprecatedMitmServiceName; const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_2_0_0) ? MitmServiceName : DeprecatedMitmServiceName;