mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 03:11:16 +00:00
hekate/nyx: improve cyclomatic complexity
This commit is contained in:
parent
2f1d1572f7
commit
aee5861f65
9 changed files with 1733 additions and 1701 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue