Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
562a6fb61d | ||
|
|
938562cc0a | ||
|
|
1e4d63731b | ||
|
|
8ff01301cb | ||
|
|
a664118fc7 | ||
|
|
87d376654b | ||
|
|
c6e92311f9 | ||
|
|
24d30a40f9 | ||
|
|
ae283aef59 | ||
|
|
e4f7928513 | ||
|
|
bd8a5ece58 |
9
Makefile
9
Makefile
@@ -8,11 +8,7 @@ include $(DEVKITARM)/base_rules
|
||||
|
||||
IPL_LOAD_ADDR := 0x40008000
|
||||
IPL_MAGIC := 0x43544349 #"ICTC"
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 1
|
||||
BLVERSION_HOTFX := 0
|
||||
|
||||
BL_RESERVED := 0
|
||||
include ./Versions.inc
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -60,7 +56,8 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
################################################################################
|
||||
|
||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||
#CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
|
||||
@@ -14,7 +14,7 @@ Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
|
||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
|
||||
| \|__ patches.ini | Add external patches. Can be skipped. A template can be found [here](./res/patches_template.ini) |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Can be skipped. |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Auto updated. Can be skipped. |
|
||||
| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
|
||||
| bootloader/res/ | Nyx user resources. Icons and more. |
|
||||
| \|__ background.bmp | Nyx - custom background. |
|
||||
@@ -55,6 +55,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
|
||||
|
||||
11
Versions.inc
Normal file
11
Versions.inc
Normal file
@@ -0,0 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 1
|
||||
BLVERSION_HOTFX := 1
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 0
|
||||
NYXVERSION_MINOR := 8
|
||||
NYXVERSION_HOTFX := 4
|
||||
NYXVERSION_RSVD := 0
|
||||
@@ -43,6 +43,7 @@ void set_default_configuration()
|
||||
h_cfg.backlight = 100;
|
||||
h_cfg.autohosoff = 0;
|
||||
h_cfg.autonogc = 1;
|
||||
h_cfg.updater2p = 0;
|
||||
h_cfg.brand = NULL;
|
||||
h_cfg.tagline = NULL;
|
||||
h_cfg.errors = 0;
|
||||
@@ -108,6 +109,9 @@ int create_config_entry()
|
||||
f_puts("\nautonogc=", &fp);
|
||||
itoa(h_cfg.autonogc, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nupdater2p=", &fp);
|
||||
itoa(h_cfg.updater2p, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
if (h_cfg.brand)
|
||||
{
|
||||
f_puts("\nbrand=", &fp);
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef struct _hekate_config
|
||||
u32 backlight;
|
||||
u32 autohosoff;
|
||||
u32 autonogc;
|
||||
u32 updater2p;
|
||||
char *brand;
|
||||
char *tagline;
|
||||
// Global temporary config.
|
||||
@@ -40,11 +41,6 @@ typedef struct _hekate_config
|
||||
u32 errors;
|
||||
} hekate_config;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
} hsysmodule_t;
|
||||
|
||||
void set_default_configuration();
|
||||
int create_config_entry();
|
||||
void config_autoboot();
|
||||
|
||||
@@ -157,13 +157,9 @@ void *tui_do_menu(menu_t *menu)
|
||||
gfx_con_setcol(0xFFCCCCCC, 1, 0xFF1B1B1B);
|
||||
gfx_putc('\n');
|
||||
|
||||
// Print erros, help and battery status.
|
||||
gfx_con_setpos(0, h_cfg.errors ? 1111 : 1127);
|
||||
gfx_printf("%k Warning: %k", 0xFF800000, 0xFF555555);
|
||||
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
||||
gfx_printf("Sleep mode library is missing!\n");
|
||||
gfx_printf(" Nyx is missing!\n");
|
||||
|
||||
// Print errors, help and battery status.
|
||||
gfx_con_setpos(0, 1127);
|
||||
gfx_printf("%k Warning: %k Nyx is missing!", 0xFF800000, 0xFF555555);
|
||||
gfx_con_setpos(0, 1191);
|
||||
gfx_printf("%k VOL: Move up/down\n PWR: Select option%k", 0xFF555555, 0xFFCCCCCC);
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
extern void *sd_file_read(const char *path, u32 *fsize);
|
||||
extern bool is_ipl_updated(void *buf, char *path, bool force);
|
||||
|
||||
#define FSS0_MAGIC 0x30535346
|
||||
#define CNT_TYPE_FSP 0
|
||||
#define CNT_TYPE_EXO 1
|
||||
@@ -62,7 +65,32 @@ typedef struct _fss_content_t
|
||||
char name[0x10];
|
||||
} fss_content_t;
|
||||
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
static void _update_r2p(const char *path)
|
||||
{
|
||||
char *r2p_path = malloc(256);
|
||||
u32 path_len = strlen(path);
|
||||
strcpy(r2p_path, path);
|
||||
|
||||
while(path_len)
|
||||
{
|
||||
if ((r2p_path[path_len - 1] == '/') || (r2p_path[path_len - 1] == 0x5C))
|
||||
{
|
||||
r2p_path[path_len] = 0;
|
||||
strcat(r2p_path, "reboot_payload.bin");
|
||||
u8 *r2p_payload = sd_file_read(r2p_path, NULL);
|
||||
|
||||
is_ipl_updated(r2p_payload, r2p_path, h_cfg.updater2p ? true : false);
|
||||
|
||||
free(r2p_payload);
|
||||
break;
|
||||
}
|
||||
path_len--;
|
||||
}
|
||||
|
||||
free(r2p_path);
|
||||
}
|
||||
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *path)
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
@@ -78,7 +106,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
if (stock && ctxt->pkg1_id->kb <= KB_FIRMWARE_VERSION_620 && (!emu_cfg.enabled || h_cfg.emummc_force_disable))
|
||||
return 1;
|
||||
|
||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||
return 0;
|
||||
|
||||
ctxt->atmosphere = true;
|
||||
@@ -139,6 +167,8 @@ int parse_fss(launch_ctxt_t *ctxt, const char *value)
|
||||
gfx_printf("Done!\n");
|
||||
f_close(&fp);
|
||||
|
||||
_update_r2p(path);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@
|
||||
|
||||
#include "hos.h"
|
||||
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *value);
|
||||
int parse_fss(launch_ctxt_t *ctxt, const char *path);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -264,6 +264,7 @@ KERNEL_PATCHSET_DEF(_kernel_5_patchset,
|
||||
{ SVC_VERIFY_DS, 0x45E6C, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x5513C, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_SYSM_INCR, 0x54E30, _MOVZW(8, 0x1E00, LSL16), NULL }, // System memory pool increase.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_500, _B(ID_SND_OFF_500, FREE_CODE_OFF_1ST_500), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_500, sizeof(PRC_ID_SND_500) >> 2, PRC_ID_SND_500}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_500 + sizeof(PRC_ID_SND_500), // Branch back and skip 2 instructions.
|
||||
@@ -279,6 +280,7 @@ KERNEL_PATCHSET_DEF(_kernel_6_patchset,
|
||||
{ SVC_VERIFY_DS, 0x47EA0, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x57548, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_SYSM_INCR, 0x57330, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_600, _B(ID_SND_OFF_600, FREE_CODE_OFF_1ST_600), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_600, sizeof(PRC_ID_SND_600) >> 2, PRC_ID_SND_600}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_600 + sizeof(PRC_ID_SND_600), // Branch back and skip 4 instructions.
|
||||
@@ -294,6 +296,7 @@ KERNEL_PATCHSET_DEF(_kernel_7_patchset,
|
||||
{ SVC_VERIFY_DS, 0x49E5C, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x581B0, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_SYSM_INCR, 0x57F98, _MOVZW(8, 0x1D80, LSL16), NULL }, // System memory pool increase.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_700, _B(ID_SND_OFF_700, FREE_CODE_OFF_1ST_700), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_700, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_700 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
|
||||
@@ -309,6 +312,7 @@ KERNEL_PATCHSET_DEF(_kernel_8_patchset,
|
||||
{ SVC_VERIFY_DS, 0x4D15C, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x5BFAC, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_SYSM_INCR, 0x5F9A4, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_800, _B(ID_SND_OFF_800, FREE_CODE_OFF_1ST_800), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_800, sizeof(PRC_ID_SND_700) >> 2, PRC_ID_SND_700}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_800 + sizeof(PRC_ID_SND_700), // Branch back and skip 4 instructions.
|
||||
@@ -324,6 +328,7 @@ KERNEL_PATCHSET_DEF(_kernel_9_patchset,
|
||||
{ SVC_VERIFY_DS, 0x50628, _NOP(), NULL }, // Disable SVC verifications
|
||||
{ DEBUG_MODE_EN, 0x609E8, _MOVZX(8, 1, 0), NULL }, // Enable Debug Patch
|
||||
// Atmosphère kernel patches.
|
||||
{ ATM_SYSM_INCR, 0x6493C, _MOVZW(19, 0x1D80, LSL16), NULL }, // System memory pool increase.
|
||||
{ ATM_GEN_PATCH, ID_SND_OFF_900, _B(ID_SND_OFF_900, FREE_CODE_OFF_1ST_900), NULL}, // Send process id branch.
|
||||
{ ATM_ARR_PATCH, FREE_CODE_OFF_1ST_900, sizeof(PRC_ID_SND_900) >> 2, PRC_ID_SND_900}, // Send process id code.
|
||||
{ ATM_GEN_PATCH, FREE_CODE_OFF_1ST_900 + sizeof(PRC_ID_SND_900), // Branch back and skip 4 instructions.
|
||||
|
||||
@@ -54,10 +54,11 @@ enum
|
||||
SVC_GENERIC = 0,
|
||||
// Generic instruction patches.
|
||||
SVC_VERIFY_DS = 0x10,
|
||||
DEBUG_MODE_EN,
|
||||
ATM_GEN_PATCH,
|
||||
DEBUG_MODE_EN = 0x11,
|
||||
ATM_GEN_PATCH = 0x12,
|
||||
ATM_SYSM_INCR = ATM_GEN_PATCH,
|
||||
// >4 bytes patches. Value is a pointer of a u32 array.
|
||||
ATM_ARR_PATCH,
|
||||
ATM_ARR_PATCH = 0x13,
|
||||
};
|
||||
|
||||
typedef struct _pkg2_hdr_t
|
||||
|
||||
@@ -252,19 +252,39 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
||||
}
|
||||
}
|
||||
|
||||
bool is_ipl_updated(void *buf)
|
||||
bool is_ipl_updated(void *buf, char *path, bool force)
|
||||
{
|
||||
ipl_ver_meta_t *update_ft = (ipl_ver_meta_t *)(buf + PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||
|
||||
if (update_ft->magic == ipl_ver.magic)
|
||||
{
|
||||
if (byte_swap_32(update_ft->version) <= byte_swap_32(ipl_ver.version))
|
||||
return true;
|
||||
return false;
|
||||
// Check if newer version.
|
||||
if (!force && (update_ft->magic == ipl_ver.magic))
|
||||
if (byte_swap_32(update_ft->version) > byte_swap_32(ipl_ver.version))
|
||||
return false;
|
||||
|
||||
// Update if old or broken.
|
||||
if ((force && (update_ft->magic != ipl_ver.magic)) ||
|
||||
(byte_swap_32(update_ft->version) < byte_swap_32(ipl_ver.version)))
|
||||
{
|
||||
FIL fp;
|
||||
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
||||
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||
memset(tmp_cfg, 0, sizeof(boot_cfg_t));
|
||||
|
||||
f_open(&fp, path, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
|
||||
|
||||
// Write needed tag in case injected ipl uses old versioning.
|
||||
f_write(&fp, "ICTC49", 6, NULL);
|
||||
|
||||
// Reset boot storage configuration.
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||
|
||||
f_close(&fp);
|
||||
free(tmp_cfg);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int launch_payload(char *path, bool update)
|
||||
@@ -301,7 +321,7 @@ int launch_payload(char *path, bool update)
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
if (update && is_ipl_updated(buf))
|
||||
if (update && is_ipl_updated(buf, path, false))
|
||||
goto out;
|
||||
|
||||
sd_unmount();
|
||||
@@ -678,6 +698,8 @@ out:
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
#define NYX_VER_OFF 0x9C
|
||||
|
||||
void nyx_load_run()
|
||||
{
|
||||
sd_mount();
|
||||
@@ -688,6 +710,9 @@ void nyx_load_run()
|
||||
|
||||
sd_unmount();
|
||||
|
||||
u32 expected_nyx_ver = ((NYX_VER_MJ + '0') << 24) | ((NYX_VER_MN + '0') << 16) | ((NYX_VER_HF + '0') << 8);
|
||||
u32 nyx_ver = byte_swap_32(*(u32 *)(nyx + NYX_VER_OFF));
|
||||
|
||||
gfx_clear_grey(0x1B);
|
||||
u8 *BOOTLOGO = (void *)malloc(0x4000);
|
||||
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
||||
@@ -695,16 +720,29 @@ void nyx_load_run()
|
||||
free(BOOTLOGO);
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
// Check if Nyx version is old.
|
||||
if (nyx_ver < expected_nyx_ver)
|
||||
{
|
||||
h_cfg.errors |= ERR_SYSOLD_NYX;
|
||||
|
||||
gfx_con_setpos(0, 0);
|
||||
WPRINTF("Old Nyx GUI found! There will be dragons!\n");
|
||||
WPRINTF("\nUpdate your bootloader folder!\n\n");
|
||||
WPRINTF("Press any key...");
|
||||
|
||||
msleep(2000);
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
nyx_str->info.errors = h_cfg.errors;
|
||||
nyx_str->cfg = 0;
|
||||
if (b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP)
|
||||
{
|
||||
b_cfg.extra_cfg &= ~(EXTRA_CFG_NYX_DUMP);
|
||||
nyx_str->cfg |= NYX_CFG_DUMP;
|
||||
}
|
||||
if (nyx_str->mtc_cfg.mtc_table)
|
||||
nyx_str->cfg |= NYX_CFG_MINERVA;
|
||||
|
||||
nyx_str->version = ipl_ver.version - 0x303030;
|
||||
nyx_str->version = ipl_ver.version - 0x303030; // Convert ASCII to numbers.
|
||||
|
||||
//memcpy((u8 *)nyx_str->irama, (void *)IRAM_BASE, 0x8000);
|
||||
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
||||
@@ -749,7 +787,7 @@ static ini_sec_t *get_ini_sec_from_id(ini_sec_t *ini_sec, char **bootlogoCustomE
|
||||
return cfg_sec;
|
||||
}
|
||||
|
||||
void auto_launch_firmware()
|
||||
static void _auto_launch_firmware()
|
||||
{
|
||||
if(b_cfg.extra_cfg & EXTRA_CFG_NYX_DUMP)
|
||||
{
|
||||
@@ -824,6 +862,8 @@ void auto_launch_firmware()
|
||||
h_cfg.autohosoff = atoi(kv->val);
|
||||
else if (!strcmp("autonogc", kv->key))
|
||||
h_cfg.autonogc = atoi(kv->val);
|
||||
else if (!strcmp("updater2p", kv->key))
|
||||
h_cfg.updater2p = atoi(kv->val);
|
||||
else if (!strcmp("brand", kv->key))
|
||||
{
|
||||
h_cfg.brand = malloc(strlen(kv->val) + 1);
|
||||
@@ -1019,7 +1059,7 @@ skip_list:
|
||||
hos_launch(cfg_sec);
|
||||
|
||||
EPRINTF("\nFailed to launch HOS!");
|
||||
gfx_printf("\nPress any key and try again...\n");
|
||||
gfx_printf("\nPress any key...\n");
|
||||
msleep(500);
|
||||
btn_wait();
|
||||
}
|
||||
@@ -1038,7 +1078,7 @@ out:
|
||||
sd_unmount();
|
||||
}
|
||||
|
||||
void patched_rcm_protection()
|
||||
static void _patched_rcm_protection()
|
||||
{
|
||||
sdmmc_storage_t storage;
|
||||
sdmmc_t sdmmc;
|
||||
@@ -1080,7 +1120,28 @@ void patched_rcm_protection()
|
||||
sdmmc_storage_end(&storage);
|
||||
}
|
||||
|
||||
void about()
|
||||
static void _show_errors()
|
||||
{
|
||||
if (h_cfg.errors)
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
||||
if (h_cfg.errors & ERR_LIBSYS_LP0)
|
||||
WPRINTF("Missing LP0 (sleep mode) library!\n");
|
||||
if (h_cfg.errors & ERR_SYSOLD_MTC)
|
||||
WPRINTF("Missing or old Minerva library!\n");
|
||||
|
||||
WPRINTF("\nUpdate your bootloader folder!\n\n");
|
||||
WPRINTF("Press any key...");
|
||||
|
||||
msleep(2000);
|
||||
btn_wait();
|
||||
}
|
||||
}
|
||||
|
||||
static void _about()
|
||||
{
|
||||
static const char credits[] =
|
||||
"\nhekate (c) 2018 naehrwert, st4rk\n\n"
|
||||
@@ -1228,11 +1289,11 @@ ment_t ment_top[] = {
|
||||
MDEF_HANDLER("Reboot (RCM)", reboot_rcm),
|
||||
MDEF_HANDLER("Power off", power_off),
|
||||
MDEF_CAPTION("---------------", 0xFF444444),
|
||||
MDEF_HANDLER("About", about),
|
||||
MDEF_HANDLER("About", _about),
|
||||
MDEF_END()
|
||||
};
|
||||
|
||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.1.0", 0, 0 };
|
||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.1.1", 0, 0 };
|
||||
|
||||
extern void pivot_stack(u32 stack_top);
|
||||
|
||||
@@ -1262,7 +1323,8 @@ void ipl_main()
|
||||
h_cfg.errors |= ERR_LIBSYS_LP0;
|
||||
|
||||
// Train DRAM and switch to max frequency.
|
||||
minerva_init();
|
||||
if (minerva_init())
|
||||
h_cfg.errors |= ERR_SYSOLD_MTC;
|
||||
|
||||
display_init();
|
||||
|
||||
@@ -1286,13 +1348,16 @@ void ipl_main()
|
||||
secmon_exo_check_panic();
|
||||
|
||||
// Check if RCM is patched and protect from a possible brick.
|
||||
patched_rcm_protection();
|
||||
_patched_rcm_protection();
|
||||
|
||||
// Load emuMMC configuration from SD.
|
||||
emummc_load_cfg();
|
||||
|
||||
// Show library errors.
|
||||
_show_errors();
|
||||
|
||||
// Load saved configuration and auto boot if enabled.
|
||||
auto_launch_firmware();
|
||||
_auto_launch_firmware();
|
||||
|
||||
minerva_change_freq(FREQ_800);
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ void free(void *buf)
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
{
|
||||
u32 count = 0;
|
||||
memset(mon, 0, sizeof(heap_monitor));
|
||||
memset(mon, 0, sizeof(heap_monitor_t));
|
||||
|
||||
hnode_t *node = _heap.first;
|
||||
while (true)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
void minerva_init()
|
||||
u32 minerva_init()
|
||||
{
|
||||
u32 curr_ram_idx = 0;
|
||||
|
||||
@@ -37,13 +37,17 @@ void minerva_init()
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
|
||||
|
||||
mtc_cfg->init_done = MTC_NEW_MAGIC;
|
||||
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);
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
|
||||
// Ensure that Minerva is new.
|
||||
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
// Get current frequency
|
||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
||||
@@ -69,6 +73,8 @@ void minerva_init()
|
||||
// Switch to max.
|
||||
mtc_cfg->rate_to = 1600000;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void minerva_change_freq(minerva_freq_t freq)
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef enum
|
||||
} minerva_freq_t;
|
||||
|
||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
void minerva_init();
|
||||
u32 minerva_init();
|
||||
void minerva_change_freq(minerva_freq_t freq);
|
||||
void minerva_periodic_training();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -25,11 +26,12 @@
|
||||
|
||||
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
|
||||
|
||||
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
|
||||
#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||
#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||
#define _ADRP(r, o) (0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F))
|
||||
#define _BL(a, o) (0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||
#define _B(a, o) (0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||
#define _MOVKX(r, i, s) (0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _MOVZX(r, i, s) (0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _MOVZW(r, i, s) (0x52800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _NOP() 0xD503201F
|
||||
|
||||
#endif
|
||||
|
||||
@@ -81,5 +81,8 @@ u8 btn_wait_timeout(u32 time_ms, u8 mask)
|
||||
};
|
||||
|
||||
// Timed out.
|
||||
return 0;
|
||||
if (!single_button || !time_ms)
|
||||
return (res & mask);
|
||||
else
|
||||
return 0; // Return no button press if single button requested.
|
||||
}
|
||||
|
||||
@@ -21,8 +21,17 @@
|
||||
#include "types.h"
|
||||
#include "../mem/minerva.h"
|
||||
|
||||
#define NYX_CFG_DUMP (1 << 7)
|
||||
#define NYX_CFG_MINERVA (1 << 8)
|
||||
typedef enum
|
||||
{
|
||||
NYX_CFG_DUMP = (1 << 7),
|
||||
} nyx_cfg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
ERR_SYSOLD_NYX = (1 << 1),
|
||||
ERR_SYSOLD_MTC = (1 << 2),
|
||||
} hekate_errors_t;
|
||||
|
||||
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000))
|
||||
@@ -33,13 +42,20 @@ typedef struct _cfg_op_t
|
||||
u32 val;
|
||||
} cfg_op_t;
|
||||
|
||||
typedef struct _nyx_info_t
|
||||
{
|
||||
u32 rsvd;
|
||||
u32 errors;
|
||||
} nyx_info_t;
|
||||
|
||||
typedef struct _nyx_storage_t
|
||||
{
|
||||
u32 version;
|
||||
u32 cfg;
|
||||
u8 irama[0x8000];
|
||||
u8 hekate[0x30000];
|
||||
u8 rsvd[0x800000];
|
||||
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
|
||||
nyx_info_t info;
|
||||
mtc_config_t mtc_cfg;
|
||||
emc_table_t mtc_table;
|
||||
} nyx_storage_t;
|
||||
|
||||
10
nyx/Makefile
10
nyx/Makefile
@@ -8,11 +8,7 @@ include $(DEVKITARM)/base_rules
|
||||
|
||||
NYX_LOAD_ADDR := 0x81000000
|
||||
NYX_MAGIC := 0x43544347 #"GCTC"
|
||||
BLVERSION_MAJOR := 0
|
||||
BLVERSION_MINOR := 8
|
||||
BLVERSION_HOTFX := 3
|
||||
|
||||
BL_RESERVED := 0
|
||||
include ./../Versions.inc
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -72,8 +68,8 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
|
||||
################################################################################
|
||||
|
||||
CUSTOMDEFINES += -DNYX_LOAD_ADDR=$(NYX_LOAD_ADDR) -DBL_MAGIC=$(NYX_MAGIC)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED)
|
||||
CUSTOMDEFINES += -DNYX_LOAD_ADDR=$(NYX_LOAD_ADDR) -DNYX_MAGIC=$(NYX_MAGIC)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=1
|
||||
|
||||
@@ -43,6 +43,7 @@ void set_default_configuration()
|
||||
h_cfg.backlight = 100;
|
||||
h_cfg.autohosoff = 0;
|
||||
h_cfg.autonogc = 1;
|
||||
h_cfg.updater2p = 0;
|
||||
h_cfg.brand = NULL;
|
||||
h_cfg.tagline = NULL;
|
||||
h_cfg.errors = 0;
|
||||
@@ -108,6 +109,9 @@ int create_config_entry()
|
||||
f_puts("\nautonogc=", &fp);
|
||||
itoa(h_cfg.autonogc, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nupdater2p=", &fp);
|
||||
itoa(h_cfg.updater2p, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
if (h_cfg.brand)
|
||||
{
|
||||
f_puts("\nbrand=", &fp);
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef struct _hekate_config
|
||||
u32 backlight;
|
||||
u32 autohosoff;
|
||||
u32 autonogc;
|
||||
u32 updater2p;
|
||||
char *brand;
|
||||
char *tagline;
|
||||
// Global temporary config.
|
||||
@@ -40,11 +41,6 @@ typedef struct _hekate_config
|
||||
u32 errors;
|
||||
} hekate_config;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
} hsysmodule_t;
|
||||
|
||||
void set_default_configuration();
|
||||
int create_config_entry();
|
||||
|
||||
|
||||
@@ -721,9 +721,8 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
|
||||
" Copyright (c) 2016 Gabor Kiss-Vamosi"
|
||||
);
|
||||
|
||||
|
||||
lv_obj_t * lbl_octopus = lv_label_create(parent, NULL);
|
||||
lv_obj_align(lbl_octopus, lbl_credits, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI, 0);
|
||||
lv_obj_align(lbl_octopus, lbl_credits, LV_ALIGN_OUT_RIGHT_TOP, -LV_DPI / 10, 0);
|
||||
lv_ta_set_style(lbl_octopus, LV_TA_STYLE_BG, &monospace_text);
|
||||
lv_label_set_recolor(lbl_octopus, true);
|
||||
|
||||
@@ -757,7 +756,7 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent)
|
||||
lv_obj_align(ctcaer_img, lbl_octopus, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI * 2 / 3);
|
||||
|
||||
char version[32];
|
||||
s_printf(version, "Nyx v%d.%d.%d", BL_VER_MJ, BL_VER_MN, BL_VER_HF);
|
||||
s_printf(version, "Nyx v%d.%d.%d", NYX_VER_MJ, NYX_VER_MN, NYX_VER_HF);
|
||||
lv_obj_t * lbl_ver = lv_label_create(parent, NULL);
|
||||
lv_obj_align(lbl_ver, ctcaer_img, LV_ALIGN_OUT_BOTTOM_RIGHT, -LV_DPI / 20, LV_DPI / 4);
|
||||
lv_ta_set_style(lbl_ver, LV_TA_STYLE_BG, &monospace_text);
|
||||
|
||||
@@ -137,7 +137,7 @@ void free(void *buf)
|
||||
void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
{
|
||||
u32 count = 0;
|
||||
memset(mon, 0, sizeof(heap_monitor));
|
||||
memset(mon, 0, sizeof(heap_monitor_t));
|
||||
|
||||
hnode_t *node = _heap.first;
|
||||
while (true)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
void minerva_init()
|
||||
u32 minerva_init()
|
||||
{
|
||||
u32 curr_ram_idx = 0;
|
||||
|
||||
@@ -37,23 +37,26 @@ void minerva_init()
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
|
||||
|
||||
// Set table to ram.
|
||||
// Check if Minerva is already initialized.
|
||||
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
|
||||
{
|
||||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN; // Retrain if needed.
|
||||
u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtc_config_t mtc_tmp;
|
||||
|
||||
mtc_tmp.mtc_table = mtc_cfg->mtc_table;
|
||||
mtc_tmp.sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
||||
mtc_tmp.init_done = MTC_NEW_MAGIC;
|
||||
|
||||
u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp);
|
||||
|
||||
// Ensure that Minerva is new.
|
||||
if (mtc_tmp.init_done == MTC_INIT_MAGIC)
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
|
||||
@@ -63,7 +66,7 @@ void minerva_init()
|
||||
}
|
||||
|
||||
if (!minerva_cfg)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
// Get current frequency
|
||||
for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++)
|
||||
@@ -89,6 +92,8 @@ void minerva_init()
|
||||
// Switch to max.
|
||||
mtc_cfg->rate_to = 1600000;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void minerva_change_freq(minerva_freq_t freq)
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef enum
|
||||
} minerva_freq_t;
|
||||
|
||||
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
|
||||
void minerva_init();
|
||||
u32 minerva_init();
|
||||
void minerva_change_freq(minerva_freq_t freq);
|
||||
void minerva_periodic_training();
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ u8 *Kc_MENU_LOGO;
|
||||
hekate_config h_cfg;
|
||||
|
||||
const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver = {
|
||||
.magic = BL_MAGIC,
|
||||
.version = (BL_VER_MJ + '0') | ((BL_VER_MN + '0') << 8) | ((BL_VER_HF + '0') << 16),
|
||||
.magic = NYX_MAGIC,
|
||||
.version = (NYX_VER_MJ + '0') | ((NYX_VER_MN + '0') << 8) | ((NYX_VER_HF + '0') << 16),
|
||||
.rsvd0 = 0,
|
||||
.rsvd1 = 0
|
||||
};
|
||||
@@ -341,6 +341,8 @@ void load_saved_configuration()
|
||||
h_cfg.autohosoff = atoi(kv->val);
|
||||
else if (!strcmp("autonogc", kv->key))
|
||||
h_cfg.autonogc = atoi(kv->val);
|
||||
else if (!strcmp("updater2p", kv->key))
|
||||
h_cfg.updater2p = atoi(kv->val);
|
||||
else if (!strcmp("brand", kv->key))
|
||||
{
|
||||
h_cfg.brand = malloc(strlen(kv->val) + 1);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -25,11 +26,12 @@
|
||||
|
||||
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
|
||||
|
||||
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
|
||||
#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||
#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
|
||||
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
|
||||
#define _ADRP(r, o) (0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F))
|
||||
#define _BL(a, o) (0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||
#define _B(a, o) (0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
|
||||
#define _MOVKX(r, i, s) (0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _MOVZX(r, i, s) (0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _MOVZW(r, i, s) (0x52800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
|
||||
#define _NOP() 0xD503201F
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,8 +21,17 @@
|
||||
#include "types.h"
|
||||
#include "../mem/minerva.h"
|
||||
|
||||
#define NYX_CFG_DUMP (1 << 7)
|
||||
#define NYX_CFG_MINERVA (1 << 8)
|
||||
typedef enum
|
||||
{
|
||||
NYX_CFG_DUMP = (1 << 7),
|
||||
} nyx_cfg_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_LIBSYS_LP0 = (1 << 0),
|
||||
ERR_SYSOLD_NYX = (1 << 1),
|
||||
ERR_SYSOLD_MTC = (1 << 2),
|
||||
} hekate_errors_t;
|
||||
|
||||
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000))
|
||||
@@ -33,13 +42,20 @@ typedef struct _cfg_op_t
|
||||
u32 val;
|
||||
} cfg_op_t;
|
||||
|
||||
typedef struct _nyx_info_t
|
||||
{
|
||||
u32 rsvd;
|
||||
u32 errors;
|
||||
} nyx_info_t;
|
||||
|
||||
typedef struct _nyx_storage_t
|
||||
{
|
||||
u32 version;
|
||||
u32 cfg;
|
||||
u8 irama[0x8000];
|
||||
u8 hekate[0x30000];
|
||||
u8 rsvd[0x800000];
|
||||
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
|
||||
nyx_info_t info;
|
||||
mtc_config_t mtc_cfg;
|
||||
emc_table_t mtc_table;
|
||||
} nyx_storage_t;
|
||||
|
||||
Reference in New Issue
Block a user