Do not always reboot to HM when autobooting HB

Also fix CRC calculation
This commit is contained in:
TuxSH 2023-02-05 22:08:15 +00:00
parent 9957d6db1a
commit 5a5332a212
2 changed files with 36 additions and 6 deletions

View File

@ -28,10 +28,11 @@
#include "utils.h"
#include "memory.h"
#include "config.h"
#include "fs.h"
u8 *loadDeliverArg(void)
{
static u8 deliverArg[0x1000] = {0};
static __attribute__((aligned(8))) u8 deliverArg[0x1000] = {0};
static bool deliverArgLoaded = false;
if (!deliverArgLoaded)
@ -50,8 +51,11 @@ u8 *loadDeliverArg(void)
// Validate deliver arg
u32 testPattern = *(u32 *)(deliverArg + 0x438);
u32 crc = *(u32 *)(deliverArg + 0x43C);
u32 *crcPtr = (u32 *)(deliverArg + 0x43C);
u32 crc = *crcPtr;
*crcPtr = 0; // clear crc field before calculation
u32 expectedCrc = crc32(deliverArg + 0x400, 0x140, 0xFFFFFFFF);
*crcPtr = crc;
if (testPattern != 0xFFFF || crc != expectedCrc)
memset(deliverArg, 0, 0x1000);
}
@ -93,6 +97,7 @@ void commitDeliverArg(void)
if (mode == 0) // CTR mode
{
*(u32 *)(deliverArg + 0x438) = 0xFFFF;
*(u32 *)(deliverArg + 0x43C) = 0; // clear CRC field before calculating it
*(u32 *)(deliverArg + 0x43C) = crc32(deliverArg + 0x400, 0x140, 0xFFFFFFFF);
memcpy((void *)0x20000000, deliverArg, 0x1000);
}
@ -185,9 +190,27 @@ bool configureHomebrewAutoboot(void)
u32 bootenv = CFG_BOOTENV;
u32 mode = bootenv >> 1;
u32 testPattern = *(u32 *)(deliverArg + 0x438);
if (mode != 0 || testPattern == 0xFFFF)
return false; // bail out if this isn't a coldboot/plain reboot
// NS always writes a valid deliver arg on reboot, no matter what.
// Check if it is empty, and, of course, bail out if we aren't rebooting from
// NATIVE_FIRM.
// Checking if it is empty is necessary to let us reboot from autobooted hbmenu
// to hbmenu.
if (mode != 0)
return false;
else if (bootenv == 1)
{
for (u32 i = 0; i < 0x410; i++)
{
if (deliverArg[i] != 0)
return false;
}
for (u32 i = 0x440; i < 0x1000; i++)
{
if (deliverArg[i] != 0)
return false;
}
}
switch (MULTICONFIG(AUTOBOOTMODE))
{

View File

@ -229,12 +229,19 @@ void main(int argc, char **argv, u32 magicWord)
nandType = FIRMWARE_SYSNAND;
firmSource = (BOOTCFG_NAND != 0) == (BOOTCFG_FIRM != 0) ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCFG_FIRM;
//Prevent multiple boot options-forcing
// Prevent multiple boot options-forcing
// This bit is a bit weird. Basically, as you return to Home Menu by pressing either
// the HOME or POWER button, nandType will be overridden to "SysNAND" (needed). But,
// if you reboot again (e.g. via Rosalina menu), it'll use your default settings.
if(nandType != BOOTCFG_NAND || firmSource != BOOTCFG_FIRM) isNoForceFlagSet = true;
goto boot;
}
// Configure homebrew autoboot (if deliver arg ends up not containing anything)
if (bootenv == 1 && MULTICONFIG(AUTOBOOTMODE) != 0)
configureHomebrewAutoboot();
/* Force the last used boot options if doing autolaunch from TWL, or unless a button is pressed
or the no-forcing flag is set */
if(validTlnc || !(pressed || BOOTCFG_NOFORCEFLAG))