mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
[main] Add brick protection for RCM patched units
- If AutoRCM was found enabled, force disable it. (In case of chainloading.) - Additionally disable AutoRCM function.
This commit is contained in:
parent
ed047ef5f5
commit
c80fecd080
6 changed files with 92 additions and 2 deletions
|
@ -44,6 +44,7 @@ void set_default_configuration()
|
||||||
h_cfg.errors = 0;
|
h_cfg.errors = 0;
|
||||||
h_cfg.autonogc = 1;
|
h_cfg.autonogc = 1;
|
||||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||||
|
h_cfg.rcm_patched = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_config_entry()
|
int create_config_entry()
|
||||||
|
|
|
@ -30,10 +30,11 @@ typedef struct _hekate_config
|
||||||
u32 autohosoff;
|
u32 autohosoff;
|
||||||
u32 autonogc;
|
u32 autonogc;
|
||||||
// Global temporary config.
|
// Global temporary config.
|
||||||
int se_keygen_done;
|
bool se_keygen_done;
|
||||||
u32 sbar_time_keeping;
|
u32 sbar_time_keeping;
|
||||||
u32 errors;
|
u32 errors;
|
||||||
int sept_run;
|
int sept_run;
|
||||||
|
bool rcm_patched;
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -294,6 +294,16 @@ void menu_autorcm()
|
||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
|
if (h_cfg.rcm_patched)
|
||||||
|
{
|
||||||
|
gfx_printf("%kThis device is RCM patched and\nAutoRCM function is disabled.\n\n"
|
||||||
|
"In case %kAutoRCM%k is enabled\nthis will %kBRICK%k your device PERMANENTLY!!%k",
|
||||||
|
0xFFFFDD00, 0xFFFF0000, 0xFFFFDD00, 0xFFFF0000, 0xFFFFDD00, 0xFFCCCCCC);
|
||||||
|
btn_wait();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Do a simple check on the main BCT.
|
// Do a simple check on the main BCT.
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
|
|
|
@ -34,10 +34,12 @@
|
||||||
#include "mem/sdram.h"
|
#include "mem/sdram.h"
|
||||||
#include "power/max77620.h"
|
#include "power/max77620.h"
|
||||||
#include "rtc/max77620-rtc.h"
|
#include "rtc/max77620-rtc.h"
|
||||||
|
#include "soc/fuse.h"
|
||||||
#include "soc/hw_init.h"
|
#include "soc/hw_init.h"
|
||||||
#include "soc/i2c.h"
|
#include "soc/i2c.h"
|
||||||
#include "soc/t210.h"
|
#include "soc/t210.h"
|
||||||
#include "soc/uart.h"
|
#include "soc/uart.h"
|
||||||
|
#include "storage/nx_emmc.h"
|
||||||
#include "storage/sdmmc.h"
|
#include "storage/sdmmc.h"
|
||||||
#include "utils/btn.h"
|
#include "utils/btn.h"
|
||||||
#include "utils/dirlist.h"
|
#include "utils/dirlist.h"
|
||||||
|
@ -945,6 +947,48 @@ out:
|
||||||
b_cfg.boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH);
|
b_cfg.boot_cfg &= ~(BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_LAUNCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void patched_rcm_protection()
|
||||||
|
{
|
||||||
|
sdmmc_storage_t storage;
|
||||||
|
sdmmc_t sdmmc;
|
||||||
|
|
||||||
|
h_cfg.rcm_patched = fuse_check_patched_rcm();
|
||||||
|
|
||||||
|
if (!h_cfg.rcm_patched)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if AutoRCM is enabled and protect from a permanent brick.
|
||||||
|
if (!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8 *tempbuf = (u8 *)malloc(0x200);
|
||||||
|
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||||
|
|
||||||
|
u8 corr_mod_byte0;
|
||||||
|
int i, sect = 0;
|
||||||
|
if ((fuse_read_odm(4) & 3) != 3)
|
||||||
|
corr_mod_byte0 = 0xF7;
|
||||||
|
else
|
||||||
|
corr_mod_byte0 = 0x37;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
sect = (0x200 + (0x4000 * i)) / NX_EMMC_BLOCKSIZE;
|
||||||
|
sdmmc_storage_read(&storage, sect, 1, tempbuf);
|
||||||
|
|
||||||
|
// If AutoRCM is enabled, disable it.
|
||||||
|
if (tempbuf[0x10] != corr_mod_byte0)
|
||||||
|
{
|
||||||
|
tempbuf[0x10] = corr_mod_byte0;
|
||||||
|
|
||||||
|
sdmmc_storage_write(&storage, sect, 1, tempbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tempbuf);
|
||||||
|
sdmmc_storage_end(&storage);
|
||||||
|
}
|
||||||
|
|
||||||
void about()
|
void about()
|
||||||
{
|
{
|
||||||
static const char credits[] =
|
static const char credits[] =
|
||||||
|
@ -1087,7 +1131,7 @@ ment_t ment_tools[] = {
|
||||||
//MDEF_HANDLER("Reset all battery cfg", reset_pmic_fuel_gauge_charger_config),
|
//MDEF_HANDLER("Reset all battery cfg", reset_pmic_fuel_gauge_charger_config),
|
||||||
//MDEF_HANDLER("Minerva", minerva), // Uncomment for testing Minerva Training Cell
|
//MDEF_HANDLER("Minerva", minerva), // Uncomment for testing Minerva Training Cell
|
||||||
MDEF_CHGLINE(),
|
MDEF_CHGLINE(),
|
||||||
MDEF_CAPTION("------ Dangerous -----", 0xFFFF0000),
|
MDEF_CAPTION("-------- Other -------", 0xFFFFDD00),
|
||||||
MDEF_HANDLER("AutoRCM", menu_autorcm),
|
MDEF_HANDLER("AutoRCM", menu_autorcm),
|
||||||
MDEF_END()
|
MDEF_END()
|
||||||
};
|
};
|
||||||
|
@ -1163,6 +1207,9 @@ void ipl_main()
|
||||||
// Check if we had a panic while in CFW.
|
// Check if we had a panic while in CFW.
|
||||||
secmon_exo_check_panic();
|
secmon_exo_check_panic();
|
||||||
|
|
||||||
|
// Check if RCM is patched and protect from a possible brick.
|
||||||
|
patched_rcm_protection();
|
||||||
|
|
||||||
// Load saved configuration and auto boot if enabled.
|
// Load saved configuration and auto boot if enabled.
|
||||||
auto_launch_firmware();
|
auto_launch_firmware();
|
||||||
|
|
||||||
|
|
|
@ -318,3 +318,32 @@ int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fuse_check_patched_rcm()
|
||||||
|
{
|
||||||
|
// Check if XUSB in use.
|
||||||
|
if (FUSE(FUSE_RESERVED_SW) & (1<<7))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Check if RCM is ipatched.
|
||||||
|
u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
||||||
|
u32 word_addr = 191;
|
||||||
|
|
||||||
|
while (word_count)
|
||||||
|
{
|
||||||
|
u32 word0 = fuse_read(word_addr);
|
||||||
|
u32 ipatch_count = (word0 >> 16) & 0xF;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < ipatch_count; i++)
|
||||||
|
{
|
||||||
|
u32 word = fuse_read(word_addr - (i + 1));
|
||||||
|
u32 addr = (word >> 16) * 2;
|
||||||
|
if (addr == 0x769A)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_addr -= word_count;
|
||||||
|
word_count = word0 >> 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#define FUSE_PRIVATE_KEY1 0x1A8
|
#define FUSE_PRIVATE_KEY1 0x1A8
|
||||||
#define FUSE_PRIVATE_KEY2 0x1AC
|
#define FUSE_PRIVATE_KEY2 0x1AC
|
||||||
#define FUSE_PRIVATE_KEY3 0x1B0
|
#define FUSE_PRIVATE_KEY3 0x1B0
|
||||||
|
#define FUSE_RESERVED_SW 0x1C0
|
||||||
|
|
||||||
/*! Fuse commands. */
|
/*! Fuse commands. */
|
||||||
#define FUSE_READ 0x1
|
#define FUSE_READ 0x1
|
||||||
|
@ -58,5 +59,6 @@ void fuse_wait_idle();
|
||||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||||
void fuse_read_array(u32 *words);
|
void fuse_read_array(u32 *words);
|
||||||
|
bool fuse_check_patched_rcm();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue