diff --git a/ipl/btn.c b/ipl/btn.c index 72a71eb..eb12ffe 100755 --- a/ipl/btn.c +++ b/ipl/btn.c @@ -18,6 +18,7 @@ #include "i2c.h" #include "gpio.h" #include "t210.h" +#include "util.h" u32 btn_read() { @@ -53,5 +54,22 @@ u32 btn_wait() else if (pwr) res &= 0xFFFFFFFE; } while (btn == res); + + return res; +} + +u32 btn_wait_timeout(u32 time_ms) +{ + u32 timeout = get_tmr() + (time_ms * 1000); + u32 res = btn_read(); + u32 btn = res; + + do + { + //Keep the new value until timeout is reached + if (btn == res) + res = btn_read(); + } while (get_tmr() < timeout); + return res; } diff --git a/ipl/btn.h b/ipl/btn.h index 8c5a8c5..09ff329 100755 --- a/ipl/btn.h +++ b/ipl/btn.h @@ -25,5 +25,6 @@ u32 btn_read(); u32 btn_wait(); +u32 btn_wait_timeout(u32 time_ms); #endif diff --git a/ipl/gpio.c b/ipl/gpio.c index 596af03..fb75ee8 100755 --- a/ipl/gpio.c +++ b/ipl/gpio.c @@ -90,5 +90,5 @@ void gpio_write(u32 port, u32 pins, int high) int gpio_read(u32 port, u32 pins) { - return GPIO(_gpio_in[port]) & pins ? 1 : 0; + return (GPIO(_gpio_in[port]) & pins) ? 1 : 0; } diff --git a/ipl/heap.c b/ipl/heap.c index c90607b..12bfb44 100755 --- a/ipl/heap.c +++ b/ipl/heap.c @@ -97,6 +97,7 @@ static void _heap_free(heap_t *heap, u32 addr) while (node) { if (!node->used) + { if (node->prev && !node->prev->used) { node->prev->size += node->size + sizeof(hnode_t); @@ -104,6 +105,7 @@ static void _heap_free(heap_t *heap, u32 addr) if (node->next) node->next->prev = node->prev; } + } node = node->next; } } @@ -129,5 +131,6 @@ void *calloc(u32 num, u32 size) void free(void *buf) { - _heap_free(&_heap, (u32)buf); + if (buf != NULL) + _heap_free(&_heap, (u32)buf); } diff --git a/ipl/hos.c b/ipl/hos.c index d3c45a4..a8df029 100755 --- a/ipl/hos.c +++ b/ipl/hos.c @@ -109,7 +109,7 @@ u32 crc32c(const u8 *buf, u32 len) { crc ^= *buf++; for (int i = 0; i < 8; i++) - crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1; + crc = (crc & 1) ? (crc >> 1) ^ CRC32C_POLY : crc >> 1; } return ~crc; } diff --git a/ipl/ini.c b/ipl/ini.c index 8551203..3e4401e 100755 --- a/ipl/ini.c +++ b/ipl/ini.c @@ -91,3 +91,51 @@ int ini_parse(link_t *dst, char *ini_path) return 1; } + +void ini_free(link_t *dst) +{ + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, dst, link) + { + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + free(kv->key); + free(kv->val); + free(kv); + } + free(ini_sec->name); + free(ini_sec); + } +} + +ini_sec_t *ini_clone_section(ini_sec_t *cfg) +{ + if (cfg == NULL) + return NULL; + + ini_sec_t *csec = (ini_sec_t *)malloc(sizeof(ini_sec_t)); + list_init(&csec->kvs); + + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link) + { + ini_kv_t *kvcfg = (ini_kv_t *)malloc(sizeof(ini_kv_t)); + kvcfg->key = _strdup(kv->key); + kvcfg->val = _strdup(kv->val); + list_append(&csec->kvs, &kvcfg->link); + } + + return csec; +} + +void ini_free_section(ini_sec_t *cfg) +{ + if (cfg == NULL) + return; + + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link) + { + free(kv->key); + free(kv->val); + free(kv); + } + free(cfg); +} diff --git a/ipl/ini.h b/ipl/ini.h index 091009e..6f8d692 100755 --- a/ipl/ini.h +++ b/ipl/ini.h @@ -35,5 +35,8 @@ typedef struct _ini_sec_t } ini_sec_t; int ini_parse(link_t *dst, char *ini_path); +void ini_free(link_t *dst); +ini_sec_t *ini_clone_section(ini_sec_t *cfg); +void ini_free_section(ini_sec_t *cfg); #endif diff --git a/ipl/main.c b/ipl/main.c index bb1b8da..25f16fd 100755 --- a/ipl/main.c +++ b/ipl/main.c @@ -870,7 +870,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) // Verify part if (dump_emmc_verify(storage, lba_curr, outFilename, NUM_SECTORS_PER_ITER, part)) { - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); return 0; @@ -938,7 +938,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) { EPRINTFARGS("\nFailed to read %d blocks @ LBA %08X from eMMC. Aborting..\n", num, lba_curr); - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); f_close(&fp); @@ -949,7 +949,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) if (res) { EPRINTFARGS("\nFatal error (%d) when writing to SD Card", res); - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); f_close(&fp); @@ -982,7 +982,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) // Verify last part or single file backup if (dump_emmc_verify(storage, lba_curr, outFilename, NUM_SECTORS_PER_ITER, part)) { - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); return 0; @@ -1099,7 +1099,7 @@ static void dump_emmc_selected(dumpType_t dumpType) gfx_printf(&gfx_con, "Time taken: %d seconds.\n", (get_tmr() - timer) / 1000000); sdmmc_storage_end(&storage); if (res) - gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key.\n",0xFF00FF96, 0xFFCCCCCC); + gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key...\n",0xFF00FF96, 0xFFCCCCCC); out:; btn_wait(); @@ -1112,15 +1112,10 @@ void dump_emmc_rawnand() { dump_emmc_selected(DUMP_RAW); } void dump_package1() { - u8 *pkg1 = (u8 *)malloc(0x40000); - u8 *warmboot = (u8 *)malloc(0x40000); - u8 *secmon = (u8 *)malloc(0x40000); - u8 *loader = (u8 *)malloc(0x40000); - - memset(pkg1, 0, 0x40000); - memset(warmboot, 0, 0x40000); - memset(secmon, 0, 0x40000); - memset(loader, 0, 0x40000); + u8 *pkg1 = (u8 *)calloc(1, 0x40000); + u8 *warmboot = (u8 *)calloc(1, 0x40000); + u8 *secmon = (u8 *)calloc(1, 0x40000); + u8 *loader = (u8 *)calloc(1, 0x40000); gfx_clear_grey(&gfx_ctxt, 0x1B); gfx_con_setpos(&gfx_con, 0, 0); @@ -1137,7 +1132,7 @@ void dump_package1() } sdmmc_storage_set_mmc_partition(&storage, 1); - //Read package1. + // Read package1. sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1); const pkg1_id_t *pkg1_id = pkg1_identify(pkg1); const pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20); @@ -1151,13 +1146,13 @@ void dump_package1() u8 * keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE); sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob); - // decrypt + // Decrypt keygen(keyblob, pkg1_id->kb, (u8 *)pkg1 + pkg1_id->tsec_off); pkg1_decrypt(pkg1_id, pkg1); pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1); - // display info + // Display info gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->ldr_size); gfx_printf(&gfx_con, "%kNX Bootloader ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->ldr_off); @@ -1169,28 +1164,28 @@ void dump_package1() gfx_printf(&gfx_con, "%kWarmboot size: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->wb_size); gfx_printf(&gfx_con, "%kWarmboot ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->wb_off); - // dump package1 + // Dump package1 if (sd_save_to_file(pkg1, 0x40000, "pkg1_decr.bin")) { EPRINTF("\nFailed to create pkg1_decr.bin"); goto out; } gfx_puts(&gfx_con, "\npackage1 dumped to pkg1_decr.bin\n"); - // dump nxbootloader + // Dump nxbootloader if (sd_save_to_file(loader, hdr->ldr_size, "nxloader.bin")) { EPRINTF("\nFailed to create nxloader.bin"); goto out; } gfx_puts(&gfx_con, "NX Bootloader dumped to nxloader.bin\n"); - // dump secmon + // Dump secmon if (sd_save_to_file(secmon, hdr->sm_size, "secmon.bin")) { EPRINTF("\nFailed to create secmon.bin"); goto out; } gfx_puts(&gfx_con, "Secure Monitor dumped to secmon.bin\n"); - // dump warmboot + // Dump warmboot if (sd_save_to_file(warmboot, hdr->wb_size, "warmboot.bin")) { EPRINTF("\nFailed to create warmboot.bin"); goto out; @@ -1199,7 +1194,7 @@ void dump_package1() sdmmc_storage_end(&storage); - gfx_puts(&gfx_con, "\nDone. Press any key.\n"); + gfx_puts(&gfx_con, "\nDone. Press any key...\n"); out:; free(pkg1); @@ -1212,6 +1207,8 @@ out:; void launch_firmware() { + u8 max_entries = 16; + ini_sec_t *cfg_sec = NULL; LIST_INIT(ini_sections); @@ -1222,8 +1219,8 @@ void launch_firmware() { if (ini_parse(&ini_sections, "hekate_ipl.ini")) { - //Build configuration menu. - ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 16); + // Build configuration menu. + ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * max_entries); ments[0].type = MENT_BACK; ments[0].caption = "Back"; u32 i = 1; @@ -1235,6 +1232,9 @@ void launch_firmware() ments[i].caption = ini_sec->name; ments[i].data = ini_sec; i++; + + if (i > max_entries) + break; } if (i > 1) { @@ -1242,13 +1242,18 @@ void launch_firmware() menu_t menu = { ments, "Launch configurations", 0, 0 }; - cfg_sec = (ini_sec_t *)tui_do_menu(&gfx_con, &menu); + cfg_sec = ini_clone_section((ini_sec_t *)tui_do_menu(&gfx_con, &menu)); if (!cfg_sec) + { + free(ments); + ini_free(&ini_sections); return; + } } else EPRINTF("No launch configurations found."); free(ments); + ini_free(&ini_sections); } else EPRINTF("Could not find or open 'hekate_ipl.ini'.\nMake sure it exists in SD Card!."); @@ -1263,7 +1268,7 @@ void launch_firmware() if (!hos_launch(cfg_sec)) EPRINTF("Failed to launch firmware."); - //TODO: free ini. + ini_free_section(cfg_sec); btn_wait(); } @@ -1310,19 +1315,19 @@ int fix_attributes(char *path, u32 *total) u32 k = 0; static FILINFO fno; - /* Open directory */ + // Open directory res = f_opendir(&dir, path); if (res == FR_OK) { for (;;) { - //Read a directory item. + // Read a directory item. res = f_readdir(&dir, &fno); - //Break on error or end of dir. + // Break on error or end of dir. if (res != FR_OK || fno.fname[0] == 0) break; - //Set new directory + // Set new directory i = strlen(path); memcpy(&path[i], "/", 1); for (k = 0; k < 256; k++) @@ -1333,23 +1338,23 @@ int fix_attributes(char *path, u32 *total) memcpy(&path[i+1], fno.fname, k + 1); path[i + k + 2] = 0; - //Check if archive bit is set + // Check if archive bit is set if (fno.fattrib & AM_ARC) { *(u32 *)total = *(u32 *)total + 1; f_chmod(path, 0, AM_ARC); } - /* Is it a directory? */ + // Is it a directory? if (fno.fattrib & AM_DIR) { - //Enter the directory. + // Enter the directory. res = fix_attributes(path, total); if (res != FR_OK) break; } - //Clear file or folder path. + // Clear file or folder path. path[i] = 0; } f_closedir(&dir); @@ -1515,7 +1520,7 @@ void ipl_main() gfx_clear_grey(&gfx_ctxt, 0x1B); gfx_con_init(&gfx_con, &gfx_ctxt); - //Enable backlight after initializing gfx + // Enable backlight after initializing gfx display_backlight(1); while (1) diff --git a/ipl/max7762x.c b/ipl/max7762x.c index 5e8d923..5a549ed 100755 --- a/ipl/max7762x.c +++ b/ipl/max7762x.c @@ -73,8 +73,8 @@ int max77620_regulator_get_status(u32 id) const max77620_regulator_t *reg = &_pmic_regulators[id]; if (reg->type == REGULATOR_SD) - return i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask ? 0 : 1; - return i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8 ? 1 : 0; + return (i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1; + return (i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8) ? 1 : 0; } int max77620_regulator_config_fps(u32 id) diff --git a/ipl/pkg1.c b/ipl/pkg1.c index 8495682..9e0300e 100755 --- a/ipl/pkg1.c +++ b/ipl/pkg1.c @@ -55,7 +55,7 @@ PATCHSET_DEF(_secmon_4_patchset, { 0x2300 + 0x5D80, _NOP() }, //package2 structure. { 0x2300 + 0x5D8C, _NOP() }, //Version. { 0x2300 + 0x5EFC, _NOP() }, //Header signature. - { 0xAC8 + 0xA2C, _NOP() } //Sections SHA2. + { 0xAC8 + 0xA2C, _NOP() } //Sections SHA2. ); PATCHSET_DEF(_secmon_5_patchset, diff --git a/ipl/sdmmc.c b/ipl/sdmmc.c index 2539bc6..c443962 100755 --- a/ipl/sdmmc.c +++ b/ipl/sdmmc.c @@ -849,7 +849,7 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage) raw_ssr2[1] = *(u32 *)&storage->raw_ssr[20]; raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16]; - storage->ssr.bus_width = unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4 ? 4 : 1; + storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1; switch(unstuff_bits(raw_ssr1, 440 - 384, 8)) { case 0: diff --git a/ipl/tui.c b/ipl/tui.c index 8761195..49874c8 100755 --- a/ipl/tui.c +++ b/ipl/tui.c @@ -40,8 +40,7 @@ void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol) void *tui_do_menu(gfx_con_t *con, menu_t *menu) { - int idx = 0, cnt = 0; - int prev_idx = 0; + int idx = 0, prev_idx = 0, cnt = 0x7FFFFFFF; gfx_clear_grey(con->gfx_ctxt, 0x1B); @@ -56,7 +55,7 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu) menu->ents[idx].type == MENT_CHGLINE) { if (prev_idx <= idx || (!idx && prev_idx == cnt - 1)) - { + { idx++; if (idx > (cnt - 1)) { @@ -83,9 +82,9 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu) gfx_con_setcol(con, 0xFF1B1B1B, 1, 0xFFCCCCCC); else gfx_con_setcol(con, 0xFFCCCCCC, 1, 0xFF1B1B1B); - if (cnt != idx && menu->ents[cnt].type == MENT_CAPTION) + if (menu->ents[cnt].type == MENT_CAPTION) gfx_printf(con, "%k %s", menu->ents[cnt].color, menu->ents[cnt].caption); - else + else if (menu->ents[cnt].type != MENT_CHGLINE) gfx_printf(con, " %s", menu->ents[cnt].caption); if(menu->ents[cnt].type == MENT_MENU) gfx_printf(con, "%k...", 0xFFEE9900);