diff --git a/bootloader/config/config.c b/bootloader/config/config.c index f284b5b..e2b1156 100644 --- a/bootloader/config/config.c +++ b/bootloader/config/config.c @@ -28,8 +28,8 @@ #include "../utils/util.h" extern hekate_config h_cfg; -extern int sd_mount(); -extern int sd_unmount(); +extern bool sd_mount(); +extern void sd_unmount(); void set_default_configuration() { @@ -41,8 +41,8 @@ void set_default_configuration() h_cfg.sbar_time_keeping = 0; h_cfg.backlight = 100; h_cfg.autohosoff = 0; - h_cfg.errors = 0; h_cfg.autonogc = 1; + h_cfg.errors = 0; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; h_cfg.rcm_patched = true; h_cfg.sd_timeoff = 0; @@ -154,6 +154,9 @@ int create_config_entry() return 0; } +#pragma GCC push_options +#pragma GCC optimize ("Os") + static void _save_config() { gfx_clear_grey(0x1B); @@ -455,10 +458,10 @@ void config_verification() ments[1].type = MENT_CHGLINE; - memcpy(vr_text, " None (Fastest - Unsafe)", 35); - memcpy(vr_text + 64, " Sparse (Fast - Safe)", 33); - memcpy(vr_text + 128, " Full (Slow - Safer)", 34); - memcpy(vr_text + 192, " Full w/ hashfiles (Slow - Safest)", 35); + memcpy(vr_text, " Disable (Fastest - Unsafe)", 28); + memcpy(vr_text + 64, " Sparse (Fast - Safe)", 23); + memcpy(vr_text + 128, " Full (Slow - Safe)", 23); + memcpy(vr_text + 192, " Full (w/ hashfile)", 23); for (u32 i = 0; i < 4; i++) { @@ -652,3 +655,5 @@ void config_nogc() return; btn_wait(); } + +#pragma GCC pop_options diff --git a/bootloader/config/ini.c b/bootloader/config/ini.c index 2d25c78..a58d4ac 100644 --- a/bootloader/config/ini.c +++ b/bootloader/config/ini.c @@ -26,9 +26,18 @@ static char *_strdup(char *str) { if (!str) return NULL; + + // Remove starting space. + if (str[0] == ' ' && strlen(str)) + str++; + char *res = (char *)malloc(strlen(str) + 1); strcpy(res, str); + // Remove trailing space. + if (res[strlen(res) - 1] == ' ' && strlen(res)) + res[strlen(res) - 1] = 0; + return res; } diff --git a/bootloader/frontend/fe_emmc_tools.c b/bootloader/frontend/fe_emmc_tools.c index a257c01..863329d 100644 --- a/bootloader/frontend/fe_emmc_tools.c +++ b/bootloader/frontend/fe_emmc_tools.c @@ -36,7 +36,7 @@ #define MIXD_BUF_ALIGNED 0xB7000000 #define NUM_SECTORS_PER_ITER 8192 // 4MB Cache. -#define OUT_FILENAME_SZ 80 +#define OUT_FILENAME_SZ 128 #define HASH_FILENAME_SZ (OUT_FILENAME_SZ + 11) // 11 == strlen(".sha256sums") #define SHA256_SZ 0x20 @@ -49,6 +49,9 @@ extern bool sd_mount(); extern void sd_unmount(); extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage); +#pragma GCC push_options +#pragma GCC optimize ("Os") + static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part) { FIL fp; @@ -115,6 +118,8 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi num, lba_curr); f_close(&fp); + if (h_cfg.verification == 3) + f_close(&hashFp); return 1; } f_lseek(&fp, (u64)sdFileSector << (u64)9); @@ -124,6 +129,9 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi EPRINTFARGS("\nFailed to read %d blocks (@LBA %08X),\nfrom sd card!\n\nVerification failed..\n", num, lba_curr); f_close(&fp); + if (h_cfg.verification == 3) + f_close(&hashFp); + return 1; } @@ -137,6 +145,9 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi EPRINTFARGS("\nSD and eMMC data (@LBA %08X),\ndo not match!\n\nVerification failed..\n", lba_curr); f_close(&fp); + if (h_cfg.verification == 3) + f_close(&hashFp); + return 1; } @@ -198,7 +209,7 @@ static int _dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFi } } -void _update_filename(char *outFilename, u32 sdPathLen, u32 numSplitParts, u32 currPartIdx) +static void _update_filename(char *outFilename, u32 sdPathLen, u32 numSplitParts, u32 currPartIdx) { if (numSplitParts >= 10 && currPartIdx < 10) { @@ -283,7 +294,7 @@ static int _dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t gfx_printf("%kPartial Backup enabled (with %d MiB parts)...%k\n\n", 0xFFFFBA00, multipartSplitSize >> 20, 0xFFCCCCCC); // Check if filesystem is FAT32 or the free space is smaller and backup in parts. - if (((sd_fs.fs_type != FS_EXFAT) && totalSectors > (FAT32_FILESIZE_LIMIT / NX_EMMC_BLOCKSIZE)) | isSmallSdCard) + if (((sd_fs.fs_type != FS_EXFAT) && totalSectors > (FAT32_FILESIZE_LIMIT / NX_EMMC_BLOCKSIZE)) || isSmallSdCard) { u32 multipartSplitSectors = multipartSplitSize / NX_EMMC_BLOCKSIZE; numSplitParts = (totalSectors + multipartSplitSectors - 1) / multipartSplitSectors; diff --git a/bootloader/frontend/fe_info.c b/bootloader/frontend/fe_info.c index 24d776d..adf3996 100644 --- a/bootloader/frontend/fe_info.c +++ b/bootloader/frontend/fe_info.c @@ -46,6 +46,9 @@ extern void sd_unmount(); extern int sd_save_to_file(void *buf, u32 size, const char *filename); extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage); +#pragma GCC push_options +#pragma GCC optimize ("Os") + void print_fuseinfo() { gfx_clear_partial_grey(0x1B, 0, 1256); @@ -75,7 +78,7 @@ void print_fuseinfo() byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3))); gfx_printf("%k(Unlocked) fuse cache:\n\n%k", 0xFF00DDFF, 0xFFCCCCCC); - gfx_hexdump(0x7000F900, (u8 *)0x7000F900, 0x2FC); + gfx_hexdump(0x7000F900, (u8 *)0x7000F900, 0x300); gfx_puts("\nPress POWER to dump them to SD Card.\nPress VOL to go to the menu.\n"); @@ -85,9 +88,16 @@ void print_fuseinfo() if (sd_mount()) { char path[64]; - emmcsn_path_impl(path, "/dumps", "fuses.bin", NULL); - if (!sd_save_to_file((u8 *)0x7000F900, 0x2FC, path)) - gfx_puts("\nDone!\n"); + emmcsn_path_impl(path, "/dumps", "fuse_cached.bin", NULL); + if (!sd_save_to_file((u8 *)0x7000F900, 0x300, path)) + gfx_puts("\nfuse_cached.bin saved!\n"); + + u32 words[192]; + fuse_read_array(words); + emmcsn_path_impl(path, "/dumps", "fuse_array_raw.bin", NULL); + if (!sd_save_to_file((u8 *)words, sizeof(words), path)) + gfx_puts("\nfuse_array_raw.bin saved!\n"); + sd_unmount(); } @@ -247,13 +257,13 @@ void print_mmc_info() u32 rpmb_size = storage.ext_csd.rpmb_mult << 17; gfx_printf("%keMMC Partitions:%k\n", 0xFF00DDFF, 0xFFCCCCCC); gfx_printf(" 1: %kBOOT0 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF96FF00, 0xFFCCCCCC, - boot_size / 1024, boot_size / 1024 / 512); + boot_size / 1024, boot_size / 512); gfx_put_small_sep(); gfx_printf(" 2: %kBOOT1 %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF96FF00, 0xFFCCCCCC, - boot_size / 1024, boot_size / 1024 / 512); + boot_size / 1024, boot_size / 512); gfx_put_small_sep(); gfx_printf(" 3: %kRPMB %k\n Size: %5d KiB (LBA Sectors: 0x%07X)\n", 0xFF96FF00, 0xFFCCCCCC, - rpmb_size / 1024, rpmb_size / 1024 / 512); + rpmb_size / 1024, rpmb_size / 512); gfx_put_small_sep(); gfx_printf(" 0: %kGPP (USER) %k\n Size: %5d MiB (LBA Sectors: 0x%07X)\n\n", 0xFF96FF00, 0xFFCCCCCC, storage.sec_cnt >> SECTORS_TO_MIB_COEFF, storage.sec_cnt); @@ -576,7 +586,7 @@ void print_battery_info() for (int i = 0; i < 0x200; i += 2) { - i2c_recv_buf_small(buf + i, 2, I2C_1, 0x36, i >> 1); + i2c_recv_buf_small(buf + i, 2, I2C_1, MAXIM17050_I2C_ADDR, i >> 1); usleep(2500); } @@ -651,12 +661,6 @@ void bootrom_ipatches_info() else EPRINTFARGS("Failed to read evp_thunks. Error: %d", res); - u32 words[192]; - fuse_read_array(words); - emmcsn_path_impl(path, "/dumps", "raw_fuses.bin", NULL); - if (!sd_save_to_file((u8 *)words, sizeof(words), path)) - gfx_puts("\nipatches.bin saved!\n"); - emmcsn_path_impl(path, "/dumps", "bootrom_patched.bin", NULL); if (!sd_save_to_file((u8 *)BOOTROM_BASE, BOOTROM_SIZE, path)) gfx_puts("\nbootrom_patched.bin saved!\n"); @@ -677,3 +681,5 @@ void bootrom_ipatches_info() btn_wait(); } } + +#pragma GCC pop_options diff --git a/bootloader/frontend/fe_tools.c b/bootloader/frontend/fe_tools.c index e3fcf2c..aa88249 100644 --- a/bootloader/frontend/fe_tools.c +++ b/bootloader/frontend/fe_tools.c @@ -45,6 +45,9 @@ extern void sd_unmount(); extern int sd_save_to_file(void *buf, u32 size, const char *filename); extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage); +#pragma GCC push_options +#pragma GCC optimize ("Os") + void dump_packages12() { if (!sd_mount()) @@ -596,61 +599,4 @@ void fix_sd_nin_attr() { _fix_sd_attr(1); } } }*/ -/* -#include "../../modules/hekate_libsys_minerva/mtc.h" -#include "../ianos/ianos.h" -#include "../soc/fuse.h" -#include "../soc/clock.h" - -mtc_config_t mtc_cfg; -void minerva() -{ - gfx_clear_partial_grey(0x1B, 0, 1256); - gfx_con_setpos(0, 0); - - u32 curr_ram_idx = 0; - - if (!sd_mount()) - return; - - gfx_printf("-- Minerva Training Cell --\n\n"); - - // Set table to ram. - mtc_cfg.mtc_table = NULL; - mtc_cfg.sdram_id = (fuse_read_odm(4) >> 3) & 0x1F; - ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_cfg); - - gfx_printf("\nStarting training process..\n\n"); - - // Get current frequency - for (curr_ram_idx = 0; curr_ram_idx < 10; curr_ram_idx++) - { - if (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) == mtc_cfg.mtc_table[curr_ram_idx].clk_src_emc) - break; - } - - // Change DRAM voltage. - //i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD1, 42); //40 = (1000 * 1100 - 600000) / 12500 -> 1.1V - - mtc_cfg.rate_from = mtc_cfg.mtc_table[curr_ram_idx].rate_khz; - mtc_cfg.rate_to = 800000; - mtc_cfg.train_mode = OP_TRAIN_SWITCH; - gfx_printf("Training and switching %7d -> %7d\n\n", mtc_cfg.mtc_table[curr_ram_idx].rate_khz, 800000); - ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_cfg); - - // Thefollowing frequency needs periodic training every 100ms. - //msleep(200); - - //mtc_cfg.rate_to = 1600000; - //gfx_printf("Training and switching %7d -> %7d\n\n", mtc_cfg.current_emc_table->rate_khz, 1600000); - //ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_cfg); - - //mtc_cfg.train_mode = OP_PERIODIC_TRAIN; - - sd_unmount(); - - gfx_printf("Finished!"); - - btn_wait(); -} -*/ +#pragma GCC pop_options diff --git a/bootloader/frontend/fe_tools.h b/bootloader/frontend/fe_tools.h index c7035b8..5311cbd 100644 --- a/bootloader/frontend/fe_tools.h +++ b/bootloader/frontend/fe_tools.h @@ -23,6 +23,5 @@ void fix_sd_all_attr(); void fix_sd_nin_attr(); void fix_battery_desync(); void menu_autorcm(); -//void minerva(); #endif diff --git a/bootloader/gfx/di.c b/bootloader/gfx/di.c index 5710ef1..ad0ec5c 100644 --- a/bootloader/gfx/di.c +++ b/bootloader/gfx/di.c @@ -18,15 +18,16 @@ #include #include "di.h" -#include "../soc/t210.h" -#include "../utils/util.h" -#include "../soc/i2c.h" -#include "../soc/pmc.h" +#include "../gfx/gfx.h" #include "../power/max77620.h" #include "../power/max7762x.h" -#include "../soc/gpio.h" -#include "../soc/pinmux.h" #include "../soc/clock.h" +#include "../soc/gpio.h" +#include "../soc/i2c.h" +#include "../soc/pinmux.h" +#include "../soc/pmc.h" +#include "../soc/t210.h" +#include "../utils/util.h" #include "di.inl" @@ -252,11 +253,11 @@ void display_color_screen(u32 color) u32 *display_init_framebuffer() { // Sanitize framebuffer area. - memset((u32 *)0xC0000000, 0, 0x3C0000); - // This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 768). + memset((u32 *)FB_ADDRESS, 0, 0x3C0000); + // This configures the framebuffer @ 0xC0000000 with a resolution of 1280x720 (line stride 720). exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32); usleep(35000); - return (u32 *)0xC0000000; + return (u32 *)FB_ADDRESS; } diff --git a/bootloader/gfx/di.h b/bootloader/gfx/di.h index 898029d..94b64ec 100644 --- a/bootloader/gfx/di.h +++ b/bootloader/gfx/di.h @@ -20,6 +20,8 @@ #include "../utils/types.h" +#define FB_ADDRESS 0xC0000000 + /*! Display registers. */ #define _DIREG(reg) ((reg) * 4) @@ -333,7 +335,7 @@ #define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8) #define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0) -#define DSI_PAD_CONTROL_CD 0x4c +#define DSI_PAD_CONTROL_CD 0x4C #define DSI_VIDEO_MODE_CONTROL 0x4E #define DSI_PAD_CONTROL_1 0x4F diff --git a/bootloader/gfx/di.inl b/bootloader/gfx/di.inl index 3d2471b..48cea7b 100644 --- a/bootloader/gfx/di.inl +++ b/bootloader/gfx/di.inl @@ -122,7 +122,7 @@ static const cfg_op_t _display_config_2[94] = { {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_COMMAND, 0}, + {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ} }; @@ -405,7 +405,7 @@ static const cfg_op_t _display_config_11[113] = { {DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, {DC_WIN_WIN_OPTIONS, 0}, {DC_DISP_DISP_WIN_OPTIONS, 0}, - {DC_CMD_DISPLAY_COMMAND, 0}, + {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ}, {DC_CMD_STATE_ACCESS, 0}, @@ -455,7 +455,7 @@ static const cfg_op_t _display_config_12[17] = { {DC_CMD_STATE_ACCESS, 0}, {DC_CMD_INT_ENABLE, 0}, {DC_CMD_CONT_SYNCPT_VSYNC, 0}, - {DC_CMD_DISPLAY_COMMAND, 0}, + {DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_STOP}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, {DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ}, {DC_CMD_STATE_CONTROL, GENERAL_UPDATE}, @@ -548,7 +548,7 @@ static const cfg_op_t cfg_display_framebuffer[32] = { {DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements. {DC_WIN_BUFFER_CONTROL, 0}, {DC_WINBUF_SURFACE_KIND, 0}, //Regular surface. - {DC_WINBUF_START_ADDR, 0xC0000000}, //Framebuffer address. + {DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address. {DC_WINBUF_ADDR_H_OFFSET, 0}, {DC_WINBUF_ADDR_V_OFFSET, 0}, {DC_WIN_WIN_OPTIONS, 0}, diff --git a/bootloader/gfx/gfx.h b/bootloader/gfx/gfx.h index 94cb0ed..ef37650 100644 --- a/bootloader/gfx/gfx.h +++ b/bootloader/gfx/gfx.h @@ -21,11 +21,13 @@ #include "../../common/common_gfx.h" -#define EPRINTF(text) gfx_printf("%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC) -#define EPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC) +#define EPRINTF(text) ({ gfx_con.mute = false; gfx_printf("%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC); }) +#define EPRINTFARGS(text, args...) ({ gfx_con.mute = false; gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC); }) #define WPRINTF(text) gfx_printf("%k"text"%k\n", 0xFFFFDD00, 0xFFCCCCCC) #define WPRINTFARGS(text, args...) gfx_printf("%k"text"%k\n", 0xFFFFDD00, args, 0xFFCCCCCC) +#define FB_ADDRESS 0xC0000000 + void gfx_init_ctxt(u32 *fb, u32 width, u32 height, u32 stride); void gfx_clear_grey(u8 color); void gfx_clear_partial_grey(u8 color, u32 pos_x, u32 height); diff --git a/bootloader/hos/fss.c b/bootloader/hos/fss.c index 749b161..b6e2eeb 100644 --- a/bootloader/hos/fss.c +++ b/bootloader/hos/fss.c @@ -95,7 +95,7 @@ int parse_fss(launch_ctxt_t *ctxt, const char *value) fss_content_t *curr_fss_cnt = (fss_content_t *)(fss + fss_meta->cnt_off); void *content; - for (int i = 0; i < fss_meta->cnt_count; i++) + for (u32 i = 0; i < fss_meta->cnt_count; i++) { content = (void *)(fss + curr_fss_cnt[i].offset); if ((curr_fss_cnt[i].offset + curr_fss_cnt[i].size) > fss_meta->size) diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 0fcecf5..bc376eb 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -524,6 +524,12 @@ int hos_launch(ini_sec_t *cfg) *(u32 *)(ctxt.kernel + PKG2_NEWKERN_INI1_START) - PKG2_NEWKERN_START); ctxt.pkg2_kernel_id = pkg2_identify(kernel_hash); + if (!ctxt.pkg2_kernel_id) + { + EPRINTF("Failed to identify kernel!"); + return 0; + } + // In case a kernel patch option is set; allows to disable SVC verification or/and enable debug mode. kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset; diff --git a/bootloader/hos/pkg1.c b/bootloader/hos/pkg1.c index 7337107..7ad07e3 100644 --- a/bootloader/hos/pkg1.c +++ b/bootloader/hos/pkg1.c @@ -141,9 +141,9 @@ static const pkg1_id_t _pkg1_ids[] = { { "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0 { "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0 { "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.0 - { "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, _warmboot_4_patchset }, //7.0.0 - { "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, _warmboot_4_patchset }, //7.0.1 - { "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, _warmboot_4_patchset }, //8.0.0 + { "20181218175730", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.0 + { "20190208150037", 7, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //7.0.1 + { "20190314172056", 7, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, false, NULL, NULL }, //8.0.0 - 8.0.1 { NULL } //End. }; diff --git a/bootloader/libs/fatfs/ff.c b/bootloader/libs/fatfs/ff.c index 38d6422..f357a5e 100644 --- a/bootloader/libs/fatfs/ff.c +++ b/bootloader/libs/fatfs/ff.c @@ -4726,7 +4726,7 @@ FRESULT f_getfree ( /* Get logical drive */ res = find_volume(&path, &fs, 0); if (res == FR_OK) { - *fatfs = fs; /* Return ptr to the fs object */ + if (fatfs) *fatfs = fs; /* Return ptr to the fs object */ /* If free_clst is valid, return it without full FAT scan */ if (fs->free_clst <= fs->n_fatent - 2) { *nclst = fs->free_clst; diff --git a/bootloader/main.c b/bootloader/main.c index 0798ebb..1ac2a0e 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -139,7 +139,7 @@ int sd_save_to_file(void *buf, u32 size, const char *filename) if (res) { EPRINTFARGS("Error (%d) creating file\n%s.\n", res, filename); - return 1; + return res; } f_write(&fp, buf, size, NULL); @@ -320,6 +320,8 @@ int launch_payload(char *path, bool update) void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR; void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR; + msleep(100); + // Launch our payload. if (!update) (*ext_payload_ptr)(); @@ -344,7 +346,7 @@ void auto_launch_update() } } -void launch_tools(u8 type) +void launch_tools() { u8 max_entries = 61; char *filelist = NULL; @@ -360,10 +362,7 @@ void launch_tools(u8 type) { dir = (char *)malloc(256); - if (!type) - memcpy(dir, "bootloader/payloads", 20); - else - memcpy(dir, "bootloader/modules", 19); + memcpy(dir, "bootloader/payloads", 20); filelist = dirlist(dir, NULL, false); @@ -391,10 +390,7 @@ void launch_tools(u8 type) if (i > 0) { memset(&ments[i + 2], 0, sizeof(ment_t)); - menu_t menu = { - ments, - "Choose a file to launch", 0, 0 - }; + menu_t menu = { ments, "Choose a file to launch", 0, 0 }; file_sec = (char *)tui_do_menu(&menu); @@ -425,16 +421,11 @@ void launch_tools(u8 type) memcpy(dir + strlen(dir), "/", 2); memcpy(dir + strlen(dir), file_sec, strlen(file_sec) + 1); - if (!type) + if (launch_payload(dir, false)) { - if (launch_payload(dir, false)) - { - EPRINTF("Failed to launch payload."); - free(dir); - } + EPRINTF("Failed to launch payload."); + free(dir); } - else - ianos_loader(true, dir, DRAM_LIB, NULL); } out: @@ -444,9 +435,6 @@ out: btn_wait(); } -void launch_tools_payload() { launch_tools(0); } -void launch_tools_module() { launch_tools(1); } - void ini_list_launcher() { u8 max_entries = 61; @@ -585,7 +573,7 @@ void launch_firmware() ments[2].type = MENT_HANDLER; ments[2].caption = "Payloads..."; - ments[2].handler = launch_tools_payload; + ments[2].handler = launch_tools; ments[3].type = MENT_HANDLER; ments[3].caption = "More configs..."; ments[3].handler = ini_list_launcher; @@ -663,8 +651,8 @@ void launch_firmware() if (!cfg_sec) { - gfx_puts("\nPress POWER to Continue.\nPress VOL to go to the menu.\n\n"); - gfx_printf("\nUsing default launch configuration...\n\n\n"); + gfx_puts("\nUsing default launch configuration...\n"); + gfx_puts("\nPress POWER to Continue.\nPress VOL to go to the menu."); u32 btn = btn_wait(); if (!(btn & BTN_POWER)) @@ -841,7 +829,7 @@ void auto_launch_firmware() goto out; u8 *bitmap = NULL; - if (!(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH) && h_cfg.bootwait) + if (!(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH) && h_cfg.bootwait && !h_cfg.sept_run) { if (bootlogoCustomEntry) // Check if user set custom logo path at the boot entry. bitmap = (u8 *)sd_file_read(bootlogoCustomEntry, NULL); @@ -907,9 +895,7 @@ void auto_launch_firmware() if (h_cfg.autoboot_list) ini_free(&ini_list_sections); - if (h_cfg.sept_run) - display_backlight_brightness(h_cfg.backlight, 0); - else if (h_cfg.bootwait) + if (!h_cfg.sept_run && h_cfg.bootwait) display_backlight_brightness(h_cfg.backlight, 1000); // Wait before booting. If VOL- is pressed go into bootloader menu. @@ -1053,10 +1039,7 @@ ment_t ment_options[] = { MDEF_END() }; -menu_t menu_options = { - ment_options, - "Launch Options", 0, 0 -}; +menu_t menu_options = { ment_options, "Launch Options", 0, 0 }; ment_t ment_cinfo[] = { MDEF_BACK(), @@ -1075,10 +1058,8 @@ ment_t ment_cinfo[] = { MDEF_HANDLER("Print battery info", print_battery_info), MDEF_END() }; -menu_t menu_cinfo = { - ment_cinfo, - "Console Info", 0, 0 -}; + +menu_t menu_cinfo = { ment_cinfo, "Console Info", 0, 0 }; ment_t ment_restore[] = { MDEF_BACK(), @@ -1092,10 +1073,7 @@ ment_t ment_restore[] = { MDEF_END() }; -menu_t menu_restore = { - ment_restore, - "Restore Options", 0, 0 -}; +menu_t menu_restore = { ment_restore, "Restore Options", 0, 0 }; ment_t ment_backup[] = { MDEF_BACK(), @@ -1110,10 +1088,7 @@ ment_t ment_backup[] = { MDEF_END() }; -menu_t menu_backup = { - ment_backup, - "Backup Options", 0, 0 -}; +menu_t menu_backup = { ment_backup, "Backup Options", 0, 0 }; ment_t ment_tools[] = { MDEF_BACK(), @@ -1129,17 +1104,13 @@ ment_t ment_tools[] = { MDEF_HANDLER("Fix archive bit (Nintendo only)", fix_sd_nin_attr), //MDEF_HANDLER("Fix fuel gauge configuration", fix_fuel_gauge_configuration), //MDEF_HANDLER("Reset all battery cfg", reset_pmic_fuel_gauge_charger_config), - //MDEF_HANDLER("Minerva", minerva), // Uncomment for testing Minerva Training Cell MDEF_CHGLINE(), MDEF_CAPTION("-------- Other -------", 0xFFFFDD00), MDEF_HANDLER("AutoRCM", menu_autorcm), MDEF_END() }; -menu_t menu_tools = { - ment_tools, - "Tools", 0, 0 -}; +menu_t menu_tools = { ment_tools, "Tools", 0, 0 }; ment_t ment_top[] = { MDEF_HANDLER("Launch", launch_firmware), @@ -1155,10 +1126,8 @@ ment_t ment_top[] = { MDEF_HANDLER("About", about), MDEF_END() }; -menu_t menu_top = { - ment_top, - "hekate - CTCaer mod v4.10.1", 0, 0 -}; + +menu_t menu_top = { ment_top, "hekate - CTCaer mod v4.10.1", 0, 0 }; #define IPL_STACK_TOP 0x90010000 #define IPL_HEAP_START 0x90020000 diff --git a/bootloader/sec/se.c b/bootloader/sec/se.c index 0b3c707..794c39d 100644 --- a/bootloader/sec/se.c +++ b/bootloader/sec/se.c @@ -20,6 +20,7 @@ #include "../sec/se.h" #include "../mem/heap.h" +#include "../soc/bpmp.h" #include "../soc/t210.h" #include "../sec/se_t210.h" #include "../utils/util.h" @@ -73,6 +74,8 @@ static int _se_wait() static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) { + bpmp_mmu_disable(); + se_ll_t *ll_dst = NULL, *ll_src = NULL; if (dst) @@ -100,6 +103,8 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src if (dst) free(ll_dst); + bpmp_mmu_enable(); + return res; } diff --git a/bootloader/sec/tsec.c b/bootloader/sec/tsec.c index b3bf95c..fe1256d 100644 --- a/bootloader/sec/tsec.c +++ b/bootloader/sec/tsec.c @@ -21,6 +21,7 @@ #include "../sec/tsec.h" #include "../sec/tsec_t210.h" #include "../sec/se_t210.h" +#include "../soc/bpmp.h" #include "../soc/clock.h" #include "../soc/smmu.h" #include "../soc/t210.h" @@ -65,6 +66,9 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt) u32 *pdir, *car, *fuse, *pmc, *flowctrl, *se, *mc, *iram, *evec; u32 *pkg11_magic_off; + bpmp_mmu_disable(); + bpmp_clk_rate_set(BPMP_CLK_NORMAL); + //Enable clocks. clock_enable_host1x(); clock_enable_tsec(); @@ -274,6 +278,8 @@ out:; clock_disable_sor_safe(); clock_disable_tsec(); clock_disable_host1x(); + bpmp_mmu_enable(); + bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST); return res; } diff --git a/bootloader/soc/clock.c b/bootloader/soc/clock.c index f712935..12776eb 100644 --- a/bootloader/soc/clock.c +++ b/bootloader/soc/clock.c @@ -30,18 +30,19 @@ static const clock_t _clock_uart[] = { }; static const clock_t _clock_i2c[] = { -/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 0xC, 6, 0 }, +/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 0xC, 6, 0 }, // 0, 19 }, // 100KHz /* I2C2 */ { 0 }, /* I2C3 */ { 0 }, /* I2C4 */ { 0 }, -/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 0xF, 6, 0 }, +/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 0xF, 6, 0 }, // 0, 4 }, // 400KHz /* I2C6 */ { 0 } }; static clock_t _clock_se = { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, 0x1F, 0, 0 }; -static clock_t _clock_unk2 = { + +static clock_t _clock_tzram = { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, 0x1E, 0, 0 }; @@ -123,9 +124,9 @@ void clock_enable_se() clock_enable(&_clock_se); } -void clock_enable_unk2() +void clock_enable_tzram() { - clock_enable(&_clock_unk2); + clock_enable(&_clock_tzram); } void clock_enable_host1x() diff --git a/bootloader/soc/clock.h b/bootloader/soc/clock.h index 8e36069..e7891b5 100644 --- a/bootloader/soc/clock.h +++ b/bootloader/soc/clock.h @@ -108,6 +108,9 @@ #define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518 #define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE 0x554 #define CLK_RST_CONTROLLER_SPARE_REG0 0x55C +#define CLK_RST_CONTROLLER_PLLC4_BASE 0x5A4 +#define CLK_RST_CONTROLLER_PLLC4_MISC 0x5A8 +#define CLK_RST_CONTROLLER_PLLC4_OUT 0x5E4 #define CLK_RST_CONTROLLER_PLLMB_BASE 0x5E8 #define CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP 0x620 #define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664 @@ -139,7 +142,7 @@ void clock_enable_uart(u32 idx); void clock_enable_i2c(u32 idx); void clock_disable_i2c(u32 idx); void clock_enable_se(); -void clock_enable_unk2(); +void clock_enable_tzram(); void clock_enable_host1x(); void clock_disable_host1x(); void clock_enable_tsec(); diff --git a/bootloader/soc/fuse.h b/bootloader/soc/fuse.h index 7f801d4..614777f 100644 --- a/bootloader/soc/fuse.h +++ b/bootloader/soc/fuse.h @@ -37,12 +37,31 @@ #define FUSE_WRITE_ACCESS_SW 0x30 #define FUSE_PWR_GOOD_SW 0x34 #define FUSE_SKU_INFO 0x110 +#define FUSE_CPU_SPEEDO_0_CALIB 0x114 +#define FUSE_CPU_IDDQ_CALIB 0x118 +#define FUSE_OPT_FT_REV 0x128 +#define FUSE_CPU_SPEEDO_1_CALIB 0x12C +#define FUSE_CPU_SPEEDO_2_CALIB 0x130 +#define FUSE_SOC_SPEEDO_0_CALIB 0x134 +#define FUSE_SOC_SPEEDO_1_CALIB 0x138 +#define FUSE_SOC_SPEEDO_2_CALIB 0x13C +#define FUSE_SOC_IDDQ_CALIB 0x140 +#define FUSE_OPT_CP_REV 0x190 #define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19c #define FUSE_PRIVATE_KEY0 0x1A4 #define FUSE_PRIVATE_KEY1 0x1A8 #define FUSE_PRIVATE_KEY2 0x1AC #define FUSE_PRIVATE_KEY3 0x1B0 +#define FUSE_PRIVATE_KEY4 0x1B4 #define FUSE_RESERVED_SW 0x1C0 +#define FUSE_OPT_VENDOR_CODE 0x200 +#define FUSE_OPT_FAB_CODE 0x204 +#define FUSE_OPT_LOT_CODE_0 0x208 +#define FUSE_OPT_LOT_CODE_1 0x20C +#define FUSE_OPT_WAFER_ID 0x210 +#define FUSE_OPT_X_COORDINATE 0x214 +#define FUSE_OPT_Y_COORDINATE 0x218 +#define FUSE_GPU_IDDQ_CALIB 0x228 /*! Fuse commands. */ #define FUSE_READ 0x1 diff --git a/bootloader/soc/hw_init.c b/bootloader/soc/hw_init.c index 2282435..caf7ada 100644 --- a/bootloader/soc/hw_init.c +++ b/bootloader/soc/hw_init.c @@ -209,7 +209,7 @@ void config_hw() clock_enable_i2c(I2C_1); clock_enable_i2c(I2C_5); - clock_enable_unk2(); + clock_enable_tzram(); i2c_init(I2C_1); i2c_init(I2C_5); diff --git a/bootloader/soc/t210.h b/bootloader/soc/t210.h index 1b11d72..1a9ef3f 100644 --- a/bootloader/soc/t210.h +++ b/bootloader/soc/t210.h @@ -20,6 +20,7 @@ #include "../utils/types.h" #define BOOTROM_BASE 0x100000 +#define IRAM_BASE 0x40000000 #define HOST1X_BASE 0x50000000 #define BPMP_CACHE_BASE 0x50040000 #define DISPLAY_A_BASE 0x54200000 diff --git a/bootloader/storage/sdmmc_driver.c b/bootloader/storage/sdmmc_driver.c index c0a2a18..bf990e9 100644 --- a/bootloader/storage/sdmmc_driver.c +++ b/bootloader/storage/sdmmc_driver.c @@ -22,6 +22,7 @@ #include "../config/config.h" #include "../gfx/gfx.h" #include "../power/max7762x.h" +#include "../soc/bpmp.h" #include "../soc/clock.h" #include "../soc/gpio.h" #include "../soc/pinmux.h" @@ -202,7 +203,7 @@ out:; int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) { - //Disable the SD clock if it was enabled, and reenable it later. + // Disable the SD clock if it was enabled, and reenable it later. bool should_enable_sd_clock = false; if (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE) { @@ -218,7 +219,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) case 1: case 5: case 6: - sdmmc->regs->hostctl &= 0xFB; //Should this be 0xFFFB (~4) ? + sdmmc->regs->hostctl &= 0xFB; // Should this be 0xFFFB (~4) ? sdmmc->regs->hostctl2 &= SDHCI_CTRL_VDD_330; break; case 2: @@ -234,7 +235,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case 4: - //Non standard + // Non standard sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | HS400_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; @@ -243,7 +244,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; case 10: - //T210 Errata for SDR50, the host must be set to SDR104. + // T210 Errata for SDR50, the host must be set to SDR104. sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & SDHCI_CTRL_UHS_MASK) | UHS_SDR104_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; @@ -265,7 +266,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) divisor = div >> 8; sdmmc->regs->clkcon = (sdmmc->regs->clkcon & 0x3F) | (div << 8) | (divisor << 6); - //Enable the SD clock again. + // Enable the SD clock again. if (should_enable_sd_clock) sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; @@ -399,7 +400,7 @@ static int _sdmmc_wait_prnsts_type0(sdmmc_t *sdmmc, u32 wait_dat) _sdmmc_get_clkcon(sdmmc); u32 timeout = get_tmr_ms() + 2000; - while(sdmmc->regs->prnsts & 1) //CMD inhibit. + while(sdmmc->regs->prnsts & 1) // CMD inhibit. if (get_tmr_ms() > timeout) { _sdmmc_reset(sdmmc); @@ -409,7 +410,7 @@ static int _sdmmc_wait_prnsts_type0(sdmmc_t *sdmmc, u32 wait_dat) if (wait_dat) { timeout = get_tmr_ms() + 2000; - while (sdmmc->regs->prnsts & 2) //DAT inhibit. + while (sdmmc->regs->prnsts & 2) // DAT inhibit. if (get_tmr_ms() > timeout) { _sdmmc_reset(sdmmc); @@ -425,7 +426,7 @@ static int _sdmmc_wait_prnsts_type1(sdmmc_t *sdmmc) _sdmmc_get_clkcon(sdmmc); u32 timeout = get_tmr_ms() + 2000; - while (!(sdmmc->regs->prnsts & 0x100000)) //DAT0 line level. + while (!(sdmmc->regs->prnsts & 0x100000)) // DAT0 line level. if (get_tmr_ms() > timeout) { _sdmmc_reset(sdmmc); @@ -667,7 +668,7 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power) { if (get_tmr_ms() > timeout) { - //In case autocalibration fails, we load suggested standard values. + // In case autocalibration fails, we load suggested standard values. _sdmmc_pad_config_fallback(sdmmc, power); sdmmc->regs->autocalcfg &= 0xDFFFFFFF; break; @@ -704,7 +705,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask) if (pout) *pout = norintsts; - //Check for error interrupt. + // Check for error interrupt. if (norintsts & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { sdmmc->regs->errintsts = errintsts; @@ -794,7 +795,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req) blkcnt = 0xFFFF; u32 admaaddr = (u32)req->buf; - //Check alignment. + // Check alignment. if (admaaddr << 29) return 0; @@ -818,7 +819,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req) trnmode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ; if (req->is_auto_cmd12) trnmode = (trnmode & 0xFFF3) | TEGRA_MMC_TRNMOD_AUTO_CMD12; - + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); sdmmc->regs->trnmod = trnmode; return 1; @@ -842,10 +843,13 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc) if (res < 0) break; if (intr & TEGRA_MMC_NORINTSTS_XFER_COMPLETE) - return 1; //Transfer complete. + { + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); + return 1; // Transfer complete. + } if (intr & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT) { - //Update DMA. + // Update DMA. sdmmc->regs->admaaddr = sdmmc->dma_addr_next; sdmmc->regs->admaaddr_hi = 0; sdmmc->dma_addr_next += 0x80000; @@ -920,7 +924,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_ static int _sdmmc_config_sdmmc1() { - //Configure SD card detect. + // Configure SD card detect. PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 1; //GPIO control, pull up. APB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0; gpio_config(GPIO_PORT_Z, GPIO_PIN_1, GPIO_MODE_GPIO); @@ -938,7 +942,7 @@ static int _sdmmc_config_sdmmc1() * APB_MISC_GP_SDMMCx_CLK_LPBK_CONTROL = SDMMCx_CLK_PAD_E_LPBK for CLK */ - //Configure SDMMC1 pinmux. + // Configure SDMMC1 pinmux. APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1; PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED; PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; @@ -947,12 +951,12 @@ static int _sdmmc_config_sdmmc1() PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP; - //Make sure the SDMMC1 controller is powered. + // Make sure the SDMMC1 controller is powered. PMC(APBDEV_PMC_NO_IOPOWER) &= ~(1 << 12); - //Assume 3.3V SD card voltage. + // Assume 3.3V SD card voltage. PMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12); - //Set enable SD card power. + // Set enable SD card power. PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; //GPIO control, pull down. gpio_config(GPIO_PORT_E, GPIO_PIN_4, GPIO_MODE_GPIO); gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH); @@ -960,13 +964,13 @@ static int _sdmmc_config_sdmmc1() usleep(1000); - //Enable SD card power. + // Enable SD card power. max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000); max77620_regulator_enable(REGULATOR_LDO2, 1); usleep(1000); - //For good measure. + // For good measure. APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x10000000; usleep(1000); @@ -1063,7 +1067,7 @@ int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *req, u32 *b if (!sdmmc->sd_clock_enabled) return 0; - //Recalibrate periodically for SDMMC1. + // Recalibrate periodically for SDMMC1. if (sdmmc->id == SDMMC_1 && sdmmc->no_sd) _sdmmc_autocal_execute(sdmmc, sdmmc_get_voltage(sdmmc)); @@ -1094,6 +1098,14 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc) _sdmmc_get_clkcon(sdmmc); + // Enable schmitt trigger for better duty cycle and low jitter clock. + PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_SCHMT; + PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) |= PINMUX_SCHMT; + PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT; + PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT; + PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT; + PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT; + max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000); PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(1 << 12);