From 9ae30ca73b289e22084e3df2fb29f1bb1be76d6d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 20 Nov 2020 01:05:45 -0800 Subject: [PATCH] exo/mariko fatal: perform display init, reboot on power button press --- libexosphere/include/exosphere/pmic.hpp | 2 ++ .../exosphere/secmon/secmon_memory_layout.hpp | 5 ++- libexosphere/source/pmic/pmic_api.cpp | 32 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/libexosphere/include/exosphere/pmic.hpp b/libexosphere/include/exosphere/pmic.hpp index fc43715b..ea85f60a 100644 --- a/libexosphere/include/exosphere/pmic.hpp +++ b/libexosphere/include/exosphere/pmic.hpp @@ -32,6 +32,8 @@ namespace ams::pmic { void DisableVddCpu(Regulator regulator); void EnableSleep(); void PowerOff(); + void ShutdownSystem(bool reboot); bool IsAcOk(); + bool IsPowerButtonPressed(); } \ No newline at end of file diff --git a/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp b/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp index 2de44631..3c46b296 100644 --- a/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp +++ b/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp @@ -149,7 +149,10 @@ namespace ams::secmon { HANDLER(ExceptionVectors, I2c1, UINT64_C(0x6000F000), UINT64_C(0x1000), true, ## __VA_ARGS__) \ HANDLER(MemoryController0, ExceptionVectors, UINT64_C(0x7001C000), UINT64_C(0x1000), true, ## __VA_ARGS__) \ HANDLER(MemoryController1, MemoryController0, UINT64_C(0x7001D000), UINT64_C(0x1000), true, ## __VA_ARGS__) \ - HANDLER(Sdmmc, MemoryController1, UINT64_C(0x700B0000), UINT64_C(0x1000), true, ## __VA_ARGS__) + HANDLER(Sdmmc, MemoryController1, UINT64_C(0x700B0000), UINT64_C(0x1000), true, ## __VA_ARGS__) \ + HANDLER(Disp1, Sdmmc, UINT64_C(0x54200000), UINT64_C(0x3000), true, ## __VA_ARGS__) \ + HANDLER(Dsi, Disp1, UINT64_C(0x54300000), UINT64_C(0x1000), true, ## __VA_ARGS__) \ + HANDLER(MipiCal, Dsi, UINT64_C(0x700E3000), UINT64_C(0x1000), true, ## __VA_ARGS__) #define DEFINE_DEVICE_REGION(_NAME_, _PREV_, _ADDRESS_, _SIZE_, _SECURE_) \ constexpr inline const MemoryRegion MemoryRegionVirtualDevice##_NAME_ = MemoryRegion(MemoryRegionVirtualDevice##_PREV_.GetEndAddress() + 0x1000, _SIZE_); \ diff --git a/libexosphere/source/pmic/pmic_api.cpp b/libexosphere/source/pmic/pmic_api.cpp index 808d465d..f42d4264 100644 --- a/libexosphere/source/pmic/pmic_api.cpp +++ b/libexosphere/source/pmic/pmic_api.cpp @@ -176,8 +176,40 @@ namespace ams::pmic { i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, Max77620RegisterOnOffCnfg1, MAX77620_ONOFFCNFG1_PWR_OFF); } + void ShutdownSystem(bool reboot) { + /* Get value, set or clear software reset mask. */ + u8 on_off_2_val = i2c::QueryByte(i2c::Port_5, I2cAddressMax77620Pmic, MAX77620_REG_ONOFFCNFG2); + if (reboot) { + on_off_2_val |= MAX77620_ONOFFCNFG2_SFT_RST_WK; + } else { + on_off_2_val &= ~(MAX77620_ONOFFCNFG2_SFT_RST_WK); + } + i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, MAX77620_REG_ONOFFCNFG2, on_off_2_val); + + /* Get value, set software reset mask. */ + u8 on_off_1_val = i2c::QueryByte(i2c::Port_5, I2cAddressMax77620Pmic, MAX77620_REG_ONOFFCNFG1); + on_off_1_val |= MAX77620_ONOFFCNFG1_SFT_RST; + + /* NOTE: Here, userland finalizes the battery on non-Calcio. */ + if (fuse::GetHardwareType() != fuse::HardwareType_Calcio) { + /* ... */ + } + + /* Actually write the value to trigger shutdown/reset. */ + i2c::SendByte(i2c::Port_5, I2cAddressMax77620Pmic, MAX77620_REG_ONOFFCNFG1, on_off_1_val); + + /* Allow up to 5 seconds for shutdown/reboot to take place. */ + util::WaitMicroSeconds(5'000'000ul); + + AMS_ABORT("Shutdown failed"); + } + bool IsAcOk() { return (GetPmicOnOffStat() & (1 << 1)) != 0; } + bool IsPowerButtonPressed() { + return (GetPmicOnOffStat() & (1 << 2)) != 0; + } + }