Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adc9d2e5bf | ||
|
|
317e4b2038 | ||
|
|
bd99e2a138 | ||
|
|
4c4a6511f3 | ||
|
|
2bbcf63bd9 | ||
|
|
78722d9a90 | ||
|
|
e24f8ad722 | ||
|
|
28fb01b155 | ||
|
|
b8b37e78ba | ||
|
|
82a4d03985 | ||
|
|
195d9797fe | ||
|
|
15e1210179 | ||
|
|
e892e69929 | ||
|
|
7e8e3ece66 | ||
|
|
b5a9d94d35 | ||
|
|
f95b6e399f | ||
|
|
6551930233 | ||
|
|
c2a2694baf | ||
|
|
03df13f34c | ||
|
|
070f9c676d | ||
|
|
7dc3500a17 | ||
|
|
97bbe2a333 | ||
|
|
a6eaa1ec51 | ||
|
|
f93cc0ff44 | ||
|
|
ee145ca9aa | ||
|
|
8832b240a4 | ||
|
|
744f90611a | ||
|
|
440a921980 | ||
|
|
d0799e3cd1 | ||
|
|
5b32937f8f | ||
|
|
f438827263 | ||
|
|
0e60746179 | ||
|
|
0e39c8dda9 | ||
|
|
45a732c388 | ||
|
|
034384622f | ||
|
|
9efbbc9317 | ||
|
|
30afcddd3a | ||
|
|
38f349618f | ||
|
|
33a64abfb0 | ||
|
|
c4783fc2ca | ||
|
|
887972d67c | ||
|
|
9aff029ee4 | ||
|
|
bfcdc2ffd5 | ||
|
|
e4ae9d9d7c |
4
Makefile
4
Makefile
@@ -10,8 +10,8 @@ include $(DEVKITARM)/base_rules
|
||||
|
||||
IPL_LOAD_ADDR := 0x40003000
|
||||
LPVERSION_MAJOR := 2
|
||||
LPVERSION_MINOR := 4
|
||||
LPVERSION_BUGFX := 0
|
||||
LPVERSION_MINOR := 5
|
||||
LPVERSION_BUGFX := 2
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -37,12 +37,12 @@ void set_default_configuration()
|
||||
h_cfg.autoboot = 0;
|
||||
h_cfg.autoboot_list = 0;
|
||||
h_cfg.bootwait = 3;
|
||||
h_cfg.verification = 1;
|
||||
h_cfg.se_keygen_done = 0;
|
||||
h_cfg.sbar_time_keeping = 0;
|
||||
h_cfg.backlight = 100;
|
||||
h_cfg.autohosoff = 0;
|
||||
h_cfg.autonogc = 1;
|
||||
h_cfg.updater2p = 0;
|
||||
h_cfg.brand = NULL;
|
||||
h_cfg.tagline = NULL;
|
||||
h_cfg.errors = 0;
|
||||
@@ -50,7 +50,7 @@ void set_default_configuration()
|
||||
h_cfg.rcm_patched = true;
|
||||
h_cfg.emummc_force_disable = false;
|
||||
|
||||
sd_power_cycle_time_start = 0xFFFFFFF;
|
||||
sd_power_cycle_time_start = 0;
|
||||
}
|
||||
|
||||
int create_config_entry()
|
||||
@@ -96,9 +96,6 @@ int create_config_entry()
|
||||
f_puts("\nbootwait=", &fp);
|
||||
itoa(h_cfg.bootwait, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nverification=", &fp);
|
||||
itoa(h_cfg.verification, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nbacklight=", &fp);
|
||||
itoa(h_cfg.backlight, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
@@ -108,6 +105,9 @@ int create_config_entry()
|
||||
f_puts("\nautonogc=", &fp);
|
||||
itoa(h_cfg.autonogc, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nupdater2p=", &fp);
|
||||
itoa(h_cfg.updater2p, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
if (h_cfg.brand)
|
||||
{
|
||||
f_puts("\nbrand=", &fp);
|
||||
@@ -281,10 +281,11 @@ void config_autoboot()
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
u8 max_entries = 30;
|
||||
u32 boot_text_size = 512;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
|
||||
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
|
||||
char *boot_text = (char *)malloc(512 * max_entries);
|
||||
char *boot_text = (char *)malloc(boot_text_size * max_entries);
|
||||
|
||||
for (u32 j = 0; j < max_entries; j++)
|
||||
boot_values[j] = j;
|
||||
@@ -330,12 +331,12 @@ void config_autoboot()
|
||||
else
|
||||
{
|
||||
if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list)
|
||||
boot_text[(i - 4) * 512] = ' ';
|
||||
boot_text[(i - 4) * boot_text_size] = ' ';
|
||||
|
||||
else
|
||||
boot_text[(i - 4) * 512] = '*';
|
||||
strcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name);
|
||||
ments[i].caption = &boot_text[(i - 4) * 512];
|
||||
boot_text[(i - 4) * boot_text_size] = '*';
|
||||
strcpy(boot_text + (i - 4) * boot_text_size + 1, ini_sec->name);
|
||||
ments[i].caption = &boot_text[(i - 4) * boot_text_size];
|
||||
}
|
||||
ments[i].type = ini_sec->type;
|
||||
ments[i].data = &boot_values[i - 4];
|
||||
@@ -391,10 +392,11 @@ void config_bootdelay()
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
u32 delay_entries = 6;
|
||||
u32 delay_text_size = 32;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (delay_entries + 3));
|
||||
u32 *delay_values = (u32 *)malloc(sizeof(u32) * delay_entries);
|
||||
char *delay_text = (char *)malloc(32 * delay_entries);
|
||||
char *delay_text = (char *)malloc(delay_text_size * delay_entries);
|
||||
|
||||
for (u32 j = 0; j < delay_entries; j++)
|
||||
delay_values[j] = j;
|
||||
@@ -415,14 +417,14 @@ void config_bootdelay()
|
||||
for (i = 1; i < delay_entries; i++)
|
||||
{
|
||||
if (h_cfg.bootwait != i)
|
||||
delay_text[i * 32] = ' ';
|
||||
delay_text[i * delay_text_size] = ' ';
|
||||
else
|
||||
delay_text[i * 32] = '*';
|
||||
delay_text[i * 32 + 1] = i + '0';
|
||||
strcpy(delay_text + i * 32 + 2, " seconds");
|
||||
delay_text[i * delay_text_size] = '*';
|
||||
delay_text[i * delay_text_size + 1] = i + '0';
|
||||
strcpy(delay_text + i * delay_text_size + 2, " seconds");
|
||||
|
||||
ments[i + 2].type = MENT_DATA;
|
||||
ments[i + 2].caption = delay_text + i * 32;
|
||||
ments[i + 2].caption = delay_text + (i * delay_text_size);
|
||||
ments[i + 2].data = &delay_values[i];
|
||||
}
|
||||
|
||||
@@ -445,69 +447,17 @@ void config_bootdelay()
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_verification()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
|
||||
u32 *vr_values = (u32 *)malloc(sizeof(u32) * 3);
|
||||
char *vr_text = (char *)malloc(64 * 3);
|
||||
|
||||
for (u32 j = 0; j < 3; j++)
|
||||
{
|
||||
vr_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &vr_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
strcpy(vr_text, " Disable (Fastest - Unsafe)");
|
||||
strcpy(vr_text + 64, " Sparse (Fast - Safe)");
|
||||
strcpy(vr_text + 128, " Full (Slow - Safe)");
|
||||
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (h_cfg.verification != i)
|
||||
vr_text[64 * i] = ' ';
|
||||
else
|
||||
vr_text[64 * i] = '*';
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
|
||||
memset(&ments[5], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Backup & Restore verification", 0, 0};
|
||||
|
||||
u32 *temp_verification = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_verification != NULL)
|
||||
{
|
||||
h_cfg.verification = *(u32 *)temp_verification;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(vr_values);
|
||||
free(vr_text);
|
||||
|
||||
if (temp_verification == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_backlight()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
u32 bri_text_size = 8;
|
||||
u32 bri_entries = 11;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (bri_entries + 3));
|
||||
u32 *bri_values = (u32 *)malloc(sizeof(u32) * bri_entries);
|
||||
char *bri_text = (char *)malloc(8 * bri_entries);
|
||||
char *bri_text = (char *)malloc(bri_text_size * bri_entries);
|
||||
|
||||
for (u32 j = 1; j < bri_entries; j++)
|
||||
bri_values[j] = j * 10;
|
||||
@@ -521,20 +471,20 @@ void config_backlight()
|
||||
for (i = 1; i < bri_entries; i++)
|
||||
{
|
||||
if ((h_cfg.backlight / 20) != i)
|
||||
bri_text[i * 32] = ' ';
|
||||
bri_text[i * bri_text_size] = ' ';
|
||||
else
|
||||
bri_text[i * 32] = '*';
|
||||
bri_text[i * bri_text_size] = '*';
|
||||
|
||||
if (i < 10)
|
||||
{
|
||||
bri_text[i * 32 + 1] = i + '0';
|
||||
strcpy(bri_text + i * 32 + 2, "0%");
|
||||
bri_text[i * bri_text_size + 1] = i + '0';
|
||||
strcpy(bri_text + i * bri_text_size + 2, "0%");
|
||||
}
|
||||
else
|
||||
strcpy(bri_text + i * 32 + 1, "100%");
|
||||
strcpy(bri_text + i * bri_text_size + 1, "100%");
|
||||
|
||||
ments[i + 1].type = MENT_DATA;
|
||||
ments[i + 1].caption = bri_text + i * 32;
|
||||
ments[i + 1].caption = bri_text + (i * bri_text_size);
|
||||
ments[i + 1].data = &bri_values[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@ typedef struct _hekate_config
|
||||
u32 autoboot;
|
||||
u32 autoboot_list;
|
||||
u32 bootwait;
|
||||
u32 verification;
|
||||
u32 backlight;
|
||||
u32 autohosoff;
|
||||
u32 autonogc;
|
||||
u32 updater2p;
|
||||
char *brand;
|
||||
char *tagline;
|
||||
// Global temporary config.
|
||||
@@ -40,16 +40,10 @@ typedef struct _hekate_config
|
||||
u32 errors;
|
||||
} hekate_config;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
} hsysmodule_t;
|
||||
|
||||
void set_default_configuration();
|
||||
int create_config_entry();
|
||||
void config_autoboot();
|
||||
void config_bootdelay();
|
||||
void config_verification();
|
||||
void config_backlight();
|
||||
void config_auto_hos_poweroff();
|
||||
void config_nogc();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -44,7 +44,8 @@ static char *_strdup(char *str)
|
||||
u32 _find_section_name(char *lbuf, u32 lblen, char schar)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
|
||||
// Depends on 'FF_USE_STRFUNC 2' that removes \r.
|
||||
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n'; i++)
|
||||
;
|
||||
lbuf[i] = 0;
|
||||
|
||||
@@ -123,8 +124,8 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
f_gets(lbuf, 512, &fp);
|
||||
lblen = strlen(lbuf);
|
||||
|
||||
// Remove trailing newline.
|
||||
if (lbuf[lblen - 1] == '\n' || lbuf[lblen - 1] == '\r')
|
||||
// Remove trailing newline. Depends on 'FF_USE_STRFUNC 2' that removes \r.
|
||||
if (lblen && lbuf[lblen - 1] == '\n')
|
||||
lbuf[lblen - 1] = 0;
|
||||
|
||||
if (lblen > 2 && lbuf[0] == '[') // Create new section.
|
||||
@@ -134,24 +135,22 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE);
|
||||
list_init(&csec->kvs);
|
||||
}
|
||||
else if (lblen > 2 && lbuf[0] == '{') //Create new caption.
|
||||
else if (lblen > 1 && lbuf[0] == '{') // Create new caption. Support empty caption '{}'.
|
||||
{
|
||||
_find_section_name(lbuf, lblen, '}');
|
||||
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CAPTION);
|
||||
csec->color = 0xFF0AB9E6;
|
||||
}
|
||||
else if (lblen > 2 && lbuf[0] == '#') //Create empty lines and comments.
|
||||
else if (lblen > 2 && lbuf[0] == '#') // Create comment.
|
||||
{
|
||||
_find_section_name(lbuf, lblen, '\0');
|
||||
|
||||
csec = _ini_create_section(dst, csec, &lbuf[1], INI_COMMENT);
|
||||
}
|
||||
else if (lblen < 2)
|
||||
else if (lblen < 2) // Create empty line.
|
||||
{
|
||||
csec = _ini_create_section(dst, csec, NULL, INI_NEWLINE);
|
||||
}
|
||||
else if (csec && csec->type == INI_CHOICE) //Extract key/value.
|
||||
else if (csec && csec->type == INI_CHOICE) // Extract key/value.
|
||||
{
|
||||
u32 i = _find_section_name(lbuf, lblen, '=');
|
||||
|
||||
|
||||
@@ -269,6 +269,12 @@ void gfx_putc(char c)
|
||||
if (gfx_con.y > gfx_ctxt.height - 8)
|
||||
gfx_con.y = 0;
|
||||
}
|
||||
else if (c == '\e')
|
||||
gfx_con.x = 672;
|
||||
else if (c == '\a')
|
||||
gfx_con.x = 608;
|
||||
else if (c == '\r')
|
||||
gfx_con.x = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -513,6 +519,12 @@ void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_boxGrey(int x0, int y0, int x1, int y1, u8 shade){
|
||||
for (int y = y0; y <= y1; y++){
|
||||
memset(gfx_ctxt.fb + y * gfx_ctxt.stride + x0, shade, (x1 - x0) * 4);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_box(int x0, int y0, int x1, int y1, u32 color){
|
||||
for (int x = x0; x < x1 + 1; x++){
|
||||
for (int y = y0; y < y1 + 1; y++){
|
||||
|
||||
@@ -50,6 +50,7 @@ void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_
|
||||
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
void gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||
void gfx_box(int x0, int y0, int x1, int y1, u32 color);
|
||||
void gfx_boxGrey(int x0, int y0, int x1, int y1, u8 shade);
|
||||
|
||||
// Global gfx console and context.
|
||||
gfx_ctxt_t gfx_ctxt;
|
||||
|
||||
@@ -42,6 +42,7 @@ static const pkg1_id_t _pkg1_ids[] = {
|
||||
{ "20190531152432", 8, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_9xx, 0x5563, 0x1d437} }, //8.1.0
|
||||
{ "20190809135709", 9, {0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_9xx, 0x6495, 0x1d807} }, //9.0.0 - 9.0.1
|
||||
{ "20191021113848", 10,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_9xx, 0x6495, 0x1d807} }, //9.1.0
|
||||
{ "20200303104606", 11,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_9xx, 0x6495, 0x1d807} }, //10.0.0, May or may not be accurate. I just need to feed tsec anyway so this doesn't matter
|
||||
{ NULL } //End.
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -41,14 +41,34 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
|
||||
|
||||
void pkg2_get_newkern_info(u8 *kern_data)
|
||||
{
|
||||
u32 info_op = *(u32 *)(kern_data + PKG2_NEWKERN_GET_INI1);
|
||||
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + PKG2_NEWKERN_GET_INI1; // Parse ADR and PC.
|
||||
u32 pkg2_newkern_ini1_off = 0;
|
||||
pkg2_newkern_ini1_start = 0;
|
||||
|
||||
// Find static OP offset that is close to INI1 offset.
|
||||
u32 counter_ops = 0x100;
|
||||
while (counter_ops)
|
||||
{
|
||||
if (*(u32 *)(kern_data + 0x100 - counter_ops) == PKG2_NEWKERN_GET_INI1_HEURISTIC)
|
||||
{
|
||||
pkg2_newkern_ini1_off = 0x100 - counter_ops + 12; // OP found. Add 12 for the INI1 offset.
|
||||
break;
|
||||
}
|
||||
|
||||
counter_ops -= 4;
|
||||
}
|
||||
|
||||
// Offset not found?
|
||||
if (!counter_ops)
|
||||
return;
|
||||
|
||||
u32 info_op = *(u32 *)(kern_data + pkg2_newkern_ini1_off);
|
||||
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + pkg2_newkern_ini1_off; // Parse ADR and PC.
|
||||
|
||||
pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val);
|
||||
pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8);
|
||||
}
|
||||
}
|
||||
|
||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
|
||||
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
|
||||
{
|
||||
u8 *ptr;
|
||||
// Check for new pkg2 type.
|
||||
@@ -56,6 +76,9 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
|
||||
{
|
||||
pkg2_get_newkern_info(pkg2->data);
|
||||
|
||||
if (!pkg2_newkern_ini1_start)
|
||||
return false;
|
||||
|
||||
ptr = pkg2->data + pkg2_newkern_ini1_start;
|
||||
*new_pkg2 = true;
|
||||
}
|
||||
@@ -75,6 +98,8 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
|
||||
ptr += ki->size;
|
||||
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018-2019 CTCaer
|
||||
* Copyright (C) 2018-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,
|
||||
@@ -26,7 +26,7 @@
|
||||
#define PKG2_SEC_KERNEL 0
|
||||
#define PKG2_SEC_INI1 1
|
||||
|
||||
#define PKG2_NEWKERN_GET_INI1 0x44
|
||||
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
|
||||
|
||||
u32 pkg2_newkern_ini1_val;
|
||||
u32 pkg2_newkern_ini1_start;
|
||||
@@ -87,7 +87,7 @@ typedef struct _pkg2_kip1_info_t
|
||||
link_t link;
|
||||
} pkg2_kip1_info_t;
|
||||
|
||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
|
||||
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
|
||||
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp);
|
||||
pkg2_hdr_t *pkg2_decrypt(void *data);
|
||||
|
||||
|
||||
@@ -45,20 +45,11 @@
|
||||
sdmmc_t sd_sdmmc;
|
||||
sdmmc_storage_t sd_storage;
|
||||
__attribute__ ((aligned (16))) FATFS sd_fs;
|
||||
static bool sd_mounted, sd_inited;
|
||||
bool sd_mounted, sd_inited;
|
||||
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
|
||||
hekate_config h_cfg;
|
||||
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
|
||||
|
||||
bool return_sd_mounted(int value){
|
||||
switch(value){
|
||||
case 10:
|
||||
return sd_inited;
|
||||
default:
|
||||
return sd_mounted;
|
||||
}
|
||||
}
|
||||
|
||||
bool sd_mount()
|
||||
{
|
||||
if (sd_mounted)
|
||||
@@ -146,11 +137,13 @@ int sd_save_to_file(void *buf, u32 size, const char *filename)
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
#define PATCHED_RELOC_STACK 0x40007000
|
||||
#define PATCHED_RELOC_ENTRY 0x40010000
|
||||
#define EXT_PAYLOAD_ADDR 0xC03C0000
|
||||
#define EXT_PAYLOAD_ADDR 0xC0000000
|
||||
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||
#define COREBOOT_END_ADDR 0xD0000000
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000
|
||||
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
|
||||
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
|
||||
|
||||
static void *coreboot_addr;
|
||||
|
||||
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
||||
{
|
||||
@@ -165,7 +158,7 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
||||
|
||||
if (payload_size == 0x7000)
|
||||
{
|
||||
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
|
||||
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), coreboot_addr, 0x7000); //Bootblock
|
||||
*(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
|
||||
}
|
||||
}
|
||||
@@ -195,7 +188,10 @@ int launch_payload(char *path)
|
||||
if (size < 0x30000)
|
||||
buf = (void *)RCM_PAYLOAD_ADDR;
|
||||
else
|
||||
buf = (void *)COREBOOT_ADDR;
|
||||
{
|
||||
coreboot_addr = (void *)(COREBOOT_END_ADDR - size);
|
||||
buf = coreboot_addr;
|
||||
}
|
||||
|
||||
if (f_read(&fp, buf, size, NULL))
|
||||
{
|
||||
@@ -351,7 +347,7 @@ void dump_sysnand()
|
||||
{
|
||||
h_cfg.emummc_force_disable = true;
|
||||
b_cfg.extra_cfg &= ~EXTRA_CFG_DUMP_EMUMMC;
|
||||
dump_keys();
|
||||
//dump_keys();
|
||||
}
|
||||
|
||||
void dump_emunand()
|
||||
@@ -360,7 +356,7 @@ void dump_emunand()
|
||||
return;
|
||||
emu_cfg.enabled = 1;
|
||||
b_cfg.extra_cfg |= EXTRA_CFG_DUMP_EMUMMC;
|
||||
dump_keys();
|
||||
//dump_keys();
|
||||
}
|
||||
|
||||
ment_t ment_top[] = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018 M4xw
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -29,7 +30,7 @@ static void _heap_create(heap_t *heap, u32 start)
|
||||
// Node info is before node address.
|
||||
static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||
{
|
||||
hnode_t *node, *new;
|
||||
hnode_t *node, *new_node;
|
||||
|
||||
// Align to cache line size.
|
||||
size = ALIGN(size, sizeof(hnode_t));
|
||||
@@ -49,22 +50,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||
node = heap->first;
|
||||
while (true)
|
||||
{
|
||||
// Check if there's available unused node.
|
||||
if (!node->used && (size <= node->size))
|
||||
{
|
||||
// Size and offset of the new unused node.
|
||||
u32 new_size = node->size - size;
|
||||
new = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
|
||||
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
|
||||
|
||||
// If there's aligned leftover space, create a new node.
|
||||
// If there's aligned unused space from the old node,
|
||||
// create a new one and set the leftover size.
|
||||
if (new_size >= (sizeof(hnode_t) << 2))
|
||||
{
|
||||
new->size = new_size - sizeof(hnode_t);
|
||||
new->used = 0;
|
||||
new->next = node->next;
|
||||
new->next->prev = new;
|
||||
new->prev = node;
|
||||
node->next = new;
|
||||
new_node->size = new_size - sizeof(hnode_t);
|
||||
new_node->used = 0;
|
||||
new_node->next = node->next;
|
||||
|
||||
// Check that we are not on first node.
|
||||
if (new_node->next)
|
||||
new_node->next->prev = new_node;
|
||||
|
||||
new_node->prev = node;
|
||||
node->next = new_node;
|
||||
}
|
||||
else
|
||||
else // Unused node size is just enough.
|
||||
size += new_size;
|
||||
|
||||
node->size = size;
|
||||
@@ -72,20 +80,23 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
|
||||
|
||||
return (u32)node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
// No unused node found, try the next one.
|
||||
if (node->next)
|
||||
node = node->next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
|
||||
new->used = 1;
|
||||
new->size = size;
|
||||
new->prev = node;
|
||||
new->next = NULL;
|
||||
node->next = new;
|
||||
// No unused node found, create a new one.
|
||||
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
|
||||
new_node->used = 1;
|
||||
new_node->size = size;
|
||||
new_node->prev = node;
|
||||
new_node->next = NULL;
|
||||
node->next = new_node;
|
||||
|
||||
return (u32)new + sizeof(hnode_t);
|
||||
return (u32)new_node + sizeof(hnode_t);
|
||||
}
|
||||
|
||||
static void _heap_free(heap_t *heap, u32 addr)
|
||||
@@ -101,6 +112,7 @@ static void _heap_free(heap_t *heap, u32 addr)
|
||||
{
|
||||
node->prev->size += node->size + sizeof(hnode_t);
|
||||
node->prev->next = node->next;
|
||||
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-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,
|
||||
|
||||
@@ -34,18 +34,21 @@ u32 minerva_init()
|
||||
|
||||
minerva_cfg = NULL;
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
memset(mtc_cfg, 0, sizeof(mtc_config_t));
|
||||
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
|
||||
|
||||
mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
||||
mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table.
|
||||
|
||||
|
||||
u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||
|
||||
// Ensure that Minerva is new.
|
||||
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
else
|
||||
mtc_cfg->init_done = 0;
|
||||
|
||||
if (!minerva_cfg)
|
||||
return 1;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 balika011
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* 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,
|
||||
@@ -696,7 +696,6 @@ sdram_params_t *sdram_get_params_patched()
|
||||
|
||||
void sdram_init()
|
||||
{
|
||||
//TODO: sdram_id should be in [0,4].
|
||||
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
|
||||
|
||||
// Set DRAM voltage.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -96,14 +96,17 @@ enum MAX17050_reg {
|
||||
MAX17050_K_empty0 = 0x3B,
|
||||
MAX17050_TaskPeriod = 0x3C,
|
||||
MAX17050_FSTAT = 0x3D,
|
||||
|
||||
MAX17050_TIMER = 0x3E,
|
||||
MAX17050_SHDNTIMER = 0x3F,
|
||||
|
||||
MAX17050_QRTbl30 = 0x42,
|
||||
|
||||
MAX17050_dQacc = 0x45,
|
||||
MAX17050_dPacc = 0x46,
|
||||
|
||||
MAX17050_VFSOC0 = 0x48,
|
||||
|
||||
Max17050_QH0 = 0x4C,
|
||||
MAX17050_QH = 0x4D,
|
||||
MAX17050_QL = 0x4E,
|
||||
|
||||
@@ -111,6 +114,8 @@ enum MAX17050_reg {
|
||||
MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c.
|
||||
|
||||
MAX17050_VFSOC0Enable = 0x60,
|
||||
MAX17050_MODELEnable1 = 0x62,
|
||||
MAX17050_MODELEnable2 = 0x63,
|
||||
|
||||
MAX17050_MODELChrTbl = 0x80,
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ int max77620_regulator_enable(u32 id, int enable)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// LDO only.
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
@@ -168,9 +169,9 @@ void max77620_config_default()
|
||||
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4);
|
||||
}
|
||||
|
||||
void max77620_low_battery_monitor_config()
|
||||
void max77620_low_battery_monitor_config(bool enable)
|
||||
{
|
||||
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1,
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_MPPLD |
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
|
||||
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
|
||||
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
|
||||
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
|
||||
* ldo5 | GC ASIC | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
|
||||
* ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
|
||||
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
|
||||
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
|
||||
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
|
||||
@@ -113,6 +113,6 @@ int max77620_regulator_set_voltage(u32 id, u32 mv);
|
||||
int max77620_regulator_enable(u32 id, int enable);
|
||||
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
|
||||
void max77620_config_default();
|
||||
void max77620_low_battery_monitor_config();
|
||||
void max77620_low_battery_monitor_config(bool enable);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2019-2020 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,
|
||||
@@ -75,3 +76,94 @@ void max77620_rtc_stop_alarm()
|
||||
// Update RTC clock from RTC regs.
|
||||
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
|
||||
}
|
||||
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
||||
{
|
||||
u32 tmp, edays, year, month, day;
|
||||
|
||||
// Set time.
|
||||
time->sec = epoch % 60;
|
||||
epoch /= 60;
|
||||
time->min = epoch % 60;
|
||||
epoch /= 60;
|
||||
time->hour = epoch % 24;
|
||||
epoch /= 24;
|
||||
|
||||
// Calculate base date values.
|
||||
tmp = (u32)(((u64)4 * epoch + 102032) / 146097 + 15);
|
||||
tmp = (u32)((u64)epoch + 2442113 + tmp - (tmp >> 2));
|
||||
|
||||
year = (20 * tmp - 2442) / 7305;
|
||||
edays = tmp - 365 * year - (year >> 2);
|
||||
month = edays * 1000 / 30601;
|
||||
day = edays - month * 30 - month * 601 / 1000;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 14)
|
||||
{
|
||||
year -= 4716;
|
||||
month--;
|
||||
}
|
||||
else
|
||||
{
|
||||
year -= 4715;
|
||||
month -= 13;
|
||||
}
|
||||
|
||||
// Set date.
|
||||
time->year = year;
|
||||
time->month = month;
|
||||
time->day = day;
|
||||
|
||||
// Set weekday.
|
||||
time->weekday = 0; //! TODO.
|
||||
}
|
||||
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding)
|
||||
{
|
||||
u32 year, month, epoch;
|
||||
|
||||
//Year
|
||||
year = time->year;
|
||||
//Month of year
|
||||
month = time->month;
|
||||
|
||||
if (!hos_encoding)
|
||||
{
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
year -= 2000;
|
||||
month++;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
month += 9;
|
||||
year--;
|
||||
}
|
||||
else
|
||||
month -= 3;
|
||||
}
|
||||
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
|
||||
if (!hos_encoding)
|
||||
{
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
}
|
||||
else
|
||||
epoch += (30 * month) + ((3 * month + 2) / 5) + 59 + time->day; // Months to days.
|
||||
|
||||
epoch *= 86400; // Days to seconds.
|
||||
epoch += (3600 * time->hour) + (60 * time->min) + time->sec; // Add hours, minutes and seconds.
|
||||
|
||||
return epoch;
|
||||
}
|
||||
|
||||
@@ -71,5 +71,7 @@ typedef struct _rtc_time_t {
|
||||
|
||||
void max77620_rtc_get_time(rtc_time_t *time);
|
||||
void max77620_rtc_stop_alarm();
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding);
|
||||
|
||||
#endif /* _MFD_MAX77620_RTC_H_ */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
extern sdmmc_t sd_sdmmc;
|
||||
extern boot_cfg_t b_cfg;
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
/*
|
||||
* CLK_OSC - 38.4 MHz crystal.
|
||||
@@ -78,8 +79,8 @@ void _config_gpios()
|
||||
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
|
||||
|
||||
// Set Joy-Con IsAttached direction.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE;
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE;
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
|
||||
// Set pin mode for Joy-Con IsAttached and UARTB/C TX pins.
|
||||
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
|
||||
@@ -109,7 +110,7 @@ void _config_gpios()
|
||||
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
|
||||
|
||||
// Configure HOME as inputs.
|
||||
// PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_PULL_UP | PINMUX_INPUT_ENABLE;
|
||||
// PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
}
|
||||
|
||||
@@ -160,7 +161,7 @@ void _mbist_workaround()
|
||||
// Enable specific clocks and disable all others.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0; // Enable clock PMC, FUSE.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130; // Enable clock RTC, TMR, GPIO, BPMP_CACHE.
|
||||
//CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USB data ON.
|
||||
//CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USBD ON.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200; // Enable clock CSITE, IRAMA, IRAMB, IRAMC, IRAMD, BPMP_CACHE_RAM.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808; // Enable clock MSELECT, APB2APE, SPDIF_DOUBLER, SE.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC; // Enable clock PCIERX0, PCIERX1, PCIERX2, PCIERX3, PCIERX4, PCIERX5, ENTROPY, MC1.
|
||||
@@ -184,6 +185,9 @@ void _mbist_workaround()
|
||||
|
||||
void _config_se_brom()
|
||||
{
|
||||
// Enable fuse clock.
|
||||
clock_enable_fuse(true);
|
||||
|
||||
// Skip SBK/SSK if sept was run.
|
||||
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
|
||||
{
|
||||
@@ -217,10 +221,19 @@ void _config_se_brom()
|
||||
|
||||
void _config_regulators()
|
||||
{
|
||||
// Disable low battery shutdown monitor.
|
||||
max77620_low_battery_monitor_config(false);
|
||||
|
||||
// Disable SDMMC1 IO power.
|
||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||
max77620_regulator_enable(REGULATOR_LDO2, 0);
|
||||
sd_power_cycle_time_start = get_tmr_ms();
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
||||
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||
|
||||
// Configure all Flexible Power Sequencers.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
|
||||
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1,
|
||||
@@ -236,10 +249,10 @@ void _config_regulators()
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
|
||||
(4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
|
||||
|
||||
// Set vdd_core voltage to 1.125V
|
||||
// Set vdd_core voltage to 1.125V.
|
||||
max77620_regulator_set_voltage(REGULATOR_SD0, 1125000);
|
||||
|
||||
// Fix CPU/GPU after a Linux warmboot.
|
||||
// Fix CPU/GPU after a L4T warmboot.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
|
||||
|
||||
@@ -256,9 +269,6 @@ void _config_regulators()
|
||||
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
|
||||
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
|
||||
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
||||
|
||||
// Enable low battery shutdown monitor for < 2800mV.
|
||||
max77620_low_battery_monitor_config();
|
||||
}
|
||||
|
||||
void config_hw()
|
||||
@@ -312,6 +322,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
||||
bpmp_mmu_disable();
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
minerva_change_freq(FREQ_204);
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-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,
|
||||
@@ -19,7 +20,7 @@
|
||||
#include "i2c.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
static u32 i2c_addrs[] = {
|
||||
static const u32 i2c_addrs[] = {
|
||||
0x7000C000, 0x7000C400, 0x7000C500,
|
||||
0x7000C700, 0x7000D000, 0x7000D100
|
||||
};
|
||||
@@ -121,6 +122,11 @@ int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
|
||||
return _i2c_send_pkt(idx, x, tmp, size + 1);
|
||||
}
|
||||
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x)
|
||||
{
|
||||
return _i2c_recv_pkt(idx, buf, size, x);
|
||||
}
|
||||
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
|
||||
{
|
||||
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 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,
|
||||
@@ -39,6 +40,7 @@
|
||||
|
||||
void i2c_init(u32 idx);
|
||||
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
|
||||
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x);
|
||||
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
|
||||
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
|
||||
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);
|
||||
|
||||
@@ -31,7 +31,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
|
||||
for (u32 i = 0; i < hdr->num_part_ents; i++)
|
||||
{
|
||||
gpt_entry_t *ent = (gpt_entry_t *)(buf + (hdr->part_ent_lba - 1) * NX_EMMC_BLOCKSIZE + i * sizeof(gpt_entry_t));
|
||||
emmc_part_t *part = (emmc_part_t *)malloc(sizeof(emmc_part_t));
|
||||
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
|
||||
part->lba_start = ent->lba_start;
|
||||
part->lba_end = ent->lba_end;
|
||||
part->attrs = ent->attrs;
|
||||
|
||||
@@ -5,7 +5,7 @@ extern const char *gfx_file_size_names[];
|
||||
extern const char *menu_sd_states[];
|
||||
extern const char *emmc_fs_entries[];
|
||||
extern const char *utils_err_codes[];
|
||||
extern const char *pkg2names[];
|
||||
//extern const char *pkg2names[];
|
||||
extern const char *mainmenu_credits;
|
||||
|
||||
enum utils_err_codes_te_call {
|
||||
@@ -19,7 +19,11 @@ enum utils_err_codes_te_call {
|
||||
ERR_MEM_ALLOC_FAILED,
|
||||
ERR_EMMC_READ_FAILED,
|
||||
ERR_EMMC_WRITE_FAILED,
|
||||
ERR_FILE_TOO_BIG_FOR_DEST
|
||||
ERR_FILE_TOO_BIG_FOR_DEST,
|
||||
ERR_SD_EJECTED,
|
||||
ERR_PARSE_FAIL,
|
||||
ERR_CANNOT_COPY_FILE_TO_FS_PART,
|
||||
ERR_NO_DESTENATION
|
||||
};
|
||||
|
||||
extern const char *utils_err_codes_te[];
|
||||
@@ -55,8 +59,7 @@ enum mainmenu_tools_return {
|
||||
TOOLS_DISPLAY_INFO = 1,
|
||||
TOOLS_DISPLAY_GPIO,
|
||||
TOOLS_DUMPFIRMWARE,
|
||||
TOOLS_DUMPUSERSAVE,
|
||||
TOOLS_DUMP_BOOT
|
||||
TOOLS_DUMPUSERSAVE
|
||||
};
|
||||
|
||||
extern menu_entry mainmenu_tools[];
|
||||
@@ -82,8 +85,7 @@ enum fs_menu_file_return {
|
||||
FILE_PAYLOAD,
|
||||
FILE_SCRIPT,
|
||||
FILE_HEXVIEW,
|
||||
FILE_DUMPBIS,
|
||||
FILE_RESTOREBIS
|
||||
FILE_DUMPBIS
|
||||
};
|
||||
|
||||
extern menu_entry fs_menu_file[];
|
||||
@@ -102,4 +104,10 @@ enum fs_menu_startdir_return {
|
||||
FILEMENU_CURFOLDER
|
||||
};
|
||||
|
||||
extern menu_entry fs_menu_startdir[];
|
||||
extern menu_entry fs_menu_startdir[];
|
||||
|
||||
extern gpt_entry_rule gpt_fs_rules[];
|
||||
|
||||
extern menu_entry mmcmenu_start[];
|
||||
|
||||
extern menu_entry mmcmenu_filemenu[];
|
||||
@@ -48,9 +48,13 @@ const char *utils_err_codes_te[] = { // these start at 50
|
||||
"MEM ALLOC FAILED",
|
||||
"EMMC READ FAILED",
|
||||
"EMMC WRITE FAILED",
|
||||
"FILE TOO BIG FOR DEST"
|
||||
"FILE TOO BIG FOR DEST",
|
||||
"SD EJECTED",
|
||||
"PARSING FAILED",
|
||||
"CANNOT COPY FILE TO FS PART",
|
||||
"NO DESTENATION"
|
||||
};
|
||||
|
||||
/*
|
||||
const char *pkg2names[] = {
|
||||
"BCPKG2-1-Normal-Main",
|
||||
"BCPKG2-2-Normal-Sub",
|
||||
@@ -59,5 +63,5 @@ const char *pkg2names[] = {
|
||||
"BCPKG2-5-Repair-Main",
|
||||
"BCPKG2-6-Repair-Sub"
|
||||
};
|
||||
|
||||
*/
|
||||
const char *mainmenu_credits = "\nTegraexplorer, made by:\nSuch Meme, Many Skill\n\nProject based on:\nLockpick_RCM\nHekate\n\nCool people:\nshchmue\ndennthecafebabe\nDax";
|
||||
@@ -2,13 +2,9 @@
|
||||
#include "types.h"
|
||||
|
||||
menu_entry mainmenu_main[] = {
|
||||
{"[SD:/] SD CARD\n", COLOR_GREEN, ISMENU},
|
||||
{"[SAFE:/] EMMC", COLOR_ORANGE, ISMENU},
|
||||
{"[SYSTEM:/] EMMC", COLOR_ORANGE, ISMENU},
|
||||
{"[USER:/] EMMC", COLOR_ORANGE, ISMENU},
|
||||
{"\n[SAFE:/] EMUMMC", COLOR_BLUE, ISMENU},
|
||||
{"[SYSTEM:/] EMUMMC", COLOR_BLUE, ISMENU},
|
||||
{"[USER:/] EMUMMC", COLOR_BLUE, ISMENU},
|
||||
{"[SD:/] SD CARD", COLOR_GREEN, ISMENU},
|
||||
{"[EMMC:/] EMMC", COLOR_ORANGE, ISMENU},
|
||||
{"[EMMC:/] EMUMMC", COLOR_BLUE, ISMENU},
|
||||
{"\nMount/Unmount SD", COLOR_WHITE, ISMENU},
|
||||
{"Tools", COLOR_VIOLET, ISMENU},
|
||||
{"SD format", COLOR_VIOLET, ISMENU},
|
||||
@@ -30,8 +26,7 @@ menu_entry mainmenu_tools[] = {
|
||||
{"\nDisplay Console Info", COLOR_GREEN, ISMENU},
|
||||
{"Display GPIO pins", COLOR_VIOLET, ISMENU},
|
||||
{"Dump Firmware", COLOR_BLUE, ISMENU},
|
||||
{"Dump User Saves", COLOR_YELLOW, ISMENU},
|
||||
{"Dump bis", COLOR_ORANGE, ISMENU}
|
||||
{"Dump User Saves", COLOR_YELLOW, ISMENU}
|
||||
};
|
||||
|
||||
menu_entry mainmenu_format[] = {
|
||||
@@ -57,8 +52,7 @@ menu_entry fs_menu_file[] = {
|
||||
{"Launch Payload", COLOR_ORANGE, ISMENU},
|
||||
{"Launch Script", COLOR_YELLOW, ISMENU},
|
||||
{"View Hex", COLOR_GREEN, ISMENU},
|
||||
{"\nExtract BIS", COLOR_YELLOW, ISMENU},
|
||||
{"Restore BIS", COLOR_RED, ISMENU}
|
||||
{"\nExtract BIS", COLOR_YELLOW, ISMENU}
|
||||
};
|
||||
|
||||
menu_entry fs_menu_folder[] = {
|
||||
@@ -70,7 +64,29 @@ menu_entry fs_menu_folder[] = {
|
||||
};
|
||||
|
||||
menu_entry fs_menu_startdir[] = {
|
||||
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
|
||||
{"Clipboard -> Current folder ", COLOR_ORANGE, ISMENU},
|
||||
{"Current folder menu ", COLOR_ORANGE, ISMENU}
|
||||
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
|
||||
{"Clipboard -> Current folder", COLOR_ORANGE, ISMENU},
|
||||
{"Current folder menu ", COLOR_ORANGE, ISMENU}
|
||||
};
|
||||
|
||||
gpt_entry_rule gpt_fs_rules[] = {
|
||||
{"PRODINFOF", 0 | isFS},
|
||||
{"SAFE", 1 | isFS },
|
||||
{"SYSTEM", 2 | isFS},
|
||||
{"USER", 3 | isFS},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
menu_entry mmcmenu_start[] = {
|
||||
{"Back", COLOR_ORANGE, ISMENU},
|
||||
{"Dump File Partitions", COLOR_ORANGE, ISMENU},
|
||||
{"Clipboard -> Partition\n", COLOR_ORANGE, ISMENU},
|
||||
{"BOOT0/1", COLOR_BLUE, isBOOT | ISMENU}
|
||||
};
|
||||
|
||||
menu_entry mmcmenu_filemenu[] = {
|
||||
{"Part:", COLOR_ORANGE, ISSKIP | ISMENU},
|
||||
{NULL, COLOR_VIOLET, ISSKIP | ISMENU},
|
||||
{"\nBack", COLOR_WHITE, ISMENU},
|
||||
{"Dump to SD", COLOR_YELLOW, ISMENU}
|
||||
};
|
||||
@@ -43,4 +43,12 @@ typedef struct {
|
||||
char *name;
|
||||
u32 storage;
|
||||
u16 property;
|
||||
} menu_entry;
|
||||
} menu_entry;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
u8 property;
|
||||
} gpt_entry_rule;
|
||||
|
||||
#define isFS 0x80
|
||||
#define isBOOT 0x2
|
||||
@@ -22,13 +22,16 @@
|
||||
#include "../../config/config.h"
|
||||
#include "../common/common.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../../utils/list.h"
|
||||
#include "../../mem/heap.h"
|
||||
|
||||
sdmmc_storage_t storage;
|
||||
emmc_part_t *system_part;
|
||||
sdmmc_t sdmmc;
|
||||
extern hekate_config h_cfg;
|
||||
__attribute__ ((aligned (16))) FATFS emmc;
|
||||
LIST_INIT(gpt);
|
||||
LIST_INIT(sys_gpt);
|
||||
LIST_INIT(emu_gpt);
|
||||
|
||||
u8 bis_key[4][32];
|
||||
pkg1_info pkg1inf = {-1, ""};
|
||||
@@ -64,10 +67,10 @@ pkg1_info returnpkg1info(){
|
||||
int connect_part(const char *partition){
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
|
||||
system_part = nx_emmc_part_find(&gpt, partition);
|
||||
system_part = nx_emmc_part_find(selectGpt(currentlyMounted), partition);
|
||||
if (!system_part) {
|
||||
gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -81,11 +84,11 @@ int mount_mmc(const char *partition, const int biskeynumb){
|
||||
se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10);
|
||||
|
||||
if (connect_part(partition))
|
||||
return -1;
|
||||
return 1;
|
||||
|
||||
if ((res = f_mount(&emmc, "emmc:", 1))) {
|
||||
gfx_errDisplay("mount_mmc", res, 0);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -136,6 +139,7 @@ int dump_biskeys(){
|
||||
u8 *pkg1 = (u8 *)malloc(0x40000);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 1);
|
||||
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
|
||||
strncpy(pkg1inf.id, pkg1 + 0x10, 14);
|
||||
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||
if (!pkg1_id) {
|
||||
EPRINTF("Unknown pkg1 version.");
|
||||
@@ -212,9 +216,8 @@ int dump_biskeys(){
|
||||
memcpy(bis_key[3], bis_key[2], 0x20);
|
||||
}
|
||||
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
// Parse eMMC GPT.
|
||||
nx_emmc_gpt_parse(&gpt, &storage);
|
||||
//sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
//nx_emmc_gpt_parse(&sys_gpt, &storage);
|
||||
|
||||
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
|
||||
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
|
||||
@@ -222,4 +225,34 @@ int dump_biskeys(){
|
||||
pkg1inf.ver = pkg1_id->kb;
|
||||
strcpy(pkg1inf.id, pkg1_id->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dumpGpt(){
|
||||
connect_mmc(SYSMMC);
|
||||
sdmmc_storage_set_mmc_partition(&storage, 0);
|
||||
nx_emmc_gpt_parse(&sys_gpt, &storage);
|
||||
|
||||
if (emu_cfg.enabled){
|
||||
connect_mmc(EMUMMC);
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
nx_emmc_gpt_parse(&emu_gpt, &storage);
|
||||
}
|
||||
}
|
||||
|
||||
link_t *selectGpt(short mmcType){
|
||||
switch(mmcType){
|
||||
case SYSMMC:
|
||||
return &sys_gpt;
|
||||
case EMUMMC:
|
||||
return &emu_gpt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int checkGptRules(char *in){
|
||||
for (int i = 0; gpt_fs_rules[i].name != NULL; i++){
|
||||
if (!strcmp(in, gpt_fs_rules[i].name))
|
||||
return gpt_fs_rules[i].property;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "../../utils/types.h"
|
||||
#include "../../utils/list.h"
|
||||
|
||||
typedef struct _pkg1_info {
|
||||
short ver;
|
||||
@@ -15,6 +16,9 @@ int mount_mmc(const char *partition, const int biskeynumb);
|
||||
void connect_mmc(short mmctype);
|
||||
void disconnect_mmc();
|
||||
int connect_part(const char *partition);
|
||||
void dumpGpt();
|
||||
link_t *selectGpt(short mmcType);
|
||||
int checkGptRules(char *in);
|
||||
|
||||
static const u8 zeros[0x10] = {0};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
extern sdmmc_storage_t storage;
|
||||
extern emmc_part_t *system_part;
|
||||
|
||||
int dump_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||
FIL fp;
|
||||
u8 *buf;
|
||||
u32 lba_curr = part->lba_start;
|
||||
@@ -68,11 +68,25 @@ int dump_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int existsCheck(char *path){
|
||||
int res = 0;
|
||||
|
||||
if (fsutil_checkfile(path)){
|
||||
gfx_printf("File already exists! Overwrite?\nVol +/- to cancel\n");
|
||||
res = gfx_makewaitmenu("Power to continue", 3);
|
||||
gfx_printf("\r \r");
|
||||
return res;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
int dump_emmc_parts(u16 parts, u8 mmctype){
|
||||
char *path;
|
||||
char basepath[] = "sd:/tegraexplorer/dumps";
|
||||
char basepath[] = "sd:/tegraexplorer/partition_dumps";
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir("sd:/tegraexplorer/dumps");
|
||||
f_mkdir("sd:/tegraexplorer/partition_dumps");
|
||||
|
||||
connect_mmc(mmctype);
|
||||
gfx_clearscreen();
|
||||
@@ -92,29 +106,79 @@ int dump_emmc_parts(u16 parts, u8 mmctype){
|
||||
|
||||
emummc_storage_set_mmc_partition(&storage, i + 1);
|
||||
utils_copystring(fsutil_getnextloc(basepath, bootPart.name), &path);
|
||||
|
||||
if (!existsCheck(path))
|
||||
continue;
|
||||
|
||||
gfx_printf("Dumping %s\n", bootPart.name);
|
||||
|
||||
dump_emmc_part(path, &storage, &bootPart);
|
||||
free(path);
|
||||
}
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
}
|
||||
|
||||
if (parts & PART_PKG2){
|
||||
for (int i = 0; i < 6; i++){
|
||||
if (connect_part(pkg2names[i])){
|
||||
gfx_errDisplay("dump_emmc_parts", ERR_PART_NOT_FOUND, 0);
|
||||
return -1;
|
||||
}
|
||||
utils_copystring(fsutil_getnextloc(basepath, pkg2names[i]), &path);
|
||||
gfx_printf("Dumping %s\n", pkg2names[i]);
|
||||
|
||||
utils_copystring(fsutil_getnextloc(basepath, system_part->name), &path);
|
||||
gfx_printf("Dumping %s\n", system_part->name);
|
||||
|
||||
dump_emmc_part(path, &storage, system_part);
|
||||
emmcDumpSpecific(pkg2names[i], path);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
gfx_printf("\nDone!");
|
||||
btn_wait();
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int emmcDumpBoot(char *basePath){
|
||||
emmc_part_t bootPart;
|
||||
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
|
||||
char *path;
|
||||
memset(&bootPart, 0, sizeof(emmc_part_t));
|
||||
|
||||
bootPart.lba_start = 0;
|
||||
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||
|
||||
for (int i = 0; i < 2; i++){
|
||||
strcpy(bootPart.name, "BOOT");
|
||||
bootPart.name[4] = (u8)('0' + i);
|
||||
bootPart.name[5] = 0;
|
||||
|
||||
emummc_storage_set_mmc_partition(&storage, i + 1);
|
||||
utils_copystring(fsutil_getnextloc(basePath, bootPart.name), &path);
|
||||
|
||||
if (!existsCheck(path))
|
||||
continue;
|
||||
|
||||
SWAPCOLOR(COLOR_BLUE);
|
||||
gfx_printf("Dumping %s\n", bootPart.name);
|
||||
RESETCOLOR;
|
||||
|
||||
emmcDumpPart(path, &storage, &bootPart);
|
||||
free(path);
|
||||
}
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emmcDumpSpecific(char *part, char *path){
|
||||
if (!existsCheck(path))
|
||||
return 0;
|
||||
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
if (connect_part(part)){
|
||||
gfx_errDisplay("dump_emmc_specific", ERR_PART_NOT_FOUND, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
SWAPCOLOR(COLOR_VIOLET);
|
||||
gfx_printf("Dumping %s\n", part);
|
||||
RESETCOLOR;
|
||||
emmcDumpPart(path, &storage, system_part);
|
||||
|
||||
return 0;
|
||||
}
|
||||
176
source/tegraexplorer/emmc/emmcmenu.c
Normal file
176
source/tegraexplorer/emmc/emmcmenu.c
Normal file
@@ -0,0 +1,176 @@
|
||||
#include <string.h>
|
||||
#include "emmc.h"
|
||||
#include "../../mem/heap.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/btn.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../storage/nx_emmc.h"
|
||||
#include "../../mem/mc.h"
|
||||
#include "../../mem/emc.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "../../config/config.h"
|
||||
#include "../common/common.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../../utils/list.h"
|
||||
#include "../../mem/heap.h"
|
||||
#include "emmcmenu.h"
|
||||
#include "../fs/fsreader.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../gfx/menu.h"
|
||||
#include "../fs/fsmenu.h"
|
||||
#include "emmcoperations.h"
|
||||
#include "../fs/fsutils.h"
|
||||
|
||||
menu_entry *mmcMenuEntries = NULL;
|
||||
extern sdmmc_storage_t storage;
|
||||
extern emmc_part_t *system_part;
|
||||
extern char *clipboard;
|
||||
extern u8 clipboardhelper;
|
||||
|
||||
|
||||
void addEntry(emmc_part_t *part, u8 property, int spot){
|
||||
if (mmcMenuEntries[spot].name != NULL){
|
||||
free(mmcMenuEntries[spot].name);
|
||||
}
|
||||
|
||||
utils_copystring(part->name, &mmcMenuEntries[spot].name);
|
||||
|
||||
if (property & isFS){
|
||||
mmcMenuEntries[spot].storage = (u32)(property & 0x7F);
|
||||
mmcMenuEntries[spot].property = ISDIR;
|
||||
}
|
||||
else {
|
||||
u64 size = 0;
|
||||
int sizes = 0;
|
||||
mmcMenuEntries[spot].property = 0;
|
||||
size = (u64)(part->lba_end + 1 - part->lba_start);
|
||||
size *= (u64)NX_EMMC_BLOCKSIZE;
|
||||
|
||||
while (size > 1024){
|
||||
size /= 1024;
|
||||
sizes++;
|
||||
}
|
||||
|
||||
if (sizes > 3)
|
||||
sizes = 0;
|
||||
|
||||
mmcMenuEntries[spot].property |= (1 << (4 + sizes));
|
||||
mmcMenuEntries[spot].storage = (u32)size;
|
||||
}
|
||||
}
|
||||
|
||||
int fillMmcMenu(short mmcType){
|
||||
int count = 4, i;
|
||||
|
||||
if (mmcMenuEntries != NULL)
|
||||
clearfileobjects(&mmcMenuEntries);
|
||||
|
||||
link_t *gpt = selectGpt(mmcType);
|
||||
|
||||
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link)
|
||||
count++;
|
||||
|
||||
createfileobjects(count, &mmcMenuEntries);
|
||||
|
||||
for (i = 0; i < 4; i++){
|
||||
utils_copystring(mmcmenu_start[i].name, &mmcMenuEntries[i].name);
|
||||
mmcMenuEntries[i].property = mmcmenu_start[i].property;
|
||||
mmcMenuEntries[i].storage = mmcmenu_start[i].storage;
|
||||
}
|
||||
|
||||
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link){
|
||||
addEntry(part, checkGptRules(part->name), i++);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int handleEntries(short mmcType, menu_entry part){
|
||||
int res = 0;
|
||||
|
||||
if (part.property & ISDIR){
|
||||
if (returnpkg1info().ver < 0){
|
||||
gfx_errDisplay("emmcMakeMenu", ERR_BISKEY_DUMP_FAILED, 0);
|
||||
return -1;
|
||||
}
|
||||
if (!mount_mmc(part.name, part.storage))
|
||||
fileexplorer("emmc:/", 1);
|
||||
}
|
||||
else {
|
||||
if (mmcmenu_filemenu[1].name != NULL)
|
||||
free(mmcmenu_filemenu[1].name);
|
||||
|
||||
utils_copystring(part.name, &mmcmenu_filemenu[1].name);
|
||||
|
||||
if ((menu_make(mmcmenu_filemenu, 4, "-- RAW PARTITION --")) < 3)
|
||||
return 0;
|
||||
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir("sd:/tegraexplorer/partition_dumps");
|
||||
|
||||
gfx_clearscreen();
|
||||
|
||||
if (part.property & isBOOT){
|
||||
res = emmcDumpBoot("sd:/tegraexplorer/partition_dumps");
|
||||
}
|
||||
else {
|
||||
//gfx_printf("Dumping %s...\n", part.name);
|
||||
res = emmcDumpSpecific(part.name, fsutil_getnextloc("sd:/tegraexplorer/partition_dumps", part.name));
|
||||
}
|
||||
|
||||
if (!res){
|
||||
gfx_printf("\nDone!");
|
||||
btn_wait();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int makeMmcMenu(short mmcType){
|
||||
int count, selection;
|
||||
count = fillMmcMenu(mmcType);
|
||||
connect_mmc(mmcType);
|
||||
while (1){
|
||||
selection = menu_make(mmcMenuEntries, count, (mmcType == SYSMMC) ? "-- SYSMMC --" : "-- EMUMMC --");
|
||||
|
||||
switch(selection){
|
||||
case -1:
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
gfx_clearscreen();
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir("sd:/tegraexplorer/partition_dumps");
|
||||
|
||||
for (int i = 0; i < count; i++){
|
||||
if (mmcMenuEntries[i].property & ISMENU || mmcMenuEntries[i].property & ISDIR)
|
||||
continue;
|
||||
|
||||
//gfx_printf("Dumping %s...\n", mmcMenuEntries[i].name);
|
||||
emmcDumpSpecific(mmcMenuEntries[i].name, fsutil_getnextloc("sd:/tegraexplorer/partition_dumps", mmcMenuEntries[i].name));
|
||||
}
|
||||
|
||||
gfx_printf("\nDone!");
|
||||
btn_wait();
|
||||
break;
|
||||
case 2:
|
||||
if (!(clipboardhelper & ISDIR) && (clipboardhelper & OPERATIONCOPY)){
|
||||
gfx_clearscreen();
|
||||
if (!mmcFlashFile(clipboard, mmcType)){
|
||||
gfx_printf("\nDone!");
|
||||
btn_wait();
|
||||
}
|
||||
clipboardhelper = 0;
|
||||
}
|
||||
else
|
||||
gfx_errDisplay("mmcMenu", ERR_EMPTY_CLIPBOARD, 0);
|
||||
break;
|
||||
default:
|
||||
handleEntries(mmcType, mmcMenuEntries[selection]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
source/tegraexplorer/emmc/emmcmenu.h
Normal file
3
source/tegraexplorer/emmc/emmcmenu.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int makeMmcMenu(short mmcType);
|
||||
@@ -1,5 +1,10 @@
|
||||
#pragma once
|
||||
#include "../../utils/types.h"
|
||||
#include "../../storage/nx_emmc.h"
|
||||
|
||||
int dump_emmc_parts(u16 parts, u8 mmctype);
|
||||
int restore_bis_using_file(char *path, u8 mmctype);
|
||||
int emmcDumpSpecific(char *part, char *path);
|
||||
int emmcDumpBoot(char *basePath);
|
||||
int mmcFlashFile(char *path, short mmcType);
|
||||
|
||||
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
|
||||
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
|
||||
@@ -18,12 +18,12 @@
|
||||
extern sdmmc_storage_t storage;
|
||||
extern emmc_part_t *system_part;
|
||||
|
||||
int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
|
||||
FIL fp;
|
||||
FILINFO fno;
|
||||
u8 *buf;
|
||||
u32 lba_curr = part->lba_start;
|
||||
u32 bytesWritten = 0;
|
||||
u64 bytesWritten = 0;
|
||||
u32 totalSectorsDest = part->lba_end - part->lba_start + 1;
|
||||
u64 totalSizeDest = (u64)((u64)totalSectorsDest << 9);
|
||||
u64 totalSize;
|
||||
@@ -93,9 +93,9 @@ int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part
|
||||
|
||||
lba_curr += num;
|
||||
totalSectors -= num;
|
||||
bytesWritten += num * NX_EMMC_BLOCKSIZE;
|
||||
bytesWritten += (u64)(num * NX_EMMC_BLOCKSIZE);
|
||||
|
||||
pct = (u64)((u64)(bytesWritten) * 100u) / (u64)(fno.fsize);
|
||||
pct = (u64)(bytesWritten * (u64)100) / (u64)(fno.fsize);
|
||||
gfx_printf("Progress: %d%%\r", pct);
|
||||
}
|
||||
|
||||
@@ -105,6 +105,8 @@ int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part
|
||||
return 0;
|
||||
}
|
||||
|
||||
// function replaced by new mmc implementation. Will be removed at some point
|
||||
/*
|
||||
int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
|
||||
connect_mmc(mmctype);
|
||||
|
||||
@@ -164,4 +166,64 @@ int restore_bis_using_file(char *path, u8 mmctype){
|
||||
btn_wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
emmc_part_t *mmcFindPart(char *path, short mmcType){
|
||||
char *filename, *extention, *path_local;
|
||||
emmc_part_t *part;
|
||||
|
||||
utils_copystring(path, &path_local);
|
||||
filename = strrchr(path_local, '/') + 1;
|
||||
extention = strrchr(path_local, '.');
|
||||
|
||||
if (extention != NULL)
|
||||
*extention = '\0';
|
||||
|
||||
if (checkGptRules(filename)){
|
||||
gfx_errDisplay("mmcFindPart", ERR_CANNOT_COPY_FILE_TO_FS_PART, 1);
|
||||
free(path_local);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
part = nx_emmc_part_find(selectGpt(mmcType), filename);
|
||||
|
||||
if (part != NULL){
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
free(path_local);
|
||||
return part;
|
||||
}
|
||||
|
||||
if (!strcmp(filename, "BOOT0") || !strcmp(filename, "BOOT1")){
|
||||
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
|
||||
part = calloc(1, sizeof(emmc_part_t));
|
||||
|
||||
part->lba_start = 0;
|
||||
part->lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
|
||||
|
||||
strcpy(part->name, filename);
|
||||
|
||||
emummc_storage_set_mmc_partition(&storage, (!strcmp(filename, "BOOT0")) ? 1 : 2);
|
||||
free(path_local);
|
||||
return part;
|
||||
}
|
||||
|
||||
//gfx_printf("Path: %s\nFilename: %s", path, filename);
|
||||
//btn_wait();
|
||||
gfx_errDisplay("mmcFindPart", ERR_NO_DESTENATION, 2);
|
||||
free(path_local);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mmcFlashFile(char *path, short mmcType){
|
||||
emmc_part_t *part;
|
||||
int res;
|
||||
|
||||
part = mmcFindPart(path, mmcType);
|
||||
if (part != NULL){
|
||||
res = emmcRestorePart(path, &storage, part);
|
||||
emummc_storage_set_mmc_partition(&storage, 0);
|
||||
return res;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../gfx/menu.h"
|
||||
#include "../common/types.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../utils/script.h"
|
||||
#include "../script/parser.h"
|
||||
#include "../emmc/emmcoperations.h"
|
||||
|
||||
extern char *currentpath;
|
||||
@@ -47,7 +47,7 @@ void viewbytes(char *path){
|
||||
return;
|
||||
}
|
||||
|
||||
msleep(200);
|
||||
while (btn_read() & BTN_POWER);
|
||||
|
||||
while (1){
|
||||
f_lseek(&in, offset * 16);
|
||||
@@ -111,7 +111,6 @@ void copyfile(const char *src_in, const char *outfolder){
|
||||
free(out);
|
||||
free(filename);
|
||||
fsreader_readfolder(currentpath);
|
||||
clipboardhelper = 0;
|
||||
}
|
||||
|
||||
int filemenu(menu_entry file){
|
||||
@@ -144,12 +143,11 @@ int filemenu(menu_entry file){
|
||||
(attribs.fattrib & AM_ARC) ? 'A' : '-');
|
||||
}
|
||||
|
||||
SETBIT(fs_menu_file[7].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.property & ISKB));
|
||||
SETBIT(fs_menu_file[8].property, ISHIDE, !(strstr(file.name, ".tegrascript") != NULL));
|
||||
SETBIT(fs_menu_file[10].property, ISHIDE, !(strstr(file.name, ".bis") != NULL));
|
||||
SETBIT(fs_menu_file[11].property, ISHIDE, !(strstr(file.name, ".bis") != NULL));
|
||||
SETBIT(fs_menu_file[7].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.property & ISKB) && strstr(file.name, ".rom") == NULL);
|
||||
SETBIT(fs_menu_file[8].property, ISHIDE, strstr(file.name, ".te") == NULL);
|
||||
SETBIT(fs_menu_file[10].property, ISHIDE, strstr(file.name, ".bis") == NULL);
|
||||
|
||||
temp = menu_make(fs_menu_file, 12, "-- File Menu --");
|
||||
temp = menu_make(fs_menu_file, 11, "-- File Menu --");
|
||||
|
||||
switch (temp){
|
||||
case FILE_COPY:
|
||||
@@ -165,7 +163,9 @@ int filemenu(menu_entry file){
|
||||
launch_payload(fsutil_getnextloc(currentpath, file.name));
|
||||
break;
|
||||
case FILE_SCRIPT:
|
||||
ParseScript(fsutil_getnextloc(currentpath, file.name));
|
||||
//ParseScript(fsutil_getnextloc(currentpath, file.name));
|
||||
runScript(fsutil_getnextloc(currentpath, file.name));
|
||||
fsreader_readfolder(currentpath);
|
||||
break;
|
||||
case FILE_HEXVIEW:
|
||||
viewbytes(fsutil_getnextloc(currentpath, file.name));
|
||||
@@ -176,9 +176,8 @@ int filemenu(menu_entry file){
|
||||
fsreader_readfolder(currentpath);
|
||||
btn_wait();
|
||||
break;
|
||||
case FILE_RESTOREBIS:
|
||||
restore_bis_using_file(fsutil_getnextloc(currentpath, file.name), SYSMMC);
|
||||
break;
|
||||
case -1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -66,6 +66,7 @@ int foldermenu(){
|
||||
|
||||
switch (res){
|
||||
case DIR_EXITFOLDER:
|
||||
case -1:
|
||||
return -1;
|
||||
case DIR_COPYFOLDER:
|
||||
fsreader_writeclipboard(currentpath, OPERATIONCOPY | ISDIR);
|
||||
|
||||
@@ -23,22 +23,22 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
|
||||
|
||||
if (!strcmp(locin, locout)){
|
||||
gfx_errDisplay("copy", ERR_SAME_LOC, 1);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){
|
||||
gfx_errDisplay("copy", res, 2);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (f_stat(locin, &in_info)){
|
||||
gfx_errDisplay("copy", res, 3);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
|
||||
gfx_errDisplay("copy", res, 4);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
buff = malloc (BUFSIZE);
|
||||
@@ -48,17 +48,17 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
|
||||
while (sizeoffile > 0){
|
||||
if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))){
|
||||
gfx_errDisplay("copy", res, 5);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))){
|
||||
gfx_errDisplay("copy", res, 6);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (temp1 != temp2){
|
||||
gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sizeoffile -= temp1;
|
||||
@@ -84,7 +84,7 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
|
||||
|
||||
if ((res = f_chmod(locout, in_info.fattrib, 0x3A))){
|
||||
gfx_errDisplay("copy", res, 8);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
f_stat(locin, &in_info); //somehow stops fatfs from being weird
|
||||
@@ -103,7 +103,7 @@ int fsact_del_recursive(char *path){
|
||||
|
||||
if ((res = f_opendir(&dir, localpath))){
|
||||
gfx_errDisplay("del_recursive", res, 1);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (!f_readdir(&dir, &fno) && fno.fname[0]){
|
||||
@@ -117,7 +117,7 @@ int fsact_del_recursive(char *path){
|
||||
|
||||
if ((res = f_unlink(fsutil_getnextloc(localpath, fno.fname)))){
|
||||
gfx_errDisplay("del_recursive", res, 2);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ int fsact_del_recursive(char *path){
|
||||
|
||||
if ((res = f_unlink(localpath))){
|
||||
gfx_errDisplay("del_recursive", res, 3);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(localpath);
|
||||
@@ -148,7 +148,7 @@ int fsact_copy_recursive(char *path, char *dstpath){
|
||||
|
||||
if ((res = f_opendir(&dir, startpath))){
|
||||
gfx_errDisplay("copy_recursive", res, 1);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
f_mkdir(destpath);
|
||||
@@ -166,7 +166,7 @@ int fsact_copy_recursive(char *path, char *dstpath){
|
||||
|
||||
if ((res = fsact_copy(temp, fsutil_getnextloc(destpath, fno.fname), COPY_MODE_PRINT))){
|
||||
gfx_errDisplay("copy_recursive", res, 2);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(temp);
|
||||
@@ -177,12 +177,12 @@ int fsact_copy_recursive(char *path, char *dstpath){
|
||||
|
||||
if ((res = (f_stat(startpath, &fno)))){
|
||||
gfx_errDisplay("copy_recursive", res, 3);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((res = f_chmod(destpath, fno.fattrib, 0x3A))){
|
||||
gfx_errDisplay("copy_recursive", res, 4);
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(startpath);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../../storage/nx_emmc.h"
|
||||
#include "../common/types.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "fsactions.h"
|
||||
|
||||
u32 DecodeInt(u8* data) {
|
||||
u32 out = 0;
|
||||
@@ -55,6 +56,7 @@ int extract_bis_file(char *path, char *outfolder){
|
||||
u8 args;
|
||||
u8 temp[0x4];
|
||||
u32 filesizes[4];
|
||||
char *tempPath;
|
||||
|
||||
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
|
||||
gfx_errDisplay("extract_bis_file", res, 0);
|
||||
@@ -71,21 +73,35 @@ int extract_bis_file(char *path, char *outfolder){
|
||||
|
||||
gfx_printf("Version: %s\n\n", version);
|
||||
|
||||
gfx_printf("\nExtracting BOOT0\n");
|
||||
if (args & BOOT0_ARG)
|
||||
if (args & BOOT0_ARG){
|
||||
gfx_printf("\nExtracting BOOT0\n");
|
||||
gen_part(filesizes[0], &in, fsutil_getnextloc(outfolder, "BOOT0.bin"));
|
||||
|
||||
gfx_printf("Extracting BOOT1\n");
|
||||
if (args & BOOT1_ARG)
|
||||
}
|
||||
|
||||
if (args & BOOT1_ARG){
|
||||
gfx_printf("Extracting BOOT1\n");
|
||||
gen_part(filesizes[1], &in, fsutil_getnextloc(outfolder, "BOOT1.bin"));
|
||||
}
|
||||
|
||||
gfx_printf("Extracting BCPKG2_1\n");
|
||||
if (args & BCPKG2_1_ARG)
|
||||
gen_part(filesizes[2], &in, fsutil_getnextloc(outfolder, "BCPKG2-1-Normal-Main"));
|
||||
if (args & BCPKG2_1_ARG){
|
||||
utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-1-Normal-Main"), &tempPath);
|
||||
gfx_printf("Extracting BCPKG2_1/2\n");
|
||||
|
||||
gfx_printf("Extracting BCPKG2_3\n");
|
||||
if (args & BCPKG2_3_ARG)
|
||||
gen_part(filesizes[3], &in, fsutil_getnextloc(outfolder, "BCPKG2-3-SafeMode-Main"));
|
||||
gen_part(filesizes[2], &in, tempPath);
|
||||
fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-2-Normal-Sub"), COPY_MODE_PRINT);
|
||||
RESETCOLOR;
|
||||
free(tempPath);
|
||||
}
|
||||
|
||||
if (args & BCPKG2_3_ARG){
|
||||
utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-3-SafeMode-Main"), &tempPath);
|
||||
gfx_printf("Extracting BCPKG2_3/4\n");
|
||||
|
||||
gen_part(filesizes[3], &in, tempPath);
|
||||
fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-4-SafeMode-Sub"), COPY_MODE_PRINT);
|
||||
RESETCOLOR;
|
||||
free(tempPath);
|
||||
}
|
||||
|
||||
gfx_printf("\n\nDone!\n");
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ void fileexplorer(const char *startpath, int type){
|
||||
if (lastentry > 0 && lastentry == type)
|
||||
clipboardhelper = 0;
|
||||
|
||||
if (clipboardhelper & OPERATIONMOVE)
|
||||
clipboardhelper = 0;
|
||||
|
||||
lastentry = type;
|
||||
|
||||
fsreader_writecurpath(startpath);
|
||||
@@ -48,12 +51,15 @@ void fileexplorer(const char *startpath, int type){
|
||||
copyfolder(clipboard, currentpath);
|
||||
else
|
||||
copyfile(clipboard, currentpath);
|
||||
clipboardhelper = 0;
|
||||
break;
|
||||
|
||||
case FILEMENU_CURFOLDER:
|
||||
if (foldermenu())
|
||||
return;
|
||||
break;
|
||||
case -1:
|
||||
return;
|
||||
|
||||
default:
|
||||
if(fsreader_files[res].property & ISDIR){
|
||||
@@ -61,7 +67,8 @@ void fileexplorer(const char *startpath, int type){
|
||||
fsreader_readfolder(currentpath);
|
||||
}
|
||||
else
|
||||
filemenu(fsreader_files[res]);
|
||||
if(filemenu(fsreader_files[res]))
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -29,20 +29,20 @@ void fsreader_writeclipboard(const char *in, u8 args){
|
||||
utils_copystring(in, &clipboard);
|
||||
}
|
||||
|
||||
void clearfileobjects(){
|
||||
if (fsreader_files != NULL){
|
||||
for (int i = 0; fsreader_files[i].name != NULL; i++){
|
||||
free(fsreader_files[i].name);
|
||||
fsreader_files[i].name = NULL;
|
||||
void clearfileobjects(menu_entry **menu){
|
||||
if ((*menu) != NULL){
|
||||
for (int i = 0; (*menu)[i].name != NULL; i++){
|
||||
free((*menu)[i].name);
|
||||
(*menu)[i].name = NULL;
|
||||
}
|
||||
free(fsreader_files);
|
||||
fsreader_files = NULL;
|
||||
free((*menu));
|
||||
(*menu) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void createfileobjects(int size){
|
||||
fsreader_files = calloc (size + 1, sizeof(menu_entry));
|
||||
fsreader_files[size].name = NULL;
|
||||
void createfileobjects(int size, menu_entry **menu){
|
||||
(*menu) = calloc (size + 1, sizeof(menu_entry));
|
||||
(*menu)[size].name = NULL;
|
||||
}
|
||||
|
||||
void addobject(char* name, int spot, u8 attribs){
|
||||
@@ -83,8 +83,8 @@ int fsreader_readfolder(const char *path){
|
||||
FILINFO fno;
|
||||
int folderamount, res;
|
||||
|
||||
clearfileobjects();
|
||||
createfileobjects(fsutil_getfolderentryamount(path) + 3);
|
||||
clearfileobjects(&fsreader_files);
|
||||
createfileobjects(fsutil_getfolderentryamount(path) + 3, &fsreader_files);
|
||||
|
||||
for (folderamount = 0; folderamount < 3; folderamount++){
|
||||
utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name));
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
extern menu_entry *fsreader_files;
|
||||
void fsreader_writecurpath(const char *in);
|
||||
void fsreader_writeclipboard(const char *in, u8 args);
|
||||
int fsreader_readfolder(const char *path);
|
||||
int fsreader_readfolder(const char *path);
|
||||
|
||||
void createfileobjects(int size, menu_entry **menu);
|
||||
void clearfileobjects(menu_entry **menu);
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "../../mem/heap.h"
|
||||
#include "../common/common.h"
|
||||
|
||||
int printerrors = true;
|
||||
|
||||
void gfx_clearscreen(){
|
||||
int battery = 0;
|
||||
@@ -24,7 +25,7 @@ void gfx_clearscreen(){
|
||||
|
||||
gfx_box(0, 0, 719, 15, COLOR_WHITE);
|
||||
gfx_con_setpos(0, 0);
|
||||
gfx_printf("Tegraexplorer v1.4.0\n");
|
||||
gfx_printf("Tegraexplorer v1.5.2\n");
|
||||
|
||||
RESETCOLOR;
|
||||
}
|
||||
@@ -43,6 +44,9 @@ int gfx_message(u32 color, const char* message, ...){
|
||||
}
|
||||
|
||||
int gfx_errDisplay(char *src_func, int err, int loc){
|
||||
if (!printerrors)
|
||||
return 0;
|
||||
|
||||
gfx_clearscreen();
|
||||
SWAPCOLOR(COLOR_ORANGE);
|
||||
gfx_printf("\nAn error occured:\n\n");
|
||||
@@ -50,7 +54,7 @@ int gfx_errDisplay(char *src_func, int err, int loc){
|
||||
|
||||
if (err < 15)
|
||||
gfx_printf("Desc: %s\n", utils_err_codes[err]);
|
||||
else if (err >= ERR_SAME_LOC && err <= ERR_FILE_TOO_BIG_FOR_DEST)
|
||||
else if (err >= ERR_SAME_LOC && err <= ERR_NO_DESTENATION)
|
||||
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
|
||||
|
||||
if (loc)
|
||||
@@ -59,6 +63,9 @@ int gfx_errDisplay(char *src_func, int err, int loc){
|
||||
gfx_printf("\nPress any button to return");
|
||||
|
||||
RESETCOLOR;
|
||||
|
||||
while (btn_read() != 0);
|
||||
|
||||
return btn_wait();
|
||||
}
|
||||
|
||||
@@ -108,8 +115,13 @@ void gfx_printandclear(char *in, int length){
|
||||
gfx_con_getpos(&x, &y);
|
||||
RESETCOLOR;
|
||||
|
||||
|
||||
/*
|
||||
for (int i = (703 - x) / 16; i > 0; i--)
|
||||
gfx_printf(" ");
|
||||
*/
|
||||
|
||||
gfx_boxGrey(x, y, 703, y + 16, 0x1B);
|
||||
|
||||
gfx_con_setpos(x, y);
|
||||
|
||||
|
||||
@@ -12,4 +12,6 @@ int gfx_errDisplay(char *src_func, int err, int loc);
|
||||
int gfx_makewaitmenu(char *hiddenmessage, int timer);
|
||||
void gfx_printlength(int size, char *toprint);
|
||||
void gfx_printandclear(char *in, int length);
|
||||
void gfx_printfilesize(int size, char *type);
|
||||
void gfx_printfilesize(int size, char *type);
|
||||
|
||||
extern int printerrors;
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "../common/common.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../mem/minerva.h"
|
||||
#include "../../soc/gpio.h"
|
||||
|
||||
extern void sd_unmount();
|
||||
extern bool sd_inited;
|
||||
|
||||
void _printentry(menu_entry entry, bool highlighted, bool refresh){
|
||||
int size;
|
||||
@@ -49,22 +53,33 @@ void _printentry(menu_entry entry, bool highlighted, bool refresh){
|
||||
else {
|
||||
SWAPCOLOR(COLOR_BLUE);
|
||||
SWAPBGCOLOR(COLOR_DEFAULT);
|
||||
gfx_printf("\a%d\e%s", entry.storage, gfx_file_size_names[size - 4]);
|
||||
gfx_printf("\a%4d", entry.storage);
|
||||
gfx_con.fntsz = 8;
|
||||
gfx_printf("\n\e%s\n", gfx_file_size_names[size - 4]);
|
||||
gfx_con.fntsz = 16;
|
||||
}
|
||||
}
|
||||
|
||||
int menu_make(menu_entry *entries, int amount, char *toptext){
|
||||
int currentpos = 0, res = 0, offset = 0, delay = 300, minscreen = 0, maxscreen = 59;
|
||||
int currentpos = 0, res = 0, offset = 0, delay = 300, minscreen = 0, maxscreen = 59, calculatedamount = 0;
|
||||
u32 scrolltimer, timer;
|
||||
bool refresh = false;
|
||||
|
||||
gfx_clearscreen();
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
if (!(entries[i].property & ISMENU))
|
||||
calculatedamount++;
|
||||
|
||||
gfx_con_setpos(512, 0);
|
||||
SWAPCOLOR(COLOR_DEFAULT);
|
||||
SWAPBGCOLOR(COLOR_WHITE);
|
||||
gfx_printf("%3d entries\n", amount);
|
||||
RESETCOLOR;
|
||||
if (calculatedamount){
|
||||
SWAPCOLOR(COLOR_DEFAULT);
|
||||
SWAPBGCOLOR(COLOR_WHITE);
|
||||
gfx_printf("%3d entries\n", calculatedamount);
|
||||
RESETCOLOR;
|
||||
}
|
||||
else
|
||||
gfx_printf("\n");
|
||||
|
||||
SWAPCOLOR(COLOR_GREEN);
|
||||
gfx_printlength(42, toptext);
|
||||
@@ -108,6 +123,12 @@ int menu_make(menu_entry *entries, int amount, char *toptext){
|
||||
|
||||
res = 0;
|
||||
while (!res){
|
||||
if (sd_inited && !!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)){
|
||||
gfx_errDisplay("menu", ERR_SD_EJECTED, 0);
|
||||
sd_unmount();
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = btn_read();
|
||||
|
||||
if (!res)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "../utils/btn.h"
|
||||
#include "emmc/emmc.h"
|
||||
#include "../storage/emummc.h"
|
||||
#include "utils/script.h"
|
||||
#include "script/functions.h"
|
||||
|
||||
#include "common/common.h"
|
||||
#include "gfx/menu.h"
|
||||
@@ -16,11 +16,13 @@
|
||||
#include "fs/fsutils.h"
|
||||
#include "fs/fsmenu.h"
|
||||
#include "emmc/emmcoperations.h"
|
||||
#include "emmc/emmcmenu.h"
|
||||
|
||||
extern bool sd_mount();
|
||||
extern void sd_unmount();
|
||||
extern bool return_sd_mounted(int value);
|
||||
extern int launch_payload(char *path);
|
||||
extern bool sd_inited;
|
||||
extern bool sd_mounted;
|
||||
|
||||
int res = 0, meter = 0;
|
||||
|
||||
@@ -32,30 +34,33 @@ void MainMenu_EMMC(){
|
||||
gfx_clearscreen();
|
||||
gfx_printf("You're about to enter EMMC\nModifying anything here\n can result in a BRICK!\n\nPlease only continue\n if you know what you're doing\n\nPress Vol+/- to return\n");
|
||||
if (gfx_makewaitmenu("Press Power to enter", 4)){
|
||||
/*
|
||||
connect_mmc(SYSMMC);
|
||||
|
||||
if (!mount_mmc(emmc_fs_entries[res - 2], res - 1))
|
||||
fileexplorer("emmc:/", 1);
|
||||
*/
|
||||
makeMmcMenu(SYSMMC);
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenu_EMUMMC(){
|
||||
/*
|
||||
connect_mmc(EMUMMC);
|
||||
|
||||
if (!mount_mmc(emmc_fs_entries[res - 5], res - 4))
|
||||
fileexplorer("emmc:/", 1);
|
||||
fileexplorer("emmc:/", 1);
|
||||
*/
|
||||
makeMmcMenu(EMUMMC);
|
||||
}
|
||||
|
||||
void MainMenu_MountSD(){
|
||||
if (return_sd_mounted(1))
|
||||
sd_unmount();
|
||||
else
|
||||
sd_mount();
|
||||
(sd_mounted) ? sd_unmount() : sd_mount();
|
||||
}
|
||||
|
||||
void MainMenu_Tools(){
|
||||
//res = makemenu(toolsmenu, 8);
|
||||
res = menu_make(mainmenu_tools, 6, "-- Tools Menu --");
|
||||
res = menu_make(mainmenu_tools, 5, "-- Tools Menu --");
|
||||
|
||||
switch(res){
|
||||
case TOOLS_DISPLAY_INFO:
|
||||
@@ -63,6 +68,7 @@ void MainMenu_Tools(){
|
||||
break;
|
||||
case TOOLS_DISPLAY_GPIO:
|
||||
displaygpio();
|
||||
//makeMmcMenu(SYSMMC);
|
||||
break;
|
||||
case TOOLS_DUMPFIRMWARE:
|
||||
dumpfirmware(SYSMMC);
|
||||
@@ -72,9 +78,6 @@ void MainMenu_Tools(){
|
||||
dumpusersaves(res);
|
||||
|
||||
break;
|
||||
case TOOLS_DUMP_BOOT:
|
||||
dump_emmc_parts(PART_BOOT | PART_PKG2, SYSMMC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +103,7 @@ void MainMenu_Credits(){
|
||||
}
|
||||
|
||||
void MainMenu_Exit(){
|
||||
if (return_sd_mounted(1)){
|
||||
if (sd_mounted){
|
||||
SETBIT(mainmenu_shutdown[4].property, ISHIDE, !fsutil_checkfile("/bootloader/update.bin"));
|
||||
SETBIT(mainmenu_shutdown[5].property, ISHIDE, !fsutil_checkfile("/atmosphere/reboot_payload.bin"));
|
||||
}
|
||||
@@ -129,13 +132,9 @@ void MainMenu_Exit(){
|
||||
} //todo declock bpmp
|
||||
}
|
||||
|
||||
part_handler mainmenu_functions[] = {
|
||||
func_void_ptr mainmenu_functions[] = {
|
||||
MainMenu_SDCard,
|
||||
MainMenu_EMMC,
|
||||
MainMenu_EMMC,
|
||||
MainMenu_EMMC,
|
||||
MainMenu_EMUMMC,
|
||||
MainMenu_EMUMMC,
|
||||
MainMenu_EMUMMC,
|
||||
MainMenu_MountSD,
|
||||
MainMenu_Tools,
|
||||
@@ -145,7 +144,7 @@ part_handler mainmenu_functions[] = {
|
||||
};
|
||||
|
||||
void RunMenuOption(int option){
|
||||
if (option != 11)
|
||||
if (option != 7)
|
||||
meter = 0;
|
||||
if (option > 0)
|
||||
mainmenu_functions[option - 1]();
|
||||
@@ -155,34 +154,33 @@ void te_main(){
|
||||
|
||||
if (dump_biskeys() == -1){
|
||||
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
|
||||
for (int i = 1; i <= 3; i++)
|
||||
mainmenu_main[i].property |= ISHIDE;
|
||||
//mainmenu_main[1].property |= ISHIDE;
|
||||
}
|
||||
|
||||
if (emummc_load_cfg()){
|
||||
for (int i = 4; i <= 6; i++)
|
||||
mainmenu_main[i].property |= ISHIDE;
|
||||
mainmenu_main[2].property |= ISHIDE;
|
||||
}
|
||||
|
||||
dumpGpt();
|
||||
|
||||
disconnect_mmc();
|
||||
|
||||
while (1){
|
||||
//fillmainmenu();
|
||||
|
||||
setter = return_sd_mounted(1);
|
||||
setter = sd_mounted;
|
||||
|
||||
if (emu_cfg.enabled){
|
||||
for (int i = 4; i <= 6; i++)
|
||||
SETBIT(mainmenu_main[i].property, ISHIDE, !setter);
|
||||
SETBIT(mainmenu_main[2].property, ISHIDE, !setter);
|
||||
}
|
||||
|
||||
SETBIT(mainmenu_main[0].property, ISHIDE, !setter);
|
||||
mainmenu_main[7].name = (menu_sd_states[!setter]);
|
||||
mainmenu_main[3].name = (menu_sd_states[!setter]);
|
||||
|
||||
setter = return_sd_mounted(10);
|
||||
SETBIT(mainmenu_main[9].property, ISHIDE, !setter);
|
||||
setter = sd_inited;
|
||||
SETBIT(mainmenu_main[5].property, ISHIDE, !setter);
|
||||
|
||||
res = menu_make(mainmenu_main, 12, "-- Main Menu --") + 1;
|
||||
res = menu_make(mainmenu_main, 8, "-- Main Menu --") + 1;
|
||||
RunMenuOption(res);
|
||||
}
|
||||
}
|
||||
594
source/tegraexplorer/script/functions.c
Normal file
594
source/tegraexplorer/script/functions.c
Normal file
@@ -0,0 +1,594 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../mem/heap.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../emmc/emmc.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../../utils/btn.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "parser.h"
|
||||
#include "../common/common.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "variables.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "functions.h"
|
||||
#include "../fs/fsutils.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "../emmc/emmcoperations.h"
|
||||
#include "../emmc/emmcmenu.h"
|
||||
|
||||
extern FIL scriptin;
|
||||
extern char **argv;
|
||||
extern u32 argc;
|
||||
extern int forceExit;
|
||||
extern short currentlyMounted;
|
||||
|
||||
int parseIntInput(char *in, int *out){
|
||||
if (in[0] == '@'){
|
||||
if (str_int_find(in, out))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
*out = atoi(in);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
int parseJmpInput(char *in, u64 *out){
|
||||
if (in[0] == '?'){
|
||||
if (str_jmp_find(in, out))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
int parseStringInput(char *in, char **out){
|
||||
if (in[0] == '$'){
|
||||
if (str_str_find(in, out))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
*out = in;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 currentcolor = COLOR_WHITE;
|
||||
int part_printf(){
|
||||
SWAPCOLOR(currentcolor);
|
||||
for (int i = 0; i < argc; i++){
|
||||
if (argv[i][0] == '@'){
|
||||
int toprintint;
|
||||
if (parseIntInput(argv[i], &toprintint))
|
||||
return -1;
|
||||
|
||||
gfx_printf("%d", toprintint);
|
||||
}
|
||||
else {
|
||||
char *toprintstring;
|
||||
if (parseStringInput(argv[i], &toprintstring))
|
||||
return -1;
|
||||
|
||||
gfx_printf(toprintstring);
|
||||
}
|
||||
}
|
||||
|
||||
gfx_printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_print_int(){
|
||||
int toprint;
|
||||
if (parseIntInput(argv[0], &toprint))
|
||||
return -1;
|
||||
|
||||
SWAPCOLOR(currentcolor);
|
||||
gfx_printf("%s: %d\n", argv[0], toprint);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_Wait(){
|
||||
int arg;
|
||||
u32 begintime;
|
||||
SWAPCOLOR(currentcolor);
|
||||
|
||||
if (parseIntInput(argv[0], &arg))
|
||||
return -1;
|
||||
|
||||
begintime = get_tmr_s();
|
||||
|
||||
while (begintime + arg > get_tmr_s()){
|
||||
gfx_printf("\r<Wait %d seconds> ", (begintime + arg) - get_tmr_s());
|
||||
}
|
||||
|
||||
gfx_printf("\r \r");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_Check(){
|
||||
int left, right;
|
||||
if (parseIntInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseIntInput(argv[2], &right))
|
||||
return -1;
|
||||
|
||||
if (!strcmp(argv[1], "=="))
|
||||
return (left == right);
|
||||
else if (!strcmp(argv[1], "!="))
|
||||
return (left != right);
|
||||
else if (!strcmp(argv[1], ">="))
|
||||
return (left >= right);
|
||||
else if (!strcmp(argv[1], "<="))
|
||||
return (left <= right);
|
||||
else if (!strcmp(argv[1], ">"))
|
||||
return (left > right);
|
||||
else if (!strcmp(argv[1], "<"))
|
||||
return (left < right);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int part_if(){
|
||||
int condition;
|
||||
if (parseIntInput(argv[0], &condition))
|
||||
return -1;
|
||||
|
||||
getfollowingchar('{');
|
||||
|
||||
if (!condition)
|
||||
skipbrackets();
|
||||
|
||||
return 0;
|
||||
|
||||
/*
|
||||
if (condition)
|
||||
return 0;
|
||||
else {
|
||||
skipbrackets();
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int part_if_args(){
|
||||
int condition;
|
||||
if ((condition = part_Check()) < 0)
|
||||
return -1;
|
||||
|
||||
getfollowingchar('{');
|
||||
|
||||
if (!condition)
|
||||
skipbrackets();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_Math(){
|
||||
int left, right;
|
||||
if (parseIntInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseIntInput(argv[2], &right))
|
||||
return -1;
|
||||
|
||||
switch (argv[1][0]){
|
||||
case '+':
|
||||
return left + right;
|
||||
case '-':
|
||||
return left - right;
|
||||
case '*':
|
||||
return left * right;
|
||||
case '/':
|
||||
return left / right;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int part_SetInt(){
|
||||
int out;
|
||||
parseIntInput(argv[0], &out);
|
||||
return out;
|
||||
}
|
||||
|
||||
int part_SetString(){
|
||||
char *arg0;
|
||||
if (parseStringInput(argv[0], &arg0))
|
||||
return -1;
|
||||
if (argv[1][0] != '$')
|
||||
return -1;
|
||||
|
||||
str_str_add(argv[1], arg0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_SetStringIndex(){
|
||||
int index;
|
||||
char *out;
|
||||
if (parseIntInput(argv[0], &index))
|
||||
return -1;
|
||||
if (argv[1][0] != '$')
|
||||
return -1;
|
||||
if (str_str_index(index, &out))
|
||||
return -1;
|
||||
|
||||
str_str_add(argv[1], out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_goto(){
|
||||
int target = 0;
|
||||
if (parseIntInput(argv[0], &target))
|
||||
return -1;
|
||||
f_lseek(&scriptin, target);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_invert(){
|
||||
int arg;
|
||||
if (parseIntInput(argv[0], &arg))
|
||||
return -1;
|
||||
return (arg) ? 0 : 1;
|
||||
}
|
||||
|
||||
int part_fs_exists(){
|
||||
char *path;
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return -1;
|
||||
|
||||
return fsutil_checkfile(path);
|
||||
}
|
||||
|
||||
int part_ConnectMMC(){
|
||||
char *arg;
|
||||
parseStringInput(argv[0], &arg);
|
||||
|
||||
if (!strcmp(arg, "SYSMMC"))
|
||||
connect_mmc(SYSMMC);
|
||||
else if (!strcmp(arg, "EMUMMC"))
|
||||
connect_mmc(EMUMMC);
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_MountMMC(){
|
||||
char *arg;
|
||||
parseStringInput(argv[0], &arg);
|
||||
return mount_mmc(arg, 2);
|
||||
}
|
||||
|
||||
int part_Pause(){
|
||||
int res;
|
||||
|
||||
while (btn_read() != 0);
|
||||
|
||||
res = btn_wait();
|
||||
|
||||
str_int_add("@BTN_POWER", (res & BTN_POWER));
|
||||
str_int_add("@BTN_VOL+", (res & BTN_VOL_UP));
|
||||
str_int_add("@BTN_VOL-", (res & BTN_VOL_DOWN));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int part_addstrings(){
|
||||
char *combined, *left, *middle;
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &middle))
|
||||
return -1;
|
||||
if (argv[2][0] != '$')
|
||||
return -1;
|
||||
|
||||
combined = calloc(strlen(left) + strlen(middle) + 1, sizeof(char));
|
||||
sprintf(combined, "%s%s", left, middle);
|
||||
|
||||
str_str_add(argv[2], combined);
|
||||
free(combined);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_setColor(){
|
||||
char *arg;
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return -1;
|
||||
|
||||
if (!strcmp(arg, "RED"))
|
||||
currentcolor = COLOR_RED;
|
||||
else if (!strcmp(arg, "ORANGE"))
|
||||
currentcolor = COLOR_ORANGE;
|
||||
else if (!strcmp(arg, "YELLOW"))
|
||||
currentcolor = COLOR_YELLOW;
|
||||
else if (!strcmp(arg, "GREEN"))
|
||||
currentcolor = COLOR_GREEN;
|
||||
else if (!strcmp(arg, "BLUE"))
|
||||
currentcolor = COLOR_BLUE;
|
||||
else if (!strcmp(arg, "VIOLET"))
|
||||
currentcolor = COLOR_VIOLET;
|
||||
else if (!strcmp(arg, "WHITE"))
|
||||
currentcolor = COLOR_WHITE;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_Exit(){
|
||||
forceExit = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_fs_Move(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return -1;
|
||||
|
||||
int res;
|
||||
res = f_rename(left, right);
|
||||
if (res)
|
||||
res = f_rename(left, right);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int part_fs_Delete(){
|
||||
char *arg;
|
||||
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return -1;
|
||||
|
||||
int res;
|
||||
res = f_unlink(arg);
|
||||
if (res)
|
||||
res = f_unlink(arg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int part_fs_DeleteRecursive(){
|
||||
char *arg;
|
||||
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return -1;
|
||||
|
||||
return fsact_del_recursive(arg);
|
||||
}
|
||||
|
||||
int part_fs_Copy(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return -1;
|
||||
|
||||
return fsact_copy(left, right, COPY_MODE_PRINT);
|
||||
}
|
||||
|
||||
int part_fs_CopyRecursive(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return -1;
|
||||
|
||||
return fsact_copy_recursive(left, right);
|
||||
}
|
||||
|
||||
int part_fs_MakeDir(){
|
||||
char *arg;
|
||||
|
||||
if (parseStringInput(argv[0], &arg))
|
||||
return -1;
|
||||
|
||||
int res;
|
||||
res = f_mkdir(arg);
|
||||
if (res)
|
||||
res = f_mkdir(arg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
int isdirvalid = false;
|
||||
int part_fs_OpenDir(){
|
||||
char *path;
|
||||
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return -1;
|
||||
|
||||
if (f_opendir(&dir, path))
|
||||
return -1;
|
||||
|
||||
isdirvalid = true;
|
||||
str_int_add("@ISDIRVALID", isdirvalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_fs_CloseDir(){
|
||||
if (!isdirvalid)
|
||||
return 0;
|
||||
|
||||
f_closedir(&dir);
|
||||
isdirvalid = false;
|
||||
str_int_add("@ISDIRVALID", isdirvalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_fs_ReadDir(){
|
||||
if (!isdirvalid)
|
||||
return -1;
|
||||
|
||||
if (!f_readdir(&dir, &fno) && fno.fname[0]){
|
||||
str_str_add("$FILENAME", fno.fname);
|
||||
str_int_add("@ISDIR", (fno.fattrib & AM_DIR) ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
part_fs_CloseDir();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_setPrintPos(){
|
||||
int left, right;
|
||||
|
||||
if (parseIntInput(argv[0], &left))
|
||||
return -1;
|
||||
|
||||
if (parseIntInput(argv[1], &right))
|
||||
return -1;
|
||||
|
||||
if (left > 42)
|
||||
return -1;
|
||||
|
||||
if (right > 78)
|
||||
return -1;
|
||||
|
||||
gfx_con_setpos(left * 16, right * 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_stringcompare(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return -1;
|
||||
|
||||
return (strcmp(left, right)) ? 0 : 1;
|
||||
}
|
||||
|
||||
int part_fs_combinePath(){
|
||||
char *combined, *left, *middle;
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &middle))
|
||||
return -1;
|
||||
if (argv[2][0] != '$')
|
||||
return -1;
|
||||
|
||||
combined = fsutil_getnextloc(left, middle);
|
||||
|
||||
str_str_add(argv[2], combined);
|
||||
free(combined);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_mmc_dumpPart(){
|
||||
char *left, *right;
|
||||
|
||||
if (parseStringInput(argv[0], &left))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &right))
|
||||
return -1;
|
||||
|
||||
if (!strcmp(left, "BOOT")){
|
||||
return emmcDumpBoot(right);
|
||||
}
|
||||
else {
|
||||
return emmcDumpSpecific(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
int part_mmc_restorePart(){
|
||||
char *path;
|
||||
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return -1;
|
||||
|
||||
if (currentlyMounted < 0)
|
||||
return -1;
|
||||
|
||||
return mmcFlashFile(path, currentlyMounted);
|
||||
}
|
||||
|
||||
int part_fs_extractBisFile(){
|
||||
char *path, *outfolder;
|
||||
|
||||
if (parseStringInput(argv[0], &path))
|
||||
return -1;
|
||||
if (parseStringInput(argv[1], &outfolder))
|
||||
return -1;
|
||||
|
||||
return extract_bis_file(path, outfolder);
|
||||
}
|
||||
|
||||
int part_clearscreen(){
|
||||
gfx_clearscreen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_getPos(){
|
||||
return (int)f_tell(&scriptin);
|
||||
}
|
||||
|
||||
str_fnc_struct functions[] = {
|
||||
{"printf", part_printf, 255},
|
||||
{"printInt", part_print_int, 1},
|
||||
{"setPrintPos", part_setPrintPos, 2},
|
||||
{"clearscreen", part_clearscreen, 0},
|
||||
{"if", part_if, 1},
|
||||
{"if", part_if_args, 3}, // function overloading
|
||||
{"math", part_Math, 3},
|
||||
{"check", part_Check, 3},
|
||||
{"setInt", part_SetInt, 1},
|
||||
{"goto", part_goto, 1},
|
||||
{"setString", part_SetString, 2},
|
||||
{"setStringIndex", part_SetStringIndex, 2},
|
||||
{"setColor", part_setColor, 1},
|
||||
{"combineStrings", part_addstrings, 3},
|
||||
{"compareStrings", part_stringcompare, 2},
|
||||
{"invert", part_invert, 1},
|
||||
{"fs_exists", part_fs_exists, 1},
|
||||
{"fs_move", part_fs_Move, 2},
|
||||
{"fs_mkdir", part_fs_MakeDir, 1},
|
||||
{"fs_del", part_fs_Delete, 1},
|
||||
{"fs_delRecursive", part_fs_DeleteRecursive, 1},
|
||||
{"fs_copy", part_fs_Copy, 2},
|
||||
{"fs_copyRecursive", part_fs_CopyRecursive, 2},
|
||||
{"fs_openDir", part_fs_OpenDir, 1},
|
||||
{"fs_closeDir", part_fs_CloseDir, 0},
|
||||
{"fs_readDir", part_fs_ReadDir, 0},
|
||||
{"fs_combinePath", part_fs_combinePath, 3},
|
||||
{"fs_extractBisFile", part_fs_extractBisFile, 2},
|
||||
{"mmc_connect", part_ConnectMMC, 1},
|
||||
{"mmc_mount", part_MountMMC, 1},
|
||||
{"mmc_dumpPart", part_mmc_dumpPart, 2},
|
||||
{"mmc_restorePart", part_mmc_restorePart, 1},
|
||||
{"getPosition", part_getPos, 0},
|
||||
{"pause", part_Pause, 0},
|
||||
{"wait", part_Wait, 1},
|
||||
{"exit", part_Exit, 0},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
|
||||
int run_function(char *func_name, int *out){
|
||||
for (u32 i = 0; functions[i].key != NULL; i++){
|
||||
if (!strcmp(functions[i].key, func_name)){
|
||||
if (argc != functions[i].arg_count && functions[i].arg_count != 255)
|
||||
continue;
|
||||
|
||||
*out = functions[i].value();
|
||||
return (*out < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
13
source/tegraexplorer/script/functions.h
Normal file
13
source/tegraexplorer/script/functions.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "../../utils/types.h"
|
||||
|
||||
typedef void (*func_void_ptr)();
|
||||
typedef int (*func_int_ptr)();
|
||||
|
||||
typedef struct {
|
||||
char *key;
|
||||
func_int_ptr value;
|
||||
u8 arg_count;
|
||||
} str_fnc_struct;
|
||||
|
||||
int run_function(char *func_name, int *out);
|
||||
310
source/tegraexplorer/script/parser.c
Normal file
310
source/tegraexplorer/script/parser.c
Normal file
@@ -0,0 +1,310 @@
|
||||
#include <string.h>
|
||||
#include "../../mem/heap.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../emmc/emmc.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../../utils/btn.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "parser.h"
|
||||
#include "../common/common.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
#include "../fs/fsreader.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
u32 countchars(char* in, char target) {
|
||||
u32 len = strlen(in);
|
||||
u32 count = 0;
|
||||
for (u32 i = 0; i < len; i++) {
|
||||
if (in[i] == '"'){
|
||||
i++;
|
||||
while (in[i] != '"'){
|
||||
i++;
|
||||
if (i >= len)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (in[i] == target)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
char **argv = NULL;
|
||||
u32 argc;
|
||||
u32 splitargs(char* in) {
|
||||
// arg like '5, "6", @arg7'
|
||||
u32 i, current = 0, count = 1, len = strlen(in), curcount = 0;
|
||||
|
||||
if ((count += countchars(in, ',')) < 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
if (argv != NULL) {
|
||||
for (i = 0; argv[i] != NULL; i++)
|
||||
free(argv[i]);
|
||||
free(argv);
|
||||
}
|
||||
*/
|
||||
|
||||
argv = calloc(count + 1, sizeof(char*));
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
argv[i] = calloc(96, sizeof(char));
|
||||
|
||||
|
||||
for (i = 0; i < len && curcount < count; i++) {
|
||||
if (in[i] == ',') {
|
||||
curcount++;
|
||||
current = 0;
|
||||
}
|
||||
else if (in[i] == '@' || in[i] == '$' || in[i] == '?') {
|
||||
while (in[i] != ',' && in[i] != ' ' && in[i] != ')' && i < len) {
|
||||
argv[curcount][current++] = in[i++];
|
||||
}
|
||||
i--;
|
||||
}
|
||||
else if ((in[i] >= '0' && in[i] <= '9') || (in[i] >= '<' && in[i] <= '>') || in[i] == '+' || in[i] == '-' || in[i] == '*' || in[i] == '/')
|
||||
argv[curcount][current++] = in[i];
|
||||
else if (in[i] == '"') {
|
||||
i++;
|
||||
while (in[i] != '"') {
|
||||
argv[curcount][current++] = in[i++];
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
FIL scriptin;
|
||||
UINT endByte = 0;
|
||||
int forceExit = false;
|
||||
char currentchar = 0;
|
||||
|
||||
char getnextchar(){
|
||||
f_read(&scriptin, ¤tchar, sizeof(char), &endByte);
|
||||
|
||||
if (sizeof(char) != endByte)
|
||||
forceExit = true;
|
||||
|
||||
//gfx_printf("|%c|", currentchar);
|
||||
return currentchar;
|
||||
}
|
||||
|
||||
void getfollowingchar(char end){
|
||||
while (currentchar != end && !f_eof(&scriptin)){
|
||||
if (currentchar == '"'){
|
||||
while (getnextchar() != '"' && !f_eof(&scriptin));
|
||||
}
|
||||
getnextchar();
|
||||
}
|
||||
}
|
||||
|
||||
void getnextvalidchar(){
|
||||
while ((!((currentchar >= '?' && currentchar <= 'Z') || (currentchar >= 'a' && currentchar <= 'z') || currentchar == '#') && !f_eof(&scriptin)) /*|| currentchar == ';' */)
|
||||
getnextchar();
|
||||
}
|
||||
|
||||
char *makestr(u32 size, char ignore){
|
||||
char *str;
|
||||
u32 count = 0;
|
||||
|
||||
str = calloc(size + 1, sizeof(char));
|
||||
for (u32 i = 0; i < size; i++){
|
||||
getnextchar();
|
||||
if (ignore != 0 && ignore == currentchar)
|
||||
continue;
|
||||
|
||||
str[count++] = currentchar;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *readtilchar(char end, char ignore){
|
||||
FSIZE_t offset, size;
|
||||
|
||||
offset = f_tell(&scriptin);
|
||||
getfollowingchar(end);
|
||||
size = f_tell(&scriptin) - offset;
|
||||
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
f_lseek(&scriptin, offset - 1);
|
||||
|
||||
return makestr((u32)size, ignore);
|
||||
}
|
||||
|
||||
|
||||
char *funcbuff = NULL;
|
||||
void functionparser(){
|
||||
char *unsplitargs;
|
||||
|
||||
/*
|
||||
if (funcbuff != NULL)
|
||||
free(funcbuff);
|
||||
*/
|
||||
|
||||
funcbuff = readtilchar('(', ' ');
|
||||
|
||||
getfollowingchar('(');
|
||||
getnextchar();
|
||||
|
||||
unsplitargs = readtilchar(')', 0);
|
||||
|
||||
if (unsplitargs != NULL){
|
||||
argc = splitargs(unsplitargs);
|
||||
getnextchar();
|
||||
}
|
||||
else {
|
||||
argc = 0;
|
||||
}
|
||||
getnextchar();
|
||||
|
||||
free(unsplitargs);
|
||||
}
|
||||
|
||||
char *gettargetvar(){
|
||||
char *variable = NULL;
|
||||
|
||||
variable = readtilchar('=', ' ');
|
||||
|
||||
getfollowingchar('=');
|
||||
getnextchar();
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
void mainparser(){
|
||||
char *variable = NULL;
|
||||
int res, out = 0;
|
||||
|
||||
getnextvalidchar();
|
||||
|
||||
if (f_eof(&scriptin))
|
||||
return;
|
||||
|
||||
if (currentchar == '#'){
|
||||
getfollowingchar('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentchar == '@'){
|
||||
variable = gettargetvar();
|
||||
getnextvalidchar();
|
||||
}
|
||||
|
||||
/*
|
||||
if (currentchar == '?'){
|
||||
char *jumpname;
|
||||
jumpname = readtilchar(';', ' ');
|
||||
getnextchar();
|
||||
str_jmp_add(jumpname, f_tell(&scriptin));
|
||||
getfollowingchar('\n');
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
functionparser();
|
||||
|
||||
res = run_function(funcbuff, &out);
|
||||
if (res < 0){
|
||||
printerrors = true;
|
||||
//gfx_printf("%s|%s|%d", funcbuff, argv[0], argc);
|
||||
//btn_wait();
|
||||
gfx_errDisplay("mainparser", ERR_PARSE_FAIL, f_tell(&scriptin));
|
||||
forceExit = true;
|
||||
//gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]);
|
||||
}
|
||||
else {
|
||||
str_int_add("@RESULT", out);
|
||||
|
||||
if (variable != NULL)
|
||||
str_int_add(variable, out);
|
||||
}
|
||||
|
||||
//gfx_printf("\nGoing to next func %c\n", currentchar);
|
||||
|
||||
if (funcbuff != NULL){
|
||||
free(funcbuff);
|
||||
funcbuff = NULL;
|
||||
}
|
||||
|
||||
if (argv != NULL) {
|
||||
for (int i = 0; argv[i] != NULL; i++)
|
||||
free(argv[i]);
|
||||
free(argv);
|
||||
argv = NULL;
|
||||
}
|
||||
|
||||
if (variable != NULL){
|
||||
free(variable);
|
||||
}
|
||||
}
|
||||
|
||||
void skipbrackets(){
|
||||
u32 bracketcounter = 0;
|
||||
|
||||
getfollowingchar('{');
|
||||
getnextchar();
|
||||
|
||||
while ((currentchar != '}' || bracketcounter != 0) && !f_eof(&scriptin)){
|
||||
if (currentchar == '{')
|
||||
bracketcounter++;
|
||||
else if (currentchar == '}')
|
||||
bracketcounter--;
|
||||
|
||||
getnextchar();
|
||||
}
|
||||
}
|
||||
|
||||
extern u32 currentcolor;
|
||||
extern char *currentpath;
|
||||
void runScript(char *path){
|
||||
int res;
|
||||
char *path_local = NULL;
|
||||
forceExit = false;
|
||||
currentchar = 0;
|
||||
currentcolor = COLOR_WHITE;
|
||||
gfx_clearscreen();
|
||||
utils_copystring(path, &path_local);
|
||||
|
||||
res = f_open(&scriptin, path, FA_READ | FA_OPEN_EXISTING);
|
||||
if (res != FR_OK){
|
||||
gfx_errDisplay("ParseScript", res, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
printerrors = false;
|
||||
|
||||
//add builtin vars
|
||||
str_int_add("@EMUMMC", emu_cfg.enabled);
|
||||
str_int_add("@RESULT", 0);
|
||||
str_int_add("@BTN_POWER", 0);
|
||||
str_int_add("@BTN_VOL+", 0);
|
||||
str_int_add("@BTN_VOL-", 0);
|
||||
str_str_add("$CURRENTPATH", currentpath);
|
||||
|
||||
//str_int_printall();
|
||||
|
||||
while (!f_eof(&scriptin) && !forceExit){
|
||||
mainparser();
|
||||
}
|
||||
|
||||
printerrors = true;
|
||||
//str_int_printall();
|
||||
|
||||
f_close(&scriptin);
|
||||
str_int_clear();
|
||||
//str_jmp_clear();
|
||||
str_str_clear();
|
||||
free(path_local);
|
||||
//btn_wait();
|
||||
}
|
||||
5
source/tegraexplorer/script/parser.h
Normal file
5
source/tegraexplorer/script/parser.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void runScript(char *path);
|
||||
void skipbrackets();
|
||||
void getfollowingchar(char end);
|
||||
250
source/tegraexplorer/script/variables.c
Normal file
250
source/tegraexplorer/script/variables.c
Normal file
@@ -0,0 +1,250 @@
|
||||
#include <string.h>
|
||||
#include "../../mem/heap.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../emmc/emmc.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../../utils/btn.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "parser.h"
|
||||
#include "../common/common.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "variables.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
static dict_str_int *str_int_table = NULL;
|
||||
static dict_str_str *str_str_table = NULL;
|
||||
//static dict_str_loc *str_jmp_table = NULL;
|
||||
|
||||
int str_int_add(char *key, int value){
|
||||
char *key_local;
|
||||
dict_str_int *keyvaluepair;
|
||||
|
||||
utils_copystring(key, &key_local);
|
||||
|
||||
keyvaluepair = calloc(1, sizeof(dict_str_int));
|
||||
keyvaluepair->key = key_local;
|
||||
keyvaluepair->value = value;
|
||||
keyvaluepair->next = NULL;
|
||||
|
||||
if (str_int_table == NULL){
|
||||
str_int_table = keyvaluepair;
|
||||
}
|
||||
else {
|
||||
dict_str_int *temp;
|
||||
temp = str_int_table;
|
||||
while (temp != NULL){
|
||||
if (!strcmp(temp->key, key_local)){
|
||||
free(keyvaluepair);
|
||||
free(key_local);
|
||||
temp->value = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (temp->next == NULL){
|
||||
temp->next = keyvaluepair;
|
||||
return 0;
|
||||
}
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int str_int_find(char *key, int *out){
|
||||
dict_str_int *temp;
|
||||
temp = str_int_table;
|
||||
while (temp != NULL){
|
||||
if (!strcmp(temp->key, key)){
|
||||
*out = temp->value;
|
||||
return 0;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void str_int_clear(){
|
||||
dict_str_int *cur, *next;
|
||||
cur = str_int_table;
|
||||
|
||||
while (cur != NULL){
|
||||
next = cur->next;
|
||||
free(cur->key);
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
str_int_table = NULL;
|
||||
}
|
||||
|
||||
void str_int_printall(){
|
||||
dict_str_int *temp;
|
||||
temp = str_int_table;
|
||||
while (temp != NULL){
|
||||
gfx_printf("%s -> %d\n", temp->key, temp->value);
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
/*
|
||||
int str_jmp_add(char *key, u64 value){
|
||||
char *key_local;
|
||||
dict_str_loc *keyvaluepair;
|
||||
|
||||
//gfx_printf("Adding |%s|\n", key_local);
|
||||
|
||||
utils_copystring(key, &key_local);
|
||||
|
||||
keyvaluepair = calloc(1, sizeof(dict_str_loc));
|
||||
keyvaluepair->key = key_local;
|
||||
keyvaluepair->value = value;
|
||||
keyvaluepair->next = NULL;
|
||||
|
||||
if (str_jmp_table == NULL){
|
||||
str_jmp_table = keyvaluepair;
|
||||
}
|
||||
else {
|
||||
dict_str_loc *temp;
|
||||
temp = str_jmp_table;
|
||||
while (temp != NULL){
|
||||
if (!strcmp(temp->key, key_local)){
|
||||
free(keyvaluepair);
|
||||
free(key_local);
|
||||
|
||||
temp->value = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (temp->next == NULL){
|
||||
temp->next = keyvaluepair;
|
||||
return 0;
|
||||
}
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int str_jmp_find(char *key, u64 *out){
|
||||
dict_str_loc *temp;
|
||||
temp = str_jmp_table;
|
||||
//gfx_printf("Searching |%s|\n", key);
|
||||
while (temp != NULL){
|
||||
if (!strcmp(temp->key, key)){
|
||||
//gfx_printf("Key found!\n", temp->value);
|
||||
*out = temp->value;
|
||||
return 0;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
//gfx_printf("no key!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void str_jmp_clear(){
|
||||
dict_str_loc *cur, *next;
|
||||
cur = str_jmp_table;
|
||||
|
||||
while (cur != NULL){
|
||||
next = cur->next;
|
||||
free(cur->key);
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
str_jmp_table = NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
int str_str_add(char *key, char *value){
|
||||
char *key_local, *value_local;
|
||||
dict_str_str *keyvaluepair;
|
||||
//gfx_printf("Adding |%s|\n", key_local);
|
||||
utils_copystring(value, &value_local);
|
||||
utils_copystring(key, &key_local);
|
||||
|
||||
keyvaluepair = calloc(1, sizeof(dict_str_str));
|
||||
keyvaluepair->key = key_local;
|
||||
keyvaluepair->value = value_local;
|
||||
keyvaluepair->next = NULL;
|
||||
|
||||
if (str_str_table == NULL){
|
||||
str_str_table = keyvaluepair;
|
||||
}
|
||||
else {
|
||||
dict_str_str *temp;
|
||||
temp = str_str_table;
|
||||
while (temp != NULL){
|
||||
if (!strcmp(temp->key, key_local)){
|
||||
free(keyvaluepair);
|
||||
free(key_local);
|
||||
|
||||
free(temp->value);
|
||||
temp->value = value_local;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (temp->next == NULL){
|
||||
temp->next = keyvaluepair;
|
||||
return 0;
|
||||
}
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int str_str_find(char *key, char **out){
|
||||
dict_str_str *temp;
|
||||
temp = str_str_table;
|
||||
|
||||
while (temp != NULL){
|
||||
if (!strcmp(temp->key, key)){
|
||||
*out = temp->value;
|
||||
return 0;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int str_str_index(int index, char **out){
|
||||
dict_str_str *temp;
|
||||
temp = str_str_table;
|
||||
|
||||
for (int i = 0; i < index; i++){
|
||||
if (temp == NULL)
|
||||
return -1;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
if (temp == NULL)
|
||||
return -1;
|
||||
|
||||
*out = temp->value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void str_str_clear(){
|
||||
dict_str_str *cur, *next;
|
||||
cur = str_str_table;
|
||||
|
||||
while (cur != NULL){
|
||||
next = cur->next;
|
||||
free(cur->key);
|
||||
free(cur->value);
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
str_str_table = NULL;
|
||||
}
|
||||
34
source/tegraexplorer/script/variables.h
Normal file
34
source/tegraexplorer/script/variables.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "../../utils/types.h"
|
||||
|
||||
typedef struct _dict_str_int {
|
||||
char *key;
|
||||
int value;
|
||||
struct _dict_str_int *next;
|
||||
} dict_str_int;
|
||||
|
||||
typedef struct _dict_str_str {
|
||||
char *key;
|
||||
char *value;
|
||||
struct _dict_str_str *next;
|
||||
} dict_str_str;
|
||||
|
||||
typedef struct _dict_str_loc {
|
||||
char *key;
|
||||
u64 value;
|
||||
struct _dict_str_loc *next;
|
||||
} dict_str_loc;
|
||||
|
||||
int str_int_add(char *key, int value);
|
||||
int str_int_find(char *key, int *out);
|
||||
void str_int_clear();
|
||||
void str_int_printall();
|
||||
/*
|
||||
int str_jmp_add(char *key, u64 value);
|
||||
int str_jmp_find(char *key, u64 *out);
|
||||
void str_jmp_clear();
|
||||
*/
|
||||
int str_str_add(char *key, char *value);
|
||||
int str_str_find(char *key, char **out);
|
||||
int str_str_index(int index, char **out);
|
||||
void str_str_clear();
|
||||
@@ -1,283 +0,0 @@
|
||||
#include <string.h>
|
||||
#include "../../mem/heap.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../emmc/emmc.h"
|
||||
#include "../../utils/types.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
#include "../../utils/sprintf.h"
|
||||
#include "../../utils/btn.h"
|
||||
#include "../../gfx/gfx.h"
|
||||
#include "../../utils/util.h"
|
||||
#include "../../storage/emummc.h"
|
||||
#include "script.h"
|
||||
#include "../common/common.h"
|
||||
#include "../fs/fsactions.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
char func[11] = "", args[2][128] = {"", ""};
|
||||
int res, errcode;
|
||||
const int scriptver = 140;
|
||||
bool forceExit = false;
|
||||
u32 currentcolor;
|
||||
|
||||
void Part_CheckFile(){
|
||||
FILINFO fno;
|
||||
errcode = f_stat(args[0], &fno);
|
||||
}
|
||||
|
||||
void Part_SetColor(){
|
||||
if (strcmpcheck(args[0], "RED"))
|
||||
currentcolor = COLOR_RED;
|
||||
else if (strcmpcheck(args[0], "ORANGE"))
|
||||
currentcolor = COLOR_ORANGE;
|
||||
else if (strcmpcheck(args[0], "YELLOW"))
|
||||
currentcolor = COLOR_YELLOW;
|
||||
else if (strcmpcheck(args[0], "GREEN"))
|
||||
currentcolor = COLOR_GREEN;
|
||||
else if (strcmpcheck(args[0], "BLUE"))
|
||||
currentcolor = COLOR_BLUE;
|
||||
else if (strcmpcheck(args[0], "VIOLET"))
|
||||
currentcolor = COLOR_VIOLET;
|
||||
else if (strcmpcheck(args[0], "WHITE"))
|
||||
currentcolor = COLOR_WHITE;
|
||||
}
|
||||
|
||||
void Part_Wait(){
|
||||
int waitamount, begintime;
|
||||
SWAPCOLOR(currentcolor);
|
||||
|
||||
waitamount = atoi(args[0]);
|
||||
begintime = get_tmr_s();
|
||||
|
||||
while (begintime + waitamount > get_tmr_s()){
|
||||
gfx_printf("\r<Wait %d seconds> ", (begintime + waitamount) - get_tmr_s());
|
||||
}
|
||||
|
||||
gfx_printf("\r \r");
|
||||
}
|
||||
|
||||
void Part_VersionCheck(){
|
||||
int givenversion = atoi(args[0]);
|
||||
|
||||
if (givenversion > scriptver){
|
||||
gfx_printf("Script required version is too high\nUpdate TegraExplorer!");
|
||||
btn_wait();
|
||||
forceExit = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Part_Move(){
|
||||
errcode = f_rename(args[0], args[1]);
|
||||
if (errcode)
|
||||
f_rename(args[0], args[1]);
|
||||
}
|
||||
|
||||
void Part_Delete(){
|
||||
errcode = f_unlink(args[0]);
|
||||
if (errcode)
|
||||
f_unlink(args[0]);
|
||||
}
|
||||
|
||||
void Part_DeleteRecursive(){
|
||||
errcode = fsact_del_recursive(args[0]);
|
||||
}
|
||||
|
||||
void Part_Copy(){
|
||||
errcode = fsact_copy(args[0], args[1], COPY_MODE_PRINT);
|
||||
}
|
||||
|
||||
void Part_RecursiveCopy(){
|
||||
errcode = fsact_copy_recursive(args[0], args[1]);
|
||||
}
|
||||
|
||||
void Part_MakeFolder(){
|
||||
errcode = f_mkdir(args[0]);
|
||||
if (errcode)
|
||||
f_mkdir(args[0]);
|
||||
}
|
||||
|
||||
void Part_ConnectMMC(){
|
||||
if (strcmpcheck(args[0], "SYSMMC"))
|
||||
connect_mmc(SYSMMC);
|
||||
if (strcmpcheck(args[0], "EMUMMC"))
|
||||
connect_mmc(EMUMMC);
|
||||
}
|
||||
|
||||
void Part_MountMMC(){
|
||||
errcode = mount_mmc(args[0], 2);
|
||||
}
|
||||
|
||||
void Part_Print(){
|
||||
RESETCOLOR;
|
||||
SWAPCOLOR(currentcolor);
|
||||
gfx_printf("%s\n", args[0]);
|
||||
}
|
||||
|
||||
void Part_ErrorPrint(){
|
||||
RESETCOLOR;
|
||||
SWAPCOLOR(COLOR_RED);
|
||||
gfx_printf("Errorcode: %d\n", errcode);
|
||||
}
|
||||
|
||||
void Part_Exit(){
|
||||
forceExit = true;
|
||||
}
|
||||
|
||||
u8 buttons_pressed = 0;
|
||||
void Part_WaitOnUser(){
|
||||
buttons_pressed = btn_wait();
|
||||
}
|
||||
|
||||
script_parts parts[] = {
|
||||
{"COPY", Part_Copy, 2},
|
||||
{"COPY-R", Part_RecursiveCopy, 2},
|
||||
{"MKDIR", Part_MakeFolder, 1},
|
||||
{"CON_MMC", Part_ConnectMMC, 1},
|
||||
{"MNT_MMC", Part_MountMMC, 1},
|
||||
{"PRINT", Part_Print, 1},
|
||||
{"ERRPRINT", Part_ErrorPrint, 0},
|
||||
{"EXIT", Part_Exit, 0},
|
||||
{"PAUSE", Part_WaitOnUser, 0},
|
||||
{"DEL", Part_Delete, 1},
|
||||
{"DEL-R", Part_DeleteRecursive, 1},
|
||||
{"MOVE", Part_Move, 2},
|
||||
{"VERSION", Part_VersionCheck, 1},
|
||||
{"WAIT", Part_Wait, 1},
|
||||
{"COLOR", Part_SetColor, 1},
|
||||
{"CHECKPATH", Part_CheckFile, 1},
|
||||
{"NULL", NULL, -1}
|
||||
};
|
||||
|
||||
int ParsePart(){
|
||||
int i;
|
||||
for (i = 0; parts[i].arg_amount != -1; i++){
|
||||
if (strcmpcheck(func, parts[i].name))
|
||||
return i;
|
||||
}
|
||||
gfx_printf("Parsing error...\nPress any key to continue");
|
||||
btn_wait();
|
||||
forceExit = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FIL in;
|
||||
UINT endByte = 0;
|
||||
|
||||
char GetNextByte(){
|
||||
char single;
|
||||
f_read(&in, &single, sizeof(char), &endByte);
|
||||
|
||||
if (sizeof(char) != endByte)
|
||||
forceExit = true;
|
||||
|
||||
return single;
|
||||
}
|
||||
|
||||
void ParseScript(char* path){
|
||||
char currentchar;
|
||||
int strlength;
|
||||
bool inifstatement = false;
|
||||
forceExit = false;
|
||||
currentcolor = COLOR_WHITE;
|
||||
|
||||
gfx_clearscreen();
|
||||
|
||||
res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING);
|
||||
if (res != FR_OK){
|
||||
gfx_errDisplay("ParseScript", res, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
while (!forceExit){
|
||||
currentchar = GetNextByte();
|
||||
|
||||
if (endByte == 0 || currentchar == (char)EOF)
|
||||
break;
|
||||
|
||||
switch(currentchar){
|
||||
case '{':
|
||||
if (!inifstatement)
|
||||
while (currentchar != '}')
|
||||
currentchar = GetNextByte();
|
||||
|
||||
break;
|
||||
case '}':
|
||||
if (inifstatement)
|
||||
inifstatement = false;
|
||||
|
||||
break;
|
||||
case '<':
|
||||
strlength = 0;
|
||||
currentchar = GetNextByte();
|
||||
|
||||
while (currentchar != '>'){
|
||||
func[strlength++] = currentchar;
|
||||
currentchar = GetNextByte();
|
||||
}
|
||||
func[strlength] = '\0';
|
||||
|
||||
res = ParsePart();
|
||||
if (res == -1)
|
||||
break;
|
||||
|
||||
for (int i = 0; i < parts[res].arg_amount; i++){
|
||||
while (currentchar != 0x22)
|
||||
currentchar = GetNextByte();
|
||||
|
||||
strlength = 0;
|
||||
currentchar = GetNextByte();
|
||||
while (currentchar != 0x22){
|
||||
args[i][strlength++] = currentchar;
|
||||
currentchar = GetNextByte();
|
||||
}
|
||||
args[i][strlength] = '\0';
|
||||
|
||||
if (i < parts[res].arg_amount)
|
||||
currentchar = GetNextByte();
|
||||
}
|
||||
parts[res].handler();
|
||||
break;
|
||||
case '$':
|
||||
strlength = 0;
|
||||
currentchar = GetNextByte();
|
||||
|
||||
while (currentchar != '$'){
|
||||
func[strlength++] = currentchar;
|
||||
currentchar = GetNextByte();
|
||||
}
|
||||
func[strlength] = '\0';
|
||||
|
||||
if (strcmpcheck(func, "ERROR") || strcmpcheck(func, "TRUE")){
|
||||
inifstatement = (errcode);
|
||||
}
|
||||
else if (strcmpcheck(func, "NOERROR") || strcmpcheck(func, "FALSE")){
|
||||
inifstatement = (!errcode);
|
||||
}
|
||||
else if (strcmpcheck(func, "BTN_POWER")){
|
||||
inifstatement = (buttons_pressed & BTN_POWER);
|
||||
}
|
||||
else if (strcmpcheck(func, "BTN_VOL+")){
|
||||
inifstatement = (buttons_pressed & BTN_VOL_UP);
|
||||
}
|
||||
else if (strcmpcheck(func, "BTN_VOL-")){
|
||||
inifstatement = (buttons_pressed & BTN_VOL_DOWN);
|
||||
}
|
||||
else if (strcmpcheck(func, "EMUMMC")){
|
||||
inifstatement = (emu_cfg.enabled);
|
||||
}
|
||||
else if (strcmpcheck(func, "NOEMUMMC")){
|
||||
inifstatement = (!emu_cfg.enabled);
|
||||
}
|
||||
|
||||
if (inifstatement)
|
||||
while(currentchar != '{')
|
||||
currentchar = GetNextByte();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
f_close(&in);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
#define strcmpcheck(x, y) (!strcmp(x, y))
|
||||
|
||||
typedef void (*part_handler)();
|
||||
typedef struct _script_parts {
|
||||
char name[11];
|
||||
part_handler handler;
|
||||
short arg_amount;
|
||||
} script_parts;
|
||||
|
||||
void ParseScript(char* path);
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <string.h>
|
||||
#include "tools.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../../libs/fatfs/ff.h"
|
||||
@@ -13,6 +14,9 @@
|
||||
#include "../emmc/emmc.h"
|
||||
#include "../common/common.h"
|
||||
#include "../fs/fsactions.h"
|
||||
#include "../fs/fsutils.h"
|
||||
#include "../../mem/heap.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
extern bool sd_mount();
|
||||
extern void sd_unmount();
|
||||
@@ -35,7 +39,12 @@ void displayinfo(){
|
||||
|
||||
SWAPCOLOR(COLOR_ORANGE);
|
||||
|
||||
gfx_printf("Fuse count: %d\nPKG1 version: %d\nPKG1 id: %s\n\n", fuse_count, pkg1.ver, pkg1.id);
|
||||
gfx_printf("Fuse count: %d\nPKG1 id: '%s'\n", fuse_count, pkg1.id);
|
||||
if (pkg1.ver >= 0)
|
||||
gfx_printf("PKG1 version: %d\n", pkg1.ver);
|
||||
|
||||
gfx_printf("\n");
|
||||
|
||||
print_biskeys();
|
||||
|
||||
RESETCOLOR;
|
||||
@@ -91,10 +100,8 @@ int dumpfirmware(int mmc){
|
||||
FILINFO fno;
|
||||
bool fail = false;
|
||||
int ret, amount = 0;
|
||||
char path[100] = "emmc:/Contents/registered";
|
||||
char sdfolderpath[100] = "";
|
||||
char syspath[100] = "";
|
||||
char sdpath[100] = "";
|
||||
char sysbase[] = "emmc:/Contents/registered";
|
||||
char *syspathtemp, *syspath, *sdpath, *sdbase;
|
||||
pkg1_info pkg1 = returnpkg1info();
|
||||
u32 timer = get_tmr_s();
|
||||
|
||||
@@ -104,26 +111,33 @@ int dumpfirmware(int mmc){
|
||||
|
||||
gfx_printf("PKG1 version: %d\n", pkg1.ver);
|
||||
|
||||
ret = f_mkdir("sd:/tegraexplorer");
|
||||
gfx_printf("Creating sd:/tegraexplorer %d\n", ret);
|
||||
gfx_printf("Creating folders...\n");
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir("sd:/tegraexplorer/Firmware");
|
||||
|
||||
ret = f_mkdir("sd:/tegraexplorer/Firmware");
|
||||
gfx_printf("Creating sd:/tegraexplorer/Firmware %d\n", ret);
|
||||
sdbase = calloc(32 + strlen(pkg1.id), sizeof(char));
|
||||
sprintf(sdbase, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
|
||||
gfx_printf("Out: %s\n", sdbase);
|
||||
f_mkdir(sdbase);
|
||||
|
||||
sprintf(sdfolderpath, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
|
||||
ret = f_mkdir(sdfolderpath);
|
||||
gfx_printf("Creating %s %d\n", sdfolderpath, ret);
|
||||
if ((ret = f_opendir(&dir, sysbase)))
|
||||
fail = true;
|
||||
|
||||
ret = f_opendir(&dir, path);
|
||||
gfx_printf("Result opening system:/ %d\n\n%k", ret, COLOR_GREEN);
|
||||
gfx_printf("Starting dump...\n");
|
||||
SWAPCOLOR(COLOR_GREEN);
|
||||
|
||||
printerrors = 0;
|
||||
|
||||
while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){
|
||||
sprintf(sdpath, "%s/%s", sdfolderpath, fno.fname);
|
||||
|
||||
if (fno.fattrib & AM_DIR)
|
||||
sprintf(syspath, "%s/%s/00", path, fno.fname);
|
||||
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
|
||||
utils_copystring(fsutil_getnextloc(sysbase, fno.fname), &syspathtemp);
|
||||
|
||||
if (fno.fattrib & AM_DIR){
|
||||
utils_copystring(fsutil_getnextloc(syspathtemp, "00"), &syspath);
|
||||
free(syspathtemp);
|
||||
}
|
||||
else
|
||||
sprintf(syspath, "%s/%s", path, fno.fname);
|
||||
syspath = syspathtemp;
|
||||
|
||||
ret = fsact_copy(syspath, sdpath, 0);
|
||||
|
||||
@@ -131,42 +145,40 @@ int dumpfirmware(int mmc){
|
||||
|
||||
if (ret != 0)
|
||||
fail = true;
|
||||
|
||||
free(sdpath);
|
||||
free(syspath);
|
||||
}
|
||||
|
||||
printerrors = 1;
|
||||
|
||||
if (fail)
|
||||
gfx_printf("%k\n\nDump failed! Aborting (%d)", COLOR_RED, ret);
|
||||
|
||||
gfx_printf("%k\n\nPress any button to continue...\nTime taken: %ds", COLOR_WHITE, get_tmr_s() - timer);
|
||||
|
||||
free(sdbase);
|
||||
btn_wait();
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
void dumpusersaves(int mmc){
|
||||
int res;
|
||||
|
||||
connect_mmc(mmc);
|
||||
mount_mmc("USER", 2);
|
||||
gfx_clearscreen();
|
||||
|
||||
res = f_mkdir("sd:/tegraexplorer");
|
||||
gfx_printf("Creating sd:/tegraexplorer, res: %d\nCopying:\n", res);
|
||||
gfx_printf("Creating folders...\n");
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
|
||||
gfx_printf("Starting dump...\n");
|
||||
|
||||
SWAPCOLOR(COLOR_GREEN);
|
||||
|
||||
res = fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer");
|
||||
|
||||
SWAPCOLOR(COLOR_ORANGE);
|
||||
gfx_printf("\rResult copy_recursive() %d\n\n", res);
|
||||
|
||||
if (res){
|
||||
SWAPCOLOR(COLOR_RED);
|
||||
gfx_printf("Dump failed!\n");
|
||||
}
|
||||
else
|
||||
gfx_printf("Saves are located in SD:/tegraexplorer/save\n");
|
||||
if(fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer"))
|
||||
return;
|
||||
|
||||
RESETCOLOR;
|
||||
gfx_printf("\n\nSaves are located in SD:/tegraexplorer/save\n");
|
||||
gfx_printf("Press any key to continue");
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 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,
|
||||
@@ -25,11 +26,12 @@
|
||||
|
||||
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
|
||||
|
||||
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
|
||||
#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||
#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||
#define _ADRP(r, o) (0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F))
|
||||
#define _BL(a, o) (0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||
#define _B(a, o) (0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||
#define _MOVKX(r, i, s) (0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _MOVZX(r, i, s) (0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _MOVZW(r, i, s) (0x52800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _NOP() 0xD503201F
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 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,
|
||||
@@ -33,9 +34,10 @@
|
||||
#define LIST_FOREACH_SAFE(iter, list) \
|
||||
for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
|
||||
|
||||
/*! Iterate over all list members. */
|
||||
/*! Iterate over all list members and make sure that the list has at least one entry. */
|
||||
#define LIST_FOREACH_ENTRY(etype, iter, list, mn) \
|
||||
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
|
||||
if ((list)->next != (list)) \
|
||||
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
|
||||
|
||||
typedef struct _link_t
|
||||
{
|
||||
|
||||
@@ -33,15 +33,22 @@ typedef struct _cfg_op_t
|
||||
u32 val;
|
||||
} cfg_op_t;
|
||||
|
||||
typedef struct _nyx_info_t
|
||||
{
|
||||
u32 rsvd;
|
||||
u32 errors;
|
||||
} nyx_info_t;
|
||||
|
||||
typedef struct _nyx_storage_t
|
||||
{
|
||||
u32 version;
|
||||
u32 cfg;
|
||||
u8 irama[0x8000];
|
||||
u8 hekate[0x30000];
|
||||
u8 rsvd[0x800000];
|
||||
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
|
||||
nyx_info_t info;
|
||||
mtc_config_t mtc_cfg;
|
||||
emc_table_t mtc_table;
|
||||
emc_table_t mtc_table[10];
|
||||
} nyx_storage_t;
|
||||
|
||||
u32 get_tmr_us();
|
||||
|
||||
Reference in New Issue
Block a user