diff --git a/bootloader/main.c b/bootloader/main.c index fcc9ee4..fe299e3 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -192,87 +192,87 @@ int launch_payload(char *path, bool update, bool clear_screen) gfx_clear_grey(0x1B); gfx_con_setpos(0, 0); - if (sd_mount()) + if (!sd_mount()) + goto out; + + FIL fp; + if (f_open(&fp, path, FA_READ)) { - FIL fp; - if (f_open(&fp, path, FA_READ)) - { - gfx_con.mute = false; - EPRINTFARGS("Payload file is missing!\n(%s)", path); + gfx_con.mute = false; + EPRINTFARGS("Payload file is missing!\n(%s)", path); - goto out; - } + goto out; + } - // Read and copy the payload to our chosen address - void *buf; - u32 size = f_size(&fp); + // Read and copy the payload to our chosen address + void *buf; + u32 size = f_size(&fp); - if (size < 0x30000) - buf = (void *)RCM_PAYLOAD_ADDR; - else - { - coreboot_addr = (void *)(COREBOOT_END_ADDR - size); - buf = coreboot_addr; - if (h_cfg.t210b01) - { - f_close(&fp); - - gfx_con.mute = false; - EPRINTF("Coreboot not allowed on Mariko!"); - - goto out; - } - } - - if (f_read(&fp, buf, size, NULL)) + if (size < 0x30000) + buf = (void *)RCM_PAYLOAD_ADDR; + else + { + coreboot_addr = (void *)(COREBOOT_END_ADDR - size); + buf = coreboot_addr; + if (h_cfg.t210b01) { f_close(&fp); + gfx_con.mute = false; + EPRINTF("Coreboot not allowed on Mariko!"); + goto out; } + } + if (f_read(&fp, buf, size, NULL)) + { f_close(&fp); - if (update && is_ipl_updated(buf, path, false)) - goto out; + goto out; + } - sd_end(); + f_close(&fp); - if (size < 0x30000) - { - if (update) - memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t)); // Transfer boot cfg. - else - reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10)); + if (update && is_ipl_updated(buf, path, false)) + goto out; - hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32)))); - } + sd_end(); + + if (size < 0x30000) + { + if (update) + memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t)); // Transfer boot cfg. else - { - reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000); + reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10)); - // Get coreboot seamless display magic. - u32 magic = 0; - char *magic_ptr = buf + COREBOOT_VER_OFF; - memcpy(&magic, magic_ptr + strlen(magic_ptr) - 4, 4); - hw_reinit_workaround(true, magic); - } + hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32)))); + } + else + { + reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000); - // Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms. - sdmmc_storage_init_wait_sd(); + // Get coreboot seamless display magic. + u32 magic = 0; + char *magic_ptr = buf + COREBOOT_VER_OFF; + memcpy(&magic, magic_ptr + strlen(magic_ptr) - 4, 4); + hw_reinit_workaround(true, magic); + } - void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR; - void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR; + // Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms. + sdmmc_storage_init_wait_sd(); - // Launch our payload. - if (!update) - (*ext_payload_ptr)(); - else - { - // Set updated flag to skip check on launch. - EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD; - (*update_ptr)(); - } + void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR; + void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR; + + // Launch our payload. + if (!update) + (*ext_payload_ptr)(); + else + { + // Set updated flag to skip check on launch. + EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD; + (*update_ptr)(); } out: @@ -282,25 +282,6 @@ out: return 1; } -void auto_launch_update() -{ - // Check if already chainloaded update and clear flag. Otherwise check for updates. - if (EMC(EMC_SCRATCH0) & EMC_HEKA_UPD) - EMC(EMC_SCRATCH0) &= ~EMC_HEKA_UPD; - else - { - // Check if update.bin exists and is newer and launch it. Otherwise create it. - if (!f_stat("bootloader/update.bin", NULL)) - launch_payload("bootloader/update.bin", true, false); - else - { - u8 *buf = calloc(0x200, 1); - is_ipl_updated(buf, "bootloader/update.bin", true); - free(buf); - } - } -} - void launch_tools() { u8 max_entries = 61; @@ -313,63 +294,60 @@ void launch_tools() gfx_clear_grey(0x1B); gfx_con_setpos(0, 0); - if (sd_mount()) + if (!sd_mount()) { - dir = (char *)malloc(256); - - memcpy(dir, "bootloader/payloads", 20); - - filelist = dirlist(dir, NULL, false, false); - - u32 i = 0; - - if (filelist) - { - // Build configuration menu. - ments[0].type = MENT_BACK; - ments[0].caption = "Back"; - ments[1].type = MENT_CHGLINE; - - while (true) - { - if (i > max_entries || !filelist[i * 256]) - break; - ments[i + 2].type = INI_CHOICE; - ments[i + 2].caption = &filelist[i * 256]; - ments[i + 2].data = &filelist[i * 256]; - - i++; - } - } - - if (i > 0) - { - memset(&ments[i + 2], 0, sizeof(ment_t)); - menu_t menu = { ments, "Choose a file to launch", 0, 0 }; - - file_sec = (char *)tui_do_menu(&menu); - - if (!file_sec) - { - free(ments); - free(dir); - free(filelist); - sd_end(); - - return; - } - } - else - EPRINTF("No payloads or modules found."); - free(ments); - free(filelist); + goto failed_sd_mount; + } + + dir = (char *)malloc(256); + memcpy(dir, "bootloader/payloads", 20); + + filelist = dirlist(dir, NULL, false, false); + + u32 i = 0; + + if (filelist) + { + // Build configuration menu. + ments[0].type = MENT_BACK; + ments[0].caption = "Back"; + ments[1].type = MENT_CHGLINE; + + while (true) + { + if (i > max_entries || !filelist[i * 256]) + break; + ments[i + 2].type = INI_CHOICE; + ments[i + 2].caption = &filelist[i * 256]; + ments[i + 2].data = &filelist[i * 256]; + + i++; + } + } + + if (i > 0) + { + memset(&ments[i + 2], 0, sizeof(ment_t)); + menu_t menu = { ments, "Choose a file to launch", 0, 0 }; + + file_sec = (char *)tui_do_menu(&menu); + + if (!file_sec) + { + free(ments); + free(dir); + free(filelist); + sd_end(); + + return; + } } else - { - free(ments); - goto out; - } + EPRINTF("No payloads or modules found."); + + free(ments); + free(filelist); if (file_sec) { @@ -380,7 +358,7 @@ void launch_tools() EPRINTF("Failed to launch payload."); } -out: +failed_sd_mount: sd_end(); free(dir); @@ -399,94 +377,101 @@ void ini_list_launcher() gfx_clear_grey(0x1B); gfx_con_setpos(0, 0); - if (sd_mount()) + if (!sd_mount()) + goto parse_failed; + + // Check that ini files exist and parse them. + if (!ini_parse(&ini_list_sections, "bootloader/ini", true)) { - if (ini_parse(&ini_list_sections, "bootloader/ini", true)) - { - // Build configuration menu. - ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3)); - ments[0].type = MENT_BACK; - ments[0].caption = "Back"; - ments[1].type = MENT_CHGLINE; - - u32 i = 2; - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_list_sections, link) - { - if (!strcmp(ini_sec->name, "config") || - ini_sec->type == INI_COMMENT || ini_sec->type == INI_NEWLINE) - continue; - ments[i].type = ini_sec->type; - ments[i].caption = ini_sec->name; - ments[i].data = ini_sec; - if (ini_sec->type == MENT_CAPTION) - ments[i].color = ini_sec->color; - i++; - - if ((i - 1) > max_entries) - break; - } - if (i > 2) - { - memset(&ments[i], 0, sizeof(ment_t)); - menu_t menu = { - ments, "Launch ini configurations", 0, 0 - }; - - cfg_sec = (ini_sec_t *)tui_do_menu(&menu); - - if (cfg_sec) - { - u32 non_cfg = 1; - for (u32 j = 2; j < i; j++) - { - if (ments[j].type != INI_CHOICE) - non_cfg++; - - if (ments[j].data == cfg_sec) - { - b_cfg.boot_cfg = BOOT_CFG_FROM_LAUNCH; - b_cfg.autoboot = j - non_cfg; - b_cfg.autoboot_list = 1; - - break; - } - } - } - - payload_path = ini_check_payload_section(cfg_sec); - - if (cfg_sec) - { - LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) - { - if (!strcmp("emummc_force_disable", kv->key)) - h_cfg.emummc_force_disable = atoi(kv->val); - else if (!strcmp("emupath", kv->key)) - emummc_path = kv->val; - } - } - - if (emummc_path && !emummc_set_path(emummc_path)) - { - EPRINTF("emupath is wrong!"); - goto wrong_emupath; - } - - if (!cfg_sec) - { - free(ments); - - return; - } - } - else - EPRINTF("No extra configs found."); - free(ments); - } - else - EPRINTF("Could not find any ini\nin bootloader/ini!"); + EPRINTF("Could not find any ini\nin bootloader/ini!"); + goto parse_failed; } + // Build configuration menu. + ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3)); + ments[0].type = MENT_BACK; + ments[0].caption = "Back"; + ments[1].type = MENT_CHGLINE; + + u32 i = 2; + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_list_sections, link) + { + if (!strcmp(ini_sec->name, "config") || + ini_sec->type == INI_COMMENT || + ini_sec->type == INI_NEWLINE) + continue; + + ments[i].type = ini_sec->type; + ments[i].caption = ini_sec->name; + ments[i].data = ini_sec; + + if (ini_sec->type == MENT_CAPTION) + ments[i].color = ini_sec->color; + i++; + + if ((i - 1) > max_entries) + break; + } + + if (i > 2) + { + memset(&ments[i], 0, sizeof(ment_t)); + menu_t menu = { + ments, "Launch ini configurations", 0, 0 + }; + + cfg_sec = (ini_sec_t *)tui_do_menu(&menu); + + if (cfg_sec) + { + u32 non_cfg = 1; + for (u32 j = 2; j < i; j++) + { + if (ments[j].type != INI_CHOICE) + non_cfg++; + + if (ments[j].data == cfg_sec) + { + b_cfg.boot_cfg = BOOT_CFG_FROM_LAUNCH; + b_cfg.autoboot = j - non_cfg; + b_cfg.autoboot_list = 1; + + break; + } + } + } + + payload_path = ini_check_payload_section(cfg_sec); + + if (cfg_sec) + { + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) + { + if (!strcmp("emummc_force_disable", kv->key)) + h_cfg.emummc_force_disable = atoi(kv->val); + else if (!strcmp("emupath", kv->key)) + emummc_path = kv->val; + } + } + + if (emummc_path && !emummc_set_path(emummc_path)) + { + EPRINTF("emupath is wrong!"); + goto wrong_emupath; + } + + if (!cfg_sec) + { + free(ments); + + return; + } + } + else + EPRINTF("No extra configs found."); + free(ments); + +parse_failed: if (!cfg_sec) goto out; @@ -524,108 +509,116 @@ void launch_firmware() gfx_clear_grey(0x1B); gfx_con_setpos(0, 0); - if (sd_mount()) + if (!sd_mount()) + goto parse_failed; + + // Load emuMMC configuration. + emummc_load_cfg(); + + // Check that main configuration exists and parse it. + if (!ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) { - // Load emuMMC configuration. - emummc_load_cfg(); - - if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) - { - // Build configuration menu. - ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 6)); - ments[0].type = MENT_BACK; - ments[0].caption = "Back"; - ments[1].type = MENT_CHGLINE; - - ments[2].type = MENT_HANDLER; - ments[2].caption = "Payloads..."; - ments[2].handler = launch_tools; - ments[3].type = MENT_HANDLER; - ments[3].caption = "More configs..."; - ments[3].handler = ini_list_launcher; - - ments[4].type = MENT_CHGLINE; - - u32 i = 5; - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) - { - if (!strcmp(ini_sec->name, "config") || - ini_sec->type == INI_COMMENT || ini_sec->type == INI_NEWLINE) - continue; - ments[i].type = ini_sec->type; - ments[i].caption = ini_sec->name; - ments[i].data = ini_sec; - if (ini_sec->type == MENT_CAPTION) - ments[i].color = ini_sec->color; - i++; - - if ((i - 4) > max_entries) - break; - } - if (i < 6) - { - ments[i].type = MENT_CAPTION; - ments[i].caption = "No main configs found..."; - ments[i].color = 0xFFFFDD00; - i++; - } - memset(&ments[i], 0, sizeof(ment_t)); - menu_t menu = { - ments, "Launch configurations", 0, 0 - }; - - cfg_sec = (ini_sec_t *)tui_do_menu(&menu); - - if (cfg_sec) - { - u8 non_cfg = 4; - for (u32 j = 5; j < i; j++) - { - if (ments[j].type != INI_CHOICE) - non_cfg++; - if (ments[j].data == cfg_sec) - { - b_cfg.boot_cfg = BOOT_CFG_FROM_LAUNCH; - b_cfg.autoboot = j - non_cfg; - b_cfg.autoboot_list = 0; - - break; - } - } - } - - payload_path = ini_check_payload_section(cfg_sec); - - if (cfg_sec) - { - LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) - { - if (!strcmp("emummc_force_disable", kv->key)) - h_cfg.emummc_force_disable = atoi(kv->val); - if (!strcmp("emupath", kv->key)) - emummc_path = kv->val; - } - } - - if (emummc_path && !emummc_set_path(emummc_path)) - { - EPRINTF("emupath is wrong!"); - goto wrong_emupath; - } - - if (!cfg_sec) - { - free(ments); - sd_end(); - return; - } - - free(ments); - } - else - EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists!"); + EPRINTF("Could not open 'bootloader/hekate_ipl.ini'!"); + goto parse_failed; } + // Build configuration menu. + ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 6)); + ments[0].type = MENT_BACK; + ments[0].caption = "Back"; + ments[1].type = MENT_CHGLINE; + + ments[2].type = MENT_HANDLER; + ments[2].caption = "Payloads..."; + ments[2].handler = launch_tools; + ments[3].type = MENT_HANDLER; + ments[3].caption = "More configs..."; + ments[3].handler = ini_list_launcher; + + ments[4].type = MENT_CHGLINE; + + u32 i = 5; + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) + { + if (!strcmp(ini_sec->name, "config") || + ini_sec->type == INI_COMMENT || + ini_sec->type == INI_NEWLINE) + continue; + + ments[i].type = ini_sec->type; + ments[i].caption = ini_sec->name; + ments[i].data = ini_sec; + + if (ini_sec->type == MENT_CAPTION) + ments[i].color = ini_sec->color; + i++; + + if ((i - 4) > max_entries) + break; + } + + if (i < 6) + { + ments[i].type = MENT_CAPTION; + ments[i].caption = "No main configs found..."; + ments[i].color = 0xFFFFDD00; + i++; + } + + memset(&ments[i], 0, sizeof(ment_t)); + menu_t menu = { + ments, "Launch configurations", 0, 0 + }; + + cfg_sec = (ini_sec_t *)tui_do_menu(&menu); + + if (cfg_sec) + { + u8 non_cfg = 4; + for (u32 j = 5; j < i; j++) + { + if (ments[j].type != INI_CHOICE) + non_cfg++; + if (ments[j].data == cfg_sec) + { + b_cfg.boot_cfg = BOOT_CFG_FROM_LAUNCH; + b_cfg.autoboot = j - non_cfg; + b_cfg.autoboot_list = 0; + + break; + } + } + } + + payload_path = ini_check_payload_section(cfg_sec); + + if (cfg_sec) + { + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) + { + if (!strcmp("emummc_force_disable", kv->key)) + h_cfg.emummc_force_disable = atoi(kv->val); + if (!strcmp("emupath", kv->key)) + emummc_path = kv->val; + } + } + + if (emummc_path && !emummc_set_path(emummc_path)) + { + EPRINTF("emupath is wrong!"); + goto wrong_emupath; + } + + if (!cfg_sec) + { + free(ments); + sd_end(); + return; + } + + free(ments); + +parse_failed: if (!cfg_sec) { gfx_printf("\nPress any key...\n"); @@ -769,6 +762,25 @@ static void _bootloader_corruption_protect() } } +void auto_launch_update() +{ + // Check if already chainloaded update and clear flag. Otherwise check for updates. + if (EMC(EMC_SCRATCH0) & EMC_HEKA_UPD) + EMC(EMC_SCRATCH0) &= ~EMC_HEKA_UPD; + else + { + // Check if update.bin exists and is newer and launch it. Otherwise create it. + if (!f_stat("bootloader/update.bin", NULL)) + launch_payload("bootloader/update.bin", true, false); + else + { + u8 *buf = calloc(0x200, 1); + is_ipl_updated(buf, "bootloader/update.bin", true); + free(buf); + } + } +} + static void _auto_launch_firmware() { struct _bmp_data @@ -784,6 +796,8 @@ static void _auto_launch_firmware() char *emummc_path = NULL; char *bootlogoCustomEntry = NULL; ini_sec_t *cfg_sec = NULL; + u32 boot_entry_id = 0; + bool config_entry_found = false; auto_launch_update(); @@ -803,142 +817,137 @@ static void _auto_launch_firmware() if (f_stat("bootloader/hekate_ipl.ini", NULL)) create_config_entry(); - if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) - { - u32 configEntry = 0; - u32 boot_entry_id = 0; - - // Load configuration. - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) - { - // Skip other ini entries for autoboot. - if (ini_sec->type == INI_CHOICE) - { - if (!strcmp(ini_sec->name, "config")) - { - configEntry = 1; - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) - { - if (!strcmp("autoboot", kv->key)) - h_cfg.autoboot = atoi(kv->val); - else if (!strcmp("autoboot_list", kv->key)) - h_cfg.autoboot_list = atoi(kv->val); - else if (!strcmp("bootwait", kv->key)) - { - h_cfg.bootwait = atoi(kv->val); - - /* - * Clamp value to default if it exceeds 20s to protect against corruption. - * Allow up to 20s though for use in cases where user needs lots of time. - * For example dock-only use and r2p with enough time to reach dock and cancel it. - */ - if (h_cfg.bootwait > 20) - h_cfg.bootwait = 3; - } - else if (!strcmp("backlight", kv->key)) - h_cfg.backlight = atoi(kv->val); - else if (!strcmp("autohosoff", kv->key)) - 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("bootprotect", kv->key)) - h_cfg.bootprotect = atoi(kv->val); - } - boot_entry_id++; - - // Override autoboot. - if (b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN) - { - h_cfg.autoboot = b_cfg.autoboot; - h_cfg.autoboot_list = b_cfg.autoboot_list; - } - - // Apply bootloader protection against corruption. - _bootloader_corruption_protect(); - - continue; - } - - if (boot_from_id) - cfg_sec = get_ini_sec_from_id(ini_sec, &bootlogoCustomEntry, &emummc_path); - else if (h_cfg.autoboot == boot_entry_id && configEntry) - { - cfg_sec = ini_sec; - LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) - { - if (!strcmp("logopath", kv->key)) - bootlogoCustomEntry = kv->val; - else if (!strcmp("emummc_force_disable", kv->key)) - h_cfg.emummc_force_disable = atoi(kv->val); - else if (!strcmp("emupath", kv->key)) - emummc_path = kv->val; - } - } - if (cfg_sec) - break; - boot_entry_id++; - } - } - - if (h_cfg.autohosoff && !(b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN)) - check_power_off_from_hos(); - - if (h_cfg.autoboot_list || (boot_from_id && !cfg_sec)) - { - if (boot_from_id && cfg_sec) - goto skip_list; - - cfg_sec = NULL; - boot_entry_id = 1; - bootlogoCustomEntry = NULL; - - if (ini_parse(&ini_list_sections, "bootloader/ini", true)) - { - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec_list, &ini_list_sections, link) - { - if (ini_sec_list->type == INI_CHOICE) - { - if (!strcmp(ini_sec_list->name, "config")) - continue; - - if (boot_from_id) - cfg_sec = get_ini_sec_from_id(ini_sec_list, &bootlogoCustomEntry, &emummc_path); - else if (h_cfg.autoboot == boot_entry_id) - { - h_cfg.emummc_force_disable = false; - cfg_sec = ini_sec_list; - LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) - { - if (!strcmp("logopath", kv->key)) - bootlogoCustomEntry = kv->val; - else if (!strcmp("emummc_force_disable", kv->key)) - h_cfg.emummc_force_disable = atoi(kv->val); - else if (!strcmp("emupath", kv->key)) - emummc_path = kv->val; - } - } - if (cfg_sec) - break; - boot_entry_id++; - } - } - - } - - } -skip_list: - // Add missing configuration entry. - if (!configEntry) - create_config_entry(); - - if (!cfg_sec) - goto out; // No configurations or auto boot is disabled. - } - else + // Parse hekate main configuration. + if (!ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) goto out; // Can't load hekate_ipl.ini. + // Load configuration. + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) + { + // Skip other ini entries for autoboot. + if (ini_sec->type == INI_CHOICE) + { + if (!config_entry_found && !strcmp(ini_sec->name, "config")) + { + config_entry_found = true; + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + if (!strcmp("autoboot", kv->key)) + h_cfg.autoboot = atoi(kv->val); + else if (!strcmp("autoboot_list", kv->key)) + h_cfg.autoboot_list = atoi(kv->val); + else if (!strcmp("bootwait", kv->key)) + { + h_cfg.bootwait = atoi(kv->val); + + /* + * Clamp value to default if it exceeds 20s to protect against corruption. + * Allow up to 20s though for use in cases where user needs lots of time. + * For example dock-only use and r2p with enough time to reach dock and cancel it. + */ + if (h_cfg.bootwait > 20) + h_cfg.bootwait = 3; + } + else if (!strcmp("backlight", kv->key)) + h_cfg.backlight = atoi(kv->val); + else if (!strcmp("autohosoff", kv->key)) + 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("bootprotect", kv->key)) + h_cfg.bootprotect = atoi(kv->val); + } + boot_entry_id++; + + // Override autoboot. + if (b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN) + { + h_cfg.autoboot = b_cfg.autoboot; + h_cfg.autoboot_list = b_cfg.autoboot_list; + } + + // Apply bootloader protection against corruption. + _bootloader_corruption_protect(); + + continue; + } + + if (boot_from_id) + cfg_sec = get_ini_sec_from_id(ini_sec, &bootlogoCustomEntry, &emummc_path); + else if (h_cfg.autoboot == boot_entry_id && config_entry_found) + { + cfg_sec = ini_sec; + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) + { + if (!strcmp("logopath", kv->key)) + bootlogoCustomEntry = kv->val; + else if (!strcmp("emummc_force_disable", kv->key)) + h_cfg.emummc_force_disable = atoi(kv->val); + else if (!strcmp("emupath", kv->key)) + emummc_path = kv->val; + } + } + if (cfg_sec) + break; + boot_entry_id++; + } + } + + if (h_cfg.autohosoff && !(b_cfg.boot_cfg & BOOT_CFG_AUTOBOOT_EN)) + check_power_off_from_hos(); + + if (h_cfg.autoboot_list || (boot_from_id && !cfg_sec)) + { + if (boot_from_id && cfg_sec) + goto skip_list; + + cfg_sec = NULL; + boot_entry_id = 1; + bootlogoCustomEntry = NULL; + + if (!ini_parse(&ini_list_sections, "bootloader/ini", true)) + goto skip_list; + + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec_list, &ini_list_sections, link) + { + if (ini_sec_list->type != INI_CHOICE) + continue; + + if (!strcmp(ini_sec_list->name, "config")) + continue; + + if (boot_from_id) + cfg_sec = get_ini_sec_from_id(ini_sec_list, &bootlogoCustomEntry, &emummc_path); + else if (h_cfg.autoboot == boot_entry_id) + { + h_cfg.emummc_force_disable = false; + cfg_sec = ini_sec_list; + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link) + { + if (!strcmp("logopath", kv->key)) + bootlogoCustomEntry = kv->val; + else if (!strcmp("emummc_force_disable", kv->key)) + h_cfg.emummc_force_disable = atoi(kv->val); + else if (!strcmp("emupath", kv->key)) + emummc_path = kv->val; + } + } + if (cfg_sec) + break; + boot_entry_id++; + } + } + +skip_list: + // Add missing configuration entry. + if (!config_entry_found) + create_config_entry(); + + if (!cfg_sec) + goto out; // No configurations or auto boot is disabled. + u8 *bitmap = NULL; struct _bmp_data bmpData; bool bootlogoFound = false; diff --git a/nyx/nyx_gui/frontend/fe_emmc_tools.c b/nyx/nyx_gui/frontend/fe_emmc_tools.c index 4fde3ac..04e331a 100644 --- a/nyx/nyx_gui/frontend/fe_emmc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emmc_tools.c @@ -950,124 +950,125 @@ static int _restore_emmc_part(emmc_tool_gui_t *gui, char *sd_path, int active_pa bool use_multipart = false; bool check_4MB_aligned = true; - if (allow_multi_part) + if (!allow_multi_part) + goto multipart_not_allowed; + + // Check to see if there is a combined file and if so then use that. + if (f_stat(outFilename, &fno)) { - // Check to see if there is a combined file and if so then use that. - if (f_stat(outFilename, &fno)) + // If not, check if there are partial files and the total size matches. + s_printf(gui->txt_buf, "\nNo single file, checking for part files...\n"); + lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); + manual_system_maintenance(true); + + outFilename[sdPathLen++] = '.'; + + _update_filename(outFilename, sdPathLen, numSplitParts); + + s_printf(gui->txt_buf, "#96FF00 Filepath:#\n%s\n#96FF00 Filename:# #FF8000 %s#", + gui->base_path, outFilename + strlen(gui->base_path)); + lv_label_ins_text(gui->label_info, LV_LABEL_POS_LAST, gui->txt_buf); + + // Stat total size of the part files. + while ((u32)((u64)totalCheckFileSize >> (u64)9) != totalSectors) { - // If not, check if there are partial files and the total size matches. - s_printf(gui->txt_buf, "\nNo single file, checking for part files...\n"); - lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); - manual_system_maintenance(true); - - outFilename[sdPathLen++] = '.'; - _update_filename(outFilename, sdPathLen, numSplitParts); - s_printf(gui->txt_buf, "#96FF00 Filepath:#\n%s\n#96FF00 Filename:# #FF8000 %s#", - gui->base_path, outFilename + strlen(gui->base_path)); + s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path)); + 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); - // Stat total size of the part files. - while ((u32)((u64)totalCheckFileSize >> (u64)9) != totalSectors) + if ((u32)((u64)totalCheckFileSize >> (u64)9) > totalSectors) { - _update_filename(outFilename, sdPathLen, numSplitParts); - - s_printf(gui->txt_buf, "%s#", outFilename + strlen(gui->base_path)); - 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); + s_printf(gui->txt_buf, "#FF8000 Size of SD Card split backup exceeds#\n#FF8000 eMMC's selected part size!#\n#FFDD00 Aborting...#"); + lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); manual_system_maintenance(true); - if ((u32)((u64)totalCheckFileSize >> (u64)9) > totalSectors) + return 0; + } + else if (f_stat(outFilename, &fno)) + { + if (!gui->raw_emummc) { - s_printf(gui->txt_buf, "#FF8000 Size of SD Card split backup exceeds#\n#FF8000 eMMC's selected part size!#\n#FFDD00 Aborting...#"); + s_printf(gui->txt_buf, "#FFDD00 Error (%d) file not found#\n#FFDD00 %s.#\n\n", res, outFilename); lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); manual_system_maintenance(true); - return 0; - } - else if (f_stat(outFilename, &fno)) - { - if (!gui->raw_emummc) - { - s_printf(gui->txt_buf, "#FFDD00 Error (%d) file not found#\n#FFDD00 %s.#\n\n", res, outFilename); - lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); - manual_system_maintenance(true); - - // Attempt a smaller restore. - if (numSplitParts) - break; - } - else - { - // Set new total sectors and lba end sector for percentage calculations. - totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9); - lba_end = totalSectors + part->lba_start - 1; - } - - // Restore folder is empty. - if (!numSplitParts) - { - s_printf(gui->txt_buf, "#FFDD00 Restore folder is empty.#\n\n"); - lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); - manual_system_maintenance(true); - - return 0; - } + // Attempt a smaller restore. + if (numSplitParts) + break; } else { - totalCheckFileSize += (u64)fno.fsize; - - if (check_4MB_aligned && (((u64)fno.fsize) % SZ_4M)) - { - s_printf(gui->txt_buf, "#FFDD00 The split file must be a#\n#FFDD00 multiple of 4 MiB.#\n#FFDD00 Aborting...#", res, outFilename); - lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); - manual_system_maintenance(true); - - return 0; - } - - check_4MB_aligned = false; + // Set new total sectors and lba end sector for percentage calculations. + totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9); + lba_end = totalSectors + part->lba_start - 1; } - numSplitParts++; - } - - s_printf(gui->txt_buf, "%X sectors total.\n", (u32)((u64)totalCheckFileSize >> (u64)9)); - lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); - manual_system_maintenance(true); - - if ((u32)((u64)totalCheckFileSize >> (u64)9) != totalSectors) - { - lv_obj_t *warn_mbox_bg = create_mbox_text( - "#FF8000 Size of SD Card split backup does not match#\n#FF8000 eMMC's selected part size!#\n\n" - "#FFDD00 The backup might be corrupted,#\n#FFDD00 or missing files!#\n#FFDD00 Aborting is suggested!#\n\n" - "Press #FF8000 POWER# to Continue.\nPress #FF8000 VOL# to abort.", false); - manual_system_maintenance(true); - - if (!(btn_wait() & BTN_POWER)) + // Restore folder is empty. + if (!numSplitParts) { - lv_obj_del(warn_mbox_bg); - s_printf(gui->txt_buf, "#FF0000 Size of SD Card split backup does not match#\n#FF0000 eMMC's selected part size!#\n"); + s_printf(gui->txt_buf, "#FFDD00 Restore folder is empty.#\n\n"); lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); manual_system_maintenance(true); return 0; } - lv_obj_del(warn_mbox_bg); - - // Set new total sectors and lba end sector for percentage calculations. - totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9); - lba_end = totalSectors + part->lba_start - 1; } - use_multipart = true; - _update_filename(outFilename, sdPathLen, 0); + else + { + totalCheckFileSize += (u64)fno.fsize; + + if (check_4MB_aligned && (((u64)fno.fsize) % SZ_4M)) + { + s_printf(gui->txt_buf, "#FFDD00 The split file must be a#\n#FFDD00 multiple of 4 MiB.#\n#FFDD00 Aborting...#", res, outFilename); + lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); + manual_system_maintenance(true); + + return 0; + } + + check_4MB_aligned = false; + } + + numSplitParts++; } + + s_printf(gui->txt_buf, "%X sectors total.\n", (u32)((u64)totalCheckFileSize >> (u64)9)); + lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); + manual_system_maintenance(true); + + if ((u32)((u64)totalCheckFileSize >> (u64)9) != totalSectors) + { + lv_obj_t *warn_mbox_bg = create_mbox_text( + "#FF8000 Size of SD Card split backup does not match#\n#FF8000 eMMC's selected part size!#\n\n" + "#FFDD00 The backup might be corrupted,#\n#FFDD00 or missing files!#\n#FFDD00 Aborting is suggested!#\n\n" + "Press #FF8000 POWER# to Continue.\nPress #FF8000 VOL# to abort.", false); + manual_system_maintenance(true); + + if (!(btn_wait() & BTN_POWER)) + { + lv_obj_del(warn_mbox_bg); + s_printf(gui->txt_buf, "#FF0000 Size of SD Card split backup does not match#\n#FF0000 eMMC's selected part size!#\n"); + lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, gui->txt_buf); + manual_system_maintenance(true); + + return 0; + } + lv_obj_del(warn_mbox_bg); + + // Set new total sectors and lba end sector for percentage calculations. + totalSectors = (u32)((u64)totalCheckFileSize >> (u64)9); + lba_end = totalSectors + part->lba_start - 1; + } + use_multipart = true; + _update_filename(outFilename, sdPathLen, 0); } +multipart_not_allowed: res = f_open(&fp, outFilename, FA_READ); if (use_multipart) { diff --git a/nyx/nyx_gui/frontend/fe_emummc_tools.c b/nyx/nyx_gui/frontend/fe_emummc_tools.c index 156e5f1..61e9f78 100644 --- a/nyx/nyx_gui/frontend/fe_emummc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emummc_tools.c @@ -42,26 +42,28 @@ void load_emummc_cfg(emummc_cfg_t *emu_info) // Parse emuMMC configuration. LIST_INIT(ini_sections); - if (ini_parse(&ini_sections, "emuMMC/emummc.ini", false)) + if (!ini_parse(&ini_sections, "emuMMC/emummc.ini", false)) + return; + + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) { - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) + if (!strcmp(ini_sec->name, "emummc")) { - if (!strcmp(ini_sec->name, "emummc")) + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) { - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) - { - if (!strcmp("enabled", kv->key)) - emu_info->enabled = atoi(kv->val); - else if (!strcmp("sector", kv->key)) - emu_info->sector = strtol(kv->val, NULL, 16); - else if (!strcmp("id", kv->key)) - emu_info->id = strtol(kv->val, NULL, 16); - else if (!strcmp("path", kv->key)) - emu_info->path = kv->val; - else if (!strcmp("nintendo_path", kv->key)) - emu_info->nintendo_path = kv->val; - } + if (!strcmp("enabled", kv->key)) + emu_info->enabled = atoi(kv->val); + else if (!strcmp("sector", kv->key)) + emu_info->sector = strtol(kv->val, NULL, 16); + else if (!strcmp("id", kv->key)) + emu_info->id = strtol(kv->val, NULL, 16); + else if (!strcmp("path", kv->key)) + emu_info->path = kv->val; + else if (!strcmp("nintendo_path", kv->key)) + emu_info->nintendo_path = kv->val; } + + break; } } } @@ -262,6 +264,7 @@ static int _dump_emummc_file_part(emmc_tool_gui_t *gui, char *sd_path, sdmmc_sto retryCount = 0; num = MIN(totalSectors, NUM_SECTORS_PER_ITER); + while (!sdmmc_storage_read(storage, lba_curr, num, buf)) { s_printf(gui->txt_buf, @@ -405,6 +408,7 @@ void dump_emummc_file(emmc_tool_gui_t *gui) memset(&bootPart, 0, sizeof(bootPart)); bootPart.lba_start = 0; bootPart.lba_end = (BOOT_PART_SIZE / EMMC_BLOCKSIZE) - 1; + for (i = 0; i < 2; i++) { strcpy(bootPart.name, "BOOT"); @@ -448,24 +452,23 @@ void dump_emummc_file(emmc_tool_gui_t *gui) rawPart.lba_start = 0; rawPart.lba_end = RAW_AREA_NUM_SECTORS - 1; strcpy(rawPart.name, "GPP"); - { - 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_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); - res = _dump_emummc_file_part(gui, sdPath, &emmc_storage, &rawPart); + 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_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); - if (!res) - s_printf(txt_buf, "#FFDD00 Failed!#\n"); - else - s_printf(txt_buf, "Done!\n"); + res = _dump_emummc_file_part(gui, sdPath, &emmc_storage, &rawPart); - lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf); - manual_system_maintenance(true); - } + if (!res) + s_printf(txt_buf, "#FFDD00 Failed!#\n"); + else + s_printf(txt_buf, "Done!\n"); + + lv_label_ins_text(gui->label_log, LV_LABEL_POS_LAST, txt_buf); + manual_system_maintenance(true); out_failed: timer = get_tmr_s() - timer; diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c index b044af8..3fe386b 100644 --- a/nyx/nyx_gui/frontend/gui.c +++ b/nyx/nyx_gui/frontend/gui.c @@ -1608,149 +1608,151 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn) u32 curr_btn_idx = 0; // Active buttons. LIST_INIT(ini_sections); - if (sd_mount()) + if (!sd_mount()) + goto failed_sd_mount; + + // Check if we use custom system icons. + bool icon_sw_custom = !f_stat("bootloader/res/icon_switch_custom.bmp", NULL); + bool icon_pl_custom = !f_stat("bootloader/res/icon_payload_custom.bmp", NULL); + + // Choose what to parse. + bool ini_parse_success = false; + if (!more_cfg) + ini_parse_success = ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false); + else + ini_parse_success = ini_parse(&ini_sections, "bootloader/ini", true); + + if (combined_cfg && !ini_parse_success) { - // Check if we use custom system icons. - bool icon_sw_custom = !f_stat("bootloader/res/icon_switch_custom.bmp", NULL); - bool icon_pl_custom = !f_stat("bootloader/res/icon_payload_custom.bmp", NULL); - - // Choose what to parse. - bool ini_parse_success = false; - if (!more_cfg) - ini_parse_success = ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false); - else - ini_parse_success = ini_parse(&ini_sections, "bootloader/ini", true); - - if (combined_cfg && !ini_parse_success) - { ini_parsing: - // Reinit list. - ini_sections.prev = &ini_sections; - ini_sections.next = &ini_sections; - ini_parse_success = ini_parse(&ini_sections, "bootloader/ini", true); - more_cfg = true; - } - - if (ini_parse_success) - { - // Iterate to all boot entries and load icons. - u32 entry_idx = 1; - - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) - { - if (!strcmp(ini_sec->name, "config") || (ini_sec->type != INI_CHOICE)) - continue; - - icon_path = NULL; - bool payload = false; - bool img_colorize = false; - lv_img_dsc_t *bmp = NULL; - lv_obj_t *img = NULL; - - // Check for icons. - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) - { - if (!strcmp("icon", kv->key)) - icon_path = kv->val; - else if (!strcmp("payload", kv->key)) - payload = true; - } - - // If icon not found, check res folder for section_name.bmp. - // If not, use defaults. - if (!icon_path) - { - s_printf(tmp_path, "bootloader/res/%s.bmp", ini_sec->name); - bmp = bmp_to_lvimg_obj(tmp_path); - if (!bmp) - { - s_printf(tmp_path, "bootloader/res/%s_hue.bmp", ini_sec->name); - bmp = bmp_to_lvimg_obj(tmp_path); - if (bmp) - img_colorize = true; - } - - if (!bmp && payload) - { - bmp = icon_payload; - - if (!icon_pl_custom) - img_colorize = true; - } - } - else - { - bmp = bmp_to_lvimg_obj(icon_path); - - // Check if colorization is enabled. - if (bmp && strlen(icon_path) > 8 && !memcmp(icon_path + strlen(icon_path) - 8, "_hue", 4)) - img_colorize = true; - } - - // Enable button. - lv_obj_set_opa_scale(launch_ctxt.btn[curr_btn_idx], LV_OPA_COVER); - - // Default to switch logo if no icon found at all. - if (!bmp) - { - bmp = icon_switch; - - if (!icon_sw_custom) - img_colorize = true; - } - - //Set icon. - if (bmp) - { - img = lv_img_create(launch_ctxt.btn[curr_btn_idx], NULL); - - if (img_colorize) - lv_img_set_style(img, &img_style); - - lv_img_set_src(img, bmp); - } - - // Add button mask/radius and align icon. - lv_obj_t *btn = lv_btn_create(launch_ctxt.btn[curr_btn_idx], NULL); - lv_obj_set_size(btn, 200, 200); - lv_btn_set_style(btn, LV_BTN_STYLE_REL, &btn_home_transp_rel); - lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_home_transp_pr); - if (img) - lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, 0); - - // Set autoboot index. - ext = lv_obj_get_ext_attr(btn); - ext->idx = entry_idx; - ext = lv_obj_get_ext_attr(launch_ctxt.btn[curr_btn_idx]); // Redundancy. - ext->idx = entry_idx; - - // Set action. - if (!more_cfg) - lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_action); - else - lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_more_cfg_action); - - // Set button's label text. - lv_label_set_text(launch_ctxt.label[curr_btn_idx], ini_sec->name); - lv_obj_set_opa_scale(launch_ctxt.label[curr_btn_idx], LV_OPA_COVER); - - // Set rolling text if name is big. - if (strlen(ini_sec->name) > 22) - lv_label_set_long_mode(launch_ctxt.label[curr_btn_idx], LV_LABEL_LONG_ROLL); - - entry_idx++; - curr_btn_idx++; - - // Check if we exceed max buttons. - if (curr_btn_idx >= max_entries) - break; - } - } - // Reiterate the loop with more cfgs if combined. - if (combined_cfg && (curr_btn_idx < 8) && !more_cfg) - goto ini_parsing; + // Reinit list. + ini_sections.prev = &ini_sections; + ini_sections.next = &ini_sections; + ini_parse_success = ini_parse(&ini_sections, "bootloader/ini", true); + more_cfg = true; } + if (!ini_parse_success) + goto ini_parse_failed; + + // Iterate to all boot entries and load icons. + u32 entry_idx = 1; + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) + { + if (!strcmp(ini_sec->name, "config") || (ini_sec->type != INI_CHOICE)) + continue; + + icon_path = NULL; + bool payload = false; + bool img_colorize = false; + lv_img_dsc_t *bmp = NULL; + lv_obj_t *img = NULL; + + // Check for icons. + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + if (!strcmp("icon", kv->key)) + icon_path = kv->val; + else if (!strcmp("payload", kv->key)) + payload = true; + } + + // If icon not found, check res folder for section_name.bmp. + // If not, use defaults. + if (!icon_path) + { + s_printf(tmp_path, "bootloader/res/%s.bmp", ini_sec->name); + bmp = bmp_to_lvimg_obj(tmp_path); + if (!bmp) + { + s_printf(tmp_path, "bootloader/res/%s_hue.bmp", ini_sec->name); + bmp = bmp_to_lvimg_obj(tmp_path); + if (bmp) + img_colorize = true; + } + + if (!bmp && payload) + { + bmp = icon_payload; + + if (!icon_pl_custom) + img_colorize = true; + } + } + else + { + bmp = bmp_to_lvimg_obj(icon_path); + + // Check if colorization is enabled. + if (bmp && strlen(icon_path) > 8 && !memcmp(icon_path + strlen(icon_path) - 8, "_hue", 4)) + img_colorize = true; + } + + // Enable button. + lv_obj_set_opa_scale(launch_ctxt.btn[curr_btn_idx], LV_OPA_COVER); + + // Default to switch logo if no icon found at all. + if (!bmp) + { + bmp = icon_switch; + + if (!icon_sw_custom) + img_colorize = true; + } + + //Set icon. + if (bmp) + { + img = lv_img_create(launch_ctxt.btn[curr_btn_idx], NULL); + + if (img_colorize) + lv_img_set_style(img, &img_style); + + lv_img_set_src(img, bmp); + } + + // Add button mask/radius and align icon. + lv_obj_t *btn = lv_btn_create(launch_ctxt.btn[curr_btn_idx], NULL); + lv_obj_set_size(btn, 200, 200); + lv_btn_set_style(btn, LV_BTN_STYLE_REL, &btn_home_transp_rel); + lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_home_transp_pr); + if (img) + lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, 0); + + // Set autoboot index. + ext = lv_obj_get_ext_attr(btn); + ext->idx = entry_idx; + ext = lv_obj_get_ext_attr(launch_ctxt.btn[curr_btn_idx]); // Redundancy. + ext->idx = entry_idx; + + // Set action. + if (!more_cfg) + lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_action); + else + lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _launch_more_cfg_action); + + // Set button's label text. + lv_label_set_text(launch_ctxt.label[curr_btn_idx], ini_sec->name); + lv_obj_set_opa_scale(launch_ctxt.label[curr_btn_idx], LV_OPA_COVER); + + // Set rolling text if name is big. + if (strlen(ini_sec->name) > 22) + lv_label_set_long_mode(launch_ctxt.label[curr_btn_idx], LV_LABEL_LONG_ROLL); + + entry_idx++; + curr_btn_idx++; + + // Check if we exceed max buttons. + if (curr_btn_idx >= max_entries) + break; + } + +ini_parse_failed: + // Reiterate the loop with more cfgs if combined. + if (combined_cfg && (curr_btn_idx < 8) && !more_cfg) + goto ini_parsing; + +failed_sd_mount: if (curr_btn_idx < 1) no_boot_entries = true; diff --git a/nyx/nyx_gui/frontend/gui_emummc_tools.c b/nyx/nyx_gui/frontend/gui_emummc_tools.c index 6ad79ec..e8362e9 100644 --- a/nyx/nyx_gui/frontend/gui_emummc_tools.c +++ b/nyx/nyx_gui/frontend/gui_emummc_tools.c @@ -782,26 +782,27 @@ static lv_res_t _create_mbox_emummc_migrate(lv_obj_t *btn) for (int i = 1; i < 4; i++) { mbr_ctx.sector_start = mbr->partitions[i].start_sct; - if (mbr_ctx.sector_start) + + if (!mbr_ctx.sector_start) + continue; + + sdmmc_storage_read(&sd_storage, mbr_ctx.sector_start + 0xC001, 1, efi_part); + if (!memcmp(efi_part, "EFI PART", 8)) { - sdmmc_storage_read(&sd_storage, mbr_ctx.sector_start + 0xC001, 1, efi_part); + mbr_ctx.sector_start += 0x8000; + emummc = true; + mbr_ctx.part_idx = i; + break; + } + else + { + sdmmc_storage_read(&sd_storage, mbr_ctx.sector_start + 0x4001, 1, efi_part); if (!memcmp(efi_part, "EFI PART", 8)) { - mbr_ctx.sector_start += 0x8000; emummc = true; mbr_ctx.part_idx = i; break; } - else - { - sdmmc_storage_read(&sd_storage, mbr_ctx.sector_start + 0x4001, 1, efi_part); - if (!memcmp(efi_part, "EFI PART", 8)) - { - emummc = true; - mbr_ctx.part_idx = i; - break; - } - } } } diff --git a/nyx/nyx_gui/frontend/gui_info.c b/nyx/nyx_gui/frontend/gui_info.c index 870f62e..9fafca8 100644 --- a/nyx/nyx_gui/frontend/gui_info.c +++ b/nyx/nyx_gui/frontend/gui_info.c @@ -1329,194 +1329,197 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench) } if (res) - lv_mbox_set_text(mbox, "#FFDD00 Failed to init Storage!#"); - else { - int error = 0; - u32 iters = 3; - u32 offset_chunk_start = ALIGN_DOWN(storage->sec_cnt / 3, 0x8000); // Align to 16MB. - if (storage->sec_cnt < 0xC00000) - iters -= 2; // 4GB card. + lv_mbox_set_text(mbox, "#FFDD00 Failed to init Storage!#"); + goto out; + } - for (u32 iter_curr = 0; iter_curr < iters; iter_curr++) + int error = 0; + u32 iters = 3; + u32 offset_chunk_start = ALIGN_DOWN(storage->sec_cnt / 3, 0x8000); // Align to 16MB. + if (storage->sec_cnt < 0xC00000) + iters -= 2; // 4GB card. + + for (u32 iter_curr = 0; iter_curr < iters; iter_curr++) + { + u32 pct = 0; + u32 prevPct = 200; + u32 timer = 0; + u32 lba_curr = 0; + u32 sector = offset_chunk_start * iter_curr; + u32 sector_num = 0x8000; // 16MB chunks. + u32 data_remaining = 0x200000; // 1GB. + + s_printf(txt_buf + strlen(txt_buf), "#C7EA46 %d/3# - Sector Offset #C7EA46 %08X#:\n", iter_curr + 1, sector); + + while (data_remaining) { - u32 pct = 0; - u32 prevPct = 200; - u32 timer = 0; - u32 lba_curr = 0; - u32 sector = offset_chunk_start * iter_curr; - u32 sector_num = 0x8000; // 16MB chunks. - u32 data_remaining = 0x200000; // 1GB. + u32 time_taken = get_tmr_us(); + error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED); + time_taken = get_tmr_us() - time_taken; + timer += time_taken; - s_printf(txt_buf + strlen(txt_buf), "#C7EA46 %d/3# - Sector Offset #C7EA46 %08X#:\n", iter_curr + 1, sector); + manual_system_maintenance(false); + data_remaining -= sector_num; + lba_curr += sector_num; - while (data_remaining) + pct = (lba_curr * 100) / 0x200000; + if (pct != prevPct) { - u32 time_taken = get_tmr_us(); - error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED); - time_taken = get_tmr_us() - time_taken; - timer += time_taken; + lv_bar_set_value(bar, pct); + manual_system_maintenance(true); - manual_system_maintenance(false); - data_remaining -= sector_num; - lba_curr += sector_num; + prevPct = pct; - pct = (lba_curr * 100) / 0x200000; - if (pct != prevPct) - { - lv_bar_set_value(bar, pct); - manual_system_maintenance(true); - - prevPct = pct; - - if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - error = -1; - } - - if (error) - goto error; - } - lv_bar_set_value(bar, 100); - - u32 rate_1k = ((u64)1024 * 1000 * 1000 * 1000) / timer; - s_printf(txt_buf + strlen(txt_buf), - " Sequential 16MiB - Rate: #C7EA46 %3d.%02d MiB/s#\n", - rate_1k / 1000, (rate_1k % 1000) / 10); - lv_label_set_text(lbl_status, txt_buf); - lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - manual_system_maintenance(true); - - pct = 0; - prevPct = 200; - timer = 0; - lba_curr = 0; - sector_num = 8; // 4KB chunks. - data_remaining = 0x100000; // 512MB. - - while (data_remaining) - { - u32 time_taken = get_tmr_us(); - error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED); - time_taken = get_tmr_us() - time_taken; - timer += time_taken; - - manual_system_maintenance(false); - data_remaining -= sector_num; - lba_curr += sector_num; - - pct = (lba_curr * 100) / 0x100000; - if (pct != prevPct) - { - lv_bar_set_value(bar, pct); - manual_system_maintenance(true); - - prevPct = pct; - - if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - error = -1; - } - - if (error) - goto error; - } - lv_bar_set_value(bar, 100); - - rate_1k = ((u64)512 * 1000 * 1000 * 1000) / timer; - u32 iops_1k = ((u64)512 * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000; - s_printf(txt_buf + strlen(txt_buf), - " Sequential 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n", - rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k); - lv_label_set_text(lbl_status, txt_buf); - lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - manual_system_maintenance(true); - - u32 lba_idx = 0; - u32 *random_offsets = malloc(0x20000 * sizeof(u32)); - u32 random_numbers[4]; - for (u32 i = 0; i < 0x20000; i += 4) - { - // Generate new random numbers. - while (!se_gen_prng128(random_numbers)) - ; - // Clamp offsets to 512MBrange. - random_offsets[i + 0] = random_numbers[0] % 0x100000; - random_offsets[i + 1] = random_numbers[1] % 0x100000; - random_offsets[i + 2] = random_numbers[2] % 0x100000; - random_offsets[i + 3] = random_numbers[3] % 0x100000; + if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) + error = -1; } - pct = 0; - prevPct = 200; - timer = 0; - data_remaining = 0x100000; // 512MB. - - while (data_remaining) - { - u32 time_taken = get_tmr_us(); - error = !sdmmc_storage_read(storage, sector + random_offsets[lba_idx], sector_num, (u8 *)MIXD_BUF_ALIGNED); - time_taken = get_tmr_us() - time_taken; - timer += time_taken; - - manual_system_maintenance(false); - data_remaining -= sector_num; - lba_idx++; - - pct = (lba_idx * 100) / 0x20000; - if (pct != prevPct) - { - lv_bar_set_value(bar, pct); - manual_system_maintenance(true); - - prevPct = pct; - - if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) - error = -1; - } - - if (error) - { - free(random_offsets); - goto error; - } - } - lv_bar_set_value(bar, 100); - - // Calculate rate and IOPS for 512MB transfer. - rate_1k = ((u64)512 * 1000 * 1000 * 1000) / timer; - iops_1k = ((u64)512 * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000; - s_printf(txt_buf + strlen(txt_buf), - " Random 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n", - rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k); - if (iter_curr == iters - 1) - txt_buf[strlen(txt_buf) - 1] = 0; // Cut off last line change. - lv_label_set_text(lbl_status, txt_buf); - lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - manual_system_maintenance(true); - free(random_offsets); + if (error) + goto error; } + lv_bar_set_value(bar, 100); + + u32 rate_1k = ((u64)1024 * 1000 * 1000 * 1000) / timer; + s_printf(txt_buf + strlen(txt_buf), + " Sequential 16MiB - Rate: #C7EA46 %3d.%02d MiB/s#\n", + rate_1k / 1000, (rate_1k % 1000) / 10); + lv_label_set_text(lbl_status, txt_buf); + lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + manual_system_maintenance(true); + + pct = 0; + prevPct = 200; + timer = 0; + lba_curr = 0; + sector_num = 8; // 4KB chunks. + data_remaining = 0x100000; // 512MB. + + while (data_remaining) + { + u32 time_taken = get_tmr_us(); + error = !sdmmc_storage_read(storage, sector + lba_curr, sector_num, (u8 *)MIXD_BUF_ALIGNED); + time_taken = get_tmr_us() - time_taken; + timer += time_taken; + + manual_system_maintenance(false); + data_remaining -= sector_num; + lba_curr += sector_num; + + pct = (lba_curr * 100) / 0x100000; + if (pct != prevPct) + { + lv_bar_set_value(bar, pct); + manual_system_maintenance(true); + + prevPct = pct; + + if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) + error = -1; + } + + if (error) + goto error; + } + lv_bar_set_value(bar, 100); + + rate_1k = ((u64)512 * 1000 * 1000 * 1000) / timer; + u32 iops_1k = ((u64)512 * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000; + s_printf(txt_buf + strlen(txt_buf), + " Sequential 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n", + rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k); + lv_label_set_text(lbl_status, txt_buf); + lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + manual_system_maintenance(true); + + u32 lba_idx = 0; + u32 *random_offsets = malloc(0x20000 * sizeof(u32)); + u32 random_numbers[4]; + for (u32 i = 0; i < 0x20000; i += 4) + { + // Generate new random numbers. + while (!se_gen_prng128(random_numbers)) + ; + // Clamp offsets to 512MBrange. + random_offsets[i + 0] = random_numbers[0] % 0x100000; + random_offsets[i + 1] = random_numbers[1] % 0x100000; + random_offsets[i + 2] = random_numbers[2] % 0x100000; + random_offsets[i + 3] = random_numbers[3] % 0x100000; + } + + pct = 0; + prevPct = 200; + timer = 0; + data_remaining = 0x100000; // 512MB. + + while (data_remaining) + { + u32 time_taken = get_tmr_us(); + error = !sdmmc_storage_read(storage, sector + random_offsets[lba_idx], sector_num, (u8 *)MIXD_BUF_ALIGNED); + time_taken = get_tmr_us() - time_taken; + timer += time_taken; + + manual_system_maintenance(false); + data_remaining -= sector_num; + lba_idx++; + + pct = (lba_idx * 100) / 0x20000; + if (pct != prevPct) + { + lv_bar_set_value(bar, pct); + manual_system_maintenance(true); + + prevPct = pct; + + if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) + error = -1; + } + + if (error) + { + free(random_offsets); + goto error; + } + } + lv_bar_set_value(bar, 100); + + // Calculate rate and IOPS for 512MB transfer. + rate_1k = ((u64)512 * 1000 * 1000 * 1000) / timer; + iops_1k = ((u64)512 * 1024 * 1000 * 1000 * 1000) / (4096 / 1024) / timer / 1000; + s_printf(txt_buf + strlen(txt_buf), + " Random 4KiB - Rate: #C7EA46 %3d.%02d MiB/s#, IOPS: #C7EA46 %4d#\n", + rate_1k / 1000, (rate_1k % 1000) / 10, iops_1k); + if (iter_curr == iters - 1) + txt_buf[strlen(txt_buf) - 1] = 0; // Cut off last line change. + lv_label_set_text(lbl_status, txt_buf); + lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + manual_system_maintenance(true); + free(random_offsets); + } error: - if (error) - { - if (error == -1) - s_printf(txt_buf + strlen(txt_buf), "\n#FFDD00 Aborted!#"); - else - s_printf(txt_buf + strlen(txt_buf), "\n#FFDD00 IO Error occurred!#"); - - lv_label_set_text(lbl_status, txt_buf); - lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); - } - - lv_obj_del(bar); - - if (sd_bench) - sd_unmount(); + if (error) + { + if (error == -1) + s_printf(txt_buf + strlen(txt_buf), "\n#FFDD00 Aborted!#"); else - sdmmc_storage_end(&emmc_storage); + s_printf(txt_buf + strlen(txt_buf), "\n#FFDD00 IO Error occurred!#"); + + lv_label_set_text(lbl_status, txt_buf); + lv_obj_align(lbl_status, NULL, LV_ALIGN_CENTER, 0, 0); } + + lv_obj_del(bar); + + if (sd_bench) + sd_unmount(); + else + sdmmc_storage_end(&emmc_storage); + +out: free(txt_buf); lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); // Important. After set_text. @@ -1559,233 +1562,234 @@ static lv_res_t _create_window_emmc_info_status(lv_obj_t *btn) { lv_label_set_text(lb_desc, "#FFDD00 Failed to init eMMC!#"); lv_obj_set_width(lb_desc, lv_obj_get_width(desc)); + + goto out; } - else + + u32 speed = 0; + char *rsvd_blocks; + char life_a_txt[8]; + char life_b_txt[8]; + u32 cache = emmc_storage.ext_csd.cache_size; + u32 life_a = emmc_storage.ext_csd.dev_life_est_a; + u32 life_b = emmc_storage.ext_csd.dev_life_est_b; + u16 card_type = emmc_storage.ext_csd.card_type; + char card_type_support[96]; + card_type_support[0] = 0; + + // Identify manufacturer. Only official eMMCs. + switch (emmc_storage.cid.manfid) { - u32 speed = 0; - char *rsvd_blocks; - char life_a_txt[8]; - char life_b_txt[8]; - u32 cache = emmc_storage.ext_csd.cache_size; - u32 life_a = emmc_storage.ext_csd.dev_life_est_a; - u32 life_b = emmc_storage.ext_csd.dev_life_est_b; - u16 card_type = emmc_storage.ext_csd.card_type; - char card_type_support[96]; - card_type_support[0] = 0; - - // Identify manufacturer. Only official eMMCs. - switch (emmc_storage.cid.manfid) - { - case 0x11: - strcat(txt_buf, "Toshiba "); - break; - case 0x15: - strcat(txt_buf, "Samsung "); - break; - case 0x45: // Unofficial. - strcat(txt_buf, "SanDisk "); - lv_win_add_btn(win, NULL, SYMBOL_FILE_ALT" Device Report", _create_mbox_emmc_sandisk_report); - break; - case 0x90: - strcat(txt_buf, "SK Hynix "); - break; - } - - s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c%c\n%d.%d\n%04X\n%02d/%04d\n\n", - emmc_storage.cid.manfid, - emmc_storage.cid.prod_name[0], emmc_storage.cid.prod_name[1], emmc_storage.cid.prod_name[2], - emmc_storage.cid.prod_name[3], emmc_storage.cid.prod_name[4], emmc_storage.cid.prod_name[5], - emmc_storage.cid.prv & 0xF, emmc_storage.cid.prv >> 4, - emmc_storage.cid.serial, emmc_storage.cid.month, emmc_storage.cid.year); - - if (card_type & EXT_CSD_CARD_TYPE_HS_26) - { - strcat(card_type_support, "HS26"); - speed = (26 << 16) | 26; - } - if (card_type & EXT_CSD_CARD_TYPE_HS_52) - { - strcat(card_type_support, ", HS52"); - speed = (52 << 16) | 52; - } - if (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) - { - strcat(card_type_support, ", DDR52 1.8V"); - speed = (52 << 16) | 104; - } - if (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) - { - strcat(card_type_support, ", HS200 1.8V"); - speed = (200 << 16) | 200; - } - if (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) - { - strcat(card_type_support, ", HS400 1.8V"); - speed = (200 << 16) | 400; - } - - strcpy(life_a_txt, "-"); - strcpy(life_b_txt, "-"); - - // Normalize cells life. - if (life_a) // SK Hynix is 0 (undefined). - { - life_a--; - life_a = (10 - life_a) * 10; - s_printf(life_a_txt, "%d%%", life_a); - } - - if (life_b) // Toshiba is 0 (undefined). - { - life_b--; - life_b = (10 - life_b) * 10; - s_printf(life_b_txt, "%d%%", life_b); - } - - switch (emmc_storage.ext_csd.pre_eol_info) - { - case 1: - rsvd_blocks = "Normal (< 80%)"; - break; - case 2: - rsvd_blocks = "Warning (> 80%)"; - break; - case 3: - rsvd_blocks = "Critical (> 90%)"; - break; - default: - rsvd_blocks = "#FF8000 Unknown#"; - break; - } - - s_printf(txt_buf + strlen(txt_buf), - "#00DDFF V1.%d (rev 1.%d)#\n%02X\n%d MB/s (%d MHz)\n%d MB/s\n%s\n%d %s\n%d MiB\nA: %s, B: %s\n%s", - emmc_storage.ext_csd.ext_struct, emmc_storage.ext_csd.rev, - emmc_storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF, - emmc_storage.csd.busspeed, card_type_support, - !(cache % 1024) ? (cache / 1024) : cache, !(cache % 1024) ? "MiB" : "KiB", - emmc_storage.ext_csd.max_enh_mult * 512 / 1024, - life_a_txt, life_b_txt, rsvd_blocks); - - lv_label_set_static_text(lb_desc, - "#00DDFF CID:#\n" - "Vendor ID:\n" - "Model:\n" - "Prod Rev:\n" - "S/N:\n" - "Month/Year:\n\n" - "#00DDFF Ext CSD:#\n" - "Cmd Classes:\n" - "Max Rate:\n" - "Current Rate:\n" - "Type Support:\n\n" - "Write Cache:\n" - "Enhanced Area:\n" - "Estimated Life:\n" - "Reserved Used:" - ); - lv_obj_set_width(lb_desc, lv_obj_get_width(desc)); - - lv_obj_t *val = lv_cont_create(win, NULL); - lv_obj_set_size(val, LV_HOR_RES / 11 * 3, LV_VER_RES - (LV_DPI * 11 / 7) - 5); - - lv_obj_t * lb_val = lv_label_create(val, lb_desc); - - 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); - - lv_obj_t *desc2 = lv_cont_create(win, NULL); - lv_obj_set_size(desc2, LV_HOR_RES / 2 / 4 * 4, LV_VER_RES - (LV_DPI * 11 / 7) - 5); - - lv_obj_t * lb_desc2 = lv_label_create(desc2, lb_desc); - lv_label_set_style(lb_desc2, &monospace_text); - - u32 boot_size = emmc_storage.ext_csd.boot_mult << 17; - u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17; - strcpy(txt_buf, "#00DDFF eMMC Physical Partitions:#\n"); - s_printf(txt_buf + strlen(txt_buf), "1: #96FF00 BOOT0# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512); - s_printf(txt_buf + strlen(txt_buf), "2: #96FF00 BOOT1# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512); - s_printf(txt_buf + strlen(txt_buf), "3: #96FF00 RPMB# Size: %6d KiB (Sect: 0x%08X)\n", rpmb_size / 1024, rpmb_size / 512); - s_printf(txt_buf + strlen(txt_buf), "0: #96FF00 GPP# Size: %6d MiB (Sect: 0x%08X)\n", emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt); - strcat(txt_buf, "\n#00DDFF GPP (eMMC USER) Partition Table:#\n"); - - sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_GPP); - LIST_INIT(gpt); - emmc_gpt_parse(&gpt); - - u32 idx = 0; - LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link) - { - if (idx > 10) - { - strcat(txt_buf, "#FFDD00 Table does not fit on screen!#"); - break; - } - - if (part->index < 2) - { - s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#%s Size: %d MiB (Sect: 0x%X), Start: %06X\n", - part->index, part->name, !part->name[8] ? " " : "", - (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF, - part->lba_end - part->lba_start + 1, part->lba_start); - } - else - { - s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#\n Size: %7d MiB (Sect: 0x%07X), Start: %07X\n", - part->index, part->name, (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF, - part->lba_end - part->lba_start + 1, part->lba_start); - } - - idx++; - } - if (!idx) - strcat(txt_buf, "#FFDD00 Partition table is empty!#"); - - emmc_gpt_free(&gpt); - - 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); - - u16 *emmc_errors = emmc_get_error_count(); - if (emmc_get_mode() < EMMC_MMC_HS400 || - emmc_errors[EMMC_ERROR_INIT_FAIL] || - emmc_errors[EMMC_ERROR_RW_FAIL] || - emmc_errors[EMMC_ERROR_RW_RETRY]) - { - lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); - 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", "" }; - lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); - lv_mbox_set_recolor_text(mbox, true); - - s_printf(txt_buf, - "#FF8000 eMMC Issues Check#\n\n" - "#FFDD00 Your eMMC is initialized in slower mode,#\n" - "#FFDD00 or init/read/write errors occurred!#\n" - "#FFDD00 This might mean hardware issues!#\n\n" - "#00DDFF Bus Speed:# %d MB/s\n\n" - "#00DDFF SDMMC4 Errors:#\n" - "Init fails: %d\n" - "Read/Write fails: %d\n" - "Read/Write errors: %d", - emmc_storage.csd.busspeed, - emmc_errors[EMMC_ERROR_INIT_FAIL], - emmc_errors[EMMC_ERROR_RW_FAIL], - emmc_errors[EMMC_ERROR_RW_RETRY]); - - lv_mbox_set_text(mbox, txt_buf); - lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); - lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_top(mbox, true); - } + case 0x11: + strcat(txt_buf, "Toshiba "); + break; + case 0x15: + strcat(txt_buf, "Samsung "); + break; + case 0x45: // Unofficial. + strcat(txt_buf, "SanDisk "); + lv_win_add_btn(win, NULL, SYMBOL_FILE_ALT" Device Report", _create_mbox_emmc_sandisk_report); + break; + case 0x90: + strcat(txt_buf, "SK Hynix "); + break; } + s_printf(txt_buf + strlen(txt_buf), "(%02X)\n%c%c%c%c%c%c\n%d.%d\n%04X\n%02d/%04d\n\n", + emmc_storage.cid.manfid, + emmc_storage.cid.prod_name[0], emmc_storage.cid.prod_name[1], emmc_storage.cid.prod_name[2], + emmc_storage.cid.prod_name[3], emmc_storage.cid.prod_name[4], emmc_storage.cid.prod_name[5], + emmc_storage.cid.prv & 0xF, emmc_storage.cid.prv >> 4, + emmc_storage.cid.serial, emmc_storage.cid.month, emmc_storage.cid.year); + + if (card_type & EXT_CSD_CARD_TYPE_HS_26) + { + strcat(card_type_support, "HS26"); + speed = (26 << 16) | 26; + } + if (card_type & EXT_CSD_CARD_TYPE_HS_52) + { + strcat(card_type_support, ", HS52"); + speed = (52 << 16) | 52; + } + if (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) + { + strcat(card_type_support, ", DDR52 1.8V"); + speed = (52 << 16) | 104; + } + if (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) + { + strcat(card_type_support, ", HS200 1.8V"); + speed = (200 << 16) | 200; + } + if (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) + { + strcat(card_type_support, ", HS400 1.8V"); + speed = (200 << 16) | 400; + } + + strcpy(life_a_txt, "-"); + strcpy(life_b_txt, "-"); + + // Normalize cells life. + if (life_a) // SK Hynix is 0 (undefined). + { + life_a--; + life_a = (10 - life_a) * 10; + s_printf(life_a_txt, "%d%%", life_a); + } + + if (life_b) // Toshiba is 0 (undefined). + { + life_b--; + life_b = (10 - life_b) * 10; + s_printf(life_b_txt, "%d%%", life_b); + } + + switch (emmc_storage.ext_csd.pre_eol_info) + { + case 1: + rsvd_blocks = "Normal (< 80%)"; + break; + case 2: + rsvd_blocks = "Warning (> 80%)"; + break; + case 3: + rsvd_blocks = "Critical (> 90%)"; + break; + default: + rsvd_blocks = "#FF8000 Unknown#"; + break; + } + + s_printf(txt_buf + strlen(txt_buf), + "#00DDFF V1.%d (rev 1.%d)#\n%02X\n%d MB/s (%d MHz)\n%d MB/s\n%s\n%d %s\n%d MiB\nA: %s, B: %s\n%s", + emmc_storage.ext_csd.ext_struct, emmc_storage.ext_csd.rev, + emmc_storage.csd.cmdclass, speed & 0xFFFF, (speed >> 16) & 0xFFFF, + emmc_storage.csd.busspeed, card_type_support, + !(cache % 1024) ? (cache / 1024) : cache, !(cache % 1024) ? "MiB" : "KiB", + emmc_storage.ext_csd.max_enh_mult * 512 / 1024, + life_a_txt, life_b_txt, rsvd_blocks); + + lv_label_set_static_text(lb_desc, + "#00DDFF CID:#\n" + "Vendor ID:\n" + "Model:\n" + "Prod Rev:\n" + "S/N:\n" + "Month/Year:\n\n" + "#00DDFF Ext CSD:#\n" + "Cmd Classes:\n" + "Max Rate:\n" + "Current Rate:\n" + "Type Support:\n\n" + "Write Cache:\n" + "Enhanced Area:\n" + "Estimated Life:\n" + "Reserved Used:" + ); + lv_obj_set_width(lb_desc, lv_obj_get_width(desc)); + + lv_obj_t *val = lv_cont_create(win, NULL); + lv_obj_set_size(val, LV_HOR_RES / 11 * 3, LV_VER_RES - (LV_DPI * 11 / 7) - 5); + + lv_obj_t * lb_val = lv_label_create(val, lb_desc); + + 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); + + lv_obj_t *desc2 = lv_cont_create(win, NULL); + lv_obj_set_size(desc2, LV_HOR_RES / 2 / 4 * 4, LV_VER_RES - (LV_DPI * 11 / 7) - 5); + + lv_obj_t * lb_desc2 = lv_label_create(desc2, lb_desc); + lv_label_set_style(lb_desc2, &monospace_text); + + u32 boot_size = emmc_storage.ext_csd.boot_mult << 17; + u32 rpmb_size = emmc_storage.ext_csd.rpmb_mult << 17; + strcpy(txt_buf, "#00DDFF eMMC Physical Partitions:#\n"); + s_printf(txt_buf + strlen(txt_buf), "1: #96FF00 BOOT0# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512); + s_printf(txt_buf + strlen(txt_buf), "2: #96FF00 BOOT1# Size: %6d KiB (Sect: 0x%08X)\n", boot_size / 1024, boot_size / 512); + s_printf(txt_buf + strlen(txt_buf), "3: #96FF00 RPMB# Size: %6d KiB (Sect: 0x%08X)\n", rpmb_size / 1024, rpmb_size / 512); + s_printf(txt_buf + strlen(txt_buf), "0: #96FF00 GPP# Size: %6d MiB (Sect: 0x%08X)\n", emmc_storage.sec_cnt >> SECTORS_TO_MIB_COEFF, emmc_storage.sec_cnt); + strcat(txt_buf, "\n#00DDFF GPP (eMMC USER) Partition Table:#\n"); + + sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_GPP); + LIST_INIT(gpt); + emmc_gpt_parse(&gpt); + + u32 idx = 0; + LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link) + { + if (idx > 10) + { + strcat(txt_buf, "#FFDD00 Table does not fit on screen!#"); + break; + } + + if (part->index < 2) + { + s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#%s Size: %d MiB (Sect: 0x%X), Start: %06X\n", + part->index, part->name, !part->name[8] ? " " : "", + (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF, + part->lba_end - part->lba_start + 1, part->lba_start); + } + else + { + s_printf(txt_buf + strlen(txt_buf), "%02d: #96FF00 %s#\n Size: %7d MiB (Sect: 0x%07X), Start: %07X\n", + part->index, part->name, (part->lba_end - part->lba_start + 1) >> SECTORS_TO_MIB_COEFF, + part->lba_end - part->lba_start + 1, part->lba_start); + } + + idx++; + } + if (!idx) + strcat(txt_buf, "#FFDD00 Partition table is empty!#"); + + emmc_gpt_free(&gpt); + + 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); + + u16 *emmc_errors = emmc_get_error_count(); + if (emmc_get_mode() < EMMC_MMC_HS400 || + emmc_errors[EMMC_ERROR_INIT_FAIL] || + emmc_errors[EMMC_ERROR_RW_FAIL] || + emmc_errors[EMMC_ERROR_RW_RETRY]) + { + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + 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", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + + s_printf(txt_buf, + "#FF8000 eMMC Issues Check#\n\n" + "#FFDD00 Your eMMC is initialized in slower mode,#\n" + "#FFDD00 or init/read/write errors occurred!#\n" + "#FFDD00 This might mean hardware issues!#\n\n" + "#00DDFF Bus Speed:# %d MB/s\n\n" + "#00DDFF SDMMC4 Errors:#\n" + "Init fails: %d\n" + "Read/Write fails: %d\n" + "Read/Write errors: %d", + emmc_storage.csd.busspeed, + emmc_errors[EMMC_ERROR_INIT_FAIL], + emmc_errors[EMMC_ERROR_RW_FAIL], + emmc_errors[EMMC_ERROR_RW_RETRY]); + + lv_mbox_set_text(mbox, txt_buf); + lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); + } + +out: sdmmc_storage_end(&emmc_storage); free(txt_buf); diff --git a/nyx/nyx_gui/frontend/gui_tools.c b/nyx/nyx_gui/frontend/gui_tools.c index 7da29a1..48ee4ff 100644 --- a/nyx/nyx_gui/frontend/gui_tools.c +++ b/nyx/nyx_gui/frontend/gui_tools.c @@ -993,66 +993,67 @@ static lv_res_t _create_mbox_fix_touchscreen(lv_obj_t *btn) } u8 err[2]; - if (touch_panel_ito_test(err)) + if (!touch_panel_ito_test(err)) + goto ito_failed; + + if (!err[0] && !err[1]) { - if (!err[0] && !err[1]) - { - res = touch_execute_autotune(); - if (res) - goto out; - } - else - { - touch_sense_enable(); + res = touch_execute_autotune(); + if (res) + goto out; + } + else + { + touch_sense_enable(); - s_printf(txt_buf, "#FFFF00 ITO Test: "); - switch (err[0]) - { - case ITO_FORCE_OPEN: - strcat(txt_buf, "Force Open"); - break; - case ITO_SENSE_OPEN: - strcat(txt_buf, "Sense Open"); - break; - case ITO_FORCE_SHRT_GND: - strcat(txt_buf, "Force Short to GND"); - break; - case ITO_SENSE_SHRT_GND: - strcat(txt_buf, "Sense Short to GND"); - break; - case ITO_FORCE_SHRT_VCM: - strcat(txt_buf, "Force Short to VDD"); - break; - case ITO_SENSE_SHRT_VCM: - strcat(txt_buf, "Sense Short to VDD"); - break; - case ITO_FORCE_SHRT_FORCE: - strcat(txt_buf, "Force Short to Force"); - break; - case ITO_SENSE_SHRT_SENSE: - strcat(txt_buf, "Sense Short to Sense"); - break; - case ITO_F2E_SENSE: - strcat(txt_buf, "Force Short to Sense"); - break; - case ITO_FPC_FORCE_OPEN: - strcat(txt_buf, "FPC Force Open"); - break; - case ITO_FPC_SENSE_OPEN: - strcat(txt_buf, "FPC Sense Open"); - break; - default: - strcat(txt_buf, "Unknown"); - break; + s_printf(txt_buf, "#FFFF00 ITO Test: "); + switch (err[0]) + { + case ITO_FORCE_OPEN: + strcat(txt_buf, "Force Open"); + break; + case ITO_SENSE_OPEN: + strcat(txt_buf, "Sense Open"); + break; + case ITO_FORCE_SHRT_GND: + strcat(txt_buf, "Force Short to GND"); + break; + case ITO_SENSE_SHRT_GND: + strcat(txt_buf, "Sense Short to GND"); + break; + case ITO_FORCE_SHRT_VCM: + strcat(txt_buf, "Force Short to VDD"); + break; + case ITO_SENSE_SHRT_VCM: + strcat(txt_buf, "Sense Short to VDD"); + break; + case ITO_FORCE_SHRT_FORCE: + strcat(txt_buf, "Force Short to Force"); + break; + case ITO_SENSE_SHRT_SENSE: + strcat(txt_buf, "Sense Short to Sense"); + break; + case ITO_F2E_SENSE: + strcat(txt_buf, "Force Short to Sense"); + break; + case ITO_FPC_FORCE_OPEN: + strcat(txt_buf, "FPC Force Open"); + break; + case ITO_FPC_SENSE_OPEN: + strcat(txt_buf, "FPC Sense Open"); + break; + default: + strcat(txt_buf, "Unknown"); + break; - } - s_printf(txt_buf + strlen(txt_buf), " (%d), Chn: %d#\n\n", err[0], err[1]); - strcat(txt_buf, "#FFFF00 The touchscreen calibration failed!"); - lv_mbox_set_text(mbox, txt_buf); - goto out2; } + s_printf(txt_buf + strlen(txt_buf), " (%d), Chn: %d#\n\n", err[0], err[1]); + strcat(txt_buf, "#FFFF00 The touchscreen calibration failed!"); + lv_mbox_set_text(mbox, txt_buf); + goto out2; } +ito_failed: touch_sense_enable(); out: diff --git a/nyx/nyx_gui/frontend/gui_tools_partition_manager.c b/nyx/nyx_gui/frontend/gui_tools_partition_manager.c index ff9518d..4256b26 100644 --- a/nyx/nyx_gui/frontend/gui_tools_partition_manager.c +++ b/nyx/nyx_gui/frontend/gui_tools_partition_manager.c @@ -540,183 +540,183 @@ static lv_res_t _action_flash_linux_data(lv_obj_t * btns, const char * txt) bool succeeded = false; + if (btn_idx) + return LV_RES_INV; + // Flash Linux. - if (!btn_idx) + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + 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_map2[] = { "\223Delete Installation Files", "\221OK", "" }; + 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 / 10 * 5); + + lv_mbox_set_text(mbox, "#FF8000 Linux Flasher#"); + + lv_obj_t *lbl_status = lv_label_create(mbox, NULL); + lv_label_set_recolor(lbl_status, true); + lv_label_set_text(lbl_status, "#C7EA46 Status:# Flashing Linux..."); + + // Create container to keep content inside. + lv_obj_t *h1 = lv_cont_create(mbox, NULL); + lv_cont_set_fit(h1, true, true); + lv_cont_set_style(h1, &lv_style_transp_tight); + + lv_obj_t *bar = lv_bar_create(h1, NULL); + lv_obj_set_size(bar, LV_DPI * 30 / 10, LV_DPI / 5); + lv_bar_set_range(bar, 0, 100); + lv_bar_set_value(bar, 0); + + lv_obj_t *label_pct = lv_label_create(h1, NULL); + lv_label_set_recolor(label_pct, true); + lv_label_set_text(label_pct, " "SYMBOL_DOT" 0%"); + lv_label_set_style(label_pct, lv_theme_get_current()->label.prim); + lv_obj_align(label_pct, bar, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 20, 0); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); + + sd_mount(); + + int res = 0; + char *path = malloc(1024); + char *txt_buf = malloc(SZ_4K); + strcpy(path, "switchroot/install/l4t.00"); + u32 path_len = strlen(path) - 2; + + FIL fp; + + res = f_open(&fp, path, FA_READ); + if (res) { - lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); - lv_obj_set_style(dark_bg, &mbox_darken); - lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + lv_label_set_text(lbl_status, "#FFDD00 Error:# Failed to open 1st part!"); - static const char *mbox_btn_map[] = { "\211", "\222OK", "\211", "" }; - static const char *mbox_btn_map2[] = { "\223Delete Installation Files", "\221OK", "" }; - 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 / 10 * 5); + goto exit; + } - lv_mbox_set_text(mbox, "#FF8000 Linux Flasher#"); + u64 fileSize = (u64)f_size(&fp); - lv_obj_t *lbl_status = lv_label_create(mbox, NULL); - lv_label_set_recolor(lbl_status, true); - lv_label_set_text(lbl_status, "#C7EA46 Status:# Flashing Linux..."); + u32 num = 0; + u32 pct = 0; + u32 lba_curr = 0; + u32 bytesWritten = 0; + u32 currPartIdx = 0; + u32 prevPct = 200; + int retryCount = 0; + u32 total_size_sct = l4t_flash_ctxt.image_size_sct; - // Create container to keep content inside. - lv_obj_t *h1 = lv_cont_create(mbox, NULL); - lv_cont_set_fit(h1, true, true); - lv_cont_set_style(h1, &lv_style_transp_tight); + u8 *buf = (u8 *)MIXD_BUF_ALIGNED; + DWORD *clmt = f_expand_cltbl(&fp, SZ_4M, 0); - lv_obj_t *bar = lv_bar_create(h1, NULL); - lv_obj_set_size(bar, LV_DPI * 30 / 10, LV_DPI / 5); - lv_bar_set_range(bar, 0, 100); - lv_bar_set_value(bar, 0); - - lv_obj_t *label_pct = lv_label_create(h1, NULL); - lv_label_set_recolor(label_pct, true); - lv_label_set_text(label_pct, " "SYMBOL_DOT" 0%"); - lv_label_set_style(label_pct, lv_theme_get_current()->label.prim); - lv_obj_align(label_pct, bar, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 20, 0); - - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_top(mbox, true); - - sd_mount(); - - int res = 0; - char *path = malloc(1024); - char *txt_buf = malloc(SZ_4K); - strcpy(path, "switchroot/install/l4t.00"); - u32 path_len = strlen(path) - 2; - - FIL fp; - - res = f_open(&fp, path, FA_READ); - if (res) + while (total_size_sct > 0) + { + // If we have more than one part, check the size for the split parts and make sure that the bytes written is not more than that. + if (bytesWritten >= fileSize) { - lv_label_set_text(lbl_status, "#FFDD00 Error:# Failed to open 1st part!"); + // If we have more bytes written then close the file pointer and increase the part index we are using + f_close(&fp); + free(clmt); + memset(&fp, 0, sizeof(fp)); + currPartIdx++; - goto exit; - } - - u64 fileSize = (u64)f_size(&fp); - - u32 num = 0; - u32 pct = 0; - u32 lba_curr = 0; - u32 bytesWritten = 0; - u32 currPartIdx = 0; - u32 prevPct = 200; - int retryCount = 0; - u32 total_size_sct = l4t_flash_ctxt.image_size_sct; - - u8 *buf = (u8 *)MIXD_BUF_ALIGNED; - DWORD *clmt = f_expand_cltbl(&fp, SZ_4M, 0); - - while (total_size_sct > 0) - { - // If we have more than one part, check the size for the split parts and make sure that the bytes written is not more than that. - if (bytesWritten >= fileSize) + if (currPartIdx < 10) { - // If we have more bytes written then close the file pointer and increase the part index we are using - f_close(&fp); - free(clmt); - memset(&fp, 0, sizeof(fp)); - currPartIdx++; - - if (currPartIdx < 10) - { - path[path_len] = '0'; - itoa(currPartIdx, &path[path_len + 1], 10); - } - else - itoa(currPartIdx, &path[path_len], 10); - - // Try to open the next file part - res = f_open(&fp, path, FA_READ); - if (res) - { - s_printf(txt_buf, "#FFDD00 Error:# Failed to open part %d#", currPartIdx); - lv_label_set_text(lbl_status, txt_buf); - manual_system_maintenance(true); - - goto exit; - } - fileSize = (u64)f_size(&fp); - bytesWritten = 0; - clmt = f_expand_cltbl(&fp, SZ_4M, 0); + path[path_len] = '0'; + itoa(currPartIdx, &path[path_len + 1], 10); } + else + itoa(currPartIdx, &path[path_len], 10); - retryCount = 0; - num = MIN(total_size_sct, 8192); - - res = f_read_fast(&fp, buf, num << 9); - manual_system_maintenance(false); - + // Try to open the next file part + res = f_open(&fp, path, FA_READ); if (res) { - lv_label_set_text(lbl_status, "#FFDD00 Error:# Reading from SD!"); + s_printf(txt_buf, "#FFDD00 Error:# Failed to open part %d#", currPartIdx); + lv_label_set_text(lbl_status, txt_buf); + manual_system_maintenance(true); + + goto exit; + } + fileSize = (u64)f_size(&fp); + bytesWritten = 0; + clmt = f_expand_cltbl(&fp, SZ_4M, 0); + } + + retryCount = 0; + num = MIN(total_size_sct, 8192); + + res = f_read_fast(&fp, buf, num << 9); + manual_system_maintenance(false); + + if (res) + { + lv_label_set_text(lbl_status, "#FFDD00 Error:# Reading from SD!"); + manual_system_maintenance(true); + + f_close(&fp); + free(clmt); + goto exit; + } + res = !sdmmc_storage_write(&sd_storage, lba_curr + l4t_flash_ctxt.offset_sct, num, buf); + + manual_system_maintenance(false); + + while (res) + { + msleep(150); + manual_system_maintenance(true); + + if (retryCount >= 3) + { + lv_label_set_text(lbl_status, "#FFDD00 Error:# Writing to SD!"); manual_system_maintenance(true); f_close(&fp); free(clmt); goto exit; } + res = !sdmmc_storage_write(&sd_storage, lba_curr + l4t_flash_ctxt.offset_sct, num, buf); - manual_system_maintenance(false); - - while (res) - { - msleep(150); - manual_system_maintenance(true); - - if (retryCount >= 3) - { - lv_label_set_text(lbl_status, "#FFDD00 Error:# Writing to SD!"); - manual_system_maintenance(true); - - f_close(&fp); - free(clmt); - goto exit; - } - - res = !sdmmc_storage_write(&sd_storage, lba_curr + l4t_flash_ctxt.offset_sct, num, buf); - manual_system_maintenance(false); - } - pct = (u64)((u64)lba_curr * 100u) / (u64)l4t_flash_ctxt.image_size_sct; - if (pct != prevPct) - { - lv_bar_set_value(bar, pct); - s_printf(txt_buf, " #DDDDDD "SYMBOL_DOT"# %d%%", pct); - lv_label_set_text(label_pct, txt_buf); - manual_system_maintenance(true); - prevPct = pct; - } - - lba_curr += num; - total_size_sct -= num; - bytesWritten += num * EMMC_BLOCKSIZE; } - lv_bar_set_value(bar, 100); - lv_label_set_text(label_pct, " "SYMBOL_DOT" 100%"); - manual_system_maintenance(true); + pct = (u64)((u64)lba_curr * 100u) / (u64)l4t_flash_ctxt.image_size_sct; + if (pct != prevPct) + { + lv_bar_set_value(bar, pct); + s_printf(txt_buf, " #DDDDDD "SYMBOL_DOT"# %d%%", pct); + lv_label_set_text(label_pct, txt_buf); + manual_system_maintenance(true); + prevPct = pct; + } - // Restore operation ended successfully. - f_close(&fp); - free(clmt); + lba_curr += num; + total_size_sct -= num; + bytesWritten += num * EMMC_BLOCKSIZE; + } + lv_bar_set_value(bar, 100); + lv_label_set_text(label_pct, " "SYMBOL_DOT" 100%"); + manual_system_maintenance(true); - succeeded = true; + // Restore operation ended successfully. + f_close(&fp); + free(clmt); + + succeeded = true; exit: - free(path); - free(txt_buf); + free(path); + free(txt_buf); - if (!succeeded) - lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); - else - lv_mbox_add_btns(mbox, mbox_btn_map2, _action_delete_linux_installer_files); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + if (!succeeded) + lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); + else + lv_mbox_add_btns(mbox, mbox_btn_map2, _action_delete_linux_installer_files); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - sd_unmount(); - } + sd_unmount(); return LV_RES_INV; } @@ -856,36 +856,34 @@ static lv_res_t _action_check_flash_linux(lv_obj_t *btn) itoa(idx, &path[23], 10); // Check for alignment. - if (!f_stat(path, &fno)) - { - if ((u64)fno.fsize % SZ_4M) - { - // Check if last part. - idx++; - if (idx < 10) - { - path[23] = '0'; - itoa(idx, &path[23 + 1], 10); - } - else - itoa(idx, &path[23], 10); - - // If not the last part, unaligned size is not permitted. - if (!f_stat(path, NULL)) // NULL: Don't override current part fs info. - { - lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!"); - goto error; - } - - // Last part. Align size to LBA (512 bytes). - fno.fsize = ALIGN((u64)fno.fsize, 512); - idx--; - } - l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9; - } - else + if (f_stat(path, &fno)) break; + if ((u64)fno.fsize % SZ_4M) + { + // Check if last part. + idx++; + if (idx < 10) + { + path[23] = '0'; + itoa(idx, &path[23 + 1], 10); + } + else + itoa(idx, &path[23], 10); + + // If not the last part, unaligned size is not permitted. + if (!f_stat(path, NULL)) // NULL: Don't override current part fs info. + { + lv_label_set_text(lbl_status, "#FFDD00 Error:# The image is not aligned to 4 MiB!"); + goto error; + } + + // Last part. Align size to LBA (512 bytes). + fno.fsize = ALIGN((u64)fno.fsize, 512); + idx--; + } + l4t_flash_ctxt.image_size_sct += (u64)fno.fsize >> 9; + idx++; } @@ -950,236 +948,244 @@ static lv_res_t _action_flash_android_data(lv_obj_t * btns, const char * txt) // Delete parent mbox. mbox_action(btns, txt); + if (btn_idx) + return LV_RES_INV; + // Flash Android components. - if (!btn_idx) + char path[128]; + gpt_t *gpt = calloc(1, sizeof(gpt_t)); + char *txt_buf = malloc(SZ_4K); + + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + 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_map2[] = { "\222Continue", "\222No", "" }; + 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); + + lv_mbox_set_text(mbox, "#FF8000 Android Flasher#"); + + lv_obj_t *lbl_status = lv_label_create(mbox, NULL); + lv_label_set_recolor(lbl_status, true); + lv_label_set_text(lbl_status, "#C7EA46 Status:# Searching for files and partitions..."); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); + + manual_system_maintenance(true); + + sd_mount(); + + // Read main GPT. + sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt); + + bool boot_twrp = false; + if (memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128) { - char path[128]; - gpt_t *gpt = calloc(1, sizeof(gpt_t)); - char *txt_buf = malloc(SZ_4K); + lv_label_set_text(lbl_status, "#FFDD00 Error:# No Android GPT was found!"); + goto error; + } - lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); - lv_obj_set_style(dark_bg, &mbox_darken); - lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + u32 offset_sct = 0; + u32 size_sct = 0; - static const char *mbox_btn_map[] = { "\211", "\222OK", "\211", "" }; - static const char *mbox_btn_map2[] = { "\222Continue", "\222No", "" }; - 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); + strcpy(path, "switchroot/install/boot.img"); + if (f_stat(path, NULL)) + { + s_printf(txt_buf, "#FF8000 Warning:# Kernel image not found!\n"); + goto boot_img_not_found; + } - lv_mbox_set_text(mbox, "#FF8000 Android Flasher#"); - - lv_obj_t *lbl_status = lv_label_create(mbox, NULL); - lv_label_set_recolor(lbl_status, true); - lv_label_set_text(lbl_status, "#C7EA46 Status:# Searching for files and partitions..."); - - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_top(mbox, true); - - manual_system_maintenance(true); - - sd_mount(); - - // Read main GPT. - sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt); - - bool boot_twrp = false; - if (memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128) + for (u32 i = 0; i < gpt->header.num_part_ents; i++) + { + if (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6)) { - lv_label_set_text(lbl_status, "#FFDD00 Error:# No Android GPT was found!"); - goto error; + offset_sct = gpt->entries[i].lba_start; + size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start; + break; } - strcpy(path, "switchroot/install/boot.img"); - if (!f_stat(path, NULL)) + if (i > 126) + break; + } + + if (offset_sct && size_sct) + { + u32 file_size = 0; + u8 *buf = sd_file_read(path, &file_size); + + if (file_size % 0x200) { - u32 offset_sct = 0; - u32 size_sct = 0; - for (u32 i = 0; i < gpt->header.num_part_ents; i++) - { - if (!memcmp(gpt->entries[i].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6)) - { - offset_sct = gpt->entries[i].lba_start; - size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start; - break; - } - - if (i > 126) - break; - } - - if (offset_sct && size_sct) - { - u32 file_size = 0; - u8 *buf = sd_file_read(path, &file_size); - - if (file_size % 0x200) - { - file_size = ALIGN(file_size, 0x200); - u8 *buf_tmp = calloc(file_size, 1); - memcpy(buf_tmp, buf, file_size); - free(buf); - buf = buf_tmp; - } - - if ((file_size >> 9) > size_sct) - s_printf(txt_buf, "#FF8000 Warning:# Kernel image too big!\n"); - else - { - sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf); - - s_printf(txt_buf, "#C7EA46 Success:# Kernel image flashed!\n"); - f_unlink(path); - } - - free(buf); - } - else - s_printf(txt_buf, "#FF8000 Warning:# Kernel partition not found!\n"); + file_size = ALIGN(file_size, 0x200); + u8 *buf_tmp = calloc(file_size, 1); + memcpy(buf_tmp, buf, file_size); + free(buf); + buf = buf_tmp; } + + if ((file_size >> 9) > size_sct) + s_printf(txt_buf, "#FF8000 Warning:# Kernel image too big!\n"); else - s_printf(txt_buf, "#FF8000 Warning:# Kernel image not found!\n"); - - lv_label_set_text(lbl_status, txt_buf); - manual_system_maintenance(true); - - strcpy(path, "switchroot/install/twrp.img"); - if (!f_stat(path, NULL)) { - u32 offset_sct = 0; - u32 size_sct = 0; - for (u32 i = 0; i < gpt->header.num_part_ents; i++) - { - if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6)) - { - offset_sct = gpt->entries[i].lba_start; - size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start; - break; - } + sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf); - if (i > 126) - break; - } - - if (offset_sct && size_sct) - { - u32 file_size = 0; - u8 *buf = sd_file_read(path, &file_size); - - if (file_size % 0x200) - { - file_size = ALIGN(file_size, 0x200); - u8 *buf_tmp = calloc(file_size, 1); - memcpy(buf_tmp, buf, file_size); - free(buf); - buf = buf_tmp; - } - - if ((file_size >> 9) > size_sct) - strcat(txt_buf, "#FF8000 Warning:# TWRP image too big!\n"); - else - { - sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf); - strcat(txt_buf, "#C7EA46 Success:# TWRP image flashed!\n"); - f_unlink(path); - } - - free(buf); - } - else - strcat(txt_buf, "#FF8000 Warning:# TWRP partition not found!\n"); + s_printf(txt_buf, "#C7EA46 Success:# Kernel image flashed!\n"); + f_unlink(path); } + + free(buf); + } + else + s_printf(txt_buf, "#FF8000 Warning:# Kernel partition not found!\n"); + +boot_img_not_found: + lv_label_set_text(lbl_status, txt_buf); + manual_system_maintenance(true); + + strcpy(path, "switchroot/install/twrp.img"); + if (f_stat(path, NULL)) + { + strcat(txt_buf, "#FF8000 Warning:# TWRP image not found!\n"); + goto twrp_not_found; + } + + offset_sct = 0; + size_sct = 0; + for (u32 i = 0; i < gpt->header.num_part_ents; i++) + { + if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6)) + { + offset_sct = gpt->entries[i].lba_start; + size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start; + break; + } + + if (i > 126) + break; + } + + if (offset_sct && size_sct) + { + u32 file_size = 0; + u8 *buf = sd_file_read(path, &file_size); + + if (file_size % 0x200) + { + file_size = ALIGN(file_size, 0x200); + u8 *buf_tmp = calloc(file_size, 1); + memcpy(buf_tmp, buf, file_size); + free(buf); + buf = buf_tmp; + } + + if ((file_size >> 9) > size_sct) + strcat(txt_buf, "#FF8000 Warning:# TWRP image too big!\n"); else - strcat(txt_buf, "#FF8000 Warning:# TWRP image not found!\n"); - - lv_label_set_text(lbl_status, txt_buf); - manual_system_maintenance(true); - - strcpy(path, "switchroot/install/tegra210-icosa.dtb"); - if (!f_stat(path, NULL)) { - u32 offset_sct = 0; - u32 size_sct = 0; - for (u32 i = 0; i < gpt->header.num_part_ents; i++) - { - if (!memcmp(gpt->entries[i].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6)) - { - offset_sct = gpt->entries[i].lba_start; - size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start; - break; - } - - if (i > 126) - break; - } - - if (offset_sct && size_sct) - { - u32 file_size = 0; - u8 *buf = sd_file_read(path, &file_size); - - if (file_size % 0x200) - { - file_size = ALIGN(file_size, 0x200); - u8 *buf_tmp = calloc(file_size, 1); - memcpy(buf_tmp, buf, file_size); - free(buf); - buf = buf_tmp; - } - - if ((file_size >> 9) > size_sct) - strcat(txt_buf, "#FF8000 Warning:# DTB image too big!"); - else - { - sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf); - strcat(txt_buf, "#C7EA46 Success:# DTB image flashed!"); - f_unlink(path); - } - - free(buf); - } - else - strcat(txt_buf, "#FF8000 Warning:# DTB partition not found!"); + sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf); + strcat(txt_buf, "#C7EA46 Success:# TWRP image flashed!\n"); + f_unlink(path); } + + free(buf); + } + else + strcat(txt_buf, "#FF8000 Warning:# TWRP partition not found!\n"); + +twrp_not_found: + lv_label_set_text(lbl_status, txt_buf); + manual_system_maintenance(true); + + strcpy(path, "switchroot/install/tegra210-icosa.dtb"); + if (f_stat(path, NULL)) + { + strcat(txt_buf, "#FF8000 Warning:# DTB image not found!"); + + goto dtb_not_found; + } + + offset_sct = 0; + size_sct = 0; + for (u32 i = 0; i < gpt->header.num_part_ents; i++) + { + if (!memcmp(gpt->entries[i].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6)) + { + offset_sct = gpt->entries[i].lba_start; + size_sct = (gpt->entries[i].lba_end + 1) - gpt->entries[i].lba_start; + break; + } + + if (i > 126) + break; + } + + if (offset_sct && size_sct) + { + u32 file_size = 0; + u8 *buf = sd_file_read(path, &file_size); + + if (file_size % 0x200) + { + file_size = ALIGN(file_size, 0x200); + u8 *buf_tmp = calloc(file_size, 1); + memcpy(buf_tmp, buf, file_size); + free(buf); + buf = buf_tmp; + } + + if ((file_size >> 9) > size_sct) + strcat(txt_buf, "#FF8000 Warning:# DTB image too big!"); else - strcat(txt_buf, "#FF8000 Warning:# DTB image not found!"); - - lv_label_set_text(lbl_status, txt_buf); - - // Check if TWRP is flashed unconditionally. - for (u32 i = 0; i < gpt->header.num_part_ents; i++) { - if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6)) - { - u8 *buf = malloc(512); - sdmmc_storage_read(&sd_storage, gpt->entries[i].lba_start, 1, buf); - if (!memcmp(buf, "ANDROID", 7)) - boot_twrp = true; - free(buf); - break; - } - - if (i > 126) - break; + sdmmc_storage_write(&sd_storage, offset_sct, file_size >> 9, buf); + strcat(txt_buf, "#C7EA46 Success:# DTB image flashed!"); + f_unlink(path); } + free(buf); + } + else + strcat(txt_buf, "#FF8000 Warning:# DTB partition not found!"); + +dtb_not_found: + lv_label_set_text(lbl_status, txt_buf); + + // Check if TWRP is flashed unconditionally. + for (u32 i = 0; i < gpt->header.num_part_ents; i++) + { + if (!memcmp(gpt->entries[i].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6)) + { + u8 *buf = malloc(512); + sdmmc_storage_read(&sd_storage, gpt->entries[i].lba_start, 1, buf); + if (!memcmp(buf, "ANDROID", 7)) + boot_twrp = true; + free(buf); + break; + } + + if (i > 126) + break; + } + error: - if (boot_twrp) - { - strcat(txt_buf,"\n\nDo you want to reboot into TWRP\nto finish Android installation?"); - lv_label_set_text(lbl_status, txt_buf); - lv_mbox_add_btns(mbox, mbox_btn_map2, _action_reboot_twrp); - } - else - lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); - - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - - free(txt_buf); - free(gpt); - - sd_unmount(); + if (boot_twrp) + { + strcat(txt_buf,"\n\nDo you want to reboot into TWRP\nto finish Android installation?"); + lv_label_set_text(lbl_status, txt_buf); + lv_mbox_add_btns(mbox, mbox_btn_map2, _action_reboot_twrp); } + else + lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + + free(txt_buf); + free(gpt); + + sd_unmount(); return LV_RES_INV; } @@ -1409,54 +1415,58 @@ static lv_res_t _create_mbox_start_partitioning(lv_obj_t *btn) u32 cluster_size = 65536; u32 mkfs_error = f_mkfs("sd:", FM_FAT32, cluster_size, buf, SZ_4M); + + if (!mkfs_error) + goto mkfs_no_error; + + // Retry by halving cluster size. + while (cluster_size > 4096) + { + cluster_size /= 2; + mkfs_error = f_mkfs("sd:", FM_FAT32, cluster_size, buf, SZ_4M); + + if (!mkfs_error) + break; + } + if (mkfs_error) { - // Retry by halving cluster size. - while (cluster_size > 4096) - { - cluster_size /= 2; - mkfs_error = f_mkfs("sd:", FM_FAT32, cluster_size, buf, SZ_4M); + // Failed to format. + s_printf((char *)buf, "#FFDD00 Error:# Failed to format disk (%d)!\n\n" + "Remove the SD card and check that is OK.\nIf not, format it, reinsert it and\npress #FF8000 POWER#!", mkfs_error); - if (!mkfs_error) - break; + lv_label_set_text(lbl_status, (char *)buf); + lv_label_set_text(lbl_paths[0], " "); + manual_system_maintenance(true); + + sd_end(); + + while (!(btn_wait() & BTN_POWER)); + + sd_mount(); + + if (!part_info.backup_possible) + { + f_chdrive("sd:"); + f_mkdir(path); } - if (mkfs_error) + lv_label_set_text(lbl_status, "#00DDFF Status:# Restoring files..."); + manual_system_maintenance(true); + if (_backup_and_restore_files(path, &total_files, &total_size, "sd:", "ram:", NULL)) { - // Failed to format. - s_printf((char *)buf, "#FFDD00 Error:# Failed to format disk (%d)!\n\n" - "Remove the SD card and check that is OK.\nIf not, format it, reinsert it and\npress #FF8000 POWER#!", mkfs_error); - - lv_label_set_text(lbl_status, (char *)buf); - lv_label_set_text(lbl_paths[0], " "); - manual_system_maintenance(true); - - sd_end(); - - while (!(btn_wait() & BTN_POWER)); - - sd_mount(); - - if (!part_info.backup_possible) - { - f_chdrive("sd:"); - f_mkdir(path); - } - - lv_label_set_text(lbl_status, "#00DDFF Status:# Restoring files..."); - manual_system_maintenance(true); - if (_backup_and_restore_files(path, &total_files, &total_size, "sd:", "ram:", NULL)) - { - lv_label_set_text(lbl_status, "#FFDD00 Error:# Failed to restore files!"); - free(buf); - goto error; - } - lv_label_set_text(lbl_status, "#00DDFF Status:# Restored files but the operation failed!"); - f_mount(NULL, "ram:", 1); // Unmount ramdisk. + lv_label_set_text(lbl_status, "#FFDD00 Error:# Failed to restore files!"); free(buf); goto error; } + + lv_label_set_text(lbl_status, "#00DDFF Status:# Restored files but the operation failed!"); + f_mount(NULL, "ram:", 1); // Unmount ramdisk. + free(buf); + goto error; } + +mkfs_no_error: free(buf); f_mount(&sd_fs, "sd:", 1); // Mount SD card. diff --git a/nyx/nyx_gui/nyx.c b/nyx/nyx_gui/nyx.c index 2bdf546..edf1c32 100644 --- a/nyx/nyx_gui/nyx.c +++ b/nyx/nyx_gui/nyx.c @@ -138,67 +138,67 @@ lv_res_t launch_payload(lv_obj_t *list) strcpy(path,"bootloader/payloads/"); strcat(path, filename); - if (sd_mount()) + if (!sd_mount()) + goto out; + + FIL fp; + if (f_open(&fp, path, FA_READ)) { - FIL fp; - if (f_open(&fp, path, FA_READ)) - { - EPRINTFARGS("Payload file is missing!\n(%s)", path); + EPRINTFARGS("Payload file is missing!\n(%s)", path); - goto out; - } + goto out; + } - // Read and copy the payload to our chosen address - void *buf; - u32 size = f_size(&fp); + // Read and copy the payload to our chosen address + void *buf; + u32 size = f_size(&fp); - if (size < 0x30000) - buf = (void *)RCM_PAYLOAD_ADDR; - else - { - coreboot_addr = (void *)(COREBOOT_END_ADDR - size); - buf = coreboot_addr; - if (h_cfg.t210b01) - { - f_close(&fp); - - EPRINTF("Coreboot not allowed on Mariko!"); - - goto out; - } - } - - if (f_read(&fp, buf, size, NULL)) + if (size < 0x30000) + buf = (void *)RCM_PAYLOAD_ADDR; + else + { + coreboot_addr = (void *)(COREBOOT_END_ADDR - size); + buf = coreboot_addr; + if (h_cfg.t210b01) { f_close(&fp); + EPRINTF("Coreboot not allowed on Mariko!"); + goto out; } + } + if (f_read(&fp, buf, size, NULL)) + { f_close(&fp); - sd_end(); - - if (size < 0x30000) - { - reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10)); - hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32)))); - } - else - { - reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000); - hw_reinit_workaround(true, 0); - } - - void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR; - - // Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms. - sdmmc_storage_init_wait_sd(); - - // Launch our payload. - (*ext_payload_ptr)(); + goto out; } + f_close(&fp); + + sd_end(); + + if (size < 0x30000) + { + reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10)); + hw_reinit_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32)))); + } + else + { + reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000); + hw_reinit_workaround(true, 0); + } + + void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR; + + // Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms. + sdmmc_storage_init_wait_sd(); + + // Launch our payload. + (*ext_payload_ptr)(); + out: sd_unmount(); @@ -210,71 +210,72 @@ void load_saved_configuration() LIST_INIT(ini_sections); LIST_INIT(ini_nyx_sections); - // Load hekate configuration. - if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) - { - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) - { - // Only parse config section. - if (ini_sec->type == INI_CHOICE && !strcmp(ini_sec->name, "config")) - { - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) - { - if (!strcmp("autoboot", kv->key)) - h_cfg.autoboot = atoi(kv->val); - else if (!strcmp("autoboot_list", kv->key)) - h_cfg.autoboot_list = atoi(kv->val); - else if (!strcmp("bootwait", kv->key)) - h_cfg.bootwait = atoi(kv->val); - else if (!strcmp("backlight", kv->key)) - { - h_cfg.backlight = atoi(kv->val); - if (h_cfg.backlight <= 20) - h_cfg.backlight = 30; - } - else if (!strcmp("autohosoff", kv->key)) - 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("bootprotect", kv->key)) - h_cfg.bootprotect = atoi(kv->val); - } + if (!ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false)) + goto skip_main_cfg_parse; - break; + // Load hekate configuration. + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link) + { + // Only parse config section. + if (ini_sec->type == INI_CHOICE && !strcmp(ini_sec->name, "config")) + { + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + if (!strcmp("autoboot", kv->key)) + h_cfg.autoboot = atoi(kv->val); + else if (!strcmp("autoboot_list", kv->key)) + h_cfg.autoboot_list = atoi(kv->val); + else if (!strcmp("bootwait", kv->key)) + h_cfg.bootwait = atoi(kv->val); + else if (!strcmp("backlight", kv->key)) + { + h_cfg.backlight = atoi(kv->val); + if (h_cfg.backlight <= 20) + h_cfg.backlight = 30; + } + else if (!strcmp("autohosoff", kv->key)) + 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("bootprotect", kv->key)) + h_cfg.bootprotect = atoi(kv->val); } + + break; } } - // Load Nyx configuration. - if (ini_parse(&ini_nyx_sections, "bootloader/nyx.ini", false)) - { - LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_nyx_sections, link) - { - // Only parse config section. - if (ini_sec->type == INI_CHOICE && !strcmp(ini_sec->name, "config")) - { - LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) - { - if (!strcmp("themecolor", kv->key)) - n_cfg.themecolor = atoi(kv->val); - else if (!strcmp("timeoff", kv->key)) - n_cfg.timeoff = strtol(kv->val, NULL, 16); - else if (!strcmp("homescreen", kv->key)) - n_cfg.home_screen = atoi(kv->val); - else if (!strcmp("verification", kv->key)) - n_cfg.verification = atoi(kv->val); - else if (!strcmp("umsemmcrw", kv->key)) - n_cfg.ums_emmc_rw = atoi(kv->val) == 1; - else if (!strcmp("jcdisable", kv->key)) - n_cfg.jc_disable = atoi(kv->val) == 1; - else if (!strcmp("bpmpclock", kv->key)) - n_cfg.bpmp_clock = strtol(kv->val, NULL, 10); - } +skip_main_cfg_parse: + if (!ini_parse(&ini_nyx_sections, "bootloader/nyx.ini", false)) + return; - break; + // Load Nyx configuration. + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_nyx_sections, link) + { + // Only parse config section. + if (ini_sec->type == INI_CHOICE && !strcmp(ini_sec->name, "config")) + { + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + if (!strcmp("themecolor", kv->key)) + n_cfg.themecolor = atoi(kv->val); + else if (!strcmp("timeoff", kv->key)) + n_cfg.timeoff = strtol(kv->val, NULL, 16); + else if (!strcmp("homescreen", kv->key)) + n_cfg.home_screen = atoi(kv->val); + else if (!strcmp("verification", kv->key)) + n_cfg.verification = atoi(kv->val); + else if (!strcmp("umsemmcrw", kv->key)) + n_cfg.ums_emmc_rw = atoi(kv->val) == 1; + else if (!strcmp("jcdisable", kv->key)) + n_cfg.jc_disable = atoi(kv->val) == 1; + else if (!strcmp("bpmpclock", kv->key)) + n_cfg.bpmp_clock = strtol(kv->val, NULL, 10); } + + break; } } }