From b2dd070d10255ad63aed39cde83616f1d8d60590 Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Wed, 13 Jun 2018 02:34:32 +0300 Subject: [PATCH 1/2] [INI] Fix memory leaks + other fixes (#38) * [INI] Fix memory leaks + other fixes * Add ini_free * check and return if NULL pointer in free() * Add button check with timeout * Fix a bug in menu rendering that tries to parse a string without existing * Change initial cnt value to max (fixes menus with first entry not a selectable entry) * Some & ? clarifications * [INI] Add get selected boot cfg - This allows to free ini as we launch the firmware and have the lowest mem leak * [INI] Rename ini section clone/free functions --- ipl/btn.c | 18 ++++++++++++ ipl/btn.h | 1 + ipl/gpio.c | 2 +- ipl/heap.c | 5 +++- ipl/hos.c | 2 +- ipl/ini.c | 48 ++++++++++++++++++++++++++++++++ ipl/ini.h | 3 ++ ipl/main.c | 75 +++++++++++++++++++++++++++----------------------- ipl/max7762x.c | 4 +-- ipl/pkg1.c | 2 +- ipl/sdmmc.c | 2 +- ipl/tui.c | 9 +++--- 12 files changed, 124 insertions(+), 47 deletions(-) diff --git a/ipl/btn.c b/ipl/btn.c index 72a71eb..eb12ffe 100755 --- a/ipl/btn.c +++ b/ipl/btn.c @@ -18,6 +18,7 @@ #include "i2c.h" #include "gpio.h" #include "t210.h" +#include "util.h" u32 btn_read() { @@ -53,5 +54,22 @@ u32 btn_wait() else if (pwr) res &= 0xFFFFFFFE; } while (btn == res); + + return res; +} + +u32 btn_wait_timeout(u32 time_ms) +{ + u32 timeout = get_tmr() + (time_ms * 1000); + u32 res = btn_read(); + u32 btn = res; + + do + { + //Keep the new value until timeout is reached + if (btn == res) + res = btn_read(); + } while (get_tmr() < timeout); + return res; } diff --git a/ipl/btn.h b/ipl/btn.h index 8c5a8c5..09ff329 100755 --- a/ipl/btn.h +++ b/ipl/btn.h @@ -25,5 +25,6 @@ u32 btn_read(); u32 btn_wait(); +u32 btn_wait_timeout(u32 time_ms); #endif diff --git a/ipl/gpio.c b/ipl/gpio.c index 596af03..fb75ee8 100755 --- a/ipl/gpio.c +++ b/ipl/gpio.c @@ -90,5 +90,5 @@ void gpio_write(u32 port, u32 pins, int high) int gpio_read(u32 port, u32 pins) { - return GPIO(_gpio_in[port]) & pins ? 1 : 0; + return (GPIO(_gpio_in[port]) & pins) ? 1 : 0; } diff --git a/ipl/heap.c b/ipl/heap.c index c90607b..12bfb44 100755 --- a/ipl/heap.c +++ b/ipl/heap.c @@ -97,6 +97,7 @@ static void _heap_free(heap_t *heap, u32 addr) while (node) { if (!node->used) + { if (node->prev && !node->prev->used) { node->prev->size += node->size + sizeof(hnode_t); @@ -104,6 +105,7 @@ static void _heap_free(heap_t *heap, u32 addr) if (node->next) node->next->prev = node->prev; } + } node = node->next; } } @@ -129,5 +131,6 @@ void *calloc(u32 num, u32 size) void free(void *buf) { - _heap_free(&_heap, (u32)buf); + if (buf != NULL) + _heap_free(&_heap, (u32)buf); } diff --git a/ipl/hos.c b/ipl/hos.c index d3c45a4..a8df029 100755 --- a/ipl/hos.c +++ b/ipl/hos.c @@ -109,7 +109,7 @@ u32 crc32c(const u8 *buf, u32 len) { crc ^= *buf++; for (int i = 0; i < 8; i++) - crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1; + crc = (crc & 1) ? (crc >> 1) ^ CRC32C_POLY : crc >> 1; } return ~crc; } diff --git a/ipl/ini.c b/ipl/ini.c index 8551203..3e4401e 100755 --- a/ipl/ini.c +++ b/ipl/ini.c @@ -91,3 +91,51 @@ int ini_parse(link_t *dst, char *ini_path) return 1; } + +void ini_free(link_t *dst) +{ + LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, dst, link) + { + LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link) + { + free(kv->key); + free(kv->val); + free(kv); + } + free(ini_sec->name); + free(ini_sec); + } +} + +ini_sec_t *ini_clone_section(ini_sec_t *cfg) +{ + if (cfg == NULL) + return NULL; + + ini_sec_t *csec = (ini_sec_t *)malloc(sizeof(ini_sec_t)); + list_init(&csec->kvs); + + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link) + { + ini_kv_t *kvcfg = (ini_kv_t *)malloc(sizeof(ini_kv_t)); + kvcfg->key = _strdup(kv->key); + kvcfg->val = _strdup(kv->val); + list_append(&csec->kvs, &kvcfg->link); + } + + return csec; +} + +void ini_free_section(ini_sec_t *cfg) +{ + if (cfg == NULL) + return; + + LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link) + { + free(kv->key); + free(kv->val); + free(kv); + } + free(cfg); +} diff --git a/ipl/ini.h b/ipl/ini.h index 091009e..6f8d692 100755 --- a/ipl/ini.h +++ b/ipl/ini.h @@ -35,5 +35,8 @@ typedef struct _ini_sec_t } ini_sec_t; int ini_parse(link_t *dst, char *ini_path); +void ini_free(link_t *dst); +ini_sec_t *ini_clone_section(ini_sec_t *cfg); +void ini_free_section(ini_sec_t *cfg); #endif diff --git a/ipl/main.c b/ipl/main.c index bb1b8da..25f16fd 100755 --- a/ipl/main.c +++ b/ipl/main.c @@ -870,7 +870,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) // Verify part if (dump_emmc_verify(storage, lba_curr, outFilename, NUM_SECTORS_PER_ITER, part)) { - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); return 0; @@ -938,7 +938,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) { EPRINTFARGS("\nFailed to read %d blocks @ LBA %08X from eMMC. Aborting..\n", num, lba_curr); - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); f_close(&fp); @@ -949,7 +949,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) if (res) { EPRINTFARGS("\nFatal error (%d) when writing to SD Card", res); - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); f_close(&fp); @@ -982,7 +982,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) // Verify last part or single file backup if (dump_emmc_verify(storage, lba_curr, outFilename, NUM_SECTORS_PER_ITER, part)) { - EPRINTF("\nPress any key and try again.\n"); + EPRINTF("\nPress any key and try again...\n"); free(buf); return 0; @@ -1099,7 +1099,7 @@ static void dump_emmc_selected(dumpType_t dumpType) gfx_printf(&gfx_con, "Time taken: %d seconds.\n", (get_tmr() - timer) / 1000000); sdmmc_storage_end(&storage); if (res) - gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key.\n",0xFF00FF96, 0xFFCCCCCC); + gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key...\n",0xFF00FF96, 0xFFCCCCCC); out:; btn_wait(); @@ -1112,15 +1112,10 @@ void dump_emmc_rawnand() { dump_emmc_selected(DUMP_RAW); } void dump_package1() { - u8 *pkg1 = (u8 *)malloc(0x40000); - u8 *warmboot = (u8 *)malloc(0x40000); - u8 *secmon = (u8 *)malloc(0x40000); - u8 *loader = (u8 *)malloc(0x40000); - - memset(pkg1, 0, 0x40000); - memset(warmboot, 0, 0x40000); - memset(secmon, 0, 0x40000); - memset(loader, 0, 0x40000); + u8 *pkg1 = (u8 *)calloc(1, 0x40000); + u8 *warmboot = (u8 *)calloc(1, 0x40000); + u8 *secmon = (u8 *)calloc(1, 0x40000); + u8 *loader = (u8 *)calloc(1, 0x40000); gfx_clear_grey(&gfx_ctxt, 0x1B); gfx_con_setpos(&gfx_con, 0, 0); @@ -1137,7 +1132,7 @@ void dump_package1() } sdmmc_storage_set_mmc_partition(&storage, 1); - //Read package1. + // Read package1. sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1); const pkg1_id_t *pkg1_id = pkg1_identify(pkg1); const pk11_hdr_t *hdr = (pk11_hdr_t *)(pkg1 + pkg1_id->pkg11_off + 0x20); @@ -1151,13 +1146,13 @@ void dump_package1() u8 * keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE); sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob); - // decrypt + // Decrypt keygen(keyblob, pkg1_id->kb, (u8 *)pkg1 + pkg1_id->tsec_off); pkg1_decrypt(pkg1_id, pkg1); pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1); - // display info + // Display info gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->ldr_size); gfx_printf(&gfx_con, "%kNX Bootloader ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->ldr_off); @@ -1169,28 +1164,28 @@ void dump_package1() gfx_printf(&gfx_con, "%kWarmboot size: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->wb_size); gfx_printf(&gfx_con, "%kWarmboot ofst: %k0x%05X\n\n", 0xFF46EAC7, 0xFFCCCCCC, hdr->wb_off); - // dump package1 + // Dump package1 if (sd_save_to_file(pkg1, 0x40000, "pkg1_decr.bin")) { EPRINTF("\nFailed to create pkg1_decr.bin"); goto out; } gfx_puts(&gfx_con, "\npackage1 dumped to pkg1_decr.bin\n"); - // dump nxbootloader + // Dump nxbootloader if (sd_save_to_file(loader, hdr->ldr_size, "nxloader.bin")) { EPRINTF("\nFailed to create nxloader.bin"); goto out; } gfx_puts(&gfx_con, "NX Bootloader dumped to nxloader.bin\n"); - // dump secmon + // Dump secmon if (sd_save_to_file(secmon, hdr->sm_size, "secmon.bin")) { EPRINTF("\nFailed to create secmon.bin"); goto out; } gfx_puts(&gfx_con, "Secure Monitor dumped to secmon.bin\n"); - // dump warmboot + // Dump warmboot if (sd_save_to_file(warmboot, hdr->wb_size, "warmboot.bin")) { EPRINTF("\nFailed to create warmboot.bin"); goto out; @@ -1199,7 +1194,7 @@ void dump_package1() sdmmc_storage_end(&storage); - gfx_puts(&gfx_con, "\nDone. Press any key.\n"); + gfx_puts(&gfx_con, "\nDone. Press any key...\n"); out:; free(pkg1); @@ -1212,6 +1207,8 @@ out:; void launch_firmware() { + u8 max_entries = 16; + ini_sec_t *cfg_sec = NULL; LIST_INIT(ini_sections); @@ -1222,8 +1219,8 @@ void launch_firmware() { if (ini_parse(&ini_sections, "hekate_ipl.ini")) { - //Build configuration menu. - ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 16); + // Build configuration menu. + ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * max_entries); ments[0].type = MENT_BACK; ments[0].caption = "Back"; u32 i = 1; @@ -1235,6 +1232,9 @@ void launch_firmware() ments[i].caption = ini_sec->name; ments[i].data = ini_sec; i++; + + if (i > max_entries) + break; } if (i > 1) { @@ -1242,13 +1242,18 @@ void launch_firmware() menu_t menu = { ments, "Launch configurations", 0, 0 }; - cfg_sec = (ini_sec_t *)tui_do_menu(&gfx_con, &menu); + cfg_sec = ini_clone_section((ini_sec_t *)tui_do_menu(&gfx_con, &menu)); if (!cfg_sec) + { + free(ments); + ini_free(&ini_sections); return; + } } else EPRINTF("No launch configurations found."); free(ments); + ini_free(&ini_sections); } else EPRINTF("Could not find or open 'hekate_ipl.ini'.\nMake sure it exists in SD Card!."); @@ -1263,7 +1268,7 @@ void launch_firmware() if (!hos_launch(cfg_sec)) EPRINTF("Failed to launch firmware."); - //TODO: free ini. + ini_free_section(cfg_sec); btn_wait(); } @@ -1310,19 +1315,19 @@ int fix_attributes(char *path, u32 *total) u32 k = 0; static FILINFO fno; - /* Open directory */ + // Open directory res = f_opendir(&dir, path); if (res == FR_OK) { for (;;) { - //Read a directory item. + // Read a directory item. res = f_readdir(&dir, &fno); - //Break on error or end of dir. + // Break on error or end of dir. if (res != FR_OK || fno.fname[0] == 0) break; - //Set new directory + // Set new directory i = strlen(path); memcpy(&path[i], "/", 1); for (k = 0; k < 256; k++) @@ -1333,23 +1338,23 @@ int fix_attributes(char *path, u32 *total) memcpy(&path[i+1], fno.fname, k + 1); path[i + k + 2] = 0; - //Check if archive bit is set + // Check if archive bit is set if (fno.fattrib & AM_ARC) { *(u32 *)total = *(u32 *)total + 1; f_chmod(path, 0, AM_ARC); } - /* Is it a directory? */ + // Is it a directory? if (fno.fattrib & AM_DIR) { - //Enter the directory. + // Enter the directory. res = fix_attributes(path, total); if (res != FR_OK) break; } - //Clear file or folder path. + // Clear file or folder path. path[i] = 0; } f_closedir(&dir); @@ -1515,7 +1520,7 @@ void ipl_main() gfx_clear_grey(&gfx_ctxt, 0x1B); gfx_con_init(&gfx_con, &gfx_ctxt); - //Enable backlight after initializing gfx + // Enable backlight after initializing gfx display_backlight(1); while (1) diff --git a/ipl/max7762x.c b/ipl/max7762x.c index 5e8d923..5a549ed 100755 --- a/ipl/max7762x.c +++ b/ipl/max7762x.c @@ -73,8 +73,8 @@ int max77620_regulator_get_status(u32 id) const max77620_regulator_t *reg = &_pmic_regulators[id]; if (reg->type == REGULATOR_SD) - return i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask ? 0 : 1; - return i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8 ? 1 : 0; + return (i2c_recv_byte(I2C_5, 0x3C, MAX77620_REG_STATSD) & reg->status_mask) ? 0 : 1; + return (i2c_recv_byte(I2C_5, 0x3C, reg->cfg_addr) & 8) ? 1 : 0; } int max77620_regulator_config_fps(u32 id) diff --git a/ipl/pkg1.c b/ipl/pkg1.c index 8495682..9e0300e 100755 --- a/ipl/pkg1.c +++ b/ipl/pkg1.c @@ -55,7 +55,7 @@ PATCHSET_DEF(_secmon_4_patchset, { 0x2300 + 0x5D80, _NOP() }, //package2 structure. { 0x2300 + 0x5D8C, _NOP() }, //Version. { 0x2300 + 0x5EFC, _NOP() }, //Header signature. - { 0xAC8 + 0xA2C, _NOP() } //Sections SHA2. + { 0xAC8 + 0xA2C, _NOP() } //Sections SHA2. ); PATCHSET_DEF(_secmon_5_patchset, diff --git a/ipl/sdmmc.c b/ipl/sdmmc.c index 2539bc6..c443962 100755 --- a/ipl/sdmmc.c +++ b/ipl/sdmmc.c @@ -849,7 +849,7 @@ static void _sd_storage_parse_ssr(sdmmc_storage_t *storage) raw_ssr2[1] = *(u32 *)&storage->raw_ssr[20]; raw_ssr2[0] = *(u32 *)&storage->raw_ssr[16]; - storage->ssr.bus_width = unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4 ? 4 : 1; + storage->ssr.bus_width = (unstuff_bits(raw_ssr1, 510 - 384, 2) & SD_BUS_WIDTH_4) ? 4 : 1; switch(unstuff_bits(raw_ssr1, 440 - 384, 8)) { case 0: diff --git a/ipl/tui.c b/ipl/tui.c index 8761195..49874c8 100755 --- a/ipl/tui.c +++ b/ipl/tui.c @@ -40,8 +40,7 @@ void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol) void *tui_do_menu(gfx_con_t *con, menu_t *menu) { - int idx = 0, cnt = 0; - int prev_idx = 0; + int idx = 0, prev_idx = 0, cnt = 0x7FFFFFFF; gfx_clear_grey(con->gfx_ctxt, 0x1B); @@ -56,7 +55,7 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu) menu->ents[idx].type == MENT_CHGLINE) { if (prev_idx <= idx || (!idx && prev_idx == cnt - 1)) - { + { idx++; if (idx > (cnt - 1)) { @@ -83,9 +82,9 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu) gfx_con_setcol(con, 0xFF1B1B1B, 1, 0xFFCCCCCC); else gfx_con_setcol(con, 0xFFCCCCCC, 1, 0xFF1B1B1B); - if (cnt != idx && menu->ents[cnt].type == MENT_CAPTION) + if (menu->ents[cnt].type == MENT_CAPTION) gfx_printf(con, "%k %s", menu->ents[cnt].color, menu->ents[cnt].caption); - else + else if (menu->ents[cnt].type != MENT_CHGLINE) gfx_printf(con, " %s", menu->ents[cnt].caption); if(menu->ents[cnt].type == MENT_MENU) gfx_printf(con, "%k...", 0xFFEE9900); From 694a8b539506c67eb217c3febb5e745813c218ad Mon Sep 17 00:00:00 2001 From: nwert Date: Fri, 15 Jun 2018 23:28:27 +1200 Subject: [PATCH 2/2] Fixed screen brightness problems (tested on 1.0.0 and 2.0.0). Some refactoring. --- ipl/arm64.h | 35 ++++++++++++++++++ ipl/btn.c | 11 +++--- ipl/di.c | 61 ++++++++++++++++-------------- ipl/gfx.c | 16 ++++++-- ipl/hos.c | 102 ++++++++++++++++++++++++--------------------------- ipl/pinmux.h | 5 +++ ipl/pkg1.c | 10 +---- ipl/pkg2.c | 4 +- ipl/tui.c | 6 +-- ipl/util.c | 13 +++++++ ipl/util.h | 1 + 11 files changed, 157 insertions(+), 107 deletions(-) create mode 100755 ipl/arm64.h diff --git a/ipl/arm64.h b/ipl/arm64.h new file mode 100755 index 0000000..da15bf1 --- /dev/null +++ b/ipl/arm64.h @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2018 naehrwert +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#ifndef _ARM64_H_ +#define _ARM64_H_ + +#include "types.h" + +#define LSL0 0 +#define LSL16 16 +#define LSL32 32 + +#define _PAGEOFF(x) ((x) & 0xFFFFF000) + +#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F) +#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF) +#define _B(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF) +#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F) +#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F) +#define _NOP() 0xD503201F + +#endif diff --git a/ipl/btn.c b/ipl/btn.c index eb12ffe..78c70eb 100755 --- a/ipl/btn.c +++ b/ipl/btn.c @@ -37,22 +37,21 @@ u32 btn_wait() u32 res = 0, btn = btn_read(); int pwr = 0; - // Power button down, raise a filter. + //Power button down, raise a filter. if (btn & BTN_POWER) { pwr = 1; - btn &= 0xFFFFFFFE; + btn &= ~BTN_POWER; } do { res = btn_read(); - // Power button up, remove filter. + //Power button up, remove filter. if (!(res & BTN_POWER) && pwr) pwr = 0; - // Power button still down. - else if (pwr) - res &= 0xFFFFFFFE; + else if (pwr) //Power button still down. + res &= ~BTN_POWER; } while (btn == res); return res; diff --git a/ipl/di.c b/ipl/di.c index 511bc55..c5383fa 100755 --- a/ipl/di.c +++ b/ipl/di.c @@ -22,6 +22,8 @@ #include "i2c.h" #include "pmc.h" #include "max77620.h" +#include "gpio.h" +#include "pinmux.h" #include "di.inl" @@ -56,25 +58,25 @@ void display_init() PMC(APBDEV_PMC_IO_DPD2_REQ) = 0x40000000; //Config pins. - PINMUX_AUX(0x1D0) &= 0xFFFFFFEF; - PINMUX_AUX(0x1D4) &= 0xFFFFFFEF; - PINMUX_AUX(0x1FC) &= 0xFFFFFFEF; - PINMUX_AUX(0x200) &= 0xFFFFFFEF; - PINMUX_AUX(0x204) &= 0xFFFFFFEF; + PINMUX_AUX(PINMUX_AUX_NFC_EN) &= 0xFFFFFFEF; + PINMUX_AUX(PINMUX_AUX_NFC_INT) &= 0xFFFFFFEF; + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= 0xFFFFFFEF; + PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= 0xFFFFFFEF; + PINMUX_AUX(PINMUX_AUX_LCD_RST) &= 0xFFFFFFEF; - GPIO_3(0x00) = (GPIO_3(0x00) & 0xFFFFFFFC) | 0x3; - GPIO_3(0x10) = (GPIO_3(0x10) & 0xFFFFFFFC) | 0x3; - GPIO_3(0x20) = (GPIO_3(0x20) & 0xFFFFFFFE) | 0x1; - - sleep(10000u); - - GPIO_3(0x20) = (GPIO_3(0x20) & 0xFFFFFFFD) | 0x2; + gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO); //Backlight +-5V. + gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE); //Backlight +-5V. + gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); //Backlight +5V enable. sleep(10000); - GPIO_6(0x04) = (GPIO_6(0x04) & 0xFFFFFFF8) | 0x7; - GPIO_6(0x14) = (GPIO_6(0x14) & 0xFFFFFFF8) | 0x7; - GPIO_6(0x24) = (GPIO_6(0x24) & 0xFFFFFFFD) | 0x2; + gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); //Backlight -5V enable. + + sleep(10000); + + gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO); //Backlight PWM, Enable, Reset. + gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE); + gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH); //Backlight Enable enable. //Config display interface and display. MIPI_CAL(0x60) = 0; @@ -85,7 +87,7 @@ void display_init() sleep(10000); - GPIO_6(0x24) = (GPIO_6(0x24) & 0xFFFFFFFB) | 0x4; + gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH); //Backlight Reset enable. sleep(60000); @@ -135,13 +137,16 @@ void display_init() void display_backlight(u8 enable) { - GPIO_6(0x24) = (GPIO_6(0x24) & 0xFFFFFFFE) | (enable & 1); + gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); //Backlight PWM. } void display_end() { display_backlight(0); - DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1; + + //TODO: figure out why this freezes. + + /*DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 1; DSI(_DSIREG(DSI_WR_DATA)) = 0x2805; u32 end = HOST1X(0x30A4) + 5; @@ -164,17 +169,17 @@ void display_end() sleep(50000); - GPIO_6(0x24) &= 0xFFFFFFFB; + //gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); //Backlight Reset disable. - sleep(10000); + //sleep(10000); - GPIO_3(0x20) &= 0xFFFFFFFD; + //gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); //Backlight -5V disable. - sleep(10000); + //sleep(10000); - GPIO_3(0x20) = (GPIO_3(0x20) >> 1) << 1; + //gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); //Backlight +5V disable. - sleep(10000); + //sleep(10000); //Disable clocks. CLOCK(0x308) = 0x1010000; @@ -183,12 +188,12 @@ void display_end() CLOCK(0x324) = 0x18000000; DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF); - DSI(_DSIREG(DSI_POWER_CONTROL)) = 0; + DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;*/ - GPIO_6(0x04) &= 0xFFFFFFFE; + gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); //Backlight PWM. - PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) & 0xFFFFFFEF) | 0x10; - PINMUX_AUX(0x1FC) = (PINMUX_AUX(0x1FC) >> 2) << 2 | 1; + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & 0xFFFFFFEF) | 0x10; + PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) >> 2) << 2 | 1; } void display_color_screen(u32 color) diff --git a/ipl/gfx.c b/ipl/gfx.c index 3c67be1..f718b5e 100755 --- a/ipl/gfx.c +++ b/ipl/gfx.c @@ -320,8 +320,8 @@ void gfx_set_pixel(gfx_ctxt_t *ctxt, u32 x, u32 y, u32 color) void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color) { - int dx = abs(x1-x0), sx = x0 < x1 ? 1 : -1; - int dy = abs(y1-y0), sy = y0 < y1 ? 1 : -1; + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1; int err = (dx > dy ? dx : -dy) / 2, e2; while (1) @@ -330,7 +330,15 @@ void gfx_line(gfx_ctxt_t *ctxt, int x0, int y0, int x1, int y1, u32 color) if (x0 == x1 && y0 == y1) break; e2 = err; - if (e2 >-dx) { err -= dy; x0 += sx; } - if (e2 < dy) { err += dx; y0 += sy; } + if (e2 >-dx) + { + err -= dy; + x0 += sx; + } + if (e2 < dy) + { + err += dx; + y0 += sy; + } } } diff --git a/ipl/hos.c b/ipl/hos.c index a8df029..0cb8e09 100755 --- a/ipl/hos.c +++ b/ipl/hos.c @@ -31,6 +31,7 @@ #include "pkg1.h" #include "pkg2.h" #include "ff.h" +#include "di.h" #include "gfx.h" extern gfx_ctxt_t gfx_ctxt; @@ -73,9 +74,9 @@ typedef struct _merge_kip_t #define KB_FIRMWARE_VERSION_301 2 #define KB_FIRMWARE_VERSION_400 3 #define KB_FIRMWARE_VERSION_500 4 +#define KB_FIRMWARE_VERSION_MAX KB_FIRMWARE_VERSION_500 -#define NUM_KEYBLOB_KEYS 5 -static const u8 keyblob_keyseeds[NUM_KEYBLOB_KEYS][0x10] = { +static const u8 keyblob_keyseeds[][0x10] = { { 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0 { 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0 { 0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B }, //3.0.1 @@ -95,24 +96,12 @@ static const u8 console_keyseed[0x10] = static const u8 key8_keyseed[] = { 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 }; -static const u8 master_keyseed_4xx[0x10] = +static const u8 master_keyseed_4xx_5xx[0x10] = { 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 }; -static const u8 console_keyseed_4xx[0x10] = +static const u8 console_keyseed_4xx_5xx[0x10] = { 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 }; -#define CRC32C_POLY 0x82F63B78 -u32 crc32c(const u8 *buf, u32 len) -{ - u32 crc = 0xFFFFFFFF; - while (len--) - { - crc ^= *buf++; - for (int i = 0; i < 8; i++) - crc = (crc & 1) ? (crc >> 1) ^ CRC32C_POLY : crc >> 1; - } - return ~crc; -} static void _se_lock() { @@ -145,23 +134,26 @@ int keygen(u8 *keyblob, u32 kb, void *tsec_fw) { u8 tmp[0x10]; - se_key_acc_ctrl(0x0D, 0x15); - se_key_acc_ctrl(0x0E, 0x15); + if (kb > KB_FIRMWARE_VERSION_MAX) + return 0; + + se_key_acc_ctrl(13, 0x15); + se_key_acc_ctrl(14, 0x15); //Get TSEC key. if (tsec_query(tmp, 1, tsec_fw) < 0) return 0; - se_aes_key_set(0x0D, tmp, 0x10); + se_aes_key_set(13, tmp, 0x10); //Derive keyblob keys from TSEC+SBK. - se_aes_crypt_block_ecb(0x0D, 0x00, tmp, keyblob_keyseeds[0]); - se_aes_unwrap_key(0x0F, 0x0E, tmp); - se_aes_crypt_block_ecb(0xD, 0x00, tmp, keyblob_keyseeds[kb]); - se_aes_unwrap_key(0x0D, 0x0E, tmp); + se_aes_crypt_block_ecb(13, 0, tmp, keyblob_keyseeds[0]); + se_aes_unwrap_key(15, 14, tmp); + se_aes_crypt_block_ecb(13, 0, tmp, keyblob_keyseeds[kb]); + se_aes_unwrap_key(13, 14, tmp); - // Clear SBK - se_aes_key_clear(0x0E); + //Clear SBK. + se_aes_key_clear(14); //TODO: verify keyblob CMAC. //se_aes_unwrap_key(11, 13, cmac_keyseed); @@ -169,45 +161,42 @@ int keygen(u8 *keyblob, u32 kb, void *tsec_fw) //if (!memcmp(keyblob, tmp, 0x10)) // return 0; - se_aes_crypt_block_ecb(0x0D, 0, tmp, cmac_keyseed); - se_aes_unwrap_key(0x0B, 0x0D, cmac_keyseed); + se_aes_crypt_block_ecb(13, 0, tmp, cmac_keyseed); + se_aes_unwrap_key(11, 13, cmac_keyseed); //Decrypt keyblob and set keyslots. - se_aes_crypt_ctr(0x0D, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10); - se_aes_key_set(0x0B, keyblob + 0x20 + 0x80, 0x10); // package1 key - se_aes_key_set(0x0C, keyblob + 0x20, 0x10); - se_aes_key_set(0x0D, keyblob + 0x20, 0x10); + se_aes_crypt_ctr(13, keyblob + 0x20, 0x90, keyblob + 0x20, 0x90, keyblob + 0x10); + se_aes_key_set(11, keyblob + 0x20 + 0x80, 0x10); //Package1 key. + se_aes_key_set(12, keyblob + 0x20, 0x10); + se_aes_key_set(13, keyblob + 0x20, 0x10); - se_aes_crypt_block_ecb(0x0C, 0, tmp, master_keyseed_retail); + se_aes_crypt_block_ecb(12, 0, tmp, master_keyseed_retail); switch (kb) { case KB_FIRMWARE_VERSION_100_200: case KB_FIRMWARE_VERSION_300: case KB_FIRMWARE_VERSION_301: - se_aes_unwrap_key(0x0D, 0x0F, console_keyseed); - se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail); + se_aes_unwrap_key(13, 15, console_keyseed); + se_aes_unwrap_key(12, 12, master_keyseed_retail); break; - case KB_FIRMWARE_VERSION_400: - se_aes_unwrap_key(0x0D, 0x0F, console_keyseed_4xx); - se_aes_unwrap_key(0x0F, 0x0F, console_keyseed); - se_aes_unwrap_key(0x0E, 0x0C, master_keyseed_4xx); - se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail); + se_aes_unwrap_key(13, 15, console_keyseed_4xx_5xx); + se_aes_unwrap_key(15, 15, console_keyseed); + se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx); + se_aes_unwrap_key(12, 12, master_keyseed_retail); break; - case KB_FIRMWARE_VERSION_500: - default: - se_aes_unwrap_key(0x0A, 0x0F, console_keyseed_4xx); - se_aes_unwrap_key(0x0F, 0x0F, console_keyseed); - se_aes_unwrap_key(0x0E, 0x0C, master_keyseed_4xx); - se_aes_unwrap_key(0x0C, 0x0C, master_keyseed_retail); + se_aes_unwrap_key(10, 15, console_keyseed_4xx_5xx); + se_aes_unwrap_key(15, 15, console_keyseed); + se_aes_unwrap_key(14, 12, master_keyseed_4xx_5xx); + se_aes_unwrap_key(12, 12, master_keyseed_retail); break; } //Package2 key. - se_key_acc_ctrl(0x08, 0x15); - se_aes_unwrap_key(0x08, 0x0C, key8_keyseed); + se_key_acc_ctrl(8, 0x15); + se_aes_unwrap_key(8, 12, key8_keyseed); return 1; } @@ -385,6 +374,7 @@ int hos_launch(ini_sec_t *cfg) { int bootStateDramPkg2; int bootStatePkg2Continue; + int end_di = 0; launch_ctxt_t ctxt; memset(&ctxt, 0, sizeof(launch_ctxt_t)); @@ -491,24 +481,25 @@ int hos_launch(ini_sec_t *cfg) gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF00FF96, 0xFFCCCCCC); - se_aes_key_clear(0x8); - se_aes_key_clear(0xB); + se_aes_key_clear(8); + se_aes_key_clear(11); switch (ctxt.pkg1_id->kb) { case KB_FIRMWARE_VERSION_100_200: case KB_FIRMWARE_VERSION_300: case KB_FIRMWARE_VERSION_301: - se_key_acc_ctrl(0xC, 0xFF); - se_key_acc_ctrl(0xD, 0xFF); + se_key_acc_ctrl(12, 0xFF); + se_key_acc_ctrl(13, 0xFF); bootStateDramPkg2 = 2; bootStatePkg2Continue = 3; + end_di = 1; break; default: case KB_FIRMWARE_VERSION_400: case KB_FIRMWARE_VERSION_500: - se_key_acc_ctrl(0xC, 0xFF); - se_key_acc_ctrl(0xF, 0xFF); + se_key_acc_ctrl(12, 0xFF); + se_key_acc_ctrl(15, 0xFF); bootStateDramPkg2 = 2; bootStatePkg2Continue = 4; break; @@ -545,8 +536,9 @@ int hos_launch(ini_sec_t *cfg) PMC(0x5BC) = 0xFFFFFFFF; PMC(0x5C0) = 0xFFAAFFFF;*/ - //TODO: Cleanup. - //display_end(); + //Disable display. + if (end_di) + display_end(); //Signal to pkg2 ready and continue boot. *mb_in = bootStatePkg2Continue; diff --git a/ipl/pinmux.h b/ipl/pinmux.h index 14f0ec4..eae897c 100755 --- a/ipl/pinmux.h +++ b/ipl/pinmux.h @@ -41,6 +41,11 @@ #define PINMUX_AUX_DMIC3_CLK 0xB4 #define PINMUX_AUX_UART2_TX 0xF4 #define PINMUX_AUX_UART3_TX 0x104 +#define PINMUX_AUX_NFC_EN 0x1D0 +#define PINMUX_AUX_NFC_INT 0x1D4 +#define PINMUX_AUX_LCD_BL_PWM 0x1FC +#define PINMUX_AUX_LCD_BL_EN 0x200 +#define PINMUX_AUX_LCD_RST 0x204 #define PINMUX_AUX_GPIO_PE6 0x248 #define PINMUX_AUX_GPIO_PH6 0x250 #define PINMUX_AUX_GPIO_PZ1 0x280 diff --git a/ipl/pkg1.c b/ipl/pkg1.c index 9e0300e..7e4565e 100755 --- a/ipl/pkg1.c +++ b/ipl/pkg1.c @@ -16,19 +16,13 @@ #include #include "pkg1.h" +#include "arm64.h" #include "se.h" -#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F) -#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F) -#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F) -#define _BL(a, o) 0x94000000 | (((o) - (a)) >> 2) & 0x3FFFFFF -#define _NOP() 0xD503201F - #define SM_100_ADR 0x4002B020 - PATCHSET_DEF(_secmon_1_patchset, //Patch the relocator to be able to run from SM_100_ADR. - { 0x1E0, _ADRP(0, 0x7C013000 - (SM_100_ADR - 0x40)) }, + { 0x1E0, _ADRP(0, 0x7C013000 - _PAGEOFF(SM_100_ADR)) }, //Patch package2 decryption and signature/hash checks. { 0x9F0 + 0xADC, _NOP() }, //Header signature. { 0x9F0 + 0xB8C, _NOP() }, //Version. diff --git a/ipl/pkg2.c b/ipl/pkg2.c index cd66c94..88a4bca 100755 --- a/ipl/pkg2.c +++ b/ipl/pkg2.c @@ -16,6 +16,7 @@ #include #include "pkg2.h" +#include "arm64.h" #include "heap.h" #include "se.h" @@ -25,9 +26,6 @@ extern gfx_con_t gfx_con; #define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)*/ #define DPRINTF(...) -#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F) -#define _NOP() 0xD503201F - // Include kernel patches here, so we can utilize pkg1 id PATCHSET_DEF(_kernel_1_patchset, { 0x3764C, _NOP() }, // Disable SVC verifications diff --git a/ipl/tui.c b/ipl/tui.c index 49874c8..d95e061 100755 --- a/ipl/tui.c +++ b/ipl/tui.c @@ -50,11 +50,11 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu) gfx_con_setpos(con, menu->x, menu->y); gfx_printf(con, "[%s]\n\n", menu->caption); - // Skip caption or seperator lines selection + // Skip caption or seperator lines selection. while (menu->ents[idx].type == MENT_CAPTION || menu->ents[idx].type == MENT_CHGLINE) { - if (prev_idx <= idx || (!idx && prev_idx == cnt - 1)) + if (prev_idx <= idx || (!idx && prev_idx == cnt - 1)) { idx++; if (idx > (cnt - 1)) @@ -75,7 +75,7 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu) } prev_idx = idx; - // Draw the menu + //Draw the menu. for (cnt = 0; menu->ents[cnt].type != MENT_END; cnt++) { if (cnt == idx) diff --git a/ipl/util.c b/ipl/util.c index ef009a1..c060522 100755 --- a/ipl/util.c +++ b/ipl/util.c @@ -35,3 +35,16 @@ void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops) base[ops[i].off] = ops[i].val; } +#define CRC32C_POLY 0x82F63B78 +u32 crc32c(const void *buf, u32 len) +{ + const u8 *cbuf = (const u8 *)buf; + u32 crc = 0xFFFFFFFF; + while (len--) + { + crc ^= *cbuf++; + for (int i = 0; i < 8; i++) + crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1; + } + return ~crc; +} diff --git a/ipl/util.h b/ipl/util.h index a1fc7dd..8377446 100755 --- a/ipl/util.h +++ b/ipl/util.h @@ -28,5 +28,6 @@ typedef struct _cfg_op_t u32 get_tmr(); void sleep(u32 ticks); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); +u32 crc32c(const void *buf, u32 len); #endif