Update to hekate bdk 5.5.6

This commit is contained in:
shchmue 2021-05-12 15:38:34 -06:00
parent 93909f149e
commit a7712b173c
95 changed files with 2720 additions and 1684 deletions

View file

@ -49,6 +49,7 @@ void set_default_configuration()
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
h_cfg.aes_slots_new = false;
h_cfg.rcm_patched = fuse_check_patched_rcm();
h_cfg.sbk_set = FUSE(FUSE_PRIVATE_KEY0) == 0xFFFFFFFF;
h_cfg.emummc_force_disable = false;
h_cfg.t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;

View file

@ -38,6 +38,7 @@ typedef struct _hekate_config
bool aes_slots_new;
bool emummc_force_disable;
bool rcm_patched;
bool sbk_set;
u32 errors;
hos_eks_mbr_t *eks;
} hekate_config;

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2019-2020 shchmue
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2019-2021 shchmue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -24,6 +24,8 @@
gfx_ctxt_t gfx_ctxt;
gfx_con_t gfx_con;
static bool gfx_con_init_done = false;
static const u8 _gfx_font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )
0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00, // Char 033 (!)
@ -158,6 +160,8 @@ void gfx_con_init()
gfx_con.fillbg = 1;
gfx_con.bgcol = 0xFF1B1B1B;
gfx_con.mute = 0;
gfx_con_init_done = true;
}
void gfx_con_setcol(u32 fgcol, int fillbg, u32 bgcol)
@ -274,7 +278,7 @@ void gfx_putc(char c)
void gfx_puts(const char *s)
{
if (!s || gfx_con.mute)
if (!s || !gfx_con_init_done || gfx_con.mute)
return;
for (; *s; s++)
@ -330,7 +334,7 @@ void gfx_put_big_sep()
void gfx_printf(const char *fmt, ...)
{
if (gfx_con.mute)
if (!gfx_con_init_done || gfx_con.mute)
return;
va_list ap;
@ -404,11 +408,13 @@ void gfx_printf(const char *fmt, ...)
va_end(ap);
}
void gfx_hexdump(u32 base, const u8 *buf, u32 len)
void gfx_hexdump(u32 base, const void *buf, u32 len)
{
if (gfx_con.mute)
if (!gfx_con_init_done || gfx_con.mute)
return;
u8 *buff = (u8 *)buf;
u8 prevFontSize = gfx_con.fntsz;
gfx_con.fntsz = 8;
for(u32 i = 0; i < len; i++)
@ -420,7 +426,7 @@ void gfx_hexdump(u32 base, const u8 *buf, u32 len)
gfx_puts("| ");
for(u32 j = 0; j < 0x10; j++)
{
u8 c = buf[i - 0x10 + j];
u8 c = buff[i - 0x10 + j];
if(c >= 32 && c <= 126)
gfx_putc(c);
else
@ -430,7 +436,7 @@ void gfx_hexdump(u32 base, const u8 *buf, u32 len)
}
gfx_printf("%08x: ", base + i);
}
gfx_printf("%02x ", buf[i]);
gfx_printf("%02x ", buff[i]);
if (i == len - 1)
{
int ln = len % 0x10 != 0;
@ -444,7 +450,7 @@ void gfx_hexdump(u32 base, const u8 *buf, u32 len)
gfx_puts("| ");
for(u32 j = 0; j < (ln ? k : k + 1); j++)
{
u8 c = buf[i - k + j];
u8 c = buff[i - k + j];
if(c >= 32 && c <= 126)
gfx_putc(c);
else
@ -457,12 +463,15 @@ void gfx_hexdump(u32 base, const u8 *buf, u32 len)
gfx_con.fntsz = prevFontSize;
}
void gfx_hexdiff(u32 base, const u8 *buf1, const u8 *buf2, u32 len)
void gfx_hexdiff(u32 base, const void *buf1, const void *buf2, u32 len)
{
if (gfx_con.mute)
if (!gfx_con_init_done || gfx_con.mute)
return;
if (memcmp(buf1, buf2, len) == 0)
u8 *buff1 = (u8 *)buf1;
u8 *buff2 = (u8 *)buf2;
if (memcmp(buff1, buff2, len) == 0)
{
gfx_printf("Diff: No differences found.\n");
return;
@ -473,14 +482,14 @@ void gfx_hexdiff(u32 base, const u8 *buf1, const u8 *buf2, u32 len)
for(u32 i = 0; i < len; i+=0x10)
{
u32 bytes_left = len - i < 0x10 ? len - i : 0x10;
if (memcmp(buf1 + i, buf2 + i, bytes_left) == 0)
if (memcmp(buff1 + i, buff2 + i, bytes_left) == 0)
continue;
gfx_printf("Diff 1: %08x: ", base + i);
for (u32 j = 0; j < bytes_left; j++)
{
if (buf1[i+j] != buf2[i+j])
if (buff1[i+j] != buff2[i+j])
gfx_con.fgcol = COLOR_ORANGE;
gfx_printf("%02x ", buf1[i+j]);
gfx_printf("%02x ", buff1[i+j]);
gfx_con.fgcol = 0xFFCCCCCC;
}
gfx_puts("| ");
@ -488,9 +497,9 @@ void gfx_hexdiff(u32 base, const u8 *buf1, const u8 *buf2, u32 len)
gfx_printf("Diff 2: %08x: ", base + i);
for (u32 j = 0; j < bytes_left; j++)
{
if (buf1[i+j] != buf2[i+j])
if (buff1[i+j] != buff2[i+j])
gfx_con.fgcol = COLOR_ORANGE;
gfx_printf("%02x ", buf2[i+j]);
gfx_printf("%02x ", buff2[i+j]);
gfx_con.fgcol = 0xFFCCCCCC;
}
gfx_puts("| ");

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2019-2021 shchmue
* Copyright (c) 2018 M4xw
*
* This program is free software; you can redistribute it and/or modify it
@ -63,8 +64,8 @@ void gfx_con_setpos(u32 x, u32 y);
void gfx_putc(char c);
void gfx_puts(const char *s);
void gfx_printf(const char *fmt, ...);
void gfx_hexdump(u32 base, const u8 *buf, u32 len);
void gfx_hexdiff(u32 base, const u8 *buf1, const u8 *buf2, u32 len);
void gfx_hexdump(u32 base, const void *buf, u32 len);
void gfx_hexdiff(u32 base, const void *buf1, const void *buf2, u32 len);
void gfx_set_pixel(u32 x, u32 y, u32 color);
void gfx_line(int x0, int y0, int x1, int y1, u32 color);

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gfx/di.h>
#include <display/di.h>
#include "tui.h"
#include "../config.h"
#include <power/max17050.h>
@ -77,7 +77,7 @@ void tui_pbar(int x, int y, u32 val, u32 fgcol, u32 bgcol)
x += 7 * gfx_con.fntsz;
for (int i = 0; i < (gfx_con.fntsz >> 3) * 6; i++)
for (u32 i = 0; i < (gfx_con.fntsz >> 3) * 6; i++)
{
gfx_line(x, y + i + 1, x + 3 * val, y + i + 1, fgcol);
gfx_line(x + 3 * val, y + i + 1, x + 3 * 100, y + i + 1, bgcol);

View file

@ -139,7 +139,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
if (mariko_not_supported)
{
EPRINTF("Mariko not supported on < 0.17.0!");
EPRINTF("\nMariko not supported on < 0.17.0!");
goto fail;
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 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,
@ -20,6 +20,7 @@
#include "pkg1.h"
#include "pkg2.h"
#include <sec/se_t210.h>
#include <utils/types.h>
#include <utils/ini.h>
#include <sec/tsec.h>
@ -50,20 +51,21 @@ typedef struct _exo_ctxt_t
bool fs_is_510;
bool no_user_exceptions;
bool user_pmu;
bool *usb3_force;
bool *cal0_blank;
bool *cal0_allow_writes_sys;
} exo_ctxt_t;
typedef struct _hos_eks_keys_t
{
u8 mkk[0x10];
u8 fdk[0x10];
u8 mkk[SE_KEY_128_SIZE];
u8 fdk[SE_KEY_128_SIZE];
} hos_eks_keys_t;
typedef struct _hos_eks_bis_keys_t
{
u8 crypt[0x10];
u8 tweak[0x10];
u8 crypt[SE_KEY_128_SIZE];
u8 tweak[SE_KEY_128_SIZE];
} hos_eks_bis_keys_t;
typedef struct _hos_eks_mbr_t
@ -73,8 +75,8 @@ typedef struct _hos_eks_mbr_t
u8 enabled_bis;
u8 rsvd[2];
u32 lot0;
u8 dkg[0x10];
u8 dkk[0x10];
u8 dkg[SE_KEY_128_SIZE];
u8 dkk[SE_KEY_128_SIZE];
hos_eks_keys_t keys[5];
hos_eks_bis_keys_t bis_keys[3];
} hos_eks_mbr_t;
@ -106,14 +108,16 @@ typedef struct _launch_ctxt_t
link_t kip1_list;
char* kip1_patches;
u32 fss0_hosver;
bool svcperm;
bool debugmode;
bool stock;
bool atmosphere;
bool fss0_experimental;
bool emummc_forced;
char *fss0_main_path;
u32 fss0_hosver;
bool fss0_experimental;
bool atmosphere;
exo_ctxt_t exo_ctx;
ini_sec_t *cfg;
@ -129,6 +133,6 @@ void hos_eks_get();
void hos_eks_save(u32 kb);
void hos_eks_clear(u32 kb);
int hos_launch(ini_sec_t *cfg);
int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt);
int hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt);
#endif

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@ -46,7 +46,7 @@ static const pkg1_id_t _pkg1_ids[] = {
const pkg1_id_t *pkg1_identify(u8 *pkg1)
{
for (u32 i = 0; _pkg1_ids[i].id; i++)
for (u32 i = 0; i < ARRAY_SIZE(_pkg1_ids); i++)
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 8))
return &_pkg1_ids[i];
return NULL;

View file

@ -21,7 +21,7 @@
#include "sept.h"
#include "../config.h"
#include <utils/ini.h>
#include <gfx/di.h>
#include <display/di.h>
#include <libs/fatfs/ff.h>
#include <mem/heap.h>
#include <soc/hw_init.h>

View file

@ -17,7 +17,7 @@
#include "keys.h"
#include "../config.h"
#include <gfx/di.h>
#include <display/di.h>
#include <gfx_utils.h>
#include "../gfx/tui.h"
#include "../hos/pkg1.h"
@ -93,8 +93,8 @@ static ALWAYS_INLINE u32 _get_tsec_fw_size(tsec_key_data_t *key_data) {
return key_data->blob0_size + sizeof(tsec_key_data_t) + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size;
}
static u8 *_read_pkg1(sdmmc_t *sdmmc, const pkg1_id_t **pkg1_id) {
if (emummc_storage_init_mmc(&emmc_storage, sdmmc)) {
static u8 *_read_pkg1(const pkg1_id_t **pkg1_id) {
if (emummc_storage_init_mmc()) {
EPRINTF("Unable to init MMC.");
return NULL;
}
@ -102,11 +102,11 @@ static u8 *_read_pkg1(sdmmc_t *sdmmc, const pkg1_id_t **pkg1_id) {
// Read package1.
u8 *pkg1 = (u8 *)malloc(PKG1_MAX_SIZE);
if (!emummc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0)) {
if (!emummc_storage_set_mmc_partition(EMMC_BOOT0)) {
EPRINTF("Unable to set partition.");
return NULL;
}
if (!emummc_storage_read(&emmc_storage, PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1)) {
if (!emummc_storage_read(PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1)) {
EPRINTF("Unable to read pkg1.");
return NULL;
}
@ -283,7 +283,7 @@ static void _derive_master_keys_from_keyblobs(key_derivation_ctx_t *keys) {
se_aes_key_set(8, keys->tsec_keys, sizeof(keys->tsec_keys) / 2);
if (!emummc_storage_read(&emmc_storage, KEYBLOB_OFFSET / NX_EMMC_BLOCKSIZE, KB_FIRMWARE_VERSION_600 + 1, keyblob_block)) {
if (!emummc_storage_read(KEYBLOB_OFFSET / NX_EMMC_BLOCKSIZE, KB_FIRMWARE_VERSION_600 + 1, keyblob_block)) {
EPRINTF("Unable to read keyblobs.");
}
@ -577,7 +577,7 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
rsa_keypair_t rsa_keypair = {0};
if (!emummc_storage_read(&emmc_storage, NX_EMMC_CALIBRATION_OFFSET / NX_EMMC_BLOCKSIZE, NX_EMMC_CALIBRATION_SIZE / NX_EMMC_BLOCKSIZE, titlekey_buffer->read_buffer)) {
if (!emummc_storage_read(NX_EMMC_CALIBRATION_OFFSET / NX_EMMC_BLOCKSIZE, NX_EMMC_CALIBRATION_SIZE / NX_EMMC_BLOCKSIZE, titlekey_buffer->read_buffer)) {
EPRINTF("Unable to read PRODINFO.");
return false;
}
@ -643,7 +643,7 @@ static bool _derive_emmc_keys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
se_aes_key_set(4, keys->bis_key[2] + 0x00, AES_128_KEY_SIZE);
se_aes_key_set(5, keys->bis_key[2] + 0x10, AES_128_KEY_SIZE);
if (!emummc_storage_set_mmc_partition(&emmc_storage, EMMC_GPP)) {
if (!emummc_storage_set_mmc_partition(EMMC_GPP)) {
EPRINTF("Unable to set partition.");
return false;
}
@ -690,7 +690,7 @@ static void _save_mariko_partial_keys(char *text_buffer) {
for (u32 ks = 12; ks < 16; ks++) {
// First, encrypt zeros with complete key
se_aes_crypt_block_ecb(ks, 1, &data[3 * AES_128_KEY_SIZE], zeros);
pos += sprintf(&text_buffer[pos], "%d\n", ks);
pos += s_printf(&text_buffer[pos], "%d\n", ks);
// We only need to overwrite 3 of the dwords of the key
for (u32 i = 0; i < 3; i++) {
@ -701,8 +701,8 @@ static void _save_mariko_partial_keys(char *text_buffer) {
}
for (u32 i = 0; i < 4; i++) {
for (u32 j = 0; j < AES_128_KEY_SIZE; j++)
pos += sprintf(&text_buffer[pos], "%02x", data[i * AES_128_KEY_SIZE + j]);
pos += sprintf(&text_buffer[pos], "\n");
pos += s_printf(&text_buffer[pos], "%02x", data[i * AES_128_KEY_SIZE + j]);
pos += s_printf(&text_buffer[pos], "\n");
}
}
free(data);
@ -788,7 +788,7 @@ static void _save_keys_to_sd(key_derivation_ctx_t *keys, titlekey_buffer_t *titl
f_mkdir("sd:/switch");
char keyfile_path[30] = "sd:/switch/prod.keys";
if (fuse_read_odm(4) & 3)
sprintf(&keyfile_path[11], "dev.keys");
s_printf(&keyfile_path[11], "dev.keys");
FILINFO fno;
if (!sd_save_to_file(text_buffer, strlen(text_buffer), keyfile_path) && !f_stat(keyfile_path, &fno)) {
@ -811,13 +811,13 @@ static void _save_keys_to_sd(key_derivation_ctx_t *keys, titlekey_buffer_t *titl
for (u32 i = 0; i < _titlekey_count; i++) {
for (u32 j = 0; j < AES_128_KEY_SIZE; j++)
sprintf(&titlekey_text[i].rights_id[j * 2], "%02x", titlekey_buffer->rights_ids[i][j]);
sprintf(titlekey_text[i].equals, " = ");
s_printf(&titlekey_text[i].rights_id[j * 2], "%02x", titlekey_buffer->rights_ids[i][j]);
s_printf(titlekey_text[i].equals, " = ");
for (u32 j = 0; j < AES_128_KEY_SIZE; j++)
sprintf(&titlekey_text[i].titlekey[j * 2], "%02x", titlekey_buffer->titlekeys[i][j]);
sprintf(titlekey_text[i].newline, "\n");
s_printf(&titlekey_text[i].titlekey[j * 2], "%02x", titlekey_buffer->titlekeys[i][j]);
s_printf(titlekey_text[i].newline, "\n");
}
sprintf(&keyfile_path[11], "title.keys");
s_printf(&keyfile_path[11], "title.keys");
if (!sd_save_to_file(text_buffer, strlen(text_buffer), keyfile_path) && !f_stat(keyfile_path, &fno)) {
gfx_printf("%kWrote %d bytes to %s\n", colors[(color_idx++) % 6], (u32)fno.fsize, keyfile_path);
} else
@ -828,10 +828,9 @@ static void _save_keys_to_sd(key_derivation_ctx_t *keys, titlekey_buffer_t *titl
static void _derive_keys() {
u32 start_whole_operation_time = get_tmr_us();
sdmmc_t sdmmc;
const pkg1_id_t *pkg1_id;
u8 *pkg1 = _read_pkg1(&sdmmc, &pkg1_id);
u8 *pkg1 = _read_pkg1(&pkg1_id);
if (!pkg1) {
return;
}
@ -909,17 +908,17 @@ static void _save_key(const char *name, const void *data, u32 len, char *outbuf)
if (!_key_exists(data))
return;
u32 pos = strlen(outbuf);
pos += sprintf(&outbuf[pos], "%s = ", name);
pos += s_printf(&outbuf[pos], "%s = ", name);
for (u32 i = 0; i < len; i++)
pos += sprintf(&outbuf[pos], "%02x", *(u8*)(data + i));
sprintf(&outbuf[pos], "\n");
pos += s_printf(&outbuf[pos], "%02x", *(u8*)(data + i));
s_printf(&outbuf[pos], "\n");
_key_count++;
}
static void _save_key_family(const char *name, const void *data, u32 start_key, u32 num_keys, u32 len, char *outbuf) {
char *temp_name = calloc(1, 0x40);
for (u32 i = 0; i < num_keys; i++) {
sprintf(temp_name, "%s_%02x", name, i + start_key);
s_printf(temp_name, "%s_%02x", name, i + start_key);
_save_key(temp_name, data + i * len, len, outbuf);
}
free(temp_name);

View file

@ -245,7 +245,7 @@
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2020
#define FF_NORTC_YEAR 2021
/* The option FF_FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp

View file

@ -5,7 +5,8 @@ SECTIONS {
. = __ipl_start;
.text : {
*(.text._start);
*(._boot_cfg);
KEEP(*(._boot_cfg));
*(.text._irq_setup);
*(.text*);
}
.data : {

View file

@ -1,8 +1,8 @@
/*
* Copyright (c) 2018 naehrwert
*
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2019-2020 shchmue
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2019-2021 shchmue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -20,7 +20,7 @@
#include <string.h>
#include "config.h"
#include <gfx/di.h>
#include <display/di.h>
#include <gfx_utils.h>
#include "gfx/tui.h"
#include <libs/fatfs/ff.h>
@ -57,6 +57,7 @@ volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
#define EXT_PAYLOAD_ADDR 0xC0000000
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
#define COREBOOT_END_ADDR 0xD0000000
#define COREBOOT_VER_OFF 0x41
#define CBFS_DRAM_EN_ADDR 0x4003e000
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
@ -80,9 +81,10 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
}
}
int launch_payload(char *path)
int launch_payload(char *path, bool clear_screen)
{
gfx_clear_grey(0x1B);
if (clear_screen)
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
if (!path)
return 1;
@ -92,10 +94,10 @@ int launch_payload(char *path)
FIL fp;
if (f_open(&fp, path, FA_READ))
{
gfx_con.mute = false;
EPRINTFARGS("Payload file is missing!\n(%s)", path);
sd_unmount();
return 1;
goto out;
}
// Read and copy the payload to our chosen address
@ -108,19 +110,27 @@ int launch_payload(char *path)
{
coreboot_addr = (void *)(COREBOOT_END_ADDR - size);
buf = coreboot_addr;
if (h_cfg.t210b01)
{
f_close(&fp);
gfx_con.mute = false;
EPRINTF("Coreboot not allowed on Mariko!");
goto out;
}
}
if (f_read(&fp, buf, size, NULL))
{
f_close(&fp);
sd_unmount();
return 1;
goto out;
}
f_close(&fp);
sd_unmount();
sd_end();
if (size < 0x30000)
{
@ -131,7 +141,12 @@ int launch_payload(char *path)
else
{
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000);
hw_reinit_workaround(true, 0);
// Get coreboot seamless display magic.
u32 magic = 0;
char *magic_ptr = buf + COREBOOT_VER_OFF;
memcpy(&magic, magic_ptr + strlen(magic_ptr) - 4, 4);
hw_reinit_workaround(true, magic);
}
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
@ -143,6 +158,8 @@ int launch_payload(char *path)
(*ext_payload_ptr)();
}
out:
sd_end();
return 1;
}
@ -221,7 +238,8 @@ void launch_tools()
free(ments);
free(dir);
free(filelist);
sd_unmount();
sd_end();
return;
}
}
@ -247,15 +265,12 @@ void launch_tools()
else
memcpy(dir, file_sec, strlen(file_sec) + 1);
if (launch_payload(dir))
{
EPRINTF("Failed to launch payload.");
free(dir);
}
launch_payload(dir, true);
EPRINTF("Failed to launch payload.");
}
out:
sd_unmount();
sd_end();
free(dir);
btn_wait();
@ -278,15 +293,20 @@ void dump_emunand()
dump_keys();
}
power_state_t STATE_POWER_OFF = POWER_OFF_RESET;
power_state_t STATE_REBOOT_FULL = POWER_OFF_REBOOT;
power_state_t STATE_REBOOT_RCM = REBOOT_RCM;
power_state_t STATE_REBOOT_BYPASS_FUSES = REBOOT_BYPASS_FUSES;
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("Payloads...", launch_tools, COLOR_GREEN),
MDEF_CAPTION("---------------", COLOR_BLUE),
MDEF_HANDLER("Reboot (Normal)", reboot_normal, COLOR_VIOLET),
MDEF_HANDLER("Reboot (RCM)", reboot_rcm, COLOR_RED),
MDEF_HANDLER("Power off", power_off, COLOR_ORANGE),
MDEF_HANDLER_EX("Reboot (OFW)", &STATE_REBOOT_BYPASS_FUSES, power_set_state_ex, COLOR_VIOLET),
MDEF_HANDLER_EX("Reboot (RCM)", &STATE_REBOOT_RCM, power_set_state_ex, COLOR_RED),
MDEF_HANDLER_EX("Power off", &STATE_POWER_OFF, power_set_state_ex, COLOR_ORANGE),
MDEF_END()
};
@ -305,7 +325,7 @@ void _get_key_generations(char *sysnand_label, char *emunand_label)
u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1 + pk1_offset);
if (pkg1_id) {
sprintf(sysnand_label + 36, "% 3d", pkg1_id->kb);
s_printf(sysnand_label + 36, "% 3d", pkg1_id->kb);
ment_top[0].caption = sysnand_label;
if (h_cfg.emummc_force_disable)
{
@ -314,15 +334,15 @@ void _get_key_generations(char *sysnand_label, char *emunand_label)
}
}
emummc_storage_init_mmc(&storage, &sdmmc);
emummc_storage_init_mmc();
memset(pkg1, 0, PKG1_MAX_SIZE);
emummc_storage_set_mmc_partition(&storage, EMMC_BOOT0);
emummc_storage_read(&storage, PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
emummc_storage_end(&storage);
emummc_storage_set_mmc_partition(EMMC_BOOT0);
emummc_storage_read(PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1);
emummc_storage_end();
pkg1_id = pkg1_identify(pkg1 + pk1_offset);
if (pkg1_id) {
sprintf(emunand_label + 36, "% 3d", pkg1_id->kb);
s_printf(emunand_label + 36, "% 3d", pkg1_id->kb);
free(pkg1);
ment_top[1].caption = emunand_label;
}
@ -367,8 +387,9 @@ void ipl_main()
display_backlight_pwm_init();
// Overclock BPMP.
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
// Load emuMMC configuration from SD.
emummc_load_cfg();
// Ignore whether emummc is enabled.
h_cfg.emummc_force_disable = emu_cfg.sector == 0 && !emu_cfg.path;
@ -401,7 +422,7 @@ void ipl_main()
if (h_cfg.rcm_patched)
{
ment_top[5].handler = reboot_full;
ment_top[6].data = &STATE_REBOOT_FULL;
}
// Update key generations listed in menu.

View file

@ -23,8 +23,8 @@
.extern memset
.type memset, %function
.extern ipl_main
.type ipl_main, %function
.extern _irq_setup
.type _irq_setup, %function
.globl _start
.type _start, %function
@ -67,7 +67,7 @@ _real_start:
LDR R2, =__bss_end
SUB R2, R2, R0
BL memset
BL ipl_main
BL _irq_setup
B .
.globl pivot_stack

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2021 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,
@ -131,13 +131,13 @@ static int emummc_raw_get_part_off(int part_idx)
return 2;
}
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc)
int emummc_storage_init_mmc()
{
FILINFO fno;
emu_cfg.active_part = 0;
// Always init eMMC even when in emuMMC. eMMC is needed from the emuMMC driver anyway.
if (!sdmmc_storage_init_mmc(storage, sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400))
if (!sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400))
return 2;
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
@ -173,21 +173,21 @@ out:
return 1;
}
int emummc_storage_end(sdmmc_storage_t *storage)
int emummc_storage_end()
{
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
sdmmc_storage_end(storage);
sdmmc_storage_end(&emmc_storage);
else
sd_end();
return 1;
}
int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
int emummc_storage_read(u32 sector, u32 num_sectors, void *buf)
{
FIL fp;
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
return sdmmc_storage_read(storage, sector, num_sectors, buf);
return sdmmc_storage_read(&emmc_storage, sector, num_sectors, buf);
else if (emu_cfg.sector)
{
sector += emu_cfg.sector;
@ -228,11 +228,11 @@ int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, v
return 1;
}
int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
int emummc_storage_write(u32 sector, u32 num_sectors, void *buf)
{
FIL fp;
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
return sdmmc_storage_write(storage, sector, num_sectors, buf);
return sdmmc_storage_write(&emmc_storage, sector, num_sectors, buf);
else if (emu_cfg.sector)
{
sector += emu_cfg.sector;
@ -253,15 +253,13 @@ int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors,
itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
}
}
if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_WRITE))
{
gfx_printf("e5\n");
return 0;
}
f_lseek(&fp, (u64)sector << 9);
if (f_write(&fp, buf, (u64)num_sectors << 9, NULL))
{
gfx_printf("e6\n");
f_close(&fp);
return 0;
}
@ -271,13 +269,12 @@ int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors,
}
}
int emummc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition)
int emummc_storage_set_mmc_partition(u32 partition)
{
emu_cfg.active_part = partition;
sdmmc_storage_set_mmc_partition(&emmc_storage, partition);
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
sdmmc_storage_set_mmc_partition(storage, partition);
else if (emu_cfg.sector)
if (!emu_cfg.enabled || h_cfg.emummc_force_disable || emu_cfg.sector)
return 1;
else
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2021 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,
@ -51,10 +51,10 @@ extern emummc_cfg_t emu_cfg;
void emummc_load_cfg();
bool emummc_set_path(char *path);
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
int emummc_storage_end(sdmmc_storage_t *storage);
int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int emummc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
int emummc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);
int emummc_storage_init_mmc();
int emummc_storage_end();
int emummc_storage_read(u32 sector, u32 num_sectors, void *buf);
int emummc_storage_write(u32 sector, u32 num_sectors, void *buf);
int emummc_storage_set_mmc_partition(u32 partition);
#endif

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2021 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,
@ -19,6 +20,7 @@
#include "nx_emmc.h"
#include "emummc.h"
#include <mem/heap.h>
#include <soc/fuse.h>
#include <storage/mbr_gpt.h>
#include <utils/list.h>
@ -30,7 +32,11 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
{
gpt_t *gpt_buf = (gpt_t *)calloc(NX_GPT_NUM_BLOCKS, NX_EMMC_BLOCKSIZE);
emummc_storage_read(storage, NX_GPT_FIRST_LBA, NX_GPT_NUM_BLOCKS, gpt_buf);
emummc_storage_read(NX_GPT_FIRST_LBA, NX_GPT_NUM_BLOCKS, gpt_buf);
// Check if no GPT or more than max allowed entries.
if (memcmp(&gpt_buf->header.signature, "EFI PART", 8) || gpt_buf->header.num_part_ents > 128)
goto out;
for (u32 i = 0; i < gpt_buf->header.num_part_ents; i++)
{
@ -52,6 +58,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
list_append(gpt, &part->link);
}
out:
free(gpt_buf);
}
@ -66,6 +73,7 @@ emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name)
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link)
if (!strcmp(part->name, name))
return part;
return NULL;
}
@ -74,7 +82,8 @@ int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_of
// The last LBA is inclusive.
if (part->lba_start + sector_off > part->lba_end)
return 0;
return emummc_storage_read(storage, part->lba_start + sector_off, num_sectors, buf);
return emummc_storage_read(part->lba_start + sector_off, num_sectors, buf);
}
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf)
@ -82,5 +91,20 @@ int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_o
// The last LBA is inclusive.
if (part->lba_start + sector_off > part->lba_end)
return 0;
return sdmmc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf);
return emummc_storage_write(part->lba_start + sector_off, num_sectors, buf);
}
void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1)
{
if (fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD)
{
*mod0 = 0xF7;
*mod1 = 0x86;
}
else
{
*mod0 = 0x37;
*mod1 = 0x84;
}
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2020 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,
@ -43,7 +44,9 @@ extern FATFS emmc_fs;
void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage);
void nx_emmc_gpt_free(link_t *gpt);
emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name);
int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf);
void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1);
#endif

View file

@ -23,6 +23,7 @@
#include <mem/heap.h>
#include <sec/se.h>
#include <sec/se_t210.h>
#include "../storage/nx_emmc.h"
#include "nx_emmc_bis.h"
#include <storage/sdmmc.h>
@ -32,7 +33,7 @@
#define CLUSTER_LOOKUP_EMPTY_ENTRY 0xFFFFFFFF
#define SECTORS_PER_CLUSTER 0x20
typedef struct
typedef struct _cluster_cache_t
{
u32 cluster_num; // index of the cluster in the partition
u32 visit_count; // used for debugging/access analysis
@ -41,7 +42,7 @@ typedef struct
u8 cluster[XTS_CLUSTER_SIZE]; // the cached cluster itself
} cluster_cache_t;
typedef struct
typedef struct _bis_cache_t
{
u8 emmc_buffer[XTS_CLUSTER_SIZE];
cluster_cache_t cluster_cache[];
@ -313,8 +314,8 @@ void nx_emmc_bis_cluster_cache_init()
free(cluster_lookup_buf);
// Check if carveout protected, in case of old hwinit (pre 4.0.0) chainload.
*(vu32 *)NX_BIS_LOOKUP_ADR = 0;
if (*(vu32 *)NX_BIS_LOOKUP_ADR != 0)
*(vu32 *)NX_BIS_LOOKUP_ADDR = 0;
if (*(vu32 *)NX_BIS_LOOKUP_ADDR != 0)
{
cluster_lookup_buf = (u32 *)malloc(cluster_lookup_size + 0x2000);
cluster_lookup = (u32 *)ALIGN((u32)cluster_lookup_buf, 0x1000);
@ -322,7 +323,7 @@ void nx_emmc_bis_cluster_cache_init()
else
{
cluster_lookup_buf = NULL;
cluster_lookup = (u32 *)NX_BIS_LOOKUP_ADR;
cluster_lookup = (u32 *)NX_BIS_LOOKUP_ADDR;
}
// Clear cluster lookup table and reset end index.

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2021 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,
@ -59,6 +59,11 @@ bool sd_get_card_removed()
return false;
}
bool sd_get_card_mounted()
{
return sd_mounted;
}
u32 sd_get_mode()
{
return sd_mode;
@ -180,6 +185,11 @@ static void _sd_deinit()
void sd_unmount() { _sd_deinit(); }
void sd_end() { _sd_deinit(); }
bool sd_is_gpt()
{
return sd_fs.part_type;
}
void *sd_file_read(const char *path, u32 *fsize)
{
FIL fp;