From 601c4516bf2d4450279c336279f80741aa1d823c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 3 Jan 2021 23:46:13 -0800 Subject: [PATCH] fusee/exo: fixes to allow booting (sleep broken until warmboot cache implemented) --- .../program/source/boot/secmon_boot_setup.cpp | 14 +++-------- fusee/fusee-secondary/src/nxboot.c | 23 ++++++++++++------- fusee/fusee-secondary/src/nxboot.h | 2 +- fusee/fusee-secondary/src/package1.c | 14 ++++++++--- fusee/fusee-secondary/src/package1.h | 2 ++ 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/exosphere/program/source/boot/secmon_boot_setup.cpp b/exosphere/program/source/boot/secmon_boot_setup.cpp index 80092f780..fa4d1f1c9 100644 --- a/exosphere/program/source/boot/secmon_boot_setup.cpp +++ b/exosphere/program/source/boot/secmon_boot_setup.cpp @@ -64,17 +64,9 @@ namespace ams::secmon::boot { /* Configure warmboot to set Set FUSE_PRIVATEKEYDISABLE to KEY_INVISIBLE. */ reg::ReadWrite(pmc + APBDEV_PMC_SECURE_SCRATCH21, REG_BITS_VALUE(4, 1, 1)); - /* Write the warmboot key. */ - /* TODO: This is necessary for mariko. We should decide how to handle this. */ - /* In particular, mariko will need to support loading older-than-expected warmboot firmware. */ - /* We could hash the warmboot firmware and use a lookup table, or require bootloader to provide */ - /* The warmboot key as a parameter. The latter is a better solution, but it would be nice to take */ - /* care of it here. Perhaps we should read the number of anti-downgrade fuses burnt, and translate that */ - /* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */ - reg::Write(pmc + APBDEV_PMC_SECURE_SCRATCH32, 0x129); - - /* TODO: Fix to ensure correct scratch contents on mariko, as otherwise wb is broken. */ - AMS_ABORT_UNLESS(fuse::GetSocType() != fuse::SocType_Mariko); + /* NOTE: Here, Nintendo writes the warmboot key. */ + /* However, we rely on the bootloader (e.g. fusee/hekate) having already done this. */ + /* reg::Write(pmc + APBDEV_PMC_SECURE_SCRATCH32, ...); */ } /* This function derives the master kek and device keys using the tsec root key. */ diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 260d79454..e23007b77 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -589,6 +589,16 @@ static void nxboot_set_bootreason(void *bootreason_base) { fatal_error("[NXBOOT] Failed to read the BCT!\n"); } + /* Check if we need to use BCT 2 instead. */ + if (package1_is_custom_public_key(bct, is_soc_mariko())) { + if (fseek(boot0, 0x4000 * 2, SEEK_SET) != 0) { + fatal_error("[NXBOOT] Failed to seek to BCT!\n"); + } + if (fread(bct, sizeof(nvboot_config_table), 1, boot0) == 0) { + fatal_error("[NXBOOT] Failed to read the BCT!\n"); + } + } + /* Close boot0. */ fclose(boot0); @@ -617,7 +627,7 @@ static void nxboot_set_bootreason(void *bootreason_base) { boot_reason.boot_reason_state = 0x04; /* BootReason_RtcAlarm2 */ /* Set in memory. */ - memcpy(bootreason_base, &boot_reason, sizeof(boot_reason)); + memcpy((void *)((uintptr_t)bootreason_base + 0x10), &boot_reason, sizeof(boot_reason)); /* Clean up. */ free(bct); @@ -931,13 +941,10 @@ uint32_t nxboot_main(void) { nxboot_configure_exosphere(target_firmware, keygen_type, &exo_emummc_cfg); /* Initialize BootReason on older firmware versions (Erista only). */ - if (!is_mariko) { - if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) { - print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Initializing BootReason...\n"); - nxboot_set_bootreason((void *)MAILBOX_NX_BOOTLOADER_BOOT_REASON_BASE); - } else { - memset((void *)MAILBOX_NX_BOOTLOADER_BOOT_REASON_BASE, 0, 0x200); - } + memset((void *)MAILBOX_NX_BOOTLOADER_BASE, 0, 0x200); + if (!is_mariko && target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) { + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Initializing BootReason...\n"); + nxboot_set_bootreason((void *)MAILBOX_NX_BOOTLOADER_BOOT_REASON_BASE); } /* Read the warmboot firmware from a file, otherwise from Atmosphere's implementation (Erista only) or from cache (Mariko only). */ diff --git a/fusee/fusee-secondary/src/nxboot.h b/fusee/fusee-secondary/src/nxboot.h index ebcc878b3..08ebc00e0 100644 --- a/fusee/fusee-secondary/src/nxboot.h +++ b/fusee/fusee-secondary/src/nxboot.h @@ -36,7 +36,7 @@ typedef struct { #define MAILBOX_NX_BOOTLOADER_BASE 0x40000000 #define MAKE_MAILBOX_NX_BOOTLOADER_REG(n) MAKE_REG32(MAILBOX_NX_BOOTLOADER_BASE + n) -#define MAILBOX_NX_BOOTLOADER_BOOT_REASON_BASE MAKE_MAILBOX_NX_BOOTLOADER_REG(0x10) +#define MAILBOX_NX_BOOTLOADER_BOOT_REASON_BASE (MAILBOX_NX_BOOTLOADER_BASE + 0x10) #define MAILBOX_NX_BOOTLOADER_SETUP_STATE MAKE_MAILBOX_NX_BOOTLOADER_REG(0xF8) #define MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE MAKE_MAILBOX_NX_BOOTLOADER_REG(0xFC) diff --git a/fusee/fusee-secondary/src/package1.c b/fusee/fusee-secondary/src/package1.c index 80129ccd1..4a3405bd1 100644 --- a/fusee/fusee-secondary/src/package1.c +++ b/fusee/fusee-secondary/src/package1.c @@ -46,9 +46,17 @@ static bool is_custom_public_key_erista(const void *bct) { return memcmp((const uint8_t *)bct + 0x210, custom_public_key, sizeof(custom_public_key)) == 0; } -//static bool is_custom_public_key_mariko(const void *bct) { -// return memcmp((const uint8_t *)bct + 0x10, custom_public_key, sizeof(custom_public_key)) == 0; -//} +static bool is_custom_public_key_mariko(const void *bct) { + return memcmp((const uint8_t *)bct + 0x10, custom_public_key, sizeof(custom_public_key)) == 0; +} + +bool package1_is_custom_public_key(const void *bct, bool mariko) { + if (mariko) { + return is_custom_public_key_mariko(bct); + } else { + return is_custom_public_key_erista(bct); + } +} int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0) { nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */ diff --git a/fusee/fusee-secondary/src/package1.h b/fusee/fusee-secondary/src/package1.h index 0557d5ddc..14076e0d4 100644 --- a/fusee/fusee-secondary/src/package1.h +++ b/fusee/fusee-secondary/src/package1.h @@ -57,6 +57,8 @@ typedef struct { uint8_t data[]; } pk11_mariko_oem_header_t; +bool package1_is_custom_public_key(const void *bct, bool mariko); + int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0); int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0);