Compare commits

..

34 Commits

Author SHA1 Message Date
CTCaer
a4c90aeff3 Bump hekate to v5.1.4 and Nyx to v0.8.7 2020-04-14 21:34:59 +03:00
CTCaer
bfe13981bc Disable some options from TUI to lessen codesize v2 2020-04-14 18:11:34 +03:00
CTCaer
ef11dd883a Allow bypassing empty battery charging 2020-04-14 17:55:31 +03:00
CTCaer
da149c296f touch: Reinitialize up to 3 times if failed 2020-04-14 17:52:22 +03:00
CTCaer
9af4c717a8 util: Add btn_read_vol 2020-04-14 17:51:42 +03:00
CTCaer
281e5a138e sept: Create sept folder if missing 2020-04-14 17:45:34 +03:00
CTCaer
e7f8b2c6c2 hos: Add HOS 10.0.0 support 2020-04-14 17:43:43 +03:00
CTCaer
3d9c64d548 hos: Use a new method to get kernel/ini1 offsets 2020-04-14 17:40:41 +03:00
CTCaer
5f142b4c86 main: Add empty battery screen
This disables low battery monitor shutdown (LBM shutdown) on boot and checks if battery is enough.

The logic is as follows:

If battery is not enough:
- If not charging and 15s pass, it will re enable LBM shutdown and power off.
- If charging, it will wait until it is charged above the limit.
 Screen will auto turn off to save power. A press on Power button or a change on charger, will enable it for another 15s.

If battery is enough:
- Enables LBM shutdown and continues with the boot process.
2020-04-06 05:54:45 +03:00
CTCaer
52c506af9a tools: Force sparse verification on TUI
Additionally, because the tool relies 100% on sd card, it will become a Nyx only. Remove the config also, as it will be moved to nyx configuration.
2020-04-06 05:36:09 +03:00
CTCaer
dc9c7fd95c touch: Do a panel HW test before calibration
In case the panel or the panel connection has issues, abort the calibration.
2020-03-25 01:38:16 +02:00
CTCaer
4ec7befe82 touch: Small refactor 2020-03-25 01:31:58 +02:00
CTCaer
dd4dd91152 makefile: Show a warning when binary exceeds limits 2020-03-24 20:06:10 +02:00
CTCaer
a39ba2cd71 lvgl: Fix edge case in lv_label_set_text
This fixes an edge case where the original label set was done with set_static_text, the next one with set_text and the text is at the same address.

The incomplete check would think that the text resides on heap and it would reallocate it as such, effectively corrupting .data on the next sets.
2020-03-22 04:48:50 +02:00
CTCaer
9c2202fa39 Bump hekate to v5.1.3 and Nyx to v0.8.6 2020-03-21 22:30:39 +02:00
CTCaer
9c6931a17c Bugfixes
The fan driver change ensures power off in any situation where a chainload software re-enables the 5V regulator.
2020-03-21 22:28:50 +02:00
CTCaer
976925c697 nyx: Allow cancellation of emuMMC creation 2020-03-21 22:27:17 +02:00
CTCaer
d50af46b03 chnldr: Support variable sizes of coreboot.rom 2020-03-21 22:18:40 +02:00
CTCaer
3405910f4c hwinit: Disable SD Card power on boot
Fixes issues with warmboot based reboots.
2020-03-21 22:13:18 +02:00
CTCaer
52874f9113 minerva: More protections 2020-03-21 22:10:06 +02:00
CTCaer
91a241dafa touch: Add Tuning Calibration
This, for now, can be done at Nyx boot by holding VOL- and VOL+.

Make sure that you don't touch the touchscreen.
2020-03-21 22:03:51 +02:00
CTCaer
a8db070755 fss: Fix launching CFW on sys for < 7.0.0 2020-03-21 13:15:24 +02:00
CTCaer
76676f3a2e nyx: Allow for big filepaths for archive bit fixer
It also fixes corruptions/hangs when path is bigger than 255 chars
2020-03-18 06:30:11 +02:00
CTCaer
f5040f1e41 Update and add missing copyrights
Probably more need to change.
2020-03-14 09:24:24 +02:00
CTCaer
c9c3c8f716 touch: Add context based ready checks on init 2020-03-13 17:36:44 +02:00
CTCaer
144d6fd3f6 i2c: Update drivers
Adds support for 8 byte transfers needed by touch driver changes.
2020-03-13 10:25:27 +02:00
CTCaer
9697067466 touch: Add fw info 2020-03-13 08:48:20 +02:00
CTCaer
8539095bdb touch: Proper init
This patch applies the simpler init from HOS driver.

The most important change is enabling a feature that the fw supports:
Automatic tuning and calibration based on saved tuning values (running HOS only once saves these).
2020-03-13 08:39:38 +02:00
CTCaer
95e3159fe9 touch: Correct pressure calculation
Fingertip S for Nintendo Switch uses a custom spatial calculation. It now allows to identify area of touch.
2020-03-13 08:34:16 +02:00
CTCaer
8b74c487eb exo: Add support for fatal version AFE2 2020-03-09 09:09:25 +02:00
CTCaer
8abda7f259 fss0: Support experimental content
Use key `fss0experimental=1` in a boot entry with `fss0=` defined to enable experimental content.

(Older versions of hekate will just skip any experimental content.)
2020-03-09 08:58:12 +02:00
CTCaer
8d5c52f087 lvgl heap: Fix critical issue with node header size
This fixes a critical issue where the node header was 28 bytes instead of 32, causing misalignment and heap corruption.
2020-03-09 08:39:31 +02:00
CTCaer
e6c1d9bf66 nyx: Simplify label sets
- Use only lv_label_set_text to simplify label sets
- Fix an issue with a label cut
- Add more maintenance functions for DRAM training
2020-03-09 08:37:41 +02:00
CTCaer
a52af1bf41 Fix building on make 4.3 2020-03-04 01:34:35 +02:00
84 changed files with 1020 additions and 405 deletions

View File

@@ -16,7 +16,7 @@ TARGET := hekate
BUILDDIR := build
OUTPUTDIR := output
SOURCEDIR = bootloader
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
VPATH = $(dir ./$(SOURCEDIR)/) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
# Main and graphics.
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
@@ -78,8 +78,10 @@ NYXDIR := $(wildcard nyx)
all: $(TARGET).bin
@echo -n "Payload size is "
@wc -c < $(OUTPUTDIR)/$(TARGET).bin
@echo "Max size is 126296 Bytes."
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
@echo $(BIN_SIZE)
@echo "Max size is 126296 Bytes."
@if [ ${BIN_SIZE} -gt 126296 ]; then echo "\e[1;33mPayload size exceeds limit!\e[0m"; fi
clean:
@rm -rf $(OBJS)
@@ -103,7 +105,11 @@ $(BUILDDIR)/$(TARGET)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(BUILDDIR)/$(TARGET)/%.o: %.S
$(CC) $(CFLAGS) -c $< -o $@
$(OBJS): $(BUILDDIR)/$(TARGET)
$(BUILDDIR)/$(TARGET):
@mkdir -p "$(BUILDDIR)"
@mkdir -p "$(BUILDDIR)/$(TARGET)"
@mkdir -p "$(OUTPUTDIR)"
$(CC) $(CFLAGS) -c $< -o $@

View File

@@ -70,6 +70,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. kips, exosphere, warmboot and sept. |
| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
| fullsvcperm=1 | Disables SVC verification (full services permission) |
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |

View File

@@ -1,11 +1,11 @@
# IPL Version.
BLVERSION_MAJOR := 5
BLVERSION_MINOR := 1
BLVERSION_HOTFX := 2
BLVERSION_HOTFX := 4
BLVERSION_RSVD := 0
# Nyx Version.
NYXVERSION_MAJOR := 0
NYXVERSION_MINOR := 8
NYXVERSION_HOTFX := 5
NYXVERSION_HOTFX := 7
NYXVERSION_RSVD := 0

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
* under the terms and conditions of the GNU General Public License,
@@ -37,7 +37,6 @@ void set_default_configuration()
h_cfg.autoboot = 0;
h_cfg.autoboot_list = 0;
h_cfg.bootwait = 3;
h_cfg.verification = 1;
h_cfg.se_keygen_done = 0;
h_cfg.sbar_time_keeping = 0;
h_cfg.backlight = 100;
@@ -97,9 +96,6 @@ int create_config_entry()
f_puts("\nbootwait=", &fp);
itoa(h_cfg.bootwait, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nverification=", &fp);
itoa(h_cfg.verification, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nbacklight=", &fp);
itoa(h_cfg.backlight, lbuf, 10);
f_puts(lbuf, &fp);
@@ -451,61 +447,6 @@ void config_bootdelay()
btn_wait();
}
void config_verification()
{
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
u32 vr_text_size = 64;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
u32 *vr_values = (u32 *)malloc(sizeof(u32) * 3);
char *vr_text = (char *)malloc(vr_text_size * 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[vr_text_size * i] = ' ';
else
vr_text[vr_text_size * i] = '*';
ments[2 + i].caption = vr_text + (i * vr_text_size);
}
memset(&ments[5], 0, sizeof(ment_t));
menu_t menu = {ments, "Backup & Restore verification", 0, 0};
u32 *temp_verification = (u32 *)tui_do_menu(&menu);
if (temp_verification != NULL)
{
h_cfg.verification = *(u32 *)temp_verification;
_save_config();
}
free(ments);
free(vr_values);
free(vr_text);
if (temp_verification == NULL)
return;
btn_wait();
}
void config_backlight()
{
gfx_clear_grey(0x1B);

View File

@@ -25,7 +25,6 @@ typedef struct _hekate_config
u32 autoboot;
u32 autoboot_list;
u32 bootwait;
u32 verification;
u32 backlight;
u32 autohosoff;
u32 autonogc;
@@ -45,7 +44,6 @@ void set_default_configuration();
int create_config_entry();
void config_autoboot();
void config_bootdelay();
void config_verification();
void config_backlight();
void config_auto_hos_poweroff();
void config_nogc();

View File

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

View File

@@ -78,7 +78,7 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi
// Check every time or every 4.
// Every 4 protects from fake sd, sector corruption and frequent I/O corruption.
// Full provides all that, plus protection from extremely rare I/O corruption.
if ((h_cfg.verification >= 2) || !(sparseShouldVerify % 4))
if (!(sparseShouldVerify % 4))
{
if (!sdmmc_storage_read(storage, lba_curr, num, bufEm))
{
@@ -307,15 +307,12 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
memset(&fp, 0, sizeof(fp));
currPartIdx++;
if (h_cfg.verification)
// Verify part.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
// Verify part.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again...\n");
return 0;
}
return 0;
}
_update_filename(outFilename, sdPathLen, numSplitParts, currPartIdx);
@@ -441,18 +438,15 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t
// Backup operation ended successfully.
f_close(&fp);
if (h_cfg.verification)
// Verify last part or single file backup.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
// Verify last part or single file backup.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again...\n");
return 0;
}
else
tui_pbar(0, gfx_con.y, 100, 0xFF96FF00, 0xFF155500);
return 0;
}
else
tui_pbar(0, gfx_con.y, 100, 0xFF96FF00, 0xFF155500);
gfx_con.fntsz = 16;
// Remove partial backup index file if no fatal errors occurred.
@@ -580,10 +574,8 @@ static void _dump_emmc_selected(emmcPartType_t dumpType)
timer = get_tmr_s() - timer;
gfx_printf("Time taken: %dm %ds.\n", timer / 60, timer % 60);
sdmmc_storage_end(&storage);
if (res && h_cfg.verification)
if (res)
gfx_printf("\n%kFinished and verified!%k\nPress any key...\n", 0xFF96FF00, 0xFFCCCCCC);
else if (res)
gfx_printf("\nFinished! Press any key...\n");
out:
sd_unmount();
@@ -713,15 +705,12 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
memset(&fp, 0, sizeof(fp));
currPartIdx++;
if (h_cfg.verification)
// Verify part.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
// Verify part.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again...\n");
return 0;
}
return 0;
}
_update_filename(outFilename, sdPathLen, numSplitParts, currPartIdx);
@@ -791,18 +780,15 @@ static int _restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part
// Restore operation ended successfully.
f_close(&fp);
if (h_cfg.verification)
// Verify restored data.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
// Verify restored data.
if (_dump_emmc_verify(storage, lbaStartPart, outFilename, part))
{
EPRINTF("\nPress any key and try again...\n");
EPRINTF("\nPress any key and try again...\n");
return 0;
}
else
tui_pbar(0, gfx_con.y, 100, 0xFF96FF00, 0xFF155500);
return 0;
}
else
tui_pbar(0, gfx_con.y, 100, 0xFF96FF00, 0xFF155500);
gfx_con.fntsz = 16;
gfx_puts("\n\n");
@@ -925,10 +911,8 @@ static void _restore_emmc_selected(emmcPartType_t restoreType)
timer = get_tmr_s() - timer;
gfx_printf("Time taken: %dm %ds.\n", timer / 60, timer % 60);
sdmmc_storage_end(&storage);
if (res && h_cfg.verification)
if (res)
gfx_printf("\n%kFinished and verified!%k\nPress any key...\n", 0xFF96FF00, 0xFFCCCCCC);
else if (res)
gfx_printf("\nFinished! Press any key...\n");
out:
sd_unmount();

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it

View File

@@ -223,9 +223,17 @@ void dump_packages12()
ini1_off = pkg2_newkern_ini1_start;
ini1_size = pkg2_newkern_ini1_end - pkg2_newkern_ini1_start;
}
if (sd_save_to_file(pkg2_hdr->data + ini1_off, ini1_size, path))
if (ini1_off)
{
if (sd_save_to_file(pkg2_hdr->data + ini1_off, ini1_size, path))
goto out;
gfx_puts("INI1 dumped to ini1.bin\n");
}
else
{
gfx_puts("Failed to dump INI1!\n");
goto out;
gfx_puts("INI1 dumped to ini1.bin\n");
}
gfx_puts("\nDone. Press any key...\n");

View File

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

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 M4xw
*
* This program is free software; you can redistribute it and/or modify it

View File

@@ -477,4 +477,61 @@ static u8 BOOTLOGO_BLZ[SZ_BOOTLOGO_BLZ] = {
0x6C, 0x23, 0x00, 0x00
};
// 21 x 50 @8bpp RGB.
#define X_BATTERY_EMPTY 21
#define Y_BATTERY_EMPTY_BATT 38
#define Y_BATTERY_EMPTY_CHRG 12
#define SZ_BATTERY_EMPTY 3150
#define SZ_BATTERY_EMPTY_BLZ 740
static u8 BATTERY_EMPTY_BLZ[SZ_BATTERY_EMPTY_BLZ] =
{
0x17, 0xC0, 0x5D, 0x51, 0x79, 0x12, 0x79, 0x48, 0x69, 0x00, 0x0D, 0x46, 0xE3, 0x0F, 0xF0, 0x20,
0xF0, 0x35, 0x2E, 0x38, 0x3F, 0x40, 0xEF, 0xCF, 0x00, 0x89, 0x77, 0x00, 0x17, 0x01, 0x14, 0x09,
0x90, 0x36, 0xF0, 0xA4, 0xF1, 0x62, 0x01, 0x38, 0xA1, 0x99, 0x84, 0x3E, 0x00, 0x23, 0x1F, 0x04,
0x40, 0x3B, 0xF0, 0x5B, 0x4F, 0x00, 0x18, 0x25, 0x20, 0x24, 0x90, 0x57, 0x00, 0x3C, 0xC0, 0x7B,
0x00, 0x63, 0x10, 0x31, 0x7C, 0x2B, 0x03, 0x30, 0x3C, 0xF0, 0xA2, 0x00, 0xCE, 0x11, 0x0F, 0x0D,
0x21, 0x00, 0x9E, 0xDE, 0x00, 0x06, 0x40, 0x60, 0xF0, 0xB9, 0xA0, 0xEA, 0x70, 0x3C, 0xF0, 0xF5,
0x67, 0xD4, 0x3E, 0x01, 0x54, 0x00, 0x00, 0x00, 0x57, 0x70, 0xCD, 0xB1, 0x00, 0x1E, 0xFB, 0xD9,
0x15, 0xA0, 0xC9, 0xAE, 0x69, 0x30, 0x3C, 0xD0, 0x30, 0xF0, 0xE4, 0xC1, 0xA7, 0x18, 0x10, 0x0D,
0x0C, 0x00, 0x49, 0x3F, 0x04, 0x00, 0x87, 0x75, 0x00, 0xC5, 0xAA, 0x2A, 0x00, 0x09, 0x40, 0xC0,
0xD7, 0xBA, 0x24, 0x00, 0x0C, 0xA0, 0x33, 0xF0, 0xF7, 0xD6, 0x0C, 0x00, 0x9C, 0x3C, 0xA0, 0x07,
0x06, 0x2A, 0x10, 0x7D, 0x6C, 0x00, 0xBB, 0x09, 0xA2, 0x00, 0xF3, 0xD2, 0x00, 0xE3, 0xC4, 0x0C,
0xA0, 0x80, 0x3C, 0xF0, 0x41, 0x38, 0x05, 0x50, 0x3E, 0xF1, 0x03, 0x00, 0x01, 0x19, 0x01, 0x00,
0x33, 0x2C, 0x00, 0x71, 0x62, 0x00, 0x00, 0xAF, 0x97, 0x00, 0xEB, 0xCB, 0x03, 0x30, 0x03, 0x30,
0x3C, 0x40, 0xE0, 0x81, 0x70, 0x04, 0x40, 0x0F, 0xF0, 0x23, 0xF0, 0x2D, 0x27, 0x00, 0x1C, 0x6B,
0x5D, 0x00, 0xA9, 0x92, 0x00, 0xE7, 0xC8, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xDC, 0x00, 0xBF, 0xA5,
0x0E, 0xE0, 0x81, 0x0F, 0xF0, 0x19, 0xF0, 0xA5, 0x00, 0x22, 0x00, 0x65, 0x58, 0x00, 0x07, 0x67,
0x59, 0x07, 0x70, 0x0F, 0xF0, 0x2A, 0xF0, 0x06, 0x09, 0x45, 0x10, 0x3C, 0x0A, 0x00, 0x00, 0x03,
0x30, 0x00, 0x00, 0x49, 0x11, 0x0B, 0x47, 0x0E, 0x10, 0x0B, 0x1B, 0x06, 0x04, 0x3F, 0xF0, 0xD2,
0xF0, 0xCD, 0x38, 0xE0, 0x85, 0xF8, 0xF7, 0x3A, 0x26, 0x75, 0x00, 0xD2, 0xF0, 0x33, 0x00, 0x27,
0x71, 0x09, 0x06, 0x24, 0x30, 0xBD, 0x2C, 0x1D, 0x15, 0x00, 0xDB, 0x44, 0x33, 0x22, 0x00, 0x00,
0x03, 0x30, 0x00, 0x00, 0x57, 0x00, 0x5D, 0x00, 0x18, 0x00, 0xFC, 0xC7, 0x2E, 0x1F, 0x00, 0x00,
0x45, 0x00, 0x29, 0x09, 0x06, 0x18, 0x89, 0x30, 0x2F, 0x0B, 0x07, 0xDF, 0x34, 0x23, 0x21, 0xC0,
0x81, 0x59, 0x15, 0x0E, 0x3C, 0xC0, 0x2A, 0x00, 0xF5, 0xC7, 0xE1, 0x34, 0x38, 0x23, 0x31, 0x0B,
0x07, 0xC9, 0x2F, 0x1F, 0x33, 0x00, 0x80, 0x2D, 0x00, 0x1E, 0x90, 0x4D, 0x12, 0x0C, 0x2D, 0xC0,
0x41, 0x0F, 0x23, 0x0A, 0x03, 0x30, 0x00, 0x00, 0xD9, 0x33, 0x22, 0xE7, 0x36, 0x06, 0x24, 0x06,
0x00, 0xCB, 0x2F, 0x1F, 0x39, 0x30, 0x15, 0x05, 0x22, 0x03, 0x06, 0x60, 0x0F, 0xF0, 0x21, 0xF0,
0x0F, 0x03, 0x02, 0x03, 0x00, 0x8E, 0xF9, 0x3A, 0x3C, 0xA0, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0,
0x3C, 0xF0, 0x30, 0xF0, 0xFC, 0x3C, 0xF0, 0x3C, 0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C,
0xF0, 0x30, 0xF0, 0x3C, 0xF0, 0xFF, 0x3C, 0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0,
0x30, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0xFF, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30,
0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x0F, 0xF0, 0xFF, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0,
0x3C, 0xF0, 0x3C, 0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0xFF, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0x3C,
0xF0, 0x3C, 0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0xFF, 0x3C, 0xF0, 0x30, 0xF0, 0x3C, 0xF0,
0x3C, 0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0xFF, 0x30, 0xF0, 0x3C, 0xF0, 0x3C,
0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0xFF, 0x3C, 0xF0, 0x3C, 0xF0,
0x0F, 0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0x3C, 0xF0, 0xFF, 0x3C, 0xF0, 0x0F,
0xF0, 0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0xFF, 0x0F, 0xF0,
0x27, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x0F, 0xF0, 0xFF, 0x27,
0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x0F, 0xF0, 0x27, 0xF0, 0xFF,
0x3C, 0xF0, 0x3C, 0xF0, 0x30, 0xF0, 0x3C, 0xF0, 0x84, 0x90, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0xF0,
0xFF, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x07, 0x01, 0xB1, 0x40,
0x81, 0x20, 0x33, 0x0C, 0x08, 0x00, 0x00, 0x0F, 0xF0, 0xC6, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00,
0x0D, 0x03, 0x02, 0x2D, 0x0A, 0x07, 0x07, 0x75, 0x30, 0x39, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x0F,
0xF0, 0x1B, 0xF0, 0x03, 0x00, 0xFE, 0x39, 0x00, 0xB1, 0x29, 0x1B, 0xF3, 0x39, 0x26, 0x00, 0x00,
0x81, 0x0F, 0xF0, 0x09, 0x90, 0x03, 0x30, 0x00, 0x00, 0xFE, 0x3B, 0x27, 0xF5, 0x0F, 0x39, 0x26,
0xB3, 0x2A, 0x1C, 0x17, 0x05, 0x03, 0x00, 0xFF, 0xE4, 0x02, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x6A, 0x09, 0x00, 0x00
};
#endif

View File

@@ -1,7 +1,7 @@
/*
* Atmosphère Fusée Secondary Storage parser.
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -43,6 +43,10 @@ extern bool is_ipl_updated(void *buf, char *path, bool force);
#define CNT_TYPE_KIP 6
#define CNT_TYPE_BMP 7
#define CNT_TYPE_EMC 8
#define CNT_TYPE_KLD 9
#define CNT_TYPE_KRN 10
#define CNT_FLAG0_EXPERIMENTAL (1 << 0)
typedef struct _fss_t
{
@@ -60,7 +64,10 @@ typedef struct _fss_content_t
{
u32 offset;
u32 size;
u32 type;
u8 type;
u8 flags0;
u8 flags1;
u8 flags2;
u32 rsvd1;
char name[0x10];
} fss_content_t;
@@ -106,7 +113,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
stock = true;
}
if (ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
return 1;
}
@@ -142,6 +149,9 @@ int parse_fss(launch_ctxt_t *ctxt, const char *path, fss0_sept_t *sept_ctxt)
if ((curr_fss_cnt[i].offset + curr_fss_cnt[i].size) > fss_meta->size)
continue;
if ((curr_fss_cnt[i].flags0 & CNT_FLAG0_EXPERIMENTAL) && !ctxt->fss0_enable_experimental)
continue;
// Load content to launch context.
if (!sept_ctxt)
{

View File

@@ -581,7 +581,11 @@ int hos_launch(ini_sec_t *cfg)
}
LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2);
if (!pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2))
{
_hos_crit_error("INI1 parsing failed!");
return 0;
}
gfx_printf("Parsed ini1\n");

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -67,6 +68,7 @@ typedef struct _launch_ctxt_t
bool atmosphere;
bool exo_no_user_exceptions;
bool exo_user_pmu;
bool fss0_enable_experimental;
bool emuMMC;
ini_sec_t *cfg;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -213,6 +213,15 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
static int _config_fss(launch_ctxt_t *ctxt, const char *value)
{
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ctxt->cfg->kvs, link)
{
if (!strcmp("fss0experimental", kv->key))
{
ctxt->fss0_enable_experimental = *kv->val == '1';
break;
}
}
return parse_fss(ctxt, value, NULL);
}

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -148,6 +148,7 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.1.0
{ "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.0.0 - 9.0.1
{ "20191021113848", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //9.1.0
{ "20200303104606", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //10.0.0
{ NULL } //End.
};

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
@@ -23,12 +23,12 @@
#include "pkg2_ini_kippatch.h"
#include "../config/config.h"
#include "../libs/compr/blz.h"
#include "../libs/fatfs/ff.h"
#include "../utils/aarch64_util.h"
#include "../mem/heap.h"
#include "../sec/se.h"
#include "../storage/emummc.h"
#include "../libs/compr/blz.h"
#include "../utils/aarch64_util.h"
#include "../gfx/gfx.h"
@@ -49,38 +49,41 @@ extern void *sd_file_read(const char *path, u32 *fsize);
//TODO: Reduce hardcoded values without searching kernel for patterns?
// The process ID send/receive kernel patches were taken from Atmosphère's kernel patches.
// They should only be used when running Atmosphère.
#define FREE_CODE_OFF_1ST_100 0x4797C
#define FREE_CODE_OFF_1ST_200 0x6486C
#define FREE_CODE_OFF_1ST_300 0x494A4
#define FREE_CODE_OFF_1ST_302 0x494BC
#define FREE_CODE_OFF_1ST_400 0x52890
#define FREE_CODE_OFF_1ST_500 0x5C020
#define FREE_CODE_OFF_1ST_600 0x5EE00
#define FREE_CODE_OFF_1ST_700 0x5FEC0
#define FREE_CODE_OFF_1ST_800 0x607F0
#define FREE_CODE_OFF_1ST_900 0x65780
#define FREE_CODE_OFF_1ST_100 0x4797C
#define FREE_CODE_OFF_1ST_200 0x6486C
#define FREE_CODE_OFF_1ST_300 0x494A4
#define FREE_CODE_OFF_1ST_302 0x494BC
#define FREE_CODE_OFF_1ST_400 0x52890
#define FREE_CODE_OFF_1ST_500 0x5C020
#define FREE_CODE_OFF_1ST_600 0x5EE00
#define FREE_CODE_OFF_1ST_700 0x5FEC0
#define FREE_CODE_OFF_1ST_800 0x607F0
#define FREE_CODE_OFF_1ST_900 0x65780
#define FREE_CODE_OFF_1ST_1000 0x67790
#define ID_SND_OFF_100 0x23CC0
#define ID_SND_OFF_200 0x3F134
#define ID_SND_OFF_300 0x26080
#define ID_SND_OFF_302 0x26080
#define ID_SND_OFF_400 0x2AF64
#define ID_SND_OFF_500 0x2AD34
#define ID_SND_OFF_600 0x2BB8C
#define ID_SND_OFF_700 0x2D044
#define ID_SND_OFF_800 0x2F1FC
#define ID_SND_OFF_900 0x329A0
#define ID_SND_OFF_100 0x23CC0
#define ID_SND_OFF_200 0x3F134
#define ID_SND_OFF_300 0x26080
#define ID_SND_OFF_302 0x26080
#define ID_SND_OFF_400 0x2AF64
#define ID_SND_OFF_500 0x2AD34
#define ID_SND_OFF_600 0x2BB8C
#define ID_SND_OFF_700 0x2D044
#define ID_SND_OFF_800 0x2F1FC
#define ID_SND_OFF_900 0x329A0
#define ID_SND_OFF_1000 0x34404
#define ID_RCV_OFF_100 0x219F0
#define ID_RCV_OFF_200 0x3D1A8
#define ID_RCV_OFF_300 0x240F0
#define ID_RCV_OFF_302 0x240F0
#define ID_RCV_OFF_400 0x28F6C
#define ID_RCV_OFF_500 0x28DAC
#define ID_RCV_OFF_600 0x29B6C
#define ID_RCV_OFF_700 0x2B23C
#define ID_RCV_OFF_800 0x2D424
#define ID_RCV_OFF_900 0x309B4
#define ID_RCV_OFF_100 0x219F0
#define ID_RCV_OFF_200 0x3D1A8
#define ID_RCV_OFF_300 0x240F0
#define ID_RCV_OFF_302 0x240F0
#define ID_RCV_OFF_400 0x28F6C
#define ID_RCV_OFF_500 0x28DAC
#define ID_RCV_OFF_600 0x29B6C
#define ID_RCV_OFF_700 0x2B23C
#define ID_RCV_OFF_800 0x2D424
#define ID_RCV_OFF_900 0x309B4
#define ID_RCV_OFF_1000 0x322F8
static u32 PRC_ID_SND_100[] =
{
@@ -188,6 +191,20 @@ static u32 PRC_ID_RCV_900[] =
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
static u32 PRC_ID_SND_1000[] =
{
0xA9BF2FEA, 0xF94063EB, 0x2A1603EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002E8, 0xF9401D08, 0xAA1703E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
#define FREE_CODE_OFF_2ND_1000 (FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000) + sizeof(u32))
static u32 PRC_ID_RCV_1000[] =
{
0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9,
0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0,
0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0
};
// Include kernel patches here, so we can utilize pkg1 id
KERNEL_PATCHSET_DEF(_kernel_1_patchset,
{ SVC_VERIFY_DS, 0x3764C, _NOP(), NULL }, // Disable SVC verifications
@@ -339,6 +356,22 @@ KERNEL_PATCHSET_DEF(_kernel_9_patchset,
_B(FREE_CODE_OFF_2ND_900 + sizeof(PRC_ID_RCV_900), ID_RCV_OFF_900 + sizeof(u32) * 4), NULL}
);
KERNEL_PATCHSET_DEF(_kernel_10_patchset,
{ SVC_GENERIC, 0x45DAC, _NOP(), NULL }, // Allow same process on svcControlCodeMemory.
{ SVC_VERIFY_DS, 0x523E4, _NOP(), NULL }, // Disable SVC verifications.
{ DEBUG_MODE_EN, 0x62B14, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch.
// Atmosphère kernel patches.
{ ATM_SYSM_INCR, 0x66950, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
{ ATM_GEN_PATCH, ID_SND_OFF_1000, _B(ID_SND_OFF_1000, FREE_CODE_OFF_1ST_1000), NULL}, // Send process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_1000, sizeof(PRC_ID_SND_1000) >> 2, PRC_ID_SND_1000}, // Send process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_1ST_1000 + sizeof(PRC_ID_SND_1000), ID_SND_OFF_1000 + sizeof(u32) * 4), NULL},
{ ATM_GEN_PATCH, ID_RCV_OFF_1000, _B(ID_RCV_OFF_1000, FREE_CODE_OFF_2ND_1000), NULL}, // Receive process id branch.
{ ATM_ARR_PATCH, FREE_CODE_OFF_2ND_1000, sizeof(PRC_ID_RCV_1000) >> 2, PRC_ID_RCV_1000}, // Receive process id code.
{ ATM_GEN_PATCH, FREE_CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), // Branch back and skip 4 instructions.
_B(FREE_CODE_OFF_2ND_1000 + sizeof(PRC_ID_RCV_1000), ID_RCV_OFF_1000 + sizeof(u32) * 4), NULL}
);
// Kernel sha256 hashes.
static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
{
@@ -353,6 +386,7 @@ static const pkg2_kernel_id_t _pkg2_kernel_ids[] =
{ "\xf1\x5e\xc8\x34\xfd\x68\xf0\xf0", _kernel_8_patchset }, //8.0.0 - 8.1.0. Kernel only.
{ "\x69\x00\x39\xdf\x21\x56\x70\x6b", _kernel_9_patchset }, //9.0.0 - 9.1.0. Kernel only.
{ "\xa2\xe3\xad\x1c\x98\xd8\x7a\x62", _kernel_9_patchset }, //9.2.0. Kernel only.
{ "\x21\xc1\xd7\x24\x8e\xcd\xbd\xa8", _kernel_10_patchset }, //10.0.0. Kernel only.
};
enum kip_offset_section
@@ -553,6 +587,20 @@ static kip1_patchset_t _fs_patches_910[] =
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1000[] =
{
{ KPS(KIP_TEXT) | 0x13BE90, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x14DE08, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1000[] =
{
{ "nogc", _fs_nogc_1000 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
// SHA256 hashes.
static kip1_id_t _kip_ids[] =
{
@@ -587,7 +635,9 @@ static kip1_id_t _kip_ids[] =
{ "FS", "\x46\x87\x40\x76\x1E\x19\x3E\xB7", _fs_patches_900 }, // FS 9.0.0
{ "FS", "\x7C\x95\x13\x76\xE5\xC1\x2D\xF8", _fs_patches_900 }, // FS 9.0.0 exfat
{ "FS", "\xB5\xE7\xA6\x4C\x6F\x5C\x4F\xE3", _fs_patches_910 }, // FS 9.1.0
{ "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 } // FS 9.1.0 exfat
{ "FS", "\xF1\x96\xD1\x44\xD0\x44\x45\xB6", _fs_patches_910 }, // FS 9.1.0 exfat
{ "FS", "\x3E\xEB\xD9\xB7\xBC\xD1\xB5\xE0", _fs_patches_1000 }, // FS 10.0.0
{ "FS", "\x81\x7E\xA2\xB0\xB7\x02\xC1\xF3", _fs_patches_1000 }, // FS 10.0.0 exfat
};
static void parse_external_kip_patches()
@@ -692,14 +742,34 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
void pkg2_get_newkern_info(u8 *kern_data)
{
u32 info_op = *(u32 *)(kern_data + PKG2_NEWKERN_GET_INI1);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + PKG2_NEWKERN_GET_INI1; // Parse ADR and PC.
u32 pkg2_newkern_ini1_off = 0;
pkg2_newkern_ini1_start = 0;
// Find static OP offset that is close to INI1 offset.
u32 counter_ops = 0x100;
while (counter_ops)
{
if (*(u32 *)(kern_data + 0x100 - counter_ops) == PKG2_NEWKERN_GET_INI1_HEURISTIC)
{
pkg2_newkern_ini1_off = 0x100 - counter_ops + 12; // OP found. Add 12 for the INI1 offset.
break;
}
counter_ops -= 4;
}
// Offset not found?
if (!counter_ops)
return;
u32 info_op = *(u32 *)(kern_data + pkg2_newkern_ini1_off);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + pkg2_newkern_ini1_off; // Parse ADR and PC.
pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val);
pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8);
}
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{
u8 *ptr;
// Check for new pkg2 type.
@@ -707,6 +777,9 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{
pkg2_get_newkern_info(pkg2->data);
if (!pkg2_newkern_ini1_start)
return false;
ptr = pkg2->data + pkg2_newkern_ini1_start;
*new_pkg2 = true;
}
@@ -726,6 +799,8 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
ptr += ki->size;
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
}
return true;
}
int pkg2_has_kip(link_t *info, u64 tid)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -27,7 +27,7 @@
#define PKG2_SEC_INI1 1
#define INI1_MAGIC 0x31494E49
#define PKG2_NEWKERN_GET_INI1 0x44
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
#define PKG2_NEWKERN_START 0x800
u32 pkg2_newkern_ini1_val;
@@ -144,7 +144,7 @@ typedef struct _kip1_id_t
} kip1_id_t;
void pkg2_get_newkern_info(u8 *kern_data);
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_has_kip(link_t *info, u64 tid);
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2019 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
@@ -121,10 +121,11 @@ typedef struct _atm_fatal_error_ctx
u64 stack_dump_size;
u64 stack_trace[0x20];
u8 stack_dump[0x100];
u8 tls[0x100];
} atm_fatal_error_ctx;
#define ATM_FATAL_ERR_CTX_ADDR 0x4003E000
#define ATM_FATAL_MAGIC 0x31454641 // AFE1
#define ATM_FATAL_MAGIC 0x30454641 // AFE0
#define ATM_WB_HEADER_OFF 0x244
#define ATM_WB_MAGIC 0x30544257
@@ -161,7 +162,9 @@ void config_exosphere(launch_ctxt_t *ctxt)
default:
exoFwNo = kb + 1;
if (!strcmp(ctxt->pkg1_id->id, "20190314172056") || (kb >= KB_FIRMWARE_VERSION_810))
exoFwNo++; // ATM_TARGET_FW_800/810/900.
exoFwNo++; // ATM_TARGET_FW_800/810/900/910.
if (!strcmp(ctxt->pkg1_id->id, "20200303104606"))
exoFwNo++; // ATM_TARGET_FW_1000.
break;
}
@@ -261,7 +264,8 @@ void secmon_exo_check_panic()
{
volatile atm_fatal_error_ctx *rpt = (atm_fatal_error_ctx *)ATM_FATAL_ERR_CTX_ADDR;
if (rpt->magic != ATM_FATAL_MAGIC)
// Mask magic to maintain compatibility with any AFE version, thanks to additive struct members.
if ((rpt->magic & 0xF0FFFFFF) != ATM_FATAL_MAGIC)
return;
gfx_clear_grey(0x1B);

View File

@@ -202,19 +202,22 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb, ini_sec_t *cfg_sec)
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
f_lseek(&fp, PATCHED_RELOC_SZ);
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
f_close(&fp);
update_sept_payload = false;
}
f_close(&fp);
}
else
{
f_close(&fp);
f_rename("sept/payload.bin", "sept/payload.bak"); // Backup foreign payload.
f_close(&fp);
}
}
if (update_sept_payload)
{
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
f_mkdir("sept");
f_open(&fp, "sept/payload.bin", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
f_close(&fp);

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -35,7 +35,10 @@
#include "mem/heap.h"
#include "mem/minerva.h"
#include "mem/sdram.h"
#include "power/bq24193.h"
#include "power/max17050.h"
#include "power/max77620.h"
#include "power/max7762x.h"
#include "rtc/max77620-rtc.h"
#include "soc/bpmp.h"
#include "soc/fuse.h"
@@ -228,12 +231,14 @@ void check_power_off_from_hos()
#define PATCHED_RELOC_SZ 0x94
#define PATCHED_RELOC_STACK 0x40007000
#define PATCHED_RELOC_ENTRY 0x40010000
#define EXT_PAYLOAD_ADDR 0xC03C0000
#define EXT_PAYLOAD_ADDR 0xC0000000
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
#define COREBOOT_END_ADDR 0xD0000000
#define CBFS_DRAM_EN_ADDR 0x4003e000
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
static void *coreboot_addr;
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
{
memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ);
@@ -247,7 +252,7 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
if (payload_size == 0x7000)
{
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), coreboot_addr, 0x7000); //Bootblock
*(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
}
}
@@ -313,7 +318,10 @@ int launch_payload(char *path, bool update)
if (size < 0x30000)
buf = (void *)RCM_PAYLOAD_ADDR;
else
buf = (void *)COREBOOT_ADDR;
{
coreboot_addr = (void *)(COREBOOT_END_ADDR - size);
buf = coreboot_addr;
}
if (f_read(&fp, buf, size, NULL))
{
@@ -857,8 +865,6 @@ static void _auto_launch_firmware()
h_cfg.autoboot_list = atoi(kv->val);
else if (!strcmp("bootwait", kv->key))
h_cfg.bootwait = atoi(kv->val);
else if (!strcmp("verification", kv->key))
h_cfg.verification = atoi(kv->val);
else if (!strcmp("backlight", kv->key))
h_cfg.backlight = atoi(kv->val);
else if (!strcmp("autohosoff", kv->key))
@@ -1129,7 +1135,7 @@ static void _show_errors()
{
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
display_backlight_brightness(h_cfg.backlight, 1000);
display_backlight_brightness(150, 1000);
if (h_cfg.errors & ERR_LIBSYS_LP0)
WPRINTF("Missing LP0 (sleep mode) library!\n");
@@ -1144,6 +1150,115 @@ static void _show_errors()
}
}
static void _check_low_battery()
{
int enough_battery;
int batt_volt = 3200;
int charge_status = 0;
bq24193_get_property(BQ24193_ChargeStatus, &charge_status);
max17050_get_property(MAX17050_AvgVCELL, &batt_volt);
enough_battery = charge_status ? 3250 : 3000;
if (batt_volt > enough_battery)
return;
// Prepare battery icon resources.
u8 *battery_res = malloc(ALIGN(SZ_BATTERY_EMPTY, 0x1000));
blz_uncompress_srcdest(BATTERY_EMPTY_BLZ, SZ_BATTERY_EMPTY_BLZ, battery_res, SZ_BATTERY_EMPTY);
u8 *battery_icon = malloc(0x95A); // 21x38x3
u8 *charging_icon = malloc(0x2F4); // 21x12x3
u8 *no_charging_icon = calloc(0x2F4, 1);
memcpy(charging_icon, battery_res, 0x2F4);
memcpy(battery_icon, battery_res + 0x2F4, 0x95A);
u32 battery_icon_y_pos = 1280 - 16 - Y_BATTERY_EMPTY_BATT;
u32 charging_icon_y_pos = 1280 - 16 - Y_BATTERY_EMPTY_BATT - 12 - Y_BATTERY_EMPTY_CHRG;
free(battery_res);
charge_status = !charge_status;
u32 timer = 0;
bool screen_on = false;
while (true)
{
bpmp_msleep(250);
// Refresh battery stats.
int current_charge_status = 0;
bq24193_get_property(BQ24193_ChargeStatus, &current_charge_status);
max17050_get_property(MAX17050_AvgVCELL, &batt_volt);
enough_battery = current_charge_status ? 3250 : 3000;
if (batt_volt > enough_battery)
break;
// Refresh charging icon.
if (screen_on && (charge_status != current_charge_status))
{
if (current_charge_status)
gfx_set_rect_rgb(charging_icon, X_BATTERY_EMPTY, Y_BATTERY_EMPTY_CHRG, 16, charging_icon_y_pos);
else
gfx_set_rect_rgb(no_charging_icon, X_BATTERY_EMPTY, Y_BATTERY_EMPTY_CHRG, 16, charging_icon_y_pos);
}
// Check if it's time to turn off display.
if (screen_on && timer < get_tmr_ms())
{
if (!current_charge_status)
{
max77620_low_battery_monitor_config(true);
power_off();
}
display_end();
screen_on = false;
}
// Check if charging status changed or Power button was pressed.
if (((charge_status != current_charge_status) || (btn_wait_timeout(0, BTN_POWER) & BTN_POWER)))
{
if (!screen_on)
{
display_init();
u32 *fb = display_init_framebuffer();
gfx_init_ctxt(fb, 720, 1280, 720);
gfx_set_rect_rgb(battery_icon, X_BATTERY_EMPTY, Y_BATTERY_EMPTY_BATT, 16, battery_icon_y_pos);
if (current_charge_status)
gfx_set_rect_rgb(charging_icon, X_BATTERY_EMPTY, Y_BATTERY_EMPTY_CHRG, 16, charging_icon_y_pos);
else
gfx_set_rect_rgb(no_charging_icon, X_BATTERY_EMPTY, Y_BATTERY_EMPTY_CHRG, 16, charging_icon_y_pos);
display_backlight_pwm_init();
display_backlight_brightness(100, 1000);
screen_on = true;
}
timer = get_tmr_ms() + 15000;
}
// Check if forcefully continuing.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
break;
charge_status = current_charge_status;
}
display_end();
free(battery_icon);
free(charging_icon);
free(no_charging_icon);
// Re enable Low Battery Monitor shutdown.
max77620_low_battery_monitor_config(true);
}
static void _about()
{
static const char credits[] =
@@ -1203,8 +1318,8 @@ ment_t ment_options[] = {
MDEF_HANDLER("Auto boot", config_autoboot),
MDEF_HANDLER("Boot time delay", config_bootdelay),
MDEF_HANDLER("Auto NoGC", config_nogc),
MDEF_HANDLER("Auto HOS power off", config_auto_hos_poweroff),
MDEF_HANDLER("Backlight", config_backlight),
//MDEF_HANDLER("Auto HOS power off", config_auto_hos_poweroff),
//MDEF_HANDLER("Backlight", config_backlight),
MDEF_END()
};
@@ -1216,7 +1331,7 @@ ment_t ment_cinfo[] = {
MDEF_CAPTION("---- SoC Info ----", 0xFF0AB9E6),
MDEF_HANDLER("Ipatches & bootrom info", bootrom_ipatches_info),
MDEF_HANDLER("Print fuse info", print_fuseinfo),
MDEF_HANDLER("Print kfuse info", print_kfuseinfo),
//MDEF_HANDLER("Print kfuse info", print_kfuseinfo),
MDEF_HANDLER("Print TSEC keys", print_tsec_key),
MDEF_CHGLINE(),
MDEF_CAPTION("-- Storage Info --", 0xFF0AB9E6),
@@ -1265,15 +1380,14 @@ ment_t ment_tools[] = {
MDEF_CAPTION("-- Backup & Restore --", 0xFF0AB9E6),
MDEF_MENU("Backup", &menu_backup),
MDEF_MENU("Restore", &menu_restore),
MDEF_HANDLER("Verification options", config_verification),
MDEF_CHGLINE(),
MDEF_CAPTION("-------- Misc --------", 0xFF0AB9E6),
MDEF_HANDLER("Dump package1/2", dump_packages12),
//MDEF_CAPTION("-------- Misc --------", 0xFF0AB9E6),
//MDEF_HANDLER("Dump package1/2", dump_packages12),
//MDEF_HANDLER("Fix archive bit (except Nintendo)", fix_sd_all_attr),
//MDEF_HANDLER("Fix archive bit (Nintendo only)", fix_sd_nin_attr),
//MDEF_HANDLER("Fix fuel gauge configuration", fix_fuel_gauge_configuration),
//MDEF_HANDLER("Reset all battery cfg", reset_pmic_fuel_gauge_charger_config),
MDEF_CHGLINE(),
//MDEF_CHGLINE(),
MDEF_CAPTION("-------- Other -------", 0xFFFFDD00),
MDEF_HANDLER("AutoRCM", menu_autorcm),
MDEF_END()
@@ -1296,7 +1410,7 @@ ment_t ment_top[] = {
MDEF_END()
};
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.1.2", 0, 0 };
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.1.4", 0, 0 };
extern void pivot_stack(u32 stack_top);
@@ -1312,10 +1426,13 @@ void ipl_main()
heap_init(IPL_HEAP_START);
#ifdef DEBUG_UART_PORT
uart_send(DEBUG_UART_PORT, (u8 *)"Hekate: Hello!\r\n", 16);
uart_send(DEBUG_UART_PORT, (u8 *)"hekate: Hello!\r\n", 16);
uart_wait_idle(DEBUG_UART_PORT, UART_TX_IDLE);
#endif
// Check if battery is enough.
_check_low_battery();
// Set bootloader's default configuration.
set_default_configuration();

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 M4xw
*
* This program is free software; you can redistribute it and/or modify it

View File

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

View File

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

View File

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

View File

@@ -4,7 +4,7 @@
*
* Copyright (c) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@samsung.com>
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -169,9 +169,9 @@ void max77620_config_default()
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4);
}
void max77620_low_battery_monitor_config()
void max77620_low_battery_monitor_config(bool enable)
{
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1,
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_MPPLD |
MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
}

View File

@@ -113,6 +113,6 @@ int max77620_regulator_set_voltage(u32 id, u32 mv);
int max77620_regulator_enable(u32 id, int enable);
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
void max77620_config_default();
void max77620_low_battery_monitor_config();
void max77620_low_battery_monitor_config(bool enable);
#endif

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -186,6 +186,9 @@ void _mbist_workaround()
void _config_se_brom()
{
// Enable fuse clock.
clock_enable_fuse(true);
// Skip SBK/SSK if sept was run.
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
{
@@ -219,6 +222,14 @@ void _config_se_brom()
void _config_regulators()
{
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO power.
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
max77620_regulator_enable(REGULATOR_LDO2, 0);
sd_power_cycle_time_start = get_tmr_ms();
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
@@ -259,9 +270,6 @@ void _config_regulators()
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
// Enable low battery shutdown monitor for < 2800mV.
max77620_low_battery_monitor_config();
}
void config_hw()

View File

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

View File

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

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++)
{
gpt_entry_t *ent = (gpt_entry_t *)(buf + (hdr->part_ent_lba - 1) * NX_EMMC_BLOCKSIZE + i * sizeof(gpt_entry_t));
emmc_part_t *part = (emmc_part_t *)malloc(sizeof(emmc_part_t));
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
part->lba_start = ent->lba_start;
part->lba_end = ent->lba_end;
part->attrs = ent->attrs;

View File

@@ -34,6 +34,16 @@ u8 btn_read()
return res;
}
u8 btn_read_vol()
{
u8 res = 0;
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))
res |= BTN_VOL_DOWN;
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
res |= BTN_VOL_UP;
return res;
}
u8 btn_wait()
{
u8 res = 0, btn = btn_read();

View File

@@ -26,6 +26,7 @@
#define BTN_SINGLE (1 << 7)
u8 btn_read();
u8 btn_read_vol();
u8 btn_wait();
u8 btn_wait_timeout(u32 time_ms, u8 mask);

View File

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

View File

@@ -57,7 +57,7 @@ typedef struct _nyx_storage_t
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
nyx_info_t info;
mtc_config_t mtc_cfg;
emc_table_t mtc_table;
emc_table_t mtc_table[10];
} nyx_storage_t;
u32 get_tmr_us();

View File

@@ -7,7 +7,6 @@ include $(DEVKITARM)/base_rules
TARGET := libsys_lp0
BUILD := ../../build/$(TARGET)
OUTPUT := ../../output
VPATH = $(dir $(wildcard ./*/)) $(dir $(wildcard ./*/*/))
OBJS = $(addprefix $(BUILD)/,\
sys_sdramlp0.o \

View File

@@ -7,7 +7,6 @@ include $(DEVKITARM)/base_rules
TARGET := libsys_minerva
BUILD := ../../build/$(TARGET)
OUTPUT := ../../output
VPATH = $(dir $(wildcard ./*/)) $(dir $(wildcard ./*/*/))
OBJS = $(addprefix $(BUILD)/,\
sys_sdrammtc.o \

View File

@@ -7,7 +7,7 @@ include $(DEVKITARM)/base_rules
TARGET := module_sample
BUILD := ../../build/$(TARGET)
OUTPUT := ../../output
VPATH = $(dir $(wildcard ./*/)) $(dir $(wildcard ./*/*/))
VPATH = $(dir ./) $(dir $(wildcard ./*/))
OBJS = $(addprefix $(BUILD)/,\
module_sample.o \

View File

@@ -16,7 +16,7 @@ TARGET := nyx
BUILDDIR := ./../build
OUTPUTDIR := ./../output
SOURCEDIR = nyx_gui
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/)) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
VPATH += $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/*/*/))
# Main and graphics.
@@ -104,7 +104,11 @@ $(BUILDDIR)/$(TARGET)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(BUILDDIR)/$(TARGET)/%.o: %.S
$(CC) $(CFLAGS) -c $< -o $@
$(OBJS): $(BUILDDIR)/$(TARGET)
$(BUILDDIR)/$(TARGET):
@mkdir -p "$(BUILDDIR)"
@mkdir -p "$(BUILDDIR)/$(TARGET)"
@mkdir -p "$(OUTPUTDIR)"
$(CC) $(CFLAGS) -c $< -o $@

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
* under the terms and conditions of the GNU General Public License,

View File

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

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 Rajko Stojadinovic
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -112,7 +112,7 @@ static lv_obj_t *create_mbox_text(char *text, bool button_ok)
lv_obj_set_style(dark_bg, &mbox_darken);
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
static const char * mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
static const char *mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
lv_mbox_set_recolor_text(mbox, true);
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
@@ -143,7 +143,6 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
FIL fp;
FIL hashFp;
u8 sparseShouldVerify = 4;
u32 btn = 0;
u32 prevPct = 200;
u32 sdFileSector = 0;
int res = 0;
@@ -194,7 +193,7 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
lv_bar_set_style(gui->bar, LV_BAR_STYLE_BG, gui->bar_teal_bg);
lv_bar_set_style(gui->bar, LV_BAR_STYLE_INDIC, lv_theme_get_current()->bar.indic);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
lv_label_set_text(gui->label_pct, gui->txt_buf);
manual_system_maintenance(true);
clmt = f_expand_cltbl(&fp, 0x400000, 0);
@@ -225,7 +224,7 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
return 1;
}
manual_system_maintenance(false);
se_calc_sha256(hashEm, NULL, bufEm, num << 9, 0, SHA_INIT_HASH, false);
f_lseek(&fp, (u64)sdFileSector << (u64)9);
@@ -245,7 +244,7 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
return 1;
}
manual_system_maintenance(false);
se_calc_sha256_finalize(hashEm, NULL);
se_calc_sha256(hashSd, NULL, bufSd, num << 9, 0, SHA_INIT_HASH, true);
res = memcmp(hashEm, hashSd, 0x10);
@@ -289,18 +288,19 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
{
lv_bar_set_value(gui->bar, pct);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
manual_system_maintenance(true);
lv_label_set_text(gui->label_pct, gui->txt_buf);
prevPct = pct;
}
manual_system_maintenance(false);
lba_curr += num;
totalSectorsVer -= num;
sdFileSector += num;
sparseShouldVerify++;
btn = btn_wait_timeout(0, BTN_VOL_DOWN | BTN_VOL_UP);
if ((btn & BTN_VOL_DOWN) && (btn & BTN_VOL_UP))
// Check for cancellation combo.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
{
s_printf(gui->txt_buf, "#FFDD00 Verification was cancelled!#\n");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
@@ -321,7 +321,7 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32
lv_bar_set_value(gui->bar, pct);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
lv_label_set_text(gui->label_pct, gui->txt_buf);
manual_system_maintenance(true);
return 0;
@@ -350,7 +350,6 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t
u32 currPartIdx = 0;
u32 numSplitParts = 0;
u32 maxSplitParts = 0;
u32 btn = 0;
bool isSmallSdCard = false;
bool partialDumpInProgress = false;
int res = 0;
@@ -565,12 +564,10 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t
// Create next part.
s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path));
lv_label_ins_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path) - 1),
gui->txt_buf);
lv_label_cut_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path) - 1),
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
strlen(outFilename + strlen(gui->base_path)) + 1);
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
lbaStartPart = lba_curr;
res = f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE);
@@ -620,6 +617,7 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t
manual_system_maintenance(true);
}
}
manual_system_maintenance(false);
res = f_write_fast(&fp, buf, NX_EMMC_BLOCKSIZE * num);
@@ -635,12 +633,15 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t
return 0;
}
manual_system_maintenance(false);
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
if (pct != prevPct)
{
lv_bar_set_value(gui->bar, pct);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
lv_label_set_text(gui->label_pct, gui->txt_buf);
manual_system_maintenance(true);
prevPct = pct;
@@ -657,8 +658,8 @@ static int _dump_emmc_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_storage_t
bytesWritten = 0;
}
btn = btn_wait_timeout(0, BTN_VOL_DOWN | BTN_VOL_UP);
if ((btn & BTN_VOL_DOWN) && (btn & BTN_VOL_UP))
// Check for cancellation combo.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
{
s_printf(gui->txt_buf, "\n#FFDD00 The backup was cancelled!#\n");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
@@ -719,15 +720,13 @@ void dump_emmc_selected(emmcPartType_t dumpType, emmc_tool_gui_t *gui)
char *txt_buf = (char *)malloc(0x1000);
gui->txt_buf = txt_buf;
s_printf(txt_buf, "");
lv_label_set_array_text(gui->label_log, txt_buf, 0x1000);
lv_label_set_text(gui->label_log, txt_buf);
lv_label_set_static_text(gui->label_info, "Checking for available free space...");
manual_system_maintenance(true);
// Do a reinit to refresh tuning.
sd_unmount(true);
if (!sd_mount())
{
lv_label_set_static_text(gui->label_info, "#FFDD00 Failed to init SD!#");
@@ -771,7 +770,7 @@ void dump_emmc_selected(emmcPartType_t dumpType, emmc_tool_gui_t *gui)
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, bootPart.name, bootPart.lba_start, bootPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, bootPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -812,7 +811,7 @@ void dump_emmc_selected(emmcPartType_t dumpType, emmc_tool_gui_t *gui)
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, part->name, part->lba_start, part->lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, part->name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -849,7 +848,7 @@ void dump_emmc_selected(emmcPartType_t dumpType, emmc_tool_gui_t *gui)
{
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, rawPart.name, rawPart.lba_start, rawPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, rawPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -880,7 +879,7 @@ void dump_emmc_selected(emmcPartType_t dumpType, emmc_tool_gui_t *gui)
else
s_printf(txt_buf, "Time taken: %dm %ds.", timer / 60, timer % 60);
lv_label_set_array_text(gui->label_finish, txt_buf, 0x1000);
lv_label_set_text(gui->label_finish, txt_buf);
out:
free(txt_buf);
@@ -944,12 +943,10 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
_update_filename(outFilename, sdPathLen, numSplitParts);
s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path));
lv_label_ins_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
gui->txt_buf);
lv_label_cut_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
strlen(outFilename + strlen(gui->base_path)) + 1);
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
if (f_stat(outFilename, &fno) && !gui->raw_emummc)
@@ -1007,12 +1004,10 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
if (use_multipart)
{
s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path));
lv_label_ins_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
gui->txt_buf);
lv_label_cut_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
strlen(outFilename + strlen(gui->base_path)) + 1);
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
}
else
@@ -1123,12 +1118,10 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
// Read from next part.
s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path));
lv_label_ins_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
gui->txt_buf);
lv_label_cut_text(gui->label_info,
strlen(lv_label_get_text(gui->label_info)) - strlen(outFilename + strlen(gui->base_path)) - 1,
strlen(outFilename + strlen(gui->base_path)) + 1);
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
lbaStartPart = lba_curr;
@@ -1152,6 +1145,7 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
num = MIN(totalSectors, NUM_SECTORS_PER_ITER);
res = f_read_fast(&fp, buf, num << 9);
manual_system_maintenance(false);
if (res)
{
@@ -1170,6 +1164,9 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
res = !sdmmc_storage_write(storage, lba_curr, num, buf);
else
res = !sdmmc_storage_write(&sd_storage, lba_curr + sd_sector_off, num, buf);
manual_system_maintenance(false);
while (res)
{
s_printf(gui->txt_buf,
@@ -1202,13 +1199,14 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa
res = !sdmmc_storage_write(storage, lba_curr, num, buf);
else
res = !sdmmc_storage_write(&sd_storage, lba_curr + sd_sector_off, num, buf);
manual_system_maintenance(false);
}
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
if (pct != prevPct)
{
lv_bar_set_value(gui->bar, pct);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
lv_label_set_text(gui->label_pct, gui->txt_buf);
manual_system_maintenance(true);
prevPct = pct;
}
@@ -1268,11 +1266,11 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
char *txt_buf = (char *)malloc(0x1000);
gui->txt_buf = txt_buf;
s_printf(txt_buf, "");
lv_label_set_array_text(gui->label_log, txt_buf, 0x1000);
lv_label_set_text(gui->label_log, txt_buf);
manual_system_maintenance(true);
sd_unmount(true);
s_printf(txt_buf,
"#FFDD00 This may render your device inoperative!#\n\n"
@@ -1351,7 +1349,7 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n\n\n\n",
i, bootPart.name, bootPart.lba_start, bootPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, bootPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -1385,7 +1383,7 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
{
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n\n\n\n",
i, part->name, part->lba_start, part->lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, part->name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -1418,7 +1416,7 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
{
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n\n\n\n",
i, rawPart.name, rawPart.lba_start, rawPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, rawPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -1447,7 +1445,7 @@ void restore_emmc_selected(emmcPartType_t restoreType, emmc_tool_gui_t *gui)
else
s_printf(txt_buf, "Time taken: %dm %ds.", timer / 60, timer % 60);
lv_label_set_array_text(gui->label_finish, txt_buf, 0x1000);
lv_label_set_text(gui->label_finish, txt_buf);
out:
free(txt_buf);

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 Rajko Stojadinovic
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -29,6 +29,7 @@
#include "../sec/se.h"
#include "../storage/nx_emmc.h"
#include "../storage/sdmmc.h"
#include "../utils/btn.h"
#include "../utils/sprintf.h"
#include "../utils/util.h"
@@ -195,8 +196,8 @@ static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_sto
// Create next part.
s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path));
lv_label_ins_text(gui->label_info, strlen(lv_label_get_text(gui->label_info)) - 3, gui->txt_buf);
lv_label_cut_text(gui->label_info, strlen(lv_label_get_text(gui->label_info)) - 3, 3);
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
res = f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE);
@@ -215,6 +216,22 @@ static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_sto
clmt = f_expand_cltbl(&fp, 0x400000, MIN(totalSize, multipartSplitSize));
}
// Check for cancellation combo.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
{
s_printf(gui->txt_buf, "#FFDD00 The emuMMC was cancelled!#\n");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
f_close(&fp);
free(clmt);
f_unlink(outFilename);
msleep(1000);
return 0;
}
retryCount = 0;
num = MIN(totalSectors, NUM_SECTORS_PER_ITER);
while (!sdmmc_storage_read(storage, lba_curr, num, buf))
@@ -246,8 +263,13 @@ static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_sto
manual_system_maintenance(true);
}
}
manual_system_maintenance(false);
res = f_write_fast(&fp, buf, NX_EMMC_BLOCKSIZE * num);
manual_system_maintenance(false);
if (res)
{
s_printf(gui->txt_buf, "\n#FF0000 Fatal error (%d) when writing to SD Card#\nPlease try again...\n", res);
@@ -265,7 +287,7 @@ static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_sto
{
lv_bar_set_value(gui->bar, pct);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
lv_label_set_text(gui->label_pct, gui->txt_buf);
manual_system_maintenance(true);
prevPct = pct;
@@ -281,6 +303,8 @@ static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_sto
f_sync(&fp);
bytesWritten = 0;
}
manual_system_maintenance(false);
}
lv_bar_set_value(gui->bar, 100);
lv_label_set_text(gui->label_pct, " "SYMBOL_DOT" 100%");
@@ -301,13 +325,12 @@ void dump_emummc_file(emmc_tool_gui_t *gui)
char *txt_buf = (char *)malloc(0x1000);
gui->txt_buf = txt_buf;
s_printf(txt_buf, "");
lv_label_set_array_text(gui->label_log, txt_buf, 0x1000);
lv_label_set_text(gui->label_log, txt_buf);
manual_system_maintenance(true);
sd_unmount(true);
if (!sd_mount())
{
lv_label_set_static_text(gui->label_info, "#FFDD00 Failed to init SD!#");
@@ -364,7 +387,7 @@ void dump_emummc_file(emmc_tool_gui_t *gui)
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, bootPart.name, bootPart.lba_start, bootPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, bootPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -402,7 +425,7 @@ void dump_emummc_file(emmc_tool_gui_t *gui)
{
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, rawPart.name, rawPart.lba_start, rawPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, rawPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -438,7 +461,7 @@ out_failed:
else
s_printf(txt_buf, "Time taken: %dm %ds.", timer / 60, timer % 60);
lv_label_set_array_text(gui->label_finish, txt_buf, 0x1000);
lv_label_set_text(gui->label_finish, txt_buf);
out:
free(txt_buf);
@@ -458,7 +481,6 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
lv_label_set_text(gui->label_pct, " "SYMBOL_DOT" 0%");
manual_system_maintenance(true);
s_printf(gui->txt_buf, "#96FF00 Base folder:#\n%s\n#96FF00 Partition offset:# #FF8000 0x%08X#",
gui->base_path, sd_part_off);
lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf);
@@ -478,6 +500,18 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
while (totalSectors > 0)
{
// Check for cancellation combo.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
{
s_printf(gui->txt_buf, "#FFDD00 The emuMMC was cancelled!#\n");
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf);
manual_system_maintenance(true);
msleep(1000);
return 0;
}
retryCount = 0;
num = MIN(totalSectors, NUM_SECTORS_PER_ITER);
@@ -507,6 +541,9 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
manual_system_maintenance(true);
}
}
manual_system_maintenance(false);
retryCount = 0;
// Write data to SD card.
@@ -535,12 +572,15 @@ static int _dump_emummc_raw_part(emmc_tool_gui_t *gui, int active_part, int part
manual_system_maintenance(true);
}
}
manual_system_maintenance(false);
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
if (pct != prevPct)
{
lv_bar_set_value(gui->bar, pct);
s_printf(gui->txt_buf, " "SYMBOL_DOT" %d%%", pct);
lv_label_set_array_text(gui->label_pct, gui->txt_buf, 32);
lv_label_set_text(gui->label_pct, gui->txt_buf);
manual_system_maintenance(true);
prevPct = pct;
@@ -573,13 +613,12 @@ void dump_emummc_raw(emmc_tool_gui_t *gui, int part_idx, u32 sector_start)
char *txt_buf = (char *)malloc(0x1000);
gui->txt_buf = txt_buf;
s_printf(txt_buf, "");
lv_label_set_array_text(gui->label_log, txt_buf, 0x1000);
lv_label_set_text(gui->label_log, txt_buf);
manual_system_maintenance(true);
sd_unmount(true);
if (!sd_mount())
{
lv_label_set_static_text(gui->label_info, "#FFDD00 Failed to init SD!#");
@@ -619,7 +658,7 @@ void dump_emummc_raw(emmc_tool_gui_t *gui, int part_idx, u32 sector_start)
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, bootPart.name, bootPart.lba_start, bootPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, bootPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -656,7 +695,7 @@ void dump_emummc_raw(emmc_tool_gui_t *gui, int part_idx, u32 sector_start)
{
s_printf(txt_buf, "#00DDFF %02d: %s#\n#00DDFF Range: 0x%08X - 0x%08X#\n\n",
i, rawPart.name, rawPart.lba_start, rawPart.lba_end);
lv_label_set_array_text(gui->label_info, txt_buf, 0x1000);
lv_label_set_text(gui->label_info, txt_buf);
s_printf(txt_buf, "%02d: %s... ", i, rawPart.name);
lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf);
manual_system_maintenance(true);
@@ -692,7 +731,7 @@ out_failed:
else
s_printf(txt_buf, "Time taken: %dm %ds.", timer / 60, timer % 60);
lv_label_set_array_text(gui->label_finish, txt_buf, 0x1000);
lv_label_set_text(gui->label_finish, txt_buf);
out:
free(txt_buf);

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
* under the terms and conditions of the GNU General Public License,
@@ -342,12 +342,12 @@ lv_res_t nyx_generic_onoff_toggle(lv_obj_t *btn)
if (!(lv_btn_get_state(btn) & LV_BTN_STATE_TGL_REL))
{
strcat(label_text, "#D0D0D0 OFF#");
lv_label_set_array_text(label_btn, label_text, 64);
lv_label_set_text(label_btn, label_text);
}
else
{
strcat(label_text, "#00FFC9 ON #");
lv_label_set_array_text(label_btn, label_text, 64);
lv_label_set_text(label_btn, label_text);
}
}
else
@@ -796,7 +796,7 @@ static void _update_status_bar(void *params)
s_printf(label, "%02d:%02d "SYMBOL_DOT" "SYMBOL_TEMPERATURE" %02d.%d",
time.hour, time.min, soc_temp_dec, (soc_temp & 0xFF) / 10);
lv_label_set_array_text(status_bar.time_temp, label, 64);
lv_label_set_text(status_bar.time_temp, label);
lv_obj_realign(status_bar.temp_symbol);
lv_obj_realign(status_bar.temp_degrees);
@@ -819,7 +819,7 @@ static void _update_status_bar(void *params)
if (charge_status)
s_printf(label + strlen(label), " #FFDD00 "SYMBOL_CHARGE"#");
lv_label_set_array_text(status_bar.battery, label, 64);
lv_label_set_text(status_bar.battery, label);
lv_obj_realign(status_bar.battery);
// Set battery current draw and voltage.
@@ -832,7 +832,7 @@ static void _update_status_bar(void *params)
s_printf(label + strlen(label), " mA# (%s%d mV%s)",
voltage_empty ? "#FF8000 " : "", batt_volt, voltage_empty ? " "SYMBOL_WARNING"#" : "");
lv_label_set_array_text(status_bar.battery_more, label, 64);
lv_label_set_text(status_bar.battery_more, label);
lv_obj_realign(status_bar.battery_more);
free(label);
@@ -971,12 +971,12 @@ static lv_res_t logs_onoff_toggle(lv_obj_t *btn)
if (!launch_logs_enable)
{
strcat(label_text, "#D0D0D0 OFF#");
lv_label_set_array_text(label_btn, label_text, 64);
lv_label_set_text(label_btn, label_text);
}
else
{
strcat(label_text, "#00FFC9 ON #");
lv_label_set_array_text(label_btn, label_text, 64);
lv_label_set_text(label_btn, label_text);
}
return LV_RES_OK;
@@ -1170,7 +1170,7 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_more_cfg_action);
// Set button's label text.
lv_label_set_array_text(launch_ctxt[x + 1], ini_sec->name, strlen(ini_sec->name));
lv_label_set_text(launch_ctxt[x + 1], ini_sec->name);
lv_obj_set_opa_scale(launch_ctxt[x + 1], LV_OPA_COVER);
// Set rolling text if name is big.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -877,7 +877,7 @@ out0:;
if (emummc_img->part_type[raw_btn_idx] != 0x83)
{
s_printf(txt_buf, "SD RAW %d", raw_btn_idx + 1);
lv_label_set_array_text(btn_label, txt_buf, 32);
lv_label_set_text(btn_label, txt_buf);
}
if (!emummc_img->part_sector[raw_btn_idx] || emummc_img->part_type[raw_btn_idx] == 0x83 || !emummc_img->part_path[raw_btn_idx * 128])
@@ -905,7 +905,7 @@ out0:;
lv_obj_set_style(lv_desc, &hint_small_style);
s_printf(txt_buf, "Sector start: 0x%08X\nFolder: %s", emummc_img->part_sector[raw_btn_idx], &emummc_img->part_path[raw_btn_idx * 128]);
lv_label_set_array_text(lv_desc, txt_buf, 0x500);
lv_label_set_text(lv_desc, txt_buf);
lv_obj_align(lv_desc, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 5);
}
@@ -1059,7 +1059,7 @@ lv_res_t create_win_emummc_tools(lv_obj_t *btn)
s_printf(txt_buf, "#00DDFF Type:# SD File\n#00DDFF Base folder:# %s\n#00DDFF Nintendo folder:# %s",
emu_info.path ? emu_info.path : "", emu_info.nintendo_path ? emu_info.nintendo_path : "");
lv_label_set_array_text(label_txt2, txt_buf, 0x200);
lv_label_set_text(label_txt2, txt_buf);
}
else
{

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -337,7 +337,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
FUSE(FUSE_OPT_VENDOR_CODE), FUSE(FUSE_OPT_FAB_CODE), lot_bin, FUSE(FUSE_OPT_LOT_CODE_0),
FUSE(FUSE_OPT_LOT_CODE_1), FUSE(FUSE_OPT_WAFER_ID), FUSE(FUSE_OPT_X_COORDINATE), FUSE(FUSE_OPT_Y_COORDINATE));
lv_label_set_array_text(lb_val, txt_buf, 0x1000);
lv_label_set_text(lb_val, txt_buf);
free(txt_buf);
@@ -402,7 +402,7 @@ static lv_res_t _create_window_bootrom_info_status(lv_obj_t *btn)
if (res != 0)
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Failed to read ipatches. Error: %d#", res);
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
free(txt_buf);
@@ -450,12 +450,12 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn)
if (!pkg1_id)
{
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
lv_label_set_array_text(lb_desc, txt_buf, 0x500);
lv_label_set_text(lb_desc, txt_buf);
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
goto out;
}
lv_label_set_array_text(lb_desc, txt_buf, 0x500);
lv_label_set_text(lb_desc, txt_buf);
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
lv_obj_t *val = lv_cont_create(win, NULL);
@@ -528,9 +528,9 @@ static lv_res_t _create_window_tsec_keys_status(lv_obj_t *btn)
s_printf(txt_buf2, "Error: %x", res);
}
lv_label_set_array_text(lb_desc, txt_buf, 0x500);
lv_label_set_text(lb_desc, txt_buf);
lv_label_set_array_text(lb_val, txt_buf2, 0x500);
lv_label_set_text(lb_val, txt_buf2);
out:
free(pkg1);
@@ -634,7 +634,7 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
lv_label_set_array_text(lb_val, txt_buf, 0x1000);
lv_label_set_text(lb_val, txt_buf);
lv_obj_set_width(lb_val, lv_obj_get_width(val));
lv_obj_align(val, desc, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
@@ -679,7 +679,7 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn)
}
nx_emmc_gpt_free(&gpt);
lv_label_set_array_text(lb_desc2, txt_buf, 0x1000);
lv_label_set_text(lb_desc2, txt_buf);
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
lv_obj_align(desc2, val, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 6, 0);
}
@@ -738,7 +738,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
sd_storage.cid.hwrev, sd_storage.cid.fwrev, sd_storage.cid.serial,
sd_storage.cid.month, sd_storage.cid.year);
lv_label_set_array_text(lb_val, txt_buf, 0x1000);
lv_label_set_text(lb_val, txt_buf);
lv_obj_set_width(lb_val, lv_obj_get_width(val));
lv_obj_align(val, desc, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
@@ -777,7 +777,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
sd_storage.ssr.speed_class, sd_storage.ssr.uhs_grade, sd_storage.ssr.video_class,
sd_storage.ssr.app_class, sd_storage.csd.write_protect);
lv_label_set_array_text(lb_val2, txt_buf, 0x1000);
lv_label_set_text(lb_val2, txt_buf);
lv_obj_set_width(lb_val2, lv_obj_get_width(val2));
lv_obj_align(val2, desc2, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
@@ -822,7 +822,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
(sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512,
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF);
lv_label_set_array_text(lb_val3, txt_buf, 0x1000);
lv_label_set_text(lb_val3, txt_buf);
lv_obj_set_width(lb_val3, lv_obj_get_width(val3));
lv_obj_align(val3, desc3, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
@@ -920,7 +920,7 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
else
s_printf(txt_buf + strlen(txt_buf), "-%d.%d oC\n", (~value + 1) / 10, (~value + 1) % 10);
lv_label_set_array_text(lb_val, txt_buf, 0x1000);
lv_label_set_text(lb_val, txt_buf);
lv_obj_set_width(lb_val, lv_obj_get_width(val));
lv_obj_align(val, desc, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
@@ -1006,7 +1006,7 @@ static lv_res_t _create_window_battery_status(lv_obj_t *btn)
break;
}
lv_label_set_array_text(lb_val2, txt_buf, 0x1000);
lv_label_set_text(lb_val2, txt_buf);
lv_obj_set_width(lb_val2, lv_obj_get_width(val2));
lv_obj_align(val2, desc2, LV_ALIGN_OUT_RIGHT_MID, 0, 0);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -190,7 +190,7 @@ static int _fix_attributes(u32 *ufidx, lv_obj_t *lb_val, char *path, u32 *total,
f_chmod(path, 0, AM_ARC);
if (*ufidx == 0)
lv_label_set_array_text(lb_val, path, 256);
lv_label_set_text(lb_val, path);
*ufidx += 1;
if (*ufidx > 9)
*ufidx = 0;
@@ -207,7 +207,7 @@ static int _fix_attributes(u32 *ufidx, lv_obj_t *lb_val, char *path, u32 *total,
*total = *total + 1;
f_chmod(path, AM_ARC, AM_ARC);
}
lv_label_set_array_text(lb_val, path, 256);
lv_label_set_text(lb_val, path);
manual_system_maintenance(true);
// Enter the directory.
@@ -264,7 +264,7 @@ static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
char path[256];
char *path = malloc(1024);
path[0] = 0;
lv_label_set_static_text(lb_val, "");
@@ -299,9 +299,11 @@ static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
s_printf(txt_buf, "#96FF00 Total archive bits fixed:# #FF8000 %d!#", total);
lv_label_set_array_text(lb_desc2, txt_buf, 0x500);
lv_label_set_text(lb_desc2, txt_buf);
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
lv_obj_align(desc2, val, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0);
free(path);
}
// Enable buttons.
@@ -366,7 +368,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n\n", build_date);
free(build_date);
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump package1 in its encrypted state if unknown.
@@ -374,7 +376,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
{
s_printf(txt_buf + strlen(txt_buf),
"#FFDD00 Unknown pkg1 version for reading#\n#FFDD00 TSEC firmware!#");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &storage);
@@ -382,7 +384,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
goto out_free;
s_printf(txt_buf + strlen(txt_buf), "\nEncrypted pkg1 dumped to pkg1_enc.bin");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
goto out_free;
@@ -438,7 +440,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
"#C7EA46 Warmboot size: #0x%05X\n\n",
hdr->ldr_size, pkg1_id->secmon_base, hdr->sm_size, pkg1_id->warmboot_base, hdr->wb_size);
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump package1.1.
@@ -446,7 +448,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (sd_save_to_file(pkg1, 0x40000, path))
goto out_free;
s_printf(txt_buf + strlen(txt_buf), "pkg1 dumped to pkg1_decr.bin\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump nxbootloader.
@@ -454,7 +456,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (sd_save_to_file(loader, hdr->ldr_size, path))
goto out_free;
s_printf(txt_buf + strlen(txt_buf), "NX Bootloader dumped to nxloader.bin\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump secmon.
@@ -462,7 +464,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (sd_save_to_file(secmon, hdr->sm_size, path))
goto out_free;
s_printf(txt_buf + strlen(txt_buf), "Secure Monitor dumped to secmon.bin\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump warmboot.
@@ -470,7 +472,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (sd_save_to_file(warmboot, hdr->wb_size, path))
goto out_free;
s_printf(txt_buf + strlen(txt_buf), "Warmboot dumped to warmboot.bin\n\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
}
@@ -507,7 +509,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (!pkg2_hdr)
{
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Pkg2 decryption failed!#");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
goto out;
@@ -519,7 +521,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
"#C7EA46 INI1 size: #0x%05X\n\n",
pkg2_hdr->sec_size[PKG2_SEC_KERNEL], pkg2_hdr->sec_size[PKG2_SEC_INI1]);
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump pkg2.1.
@@ -527,7 +529,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
goto out;
s_printf(txt_buf + strlen(txt_buf), "pkg2 dumped to pkg2_decr.bin\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump kernel.
@@ -535,7 +537,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path))
goto out;
s_printf(txt_buf + strlen(txt_buf), "Kernel dumped to kernel.bin\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
// Dump INI1.
@@ -547,13 +549,20 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
ini1_off = pkg2_newkern_ini1_start;
ini1_size = pkg2_newkern_ini1_end - pkg2_newkern_ini1_start;
}
if (!ini1_off)
{
s_printf(txt_buf + strlen(txt_buf), "#FFDD00 Failed to dump INI1 and kips!#\n");
goto out;
}
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)(pkg2_hdr->data + ini1_off);
emmcsn_path_impl(path, "/pkg2", "ini1.bin", &storage);
if (sd_save_to_file(ini1, ini1_size, path))
goto out;
s_printf(txt_buf + strlen(txt_buf), "INI1 dumped to ini1.bin\n\n");
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
char filename[32];
@@ -583,7 +592,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
}
s_printf(txt_buf + strlen(txt_buf), "%s kip dumped to %s.kip1\n", kip1->name, kip1->name);
lv_label_set_array_text(lb_desc, txt_buf, 0x1000);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true);
ptr += kip1_size;
@@ -852,7 +861,7 @@ static void _create_tab_tools_arc_autorcm(lv_theme_t *th, lv_obj_t *parent)
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
lv_label_set_recolor(label_txt4, true);
lv_label_set_array_text(label_txt4, txt_buf, 0x1000);
lv_label_set_text(label_txt4, txt_buf);
free(txt_buf);
lv_obj_set_style(label_txt4, &hint_small_style);

View File

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

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 balika011
*
* This program is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20190531152432", 8, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //8.1.0
{ "20190809135709", 9, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //9.0.0
{ "20191021113848", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //9.1.0
{ "20200303104606", 10, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //10.0.0
{ NULL } //End.
};

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -45,14 +45,34 @@ u32 pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
void pkg2_get_newkern_info(u8 *kern_data)
{
u32 info_op = *(u32 *)(kern_data + PKG2_NEWKERN_GET_INI1);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + PKG2_NEWKERN_GET_INI1; // Parse ADR and PC.
u32 pkg2_newkern_ini1_off = 0;
pkg2_newkern_ini1_start = 0;
// Find static OP offset that is close to INI1 offset.
u32 counter_ops = 0x100;
while (counter_ops)
{
if (*(u32 *)(kern_data + 0x100 - counter_ops) == PKG2_NEWKERN_GET_INI1_HEURISTIC)
{
pkg2_newkern_ini1_off = 0x100 - counter_ops + 12; // OP found. Add 12 for the INI1 offset.
break;
}
counter_ops -= 4;
}
// Offset not found?
if (!counter_ops)
return;
u32 info_op = *(u32 *)(kern_data + pkg2_newkern_ini1_off);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + pkg2_newkern_ini1_off; // Parse ADR and PC.
pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val);
pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8);
}
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{
u8 *ptr;
// Check for new pkg2 type.
@@ -60,6 +80,9 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{
pkg2_get_newkern_info(pkg2->data);
if (!pkg2_newkern_ini1_start)
return false;
ptr = pkg2->data + pkg2_newkern_ini1_start;
*new_pkg2 = true;
}
@@ -79,6 +102,8 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
ptr += ki->size;
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
}
return true;
}
static const u8 mkey_keyseed_8xx[][0x10] =

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -27,7 +27,7 @@
#define PKG2_SEC_INI1 1
#define INI1_MAGIC 0x31494E49
#define PKG2_NEWKERN_GET_INI1 0x44
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
#define PKG2_NEWKERN_START 0x800
u32 pkg2_newkern_ini1_val;
@@ -91,7 +91,7 @@ typedef struct _pkg2_kip1_info_t
void pkg2_get_newkern_info(u8 *kern_data);
u32 pkg2_calc_kip1_size(pkg2_kip1_t *kip1);
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);
pkg2_hdr_t *pkg2_decrypt(void *data, u8 kb);

View File

@@ -182,19 +182,22 @@ int reboot_to_sept(const u8 *tsec_fw, u32 kb)
memcpy(tmp_cfg, (boot_cfg_t *)b_cfg, sizeof(boot_cfg_t));
f_lseek(&fp, PATCHED_RELOC_SZ);
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
f_close(&fp);
update_sept_payload = false;
}
f_close(&fp);
}
else
{
f_close(&fp);
f_rename("sept/payload.bin", "sept/payload.bak"); // Backup foreign payload.
f_close(&fp);
}
}
if (update_sept_payload)
{
volatile reloc_meta_t *reloc = (reloc_meta_t *)(nyx_str->hekate + RELOC_META_OFF);
f_mkdir("sept");
f_open(&fp, "sept/payload.bin", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, (u8 *)nyx_str->hekate, reloc->end - reloc->start, NULL);
f_close(&fp);

View File

@@ -1,8 +1,8 @@
/*
* Touch driver for Nintendo Switch's STMicroelectronics FingerTip touch controller
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
*
* Copyright (c) 2018 langerhans
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,6 +26,7 @@
#include "../power/max77620.h"
#include "../soc/gpio.h"
#include "../soc/t210.h"
#include "../utils/btn.h"
#include "../utils/util.h"
#include "touch.h"
@@ -33,17 +34,40 @@
#include "../gfx/gfx.h"
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
static int touch_command(u8 cmd)
static int touch_command(u8 cmd, u8 *buf, u8 size)
{
int err = i2c_send_byte(I2C_3, STMFTS_I2C_ADDR, cmd, 0);
if (!err)
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd, buf, size);
if (!res)
return 1;
return 0;
}
static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
{
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd[0], &cmd[1], csize - 1);
if (res)
res = i2c_recv_buf(buf, size, I2C_3, STMFTS_I2C_ADDR);
if (!res)
return 1;
// TODO: Check for completion in event loop
msleep(1);
return 0;
}
static int touch_wait_event(u8 event, u8 status, u32 timeout)
{
u32 timer = get_tmr_ms() + timeout;
while (true)
{
u8 tmp[8] = {0};
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
if (tmp[1] == event && tmp[2] == status)
return 0;
if (get_tmr_ms() > timer)
return 1;
}
}
#define X_REAL_MAX 1264
#define Y_REAL_MAX 704
#define EDGE_OFFSET 15
@@ -75,7 +99,14 @@ static void _touch_process_contact_event(touch_event *event, bool touching)
if (touching)
{
event->y = (event->raw[3] << 4) | (event->raw[4] & STMFTS_MASK_X_MSB);
event->z = event->raw[5];
event->z = event->raw[5] | (event->raw[6] << 8);
event->z = event->z << 6;
u16 tmp = 0x40;
if ((event->raw[7] & 0x3F) != 1 && (event->raw[7] & 0x3F) != 0x3F)
tmp = event->raw[7] & 0x3F;
event->z /= tmp + 0x40;
event->fingers = ((event->raw[1] & STMFTS_MASK_TOUCH_ID) >> 4) + 1;
}
else
@@ -93,7 +124,7 @@ static void _touch_parse_event(touch_event *event)
case STMFTS_EV_MULTI_TOUCH_ENTER:
case STMFTS_EV_MULTI_TOUCH_MOTION:
_touch_process_contact_event(event, true);
if (event->z > 52) // Discard noisy hover touch.
if (event->z < 255) // Reject palm rest.
event->touch = true;
else
{
@@ -158,8 +189,157 @@ touch_info touch_get_info()
return info;
}
int touch_get_fw_info(touch_fw_info_t *fw)
{
u8 buf[8] = {0};
// Get fw address info.
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
int res = touch_read_reg(cmd, 3, buf, 3);
if (!res)
{
// Get fw info.
cmd[1] = buf[2]; cmd[2] = buf[1];
res = touch_read_reg(cmd, 3, buf, 8);
if (!res)
{
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
fw->ftb_ver = (buf[6] << 8) | buf[5];
}
cmd[2]++;
res = touch_read_reg(cmd, 3, buf, 8);
if (!res)
fw->fw_rev = (buf[7] << 8) | buf[6];
}
return res;
}
int touch_sys_reset()
{
u8 cmd[3] = { 0, 0x28, 0x80 }; // System reset cmd.
for (u8 retries = 0; retries < 3; retries++)
{
if (touch_command(STMFTS_WRITE_REG, cmd, 3))
{
msleep(10);
continue;
}
msleep(10);
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20))
continue;
else
return 0;
}
return 1;
}
int touch_panel_ito_test(u8 *err)
{
int res = 0;
// Reset touchscreen module.
if (touch_sys_reset())
return res;
// Do ITO Production test.
u8 cmd[2] = { 1, 0 };
if (touch_command(STMFTS_ITO_CHECK, cmd, 2))
return res;
u32 timer = get_tmr_ms() + 2000;
while (true)
{
u8 tmp[8] = {0};
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
if (tmp[1] == 0xF && tmp[2] == 0x5)
{
if (err)
{
err[0] = tmp[3];
err[1] = tmp[4];
}
res = 1;
break;
}
if (get_tmr_ms() > timer)
break;
}
// Reset touchscreen module.
touch_sys_reset();
return res;
}
int touch_sense_enable()
{
// Enable auto tuning calibration and multi-touch sensing.
u8 cmd = 1;
if (touch_command(STMFTS_AUTO_CALIBRATION, &cmd, 1))
return 0;
if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0))
return 0;
if (touch_command(STMFTS_CLEAR_EVENT_STACK, NULL, 0))
return 0;
return 1;
}
int touch_execute_autotune()
{
// Reset touchscreen module.
if (touch_sys_reset())
return 0;
// Trim low power oscillator.
if (touch_command(STMFTS_LP_TIMER_CALIB, NULL, 0))
return 0;
msleep(200);
// Apply Mutual Sense Compensation tuning.
if (touch_command(STMFTS_MS_CX_TUNING, NULL, 0))
return 0;
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000))
return 0;
// Apply Self Sense Compensation tuning.
if (touch_command(STMFTS_SS_CX_TUNING, NULL, 0))
return 0;
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000))
return 0;
// Save Compensation data to EEPROM.
if (touch_command(STMFTS_SAVE_CX_TUNING, NULL, 0))
return 0;
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000))
return 0;
return touch_sense_enable();
}
static int touch_init()
{
// Initialize touchscreen module.
if (touch_sys_reset())
return 0;
return touch_sense_enable();
}
int touch_power_on()
{
// Enables LDO6 for touchscreen VDD/AVDD supply
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
// Configure touchscreen GPIO.
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
@@ -181,45 +361,32 @@ int touch_power_on()
clock_enable_i2c(I2C_3);
i2c_init(I2C_3);
// Enables LDO6 for touchscreen VDD/AVDD supply
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
// Wait for the touchscreen module to get ready.
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20);
msleep(20);
// Check for forced boot time calibration.
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
{
u8 err[2];
if (touch_panel_ito_test(err))
if (!err[0] && !err[1])
return touch_execute_autotune();
}
// Initialize touchscreen module.
if (touch_command(STMFTS_SYSTEM_RESET))
return 0;
// Initialize touchscreen.
u32 retries = 3;
while (retries)
{
if (touch_init())
return 1;
retries--;
}
if (touch_command(STMFTS_SLEEP_OUT))
return 0;
if (touch_command(STMFTS_MS_CX_TUNING))
return 0;
if (touch_command(STMFTS_SS_CX_TUNING))
return 0;
if (touch_command(STMFTS_FULL_FORCE_CALIBRATION))
return 0;
if (touch_command(STMFTS_MS_MT_SENSE_ON))
return 0;
if (touch_command(STMFTS_SS_HOVER_SENSE_OFF))
return 0;
if (touch_command(STMFTS_MS_KEY_SENSE_OFF))
return 0;
return 1;
return 0;
}
void touch_power_off()
{
touch_command(STMFTS_SLEEP_IN);
// Disable touchscreen power.
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);

View File

@@ -1,8 +1,8 @@
/*
* Touch driver for Nintendo Switch's STMicroelectronics FingerTip S touch controller
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
*
* Copyright (c) 2018 langerhans
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -44,11 +44,13 @@
#define STMFTS_FULL_FORCE_CALIBRATION 0xA2
#define STMFTS_MS_CX_TUNING 0xA3
#define STMFTS_SS_CX_TUNING 0xA4
#define STMFTS_ITO_CHECK 0xA7
#define STMFTS_RELEASEINFO 0xAA
#define STMFTS_WRITE_REG 0xB6
#define STMFTS_AUTO_CALIBRATION 0xC3
#define STMFTS_NOISE_WRITE 0xC7
#define STMFTS_NOISE_READ 0xC8
#define STMFTS_RW_FB_REG 0xD0 // read data
#define STMFTS_RW_FRAMEBUFFER_REG 0xD0
#define STMFTS_SAVE_CX_TUNING 0xFC
#define STMFTS_UNK0 0xB8 //Request compensation
@@ -74,10 +76,13 @@
#define STMFTS_EV_NOISE_WRITE 0x18
#define STMFTS_EV_CONTROLLER_READY 0x10
#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY 0x11
#define STMFTS_EV_STATUS 0x16
#define STMFTS_EV_DEBUG 0xDB
#define STMFTS_EV_STATUS_MS_CX_TUNING_DONE 1
#define STMFTS_EV_STATUS_SS_CX_TUNING_DONE 2
#define STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE 4
/* multi touch related event masks */
#define STMFTS_MASK_EVENT_ID 0x0F
#define STMFTS_MASK_TOUCH_ID 0xF0
@@ -95,12 +100,33 @@
#define STMFTS_DATA_MAX_SIZE (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)
#define STMFTS_MAX_FINGERS 10
typedef enum _touch_ito_error {
ITO_NO_ERROR = 0,
ITO_FORCE_OPEN,
ITO_SENSE_OPEN,
ITO_FORCE_SHRT_GND,
ITO_SENSE_SHRT_GND,
ITO_FORCE_SHRT_VCM,
ITO_SENSE_SHRT_VCM,
ITO_FORCE_SHRT_FORCE,
ITO_SENSE_SHRT_SENSE,
ITO_F2E_SENSE,
ITO_FPC_FORCE_OPEN,
ITO_FPC_SENSE_OPEN,
ITO_KEY_FORCE_OPEN,
ITO_KEY_SENSE_OPEN,
ITO_RESERVED0,
ITO_RESERVED1,
ITO_RESERVED2,
ITO_MAX_ERR_REACHED = 0xFF
} touch_ito_error;
typedef struct _touch_event {
u8 raw[8];
u16 type; // Event type.
u16 x; // Horizontal coordinates.
u16 y; // Vertical coordinates.
u8 z;
u32 z;
u8 fingers;
bool touch;
} touch_event;
@@ -112,10 +138,20 @@ typedef struct _touch_info {
u16 config_ver;
} touch_info;
int touch_power_on();
void touch_power_off();
typedef struct _touch_fw_info_t {
u32 fw_id;
u16 ftb_ver;
u16 fw_rev;
} touch_fw_info_t;
void touch_poll(touch_event *event);
touch_event touch_poll_wait();
int touch_get_fw_info(touch_fw_info_t *fw);
touch_info touch_get_info();
int touch_panel_ito_test(u8 *err);
int touch_execute_autotune();
int touch_sense_enable();
int touch_power_on();
void touch_power_off();
#endif /* __TOUCH_H_ */

View File

@@ -1,3 +1,19 @@
/*
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file lv_mem.c
* General and portable implementation of malloc and free.
@@ -11,6 +27,8 @@
#include "lv_math.h"
#include <string.h>
#include <assert.h>
#if LV_MEM_CUSTOM != 0
#include LV_MEM_CUSTOM_INCLUDE
#endif
@@ -41,9 +59,11 @@ typedef union {
MEM_UNIT d_size: 31; //Size off the data (1 means 4 bytes)
};
MEM_UNIT header; //The header (used + d_size)
uint32_t align[7]; //Align header size to 32 bytes
uint32_t align[8]; //Align header size to 32 bytes
} lv_mem_header_t;
static_assert(sizeof(lv_mem_header_t) == 32, "Node header must be 32 bytes!");
typedef struct {
lv_mem_header_t header;
uint8_t first_data; /*First data byte in the allocated data (Just for easily create a pointer)*/

View File

@@ -156,7 +156,7 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
return;
}
if(ext->text == text) {
if(ext->text == text && ext->static_txt == 0) {
/*If set its own text then reallocate it (maybe its size changed)*/
ext->text = lv_mem_realloc(ext->text, strlen(ext->text) + 1);
lv_mem_assert(ext->text);

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 M4xw
*
* This program is free software; you can redistribute it and/or modify it

View File

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

View File

@@ -36,7 +36,7 @@ u32 minerva_init()
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
// 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;
// Check if Minerva is already initialized.
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
@@ -60,6 +60,8 @@ u32 minerva_init()
// Ensure that Minerva is new.
if (mtc_tmp.init_done == MTC_INIT_MAGIC)
minerva_cfg = (void *)ep_addr;
else
mtc_cfg->init_done = 0;
// Copy Minerva context to Nyx storage.
if (minerva_cfg)

View File

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

View File

@@ -217,10 +217,12 @@ void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t
#define PATCHED_RELOC_ENTRY 0x40010000
#define EXT_PAYLOAD_ADDR 0xC0000000
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
#define COREBOOT_END_ADDR 0xD0000000
#define CBFS_DRAM_EN_ADDR 0x4003e000
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
static void *coreboot_addr;
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
{
memcpy((u8 *)payload_src, (u8 *)NYX_LOAD_ADDR, PATCHED_RELOC_SZ);
@@ -234,7 +236,7 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
if (payload_size == 0x7000)
{
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), coreboot_addr, 0x7000); //Bootblock
*(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
}
}
@@ -257,7 +259,6 @@ lv_res_t launch_payload(lv_obj_t *list)
if (f_open(&fp, path, FA_READ))
{
EPRINTFARGS("Payload file is missing!\n(%s)", path);
sd_unmount(false);
goto out;
}
@@ -269,13 +270,15 @@ lv_res_t launch_payload(lv_obj_t *list)
if (size < 0x30000)
buf = (void *)RCM_PAYLOAD_ADDR;
else
buf = (void *)COREBOOT_ADDR;
{
coreboot_addr = (void *)(COREBOOT_END_ADDR - size);
buf = coreboot_addr;
}
if (f_read(&fp, buf, size, NULL))
{
f_close(&fp);
sd_unmount(false);
goto out;
}
@@ -304,6 +307,8 @@ lv_res_t launch_payload(lv_obj_t *list)
}
out:
sd_unmount(false);
return LV_RES_OK;
}
@@ -395,8 +400,6 @@ void nyx_init_load_res()
h_cfg.rcm_patched = fuse_check_patched_rcm();
}
extern void pivot_stack(u32 stack_top);
#if (LV_LOG_PRINTF == 1)
#include "soc/clock.h"
#include "soc/gpio.h"
@@ -422,7 +425,7 @@ void ipl_main()
clock_enable_uart(UART_B);
uart_init(UART_B, 115200);
uart_send(UART_B, (u8 *)"Hekate-NYX: Hello!\r\n", 20);
uart_send(UART_B, (u8 *)"hekate-NYX: Hello!\r\n", 20);
uart_wait_idle(UART_B, UART_TX_IDLE);
#endif

View File

@@ -4,7 +4,7 @@
*
* Copyright (c) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@samsung.com>
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -137,6 +137,7 @@ int max77620_regulator_enable(u32 id, int enable)
return 1;
}
// LDO only.
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
{
if (id > REGULATOR_MAX)
@@ -168,9 +169,9 @@ void max77620_config_default()
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4);
}
void max77620_low_battery_monitor_config()
void max77620_low_battery_monitor_config(bool enable)
{
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1,
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_MPPLD |
MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
}

View File

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

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,

View File

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

View File

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

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
* under the terms and conditions of the GNU General Public License,

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -19,7 +20,7 @@
#include "i2c.h"
#include "../utils/util.h"
static u32 i2c_addrs[] = {
static const u32 i2c_addrs[] = {
0x7000C000, 0x7000C400, 0x7000C500,
0x7000C700, 0x7000D000, 0x7000D100
};
@@ -37,21 +38,39 @@ static void _i2c_wait(vu32 *base)
static int _i2c_send_pkt(u32 idx, u32 x, u8 *buf, u32 size)
{
if (size > 4)
if (size > 8)
return 0;
u32 tmp = 0;
memcpy(&tmp, buf, size);
vu32 *base = (vu32 *)i2c_addrs[idx];
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
base[I2C_CMD_DATA1] = tmp; //Set value.
base[I2C_CMD_ADDR0] = x << 1; //Set x (send mode).
if (size > 4)
{
memcpy(&tmp, buf, 4);
base[I2C_CMD_DATA1] = tmp; //Set value.
tmp = 0;
memcpy(&tmp, buf + 4, size - 4);
base[I2C_CMD_DATA2] = tmp;
}
else
{
memcpy(&tmp, buf, size);
base[I2C_CMD_DATA1] = tmp; //Set value.
}
base[I2C_CNFG] = ((size - 1) << 1) | 0x2800; //Set size and send mode.
_i2c_wait(base); //Kick transaction.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
u32 timeout = get_tmr_ms() + 1500;
while (base[I2C_STATUS] & 0x100)
;
{
if (get_tmr_ms() > timeout)
return 0;
}
if (base[I2C_STATUS] << 28)
return 0;
@@ -70,8 +89,13 @@ static int _i2c_recv_pkt(u32 idx, u8 *buf, u32 size, u32 x)
_i2c_wait(base); // Kick transaction.
base[I2C_CNFG] = (base[I2C_CNFG] & 0xFFFFFDFF) | 0x200;
u32 timeout = get_tmr_ms() + 1500;
while (base[I2C_STATUS] & 0x100)
;
{
if (get_tmr_ms() > timeout)
return 0;
}
if (base[I2C_STATUS] << 28)
return 0;
@@ -112,7 +136,7 @@ int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
{
u8 tmp[4];
if (size > 3)
if (size > 7)
return 0;
tmp[0] = y;
@@ -121,6 +145,11 @@ int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
return _i2c_send_pkt(idx, x, tmp, size + 1);
}
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x)
{
return _i2c_recv_pkt(idx, buf, size, x);
}
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
{
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);

View File

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

View File

@@ -30,7 +30,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
for (u32 i = 0; i < hdr->num_part_ents; i++)
{
gpt_entry_t *ent = (gpt_entry_t *)(buf + (hdr->part_ent_lba - 1) * NX_EMMC_BLOCKSIZE + i * sizeof(gpt_entry_t));
emmc_part_t *part = (emmc_part_t *)malloc(sizeof(emmc_part_t));
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
part->lba_start = ent->lba_start;
part->lba_end = ent->lba_end;
part->attrs = ent->attrs;

View File

@@ -1,7 +1,7 @@
/*
* Fan driver for Nintendo Switch
*
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -37,7 +37,6 @@ void set_fan_duty(u32 duty)
PINMUX_AUX(PINMUX_AUX_CAM1_PWDN) = PINMUX_TRISTATE | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 1;
gpio_config(GPIO_PORT_S, GPIO_PIN_7, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_S, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
gpio_write(GPIO_PORT_S, GPIO_PIN_7, GPIO_LOW);
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); // Max PWM to disable fan.
@@ -58,12 +57,19 @@ void set_fan_duty(u32 duty)
{
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (1 << 24); // Bit 24 is absolute 0%.
regulator_disable_5v(REGULATOR_5V_FAN);
// Disable fan.
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) =
PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_DOWN; // Set source to PWM1.
}
else // Set PWM duty.
{
// Fan power supply.
regulator_enable_5v(REGULATOR_5V_FAN);
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (inv_duty << 16);
// Enable fan.
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1.
}
curr_duty = duty;

View File

@@ -34,6 +34,16 @@ u8 btn_read()
return res;
}
u8 btn_read_vol()
{
u8 res = 0;
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7))
res |= BTN_VOL_DOWN;
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
res |= BTN_VOL_UP;
return res;
}
u8 btn_wait()
{
u8 res = 0, btn = btn_read();

View File

@@ -25,6 +25,7 @@
#define BTN_VOL_UP (1 << 2)
u8 btn_read();
u8 btn_read_vol();
u8 btn_wait();
u8 btn_wait_timeout(u32 time_ms, u8 mask);

View File

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

View File

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

View File

@@ -57,7 +57,7 @@ typedef struct _nyx_storage_t
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
nyx_info_t info;
mtc_config_t mtc_cfg;
emc_table_t mtc_table;
emc_table_t mtc_table[10];
} nyx_storage_t;
u32 get_tmr_us();