Compare commits

...

44 Commits
1.4.0 ... 1.5.2

Author SHA1 Message Date
Such Meme, Many Skill
adc9d2e5bf Bump version 2020-04-26 01:28:11 +02:00
Such Meme, Many Skill
317e4b2038 Reduce file size + cleanup + add coreboot.rom file booting 2020-04-26 01:20:26 +02:00
Such Meme, Many Skill
bd99e2a138 Optimise screen scroll a bit, Edit display of filesizes 2020-04-23 14:40:55 +02:00
Such Meme, Many Skill
4c4a6511f3 Merge hekate changes
25ff127404
2020-04-23 13:54:48 +02:00
Such Meme, Many Skill
2bbcf63bd9 Fix restore% on e(mu)mmc partition restores 2020-04-23 13:40:29 +02:00
Such Meme, Many Skill
78722d9a90 Fix calc bug in partition size calculation 2020-04-22 12:23:18 +02:00
Such Meme, Many Skill
e24f8ad722 [Script] Make printf accept multiple args 2020-04-15 22:02:19 +02:00
Such Meme, Many Skill
28fb01b155 See pkg1 version on biskey dump failure 2020-04-14 10:25:31 +02:00
Such Meme, Many Skill
b8b37e78ba Hotfix for 10.0.0 2020-04-14 09:40:37 +02:00
Such Meme, Many Skill
82a4d03985 Bump version 2020-04-12 22:22:40 +02:00
Such Meme, Many Skill
195d9797fe Add that inside functions no "" are required for <=>+-/* 2020-04-12 20:31:32 +02:00
Such Meme, Many Skill
15e1210179 [script] Remove jump list & add if_check that works like if(check()) 2020-04-12 19:21:09 +02:00
Such Meme, Many Skill
e892e69929 don't hardcode locations where info should be parsed from 2020-04-08 17:33:34 +02:00
Such Meme, Many Skill
7e8e3ece66 [Script] Add clearscreen 2020-04-05 22:01:07 +02:00
Such Meme, Many Skill
b5a9d94d35 Bump version
+ Bugfix
2020-04-05 17:25:35 +02:00
Such Meme, Many Skill
f95b6e399f Bugfix + add fs_extractBisFile (to scripts) 2020-04-05 17:07:11 +02:00
Such Meme, Many Skill
6551930233 cleanup of mmc restores/dumps 2020-04-05 16:07:25 +02:00
suchmememanyskill
c2a2694baf Merge pull request #13 from suchmememanyskill/dynamic_mmc_mounting
Dynamic mmc mounting
2020-04-05 00:38:02 +02:00
Such Meme, Many Skill
03df13f34c don't forget to reset the clipboard helper 2020-04-05 00:33:12 +02:00
Such Meme, Many Skill
070f9c676d Bugfixes + relocate tools: dump bis 2020-04-05 00:22:23 +02:00
Such Meme, Many Skill
7dc3500a17 [script] add mmc_dumpPart() and mmc_restorePart() 2020-04-04 23:41:09 +02:00
Such Meme, Many Skill
97bbe2a333 Add partition restoring via clipboard 2020-04-04 22:15:13 +02:00
Such Meme, Many Skill
a6eaa1ec51 Implement dumping of partitions 2020-04-04 18:40:27 +02:00
Such Meme, Many Skill
f93cc0ff44 Get a basic gpt menu 2020-04-04 16:49:47 +02:00
suchmememanyskill
ee145ca9aa Merge pull request #11 from suchmememanyskill/script-rewrite
Finish script rewrite
2020-04-03 19:24:22 +02:00
Such Meme, Many Skill
8832b240a4 Add fs_combinePath() 2020-04-03 19:07:42 +02:00
Such Meme, Many Skill
744f90611a Fix commas causing issues, fix some freeze cases 2020-04-01 23:44:28 +02:00
Such Meme, Many Skill
440a921980 small fixes 2020-04-01 19:43:37 +02:00
Such Meme, Many Skill
d0799e3cd1 Rename some variables 2020-04-01 16:48:36 +02:00
Such Meme, Many Skill
5b32937f8f add stringcompare function, fix some returns 2020-04-01 16:37:32 +02:00
Such Meme, Many Skill
f438827263 add more functions 2020-04-01 13:57:25 +02:00
Such Meme, Many Skill
0e60746179 Add fs functions: Rewrite should be done 2020-04-01 00:41:55 +02:00
Such Meme, Many Skill
0e39c8dda9 add more functions 2020-04-01 00:17:45 +02:00
Such Meme, Many Skill
45a732c388 add functions, fix bugs 2020-03-31 22:01:20 +02:00
Such Meme, Many Skill
034384622f Add strings 2020-03-31 20:13:39 +02:00
Such Meme, Many Skill
9efbbc9317 Add functions, Add goto's 2020-03-31 17:58:09 +02:00
Such Meme, Many Skill
30afcddd3a more functions, cleanup and simple error checking 2020-03-31 15:34:19 +02:00
Such Meme, Many Skill
38f349618f Add functions and int vars 2020-03-31 14:24:34 +02:00
Such Meme, Many Skill
33a64abfb0 Small fixes 2020-03-31 00:16:46 +02:00
Such Meme, Many Skill
c4783fc2ca Cleanup 2020-03-31 00:09:23 +02:00
Such Meme, Many Skill
887972d67c Add arg recognition + more command reading 2020-03-30 22:40:59 +02:00
Such Meme, Many Skill
9aff029ee4 Start script rewrite 2020-03-30 20:15:07 +02:00
Such Meme, Many Skill
bfcdc2ffd5 Ignore menu entries in entries count and include sd ejection detection 2020-03-22 22:56:36 +01:00
Such Meme, Many Skill
e4ae9d9d7c (untested) should hide errors in scripts 2020-03-21 20:31:22 +01:00
57 changed files with 2127 additions and 638 deletions

View File

@@ -10,8 +10,8 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40003000 IPL_LOAD_ADDR := 0x40003000
LPVERSION_MAJOR := 2 LPVERSION_MAJOR := 2
LPVERSION_MINOR := 4 LPVERSION_MINOR := 5
LPVERSION_BUGFX := 0 LPVERSION_BUGFX := 2
################################################################################ ################################################################################

View File

@@ -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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * 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 = 0;
h_cfg.autoboot_list = 0; h_cfg.autoboot_list = 0;
h_cfg.bootwait = 3; h_cfg.bootwait = 3;
h_cfg.verification = 1;
h_cfg.se_keygen_done = 0; h_cfg.se_keygen_done = 0;
h_cfg.sbar_time_keeping = 0; h_cfg.sbar_time_keeping = 0;
h_cfg.backlight = 100; h_cfg.backlight = 100;
h_cfg.autohosoff = 0; h_cfg.autohosoff = 0;
h_cfg.autonogc = 1; h_cfg.autonogc = 1;
h_cfg.updater2p = 0;
h_cfg.brand = NULL; h_cfg.brand = NULL;
h_cfg.tagline = NULL; h_cfg.tagline = NULL;
h_cfg.errors = 0; h_cfg.errors = 0;
@@ -50,7 +50,7 @@ void set_default_configuration()
h_cfg.rcm_patched = true; h_cfg.rcm_patched = true;
h_cfg.emummc_force_disable = false; h_cfg.emummc_force_disable = false;
sd_power_cycle_time_start = 0xFFFFFFF; sd_power_cycle_time_start = 0;
} }
int create_config_entry() int create_config_entry()
@@ -96,9 +96,6 @@ int create_config_entry()
f_puts("\nbootwait=", &fp); f_puts("\nbootwait=", &fp);
itoa(h_cfg.bootwait, lbuf, 10); itoa(h_cfg.bootwait, lbuf, 10);
f_puts(lbuf, &fp); f_puts(lbuf, &fp);
f_puts("\nverification=", &fp);
itoa(h_cfg.verification, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nbacklight=", &fp); f_puts("\nbacklight=", &fp);
itoa(h_cfg.backlight, lbuf, 10); itoa(h_cfg.backlight, lbuf, 10);
f_puts(lbuf, &fp); f_puts(lbuf, &fp);
@@ -108,6 +105,9 @@ int create_config_entry()
f_puts("\nautonogc=", &fp); f_puts("\nautonogc=", &fp);
itoa(h_cfg.autonogc, lbuf, 10); itoa(h_cfg.autonogc, lbuf, 10);
f_puts(lbuf, &fp); f_puts(lbuf, &fp);
f_puts("\nupdater2p=", &fp);
itoa(h_cfg.updater2p, lbuf, 10);
f_puts(lbuf, &fp);
if (h_cfg.brand) if (h_cfg.brand)
{ {
f_puts("\nbrand=", &fp); f_puts("\nbrand=", &fp);
@@ -281,10 +281,11 @@ void config_autoboot()
LIST_INIT(ini_sections); LIST_INIT(ini_sections);
u8 max_entries = 30; u8 max_entries = 30;
u32 boot_text_size = 512;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5)); ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries); 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++) for (u32 j = 0; j < max_entries; j++)
boot_values[j] = j; boot_values[j] = j;
@@ -330,12 +331,12 @@ void config_autoboot()
else else
{ {
if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list) if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list)
boot_text[(i - 4) * 512] = ' '; boot_text[(i - 4) * boot_text_size] = ' ';
else else
boot_text[(i - 4) * 512] = '*'; boot_text[(i - 4) * boot_text_size] = '*';
strcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name); strcpy(boot_text + (i - 4) * boot_text_size + 1, ini_sec->name);
ments[i].caption = &boot_text[(i - 4) * 512]; ments[i].caption = &boot_text[(i - 4) * boot_text_size];
} }
ments[i].type = ini_sec->type; ments[i].type = ini_sec->type;
ments[i].data = &boot_values[i - 4]; ments[i].data = &boot_values[i - 4];
@@ -391,10 +392,11 @@ void config_bootdelay()
gfx_con_setpos(0, 0); gfx_con_setpos(0, 0);
u32 delay_entries = 6; u32 delay_entries = 6;
u32 delay_text_size = 32;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (delay_entries + 3)); ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (delay_entries + 3));
u32 *delay_values = (u32 *)malloc(sizeof(u32) * delay_entries); 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++) for (u32 j = 0; j < delay_entries; j++)
delay_values[j] = j; delay_values[j] = j;
@@ -415,14 +417,14 @@ void config_bootdelay()
for (i = 1; i < delay_entries; i++) for (i = 1; i < delay_entries; i++)
{ {
if (h_cfg.bootwait != i) if (h_cfg.bootwait != i)
delay_text[i * 32] = ' '; delay_text[i * delay_text_size] = ' ';
else else
delay_text[i * 32] = '*'; delay_text[i * delay_text_size] = '*';
delay_text[i * 32 + 1] = i + '0'; delay_text[i * delay_text_size + 1] = i + '0';
strcpy(delay_text + i * 32 + 2, " seconds"); strcpy(delay_text + i * delay_text_size + 2, " seconds");
ments[i + 2].type = MENT_DATA; 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]; ments[i + 2].data = &delay_values[i];
} }
@@ -445,69 +447,17 @@ void config_bootdelay()
btn_wait(); 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() void config_backlight()
{ {
gfx_clear_grey(0x1B); gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0); gfx_con_setpos(0, 0);
u32 bri_text_size = 8;
u32 bri_entries = 11; u32 bri_entries = 11;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (bri_entries + 3)); ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (bri_entries + 3));
u32 *bri_values = (u32 *)malloc(sizeof(u32) * bri_entries); 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++) for (u32 j = 1; j < bri_entries; j++)
bri_values[j] = j * 10; bri_values[j] = j * 10;
@@ -521,20 +471,20 @@ void config_backlight()
for (i = 1; i < bri_entries; i++) for (i = 1; i < bri_entries; i++)
{ {
if ((h_cfg.backlight / 20) != i) if ((h_cfg.backlight / 20) != i)
bri_text[i * 32] = ' '; bri_text[i * bri_text_size] = ' ';
else else
bri_text[i * 32] = '*'; bri_text[i * bri_text_size] = '*';
if (i < 10) if (i < 10)
{ {
bri_text[i * 32 + 1] = i + '0'; bri_text[i * bri_text_size + 1] = i + '0';
strcpy(bri_text + i * 32 + 2, "0%"); strcpy(bri_text + i * bri_text_size + 2, "0%");
} }
else 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].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]; ments[i + 1].data = &bri_values[i];
} }

View File

@@ -25,10 +25,10 @@ typedef struct _hekate_config
u32 autoboot; u32 autoboot;
u32 autoboot_list; u32 autoboot_list;
u32 bootwait; u32 bootwait;
u32 verification;
u32 backlight; u32 backlight;
u32 autohosoff; u32 autohosoff;
u32 autonogc; u32 autonogc;
u32 updater2p;
char *brand; char *brand;
char *tagline; char *tagline;
// Global temporary config. // Global temporary config.
@@ -40,16 +40,10 @@ typedef struct _hekate_config
u32 errors; u32 errors;
} hekate_config; } hekate_config;
typedef enum
{
ERR_LIBSYS_LP0 = (1 << 0),
} hsysmodule_t;
void set_default_configuration(); void set_default_configuration();
int create_config_entry(); int create_config_entry();
void config_autoboot(); void config_autoboot();
void config_bootdelay(); void config_bootdelay();
void config_verification();
void config_backlight(); void config_backlight();
void config_auto_hos_poweroff(); void config_auto_hos_poweroff();
void config_nogc(); void config_nogc();

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * 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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * 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 _find_section_name(char *lbuf, u32 lblen, char schar)
{ {
u32 i; 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; lbuf[i] = 0;
@@ -123,8 +124,8 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
f_gets(lbuf, 512, &fp); f_gets(lbuf, 512, &fp);
lblen = strlen(lbuf); lblen = strlen(lbuf);
// Remove trailing newline. // Remove trailing newline. Depends on 'FF_USE_STRFUNC 2' that removes \r.
if (lbuf[lblen - 1] == '\n' || lbuf[lblen - 1] == '\r') if (lblen && lbuf[lblen - 1] == '\n')
lbuf[lblen - 1] = 0; lbuf[lblen - 1] = 0;
if (lblen > 2 && lbuf[0] == '[') // Create new section. 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); csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE);
list_init(&csec->kvs); 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, '}'); _find_section_name(lbuf, lblen, '}');
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CAPTION); csec = _ini_create_section(dst, csec, &lbuf[1], INI_CAPTION);
csec->color = 0xFF0AB9E6; 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); 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); 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, '='); u32 i = _find_section_name(lbuf, lblen, '=');

View File

@@ -269,6 +269,12 @@ void gfx_putc(char c)
if (gfx_con.y > gfx_ctxt.height - 8) if (gfx_con.y > gfx_ctxt.height - 8)
gfx_con.y = 0; 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; 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){ void gfx_box(int x0, int y0, int x1, int y1, u32 color){
for (int x = x0; x < x1 + 1; x++){ for (int x = x0; x < x1 + 1; x++){
for (int y = y0; y < y1 + 1; y++){ for (int y = y0; y < y1 + 1; y++){

View File

@@ -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_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_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_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. // Global gfx console and context.
gfx_ctxt_t gfx_ctxt; gfx_ctxt_t gfx_ctxt;

View File

@@ -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 { "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 { "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 { "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. { NULL } //End.
}; };

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer * Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 Atmosphère-NX * Copyright (c) 2018 Atmosphère-NX
* *
* This program is free software; you can redistribute it and/or modify it * 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) void pkg2_get_newkern_info(u8 *kern_data)
{ {
u32 info_op = *(u32 *)(kern_data + PKG2_NEWKERN_GET_INI1); u32 pkg2_newkern_ini1_off = 0;
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + PKG2_NEWKERN_GET_INI1; // Parse ADR and PC. 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_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val);
pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8); 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; u8 *ptr;
// Check for new pkg2 type. // 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); pkg2_get_newkern_info(pkg2->data);
if (!pkg2_newkern_ini1_start)
return false;
ptr = pkg2->data + pkg2_newkern_ini1_start; ptr = pkg2->data + pkg2_newkern_ini1_start;
*new_pkg2 = true; *new_pkg2 = true;
} }
@@ -75,6 +98,8 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
ptr += ki->size; ptr += ki->size;
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, 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) int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * 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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -26,7 +26,7 @@
#define PKG2_SEC_KERNEL 0 #define PKG2_SEC_KERNEL 0
#define PKG2_SEC_INI1 1 #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_val;
u32 pkg2_newkern_ini1_start; u32 pkg2_newkern_ini1_start;
@@ -87,7 +87,7 @@ typedef struct _pkg2_kip1_info_t
link_t link; link_t link;
} pkg2_kip1_info_t; } 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); int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp);
pkg2_hdr_t *pkg2_decrypt(void *data); pkg2_hdr_t *pkg2_decrypt(void *data);

View File

@@ -45,20 +45,11 @@
sdmmc_t sd_sdmmc; sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage; sdmmc_storage_t sd_storage;
__attribute__ ((aligned (16))) FATFS sd_fs; __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; volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
hekate_config h_cfg; hekate_config h_cfg;
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_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() bool sd_mount()
{ {
if (sd_mounted) 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_SZ 0x94
#define PATCHED_RELOC_STACK 0x40007000 #define PATCHED_RELOC_STACK 0x40007000
#define PATCHED_RELOC_ENTRY 0x40010000 #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 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_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) 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) 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; *(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
} }
} }
@@ -195,7 +188,10 @@ int launch_payload(char *path)
if (size < 0x30000) if (size < 0x30000)
buf = (void *)RCM_PAYLOAD_ADDR; buf = (void *)RCM_PAYLOAD_ADDR;
else else
buf = (void *)COREBOOT_ADDR; {
coreboot_addr = (void *)(COREBOOT_END_ADDR - size);
buf = coreboot_addr;
}
if (f_read(&fp, buf, size, NULL)) if (f_read(&fp, buf, size, NULL))
{ {
@@ -351,7 +347,7 @@ void dump_sysnand()
{ {
h_cfg.emummc_force_disable = true; h_cfg.emummc_force_disable = true;
b_cfg.extra_cfg &= ~EXTRA_CFG_DUMP_EMUMMC; b_cfg.extra_cfg &= ~EXTRA_CFG_DUMP_EMUMMC;
dump_keys(); //dump_keys();
} }
void dump_emunand() void dump_emunand()
@@ -360,7 +356,7 @@ void dump_emunand()
return; return;
emu_cfg.enabled = 1; emu_cfg.enabled = 1;
b_cfg.extra_cfg |= EXTRA_CFG_DUMP_EMUMMC; b_cfg.extra_cfg |= EXTRA_CFG_DUMP_EMUMMC;
dump_keys(); //dump_keys();
} }
ment_t ment_top[] = { ment_t ment_top[] = {

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 M4xw * Copyright (c) 2018 M4xw
* *
* This program is free software; you can redistribute it and/or modify it * 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. // Node info is before node address.
static u32 _heap_alloc(heap_t *heap, u32 size) static u32 _heap_alloc(heap_t *heap, u32 size)
{ {
hnode_t *node, *new; hnode_t *node, *new_node;
// Align to cache line size. // Align to cache line size.
size = ALIGN(size, sizeof(hnode_t)); size = ALIGN(size, sizeof(hnode_t));
@@ -49,22 +50,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
node = heap->first; node = heap->first;
while (true) while (true)
{ {
// Check if there's available unused node.
if (!node->used && (size <= node->size)) if (!node->used && (size <= node->size))
{ {
// Size and offset of the new unused node.
u32 new_size = node->size - size; 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)) if (new_size >= (sizeof(hnode_t) << 2))
{ {
new->size = new_size - sizeof(hnode_t); new_node->size = new_size - sizeof(hnode_t);
new->used = 0; new_node->used = 0;
new->next = node->next; new_node->next = node->next;
new->next->prev = new;
new->prev = node; // Check that we are not on first node.
node->next = new; 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; size += new_size;
node->size = size; node->size = size;
@@ -72,20 +80,23 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
return (u32)node + sizeof(hnode_t); return (u32)node + sizeof(hnode_t);
} }
// No unused node found, try the next one.
if (node->next) if (node->next)
node = node->next; node = node->next;
else else
break; break;
} }
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size); // No unused node found, create a new one.
new->used = 1; new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
new->size = size; new_node->used = 1;
new->prev = node; new_node->size = size;
new->next = NULL; new_node->prev = node;
node->next = new; 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) 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->size += node->size + sizeof(hnode_t);
node->prev->next = node->next; node->prev->next = node->next;
if (node->next) if (node->next)
node->next->prev = node->prev; node->next->prev = node->prev;
} }

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,

View File

@@ -34,18 +34,21 @@ u32 minerva_init()
minerva_cfg = NULL; minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg; 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. // Set table to nyx storage.
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table; mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F; mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
mtc_cfg->init_done = MTC_NEW_MAGIC; // Initialize mtc table. 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); u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
// Ensure that Minerva is new. // Ensure that Minerva is new.
if (mtc_cfg->init_done == MTC_INIT_MAGIC) if (mtc_cfg->init_done == MTC_INIT_MAGIC)
minerva_cfg = (void *)ep_addr; minerva_cfg = (void *)ep_addr;
else
mtc_cfg->init_done = 0;
if (!minerva_cfg) if (!minerva_cfg)
return 1; return 1;

View File

@@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 balika011 * 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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * 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() void sdram_init()
{ {
//TODO: sdram_id should be in [0,4].
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params(); const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
// Set DRAM voltage. // Set DRAM voltage.

View File

@@ -4,7 +4,7 @@
* *
* Copyright (c) 2011 Samsung Electronics * Copyright (c) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@samsung.com> * 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 * 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 * 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_K_empty0 = 0x3B,
MAX17050_TaskPeriod = 0x3C, MAX17050_TaskPeriod = 0x3C,
MAX17050_FSTAT = 0x3D, MAX17050_FSTAT = 0x3D,
MAX17050_TIMER = 0x3E,
MAX17050_SHDNTIMER = 0x3F, MAX17050_SHDNTIMER = 0x3F,
MAX17050_QRTbl30 = 0x42, MAX17050_QRTbl30 = 0x42,
MAX17050_dQacc = 0x45, MAX17050_dQacc = 0x45,
MAX17050_dPacc = 0x46, MAX17050_dPacc = 0x46,
MAX17050_VFSOC0 = 0x48, MAX17050_VFSOC0 = 0x48,
Max17050_QH0 = 0x4C,
MAX17050_QH = 0x4D, MAX17050_QH = 0x4D,
MAX17050_QL = 0x4E, MAX17050_QL = 0x4E,
@@ -111,6 +114,8 @@ enum MAX17050_reg {
MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c. MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c.
MAX17050_VFSOC0Enable = 0x60, MAX17050_VFSOC0Enable = 0x60,
MAX17050_MODELEnable1 = 0x62,
MAX17050_MODELEnable2 = 0x63,
MAX17050_MODELChrTbl = 0x80, MAX17050_MODELChrTbl = 0x80,

View File

@@ -137,6 +137,7 @@ int max77620_regulator_enable(u32 id, int enable)
return 1; return 1;
} }
// LDO only.
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags) int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
{ {
if (id > REGULATOR_MAX) if (id > REGULATOR_MAX)
@@ -168,9 +169,9 @@ void max77620_config_default()
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4); _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_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); MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
} }

View File

@@ -33,7 +33,7 @@
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 | * ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv) * ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | * 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 * ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | * ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
* ldo8 | XUSB, DC | 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_enable(u32 id, int enable);
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags); int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
void max77620_config_default(); void max77620_config_default();
void max77620_low_battery_monitor_config(); void max77620_low_battery_monitor_config(bool enable);
#endif #endif

View File

@@ -1,7 +1,8 @@
/* /*
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC * 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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * 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. // Update RTC clock from RTC regs.
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE); 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;
}

View File

@@ -71,5 +71,7 @@ typedef struct _rtc_time_t {
void max77620_rtc_get_time(rtc_time_t *time); void max77620_rtc_get_time(rtc_time_t *time);
void max77620_rtc_stop_alarm(); 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_ */ #endif /* _MFD_MAX77620_RTC_H_ */

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * 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 * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -39,6 +39,7 @@
extern sdmmc_t sd_sdmmc; extern sdmmc_t sd_sdmmc;
extern boot_cfg_t b_cfg; extern boot_cfg_t b_cfg;
extern volatile nyx_storage_t *nyx_str;
/* /*
* CLK_OSC - 38.4 MHz crystal. * CLK_OSC - 38.4 MHz crystal.
@@ -78,8 +79,8 @@ void _config_gpios()
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0; PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
// Set Joy-Con IsAttached direction. // Set Joy-Con IsAttached direction.
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE; PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE; PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
// Set pin mode for Joy-Con IsAttached and UARTB/C TX pins. // Set pin mode for Joy-Con IsAttached and UARTB/C TX pins.
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B #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); gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
// Configure HOME as inputs. // 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); // 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. // 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_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) = 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_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_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. 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() void _config_se_brom()
{ {
// Enable fuse clock.
clock_enable_fuse(true);
// Skip SBK/SSK if sept was run. // Skip SBK/SSK if sept was run.
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN)) if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
{ {
@@ -217,10 +221,19 @@ void _config_se_brom()
void _config_regulators() 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_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off. (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, i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT)); (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, 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, 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+ (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); 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_GPIO5, 2);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 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, 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_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL); MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
// Enable low battery shutdown monitor for < 2800mV.
max77620_low_battery_monitor_config();
} }
void config_hw() void config_hw()
@@ -312,6 +322,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
bpmp_mmu_disable(); bpmp_mmu_disable();
bpmp_clk_rate_set(BPMP_CLK_NORMAL); bpmp_clk_rate_set(BPMP_CLK_NORMAL);
minerva_change_freq(FREQ_204); minerva_change_freq(FREQ_204);
nyx_str->mtc_cfg.init_done = 0;
// Re-enable clocks to Audio Processing Engine as a workaround to hanging. // 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. CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -19,7 +20,7 @@
#include "i2c.h" #include "i2c.h"
#include "../utils/util.h" #include "../utils/util.h"
static u32 i2c_addrs[] = { static const u32 i2c_addrs[] = {
0x7000C000, 0x7000C400, 0x7000C500, 0x7000C000, 0x7000C400, 0x7000C500,
0x7000C700, 0x7000D000, 0x7000D100 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); 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 i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
{ {
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1); int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -39,6 +40,7 @@
void i2c_init(u32 idx); void i2c_init(u32 idx);
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size); 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_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); int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u8 i2c_recv_byte(u32 idx, u32 x, u32 y); u8 i2c_recv_byte(u32 idx, u32 x, u32 y);

View File

@@ -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++) 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)); 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_start = ent->lba_start;
part->lba_end = ent->lba_end; part->lba_end = ent->lba_end;
part->attrs = ent->attrs; part->attrs = ent->attrs;

View File

@@ -5,7 +5,7 @@ extern const char *gfx_file_size_names[];
extern const char *menu_sd_states[]; extern const char *menu_sd_states[];
extern const char *emmc_fs_entries[]; extern const char *emmc_fs_entries[];
extern const char *utils_err_codes[]; extern const char *utils_err_codes[];
extern const char *pkg2names[]; //extern const char *pkg2names[];
extern const char *mainmenu_credits; extern const char *mainmenu_credits;
enum utils_err_codes_te_call { enum utils_err_codes_te_call {
@@ -19,7 +19,11 @@ enum utils_err_codes_te_call {
ERR_MEM_ALLOC_FAILED, ERR_MEM_ALLOC_FAILED,
ERR_EMMC_READ_FAILED, ERR_EMMC_READ_FAILED,
ERR_EMMC_WRITE_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[]; extern const char *utils_err_codes_te[];
@@ -55,8 +59,7 @@ enum mainmenu_tools_return {
TOOLS_DISPLAY_INFO = 1, TOOLS_DISPLAY_INFO = 1,
TOOLS_DISPLAY_GPIO, TOOLS_DISPLAY_GPIO,
TOOLS_DUMPFIRMWARE, TOOLS_DUMPFIRMWARE,
TOOLS_DUMPUSERSAVE, TOOLS_DUMPUSERSAVE
TOOLS_DUMP_BOOT
}; };
extern menu_entry mainmenu_tools[]; extern menu_entry mainmenu_tools[];
@@ -82,8 +85,7 @@ enum fs_menu_file_return {
FILE_PAYLOAD, FILE_PAYLOAD,
FILE_SCRIPT, FILE_SCRIPT,
FILE_HEXVIEW, FILE_HEXVIEW,
FILE_DUMPBIS, FILE_DUMPBIS
FILE_RESTOREBIS
}; };
extern menu_entry fs_menu_file[]; extern menu_entry fs_menu_file[];
@@ -102,4 +104,10 @@ enum fs_menu_startdir_return {
FILEMENU_CURFOLDER 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[];

View File

@@ -48,9 +48,13 @@ const char *utils_err_codes_te[] = { // these start at 50
"MEM ALLOC FAILED", "MEM ALLOC FAILED",
"EMMC READ FAILED", "EMMC READ FAILED",
"EMMC WRITE 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[] = { const char *pkg2names[] = {
"BCPKG2-1-Normal-Main", "BCPKG2-1-Normal-Main",
"BCPKG2-2-Normal-Sub", "BCPKG2-2-Normal-Sub",
@@ -59,5 +63,5 @@ const char *pkg2names[] = {
"BCPKG2-5-Repair-Main", "BCPKG2-5-Repair-Main",
"BCPKG2-6-Repair-Sub" "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"; const char *mainmenu_credits = "\nTegraexplorer, made by:\nSuch Meme, Many Skill\n\nProject based on:\nLockpick_RCM\nHekate\n\nCool people:\nshchmue\ndennthecafebabe\nDax";

View File

@@ -2,13 +2,9 @@
#include "types.h" #include "types.h"
menu_entry mainmenu_main[] = { menu_entry mainmenu_main[] = {
{"[SD:/] SD CARD\n", COLOR_GREEN, ISMENU}, {"[SD:/] SD CARD", COLOR_GREEN, ISMENU},
{"[SAFE:/] EMMC", COLOR_ORANGE, ISMENU}, {"[EMMC:/] EMMC", COLOR_ORANGE, ISMENU},
{"[SYSTEM:/] EMMC", COLOR_ORANGE, ISMENU}, {"[EMMC:/] EMUMMC", COLOR_BLUE, ISMENU},
{"[USER:/] EMMC", COLOR_ORANGE, ISMENU},
{"\n[SAFE:/] EMUMMC", COLOR_BLUE, ISMENU},
{"[SYSTEM:/] EMUMMC", COLOR_BLUE, ISMENU},
{"[USER:/] EMUMMC", COLOR_BLUE, ISMENU},
{"\nMount/Unmount SD", COLOR_WHITE, ISMENU}, {"\nMount/Unmount SD", COLOR_WHITE, ISMENU},
{"Tools", COLOR_VIOLET, ISMENU}, {"Tools", COLOR_VIOLET, ISMENU},
{"SD format", COLOR_VIOLET, ISMENU}, {"SD format", COLOR_VIOLET, ISMENU},
@@ -30,8 +26,7 @@ menu_entry mainmenu_tools[] = {
{"\nDisplay Console Info", COLOR_GREEN, ISMENU}, {"\nDisplay Console Info", COLOR_GREEN, ISMENU},
{"Display GPIO pins", COLOR_VIOLET, ISMENU}, {"Display GPIO pins", COLOR_VIOLET, ISMENU},
{"Dump Firmware", COLOR_BLUE, ISMENU}, {"Dump Firmware", COLOR_BLUE, ISMENU},
{"Dump User Saves", COLOR_YELLOW, ISMENU}, {"Dump User Saves", COLOR_YELLOW, ISMENU}
{"Dump bis", COLOR_ORANGE, ISMENU}
}; };
menu_entry mainmenu_format[] = { menu_entry mainmenu_format[] = {
@@ -57,8 +52,7 @@ menu_entry fs_menu_file[] = {
{"Launch Payload", COLOR_ORANGE, ISMENU}, {"Launch Payload", COLOR_ORANGE, ISMENU},
{"Launch Script", COLOR_YELLOW, ISMENU}, {"Launch Script", COLOR_YELLOW, ISMENU},
{"View Hex", COLOR_GREEN, ISMENU}, {"View Hex", COLOR_GREEN, ISMENU},
{"\nExtract BIS", COLOR_YELLOW, ISMENU}, {"\nExtract BIS", COLOR_YELLOW, ISMENU}
{"Restore BIS", COLOR_RED, ISMENU}
}; };
menu_entry fs_menu_folder[] = { menu_entry fs_menu_folder[] = {
@@ -70,7 +64,29 @@ menu_entry fs_menu_folder[] = {
}; };
menu_entry fs_menu_startdir[] = { menu_entry fs_menu_startdir[] = {
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU}, {"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
{"Clipboard -> Current folder ", COLOR_ORANGE, ISMENU}, {"Clipboard -> Current folder", COLOR_ORANGE, ISMENU},
{"Current folder menu ", 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}
}; };

View File

@@ -43,4 +43,12 @@ typedef struct {
char *name; char *name;
u32 storage; u32 storage;
u16 property; u16 property;
} menu_entry; } menu_entry;
typedef struct {
const char *name;
u8 property;
} gpt_entry_rule;
#define isFS 0x80
#define isBOOT 0x2

View File

@@ -22,13 +22,16 @@
#include "../../config/config.h" #include "../../config/config.h"
#include "../common/common.h" #include "../common/common.h"
#include "../gfx/gfxutils.h" #include "../gfx/gfxutils.h"
#include "../../utils/list.h"
#include "../../mem/heap.h"
sdmmc_storage_t storage; sdmmc_storage_t storage;
emmc_part_t *system_part; emmc_part_t *system_part;
sdmmc_t sdmmc; sdmmc_t sdmmc;
extern hekate_config h_cfg; extern hekate_config h_cfg;
__attribute__ ((aligned (16))) FATFS emmc; __attribute__ ((aligned (16))) FATFS emmc;
LIST_INIT(gpt); LIST_INIT(sys_gpt);
LIST_INIT(emu_gpt);
u8 bis_key[4][32]; u8 bis_key[4][32];
pkg1_info pkg1inf = {-1, ""}; pkg1_info pkg1inf = {-1, ""};
@@ -64,10 +67,10 @@ pkg1_info returnpkg1info(){
int connect_part(const char *partition){ int connect_part(const char *partition){
sdmmc_storage_set_mmc_partition(&storage, 0); 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) { if (!system_part) {
gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0); gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0);
return -1; return 1;
} }
return 0; 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); se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10);
if (connect_part(partition)) if (connect_part(partition))
return -1; return 1;
if ((res = f_mount(&emmc, "emmc:", 1))) { if ((res = f_mount(&emmc, "emmc:", 1))) {
gfx_errDisplay("mount_mmc", res, 0); gfx_errDisplay("mount_mmc", res, 0);
return -1; return 1;
} }
return 0; return 0;
@@ -136,6 +139,7 @@ int dump_biskeys(){
u8 *pkg1 = (u8 *)malloc(0x40000); u8 *pkg1 = (u8 *)malloc(0x40000);
sdmmc_storage_set_mmc_partition(&storage, 1); sdmmc_storage_set_mmc_partition(&storage, 1);
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1); 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); const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
if (!pkg1_id) { if (!pkg1_id) {
EPRINTF("Unknown pkg1 version."); EPRINTF("Unknown pkg1 version.");
@@ -212,9 +216,8 @@ int dump_biskeys(){
memcpy(bis_key[3], bis_key[2], 0x20); memcpy(bis_key[3], bis_key[2], 0x20);
} }
sdmmc_storage_set_mmc_partition(&storage, 0); //sdmmc_storage_set_mmc_partition(&storage, 0);
// Parse eMMC GPT. //nx_emmc_gpt_parse(&sys_gpt, &storage);
nx_emmc_gpt_parse(&gpt, &storage);
se_aes_key_set(8, bis_key[2] + 0x00, 0x10); se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
se_aes_key_set(9, bis_key[2] + 0x10, 0x10); se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
@@ -222,4 +225,34 @@ int dump_biskeys(){
pkg1inf.ver = pkg1_id->kb; pkg1inf.ver = pkg1_id->kb;
strcpy(pkg1inf.id, pkg1_id->id); strcpy(pkg1inf.id, pkg1_id->id);
return 0; 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;
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "../../utils/types.h" #include "../../utils/types.h"
#include "../../utils/list.h"
typedef struct _pkg1_info { typedef struct _pkg1_info {
short ver; short ver;
@@ -15,6 +16,9 @@ int mount_mmc(const char *partition, const int biskeynumb);
void connect_mmc(short mmctype); void connect_mmc(short mmctype);
void disconnect_mmc(); void disconnect_mmc();
int connect_part(const char *partition); int connect_part(const char *partition);
void dumpGpt();
link_t *selectGpt(short mmcType);
int checkGptRules(char *in);
static const u8 zeros[0x10] = {0}; static const u8 zeros[0x10] = {0};

View File

@@ -18,7 +18,7 @@
extern sdmmc_storage_t storage; extern sdmmc_storage_t storage;
extern emmc_part_t *system_part; 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; FIL fp;
u8 *buf; u8 *buf;
u32 lba_curr = part->lba_start; 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; 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){ int dump_emmc_parts(u16 parts, u8 mmctype){
char *path; char *path;
char basepath[] = "sd:/tegraexplorer/dumps"; char basepath[] = "sd:/tegraexplorer/partition_dumps";
f_mkdir("sd:/tegraexplorer"); f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/dumps"); f_mkdir("sd:/tegraexplorer/partition_dumps");
connect_mmc(mmctype); connect_mmc(mmctype);
gfx_clearscreen(); gfx_clearscreen();
@@ -92,29 +106,79 @@ int dump_emmc_parts(u16 parts, u8 mmctype){
emummc_storage_set_mmc_partition(&storage, i + 1); emummc_storage_set_mmc_partition(&storage, i + 1);
utils_copystring(fsutil_getnextloc(basepath, bootPart.name), &path); utils_copystring(fsutil_getnextloc(basepath, bootPart.name), &path);
if (!existsCheck(path))
continue;
gfx_printf("Dumping %s\n", bootPart.name); gfx_printf("Dumping %s\n", bootPart.name);
dump_emmc_part(path, &storage, &bootPart); dump_emmc_part(path, &storage, &bootPart);
free(path); free(path);
} }
emummc_storage_set_mmc_partition(&storage, 0);
} }
if (parts & PART_PKG2){ if (parts & PART_PKG2){
for (int i = 0; i < 6; i++){ for (int i = 0; i < 6; i++){
if (connect_part(pkg2names[i])){ utils_copystring(fsutil_getnextloc(basepath, pkg2names[i]), &path);
gfx_errDisplay("dump_emmc_parts", ERR_PART_NOT_FOUND, 0); gfx_printf("Dumping %s\n", pkg2names[i]);
return -1;
}
utils_copystring(fsutil_getnextloc(basepath, system_part->name), &path); emmcDumpSpecific(pkg2names[i], path);
gfx_printf("Dumping %s\n", system_part->name);
dump_emmc_part(path, &storage, system_part);
free(path); free(path);
} }
} }
gfx_printf("\nDone!"); gfx_printf("\nDone!");
btn_wait(); 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; return 0;
} }

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
#pragma once
int makeMmcMenu(short mmcType);

View File

@@ -1,5 +1,10 @@
#pragma once #pragma once
#include "../../utils/types.h" #include "../../utils/types.h"
#include "../../storage/nx_emmc.h"
int dump_emmc_parts(u16 parts, u8 mmctype); int emmcDumpSpecific(char *part, char *path);
int restore_bis_using_file(char *path, u8 mmctype); 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);

View File

@@ -18,12 +18,12 @@
extern sdmmc_storage_t storage; extern sdmmc_storage_t storage;
extern emmc_part_t *system_part; 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; FIL fp;
FILINFO fno; FILINFO fno;
u8 *buf; u8 *buf;
u32 lba_curr = part->lba_start; u32 lba_curr = part->lba_start;
u32 bytesWritten = 0; u64 bytesWritten = 0;
u32 totalSectorsDest = part->lba_end - part->lba_start + 1; u32 totalSectorsDest = part->lba_end - part->lba_start + 1;
u64 totalSizeDest = (u64)((u64)totalSectorsDest << 9); u64 totalSizeDest = (u64)((u64)totalSectorsDest << 9);
u64 totalSize; u64 totalSize;
@@ -93,9 +93,9 @@ int restore_emmc_part(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part
lba_curr += num; lba_curr += num;
totalSectors -= 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); 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; 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){ int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
connect_mmc(mmctype); connect_mmc(mmctype);
@@ -164,4 +166,64 @@ int restore_bis_using_file(char *path, u8 mmctype){
btn_wait(); btn_wait();
return 0; 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;
} }

View File

@@ -13,7 +13,7 @@
#include "../gfx/menu.h" #include "../gfx/menu.h"
#include "../common/types.h" #include "../common/types.h"
#include "../../utils/sprintf.h" #include "../../utils/sprintf.h"
#include "../utils/script.h" #include "../script/parser.h"
#include "../emmc/emmcoperations.h" #include "../emmc/emmcoperations.h"
extern char *currentpath; extern char *currentpath;
@@ -47,7 +47,7 @@ void viewbytes(char *path){
return; return;
} }
msleep(200); while (btn_read() & BTN_POWER);
while (1){ while (1){
f_lseek(&in, offset * 16); f_lseek(&in, offset * 16);
@@ -111,7 +111,6 @@ void copyfile(const char *src_in, const char *outfolder){
free(out); free(out);
free(filename); free(filename);
fsreader_readfolder(currentpath); fsreader_readfolder(currentpath);
clipboardhelper = 0;
} }
int filemenu(menu_entry file){ int filemenu(menu_entry file){
@@ -144,12 +143,11 @@ int filemenu(menu_entry file){
(attribs.fattrib & AM_ARC) ? 'A' : '-'); (attribs.fattrib & AM_ARC) ? 'A' : '-');
} }
SETBIT(fs_menu_file[7].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.property & ISKB)); 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, ".tegrascript") != 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)); SETBIT(fs_menu_file[10].property, ISHIDE, strstr(file.name, ".bis") == NULL);
SETBIT(fs_menu_file[11].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){ switch (temp){
case FILE_COPY: case FILE_COPY:
@@ -165,7 +163,9 @@ int filemenu(menu_entry file){
launch_payload(fsutil_getnextloc(currentpath, file.name)); launch_payload(fsutil_getnextloc(currentpath, file.name));
break; break;
case FILE_SCRIPT: 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; break;
case FILE_HEXVIEW: case FILE_HEXVIEW:
viewbytes(fsutil_getnextloc(currentpath, file.name)); viewbytes(fsutil_getnextloc(currentpath, file.name));
@@ -176,9 +176,8 @@ int filemenu(menu_entry file){
fsreader_readfolder(currentpath); fsreader_readfolder(currentpath);
btn_wait(); btn_wait();
break; break;
case FILE_RESTOREBIS: case -1:
restore_bis_using_file(fsutil_getnextloc(currentpath, file.name), SYSMMC); return -1;
break;
} }
return 0; return 0;

View File

@@ -66,6 +66,7 @@ int foldermenu(){
switch (res){ switch (res){
case DIR_EXITFOLDER: case DIR_EXITFOLDER:
case -1:
return -1; return -1;
case DIR_COPYFOLDER: case DIR_COPYFOLDER:
fsreader_writeclipboard(currentpath, OPERATIONCOPY | ISDIR); fsreader_writeclipboard(currentpath, OPERATIONCOPY | ISDIR);

View File

@@ -23,22 +23,22 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
if (!strcmp(locin, locout)){ if (!strcmp(locin, locout)){
gfx_errDisplay("copy", ERR_SAME_LOC, 1); gfx_errDisplay("copy", ERR_SAME_LOC, 1);
return -1; return 1;
} }
if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){ if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("copy", res, 2); gfx_errDisplay("copy", res, 2);
return -1; return 1;
} }
if (f_stat(locin, &in_info)){ if (f_stat(locin, &in_info)){
gfx_errDisplay("copy", res, 3); gfx_errDisplay("copy", res, 3);
return -1; return 1;
} }
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){ if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
gfx_errDisplay("copy", res, 4); gfx_errDisplay("copy", res, 4);
return -1; return 1;
} }
buff = malloc (BUFSIZE); buff = malloc (BUFSIZE);
@@ -48,17 +48,17 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
while (sizeoffile > 0){ while (sizeoffile > 0){
if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))){ if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))){
gfx_errDisplay("copy", res, 5); gfx_errDisplay("copy", res, 5);
return -1; return 1;
} }
if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))){ if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))){
gfx_errDisplay("copy", res, 6); gfx_errDisplay("copy", res, 6);
return -1; return 1;
} }
if (temp1 != temp2){ if (temp1 != temp2){
gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7); gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7);
return -1; return 1;
} }
sizeoffile -= temp1; 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))){ if ((res = f_chmod(locout, in_info.fattrib, 0x3A))){
gfx_errDisplay("copy", res, 8); gfx_errDisplay("copy", res, 8);
return -1; return 1;
} }
f_stat(locin, &in_info); //somehow stops fatfs from being weird 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))){ if ((res = f_opendir(&dir, localpath))){
gfx_errDisplay("del_recursive", res, 1); gfx_errDisplay("del_recursive", res, 1);
return -1; return 1;
} }
while (!f_readdir(&dir, &fno) && fno.fname[0]){ 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)))){ if ((res = f_unlink(fsutil_getnextloc(localpath, fno.fname)))){
gfx_errDisplay("del_recursive", res, 2); 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))){ if ((res = f_unlink(localpath))){
gfx_errDisplay("del_recursive", res, 3); gfx_errDisplay("del_recursive", res, 3);
return -1; return 1;
} }
free(localpath); free(localpath);
@@ -148,7 +148,7 @@ int fsact_copy_recursive(char *path, char *dstpath){
if ((res = f_opendir(&dir, startpath))){ if ((res = f_opendir(&dir, startpath))){
gfx_errDisplay("copy_recursive", res, 1); gfx_errDisplay("copy_recursive", res, 1);
return -1; return 1;
} }
f_mkdir(destpath); 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))){ if ((res = fsact_copy(temp, fsutil_getnextloc(destpath, fno.fname), COPY_MODE_PRINT))){
gfx_errDisplay("copy_recursive", res, 2); gfx_errDisplay("copy_recursive", res, 2);
return -1; return 1;
} }
free(temp); free(temp);
@@ -177,12 +177,12 @@ int fsact_copy_recursive(char *path, char *dstpath){
if ((res = (f_stat(startpath, &fno)))){ if ((res = (f_stat(startpath, &fno)))){
gfx_errDisplay("copy_recursive", res, 3); gfx_errDisplay("copy_recursive", res, 3);
return -1; return 1;
} }
if ((res = f_chmod(destpath, fno.fattrib, 0x3A))){ if ((res = f_chmod(destpath, fno.fattrib, 0x3A))){
gfx_errDisplay("copy_recursive", res, 4); gfx_errDisplay("copy_recursive", res, 4);
return -1; return 1;
} }
free(startpath); free(startpath);

View File

@@ -12,6 +12,7 @@
#include "../../storage/nx_emmc.h" #include "../../storage/nx_emmc.h"
#include "../common/types.h" #include "../common/types.h"
#include "../utils/utils.h" #include "../utils/utils.h"
#include "fsactions.h"
u32 DecodeInt(u8* data) { u32 DecodeInt(u8* data) {
u32 out = 0; u32 out = 0;
@@ -55,6 +56,7 @@ int extract_bis_file(char *path, char *outfolder){
u8 args; u8 args;
u8 temp[0x4]; u8 temp[0x4];
u32 filesizes[4]; u32 filesizes[4];
char *tempPath;
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){ if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("extract_bis_file", res, 0); 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("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")); 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")); gen_part(filesizes[1], &in, fsutil_getnextloc(outfolder, "BOOT1.bin"));
}
gfx_printf("Extracting BCPKG2_1\n"); if (args & BCPKG2_1_ARG){
if (args & BCPKG2_1_ARG) utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-1-Normal-Main"), &tempPath);
gen_part(filesizes[2], &in, fsutil_getnextloc(outfolder, "BCPKG2-1-Normal-Main")); gfx_printf("Extracting BCPKG2_1/2\n");
gfx_printf("Extracting BCPKG2_3\n"); gen_part(filesizes[2], &in, tempPath);
if (args & BCPKG2_3_ARG) fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-2-Normal-Sub"), COPY_MODE_PRINT);
gen_part(filesizes[3], &in, fsutil_getnextloc(outfolder, "BCPKG2-3-SafeMode-Main")); 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"); gfx_printf("\n\nDone!\n");

View File

@@ -19,6 +19,9 @@ void fileexplorer(const char *startpath, int type){
if (lastentry > 0 && lastentry == type) if (lastentry > 0 && lastentry == type)
clipboardhelper = 0; clipboardhelper = 0;
if (clipboardhelper & OPERATIONMOVE)
clipboardhelper = 0;
lastentry = type; lastentry = type;
fsreader_writecurpath(startpath); fsreader_writecurpath(startpath);
@@ -48,12 +51,15 @@ void fileexplorer(const char *startpath, int type){
copyfolder(clipboard, currentpath); copyfolder(clipboard, currentpath);
else else
copyfile(clipboard, currentpath); copyfile(clipboard, currentpath);
clipboardhelper = 0;
break; break;
case FILEMENU_CURFOLDER: case FILEMENU_CURFOLDER:
if (foldermenu()) if (foldermenu())
return; return;
break; break;
case -1:
return;
default: default:
if(fsreader_files[res].property & ISDIR){ if(fsreader_files[res].property & ISDIR){
@@ -61,7 +67,8 @@ void fileexplorer(const char *startpath, int type){
fsreader_readfolder(currentpath); fsreader_readfolder(currentpath);
} }
else else
filemenu(fsreader_files[res]); if(filemenu(fsreader_files[res]))
return;
break; break;
} }

View File

@@ -29,20 +29,20 @@ void fsreader_writeclipboard(const char *in, u8 args){
utils_copystring(in, &clipboard); utils_copystring(in, &clipboard);
} }
void clearfileobjects(){ void clearfileobjects(menu_entry **menu){
if (fsreader_files != NULL){ if ((*menu) != NULL){
for (int i = 0; fsreader_files[i].name != NULL; i++){ for (int i = 0; (*menu)[i].name != NULL; i++){
free(fsreader_files[i].name); free((*menu)[i].name);
fsreader_files[i].name = NULL; (*menu)[i].name = NULL;
} }
free(fsreader_files); free((*menu));
fsreader_files = NULL; (*menu) = NULL;
} }
} }
void createfileobjects(int size){ void createfileobjects(int size, menu_entry **menu){
fsreader_files = calloc (size + 1, sizeof(menu_entry)); (*menu) = calloc (size + 1, sizeof(menu_entry));
fsreader_files[size].name = NULL; (*menu)[size].name = NULL;
} }
void addobject(char* name, int spot, u8 attribs){ void addobject(char* name, int spot, u8 attribs){
@@ -83,8 +83,8 @@ int fsreader_readfolder(const char *path){
FILINFO fno; FILINFO fno;
int folderamount, res; int folderamount, res;
clearfileobjects(); clearfileobjects(&fsreader_files);
createfileobjects(fsutil_getfolderentryamount(path) + 3); createfileobjects(fsutil_getfolderentryamount(path) + 3, &fsreader_files);
for (folderamount = 0; folderamount < 3; folderamount++){ for (folderamount = 0; folderamount < 3; folderamount++){
utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name)); utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name));

View File

@@ -4,4 +4,7 @@
extern menu_entry *fsreader_files; extern menu_entry *fsreader_files;
void fsreader_writecurpath(const char *in); void fsreader_writecurpath(const char *in);
void fsreader_writeclipboard(const char *in, u8 args); 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);

View File

@@ -9,6 +9,7 @@
#include "../../mem/heap.h" #include "../../mem/heap.h"
#include "../common/common.h" #include "../common/common.h"
int printerrors = true;
void gfx_clearscreen(){ void gfx_clearscreen(){
int battery = 0; int battery = 0;
@@ -24,7 +25,7 @@ void gfx_clearscreen(){
gfx_box(0, 0, 719, 15, COLOR_WHITE); gfx_box(0, 0, 719, 15, COLOR_WHITE);
gfx_con_setpos(0, 0); gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer v1.4.0\n"); gfx_printf("Tegraexplorer v1.5.2\n");
RESETCOLOR; RESETCOLOR;
} }
@@ -43,6 +44,9 @@ int gfx_message(u32 color, const char* message, ...){
} }
int gfx_errDisplay(char *src_func, int err, int loc){ int gfx_errDisplay(char *src_func, int err, int loc){
if (!printerrors)
return 0;
gfx_clearscreen(); gfx_clearscreen();
SWAPCOLOR(COLOR_ORANGE); SWAPCOLOR(COLOR_ORANGE);
gfx_printf("\nAn error occured:\n\n"); gfx_printf("\nAn error occured:\n\n");
@@ -50,7 +54,7 @@ int gfx_errDisplay(char *src_func, int err, int loc){
if (err < 15) if (err < 15)
gfx_printf("Desc: %s\n", utils_err_codes[err]); 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]); gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
if (loc) if (loc)
@@ -59,6 +63,9 @@ int gfx_errDisplay(char *src_func, int err, int loc){
gfx_printf("\nPress any button to return"); gfx_printf("\nPress any button to return");
RESETCOLOR; RESETCOLOR;
while (btn_read() != 0);
return btn_wait(); return btn_wait();
} }
@@ -108,8 +115,13 @@ void gfx_printandclear(char *in, int length){
gfx_con_getpos(&x, &y); gfx_con_getpos(&x, &y);
RESETCOLOR; RESETCOLOR;
/*
for (int i = (703 - x) / 16; i > 0; i--) for (int i = (703 - x) / 16; i > 0; i--)
gfx_printf(" "); gfx_printf(" ");
*/
gfx_boxGrey(x, y, 703, y + 16, 0x1B);
gfx_con_setpos(x, y); gfx_con_setpos(x, y);

View File

@@ -12,4 +12,6 @@ int gfx_errDisplay(char *src_func, int err, int loc);
int gfx_makewaitmenu(char *hiddenmessage, int timer); int gfx_makewaitmenu(char *hiddenmessage, int timer);
void gfx_printlength(int size, char *toprint); void gfx_printlength(int size, char *toprint);
void gfx_printandclear(char *in, int length); void gfx_printandclear(char *in, int length);
void gfx_printfilesize(int size, char *type); void gfx_printfilesize(int size, char *type);
extern int printerrors;

View File

@@ -5,6 +5,10 @@
#include "../common/common.h" #include "../common/common.h"
#include "../../utils/util.h" #include "../../utils/util.h"
#include "../../mem/minerva.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){ void _printentry(menu_entry entry, bool highlighted, bool refresh){
int size; int size;
@@ -49,22 +53,33 @@ void _printentry(menu_entry entry, bool highlighted, bool refresh){
else { else {
SWAPCOLOR(COLOR_BLUE); SWAPCOLOR(COLOR_BLUE);
SWAPBGCOLOR(COLOR_DEFAULT); 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 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; u32 scrolltimer, timer;
bool refresh = false; bool refresh = false;
gfx_clearscreen(); gfx_clearscreen();
for (int i = 0; i < amount; i++)
if (!(entries[i].property & ISMENU))
calculatedamount++;
gfx_con_setpos(512, 0); gfx_con_setpos(512, 0);
SWAPCOLOR(COLOR_DEFAULT); if (calculatedamount){
SWAPBGCOLOR(COLOR_WHITE); SWAPCOLOR(COLOR_DEFAULT);
gfx_printf("%3d entries\n", amount); SWAPBGCOLOR(COLOR_WHITE);
RESETCOLOR; gfx_printf("%3d entries\n", calculatedamount);
RESETCOLOR;
}
else
gfx_printf("\n");
SWAPCOLOR(COLOR_GREEN); SWAPCOLOR(COLOR_GREEN);
gfx_printlength(42, toptext); gfx_printlength(42, toptext);
@@ -108,6 +123,12 @@ int menu_make(menu_entry *entries, int amount, char *toptext){
res = 0; res = 0;
while (!res){ 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(); res = btn_read();
if (!res) if (!res)

View File

@@ -6,7 +6,7 @@
#include "../utils/btn.h" #include "../utils/btn.h"
#include "emmc/emmc.h" #include "emmc/emmc.h"
#include "../storage/emummc.h" #include "../storage/emummc.h"
#include "utils/script.h" #include "script/functions.h"
#include "common/common.h" #include "common/common.h"
#include "gfx/menu.h" #include "gfx/menu.h"
@@ -16,11 +16,13 @@
#include "fs/fsutils.h" #include "fs/fsutils.h"
#include "fs/fsmenu.h" #include "fs/fsmenu.h"
#include "emmc/emmcoperations.h" #include "emmc/emmcoperations.h"
#include "emmc/emmcmenu.h"
extern bool sd_mount(); extern bool sd_mount();
extern void sd_unmount(); extern void sd_unmount();
extern bool return_sd_mounted(int value);
extern int launch_payload(char *path); extern int launch_payload(char *path);
extern bool sd_inited;
extern bool sd_mounted;
int res = 0, meter = 0; int res = 0, meter = 0;
@@ -32,30 +34,33 @@ void MainMenu_EMMC(){
gfx_clearscreen(); 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"); 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)){ if (gfx_makewaitmenu("Press Power to enter", 4)){
/*
connect_mmc(SYSMMC); connect_mmc(SYSMMC);
if (!mount_mmc(emmc_fs_entries[res - 2], res - 1)) if (!mount_mmc(emmc_fs_entries[res - 2], res - 1))
fileexplorer("emmc:/", 1); fileexplorer("emmc:/", 1);
*/
makeMmcMenu(SYSMMC);
} }
} }
void MainMenu_EMUMMC(){ void MainMenu_EMUMMC(){
/*
connect_mmc(EMUMMC); connect_mmc(EMUMMC);
if (!mount_mmc(emmc_fs_entries[res - 5], res - 4)) if (!mount_mmc(emmc_fs_entries[res - 5], res - 4))
fileexplorer("emmc:/", 1); fileexplorer("emmc:/", 1);
*/
makeMmcMenu(EMUMMC);
} }
void MainMenu_MountSD(){ void MainMenu_MountSD(){
if (return_sd_mounted(1)) (sd_mounted) ? sd_unmount() : sd_mount();
sd_unmount();
else
sd_mount();
} }
void MainMenu_Tools(){ void MainMenu_Tools(){
//res = makemenu(toolsmenu, 8); //res = makemenu(toolsmenu, 8);
res = menu_make(mainmenu_tools, 6, "-- Tools Menu --"); res = menu_make(mainmenu_tools, 5, "-- Tools Menu --");
switch(res){ switch(res){
case TOOLS_DISPLAY_INFO: case TOOLS_DISPLAY_INFO:
@@ -63,6 +68,7 @@ void MainMenu_Tools(){
break; break;
case TOOLS_DISPLAY_GPIO: case TOOLS_DISPLAY_GPIO:
displaygpio(); displaygpio();
//makeMmcMenu(SYSMMC);
break; break;
case TOOLS_DUMPFIRMWARE: case TOOLS_DUMPFIRMWARE:
dumpfirmware(SYSMMC); dumpfirmware(SYSMMC);
@@ -72,9 +78,6 @@ void MainMenu_Tools(){
dumpusersaves(res); dumpusersaves(res);
break; break;
case TOOLS_DUMP_BOOT:
dump_emmc_parts(PART_BOOT | PART_PKG2, SYSMMC);
break;
} }
} }
@@ -100,7 +103,7 @@ void MainMenu_Credits(){
} }
void MainMenu_Exit(){ 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[4].property, ISHIDE, !fsutil_checkfile("/bootloader/update.bin"));
SETBIT(mainmenu_shutdown[5].property, ISHIDE, !fsutil_checkfile("/atmosphere/reboot_payload.bin")); SETBIT(mainmenu_shutdown[5].property, ISHIDE, !fsutil_checkfile("/atmosphere/reboot_payload.bin"));
} }
@@ -129,13 +132,9 @@ void MainMenu_Exit(){
} //todo declock bpmp } //todo declock bpmp
} }
part_handler mainmenu_functions[] = { func_void_ptr mainmenu_functions[] = {
MainMenu_SDCard, MainMenu_SDCard,
MainMenu_EMMC, MainMenu_EMMC,
MainMenu_EMMC,
MainMenu_EMMC,
MainMenu_EMUMMC,
MainMenu_EMUMMC,
MainMenu_EMUMMC, MainMenu_EMUMMC,
MainMenu_MountSD, MainMenu_MountSD,
MainMenu_Tools, MainMenu_Tools,
@@ -145,7 +144,7 @@ part_handler mainmenu_functions[] = {
}; };
void RunMenuOption(int option){ void RunMenuOption(int option){
if (option != 11) if (option != 7)
meter = 0; meter = 0;
if (option > 0) if (option > 0)
mainmenu_functions[option - 1](); mainmenu_functions[option - 1]();
@@ -155,34 +154,33 @@ void te_main(){
if (dump_biskeys() == -1){ if (dump_biskeys() == -1){
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0); gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
for (int i = 1; i <= 3; i++) //mainmenu_main[1].property |= ISHIDE;
mainmenu_main[i].property |= ISHIDE;
} }
if (emummc_load_cfg()){ if (emummc_load_cfg()){
for (int i = 4; i <= 6; i++) mainmenu_main[2].property |= ISHIDE;
mainmenu_main[i].property |= ISHIDE;
} }
dumpGpt();
disconnect_mmc(); disconnect_mmc();
while (1){ while (1){
//fillmainmenu(); //fillmainmenu();
setter = return_sd_mounted(1); setter = sd_mounted;
if (emu_cfg.enabled){ if (emu_cfg.enabled){
for (int i = 4; i <= 6; i++) SETBIT(mainmenu_main[2].property, ISHIDE, !setter);
SETBIT(mainmenu_main[i].property, ISHIDE, !setter);
} }
SETBIT(mainmenu_main[0].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); setter = sd_inited;
SETBIT(mainmenu_main[9].property, ISHIDE, !setter); 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); RunMenuOption(res);
} }
} }

View 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;
}

View 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);

View 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, &currentchar, 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();
}

View File

@@ -0,0 +1,5 @@
#pragma once
void runScript(char *path);
void skipbrackets();
void getfollowingchar(char end);

View 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;
}

View 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();

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -1,3 +1,4 @@
#include <string.h>
#include "tools.h" #include "tools.h"
#include "../gfx/gfxutils.h" #include "../gfx/gfxutils.h"
#include "../../libs/fatfs/ff.h" #include "../../libs/fatfs/ff.h"
@@ -13,6 +14,9 @@
#include "../emmc/emmc.h" #include "../emmc/emmc.h"
#include "../common/common.h" #include "../common/common.h"
#include "../fs/fsactions.h" #include "../fs/fsactions.h"
#include "../fs/fsutils.h"
#include "../../mem/heap.h"
#include "../utils/utils.h"
extern bool sd_mount(); extern bool sd_mount();
extern void sd_unmount(); extern void sd_unmount();
@@ -35,7 +39,12 @@ void displayinfo(){
SWAPCOLOR(COLOR_ORANGE); 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(); print_biskeys();
RESETCOLOR; RESETCOLOR;
@@ -91,10 +100,8 @@ int dumpfirmware(int mmc){
FILINFO fno; FILINFO fno;
bool fail = false; bool fail = false;
int ret, amount = 0; int ret, amount = 0;
char path[100] = "emmc:/Contents/registered"; char sysbase[] = "emmc:/Contents/registered";
char sdfolderpath[100] = ""; char *syspathtemp, *syspath, *sdpath, *sdbase;
char syspath[100] = "";
char sdpath[100] = "";
pkg1_info pkg1 = returnpkg1info(); pkg1_info pkg1 = returnpkg1info();
u32 timer = get_tmr_s(); u32 timer = get_tmr_s();
@@ -104,26 +111,33 @@ int dumpfirmware(int mmc){
gfx_printf("PKG1 version: %d\n", pkg1.ver); gfx_printf("PKG1 version: %d\n", pkg1.ver);
ret = f_mkdir("sd:/tegraexplorer"); gfx_printf("Creating folders...\n");
gfx_printf("Creating sd:/tegraexplorer %d\n", ret); f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/Firmware");
ret = f_mkdir("sd:/tegraexplorer/Firmware"); sdbase = calloc(32 + strlen(pkg1.id), sizeof(char));
gfx_printf("Creating sd:/tegraexplorer/Firmware %d\n", ret); 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); if ((ret = f_opendir(&dir, sysbase)))
ret = f_mkdir(sdfolderpath); fail = true;
gfx_printf("Creating %s %d\n", sdfolderpath, ret);
ret = f_opendir(&dir, path); gfx_printf("Starting dump...\n");
gfx_printf("Result opening system:/ %d\n\n%k", ret, COLOR_GREEN); SWAPCOLOR(COLOR_GREEN);
printerrors = 0;
while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){ while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){
sprintf(sdpath, "%s/%s", sdfolderpath, fno.fname); utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
utils_copystring(fsutil_getnextloc(sysbase, fno.fname), &syspathtemp);
if (fno.fattrib & AM_DIR)
sprintf(syspath, "%s/%s/00", path, fno.fname); if (fno.fattrib & AM_DIR){
utils_copystring(fsutil_getnextloc(syspathtemp, "00"), &syspath);
free(syspathtemp);
}
else else
sprintf(syspath, "%s/%s", path, fno.fname); syspath = syspathtemp;
ret = fsact_copy(syspath, sdpath, 0); ret = fsact_copy(syspath, sdpath, 0);
@@ -131,42 +145,40 @@ int dumpfirmware(int mmc){
if (ret != 0) if (ret != 0)
fail = true; fail = true;
free(sdpath);
free(syspath);
} }
printerrors = 1;
if (fail) if (fail)
gfx_printf("%k\n\nDump failed! Aborting (%d)", COLOR_RED, ret); 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); gfx_printf("%k\n\nPress any button to continue...\nTime taken: %ds", COLOR_WHITE, get_tmr_s() - timer);
free(sdbase);
btn_wait(); btn_wait();
return fail; return fail;
} }
void dumpusersaves(int mmc){ void dumpusersaves(int mmc){
int res;
connect_mmc(mmc); connect_mmc(mmc);
mount_mmc("USER", 2); mount_mmc("USER", 2);
gfx_clearscreen(); gfx_clearscreen();
res = f_mkdir("sd:/tegraexplorer"); gfx_printf("Creating folders...\n");
gfx_printf("Creating sd:/tegraexplorer, res: %d\nCopying:\n", res); f_mkdir("sd:/tegraexplorer");
gfx_printf("Starting dump...\n");
SWAPCOLOR(COLOR_GREEN); SWAPCOLOR(COLOR_GREEN);
res = fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer"); if(fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer"))
return;
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");
RESETCOLOR;
gfx_printf("\n\nSaves are located in SD:/tegraexplorer/save\n");
gfx_printf("Press any key to continue"); gfx_printf("Press any key to continue");
btn_wait(); btn_wait();
} }

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2019 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -25,11 +26,12 @@
#define _PAGEOFF(x) ((x) & 0xFFFFF000) #define _PAGEOFF(x) ((x) & 0xFFFFF000)
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((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 _BL(a, o) (0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
#define _B(a, o) 0x14000000 | ((((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 _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 _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 #define _NOP() 0xD503201F
#endif #endif

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2020 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -33,9 +34,10 @@
#define LIST_FOREACH_SAFE(iter, list) \ #define LIST_FOREACH_SAFE(iter, list) \
for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next) 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) \ #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 typedef struct _link_t
{ {

View File

@@ -33,15 +33,22 @@ typedef struct _cfg_op_t
u32 val; u32 val;
} cfg_op_t; } cfg_op_t;
typedef struct _nyx_info_t
{
u32 rsvd;
u32 errors;
} nyx_info_t;
typedef struct _nyx_storage_t typedef struct _nyx_storage_t
{ {
u32 version; u32 version;
u32 cfg; u32 cfg;
u8 irama[0x8000]; u8 irama[0x8000];
u8 hekate[0x30000]; u8 hekate[0x30000];
u8 rsvd[0x800000]; u8 rsvd[0x800000 - sizeof(nyx_info_t)];
nyx_info_t info;
mtc_config_t mtc_cfg; mtc_config_t mtc_cfg;
emc_table_t mtc_table; emc_table_t mtc_table[10];
} nyx_storage_t; } nyx_storage_t;
u32 get_tmr_us(); u32 get_tmr_us();