mirror of
https://github.com/Decscots/Lockpick_RCM
synced 2024-12-18 22:01:13 +00:00
261 lines
6.6 KiB
C
261 lines
6.6 KiB
C
/*
|
|
* Copyright (c) 2018 naehrwert
|
|
*
|
|
* Copyright (c) 2018-2019 CTCaer
|
|
*
|
|
* 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 "config/config.h"
|
|
#include "gfx/di.h"
|
|
#include "gfx/gfx.h"
|
|
#include "gfx/tui.h"
|
|
#include "hos/pkg1.h"
|
|
#include "libs/fatfs/ff.h"
|
|
#include "mem/heap.h"
|
|
#include "mem/minerva.h"
|
|
#include "power/max77620.h"
|
|
#include "rtc/max77620-rtc.h"
|
|
#include "soc/bpmp.h"
|
|
#include "soc/hw_init.h"
|
|
#include "storage/emummc.h"
|
|
#include "storage/nx_emmc.h"
|
|
#include "storage/sdmmc.h"
|
|
#include "utils/sprintf.h"
|
|
#include "utils/util.h"
|
|
|
|
#include "keys/keys.h"
|
|
|
|
sdmmc_t sd_sdmmc;
|
|
sdmmc_storage_t sd_storage;
|
|
__attribute__ ((aligned (16))) FATFS sd_fs;
|
|
static bool sd_mounted;
|
|
|
|
hekate_config h_cfg;
|
|
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
|
|
|
|
bool sd_mount()
|
|
{
|
|
if (sd_mounted)
|
|
return true;
|
|
|
|
if (!sdmmc_storage_init_sd(&sd_storage, &sd_sdmmc, SDMMC_1, SDMMC_BUS_WIDTH_4, 11))
|
|
{
|
|
EPRINTF("Failed to init SD card.\nMake sure that it is inserted.\nOr that SD reader is properly seated!");
|
|
}
|
|
else
|
|
{
|
|
int res = 0;
|
|
res = f_mount(&sd_fs, "sd:", 1);
|
|
if (res == FR_OK)
|
|
{
|
|
sd_mounted = 1;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
EPRINTFARGS("Failed to mount SD card (FatFS Error %d).\nMake sure that a FAT partition exists..", res);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void sd_unmount()
|
|
{
|
|
if (sd_mounted)
|
|
{
|
|
f_mount(NULL, "sd:", 1);
|
|
sdmmc_storage_end(&sd_storage);
|
|
sd_mounted = false;
|
|
}
|
|
}
|
|
|
|
void *sd_file_read(const char *path, u32 *fsize)
|
|
{
|
|
FIL fp;
|
|
if (f_open(&fp, path, FA_READ) != FR_OK)
|
|
return NULL;
|
|
|
|
u32 size = f_size(&fp);
|
|
if (fsize)
|
|
*fsize = size;
|
|
|
|
void *buf = malloc(size);
|
|
|
|
if (f_read(&fp, buf, size, NULL) != FR_OK)
|
|
{
|
|
free(buf);
|
|
f_close(&fp);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
f_close(&fp);
|
|
|
|
return buf;
|
|
}
|
|
|
|
int sd_save_to_file(void *buf, u32 size, const char *filename)
|
|
{
|
|
FIL fp;
|
|
u32 res = 0;
|
|
res = f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE);
|
|
if (res)
|
|
{
|
|
EPRINTFARGS("Error (%d) creating file\n%s.\n", res, filename);
|
|
return res;
|
|
}
|
|
|
|
f_write(&fp, buf, size, NULL);
|
|
f_close(&fp);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// This is a safe and unused DRAM region for our payloads.
|
|
#define RELOC_META_OFF 0x7C
|
|
#define PATCHED_RELOC_SZ 0x94
|
|
#define PATCHED_RELOC_STACK 0x40007000
|
|
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
|
#define CBFS_DRAM_EN_ADDR 0x4003e000
|
|
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
|
|
|
|
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
|
{
|
|
memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
|
|
|
|
volatile reloc_meta_t *relocator = (reloc_meta_t *)(payload_src + RELOC_META_OFF);
|
|
|
|
relocator->start = payload_dst - ALIGN(PATCHED_RELOC_SZ, 0x10);
|
|
relocator->stack = PATCHED_RELOC_STACK;
|
|
relocator->end = payload_dst + payload_size;
|
|
relocator->ep = payload_dst;
|
|
|
|
if (payload_size == 0x7000)
|
|
{
|
|
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
|
|
*(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
|
|
}
|
|
}
|
|
|
|
void dump_sysnand()
|
|
{
|
|
h_cfg.emummc_force_disable = true;
|
|
b_cfg.extra_cfg &= ~EXTRA_CFG_DUMP_EMUMMC;
|
|
dump_keys();
|
|
}
|
|
|
|
void dump_emunand()
|
|
{
|
|
if (h_cfg.emummc_force_disable)
|
|
return;
|
|
emu_cfg.enabled = 1;
|
|
b_cfg.extra_cfg |= EXTRA_CFG_DUMP_EMUMMC;
|
|
dump_keys();
|
|
}
|
|
|
|
ment_t ment_top[] = {
|
|
MDEF_HANDLER("Dump from SysNAND | Key generation: unk", dump_sysnand, COLOR_RED),
|
|
MDEF_HANDLER("Dump from EmuNAND | Key generation: unk", dump_emunand, COLOR_ORANGE),
|
|
MDEF_CAPTION("---------------", COLOR_YELLOW),
|
|
MDEF_HANDLER("Reboot (Normal)", reboot_normal, COLOR_GREEN),
|
|
MDEF_HANDLER("Reboot (RCM)", reboot_rcm, COLOR_BLUE),
|
|
MDEF_HANDLER("Power off", power_off, COLOR_VIOLET),
|
|
MDEF_END()
|
|
};
|
|
|
|
menu_t menu_top = { ment_top, NULL, 0, 0 };
|
|
|
|
void _get_key_generations(char *sysnand_label, char *emunand_label) {
|
|
sdmmc_t sdmmc;
|
|
sdmmc_storage_t storage;
|
|
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
|
u8 *pkg1 = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
|
sdmmc_storage_set_mmc_partition(&storage, 1);
|
|
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 1, pkg1);
|
|
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
|
sdmmc_storage_end(&storage);
|
|
|
|
if (pkg1_id)
|
|
sprintf(sysnand_label + 36, "% 3d", pkg1_id->kb);
|
|
ment_top[0].caption = sysnand_label;
|
|
if (h_cfg.emummc_force_disable) {
|
|
free(pkg1);
|
|
return;
|
|
}
|
|
|
|
emummc_storage_init_mmc(&storage, &sdmmc);
|
|
memset(pkg1, 0, NX_EMMC_BLOCKSIZE);
|
|
emummc_storage_set_mmc_partition(&storage, 1);
|
|
emummc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 1, pkg1);
|
|
pkg1_id = pkg1_identify(pkg1);
|
|
emummc_storage_end(&storage);
|
|
|
|
if (pkg1_id)
|
|
sprintf(emunand_label + 36, "% 3d", pkg1_id->kb);
|
|
free(pkg1);
|
|
ment_top[1].caption = emunand_label;
|
|
}
|
|
|
|
#define IPL_STACK_TOP 0x90010000
|
|
#define IPL_HEAP_START 0x90020000
|
|
|
|
extern void pivot_stack(u32 stack_top);
|
|
|
|
void ipl_main()
|
|
{
|
|
config_hw();
|
|
pivot_stack(IPL_STACK_TOP);
|
|
heap_init(IPL_HEAP_START);
|
|
|
|
set_default_configuration();
|
|
|
|
sd_mount();
|
|
minerva_init();
|
|
minerva_change_freq(FREQ_1600);
|
|
|
|
display_init();
|
|
u32 *fb = display_init_framebuffer();
|
|
gfx_init_ctxt(fb, 720, 1280, 720);
|
|
gfx_con_init();
|
|
display_backlight_pwm_init();
|
|
|
|
bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);
|
|
|
|
h_cfg.emummc_force_disable = emummc_load_cfg();
|
|
|
|
if (b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN)
|
|
{
|
|
if (!(b_cfg.extra_cfg & EXTRA_CFG_DUMP_EMUMMC))
|
|
h_cfg.emummc_force_disable = true;
|
|
dump_keys();
|
|
}
|
|
|
|
if (h_cfg.emummc_force_disable)
|
|
{
|
|
ment_top[1].type = MENT_CAPTION;
|
|
ment_top[1].color = 0xFF555555;
|
|
ment_top[1].handler = NULL;
|
|
}
|
|
|
|
_get_key_generations((char *)ment_top[0].caption, (char *)ment_top[1].caption);
|
|
|
|
while (true)
|
|
tui_do_menu(&menu_top);
|
|
|
|
while (true)
|
|
bpmp_halt();
|
|
}
|