hekate/bootloader/frontend/fe_tools.c

162 lines
3.6 KiB
C
Raw Normal View History

2018-11-27 09:45:43 +00:00
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2022 CTCaer
2018-11-27 09:45:43 +00:00
* Copyright (c) 2018 Reisyukaku
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdlib.h>
2022-01-15 22:04:34 +00:00
#include <bdk.h>
2018-11-27 09:45:43 +00:00
#include "fe_tools.h"
#include "../config.h"
2018-11-27 09:45:43 +00:00
#include "../gfx/tui.h"
#include <libs/fatfs/ff.h>
2018-11-27 09:45:43 +00:00
extern boot_cfg_t b_cfg;
2018-11-27 09:45:43 +00:00
extern hekate_config h_cfg;
2019-06-30 00:15:46 +00:00
#pragma GCC push_options
#pragma GCC optimize ("Os")
2018-11-27 09:45:43 +00:00
void _toggle_autorcm(bool enable)
{
gfx_clear_partial_grey(0x1B, 0, 1256);
gfx_con_setpos(0, 0);
2018-11-27 09:45:43 +00:00
if (!emmc_initialize(false))
2018-11-27 09:45:43 +00:00
{
EPRINTF("Failed to init eMMC.");
goto out;
}
u8 *tempbuf = (u8 *)malloc(0x200);
2022-12-19 03:04:50 +00:00
emmc_set_partition(EMMC_BOOT0);
2018-11-27 09:45:43 +00:00
int i, sect = 0;
2020-12-26 14:38:21 +00:00
u8 corr_mod0, mod1;
2019-04-16 17:05:35 +00:00
2020-12-26 14:38:21 +00:00
// Get the correct RSA modulus byte masks.
nx_emmc_get_autorcm_masks(&corr_mod0, &mod1);
// Iterate BCTs.
2018-11-27 09:45:43 +00:00
for (i = 0; i < 4; i++)
{
sect = (0x200 + (0x4000 * i)) / EMMC_BLOCKSIZE;
sdmmc_storage_read(&emmc_storage, sect, 1, tempbuf);
2018-11-27 09:45:43 +00:00
2020-12-26 14:38:21 +00:00
// Check if 2nd byte of modulus is correct.
if (tempbuf[0x11] != mod1)
continue;
2018-11-27 09:45:43 +00:00
2020-12-26 14:38:21 +00:00
if (enable)
tempbuf[0x10] = 0;
2018-11-27 09:45:43 +00:00
else
2020-12-26 14:38:21 +00:00
tempbuf[0x10] = corr_mod0;
sdmmc_storage_write(&emmc_storage, sect, 1, tempbuf);
2018-11-27 09:45:43 +00:00
}
free(tempbuf);
2022-10-11 01:19:29 +00:00
emmc_end();
2018-11-27 09:45:43 +00:00
if (enable)
gfx_printf("%kAutoRCM mode enabled!%k", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
2018-11-27 09:45:43 +00:00
else
gfx_printf("%kAutoRCM mode disabled!%k", TXT_CLR_GREENISH, TXT_CLR_DEFAULT);
gfx_printf("\n\nPress any key...\n");
2018-11-27 09:45:43 +00:00
out:
btn_wait();
}
void _enable_autorcm() { _toggle_autorcm(true); }
void _disable_autorcm() { _toggle_autorcm(false); }
void menu_autorcm()
{
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
2018-11-27 09:45:43 +00:00
if (h_cfg.rcm_patched)
{
2021-10-15 13:26:57 +00:00
WPRINTF("This device is RCM patched and the\nfunction is disabled to avoid BRICKS!\n");
btn_wait();
return;
}
2018-11-27 09:45:43 +00:00
// Do a simple check on the main BCT.
bool disabled = true;
if (!emmc_initialize(false))
2018-11-27 09:45:43 +00:00
{
EPRINTF("Failed to init eMMC.");
btn_wait();
return;
}
2020-12-26 14:38:21 +00:00
u8 mod0, mod1;
// Get the correct RSA modulus byte masks.
nx_emmc_get_autorcm_masks(&mod0, &mod1);
2018-11-27 09:45:43 +00:00
u8 *tempbuf = (u8 *)malloc(0x200);
2022-12-19 03:04:50 +00:00
emmc_set_partition(EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, 0x200 / EMMC_BLOCKSIZE, 1, tempbuf);
2018-11-27 09:45:43 +00:00
2020-12-26 14:38:21 +00:00
// Check if 2nd byte of modulus is correct.
if (tempbuf[0x11] == mod1)
if (tempbuf[0x10] != mod0)
2019-04-16 17:05:35 +00:00
disabled = false;
2018-11-27 09:45:43 +00:00
free(tempbuf);
2022-10-11 01:19:29 +00:00
emmc_end();
2018-11-27 09:45:43 +00:00
// Create AutoRCM menu.
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
ments[0].type = MENT_BACK;
ments[0].caption = "Back";
ments[1].type = MENT_CHGLINE;
ments[2].type = MENT_CAPTION;
ments[3].type = MENT_CHGLINE;
if (disabled)
{
ments[2].caption = "Status: Disabled!";
ments[2].color = TXT_CLR_GREENISH;
2018-11-27 09:45:43 +00:00
ments[4].caption = "Enable AutoRCM";
ments[4].handler = _enable_autorcm;
}
else
{
ments[2].caption = "Status: Enabled!";
ments[2].color = TXT_CLR_ORANGE;
2018-11-27 09:45:43 +00:00
ments[4].caption = "Disable AutoRCM";
ments[4].handler = _disable_autorcm;
}
ments[4].type = MENT_HDLR_RE;
ments[4].data = NULL;
2018-11-27 09:45:43 +00:00
memset(&ments[5], 0, sizeof(ment_t));
2021-01-11 19:39:44 +00:00
menu_t menu = {ments, "This corrupts BOOT0!", 0, 0};
2018-11-27 09:45:43 +00:00
tui_do_menu(&menu);
2018-11-27 09:45:43 +00:00
}
2019-06-30 00:15:46 +00:00
#pragma GCC pop_options