From 350dccff3d72b5c75bdd0f391853d4aa66487758 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 1 Apr 2019 16:37:04 -0700 Subject: [PATCH] exo: also check for rcm ipatch (thanks @balika011) --- exosphere/src/fuse.c | 39 ++++++++++++++++++++++++++++++++++++--- exosphere/src/fuse.h | 2 +- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/exosphere/src/fuse.c b/exosphere/src/fuse.c index cd162256b..36ac6991f 100644 --- a/exosphere/src/fuse.c +++ b/exosphere/src/fuse.c @@ -24,6 +24,9 @@ #include "masterkey.h" +static bool g_has_checked_for_rcm_bug_patch = false; +static bool g_has_rcm_bug_patch = false; + /* Prototypes for internal commands. */ void fuse_make_regs_visible(void); @@ -260,7 +263,37 @@ void fuse_get_hardware_info(void *dst) { } bool fuse_has_rcm_bug_patch(void) { - /* Patched units have this bit set in reserved_sw, according to reports. */ - /* TODO: Is there an ipatch we should check? This should be researched. */ - return (FUSE_CHIP_REGS->FUSE_RESERVED_SW & 0x80) != 0; + /* Only check for RCM bug patch once, and cache our result. */ + if (!g_has_checked_for_rcm_bug_patch) { + /* Patched units have this bit set in reserved_sw, according to reports. */ + if (FUSE_CHIP_REGS->FUSE_RESERVED_SW & 0x80) { + g_has_rcm_bug_patch = true; + } + + /* Also check for an ipatch. */ + { + uint32_t word_count = FUSE_CHIP_REGS->FUSE_FIRST_BOOTROM_PATCH_SIZE & 0x7f; + uint32_t word_addr = 191; + + while (word_count) { + uint32_t word0 = fuse_hw_read(word_addr); + uint32_t ipatch_count = (word0 >> 16) & 0xf; + + for (uint32_t i = 0; i < ipatch_count; i++) { + uint32_t word = fuse_hw_read(word_addr - (i + 1)); + uint32_t addr = (word >> 16) * 2; + + if (addr == 0x769a) { + g_has_rcm_bug_patch = true; + } + } + + word_addr -= word_count; + word_count = word0 >> 25; + } + } + } + g_has_checked_for_rcm_bug_patch = true; + + return g_has_rcm_bug_patch; } diff --git a/exosphere/src/fuse.h b/exosphere/src/fuse.h index c1c8dca81..079a91ebc 100644 --- a/exosphere/src/fuse.h +++ b/exosphere/src/fuse.h @@ -74,7 +74,7 @@ typedef struct { uint32_t FUSE_CP_REV; uint32_t _0x94; uint32_t FUSE_TSENSOR_0; - uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE; uint32_t FUSE_SECURITY_MODE; uint32_t FUSE_PRIVATE_KEY[0x4]; uint32_t FUSE_DEVICE_KEY;