Compare commits

..

84 Commits
1.1.1 ... 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
Such Meme, Many Skill
d255dcf665 Cleanup 2020-03-19 23:01:30 +01:00
Such Meme, Many Skill
f1a4b05524 Bump version 2020-03-19 16:19:56 +01:00
Such Meme, Many Skill
d5c23ebf96 Reorder BIS menu options 2020-03-19 16:17:36 +01:00
Such Meme, Many Skill
4e1368faaf Re-implement bis restoring 2020-03-19 16:11:18 +01:00
Such Meme, Many Skill
2d6411f60a Add more general error codes & re-implement bis dumping 2020-03-19 13:00:42 +01:00
Such Meme, Many Skill
7191743f5d Reorganise emmc.c/h and rename main menu c file 2020-03-19 00:11:18 +01:00
Such Meme, Many Skill
9d36f741d9 Day2 of restructuring/rewriting 2020-03-18 23:58:32 +01:00
Such Meme, Many Skill
ff618bc285 Move over script and tools 2020-03-18 12:18:39 +01:00
Such Meme, Many Skill
c60eb4b722 Fix compile error, oops 2020-03-18 00:58:23 +01:00
Such Meme, Many Skill
6aed4ad7b3 Start gfx rewrite & reorganize TE 2020-03-18 00:41:09 +01:00
Such Meme, Many Skill
761ceb7dbe Misc changes 2020-03-17 00:26:35 +01:00
Such Meme, Many Skill
3f6d1b532c (Attempt at) Implement restoring bis
1 switch was harmed in the making of this commit
2020-03-15 12:35:18 +01:00
Such Meme, Many Skill
144dc3a3f5 Implement bis dumping 2020-03-14 15:03:08 +01:00
Such Meme, Many Skill
5cb50722cf [Scripting] Add CheckPath command 2020-03-11 21:01:57 +01:00
Such Meme, Many Skill
7c7dd7178f Bump version 2020-03-06 12:26:54 +01:00
Such Meme, Many Skill
d93b50205a Add battery indicator 2020-03-03 15:19:42 +01:00
Such Meme, Many Skill
405cb46b77 (Potentially) Fix file based emummc's not mounting 2020-02-22 19:49:25 +01:00
Such Meme, Many Skill
7f7c2e65ee Fix freeing errors in copy-recursive 2020-02-22 19:05:50 +01:00
Such Meme, Many Skill
c2df3d80dd Clean up main menu 2020-02-11 17:18:29 +01:00
Such Meme, Many Skill
a3b876ea3e [Scripting] Add <VERSION>, <WAIT>, <COLOR> + cleanup + version bump 2020-02-10 14:16:17 +01:00
Such Meme, Many Skill
4309194a11 Bump version to 1.3.0 2020-02-07 23:07:12 +01:00
Such Meme, Many Skill
ae57cb1e63 Add MOVE command + add jank fatfs fix 2020-02-07 17:43:20 +01:00
Such Meme, Many Skill
a86294218c Don't disable the emummc 2020-02-07 14:45:35 +01:00
Such Meme, Many Skill
eecefd634c Add $EMUMMC$ flag, add DEL and DEL-R commands to scripting 2020-02-07 12:19:46 +01:00
Such Meme, Many Skill
37ce49a31f Add $BTN$ flags to scripts 2020-02-07 00:55:55 +01:00
Such Meme, Many Skill
ab061cf0b3 Probably a good idea to not forget the forceExit 2020-02-06 23:50:06 +01:00
Such Meme, Many Skill
1a2fd158e9 Add scripting to TE 2020-02-06 23:31:19 +01:00
Such Meme, Many Skill
eb8652c6ec Bug fixing round & add some emummc menus
Notable bugs fixed:
- pkg1id is now also used as foldername during fw dump
- Clearing of screen in _recursive functions is no longer hardcoded
- Folders get the correct file attributes
- first 16 MiB of partition during partitioning gets cleared now
2020-01-30 23:53:27 +01:00
Such Meme, Many Skill
9885308bce Add emummc support 2020-01-27 23:51:59 +01:00
Such Meme, Many Skill
1410fa185f Fix partitioning mistake, bump version to 1.2.1 2020-01-08 14:21:53 +01:00
Such Meme, Many Skill
6724f364b5 Implement Tool for dumping User:/save
+ Finalize readme for release of 1.2.0
2020-01-07 21:53:02 +01:00
Such Meme, Many Skill
008d3ab494 Add file attributes to menus
+ fix a few misc things
+ bump version (readme isn't updated yet)
2020-01-07 15:28:23 +01:00
Such Meme, Many Skill
00bd1cd083 Split fs.c file
+ Misc changes to code in io.c
2020-01-06 18:42:57 +01:00
Such Meme, Many Skill
6af2bb63b8 Stop using an int to indicate dir size 2020-01-06 17:40:05 +01:00
Such Meme, Many Skill
02504c8a36 Make emmc writable + merge hekate fixes 2020-01-06 14:24:29 +01:00
Such Meme, Many Skill
ef76834ef4 Implement folder copy
+ Change error messaging internally
+ inproved recursive file deletion
2020-01-04 20:18:26 +01:00
Such Meme, Many Skill
6d75aa688c (Attempt at) dynamic folder memory allocation 2020-01-04 13:20:28 +01:00
Such Meme, Many Skill
225a17116c Fix memory leakage of getnextloc() and getprevloc() 2020-01-04 01:00:11 +01:00
Such Meme, Many Skill
e1f4c24686 Implement folder options (Delete folder) 2020-01-02 00:38:36 +01:00
suchmememanyskill
3e8cd67129 Add ko-fi link 2019-12-27 00:47:14 +01:00
78 changed files with 4246 additions and 1206 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: suchmememanyskill
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

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 := 1 LPVERSION_MINOR := 5
LPVERSION_BUGFX := 0 LPVERSION_BUGFX := 2
################################################################################ ################################################################################

View File

@@ -9,11 +9,13 @@ Navigate around the menu's using the vol+, vol- and power buttons
## Functions ## Functions
- Navigate the SD card - Navigate the SD card
- Navigate the System partition of your sysnand - Navigate the System partition of your sysnand/sysmmc
- Interact with files - Interact with files
- Deleting, copying or moving files - Deleting, copying or moving files
- Launching payloads files - Launching payloads files
- Viewing the hex data of a file - Viewing the hex data of a file
- Interacting with folders
- Deleting or copying folders
- Dumping your current firmware to sd - Dumping your current firmware to sd
- Formatting the sd card - Formatting the sd card
@@ -24,7 +26,7 @@ For general CFW support, go to the [Nintendo Homebrew](https://discord.gg/C29hYv
For question specifically for TegraExplorer, go to [my discord](https://discord.gg/aH9rsuP) For question specifically for TegraExplorer, go to [my discord](https://discord.gg/aH9rsuP)
# Credits # Credits
Based on [Lockpick_RCM](https://github.com/shchmue/Lockpick_RCM), and thus based on [Hekate](https://github.com/CTCaer/hekate) Based on [Lockpick_RCM](https://github.com/shchmue/Lockpick_RCM), and thus also based on [Hekate](https://github.com/CTCaer/hekate)
Lots of help from: Lots of help from:
- shchmue - shchmue

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

@@ -188,7 +188,7 @@ void gfx_putc(char c)
for (u32 i = 0; i < 16; i+=2) for (u32 i = 0; i < 16; i+=2)
{ {
u8 v = *cbuf++; u8 v = *cbuf;
for (u32 k = 0; k < 2; k++) for (u32 k = 0; k < 2; k++)
{ {
for (u32 j = 0; j < 8; j++) for (u32 j = 0; j < 8; j++)
@@ -213,6 +213,7 @@ void gfx_putc(char c)
fb += gfx_ctxt.stride - 16; fb += gfx_ctxt.stride - 16;
v = *cbuf; v = *cbuf;
} }
cbuf++;
} }
gfx_con.x += 16; gfx_con.x += 16;
if (gfx_con.x >= gfx_ctxt.width - 16) { if (gfx_con.x >= gfx_ctxt.width - 16) {
@@ -268,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;
} }
@@ -329,15 +336,10 @@ void gfx_put_big_sep()
gfx_con.fntsz = prevFontSize; gfx_con.fntsz = prevFontSize;
} }
void gfx_printf(const char *fmt, ...) void gfx_vprintf(const char *fmt, va_list ap)
{ {
if (gfx_con.mute)
return;
va_list ap;
int fill, fcnt; int fill, fcnt;
va_start(ap, fmt);
while(*fmt) while(*fmt)
{ {
if(*fmt == '%') if(*fmt == '%')
@@ -389,7 +391,7 @@ void gfx_printf(const char *fmt, ...)
gfx_putc('%'); gfx_putc('%');
break; break;
case '\0': case '\0':
goto out; return;
default: default:
gfx_putc('%'); gfx_putc('%');
gfx_putc(*fmt); gfx_putc(*fmt);
@@ -400,8 +402,17 @@ void gfx_printf(const char *fmt, ...)
gfx_putc(*fmt); gfx_putc(*fmt);
fmt++; fmt++;
} }
}
void gfx_printf(const char *fmt, ...)
{
if (gfx_con.mute)
return;
va_list ap;
va_start(ap, fmt);
gfx_vprintf(fmt, ap);
out:
va_end(ap); va_end(ap);
} }
@@ -508,11 +519,17 @@ 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){
int i = y0; for (int x = x0; x < x1 + 1; x++){
while(y1 >= i){ for (int y = y0; y < y1 + 1; y++){
gfx_line(x0, i, x1, i, color); gfx_set_pixel(x, y, color);
i++; }
} }
} }

View File

@@ -20,6 +20,7 @@
#define _GFX_H_ #define _GFX_H_
#include "../../common/common_gfx.h" #include "../../common/common_gfx.h"
#include <stdarg.h>
#define EPRINTF(text) gfx_printf("%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC) #define EPRINTF(text) gfx_printf("%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
#define EPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC) #define EPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
@@ -37,6 +38,7 @@ void gfx_con_setpos(u32 x, u32 y);
void gfx_putc(char c); void gfx_putc(char c);
void gfx_puts(const char *s); void gfx_puts(const char *s);
void gfx_printf(const char *fmt, ...); void gfx_printf(const char *fmt, ...);
void gfx_vprintf(const char *fmt, va_list ap);
void gfx_hexdump(u32 base, const u8 *buf, u32 len); void gfx_hexdump(u32 base, const u8 *buf, u32 len);
void gfx_set_pixel(u32 x, u32 y, u32 color); void gfx_set_pixel(u32 x, u32 y, u32 color);
@@ -48,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

@@ -32,6 +32,7 @@
#include "../../sec/se.h" #include "../../sec/se.h"
#include "../../storage/nx_emmc.h" #include "../../storage/nx_emmc.h"
#include "../../storage/sdmmc.h" #include "../../storage/sdmmc.h"
#include "../../storage/emummc.h"
extern sdmmc_storage_t sd_storage; extern sdmmc_storage_t sd_storage;
extern sdmmc_storage_t storage; extern sdmmc_storage_t storage;
@@ -150,7 +151,7 @@ DRESULT disk_read (
__attribute__ ((aligned (16))) static u8 tweak[0x10]; __attribute__ ((aligned (16))) static u8 tweak[0x10];
__attribute__ ((aligned (16))) static u64 prev_cluster = -1; __attribute__ ((aligned (16))) static u64 prev_cluster = -1;
__attribute__ ((aligned (16))) static u32 prev_sector = 0; __attribute__ ((aligned (16))) static u32 prev_sector = 0;
bool needs_cache_sector = false; //bool needs_cache_sector = false;
/* /*
if (secindex == 0 || clear_sector_cache) { if (secindex == 0 || clear_sector_cache) {
if (!sector_cache) if (!sector_cache)
@@ -212,20 +213,46 @@ DRESULT disk_read (
DRESULT disk_write ( DRESULT disk_write (
BYTE pdrv, /* Physical drive number to identify the drive */ BYTE pdrv, /* Physical drive number to identify the drive */
const BYTE *buff, /* Data to be written */ BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */ DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */ UINT count /* Number of sectors to write */
) )
{ {
if (pdrv == 1) switch (pdrv){
return RES_WRPRT; case 0:
if (((u32)buff >= DRAM_START) && !((u32)buff % 8))
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere.
memcpy(buf, buff, 512 * count);
if (sdmmc_storage_write(&sd_storage, sector, count, buf))
return RES_OK;
return RES_ERROR;
case 1:;
__attribute__ ((aligned (16))) static u8 tweak[0x10];
__attribute__ ((aligned (16))) static u64 prev_cluster = -1;
__attribute__ ((aligned (16))) static u32 prev_sector = 0;
u32 tweak_exp = 0;
bool regen_tweak = true;
if (((u32)buff >= DRAM_START) && !((u32)buff % 8)) if (prev_cluster != sector / 0x20) { // sector in different cluster than last read
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR; prev_cluster = sector / 0x20;
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere. tweak_exp = sector % 0x20;
memcpy(buf, buff, 512 * count); } else if (sector > prev_sector) { // sector in same cluster and past last sector
if (sdmmc_storage_write(&sd_storage, sector, count, buf)) tweak_exp = sector - prev_sector - 1;
return RES_OK; regen_tweak = false;
} else { // sector in same cluster and before or same as last sector
tweak_exp = sector % 0x20;
}
if (_emmc_xts(9, 8, 1, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200)){
if (nx_emmc_part_write(&storage, system_part, sector, count, buff)){
prev_sector = sector + count - 1;
return RES_OK;
}
}
return RES_ERROR;
}
return RES_ERROR; return RES_ERROR;
} }

View File

@@ -31,7 +31,7 @@ typedef enum {
DSTATUS disk_initialize (BYTE pdrv); DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv); DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); DRESULT disk_write (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);

View File

@@ -39,6 +39,8 @@
#include "ff.h" /* Declarations of FatFs API */ #include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of device I/O functions */ #include "diskio.h" /* Declarations of device I/O functions */
#include "../../gfx/gfx.h" #include "../../gfx/gfx.h"
#include "../../storage/sdmmc.h"
extern sdmmc_storage_t sd_storage;
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF); #define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
//#define EFSPRINTF(...) //#define EFSPRINTF(...)
@@ -6108,14 +6110,16 @@ FRESULT f_fdisk (
UINT i, n, sz_cyl, tot_cyl, e_cyl; UINT i, n, sz_cyl, tot_cyl, e_cyl;
BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
DSTATUS stat; DSTATUS stat;
DWORD sz_disk, sz_part, s_part, p_cyl, b_cyl; DWORD sz_disk, p_sect, b_cyl, b_sect;
FRESULT res; FRESULT res;
BYTE *empty_buff;
empty_buff = ff_memcalloc(sizeof(BYTE), 16384);
stat = disk_initialize(pdrv); stat = disk_initialize(pdrv);
if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_NOINIT) return FR_NOT_READY;
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; sz_disk = sd_storage.csd.capacity;
buf = (BYTE*)work; buf = (BYTE*)work;
#if FF_USE_LFN == 3 #if FF_USE_LFN == 3
@@ -6132,20 +6136,25 @@ FRESULT f_fdisk (
/* Create partition table */ /* Create partition table */
mem_set(buf, 0, FF_MAX_SS); mem_set(buf, 0, FF_MAX_SS);
p = buf + MBR_Table; b_cyl = 0; p = buf + MBR_Table; b_cyl = 0, b_sect = 0;
for (i = 0; i < 4; i++, p += SZ_PTE) { for (i = 0; i < 4; i++, p += SZ_PTE) {
p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * (szt[i] / 100) : szt[i]; // sz_cyl; /* Number of cylinders */ p_sect = szt[i]; /* Number of sectors */
if (p_cyl == 0) continue;
s_part = /*(DWORD)sz_cyl * */ b_cyl; if (p_sect == 0)
sz_part = /* (DWORD)sz_cyl * */ p_cyl; continue;
if (i == 0) { /* Exclude first track of cylinder 0 */
if (i == 0) { /* Exclude first 16MiB of sd */
s_hd = 1; s_hd = 1;
s_part += 32768; sz_part -= 32768; b_sect += 32768; p_sect -= 32768;
} else { }
else
s_hd = 0; s_hd = 0;
}
e_cyl = (b_cyl + p_cyl - 1) / sz_cyl; /* End cylinder */ b_cyl = b_sect / sz_cyl;
if (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER); e_cyl = ((b_sect + p_sect) / sz_cyl) - 1; /* End cylinder */
if (e_cyl >= tot_cyl)
LEAVE_MKFS(FR_INVALID_PARAMETER);
/* Set partition table */ /* Set partition table */
@@ -6156,12 +6165,17 @@ FRESULT f_fdisk (
p[5] = e_hd; /* End head */ p[5] = e_hd; /* End head */
p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */ p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */
p[7] = (BYTE)e_cyl; /* End cylinder */ p[7] = (BYTE)e_cyl; /* End cylinder */
st_dword(p + 8, s_part); /* Start sector in LBA */ st_dword(p + 8, b_sect); /* Start sector in LBA */
st_dword(p + 12, sz_part); /* Number of sectors */ st_dword(p + 12, p_sect); /* Number of sectors */
/* Next partition */ /* Next partition */
b_cyl += p_cyl; b_sect += p_sect;
for (int cursect = 0; cursect < 1024; cursect++){
disk_write(pdrv, empty_buff, b_sect + (32 * cursect), 32);
}
} }
st_word(p, 0xAA55); /* MBR signature (always at offset 510) */ st_word(p, 0xAA55); /* MBR signature (always at offset 510) */
ff_memfree(empty_buff);
/* Write it to the MBR */ /* Write it to the MBR */
res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;

View File

@@ -321,6 +321,7 @@ DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
#endif #endif
#if FF_USE_LFN == 3 /* Dynamic memory allocation */ #if FF_USE_LFN == 3 /* Dynamic memory allocation */
void* ff_memalloc (UINT msize); /* Allocate memory block */ void* ff_memalloc (UINT msize); /* Allocate memory block */
void* ff_memcalloc (UINT msize, UINT amount);
void ff_memfree (void* mblock); /* Free memory block */ void ff_memfree (void* mblock); /* Free memory block */
#endif #endif

View File

@@ -23,6 +23,10 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if no
return malloc(msize); /* Allocate a new memory block with POSIX API */ return malloc(msize); /* Allocate a new memory block with POSIX API */
} }
void* ff_memcalloc (UINT msize, UINT amount){
return calloc(amount, msize);
}
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Free a memory block */ /* Free a memory block */

View File

@@ -38,27 +38,18 @@
#include "utils/dirlist.h" #include "utils/dirlist.h"
#include "utils/sprintf.h" #include "utils/sprintf.h"
#include "utils/util.h" #include "utils/util.h"
#include "tegraexplorer/te.h" #include "tegraexplorer/mainmenu.h"
//#include "keys/keys.h" //#include "keys/keys.h"
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 1:
return sd_mounted;
case 7:
return sd_inited;
}
}
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

@@ -32,19 +32,23 @@ u32 minerva_init()
{ {
u32 curr_ram_idx = 0; u32 curr_ram_idx = 0;
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

@@ -139,7 +139,6 @@ out:
int emummc_storage_end(sdmmc_storage_t *storage) int emummc_storage_end(sdmmc_storage_t *storage)
{ {
sd_unmount();
sdmmc_storage_end(storage); sdmmc_storage_end(storage);
return 1; return 1;

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;
@@ -74,5 +74,5 @@ int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_o
// The last LBA is inclusive. // The last LBA is inclusive.
if (part->lba_start + sector_off > part->lba_end) if (part->lba_start + sector_off > part->lba_end)
return 0; return 0;
return sdmmc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf); return emummc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf);
} }

View File

@@ -0,0 +1,113 @@
#pragma once
#include "types.h"
extern const char *gfx_file_size_names[];
extern const char *menu_sd_states[];
extern const char *emmc_fs_entries[];
extern const char *utils_err_codes[];
//extern const char *pkg2names[];
extern const char *mainmenu_credits;
enum utils_err_codes_te_call {
ERR_SAME_LOC = 50,
ERR_DISK_WRITE_FAILED,
ERR_EMPTY_CLIPBOARD,
ERR_FOLDER_ROOT = 54,
ERR_DEST_PART_OF_SRC,
ERR_PART_NOT_FOUND,
ERR_BISKEY_DUMP_FAILED,
ERR_MEM_ALLOC_FAILED,
ERR_EMMC_READ_FAILED,
ERR_EMMC_WRITE_FAILED,
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[];
enum mainmenu_main_return {
MAIN_SDCARD = 0,
MAIN_EMMC_SAF,
MAIN_EMMC_SYS,
MAIN_EMMC_USR,
MAIN_EMUMMC_SAF,
MAIN_EMUMMC_SYS,
MAIN_EMUMMC_USR,
MAIN_MOUNT_SD,
MAIN_TOOLS,
MAIN_SD_FORMAT,
MAIN_CREDITS,
MAIN_EXIT
};
extern menu_entry mainmenu_main[];
enum mainmenu_shutdown_return {
SHUTDOWN_REBOOT_RCM = 1,
SHUTDOWN_REBOOT_NORMAL,
SHUTDOWN_POWER_OFF,
SHUTDOWN_HEKATE,
SHUTDOWN_AMS
};
extern menu_entry mainmenu_shutdown[];
enum mainmenu_tools_return {
TOOLS_DISPLAY_INFO = 1,
TOOLS_DISPLAY_GPIO,
TOOLS_DUMPFIRMWARE,
TOOLS_DUMPUSERSAVE
};
extern menu_entry mainmenu_tools[];
enum mainmenu_format_return {
FORMAT_ALL_FAT32 = 1,
FORMAT_EMUMMC
};
extern menu_entry mainmenu_format[];
enum mmc_types {
SYSMMC = 1,
EMUMMC
};
extern menu_entry utils_mmcChoice[];
enum fs_menu_file_return {
FILE_COPY = 4,
FILE_MOVE,
FILE_DELETE,
FILE_PAYLOAD,
FILE_SCRIPT,
FILE_HEXVIEW,
FILE_DUMPBIS
};
extern menu_entry fs_menu_file[];
enum fs_menu_folder_return {
DIR_EXITFOLDER = 2,
DIR_COPYFOLDER,
DIR_DELETEFOLDER
};
extern menu_entry fs_menu_folder[];
enum fs_menu_startdir_return {
FILEMENU_RETURN = 0,
FILEMENU_CLIPBOARD,
FILEMENU_CURFOLDER
};
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

@@ -0,0 +1,67 @@
#include "common.h"
const char *gfx_file_size_names[] = {
"B ",
"KB",
"MB",
"GB"
};
const char *menu_sd_states[] = {
"\nUnmount SD",
"\nMount SD"
};
const char *emmc_fs_entries[] = {
"SAFE",
"SYSTEM",
"USER"
};
const char *utils_err_codes[] = {
"OK",
"I/O ERROR",
"NO DISK",
"NOT READY",
"NO FILE",
"NO PATH",
"PATH INVALID",
"ACCESS DENIED",
"ACCESS DENIED",
"INVALID PTR",
"PROTECTED",
"INVALID DRIVE",
"NO MEM",
"NO FAT",
"MKFS ABORT"
};
const char *utils_err_codes_te[] = { // these start at 50
"SAME LOC",
"DISK WRITE FAILED",
"EMPTY CLIPBOARD",
"DEFENITION OF INSANITY",
"FOLDER ROOT",
"DEST PART OF SRC",
"PART NOT FOUND",
"BISKEY DUMP FAILED",
"MEM ALLOC FAILED",
"EMMC READ FAILED",
"EMMC WRITE FAILED",
"FILE TOO BIG FOR DEST",
"SD EJECTED",
"PARSING FAILED",
"CANNOT COPY FILE TO FS PART",
"NO DESTENATION"
};
/*
const char *pkg2names[] = {
"BCPKG2-1-Normal-Main",
"BCPKG2-2-Normal-Sub",
"BCPKG2-3-SafeMode-Main",
"BCPKG2-4-SafeMode-Sub",
"BCPKG2-5-Repair-Main",
"BCPKG2-6-Repair-Sub"
};
*/
const char *mainmenu_credits = "\nTegraexplorer, made by:\nSuch Meme, Many Skill\n\nProject based on:\nLockpick_RCM\nHekate\n\nCool people:\nshchmue\ndennthecafebabe\nDax";

View File

@@ -0,0 +1,92 @@
#include "common.h"
#include "types.h"
menu_entry mainmenu_main[] = {
{"[SD:/] SD CARD", COLOR_GREEN, ISMENU},
{"[EMMC:/] EMMC", COLOR_ORANGE, ISMENU},
{"[EMMC:/] EMUMMC", COLOR_BLUE, ISMENU},
{"\nMount/Unmount SD", COLOR_WHITE, ISMENU},
{"Tools", COLOR_VIOLET, ISMENU},
{"SD format", COLOR_VIOLET, ISMENU},
{"\nCredits", COLOR_WHITE, ISMENU},
{"Exit", COLOR_WHITE, ISMENU}
};
menu_entry mainmenu_shutdown[] = {
{"Back", COLOR_WHITE, ISMENU},
{"\nReboot to RCM", COLOR_VIOLET, ISMENU},
{"Reboot normally", COLOR_ORANGE, ISMENU},
{"Power off\n", COLOR_BLUE, ISMENU},
{"Reboot to Hekate", COLOR_GREEN, ISMENU},
{"Reboot to Atmosphere", COLOR_GREEN, ISMENU}
};
menu_entry mainmenu_tools[] = {
{"Back", COLOR_WHITE, ISMENU},
{"\nDisplay Console Info", COLOR_GREEN, ISMENU},
{"Display GPIO pins", COLOR_VIOLET, ISMENU},
{"Dump Firmware", COLOR_BLUE, ISMENU},
{"Dump User Saves", COLOR_YELLOW, ISMENU}
};
menu_entry mainmenu_format[] = {
{"Back\n", COLOR_WHITE, ISMENU},
{"Format entire SD to FAT32", COLOR_RED, ISMENU},
{"Format for EmuMMC setup (FAT32/RAW)", COLOR_RED, ISMENU}
};
menu_entry utils_mmcChoice[] = {
{"Back\n", COLOR_WHITE, ISMENU},
{"SysMMC", COLOR_ORANGE, ISMENU},
{"EmuMMC", COLOR_BLUE, ISMENU}
};
menu_entry fs_menu_file[] = {
{NULL, COLOR_GREEN, ISMENU | ISSKIP},
{NULL, COLOR_VIOLET, ISMENU | ISSKIP},
{NULL, COLOR_VIOLET, ISMENU | ISSKIP},
{"\n\n\nBack", COLOR_WHITE, ISMENU},
{"\nCopy to clipboard", COLOR_BLUE, ISMENU},
{"Move to clipboard", COLOR_BLUE, ISMENU},
{"\nDelete file\n", COLOR_RED, ISMENU},
{"Launch Payload", COLOR_ORANGE, ISMENU},
{"Launch Script", COLOR_YELLOW, ISMENU},
{"View Hex", COLOR_GREEN, ISMENU},
{"\nExtract BIS", COLOR_YELLOW, ISMENU}
};
menu_entry fs_menu_folder[] = {
{NULL, COLOR_VIOLET, ISMENU | ISSKIP},
{"\nBack", COLOR_WHITE, ISMENU},
{"Return to main menu\n", COLOR_BLUE, ISMENU},
{"Copy to clipboard", COLOR_VIOLET, ISMENU},
{"Delete folder", COLOR_RED, ISMENU}
};
menu_entry fs_menu_startdir[] = {
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
{"Clipboard -> Current folder", COLOR_ORANGE, ISMENU},
{"Current folder menu ", COLOR_ORANGE, ISMENU}
};
gpt_entry_rule gpt_fs_rules[] = {
{"PRODINFOF", 0 | isFS},
{"SAFE", 1 | isFS },
{"SYSTEM", 2 | isFS},
{"USER", 3 | isFS},
{NULL, 0}
};
menu_entry mmcmenu_start[] = {
{"Back", COLOR_ORANGE, ISMENU},
{"Dump File Partitions", COLOR_ORANGE, ISMENU},
{"Clipboard -> Partition\n", COLOR_ORANGE, ISMENU},
{"BOOT0/1", COLOR_BLUE, isBOOT | ISMENU}
};
menu_entry mmcmenu_filemenu[] = {
{"Part:", COLOR_ORANGE, ISSKIP | ISMENU},
{NULL, COLOR_VIOLET, ISSKIP | ISMENU},
{"\nBack", COLOR_WHITE, ISMENU},
{"Dump to SD", COLOR_YELLOW, ISMENU}
};

View File

@@ -0,0 +1,54 @@
#pragma once
#include "../../utils/types.h"
#define ISDIR (1 << 0)
#define ISARC (1 << 1)
#define ISHIDE (1 << 8)
#define ISMENU (1 << 9)
#define ISSKIP (1 << 10)
#define ISGB (1 << 7)
#define ISMB (1 << 6)
#define ISKB (1 << 5)
#define ISB (1 << 4)
#define SETBIT(object, shift, value) ((value) ? (object |= shift) : (object &= ~shift))
/* Bit table for property as a file:
0000 0001: Directory bit
0000 0010: Archive bit (or hideme)
0001 0000: Size component is a Byte
0010 0000: Size component is a KiloByte
0100 0000: Size component is a MegaByte
1000 0000: Size component is a GigaByte : note that this won't surpass gigabytes, but i don't expect people to have a single file that's a terrabyte big
*/
#define COPY_MODE_PRINT 0x1
#define COPY_MODE_CANCEL 0x2
#define BUFSIZE 32768
#define OPERATIONCOPY 0x2
#define OPERATIONMOVE 0x4
#define PART_BOOT 0x1
#define PART_PKG2 0x2
#define BOOT0_ARG 0x80
#define BOOT1_ARG 0x40
#define BCPKG2_1_ARG 0x20
#define BCPKG2_3_ARG 0x10
typedef struct {
char *name;
u32 storage;
u16 property;
} menu_entry;
typedef struct {
const char *name;
u8 property;
} gpt_entry_rule;
#define isFS 0x80
#define isBOOT 0x2

View File

@@ -1,34 +1,42 @@
#include <string.h> #include <string.h>
#include "../mem/heap.h"
#include "gfx.h"
#include "fs.h"
#include "emmc.h" #include "emmc.h"
#include "../utils/types.h" #include "../../mem/heap.h"
#include "../libs/fatfs/ff.h" #include "../../utils/types.h"
#include "../utils/sprintf.h" #include "../../libs/fatfs/ff.h"
#include "../utils/btn.h" #include "../../utils/sprintf.h"
#include "../gfx/gfx.h" #include "../../utils/btn.h"
#include "../utils/util.h" #include "../../gfx/gfx.h"
#include "../hos/pkg1.h" #include "../../utils/util.h"
#include "../storage/sdmmc.h" #include "../../hos/pkg1.h"
#include "../storage/nx_emmc.h" #include "../../storage/sdmmc.h"
#include "../sec/tsec.h" #include "../../storage/nx_emmc.h"
#include "../soc/t210.h" #include "../../sec/tsec.h"
#include "../soc/fuse.h" #include "../../soc/t210.h"
#include "../mem/mc.h" #include "../../soc/fuse.h"
#include "../sec/se.h" #include "../../mem/mc.h"
#include "../soc/hw_init.h" #include "../../sec/se.h"
#include "../mem/emc.h" #include "../../soc/hw_init.h"
#include "../mem/sdram.h" #include "../../mem/emc.h"
#include "../../mem/sdram.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"
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;
__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];
short pkg1ver = -1; pkg1_info pkg1inf = {-1, ""};
short currentlyMounted = -1;
static bool _key_exists(const void *data) { return memcmp(data, zeros, 0x10); }; static bool _key_exists(const void *data) { return memcmp(data, zeros, 0x10); };
@@ -52,33 +60,71 @@ void print_biskeys(){
gfx_hexdump(0, bis_key[2], 32); gfx_hexdump(0, bis_key[2], 32);
} }
int mount_emmc(char *partition, int biskeynumb){ pkg1_info returnpkg1info(){
f_unmount("emmc:"); return pkg1inf;
}
int connect_part(const char *partition){
sdmmc_storage_set_mmc_partition(&storage, 0);
system_part = nx_emmc_part_find(selectGpt(currentlyMounted), partition);
if (!system_part) {
gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0);
return 1;
}
return 0;
}
int mount_mmc(const char *partition, const int biskeynumb){
int res;
f_unmount("emmc:");
se_aes_key_set(8, bis_key[biskeynumb] + 0x00, 0x10); se_aes_key_set(8, bis_key[biskeynumb] + 0x00, 0x10);
se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10); se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10);
system_part = nx_emmc_part_find(&gpt, partition); if (connect_part(partition))
if (!system_part) { return 1;
gfx_printf("Failed to locate %s partition.", partition);
return -1;
}
if (f_mount(&emmc, "emmc:", 1)) { if ((res = f_mount(&emmc, "emmc:", 1))) {
gfx_printf("Mount failed of %s.", partition); gfx_errDisplay("mount_mmc", res, 0);
return -1; return 1;
} }
return 0; return 0;
} }
short returnpkg1ver(){ void connect_mmc(short mmctype){
return pkg1ver; if (mmctype != currentlyMounted){
disconnect_mmc();
h_cfg.emummc_force_disable = 0;
switch (mmctype){
case SYSMMC:
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
h_cfg.emummc_force_disable = 1;
currentlyMounted = SYSMMC;
break;
case EMUMMC:
if (emummc_storage_init_mmc(&storage, &sdmmc)){
h_cfg.emummc_force_disable = 0;
currentlyMounted = EMUMMC;
}
break;
}
}
} }
void disconnect_emmc(){ void disconnect_mmc(){
f_unmount("emmc:"); f_unmount("emmc:");
sdmmc_storage_end(&storage); switch (currentlyMounted){
case SYSMMC:
sdmmc_storage_end(&storage);
break;
case EMUMMC:
emummc_storage_end(&storage);
break;
}
currentlyMounted = -1;
} }
int dump_biskeys(){ int dump_biskeys(){
@@ -87,12 +133,13 @@ int dump_biskeys(){
int retries = 0; int retries = 0;
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4); connect_mmc(SYSMMC);
// Read package1. // Read package1.
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.");
@@ -169,44 +216,43 @@ 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);
/*
char part_name[37] = "SYSTEM";
// todo: menu selection for this
u32 bis_key_index = 0;
if (strcmp(part_name, "PRODINFOF") == 0)
bis_key_index = 0;
else if (strcmp(part_name, "SAFE") == 0)
bis_key_index = 1;
else if (strcmp(part_name, "SYSTEM") == 0)
bis_key_index = 2;
else if (strcmp(part_name, "USER") == 0)
bis_key_index = 3;
else {
gfx_printf("Partition name %s unrecognized.", part_name);
return;
}
*/
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);
pkg1inf.ver = pkg1_id->kb;
strcpy(pkg1inf.id, pkg1_id->id);
return 0;
}
/* void dumpGpt(){
system_part = nx_emmc_part_find(&gpt, "SYSTEM"); connect_mmc(SYSMMC);
if (!system_part) { sdmmc_storage_set_mmc_partition(&storage, 0);
gfx_printf("Failed to locate SYSTEM partition."); nx_emmc_gpt_parse(&sys_gpt, &storage);
return -1;
if (emu_cfg.enabled){
connect_mmc(EMUMMC);
emummc_storage_set_mmc_partition(&storage, 0);
nx_emmc_gpt_parse(&emu_gpt, &storage);
} }
}
if (f_mount(&emmc_sys, "system:", 1)) { link_t *selectGpt(short mmcType){
gfx_printf("Mount failed of SYSTEM."); switch(mmcType){
return -1; case SYSMMC:
return &sys_gpt;
case EMUMMC:
return &emu_gpt;
} }
*/ return NULL;
}
pkg1ver = pkg1_id->kb; 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; return 0;
} }

View File

@@ -1,11 +1,24 @@
#pragma once #pragma once
#include "../../utils/types.h"
#include "../../utils/list.h"
typedef struct _pkg1_info {
short ver;
char id[16];
} pkg1_info;
//int mount_emmc_partition(const char *part, int logicnumb); //int mount_emmc_partition(const char *part, int logicnumb);
int dump_biskeys(); int dump_biskeys();
void print_biskeys(); void print_biskeys();
int mount_emmc(char *partition, int biskeynumb); pkg1_info returnpkg1info();
short returnpkg1ver();
void disconnect_emmc(); int mount_mmc(const char *partition, const int biskeynumb);
void connect_mmc(short mmctype);
void disconnect_mmc();
int connect_part(const char *partition);
void dumpGpt();
link_t *selectGpt(short mmcType);
int checkGptRules(char *in);
static const u8 zeros[0x10] = {0}; static const u8 zeros[0x10] = {0};
@@ -40,4 +53,11 @@ static const u8 bis_key_source[3][0x20] = {
{ {
0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C, 0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C,
0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4} 0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4}
}; };
/*
enum mmc_types {
SYSMMC = 0,
EMUMMC
};
*/

View File

@@ -0,0 +1,184 @@
#include <string.h>
#include "emmcoperations.h"
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../../utils/types.h"
#include "emmc.h"
#include "../../storage/emummc.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#include "../utils/utils.h"
#include "../fs/fsutils.h"
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
FIL fp;
u8 *buf;
u32 lba_curr = part->lba_start;
u32 bytesWritten = 0;
u32 totalSectors = part->lba_end - part->lba_start + 1;
u64 totalSize = (u64)((u64)totalSectors << 9);
u32 num = 0;
u32 pct = 0;
int res;
gfx_printf("Initializing\r");
buf = calloc(BUFSIZE, sizeof(u8));
if (!buf){
gfx_errDisplay("dump_emmc_part", ERR_MEM_ALLOC_FAILED, 1);
return -1;
}
if ((res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE))){
gfx_errDisplay("dump_emmc_part", res, 2);
return -1;
}
f_lseek(&fp, totalSize);
f_lseek(&fp, 0);
while (totalSectors > 0){
num = MIN(totalSectors, 64);
if (!emummc_storage_read(mmcstorage, lba_curr, num, buf)){
gfx_errDisplay("dump_emmc_part", ERR_EMMC_READ_FAILED, 3);
return -1;
}
if ((res = f_write(&fp, buf, num * NX_EMMC_BLOCKSIZE, NULL))){
gfx_errDisplay("dump_emmc_part", res, 4);
return -1;
}
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
gfx_printf("Progress: %d%%\r", pct);
lba_curr += num;
totalSectors -= num;
bytesWritten += num * NX_EMMC_BLOCKSIZE;
}
gfx_printf(" \r");
f_close(&fp);
free(buf);
return 0;
}
int existsCheck(char *path){
int res = 0;
if (fsutil_checkfile(path)){
gfx_printf("File already exists! Overwrite?\nVol +/- to cancel\n");
res = gfx_makewaitmenu("Power to continue", 3);
gfx_printf("\r \r");
return res;
}
return 1;
}
/*
int dump_emmc_parts(u16 parts, u8 mmctype){
char *path;
char basepath[] = "sd:/tegraexplorer/partition_dumps";
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/partition_dumps");
connect_mmc(mmctype);
gfx_clearscreen();
if (parts & PART_BOOT){
emmc_part_t bootPart;
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
memset(&bootPart, 0, sizeof(bootPart));
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;
gfx_printf("Dumping %s\n", bootPart.name);
dump_emmc_part(path, &storage, &bootPart);
free(path);
}
emummc_storage_set_mmc_partition(&storage, 0);
}
if (parts & PART_PKG2){
for (int i = 0; i < 6; i++){
utils_copystring(fsutil_getnextloc(basepath, pkg2names[i]), &path);
gfx_printf("Dumping %s\n", pkg2names[i]);
emmcDumpSpecific(pkg2names[i], path);
free(path);
}
}
gfx_printf("\nDone!");
btn_wait();
return 0;
}
*/
int emmcDumpBoot(char *basePath){
emmc_part_t bootPart;
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
char *path;
memset(&bootPart, 0, sizeof(emmc_part_t));
bootPart.lba_start = 0;
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
for (int i = 0; i < 2; i++){
strcpy(bootPart.name, "BOOT");
bootPart.name[4] = (u8)('0' + i);
bootPart.name[5] = 0;
emummc_storage_set_mmc_partition(&storage, i + 1);
utils_copystring(fsutil_getnextloc(basePath, bootPart.name), &path);
if (!existsCheck(path))
continue;
SWAPCOLOR(COLOR_BLUE);
gfx_printf("Dumping %s\n", bootPart.name);
RESETCOLOR;
emmcDumpPart(path, &storage, &bootPart);
free(path);
}
emummc_storage_set_mmc_partition(&storage, 0);
return 0;
}
int emmcDumpSpecific(char *part, char *path){
if (!existsCheck(path))
return 0;
emummc_storage_set_mmc_partition(&storage, 0);
if (connect_part(part)){
gfx_errDisplay("dump_emmc_specific", ERR_PART_NOT_FOUND, 0);
return 1;
}
SWAPCOLOR(COLOR_VIOLET);
gfx_printf("Dumping %s\n", part);
RESETCOLOR;
emmcDumpPart(path, &storage, system_part);
return 0;
}

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

@@ -0,0 +1,10 @@
#pragma once
#include "../../utils/types.h"
#include "../../storage/nx_emmc.h"
int emmcDumpSpecific(char *part, char *path);
int emmcDumpBoot(char *basePath);
int mmcFlashFile(char *path, short mmcType);
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);

View File

@@ -0,0 +1,229 @@
#include <string.h>
#include "emmcoperations.h"
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../../utils/types.h"
#include "emmc.h"
#include "../../storage/emummc.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#include "../utils/utils.h"
#include "../fs/fsutils.h"
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
FIL fp;
FILINFO fno;
u8 *buf;
u32 lba_curr = part->lba_start;
u64 bytesWritten = 0;
u32 totalSectorsDest = part->lba_end - part->lba_start + 1;
u64 totalSizeDest = (u64)((u64)totalSectorsDest << 9);
u64 totalSize;
u32 num = 0;
u32 pct = 0;
int res;
gfx_printf("Initializing\r");
buf = calloc(16384, sizeof(u8));
if (!buf){
gfx_errDisplay("restore_emmc_part", ERR_MEM_ALLOC_FAILED, 1);
return -1;
}
if ((res = f_stat(path, &fno))){
gfx_errDisplay("restore_emmc_part", res, 2);
return -1;
}
totalSize = fno.fsize;
u64 totalSectors = totalSize / NX_EMMC_BLOCKSIZE;
if (totalSize > totalSizeDest){
gfx_errDisplay("restore_emmc_part", ERR_FILE_TOO_BIG_FOR_DEST, 3);
return -1;
}
gfx_printf("Flashing %s\n", part->name);
if (totalSize < totalSizeDest){
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("File is too small for destenation.\nDo you want to flash it anyway?\n\nVol +/- to Cancel\n");
u8 btnres = gfx_makewaitmenu(
"Power to Confirm",
2
);
RESETCOLOR;
if (!btnres){
gfx_printf("\nCancelled: %s\n\n", part->name);
return 0;
}
else
gfx_printf("\nFlashing %s\n", part->name);
}
if ((res = f_open(&fp, path, FA_OPEN_ALWAYS | FA_READ))){
gfx_errDisplay("restore_emmc_part", res, 4);
return -1;
}
while (totalSectors > 0){
num = MIN(totalSectors, 32);
if ((res = f_read(&fp, buf, num * NX_EMMC_BLOCKSIZE, NULL))){
gfx_errDisplay("restore_emmc_part", res, 5);
return -1;
}
if (!emummc_storage_write(mmcstorage, lba_curr, num, buf)){
gfx_errDisplay("restore_emmc_part", ERR_EMMC_WRITE_FAILED, 2);
return -1;
}
lba_curr += num;
totalSectors -= num;
bytesWritten += (u64)(num * NX_EMMC_BLOCKSIZE);
pct = (u64)(bytesWritten * (u64)100) / (u64)(fno.fsize);
gfx_printf("Progress: %d%%\r", pct);
}
gfx_printf(" \r");
f_close(&fp);
free(buf);
return 0;
}
// function replaced by new mmc implementation. Will be removed at some point
/*
int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
connect_mmc(mmctype);
if (partition){
emmc_part_t bootPart;
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
memset(&bootPart, 0, sizeof(bootPart));
bootPart.lba_start = 0;
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
strcpy(bootPart.name, target);
emummc_storage_set_mmc_partition(&storage, partition);
restore_emmc_part(path, &storage, &bootPart);
}
else {
if (connect_part(target)){
gfx_errDisplay("restore_emmc_part", ERR_PART_NOT_FOUND, 0);
return -1;
}
restore_emmc_part(path, &storage, system_part);
}
return 0;
}
int restore_bis_using_file(char *path, u8 mmctype){
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/bis");
gfx_clearscreen();
if (extract_bis_file(path, "sd:/tegraexplorer/bis"))
return -1;
SWAPBGCOLOR(COLOR_RED);
SWAPCOLOR(COLOR_DEFAULT);
gfx_printf("\nAre you sure you want to flash these files\nThis could leave your switch unbootable!\nTarget is SysMMC\n\nVol +/- to cancel\n");
if (!gfx_makewaitmenu(
"Power to confirm",
10
))
{
return 0;
}
RESETCOLOR;
gfx_printf("\nRestoring BIS...\n\n");
restore_emmc_file("sd:/tegraexplorer/bis/BOOT0.bin", "BOOT0", 1, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BOOT1.bin", "BOOT1", 2, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-1-Normal-Main", pkg2names[0], 0, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-1-Normal-Main", pkg2names[1], 0, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-3-SafeMode-Main", pkg2names[2], 0, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-3-SafeMode-Main", pkg2names[3], 0, mmctype);
gfx_printf("\n\nDone!\nPress any button to return");
btn_wait();
return 0;
}
*/
emmc_part_t *mmcFindPart(char *path, short mmcType){
char *filename, *extention, *path_local;
emmc_part_t *part;
utils_copystring(path, &path_local);
filename = strrchr(path_local, '/') + 1;
extention = strrchr(path_local, '.');
if (extention != NULL)
*extention = '\0';
if (checkGptRules(filename)){
gfx_errDisplay("mmcFindPart", ERR_CANNOT_COPY_FILE_TO_FS_PART, 1);
free(path_local);
return NULL;
}
part = nx_emmc_part_find(selectGpt(mmcType), filename);
if (part != NULL){
emummc_storage_set_mmc_partition(&storage, 0);
free(path_local);
return part;
}
if (!strcmp(filename, "BOOT0") || !strcmp(filename, "BOOT1")){
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
part = calloc(1, sizeof(emmc_part_t));
part->lba_start = 0;
part->lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
strcpy(part->name, filename);
emummc_storage_set_mmc_partition(&storage, (!strcmp(filename, "BOOT0")) ? 1 : 2);
free(path_local);
return part;
}
//gfx_printf("Path: %s\nFilename: %s", path, filename);
//btn_wait();
gfx_errDisplay("mmcFindPart", ERR_NO_DESTENATION, 2);
free(path_local);
return NULL;
}
int mmcFlashFile(char *path, short mmcType){
emmc_part_t *part;
int res;
part = mmcFindPart(path, mmcType);
if (part != NULL){
res = emmcRestorePart(path, &storage, part);
emummc_storage_set_mmc_partition(&storage, 0);
return res;
}
return 1;
}

View File

@@ -1,399 +0,0 @@
#include <string.h>
#include "../mem/heap.h"
#include "gfx.h"
#include "fs.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"
fs_entry fileobjects[500];
char rootpath[10] = "";
char *currentpath = "";
char *clipboard = "";
u8 clipboardhelper = 0;
extern const char sizevalues[4][3];
extern int launch_payload(char *path);
menu_item explfilemenu[9] = {
{"-- File Menu --", COLOR_BLUE, -1, 0},
{"FILE", COLOR_GREEN, -1, 0},
{"\nSIZE", COLOR_VIOLET, -1, 0},
{"\n\n\nBack", COLOR_WHITE, -1, 1},
{"\nCopy to clipboard", COLOR_BLUE, COPY, 1},
{"Move to clipboard", COLOR_BLUE, MOVE, 1},
{"\nDelete file\n", COLOR_RED, DELETE, 1},
{"Launch Payload", COLOR_ORANGE, PAYLOAD, 1},
{"View Hex", COLOR_GREEN, HEXVIEW, 1}
};
void writecurpath(const char *in){
if (currentpath != NULL)
free(currentpath);
size_t len = strlen(in) + 1;
currentpath = (char*) malloc (len);
strcpy(currentpath, in);
strcpy(currentpath, in);
}
void writeclipboard(const char *in, bool move, bool folder){
if (clipboard != NULL)
free(clipboard);
clipboardhelper = 0;
if (move)
clipboardhelper |= (OPERATIONMOVE);
else
clipboardhelper |= (OPERATIONCOPY);
if (folder)
clipboardhelper |= (ISDIR);
size_t len = strlen(in) + 1;
clipboard = (char*) malloc (len);
strcpy(clipboard, in);
strcpy(clipboard, in);
}
char *getnextloc(char *current, char *add){
char *ret;
size_t size = strlen(current) + strlen(add) + 1;
ret = (char*) malloc (size);
if (!strcmp(rootpath, current))
sprintf(ret, "%s%s", current, add);
else
sprintf(ret, "%s/%s", current, add);
return ret;
}
char *getprevloc(char *current){
char *ret, *temp;
size_t size = strlen(current) + 1;
ret = (char*) malloc (size);
strcpy(ret, current);
temp = strrchr(ret, '/');
memset(temp, '\0', 1);
if (strlen(rootpath) > strlen(ret))
strcpy(ret, rootpath);
return ret;
}
fs_entry getfileobj(int spot){
return fileobjects[spot];
}
bool checkfile(char* path){
FRESULT fr;
FILINFO fno;
fr = f_stat(path, &fno);
if (fr & FR_NO_FILE)
return false;
else
return true;
}
void viewbytes(char *path){
FIL in;
u8 print[2048];
u32 size;
QWORD offset = 0;
int res;
clearscreen();
res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING);
if (res != FR_OK){
message("File Opening Failed", COLOR_RED);
return;
}
msleep(200);
while (1){
f_lseek(&in, offset * 16);
res = f_read(&in, &print, 2048 * sizeof(u8), &size);
if (res != FR_OK){
message("Reading Failed", COLOR_RED);
return;
}
printbytes(print, size, offset * 16);
res = btn_read();
if (!res)
res = btn_wait();
if (res & BTN_VOL_DOWN && 2048 * sizeof(u8) == size)
offset++;
if (res & BTN_VOL_UP && offset > 0)
offset--;
if (res & BTN_POWER)
break;
}
f_close(&in);
}
int copy(const char *locin, const char *locout, bool print){
FIL in, out;
u64 sizeoffile, sizecopied = 0, totalsize;
UINT temp1, temp2;
u8 *buff;
unsigned int x, y, i = 0;
gfx_con_getpos(&x, &y);
if (!strcmp(locin, locout)){
return 3;
}
if (f_open(&in, locin, FA_READ | FA_OPEN_EXISTING)){
return 1;
}
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
return 2;
}
buff = malloc (BUFSIZE);
sizeoffile = f_size(&in);
totalsize = sizeoffile;
while (sizeoffile > 0){
if (f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))
return 3;
if (f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))
return 4;
if (temp1 != temp2)
return 5;
sizeoffile -= temp1;
sizecopied += temp1;
if (print && 10 > i++){
gfx_printf("%k[%d%%/100%%]%k", COLOR_GREEN, ((sizecopied * 100) / totalsize) ,COLOR_WHITE);
gfx_con_setpos(x, y);
i = 0;
if (btn_read() & BTN_VOL_DOWN){
f_unlink(locout);
break;
}
}
}
f_close(&in);
f_close(&out);
free(buff);
return 0;
}
void copyfile(const char *path, const char *outfolder){
char *filename = strrchr(path, '/');
char *outstring;
size_t outstringsize = strlen(filename) + strlen(outfolder) + 2;
int res;
clearscreen();
outstring = (char*) malloc (outstringsize);
if (strcmp(rootpath, outfolder))
sprintf(outstring, "%s/%s", outfolder, filename + 1);
else
sprintf(outstring, "%s%s", outfolder, filename + 1);
gfx_printf("Note:\nTo stop the transfer hold Vol-\n\n%s\nProgress: ", outstring);
if (clipboardhelper & OPERATIONMOVE){
if (strcmp(rootpath, "emmc:/"))
f_rename(path, outstring);
else
message("\nMoving in emummc is not allowed!", COLOR_RED);
}
else if (clipboardhelper & OPERATIONCOPY) {
res = copy(path, outstring, true);
if (res){
gfx_printf("\n\n%kSomething went wrong while copying!\n\nErrcode: %d%k", COLOR_RED, res, COLOR_WHITE);
btn_wait();
}
}
else {
message("\nClipboard is empty!", COLOR_RED);
}
free (outstring);
clipboardhelper = 0;
}
u64 getfilesize(char *path){
FILINFO fno;
f_stat(path, &fno);
return fno.fsize;
}
void addobject(char* name, int spot, bool isfol, bool isarc){
size_t length = strlen(name) + 1;
u64 size = 0;
int sizes = 0;
fileobjects[spot].property = 0;
if (fileobjects[spot].name != NULL){
free(fileobjects[spot].name);
fileobjects[spot].name = NULL;
}
fileobjects[spot].name = (char*) malloc (length);
strlcpy(fileobjects[spot].name, name, length);
if (isfol)
fileobjects[spot].property |= (ISDIR);
else {
size = getfilesize(getnextloc(currentpath, name));
while (size > 1024){
size /= 1024;
sizes++;
}
if (sizes > 3)
sizes = 0;
fileobjects[spot].property |= (1 << (4 + sizes));
fileobjects[spot].size = size;
}
if (isarc)
fileobjects[spot].property |= (ISARC);
}
int readfolder(const char *path){
DIR dir;
FILINFO fno;
int folderamount = 0, res;
if (res = f_opendir(&dir, path)){
char errmes[50] = "";
sprintf(errmes, "Error during f_opendir: %d", res);
message(errmes, COLOR_RED);
}
while (!f_readdir(&dir, &fno) && fno.fname[0] && folderamount < 500){
addobject(fno.fname, folderamount++, (fno.fattrib & AM_DIR), (fno.fattrib & AM_ARC));
}
f_closedir(&dir);
return folderamount;
}
int delfile(const char *path, const char *filename){
char *tempmessage;
size_t tempmessagesize = strlen(filename) + 65;
tempmessage = (char*) malloc (tempmessagesize);
sprintf(tempmessage, "Are you sure you want to delete:\n%s\n\nPress vol+/- to cancel\n", filename);
if (makewaitmenu(tempmessage, "Press power to delete", 3)){
f_unlink(path);
return readfolder(currentpath);
}
else
return -1;
}
void filemenu(const char *startpath){
int amount, res, tempint;
char temp[100];
if (!strcmp(rootpath, "emmc:/") && !strcmp(startpath, "emmc:/"))
clipboardhelper = 0;
strcpy(rootpath, startpath);
writecurpath(startpath);
amount = readfolder(currentpath);
if (strcmp(rootpath, "emmc:/"))
explfilemenu[5].property = 1;
else
explfilemenu[5].property = -1;
while (1){
res = makefilemenu(fileobjects, amount, currentpath);
if (res < 1){
if (res == -2){
if (!strcmp(rootpath, currentpath))
break;
else {
writecurpath(getprevloc(currentpath));
amount = readfolder(currentpath);
}
}
if (res == -1){
copyfile(clipboard, currentpath);
amount = readfolder(currentpath);
}
if (res == 0)
break;
}
else {
if (fileobjects[res - 1].property & ISDIR){
writecurpath(getnextloc(currentpath, fileobjects[res - 1].name));
amount = readfolder(currentpath);
}
else {
strlcpy(explfilemenu[1].name, fileobjects[res - 1].name, 43);
for (tempint = 4; tempint < 8; tempint++)
if ((fileobjects[res - 1].property & (1 << tempint)))
break;
sprintf(temp, "\nSize: %d %s", fileobjects[res - 1].size, sizevalues[tempint - 4]);
strcpy(explfilemenu[2].name, temp);
if (strstr(fileobjects[res - 1].name, ".bin") != NULL && fileobjects[res - 1].size & ISKB){
explfilemenu[7].property = 1;
}
else
explfilemenu[7].property = -1;
tempint = makemenu(explfilemenu, 9);
switch (tempint){
case COPY:
writeclipboard(getnextloc(currentpath, fileobjects[res - 1].name), false, false);
break;
case MOVE:
writeclipboard(getnextloc(currentpath, fileobjects[res - 1].name), true, false);
break;
case DELETE:
if ((tempint = delfile(getnextloc(currentpath, fileobjects[res - 1].name), fileobjects[res - 1].name)) != -1)
amount = tempint;
break;
case PAYLOAD:
launch_payload(getnextloc(currentpath, fileobjects[res - 1].name));
break;
case HEXVIEW:
viewbytes(getnextloc(currentpath, fileobjects[res - 1].name));
break;
}
}
}
}
}

View File

@@ -1,44 +0,0 @@
#pragma once
#include "../utils/types.h"
#define ISDIR (1 << 0)
#define ISARC (1 << 1)
#define ISGB (1 << 7)
#define ISMB (1 << 6)
#define ISKB (1 << 5)
#define ISB (1 << 4)
#define OPERATIONCOPY (1 << 1)
#define OPERATIONMOVE (1 << 2)
#define BUFSIZE 32768
/* Bit table for property:
0000 0001: Directory bit
0000 0010: Archive bit
0001 0000: Size component is a Byte
0010 0000: Size component is a KiloByte
0100 0000: Size component is a MegaByte
1000 0000: Size component is a GigaByte : note that this won't surpass gigabytes, but i don't expect people to have a single file that's a terrabyte big
*/
typedef struct _fs_entry {
char* name;
u16 size;
u8 property;
} fs_entry;
enum filemenuoptions {
COPY = 1,
MOVE,
DELETE,
PAYLOAD,
HEXVIEW
};
int readfolder(const char *path);
void filemenu();
bool checkfile(char* path);
u64 getfilesize(char *path);
int copy(const char *locin, const char *locout, bool print);

View File

@@ -0,0 +1,7 @@
#pragma once
#include "../common/types.h"
int filemenu(menu_entry file);
void copyfile(const char *src_in, const char *outfolder);
int foldermenu();
void copyfolder(char *in, char *out);

View File

@@ -0,0 +1,184 @@
#include <string.h>
#include "entrymenu.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "fsutils.h"
#include "fsactions.h"
#include "../utils/utils.h"
#include "../gfx/gfxutils.h"
#include "../../mem/heap.h"
#include "fsreader.h"
#include "../gfx/menu.h"
#include "../common/types.h"
#include "../../utils/sprintf.h"
#include "../script/parser.h"
#include "../emmc/emmcoperations.h"
extern char *currentpath;
extern char *clipboard;
extern u8 clipboardhelper;
extern int launch_payload(char *path);
int delfile(const char *path, const char *filename){
gfx_clearscreen();
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("Are you sure you want to delete:\n%s\n\nPress vol+/- to cancel\n", filename);
if (gfx_makewaitmenu("Press power to delete", 3)){
f_unlink(path);
fsreader_readfolder(currentpath);
return 0;
}
else
return -1;
}
void viewbytes(char *path){
FIL in;
u8 print[2048];
u32 size;
QWORD offset = 0;
int res;
gfx_clearscreen();
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("viewbytes", res, 1);
return;
}
while (btn_read() & BTN_POWER);
while (1){
f_lseek(&in, offset * 16);
if ((res = f_read(&in, &print, 2048 * sizeof(u8), &size))){
gfx_errDisplay("viewbytes", res, 2);
return;
}
gfx_con_setpos(0, 31);
gfx_hexdump(offset * 16, print, size * sizeof(u8));
res = btn_read();
if (!res)
res = btn_wait();
if (res & BTN_VOL_DOWN && 2048 * sizeof(u8) == size)
offset++;
if (res & BTN_VOL_UP && offset > 0)
offset--;
if (res & BTN_POWER)
break;
}
f_close(&in);
}
void copyfile(const char *src_in, const char *outfolder){
char *in, *out, *filename;
int res;
gfx_clearscreen();
utils_copystring(src_in, &in);
utils_copystring(strrchr(in, '/') + 1, &filename);
utils_copystring(fsutil_getnextloc(outfolder, filename), &out);
gfx_printf("Note:\nTo stop the transfer hold Vol-\n\n%s\nProgress: ", filename);
if (!strcmp(in, out)){
gfx_errDisplay("gfxcopy", ERR_SAME_LOC, 1);
return;
}
if (clipboardhelper & OPERATIONMOVE){
if ((res = f_rename(in, out))){
gfx_errDisplay("gfxcopy", res, 2);
return;
}
}
else if (clipboardhelper & OPERATIONCOPY) {
if (fsact_copy(in, out, COPY_MODE_CANCEL | COPY_MODE_PRINT))
return;
}
else {
gfx_errDisplay("gfxcopy", ERR_EMPTY_CLIPBOARD, 3);
return;
}
free(in);
free(out);
free(filename);
fsreader_readfolder(currentpath);
}
int filemenu(menu_entry file){
int temp;
FILINFO attribs;
for (int i = 0; i < 3; i++)
if (fs_menu_file[i].name != NULL)
free(fs_menu_file[i].name);
utils_copystring(file.name, &fs_menu_file[0].name);
fs_menu_file[1].name = malloc(16);
fs_menu_file[2].name = malloc(16);
for (temp = 4; temp < 8; temp++)
if ((file.property & (1 << temp)))
break;
sprintf(fs_menu_file[1].name, "\nSize: %d %s", file.storage, gfx_file_size_names[temp - 4]);
if (f_stat(fsutil_getnextloc(currentpath, file.name), &attribs))
SETBIT(fs_menu_file[2].property, ISHIDE, 1);
else {
SETBIT(fs_menu_file[2].property, ISHIDE, 0);
sprintf(fs_menu_file[2].name, "Attribs: %c%c%c%c",
(attribs.fattrib & AM_RDO) ? 'R' : '-',
(attribs.fattrib & AM_SYS) ? 'S' : '-',
(attribs.fattrib & AM_HID) ? 'H' : '-',
(attribs.fattrib & AM_ARC) ? 'A' : '-');
}
SETBIT(fs_menu_file[7].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.property & ISKB) && strstr(file.name, ".rom") == NULL);
SETBIT(fs_menu_file[8].property, ISHIDE, strstr(file.name, ".te") == NULL);
SETBIT(fs_menu_file[10].property, ISHIDE, strstr(file.name, ".bis") == NULL);
temp = menu_make(fs_menu_file, 11, "-- File Menu --");
switch (temp){
case FILE_COPY:
fsreader_writeclipboard(fsutil_getnextloc(currentpath, file.name), OPERATIONCOPY);
break;
case FILE_MOVE:
fsreader_writeclipboard(fsutil_getnextloc(currentpath, file.name), OPERATIONMOVE);
break;
case FILE_DELETE:
delfile(fsutil_getnextloc(currentpath, file.name), file.name);
break;
case FILE_PAYLOAD:
launch_payload(fsutil_getnextloc(currentpath, file.name));
break;
case FILE_SCRIPT:
//ParseScript(fsutil_getnextloc(currentpath, file.name));
runScript(fsutil_getnextloc(currentpath, file.name));
fsreader_readfolder(currentpath);
break;
case FILE_HEXVIEW:
viewbytes(fsutil_getnextloc(currentpath, file.name));
break;
case FILE_DUMPBIS:
gfx_clearscreen();
extract_bis_file(fsutil_getnextloc(currentpath, file.name), currentpath);
fsreader_readfolder(currentpath);
btn_wait();
break;
case -1:
return -1;
}
return 0;
}

View File

@@ -0,0 +1,90 @@
#include <string.h>
#include "entrymenu.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../mem/heap.h"
#include "../gfx/menu.h"
#include "fsreader.h"
#include "../gfx/gfxutils.h"
#include "fsactions.h"
#include "fsutils.h"
#include "../../utils/sprintf.h"
extern char *currentpath;
extern char *clipboard;
extern u8 clipboardhelper;
void copyfolder(char *in, char *out){
int res;
res = strlen(in);
if ((*(in + res - 1) == '/')){
gfx_errDisplay("copyfolder", ERR_FOLDER_ROOT, 1);
}
else if (strstr(out, in) != NULL){
gfx_errDisplay("copyfolder", ERR_DEST_PART_OF_SRC, 2);
}
else if (!strcmp(in, out)){
gfx_errDisplay("copyfolder", ERR_SAME_LOC, 3);
}
else {
gfx_clearscreen();
gfx_printf("\nCopying folder, please wait\n");
fsact_copy_recursive(in, out);
fsreader_readfolder(currentpath);
}
clipboardhelper = 0;
}
int foldermenu(){
int res;
FILINFO attribs;
if (fs_menu_folder[0].name != NULL)
free(fs_menu_folder[0].name);
fs_menu_folder[0].name = malloc(16);
res = strlen(currentpath);
SETBIT(fs_menu_folder[3].property, ISHIDE, (*(currentpath + res - 1) == '/'));
SETBIT(fs_menu_folder[4].property, ISHIDE, (*(currentpath + res - 1) == '/'));
if (f_stat(currentpath, &attribs))
SETBIT(fs_menu_folder[0].property, ISHIDE, 1);
else {
SETBIT(fs_menu_folder[0].property, ISHIDE, 0);
sprintf(fs_menu_folder[0].name, "Attribs: %c%c%c%c",
(attribs.fattrib & AM_RDO) ? 'R' : '-',
(attribs.fattrib & AM_SYS) ? 'S' : '-',
(attribs.fattrib & AM_HID) ? 'H' : '-',
(attribs.fattrib & AM_ARC) ? 'A' : '-');
}
res = menu_make(fs_menu_folder, 5, currentpath);
switch (res){
case DIR_EXITFOLDER:
case -1:
return -1;
case DIR_COPYFOLDER:
fsreader_writeclipboard(currentpath, OPERATIONCOPY | ISDIR);
break;
case DIR_DELETEFOLDER:
gfx_clearscreen();
gfx_printf("Do you want to delete this folder?\nThe entire folder, with all subcontents\n will be deleted!!!\n\nPress vol+/- to cancel\n");
if (gfx_makewaitmenu("Press power to contine...", 3)){
gfx_clearscreen();
gfx_printf("\nDeleting folder, please wait...\n");
fsact_del_recursive(currentpath);
fsreader_writecurpath(fsutil_getprevloc(currentpath));
fsreader_readfolder(currentpath);
}
break;
}
return 0;
}

View File

@@ -0,0 +1,193 @@
#include <string.h>
#include "fsactions.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../utils/utils.h"
#include "../../mem/heap.h"
#include "../../utils/btn.h"
#include "fsutils.h"
int fsact_copy(const char *locin, const char *locout, u8 options){
FIL in, out;
FILINFO in_info;
u64 sizeoffile, sizecopied = 0, totalsize;
UINT temp1, temp2;
u8 *buff;
unsigned int x, y, i = 0;
int res;
gfx_con_getpos(&x, &y);
if (!strcmp(locin, locout)){
gfx_errDisplay("copy", ERR_SAME_LOC, 1);
return 1;
}
if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("copy", res, 2);
return 1;
}
if (f_stat(locin, &in_info)){
gfx_errDisplay("copy", res, 3);
return 1;
}
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
gfx_errDisplay("copy", res, 4);
return 1;
}
buff = malloc (BUFSIZE);
sizeoffile = f_size(&in);
totalsize = sizeoffile;
while (sizeoffile > 0){
if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))){
gfx_errDisplay("copy", res, 5);
return 1;
}
if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))){
gfx_errDisplay("copy", res, 6);
return 1;
}
if (temp1 != temp2){
gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7);
return 1;
}
sizeoffile -= temp1;
sizecopied += temp1;
if (options & COPY_MODE_PRINT && 10 > i++){
gfx_printf("%k[%d%%]%k", COLOR_GREEN, ((sizecopied * 100) / totalsize) ,COLOR_WHITE);
gfx_con_setpos(x, y);
i = 0;
if (options & COPY_MODE_CANCEL)
if (btn_read() & BTN_VOL_DOWN){
f_unlink(locout);
break;
}
}
}
f_close(&in);
f_close(&out);
free(buff);
if ((res = f_chmod(locout, in_info.fattrib, 0x3A))){
gfx_errDisplay("copy", res, 8);
return 1;
}
f_stat(locin, &in_info); //somehow stops fatfs from being weird
return 0;
}
int fsact_del_recursive(char *path){
DIR dir;
FILINFO fno;
int res;
u32 x, y;
char *localpath = NULL;
gfx_con_getpos(&x, &y);
utils_copystring(path, &localpath);
if ((res = f_opendir(&dir, localpath))){
gfx_errDisplay("del_recursive", res, 1);
return 1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
if (fno.fattrib & AM_DIR){
fsact_del_recursive(fsutil_getnextloc(localpath, fno.fname));
}
else {
SWAPCOLOR(COLOR_RED);
gfx_printf("\r");
gfx_printandclear(fno.fname, 37);
if ((res = f_unlink(fsutil_getnextloc(localpath, fno.fname)))){
gfx_errDisplay("del_recursive", res, 2);
return 1;
}
}
}
f_closedir(&dir);
if ((res = f_unlink(localpath))){
gfx_errDisplay("del_recursive", res, 3);
return 1;
}
free(localpath);
return 0;
}
int fsact_copy_recursive(char *path, char *dstpath){
DIR dir;
FILINFO fno;
int res;
u32 x, y;
char *startpath = NULL, *destpath = NULL, *destfoldername = NULL, *temp = NULL;
gfx_con_getpos(&x, &y);
utils_copystring(path, &startpath);
utils_copystring(strrchr(path, '/') + 1, &destfoldername);
utils_copystring(fsutil_getnextloc(dstpath, destfoldername), &destpath);
if ((res = f_opendir(&dir, startpath))){
gfx_errDisplay("copy_recursive", res, 1);
return 1;
}
f_mkdir(destpath);
while (!f_readdir(&dir, &fno) && fno.fname[0]){
if (fno.fattrib & AM_DIR){
fsact_copy_recursive(fsutil_getnextloc(startpath, fno.fname), destpath);
}
else {
SWAPCOLOR(COLOR_GREEN);
gfx_printf("\r");
gfx_printandclear(fno.fname, 37);
utils_copystring(fsutil_getnextloc(startpath, fno.fname), &temp);
if ((res = fsact_copy(temp, fsutil_getnextloc(destpath, fno.fname), COPY_MODE_PRINT))){
gfx_errDisplay("copy_recursive", res, 2);
return 1;
}
free(temp);
}
}
f_closedir(&dir);
if ((res = (f_stat(startpath, &fno)))){
gfx_errDisplay("copy_recursive", res, 3);
return 1;
}
if ((res = f_chmod(destpath, fno.fattrib, 0x3A))){
gfx_errDisplay("copy_recursive", res, 4);
return 1;
}
free(startpath);
free(destpath);
free(destfoldername);
return 0;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "../../utils/types.h"
int fsact_copy(const char *locin, const char *locout, u8 options);
int fsact_del_recursive(char *path);
int fsact_copy_recursive(char *path, char *dstpath);

View File

@@ -0,0 +1,110 @@
#include "fsutils.h"
#include <string.h>
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../../utils/types.h"
#include "../../storage/emummc.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#include "../utils/utils.h"
#include "fsactions.h"
u32 DecodeInt(u8* data) {
u32 out = 0;
for (int i = 0; i < 4; i++) {
out |= (data[i] << ((3 - i) * 8));
}
return out;
}
void copy_fil_size(FIL* in_src, FIL* out_src, int size_src){
u8* buff;
buff = calloc(16384, sizeof(u8));
int size = size_src;
int copysize;
while (size > 0){
copysize = MIN(16834, size);
f_read(in_src, buff, copysize, NULL);
f_write(out_src, buff, copysize, NULL);
size -= copysize;
}
free(buff);
}
void gen_part(int size, FIL* in, char *path){
FIL out;
f_open(&out, path, FA_WRITE | FA_CREATE_ALWAYS);
copy_fil_size(in, &out, size);
f_close(&out);
}
int extract_bis_file(char *path, char *outfolder){
FIL in;
int res;
u8 version[0x10];
u8 args;
u8 temp[0x4];
u32 filesizes[4];
char *tempPath;
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("extract_bis_file", res, 0);
return -1;
}
f_read(&in, version, 0x10, NULL);
f_read(&in, &args, 1, NULL);
for (int i = 0; i < 4; i++){
f_read(&in, temp, 4, NULL);
filesizes[i] = DecodeInt(temp);
}
gfx_printf("Version: %s\n\n", version);
if (args & BOOT0_ARG){
gfx_printf("\nExtracting BOOT0\n");
gen_part(filesizes[0], &in, fsutil_getnextloc(outfolder, "BOOT0.bin"));
}
if (args & BOOT1_ARG){
gfx_printf("Extracting BOOT1\n");
gen_part(filesizes[1], &in, fsutil_getnextloc(outfolder, "BOOT1.bin"));
}
if (args & BCPKG2_1_ARG){
utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-1-Normal-Main"), &tempPath);
gfx_printf("Extracting BCPKG2_1/2\n");
gen_part(filesizes[2], &in, tempPath);
fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-2-Normal-Sub"), COPY_MODE_PRINT);
RESETCOLOR;
free(tempPath);
}
if (args & BCPKG2_3_ARG){
utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-3-SafeMode-Main"), &tempPath);
gfx_printf("Extracting BCPKG2_3/4\n");
gen_part(filesizes[3], &in, tempPath);
fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-4-SafeMode-Sub"), COPY_MODE_PRINT);
RESETCOLOR;
free(tempPath);
}
gfx_printf("\n\nDone!\n");
f_close(&in);
return 0;
}

View File

@@ -0,0 +1,122 @@
#include <string.h>
#include "fsmenu.h"
#include "fsreader.h"
#include "../gfx/menu.h"
#include "../gfx/gfxutils.h"
#include "fsutils.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "entrymenu.h"
extern char *currentpath;
extern char *clipboard;
extern u8 clipboardhelper;
int lastentry = 0;
void fileexplorer(const char *startpath, int type){
int res;
if (lastentry > 0 && lastentry == type)
clipboardhelper = 0;
if (clipboardhelper & OPERATIONMOVE)
clipboardhelper = 0;
lastentry = type;
fsreader_writecurpath(startpath);
fsreader_readfolder(currentpath);
/*
if (strcmp(rootpath, "emmc:/"))
explfilemenu[6].property = 1;
else
explfilemenu[6].property = -1;
*/
while (1){
res = menu_make(fsreader_files, fsutil_getfileobjamount(fsreader_files), currentpath);
switch (res){
case FILEMENU_RETURN:
if (!strcmp(startpath, currentpath))
return;
else {
fsreader_writecurpath(fsutil_getprevloc(currentpath));
fsreader_readfolder(currentpath);
}
break;
case FILEMENU_CLIPBOARD:
if (clipboardhelper & ISDIR)
copyfolder(clipboard, currentpath);
else
copyfile(clipboard, currentpath);
clipboardhelper = 0;
break;
case FILEMENU_CURFOLDER:
if (foldermenu())
return;
break;
case -1:
return;
default:
if(fsreader_files[res].property & ISDIR){
fsreader_writecurpath(fsutil_getnextloc(currentpath, fsreader_files[res].name));
fsreader_readfolder(currentpath);
}
else
if(filemenu(fsreader_files[res]))
return;
break;
}
}
/*
while (1){
res = makefilemenu(fileobjects, getfileobjamount(), currentpath);
if (res < 1){
switch (res){
case -2:
if (!strcmp(rootpath, currentpath))
breakfree = true;
else {
writecurpath(getprevloc(currentpath));
readfolder(currentpath);
}
break;
case -1:
if (clipboardhelper & ISDIR)
copyfolder(clipboard, currentpath);
else
copyfile(clipboard, currentpath);
break;
case 0:
tempint = foldermenu();
if (tempint == -1)
breakfree = true;
break;
}
}
else {
if (fileobjects[res - 1].property & ISDIR){
writecurpath(getnextloc(currentpath, fileobjects[res - 1].name));
readfolder(currentpath);
}
else {
filemenu(fileobjects[res - 1]);
}
}
if (breakfree)
break;
}
*/
}

View File

@@ -0,0 +1,3 @@
#pragma once
void fileexplorer(const char *startpath, int type);

View File

@@ -0,0 +1,106 @@
#include "fsreader.h"
#include "../common/types.h"
#include "../common/common.h"
#include "fsutils.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../gfx/gfxutils.h"
#include "../utils/utils.h"
#include "../../mem/heap.h"
menu_entry *fsreader_files = NULL;
char *currentpath = NULL;
char *clipboard = NULL;
u8 clipboardhelper = 0;
void fsreader_writecurpath(const char *in){
if (currentpath != NULL)
free(currentpath);
utils_copystring(in, &currentpath);
}
void fsreader_writeclipboard(const char *in, u8 args){
if (clipboard != NULL)
free(clipboard);
clipboardhelper = args;
utils_copystring(in, &clipboard);
}
void clearfileobjects(menu_entry **menu){
if ((*menu) != NULL){
for (int i = 0; (*menu)[i].name != NULL; i++){
free((*menu)[i].name);
(*menu)[i].name = NULL;
}
free((*menu));
(*menu) = NULL;
}
}
void createfileobjects(int size, menu_entry **menu){
(*menu) = calloc (size + 1, sizeof(menu_entry));
(*menu)[size].name = NULL;
}
void addobject(char* name, int spot, u8 attribs){
u64 size = 0;
int sizes = 0;
fsreader_files[spot].property = 0;
if (fsreader_files[spot].name != NULL){
free(fsreader_files[spot].name);
fsreader_files[spot].name = NULL;
}
utils_copystring(name, &(fsreader_files[spot].name));
if (attribs & AM_DIR)
fsreader_files[spot].property |= (ISDIR);
else {
size = fsutil_getfilesize(fsutil_getnextloc(currentpath, name));
while (size > 1024){
size /= 1024;
sizes++;
}
if (sizes > 3)
sizes = 0;
fsreader_files[spot].property |= (1 << (4 + sizes));
fsreader_files[spot].storage = size;
}
if (attribs & AM_ARC)
fsreader_files[spot].property |= (ISARC);
}
int fsreader_readfolder(const char *path){
DIR dir;
FILINFO fno;
int folderamount, res;
clearfileobjects(&fsreader_files);
createfileobjects(fsutil_getfolderentryamount(path) + 3, &fsreader_files);
for (folderamount = 0; folderamount < 3; folderamount++){
utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name));
fsreader_files[folderamount].storage = fs_menu_startdir[folderamount].storage;
fsreader_files[folderamount].property = fs_menu_startdir[folderamount].property;
}
if ((res = f_opendir(&dir, path))){
gfx_errDisplay("readfolder", res, 0);
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
addobject(fno.fname, folderamount++, fno.fattrib);
}
f_closedir(&dir);
return folderamount;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "../common/types.h"
extern menu_entry *fsreader_files;
void fsreader_writecurpath(const char *in);
void fsreader_writeclipboard(const char *in, u8 args);
int fsreader_readfolder(const char *path);
void createfileobjects(int size, menu_entry **menu);
void clearfileobjects(menu_entry **menu);

View File

@@ -0,0 +1,90 @@
#include <string.h>
#include "fsutils.h"
#include "../utils/utils.h"
#include "../common/types.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../mem/heap.h"
#include "../../utils/sprintf.h"
#include "../gfx/gfxutils.h"
char *fsutil_getnextloc(const char *current, const char *add){
static char *ret;
if (ret != NULL){
free(ret);
ret = NULL;
}
size_t size = strlen(current) + strlen(add) + 2;
ret = (char*) malloc (size);
if (current[strlen(current) - 1] == '/')
sprintf(ret, "%s%s", current, add);
else
sprintf(ret, "%s/%s", current, add);
return ret;
}
char *fsutil_getprevloc(char *current){
static char *ret;
char *temp;
if (ret != NULL){
free(ret);
ret = NULL;
}
utils_copystring(current, &ret);
temp = strrchr(ret, '/');
if (*(temp - 1) == ':')
temp++;
*temp = '\0';
return ret;
}
int fsutil_getfileobjamount(menu_entry *entries){
int amount = 0;
while (entries[amount].name != NULL)
amount++;
return amount;
}
bool fsutil_checkfile(char* path){
FRESULT fr;
FILINFO fno;
fr = f_stat(path, &fno);
return !(fr & FR_NO_FILE);
}
u64 fsutil_getfilesize(char *path){
FILINFO fno;
f_stat(path, &fno);
return fno.fsize;
}
int fsutil_getfolderentryamount(const char *path){
DIR dir;
FILINFO fno;
int folderamount = 0, res;
if ((res = f_opendir(&dir, path))){
gfx_errDisplay("fsutil_getdircount", res, 0);
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
folderamount++;
}
f_closedir(&dir);
return folderamount;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "../common/types.h"
#include "../../utils/types.h"
char *fsutil_getnextloc(const char *current, const char *add);
char *fsutil_getprevloc(char *current);
int fsutil_getfileobjamount(menu_entry *entries);
bool fsutil_checkfile(char* path);
u64 fsutil_getfilesize(char *path);
int fsutil_getfolderentryamount(const char *path);
int extract_bis_file(char *path, char *outfolder);

View File

@@ -1,214 +0,0 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../gfx/gfx.h"
#include "te.h"
#include "../utils/btn.h"
#include "../utils/util.h"
#include "gfx.h"
#include "fs.h"
#include "../mem/minerva.h"
const char fixedoptions[3][50] = {
"Folder -> previous folder ",
"Clipboard -> Current folder ",
"Return to main menu "
};
const char sizevalues[4][3] = {
"B ",
"KB",
"MB",
"GB"
};
void clearscreen(){
gfx_clear_grey(0x1B);
gfx_box(0, 0, 719, 15, COLOR_WHITE);
gfx_con_setpos(0, 0);
gfx_printf("%k%KTegraexplorer v1.1.1%k%K\n", COLOR_DEFAULT, COLOR_WHITE, COLOR_WHITE, COLOR_DEFAULT);
}
int message(char* message, u32 color){
clearscreen();
gfx_printf("%k%s%k", color, message, COLOR_DEFAULT);
return btn_wait();
}
int makemenu(menu_item menu[], int menuamount){
int currentpos = 1, i, res;
clearscreen();
while (1){
gfx_con_setpos(0, 31);
if (currentpos == 1){
while (currentpos < menuamount && menu[currentpos - 1].property < 1)
currentpos++;
}
if (currentpos == menuamount){
while (currentpos > 1 && menu[currentpos - 1].property < 1)
currentpos--;
}
for (i = 0; i < menuamount; i++){
if (menu[i].property < 0)
continue;
if (i == currentpos - 1)
gfx_printf("%k%K%s%K\n", COLOR_DEFAULT, COLOR_WHITE, menu[i].name, COLOR_DEFAULT);
else
gfx_printf("%k%s\n", menu[i].color, menu[i].name);
}
gfx_printf("\n%k%s", COLOR_WHITE, menuamount);
res = btn_wait();
if (res & BTN_VOL_UP && currentpos > 1){
currentpos--;
while(menu[currentpos - 1].property < 1 && currentpos > 1)
currentpos--;
}
else if (res & BTN_VOL_DOWN && currentpos < menuamount){
currentpos++;
while(menu[currentpos - 1].property < 1 && currentpos < menuamount)
currentpos++;
}
else if (res & BTN_POWER)
return menu[currentpos - 1].internal_function;
}
}
void printbytes(u8 print[], u32 size, u32 offset){
gfx_con_setpos(0, 31);
gfx_hexdump(offset, print, size * sizeof(u8));
}
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer){
clearscreen();
int res;
u32 start = get_tmr_s();
gfx_printf(initialmessage);
while(1){
res = btn_read();
if (res & BTN_VOL_DOWN || res & BTN_VOL_UP)
return 0;
if (start + timer > get_tmr_s())
gfx_printf("\r<Wait %d seconds> ", timer + start - get_tmr_s());
else if (res & BTN_POWER)
return 1;
else
gfx_printf("\r%k%s%k", COLOR_RED, hiddenmessage, COLOR_WHITE);
}
}
void printfsentry(fs_entry file, bool highlight, bool refresh){
int size = 0;
char *display;
int length;
display = (char*) malloc (38);
memset(display + 37, '\0', 1);
if (strlen(file.name) > 37){
strlcpy(display, file.name, 37);
memset(display + 34, '.', 3);
}
else
strcpy(display, file.name);
if (highlight)
gfx_printf("%K%k", COLOR_WHITE, COLOR_DEFAULT);
else
RESETCOLOR;
if (file.property & ISDIR)
gfx_printf("%s", display);
else {
for (size = 4; size < 8; size++)
if ((file.property & (1 << size)))
break;
SWAPCOLOR(COLOR_VIOLET);
gfx_printf("%s", display);
}
RESETCOLOR;
if (refresh){
length = strlen(display);
for (int i = 0; i < (42 - length); i++)
gfx_printf(" ");
}
if (file.property & ISDIR)
gfx_printf("\n");
else {
SWAPCOLOR(COLOR_BLUE);
gfx_printf("\a%d\e%s", file.size, sizevalues[size - 4]);
}
free(display);
}
int makefilemenu(fs_entry *files, int amount, char *path){
int currentpos = -2, i, res = 0, offset = 0, quickoffset = 300;
u32 timer;
bool refresh = false;
clearscreen();
gfx_con_setpos(544, 0);
gfx_printf("%K%k%d / 500\n%K%k%s%k\n\n", COLOR_WHITE, COLOR_DEFAULT, amount, COLOR_DEFAULT, COLOR_GREEN, path, COLOR_DEFAULT);
while (1){
gfx_con_setpos(0, 47);
timer = get_tmr_ms();
for (i = -3 + offset; i < amount && i < 60 + offset; i++){
if (i < 0){
if (i == currentpos - 1)
gfx_printf("%k%K%s%K\n", COLOR_ORANGE, COLOR_WHITE, fixedoptions[i + 3], COLOR_DEFAULT);
else
gfx_printf("%k%K%s\n", COLOR_ORANGE, COLOR_DEFAULT, fixedoptions[i + 3]);
}
else
printfsentry(files[i], (i == currentpos - 1), refresh);
}
refresh = false;
gfx_printf("\n%k%K %s %s\n\nTime taken for screen draw: %dms ", COLOR_BLUE, COLOR_DEFAULT, (offset + 60 < amount) ? "v" : " ", (offset > 0) ? "^" : " ", get_tmr_ms() - timer);
if (quickoffset == 300)
res = btn_wait();
else {
msleep(quickoffset);
res = btn_read();
}
if (res == 0)
quickoffset = 300;
else if (quickoffset > 46)
quickoffset -= 45;
if ((res & BTN_VOL_UP) && currentpos > -2){
currentpos--;
if (offset != 0 && currentpos < offset - 2){
offset--;
refresh = true;
}
}
if ((res & BTN_VOL_DOWN) && currentpos < amount){
currentpos++;
if (currentpos - offset > 60){
offset++;
refresh = true;
}
}
if (res & BTN_POWER)
return currentpos;
}
minerva_periodic_training();
}

View File

@@ -1,13 +0,0 @@
#pragma once
#include "te.h"
#include "fs.h"
#define SWAPCOLOR(color) gfx_printf("%k", color)
#define RESETCOLOR gfx_printf("%k%K", COLOR_WHITE, COLOR_DEFAULT)
int makemenu(menu_item menu[], int menuamount);
int message(char* message, u32 color);
void clearscreen();
int makefilemenu(fs_entry *files, int amount, char *path);
void printbytes(u8 print[], u32 size, u32 offset);
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer);

View File

@@ -0,0 +1,139 @@
#include "gfxutils.h"
#include <string.h>
#include <stdarg.h>
#include "menu.h"
#include "../../gfx/gfx.h"
#include "../../power/max17050.h"
#include "../../utils/btn.h"
#include "../../utils/util.h"
#include "../../mem/heap.h"
#include "../common/common.h"
int printerrors = true;
void gfx_clearscreen(){
int battery = 0;
max17050_get_property(MAX17050_RepSOC, &battery);
gfx_clear_grey(0x1B);
SWAPCOLOR(COLOR_DEFAULT);
SWAPBGCOLOR(COLOR_WHITE);
gfx_box(0, 1263, 719, 1279, COLOR_WHITE);
gfx_con_setpos(0, 1263);
gfx_printf("Move: Vol+/- | Select: Pow | Battery: %3d%%", battery >> 8);
gfx_box(0, 0, 719, 15, COLOR_WHITE);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer v1.5.2\n");
RESETCOLOR;
}
int gfx_message(u32 color, const char* message, ...){
va_list ap;
va_start(ap, message);
gfx_clearscreen();
SWAPCOLOR(color);
gfx_vprintf(message, ap);
va_end(ap);
return btn_wait();
}
int gfx_errDisplay(char *src_func, int err, int loc){
if (!printerrors)
return 0;
gfx_clearscreen();
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("\nAn error occured:\n\n");
gfx_printf("Function: %s\nErrcode: %d\n", src_func, err);
if (err < 15)
gfx_printf("Desc: %s\n", utils_err_codes[err]);
else if (err >= ERR_SAME_LOC && err <= ERR_NO_DESTENATION)
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
if (loc)
gfx_printf("Loc: %d\n", loc);
gfx_printf("\nPress any button to return");
RESETCOLOR;
while (btn_read() != 0);
return btn_wait();
}
int gfx_makewaitmenu(char *hiddenmessage, int timer){
int res;
u32 start = get_tmr_s();
while (btn_read() != 0);
while(1){
res = btn_read();
if (res & BTN_VOL_DOWN || res & BTN_VOL_UP)
return 0;
if (start + timer > get_tmr_s())
gfx_printf("\r<Wait %d seconds> ", timer + start - get_tmr_s());
else if (res & BTN_POWER)
return 1;
else
gfx_printf("\r%s", hiddenmessage);
}
}
void gfx_printlength(int size, char *toprint){
char *temp;
temp = (char*) malloc (size + 1);
if (strlen(toprint) > size){
strlcpy(temp, toprint, size);
memset(temp + size - 3, '.', 3);
memset(temp + size, '\0', 1);
}
else
strcpy(temp, toprint);
gfx_printf("%s", temp);
free(temp);
}
void gfx_printandclear(char *in, int length){
u32 x, y;
gfx_printlength(length, in);
gfx_con_getpos(&x, &y);
RESETCOLOR;
/*
for (int i = (703 - x) / 16; i > 0; i--)
gfx_printf(" ");
*/
gfx_boxGrey(x, y, 703, y + 16, 0x1B);
gfx_con_setpos(x, y);
//gfx_box(x, y, 719, y + 16, COLOR_DEFAULT);
/*
u8 color = 0x1B;
gfx_set_rect_grey(&color, 719 - x, 16, x, y);
*/
}
void gfx_printfilesize(int size, char *type){
SWAPCOLOR(COLOR_VIOLET);
gfx_printf("\a%4d\e%s", size, type);
RESETCOLOR;
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "../../gfx/gfx.h"
#include "../../utils/types.h"
#define SWAPCOLOR(color) gfx_printf("%k", color)
#define SWAPBGCOLOR(color) gfx_printf("%K", color)
#define RESETCOLOR gfx_printf("%k%K", COLOR_WHITE, COLOR_DEFAULT)
void gfx_clearscreen();
int gfx_message(u32 color, const char* message, ...);
int gfx_errDisplay(char *src_func, int err, int loc);
int gfx_makewaitmenu(char *hiddenmessage, int timer);
void gfx_printlength(int size, char *toprint);
void gfx_printandclear(char *in, int length);
void gfx_printfilesize(int size, char *type);
extern int printerrors;

View File

@@ -0,0 +1,168 @@
#include "menu.h"
#include "gfxutils.h"
#include "../common/types.h"
#include "../../utils/btn.h"
#include "../common/common.h"
#include "../../utils/util.h"
#include "../../mem/minerva.h"
#include "../../soc/gpio.h"
extern void sd_unmount();
extern bool sd_inited;
void _printentry(menu_entry entry, bool highlighted, bool refresh){
int size;
u32 color = (entry.property & ISMENU) ? entry.storage : ((entry.property & ISDIR) ? COLOR_WHITE : COLOR_VIOLET);
/*
if (entry.property & ISMENU)
SWAPCOLOR(entry.storage);
else if (entry.property & ISDIR)
SWAPCOLOR(COLOR_WHITE);
else {
SWAPCOLOR(COLOR_VIOLET);
}
*/
if (!(entry.property & ISMENU && entry.property & ISDIR)){
for (size = 4; size < 8; size++)
if ((entry.property & (1 << size)))
break;
}
/*
if (highlighted){
SWAPBGCOLOR(COLOR_WHITE);
if ((entry.property & ISMENU) ? entry.storage == COLOR_WHITE : entry.property & ISDIR)
SWAPCOLOR(COLOR_DEFAULT);
}
else
SWAPBGCOLOR(COLOR_DEFAULT);
*/
SWAPCOLOR((highlighted) ? COLOR_DEFAULT : color);
SWAPBGCOLOR((highlighted) ? color : COLOR_DEFAULT);
if (refresh)
gfx_printandclear(entry.name, 37);
else
gfx_printlength(37, entry.name);
if (entry.property & ISDIR || entry.property & ISMENU)
gfx_printf("\n");
else {
SWAPCOLOR(COLOR_BLUE);
SWAPBGCOLOR(COLOR_DEFAULT);
gfx_printf("\a%4d", entry.storage);
gfx_con.fntsz = 8;
gfx_printf("\n\e%s\n", gfx_file_size_names[size - 4]);
gfx_con.fntsz = 16;
}
}
int menu_make(menu_entry *entries, int amount, char *toptext){
int currentpos = 0, res = 0, offset = 0, delay = 300, minscreen = 0, maxscreen = 59, calculatedamount = 0;
u32 scrolltimer, timer;
bool refresh = false;
gfx_clearscreen();
for (int i = 0; i < amount; i++)
if (!(entries[i].property & ISMENU))
calculatedamount++;
gfx_con_setpos(512, 0);
if (calculatedamount){
SWAPCOLOR(COLOR_DEFAULT);
SWAPBGCOLOR(COLOR_WHITE);
gfx_printf("%3d entries\n", calculatedamount);
RESETCOLOR;
}
else
gfx_printf("\n");
SWAPCOLOR(COLOR_GREEN);
gfx_printlength(42, toptext);
RESETCOLOR;
while (!(res & BTN_POWER)){
gfx_con_setpos(0, 47);
timer = get_tmr_ms();
refresh = false;
if (!currentpos){
while (currentpos < amount && entries[currentpos].property & (ISSKIP | ISHIDE))
currentpos++;
}
if (currentpos == amount - 1){
while (currentpos >= 1 && entries[currentpos].property & (ISSKIP | ISHIDE))
currentpos--;
}
if (currentpos > maxscreen){
offset += currentpos - maxscreen;
minscreen += currentpos - maxscreen;
maxscreen += currentpos - maxscreen;
refresh = true;
}
if (currentpos < minscreen){
offset -= minscreen - currentpos;
maxscreen -= minscreen - currentpos;
minscreen -= minscreen - currentpos;
refresh = true;
}
for (int i = 0 + offset; i < amount && i < 60 + offset; i++)
if (!(entries[i].property & ISHIDE))
_printentry(entries[i], (i == currentpos), refresh);
gfx_printf("\n%k%K %s %s\n\nTime taken for screen draw: %dms", COLOR_BLUE, COLOR_DEFAULT, (offset + 60 < amount) ? "v" : " ", (offset > 0) ? "^" : " ", get_tmr_ms() - timer);
while (btn_read() & BTN_POWER);
res = 0;
while (!res){
if (sd_inited && !!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)){
gfx_errDisplay("menu", ERR_SD_EJECTED, 0);
sd_unmount();
return -1;
}
res = btn_read();
if (!res)
delay = 300;
if (delay < 300){
scrolltimer = get_tmr_ms();
while (res){
if (scrolltimer + delay <= get_tmr_ms())
break;
res = btn_read();
}
}
if (delay > 46 && res)
delay -= 45;
}
if (res & BTN_VOL_UP && currentpos >= 1){
currentpos--;
while(entries[currentpos].property & (ISSKIP | ISHIDE) && currentpos >= 1)
currentpos--;
}
else if (res & BTN_VOL_DOWN && currentpos < amount - 1){
currentpos++;
while(entries[currentpos].property & (ISSKIP | ISHIDE) && currentpos < amount - 1)
currentpos++;
}
}
minerva_periodic_training();
//return (mode) ? currentpos : entries[currentpos].property;
return currentpos;
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "../common/types.h"
int menu_make(menu_entry *entries, int amount, char *toptext);

View File

@@ -0,0 +1,186 @@
#include <stdio.h>
#include <string.h>
#include "mainmenu.h"
#include "../utils/util.h"
#include "utils/tools.h"
#include "../utils/btn.h"
#include "emmc/emmc.h"
#include "../storage/emummc.h"
#include "script/functions.h"
#include "common/common.h"
#include "gfx/menu.h"
#include "utils/utils.h"
#include "gfx/gfxutils.h"
#include "fs/fsutils.h"
#include "fs/fsmenu.h"
#include "emmc/emmcoperations.h"
#include "emmc/emmcmenu.h"
extern bool sd_mount();
extern void sd_unmount();
extern int launch_payload(char *path);
extern bool sd_inited;
extern bool sd_mounted;
int res = 0, meter = 0;
void MainMenu_SDCard(){
fileexplorer("SD:/", 0);
}
void MainMenu_EMMC(){
gfx_clearscreen();
gfx_printf("You're about to enter EMMC\nModifying anything here\n can result in a BRICK!\n\nPlease only continue\n if you know what you're doing\n\nPress Vol+/- to return\n");
if (gfx_makewaitmenu("Press Power to enter", 4)){
/*
connect_mmc(SYSMMC);
if (!mount_mmc(emmc_fs_entries[res - 2], res - 1))
fileexplorer("emmc:/", 1);
*/
makeMmcMenu(SYSMMC);
}
}
void MainMenu_EMUMMC(){
/*
connect_mmc(EMUMMC);
if (!mount_mmc(emmc_fs_entries[res - 5], res - 4))
fileexplorer("emmc:/", 1);
*/
makeMmcMenu(EMUMMC);
}
void MainMenu_MountSD(){
(sd_mounted) ? sd_unmount() : sd_mount();
}
void MainMenu_Tools(){
//res = makemenu(toolsmenu, 8);
res = menu_make(mainmenu_tools, 5, "-- Tools Menu --");
switch(res){
case TOOLS_DISPLAY_INFO:
displayinfo();
break;
case TOOLS_DISPLAY_GPIO:
displaygpio();
//makeMmcMenu(SYSMMC);
break;
case TOOLS_DUMPFIRMWARE:
dumpfirmware(SYSMMC);
break;
case TOOLS_DUMPUSERSAVE:
if ((res = utils_mmcMenu()) > 0)
dumpusersaves(res);
break;
}
}
void MainMenu_SDFormat(){
//res = makemenu(formatmenu, 4);
res = menu_make(mainmenu_format, 3, "-- Format Menu --");
if (res > 0){
gfx_clearscreen();
gfx_printf("Are you sure you want to format your sd?\nThis will delete everything on your SD card\nThis action is irreversible!\n\nPress Vol+/- to cancel\n");
if(gfx_makewaitmenu("Press Power to continue", 10)){
if (format(res)){
sd_unmount();
}
}
}
}
void MainMenu_Credits(){
if (++meter >= 3)
gfx_errDisplay("credits", 53, 0);
gfx_message(COLOR_WHITE, mainmenu_credits);
}
void MainMenu_Exit(){
if (sd_mounted){
SETBIT(mainmenu_shutdown[4].property, ISHIDE, !fsutil_checkfile("/bootloader/update.bin"));
SETBIT(mainmenu_shutdown[5].property, ISHIDE, !fsutil_checkfile("/atmosphere/reboot_payload.bin"));
}
else {
for (int i = 4; i <= 5; i++)
SETBIT(mainmenu_shutdown[i].property, ISHIDE, 1);
}
res = menu_make(mainmenu_shutdown, 6, "-- Shutdown Menu --");
switch(res){
case SHUTDOWN_REBOOT_RCM:
reboot_rcm();
case SHUTDOWN_REBOOT_NORMAL:
reboot_normal();
case SHUTDOWN_POWER_OFF:
power_off();
case SHUTDOWN_HEKATE:
launch_payload("/bootloader/update.bin");
case SHUTDOWN_AMS:
launch_payload("/atmosphere/reboot_payload.bin");
} //todo declock bpmp
}
func_void_ptr mainmenu_functions[] = {
MainMenu_SDCard,
MainMenu_EMMC,
MainMenu_EMUMMC,
MainMenu_MountSD,
MainMenu_Tools,
MainMenu_SDFormat,
MainMenu_Credits,
MainMenu_Exit,
};
void RunMenuOption(int option){
if (option != 7)
meter = 0;
if (option > 0)
mainmenu_functions[option - 1]();
}
void te_main(){
int setter;
if (dump_biskeys() == -1){
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
//mainmenu_main[1].property |= ISHIDE;
}
if (emummc_load_cfg()){
mainmenu_main[2].property |= ISHIDE;
}
dumpGpt();
disconnect_mmc();
while (1){
//fillmainmenu();
setter = sd_mounted;
if (emu_cfg.enabled){
SETBIT(mainmenu_main[2].property, ISHIDE, !setter);
}
SETBIT(mainmenu_main[0].property, ISHIDE, !setter);
mainmenu_main[3].name = (menu_sd_states[!setter]);
setter = sd_inited;
SETBIT(mainmenu_main[5].property, ISHIDE, !setter);
res = menu_make(mainmenu_main, 8, "-- Main Menu --") + 1;
RunMenuOption(res);
}
}

View File

@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "../utils/types.h" #include "../utils/types.h"
#define MAINMENU_AMOUNT 9 #define MAINMENU_AMOUNT 12
#define CREDITS_MESSAGE "\nTegraexplorer, made by:\nSuch Meme, Many Skill\n\nProject based on:\nLockpick_RCM\nHekate\n\nCool people:\nshchmue\ndennthecafebabe\nDax"
/*
typedef struct _menu_item { typedef struct _menu_item {
char name[50]; char name[50];
u32 color; u32 color;
@@ -11,11 +11,15 @@ typedef struct _menu_item {
short property; short property;
} menu_item; } menu_item;
enum mainmenu_return { enum mainmenu_return {
SD_CARD = 1, SD_CARD = 1,
EMMC_SAF, EMMC_SAF,
EMMC_SYS, EMMC_SYS,
EMMC_USR, EMMC_USR,
EMUMMC_SAF,
EMUMMC_SYS,
EMUMMC_USR,
MOUNT_SD, MOUNT_SD,
TOOLS, TOOLS,
SD_FORMAT, SD_FORMAT,
@@ -34,14 +38,16 @@ enum shutdownmenu_return {
enum toolsmenu_return { enum toolsmenu_return {
DISPLAY_INFO = 1, DISPLAY_INFO = 1,
DISPLAY_GPIO, DISPLAY_GPIO,
DUMPFIRMWARE DUMPFIRMWARE,
DUMPUSERSAVE,
DUMP_BOOT,
RESTORE_BOOT
}; };
enum formatmenu_return { enum formatmenu_return {
FORMAT_EMUMMC = 0, FORMAT_EMUMMC = 0,
FORMAT_ALL_FAT32 FORMAT_ALL_FAT32
}; };
*/
//menu_item mainmenu[MAINMENU_AMOUNT];
void te_main(); void te_main();

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,198 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "te.h"
#include "gfx.h"
#include "../utils/util.h"
#include "tools.h"
#include "fs.h"
#include "../utils/btn.h"
#include "emmc.h"
extern bool sd_mount();
extern void sd_unmount();
extern bool return_sd_mounted(int value);
extern int launch_payload(char *path);
menu_item mainmenu[MAINMENU_AMOUNT] = {
{"[SD:/] SD CARD\n", COLOR_GREEN, SD_CARD, 1},
{"[SYSTEM:/] EMMC", COLOR_ORANGE, EMMC_SYS, 1},
{"[USER:/] EMMC", COLOR_ORANGE, EMMC_USR, 1},
{"[SAFE:/] EMMC", COLOR_ORANGE, EMMC_SAF, 1},
{"\nMount/Unmount SD", COLOR_WHITE, MOUNT_SD, 1},
{"Tools", COLOR_VIOLET, TOOLS, 1},
{"SD format", COLOR_VIOLET, SD_FORMAT, 1},
{"\nCredits", COLOR_WHITE, CREDITS, 1},
{"Exit", COLOR_WHITE, EXIT, 1}
};
menu_item shutdownmenu[7] = {
{"-- EXIT --\n", COLOR_ORANGE, -1, 0},
{"Back", COLOR_WHITE, -1, 1},
{"\nReboot to RCM", COLOR_VIOLET, REBOOT_RCM, 1},
{"Reboot normally", COLOR_ORANGE, REBOOT_NORMAL, 1},
{"Power off\n", COLOR_BLUE, POWER_OFF, 1},
{"Reboot to Hekate", COLOR_GREEN, HEKATE, -1},
{"Reboot to Atmosphere", COLOR_GREEN, AMS, -1}
};
menu_item toolsmenu[5] = {
{"-- TOOLS --\n", COLOR_VIOLET, -1, 0},
{"Back", COLOR_WHITE, -1, 1},
{"\nDisplay Console Info", COLOR_GREEN, DISPLAY_INFO, 1},
{"Display GPIO pins", COLOR_VIOLET, DISPLAY_GPIO, 1},
{"Dump Firmware", COLOR_BLUE, DUMPFIRMWARE, 1}
};
menu_item formatmenu[4] = {
{"-- FORMAT SD --\n", COLOR_RED, -1, 0},
{"Back\n", COLOR_WHITE, -1, 1},
{"Format entire SD to FAT32", COLOR_RED, FORMAT_ALL_FAT32, 1},
{"Format for EmuMMC setup (FAT32/RAW)", COLOR_RED, FORMAT_EMUMMC, 1}
};
const char emmc_entries[3][8] = {
"SAFE",
"SYSTEM",
"USER"
};
void fillmainmenu(){
int i;
for (i = 0; i < MAINMENU_AMOUNT; i++){
switch (i + 1) {
case 1:
case 7:
if (return_sd_mounted(i + 1))
mainmenu[i].property = 1;
else
mainmenu[i].property = -1;
break;
case 5:
if (return_sd_mounted(1)){
mainmenu[i].property = 2;
strcpy(mainmenu[i].name, "\nUnmount SD");
}
else {
mainmenu[i].property = 1;
strcpy(mainmenu[i].name, "\nMount SD");
}
break;
}
}
}
void te_main(){
int res;
if (dump_biskeys() == -1){
message("Biskeys failed to dump!\nEmmc will not be mounted!", COLOR_RED);
mainmenu[1].property = -1;
mainmenu[2].property = -1;
mainmenu[3].property = -1;
}
while (1){
fillmainmenu();
res = makemenu(mainmenu, MAINMENU_AMOUNT);
switch(res){
case SD_CARD:
filemenu("SD:/");
break;
case EMMC_SAF:
case EMMC_SYS:
case EMMC_USR:
if (makewaitmenu("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", "Press Power to enter", 4)){
if (!mount_emmc(emmc_entries[res - 2], res - 1)){
filemenu("emmc:/");
}
else
message("EMMC failed to mount!", COLOR_RED);
}
break;
case MOUNT_SD:
if (return_sd_mounted(1))
sd_unmount();
else
sd_mount();
break;
case TOOLS:
res = makemenu(toolsmenu, 5);
switch(res){
case DISPLAY_INFO:
displayinfo();
break;
case DISPLAY_GPIO:
displaygpio();
break;
case DUMPFIRMWARE:
dumpfirmware();
break;
}
break;
case SD_FORMAT:
res = makemenu(formatmenu, 4);
if (res >= 0){
if(makewaitmenu("Are you sure you want to format your sd?\nThis will delete everything on your SD card\nThis action is irreversible!\n\nPress Vol+/- to cancel\n", "Press Power to continue", 10)){
if (format(res)){
sd_unmount();
}
}
}
break;
case CREDITS:
message(CREDITS_MESSAGE, COLOR_WHITE);
break;
case EXIT:
if (return_sd_mounted(1)){
if (checkfile("/bootloader/update.bin"))
shutdownmenu[5].property = 1;
else
shutdownmenu[5].property = -1;
if (checkfile("/atmosphere/reboot_payload.bin"))
shutdownmenu[6].property = 1;
else
shutdownmenu[6].property = -1;
}
else {
shutdownmenu[5].property = -1;
shutdownmenu[6].property = -1;
}
res = makemenu(shutdownmenu, 7);
switch(res){
case REBOOT_RCM:
reboot_rcm();
case REBOOT_NORMAL:
reboot_normal();
case POWER_OFF:
power_off();
case HEKATE:
launch_payload("/bootloader/update.bin");
case AMS:
launch_payload("/atmosphere/reboot_payload.bin");
} //todo declock bpmp
break;
}
}
}

View File

@@ -1,29 +1,35 @@
#include <string.h>
#include "tools.h" #include "tools.h"
#include "gfx.h" #include "../gfx/gfxutils.h"
#include "../libs/fatfs/ff.h" #include "../../libs/fatfs/ff.h"
#include "../gfx/gfx.h" #include "../../gfx/gfx.h"
#include "../utils/btn.h" #include "../../utils/btn.h"
#include "../soc/gpio.h" #include "../../soc/gpio.h"
#include "../utils/util.h" #include "../../utils/util.h"
#include "../utils/types.h" #include "../../utils/types.h"
#include "../libs/fatfs/diskio.h" #include "../../libs/fatfs/diskio.h"
#include "../storage/sdmmc.h" #include "../../storage/sdmmc.h"
#include "../utils/sprintf.h" #include "../../utils/sprintf.h"
#include "../soc/fuse.h" #include "../../soc/fuse.h"
#include "emmc.h" #include "../emmc/emmc.h"
#include "fs.h" #include "../common/common.h"
#include "../fs/fsactions.h"
#include "../fs/fsutils.h"
#include "../../mem/heap.h"
#include "../utils/utils.h"
extern bool sd_mount(); extern bool sd_mount();
extern void sd_unmount(); extern void sd_unmount();
extern sdmmc_storage_t sd_storage; extern sdmmc_storage_t sd_storage;
void displayinfo(){ void displayinfo(){
clearscreen(); gfx_clearscreen();
FATFS *fs; FATFS *fs;
DWORD fre_clust, fre_sect, tot_sect; DWORD fre_clust, fre_sect, tot_sect;
u32 capacity; u32 capacity;
u8 fuse_count = 0; u8 fuse_count = 0;
pkg1_info pkg1 = returnpkg1info();
int res; int res;
for (u32 i = 0; i < 32; i++){ for (u32 i = 0; i < 32; i++){
@@ -33,7 +39,12 @@ void displayinfo(){
SWAPCOLOR(COLOR_ORANGE); SWAPCOLOR(COLOR_ORANGE);
gfx_printf("Fuse count: %d\nPKG1 version: %d\n\n", fuse_count, returnpkg1ver()); 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;
@@ -65,7 +76,7 @@ void displayinfo(){
void displaygpio(){ void displaygpio(){
int res; int res;
clearscreen(); gfx_clearscreen();
gfx_printf("Updates gpio pins every 50ms:\nPress power to exit"); gfx_printf("Updates gpio pins every 50ms:\nPress power to exit");
msleep(200); msleep(200);
while (1){ while (1){
@@ -84,64 +95,96 @@ void displaygpio(){
} }
} }
int dumpfirmware(){ int dumpfirmware(int mmc){
DIR dir; DIR dir;
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] = ""; pkg1_info pkg1 = returnpkg1info();
char sdpath[100] = "";
short pkg1ver = returnpkg1ver();
u32 timer = get_tmr_s(); u32 timer = get_tmr_s();
clearscreen(); gfx_clearscreen();
mount_emmc("SYSTEM", 2); connect_mmc(mmc);
mount_mmc("SYSTEM", 2);
gfx_printf("PKG1 version: %d\n", pkg1ver); 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", pkg1ver); 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 = copy(syspath, sdpath, false); ret = fsact_copy(syspath, sdpath, 0);
gfx_printf("%d %s\r", ++amount, fno.fname); gfx_printf("%d %s\r", ++amount, fno.fname);
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){
connect_mmc(mmc);
mount_mmc("USER", 2);
gfx_clearscreen();
gfx_printf("Creating folders...\n");
f_mkdir("sd:/tegraexplorer");
gfx_printf("Starting dump...\n");
SWAPCOLOR(COLOR_GREEN);
if(fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer"))
return;
RESETCOLOR;
gfx_printf("\n\nSaves are located in SD:/tegraexplorer/save\n");
gfx_printf("Press any key to continue");
btn_wait();
}
int format(int mode){ int format(int mode){
clearscreen(); gfx_clearscreen();
int res; int res;
bool fatalerror = false; bool fatalerror = false;
DWORD plist[] = {666, 61145088}; DWORD plist[] = {666, 61145088};
@@ -152,12 +195,12 @@ int format(int mode){
formatoptions |= (FM_FAT32); formatoptions |= (FM_FAT32);
//formatoptions |= (FM_SFD); //formatoptions |= (FM_SFD);
disconnect_emmc(); disconnect_mmc();
timer = get_tmr_s(); timer = get_tmr_s();
totalsectors = sd_storage.csd.capacity; totalsectors = sd_storage.csd.capacity;
if (mode == 0){ if (mode == FORMAT_EMUMMC){
if (totalsectors < 83886080){ if (totalsectors < 83886080){
gfx_printf("%kYou seem to be running this on a <=32GB SD\nNot enough free space for emummc!", COLOR_RED); gfx_printf("%kYou seem to be running this on a <=32GB SD\nNot enough free space for emummc!", COLOR_RED);
fatalerror = true; fatalerror = true;
@@ -210,8 +253,7 @@ int format(int mode){
} }
} }
dump_biskeys(); connect_mmc(SYSMMC);
mount_emmc("SYSTEM", 2);
gfx_printf("\nPress any button to return%k\nTotal time taken: %ds", COLOR_WHITE, (get_tmr_s() - timer)); gfx_printf("\nPress any button to return%k\nTotal time taken: %ds", COLOR_WHITE, (get_tmr_s() - timer));
btn_wait(); btn_wait();

View File

@@ -3,4 +3,5 @@
void displayinfo(); void displayinfo();
void displaygpio(); void displaygpio();
int format(int mode); int format(int mode);
int dumpfirmware(); int dumpfirmware(int mmc);
void dumpusersaves(int mmc);

View File

@@ -0,0 +1,19 @@
#include <string.h>
#include "utils.h"
#include "../common/common.h"
#include "../gfx/menu.h"
#include "../../storage/emummc.h"
#include "../../mem/heap.h"
int utils_mmcMenu(){
if (emu_cfg.enabled)
return menu_make(utils_mmcChoice, 3, "-- Choose MMC --");
else
return SYSMMC;
}
void utils_copystring(const char *in, char **out){
int len = strlen(in) + 1;
*out = (char *) malloc (len);
strcpy(*out, in);
}

View File

@@ -0,0 +1,4 @@
#pragma once
int utils_mmcMenu();
void utils_copystring(const char *in, char **out);

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