From cc46e16d66b52e693b407e62a216826da4c0f978 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:44:38 +0200 Subject: [PATCH] Fix hb autoboot stuck in exception at boot after a forced shutdown Closes #1882. Whenever power button is held long enough ("force shutdown"), mcu sysmodule stores a flag in free reg 0. It will clear it next boot. During that next boot, if that flag was set and if CFG_BOOTENV.bit0 is set (warmboot/firm chainload, i.e. not coldbooting), then main() will simulate a "power button held" interrupt (after upgrading mcu fw if necessary -- it will reboot console after if it has upgraded mcu fw, I guess that's one of the reasons the flag is there). This obviously cause other processes to initiate a shutdown. In the case of autoboot, ns will panic when this happens. --- arm9/source/deliver_arg.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arm9/source/deliver_arg.c b/arm9/source/deliver_arg.c index badb0ef6..9d91eff2 100644 --- a/arm9/source/deliver_arg.c +++ b/arm9/source/deliver_arg.c @@ -29,6 +29,7 @@ #include "memory.h" #include "config.h" #include "fs.h" +#include "i2c.h" u8 *loadDeliverArg(void) { @@ -151,6 +152,26 @@ static bool configureHomebrewAutobootCtr(u8 *deliverArg) // Tell NS to run the title, and that it's not a title jump from legacy mode *(u32 *)(deliverArg + 0x460) = (0 << 1) | (1 << 0); + // Whenever power button is held long enough ("force shutdown"), mcu sysmodule + // stores a flag in free reg 0. It will clear it next boot. + + // During that next boot, if that flag was set and if CFG_BOOTENV.bit0 is set + // (warmboot/firm chainload, i.e. not coldbooting), then main() will simulate + // a "power button held" interrupt (after upgrading mcu fw if necessary -- it + // will reboot console after if it has upgraded mcu fw, I guess that's one of + // the reasons the flag is there). This obviously cause other processes to initiate + // a shutdown, and it also sets that flag again. + + // In the case of autoboot, ns will panic when this happens. This caused + // hb autoboot to keep failing over and over again. + + // Select free reg 0, read it, select it again, write it (clearing force shutdown flag) + I2C_writeReg(I2C_DEV_MCU, 0x60, 0); + u8 flags = I2C_readReg(I2C_DEV_MCU, 0x61); + flags &= ~4; + I2C_writeReg(I2C_DEV_MCU, 0x60, 0); + I2C_writeReg(I2C_DEV_MCU, 0x61, flags); + CFG_BOOTENV = 1; return true;