Compare commits

..

10 Commits
v3.1 ... v3.2

Author SHA1 Message Date
Kostas Missos
7af531de77 Add sleep mode support for 3.X.X. ^^ 2018-07-09 23:01:40 +03:00
Kostas Missos
a77783b922 Add dumping of decrypted package2 2018-07-09 22:16:42 +03:00
Kostas Missos
33457ad8f8 As always remove more uneeded stuff 2018-07-09 22:13:56 +03:00
Kostas Missos
828b616468 Add status bar (battery info)
This gets updated in menus and backup/restore options and it's still visible to other options
2018-07-09 16:06:17 +03:00
Kostas Missos
2f120d1cbb Change partial backup msg + some fixes 2018-07-09 16:02:47 +03:00
Kostas Missos
a5f2bb9d57 Support custom backcolor when logo is smaller
When the bootlogo is smaller than 720x1280, the background color will be set to match the color of bmp's 1st pixel.

This ends the limit of having to use a background color of 0x1B1B1B.
2018-07-09 15:55:09 +03:00
Kostas Missos
60905c3829 Don't run hos keygen twice + Fix memory leaks 2018-07-07 18:36:18 +03:00
Kostas Missos
19e9292128 More unfattening 2018-07-07 18:34:33 +03:00
Kostas Missos
6d556bf213 Remove null term from "" as suggested
Additionally rename the archive bits again ( :) ) to have a little better syntax.
2018-07-06 16:11:51 +03:00
Jason Tomsic
f91546a1e5 Unset archive bit on all files except official Nintendo directory (#35)
* allow for all files to unset archive bit, except Nintendo dir
* don't recalculate path length with every file
* use strlen instead of a loop
* negating the if statement to reduce conditional context
* move an operation to the beginning of the loop so we don't have to have it twice
* combining some lines and removing a var for efficiency
2018-07-06 16:02:00 +03:00
13 changed files with 317 additions and 220 deletions

View File

@@ -1,10 +1,12 @@
# hekate - Bootlogo
The bootlogo can be any size with a maximum of 720 x 1280. It is automatically centered when it's smaller than 720 x 1280.
The bootlogo can be any size with a maximum of 720 x 1280.
When saving a landscape bootlogo, it should be rotated 90o counterclockwise.
When it's smaller than 720 x 1280, it is automatically centered and the background takes the color of the first pixel.
Lastly, the supported format is 32-bit BMP. Classic 24-bit BMPs are not supported for performance reasons.
When saving a landscape bootlogo, it should be rotated 90 degrees counterclockwise.
Lastly, the supported format is 32-bit (ARGB) BMP. Classic 24-bit (RGB) BMPs are not supported for performance reasons.
## How to configure

View File

@@ -42,6 +42,8 @@ void set_default_configuration()
h_cfg.bootwait = 3;
h_cfg.customlogo = 0;
h_cfg.verification = 2;
h_cfg.se_keygen_done = 0;
h_cfg.sbar_time_keeping = 0;
}
int create_config_entry()
@@ -272,7 +274,7 @@ void config_bootdelay()
else
delay_text[i * 32] = '*';
delay_text[i * 32 + 1] = i + '0';
memcpy(delay_text + i * 32 + 2, " seconds\0", 9);
memcpy(delay_text + i * 32 + 2, " seconds", 9);
ments[i + 2].type = MENT_CHOICE;
ments[i + 2].caption = delay_text + i * 32;
@@ -389,9 +391,9 @@ void config_verification()
ments[1].type = MENT_CHGLINE;
memcpy(vr_text, " Disable\0", 9);
memcpy(vr_text + 64, " Sparse (Fast - Not reliable)\0", 31);
memcpy(vr_text + 128, " Full (Slow - 100% reliable)\0", 31);
memcpy(vr_text, " Disable", 9);
memcpy(vr_text + 64, " Sparse (Fast - Not reliable)", 31);
memcpy(vr_text + 128, " Full (Slow - 100% reliable)", 31);
for (u32 i = 0; i < 3; i++)
{

View File

@@ -25,6 +25,9 @@ typedef struct _hekate_config
u32 bootwait;
u32 customlogo;
u32 verification;
// Global temporary config.
int se_keygen_done;
u32 sbar_time_keeping;
}hekate_config;
void set_default_configuration();

View File

@@ -3290,11 +3290,11 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
} while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4);
}
if (fmt == 4) {
EFSPRINTF("Disk I/O error - Could not load boot record!");
EFSPRINTF("Could not load boot record!");
return FR_DISK_ERR; /* An error occured in the disk I/O layer */
}
if (fmt >= 2) {
EFSPRINTF("No FAT/FAT32/exFAT filesystem found!");
EFSPRINTF("No FAT/FAT32/exFAT found!");
return FR_NO_FILESYSTEM; /* No FAT volume is found */
}
@@ -3305,26 +3305,20 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
QWORD maxlba;
for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */
if (i < BPB_ZeroedEx + 53) {
EFSPRINTF("exFAT - Zero filler check failed!");
if (i < BPB_ZeroedEx + 53)
return FR_NO_FILESYSTEM;
}
if (ld_word(fs->win + BPB_FSVerEx) != 0x100) {
EFSPRINTF("exFAT - Version check failed!");
if (ld_word(fs->win + BPB_FSVerEx) != 0x100)
return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */
}
if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */
EFSPRINTF("exFAT - Bytes per sector does not match physical sector size!");
EFSPRINTF("exFAT - Sector size does not match physical sector size!");
return FR_NO_FILESYSTEM;
}
maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */
if (maxlba >= 0x100000000) {
EFSPRINTF("exFAT - Cannot handle volume LBA with 32-bit LBA!");
if (maxlba >= 0x100000000)
return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */
}
fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */
@@ -3336,30 +3330,26 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */
if (fs->csize == 0) {
EFSPRINTF("exFAT - Cluster size is not between 1KB - 32KB!");
EFSPRINTF("exFAT - Sectors per clusters!");
return FR_NO_FILESYSTEM; /* (Must be 1..32768) */
}
nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */
if (nclst > MAX_EXFAT) {
EFSPRINTF("exFAT - Total clusters exceed allowed!");
if (nclst > MAX_EXFAT)
return FR_NO_FILESYSTEM; /* (Too many clusters) */
}
fs->n_fatent = nclst + 2;
/* Boundaries and Limits */
fs->volbase = bsect;
fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);
fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);
if (maxlba < (QWORD)fs->database + nclst * fs->csize) {
EFSPRINTF("exFAT - Volume size is lower than required!");
if (maxlba < (QWORD)fs->database + nclst * fs->csize)
return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size required) */
}
fs->dirbase = ld_dword(fs->win + BPB_RootClusEx);
/* Check if bitmap location is in assumption (at the first cluster) */
if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) {
EFSPRINTF("exFAT - Bitmap location not at first cluster!");
EFSPRINTF("exFAT - Bitmap location not at 1st cluster!");
return FR_DISK_ERR;
}
for (i = 0; i < SS(fs); i += SZDIRE) {
@@ -3377,7 +3367,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
#endif /* FF_FS_EXFAT */
{
if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) {
EFSPRINTF("FAT - Bytes per sector does not match physical sector size!");
EFSPRINTF("FAT - Sector size does not match physical sector size!");
return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */
}
@@ -3386,52 +3376,38 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
fs->fsize = fasize;
fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
if (fs->n_fats != 1 && fs->n_fats != 2) {
EFSPRINTF("FAT - No or more than 2 file allocation tables found!");
if (fs->n_fats != 1 && fs->n_fats != 2)
return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
}
fasize *= fs->n_fats; /* Number of sectors for FAT area */
fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) {
EFSPRINTF("FAT - Cluster size is not a power of 2!");
if (fs->csize == 0 || (fs->csize & (fs->csize - 1)))
return FR_NO_FILESYSTEM; /* (Must be power of 2) */
}
fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
if (fs->n_rootdir % (SS(fs) / SZDIRE)) {
EFSPRINTF("FAT - Root directory entries are not sector aligned!");
if (fs->n_rootdir % (SS(fs) / SZDIRE))
return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
}
tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
if (nrsv == 0) {
EFSPRINTF("FAT - Zero reserved sectors!");
if (nrsv == 0)
return FR_NO_FILESYSTEM; /* (Must not be 0) */
}
/* Determine the FAT sub type */
sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
if (tsect < sysect) {
EFSPRINTF("FAT - Invalid volume size!");
if (tsect < sysect)
return FR_NO_FILESYSTEM; /* (Invalid volume size) */
}
nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
if (nclst == 0) {
EFSPRINTF("FAT - Invalid volume size!");
if (nclst == 0)
return FR_NO_FILESYSTEM; /* (Invalid volume size) */
}
fmt = 0;
if (nclst <= MAX_FAT32) fmt = FS_FAT32;
if (nclst <= MAX_FAT16) fmt = FS_FAT16;
if (nclst <= MAX_FAT12) fmt = FS_FAT12;
if (fmt == 0) {
EFSPRINTF("FAT - Not compatible FAT12/16/32 filesystem!");
if (fmt == 0)
return FR_NO_FILESYSTEM;
}
/* Boundaries and Limits */
fs->n_fatent = nclst + 2; /* Number of FAT entries */
@@ -3439,29 +3415,21 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
fs->fatbase = bsect + nrsv; /* FAT start sector */
fs->database = bsect + sysect; /* Data start sector */
if (fmt == FS_FAT32) {
if (ld_word(fs->win + BPB_FSVer32) != 0) {
EFSPRINTF("FAT32 - Not a 0.0 revision!");
if (ld_word(fs->win + BPB_FSVer32) != 0)
return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */
}
if (fs->n_rootdir != 0) {
EFSPRINTF("FAT32 - Root entry sector is not 0!");
if (fs->n_rootdir != 0)
return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
}
fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
} else {
if (fs->n_rootdir == 0) {
EFSPRINTF("FAT - Root entry sector is 0!");
if (fs->n_rootdir == 0)
return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
}
fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */
fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
}
if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) {
EFSPRINTF("FAT - FAT size is not the required size!");
if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs))
return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */
}
#if !FF_FS_READONLY
/* Get FSInfo if available */
@@ -3894,7 +3862,7 @@ FRESULT f_read (
}
#endif
if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
EFSPRINTF("Read - Low level disk I/O!\n(fill sector cache)");
EFSPRINTF("Read - Fill sector cache");
ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
}
}
@@ -3991,10 +3959,8 @@ FRESULT f_write (
if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
#else
if (fp->flag & FA_DIRTY) { /* Write-back sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
EFSPRINTF("Write-back sector cache!");
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK)
ABORT(fs, FR_DISK_ERR);
}
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
@@ -4037,10 +4003,8 @@ FRESULT f_write (
#else
if (fp->sect != sect && /* Fill sector cache with file data */
fp->fptr < fp->obj.objsize &&
disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
EFSPRINTF("Read - Low level disk I/O!\n(Could not fill sector cache with file data)");
disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK)
ABORT(fs, FR_DISK_ERR);
}
#endif
fp->sect = sect;
}

View File

@@ -136,6 +136,11 @@ void gfx_clear_color(gfx_ctxt_t *ctxt, u32 color)
ctxt->fb[i] = color;
}
void gfx_clear_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height)
{
memset(ctxt->fb + pos_x * ctxt->stride , color, height * 4 * ctxt->stride);
}
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt)
{
con->gfx_ctxt = ctxt;
@@ -360,7 +365,7 @@ void gfx_printf(gfx_con_t *con, const char *fmt, ...)
break;
case 'K':
con->bgcol = va_arg(ap, u32);
con->fillbg = fcnt;
con->fillbg = 1;
break;
case '%':
gfx_putc(con, '%');

View File

@@ -44,6 +44,7 @@ typedef struct _gfx_con_t
void gfx_init_ctxt(gfx_ctxt_t *ctxt, u32 *fb, u32 width, u32 height, u32 stride);
void gfx_clear_grey(gfx_ctxt_t *ctxt, u8 color);
void gfx_clear_partial_grey(gfx_ctxt_t *ctxt, u8 color, u32 pos_x, u32 height);
void gfx_clear_color(gfx_ctxt_t *ctxt, u32 color);
void gfx_con_init(gfx_con_t *con, gfx_ctxt_t *ctxt);
void gfx_con_setcol(gfx_con_t *con, u32 fgcol, int fillbg, u32 bgcol);

View File

@@ -35,6 +35,7 @@
#include "pkg2.h"
#include "ff.h"
#include "di.h"
#include "config.h"
#include "gfx.h"
extern gfx_ctxt_t gfx_ctxt;
@@ -43,6 +44,8 @@ extern void sd_unmount();
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
#define DPRINTF(...)
extern hekate_config h_cfg;
typedef struct _launch_ctxt_t
{
void *keyblob;
@@ -209,7 +212,7 @@ int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
return 1;
}
static void _copy_bootconfig(launch_ctxt_t *ctxt)
static void _copy_bootconfig()
{
sdmmc_storage_t storage;
sdmmc_t sdmmc;
@@ -247,7 +250,7 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
gfx_printf(&gfx_con, "Identified package1 ('%s'),\nKeyblob version %d\n\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb);
//Read the correct keyblob.
ctxt->keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
res = 1;
@@ -406,6 +409,16 @@ static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
return 1;
}
static void _free_launch_components(launch_ctxt_t *ctxt)
{
free(ctxt->keyblob);
free(ctxt->pkg1);
free(ctxt->pkg2);
free(ctxt->warmboot);
free(ctxt->secmon);
free(ctxt->kernel);
}
int hos_launch(ini_sec_t *cfg)
{
int bootStateDramPkg2 = 0;
@@ -434,8 +447,12 @@ int hos_launch(ini_sec_t *cfg)
gfx_printf(&gfx_con, "Loaded package1 and keyblob\n");
// Generate keys.
keygen(ctxt.keyblob, ctxt.pkg1_id->kb, (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off);
DPRINTF("Generated keys\n");
if (!h_cfg.se_keygen_done)
{
keygen(ctxt.keyblob, ctxt.pkg1_id->kb, (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off);
h_cfg.se_keygen_done = 1;
DPRINTF("Generated keys\n");
}
// Decrypt and unpack package1 if we require parts of it.
if (!ctxt.warmboot || !ctxt.secmon)
@@ -544,6 +561,10 @@ int hos_launch(ini_sec_t *cfg)
}
case KB_FIRMWARE_VERSION_300:
case KB_FIRMWARE_VERSION_301:
if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_300)
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 security check.
else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 security check.
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(13, 0xFF);
bootStateDramPkg2 = 2;
@@ -552,11 +573,11 @@ int hos_launch(ini_sec_t *cfg)
if (!exoFwNumber)
exoFwNumber = 3;
break;
default:
case KB_FIRMWARE_VERSION_400:
if (!exoFwNumber)
exoFwNumber = 4;
case KB_FIRMWARE_VERSION_500:
default:
se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(15, 0xFF);
bootStateDramPkg2 = 2;
@@ -566,6 +587,10 @@ int hos_launch(ini_sec_t *cfg)
break;
}
// Free allocated memory.
ini_free_section(cfg);
_free_launch_components(&ctxt);
// Copy BCT if debug mode is enabled.
memset((void *)0x4003D000, 0, 0x3000);
if(ctxt.debugmode)
@@ -584,17 +609,17 @@ int hos_launch(ini_sec_t *cfg)
// Lock SE before starting 'SecureMonitor'.
_se_lock();
//< 4.0.0 Signals. 0: Nothing ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot
//>=4.0.0 Signals. 0: Nothing ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot
// < 4.0.0 Signals - 0: Nothing ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
// >= 4.0.0 Signals - 0: Nothing ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
vu32 *mb_in = (vu32 *)0x40002EF8;
//Non-zero: Secmon ready
vu32 *mb_out = (vu32 *)0x40002EFC;
//Start from DRAM ready signal
// Start from DRAM ready signal.
*mb_in = bootStateDramPkg2;
*mb_out = 0;
//Wait for secmon to get ready.
// Wait for secmon to get ready.
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
while (!*mb_out)
usleep(1);
@@ -613,10 +638,10 @@ int hos_launch(ini_sec_t *cfg)
if (end_di)
display_end();
//Signal to pkg2 ready and continue boot.
// Signal pkg2 ready and continue boot.
*mb_in = bootStatePkg2Continue;
//Halt ourselves in waitevent state and resume if there's JTAG activity.
// Halt ourselves in waitevent state and resume if there's JTAG activity.
while (1)
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = 0x50000000;

View File

@@ -50,6 +50,7 @@
#include "se_t210.h"
#include "hos.h"
#include "pkg1.h"
#include "pkg2.h"
#include "mmc.h"
#include "lz.h"
#include "max17050.h"
@@ -354,7 +355,7 @@ void config_hw()
void print_fuseinfo()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
u32 burntFuses = 0;
@@ -392,11 +393,9 @@ void print_fuseinfo()
char fuseFilename[23];
f_mkdir("Backup");
f_mkdir("Backup/Dumps");
memcpy(fuseFilename, "Backup/Dumps/fuses.bin\0", 23);
memcpy(fuseFilename, "Backup/Dumps/fuses.bin", 23);
if (sd_save_to_file((u8 *)0x7000F900, 0x2FC, fuseFilename))
EPRINTF("\nError creating fuse.bin file.");
else
if (!sd_save_to_file((u8 *)0x7000F900, 0x2FC, fuseFilename))
gfx_puts(&gfx_con, "\nDone!\n");
sd_unmount();
}
@@ -407,7 +406,7 @@ void print_fuseinfo()
void print_kfuseinfo()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%kKFuse contents:\n\n%k", 0xFF00DDFF, 0xFFCCCCCC);
@@ -427,11 +426,9 @@ void print_kfuseinfo()
char kfuseFilename[24];
f_mkdir("Backup");
f_mkdir("Backup/Dumps");
memcpy(kfuseFilename, "Backup/Dumps/kfuses.bin\0", 24);
memcpy(kfuseFilename, "Backup/Dumps/kfuses.bin", 24);
if (sd_save_to_file((u8 *)buf, KFUSE_NUM_WORDS * 4, kfuseFilename))
EPRINTF("\nError creating kfuse.bin file.");
else
if (!sd_save_to_file((u8 *)buf, KFUSE_NUM_WORDS * 4, kfuseFilename))
gfx_puts(&gfx_con, "\nDone!\n");
sd_unmount();
}
@@ -442,7 +439,7 @@ void print_kfuseinfo()
void print_mmc_info()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
static const u32 SECTORS_TO_MIB_COEFF = 11;
@@ -599,7 +596,7 @@ void print_sdcard_info()
{
static const u32 SECTORS_TO_MIB_COEFF = 11;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
if (sd_mount())
@@ -651,7 +648,7 @@ void print_sdcard_info()
void print_tsec_key()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
sdmmc_storage_t storage;
@@ -845,7 +842,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
FIL partialIdxFp;
char partialIdxFilename[12];
memcpy(partialIdxFilename, "partial.idx\0", 12);
memcpy(partialIdxFilename, "partial.idx", 12);
gfx_con.fntsz = 8;
gfx_printf(&gfx_con, "\nSD Card free space: %d MiB, Total backup size %d MiB\n\n",
@@ -1015,11 +1012,11 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
// More parts to backup that do not currently fit the sd card free space or fatal error.
if (currPartIdx >= maxSplitParts)
{
gfx_puts(&gfx_con, "\n\n1. Press any key and Power off Switch from the main menu.\n\
2. Move the files from SD card to free space.\n\
gfx_puts(&gfx_con, "\n\n1. Press any key to unmount SD Card.\n\
2. Remove SD Card and move files to free space.\n\
Don\'t move the partial.idx file!\n\
3. Unplug and re-plug USB while pressing Vol+.\n\
4. Run hekate again and press Backup eMMC RAW GPP (or eMMC USER) to continue.\n");
3. Re-insert SD Card.\n\
4. Select the SAME option again to continue.\n");
gfx_con.fntsz = 16;
free(buf);
@@ -1137,7 +1134,8 @@ static void dump_emmc_selected(emmcPartType_t dumpType)
{
int res = 0;
u32 timer = 0;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
tui_sbar(&gfx_con, 1);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sd_mount())
@@ -1283,7 +1281,7 @@ int restore_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part
else if (((u32)((u64)f_size(&fp)>>(u64)9)) != totalSectors)
{
gfx_con.fntsz = 16;
EPRINTF("Size of sd card backup does not match,\neMMC's selected part size.\n");
EPRINTF("Size of the SD Card backup does not match,\neMMC's selected part size.\n");
f_close(&fp);
return 0;
@@ -1381,7 +1379,8 @@ static void restore_emmc_selected(emmcPartType_t restoreType)
{
int res = 0;
u32 timer = 0;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
tui_sbar(&gfx_con, 1);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%kThis is a dangerous operation\nand may render your device inoperative!\n\n", 0xFFFFDD00);
@@ -1504,16 +1503,15 @@ void restore_emmc_boot() { restore_emmc_selected(PART_BOOT); }
void restore_emmc_rawnand() { restore_emmc_selected(PART_RAW); }
void restore_emmc_gpp_parts() { restore_emmc_selected(PART_GP_ALL); }
//TODO: dump_package2
void dump_package1()
void dump_packages12()
{
u8 *pkg1 = (u8 *)calloc(1, 0x40000);
u8 *warmboot = (u8 *)calloc(1, 0x40000);
u8 *secmon = (u8 *)calloc(1, 0x40000);
u8 *loader = (u8 *)calloc(1, 0x40000);
u8 *pkg2 = NULL;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sd_mount())
@@ -1539,61 +1537,102 @@ void dump_package1()
goto out;
}
// Read keyblob.
u8 * keyblob = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob);
if (!h_cfg.se_keygen_done)
{
// Read keyblob.
u8 *keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
sdmmc_storage_read(&storage, 0x180000 / NX_EMMC_BLOCKSIZE + pkg1_id->kb, 1, keyblob);
// Decrypt.
keygen(keyblob, pkg1_id->kb, (u8 *)pkg1 + pkg1_id->tsec_off);
// Decrypt.
keygen(keyblob, pkg1_id->kb, (u8 *)pkg1 + pkg1_id->tsec_off);
h_cfg.se_keygen_done = 1;
free(keyblob);
}
pkg1_decrypt(pkg1_id, pkg1);
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1);
// Display info.
gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->ldr_size);
gfx_printf(&gfx_con, "%kNX Bootloader ofst: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->ldr_off);
gfx_printf(&gfx_con, "%kNX Bootloader size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->ldr_size);
gfx_printf(&gfx_con, "%kSecure monitor addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->secmon_base);
gfx_printf(&gfx_con, "%kSecure monitor size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->sm_size);
gfx_printf(&gfx_con, "%kSecure monitor ofst: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->sm_off);
gfx_printf(&gfx_con, "%kWarmboot addr: %k0x%05X\n", 0xFFC7EA46, 0xFFCCCCCC, pkg1_id->warmboot_base);
gfx_printf(&gfx_con, "%kWarmboot size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_size);
gfx_printf(&gfx_con, "%kWarmboot ofst: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, hdr->wb_off);
// Dump package1.
// Create folders if they do not exist.
f_mkdir("Backup");
f_mkdir("Backup/pkg1");
if (sd_save_to_file(pkg1, 0x40000, "Backup/pkg1/pkg1_decr.bin")) {
EPRINTF("\nFailed to create pkg1_decr.bin");
f_mkdir("Backup/pkg2");
// Dump package1.1.
if (sd_save_to_file(pkg1, 0x40000, "Backup/pkg1/pkg1_decr.bin"))
goto out;
}
gfx_puts(&gfx_con, "\nFull package1 dumped to pkg1_decr.bin\n");
// Dump nxbootloader.
if (sd_save_to_file(loader, hdr->ldr_size, "Backup/pkg1/nxloader.bin")) {
EPRINTF("\nFailed to create nxloader.bin");
if (sd_save_to_file(loader, hdr->ldr_size, "Backup/pkg1/nxloader.bin"))
goto out;
}
gfx_puts(&gfx_con, "NX Bootloader dumped to nxloader.bin\n");
// Dump secmon.
if (sd_save_to_file(secmon, hdr->sm_size, "Backup/pkg1/secmon.bin")) {
EPRINTF("\nFailed to create secmon.bin");
if (sd_save_to_file(secmon, hdr->sm_size, "Backup/pkg1/secmon.bin"))
goto out;
}
gfx_puts(&gfx_con, "Secure Monitor dumped to secmon.bin\n");
// Dump warmboot.
if (sd_save_to_file(warmboot, hdr->wb_size, "Backup/pkg1/warmboot.bin")) {
EPRINTF("\nFailed to create warmboot.bin");
if (sd_save_to_file(warmboot, hdr->wb_size, "Backup/pkg1/warmboot.bin"))
goto out;
}
gfx_puts(&gfx_con, "Warmboot dumped to warmboot.bin\n");
gfx_puts(&gfx_con, "Warmboot dumped to warmboot.bin\n\n\n");
// Dump package2.1
sdmmc_storage_set_mmc_partition(&storage, 0);
//Parse eMMC GPT.
LIST_INIT(gpt);
nx_emmc_gpt_parse(&gpt, &storage);
//Find package2 partition.
emmc_part_t *pkg2_part = nx_emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
if (!pkg2_part)
goto out;
sdmmc_storage_end(&storage);
sd_unmount();
//Read in package2 header and get package2 real size.
u8 *tmp = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE, 1, tmp);
u32 *hdr_pkg2_raw = (u32 *)(tmp + 0x100);
u32 pkg2_size = hdr_pkg2_raw[0] ^ hdr_pkg2_raw[2] ^ hdr_pkg2_raw[3];
free(tmp);
//Read in package2.
u32 pkg2_size_aligned = ALIGN(pkg2_size, NX_EMMC_BLOCKSIZE);
pkg2 = malloc(pkg2_size_aligned);
nx_emmc_part_read(&storage, pkg2_part, 0x4000 / NX_EMMC_BLOCKSIZE,
pkg2_size_aligned / NX_EMMC_BLOCKSIZE, pkg2);
// Decrypt package2 and parse KIP1 blobs in INI1 section.
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2);
// Display info.
u32 kernel_crc32 = crc32c(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL]);
gfx_printf(&gfx_con, "\n%kKernel CRC32C: %k0x%08X\n\n",0xFFC7EA46, 0xFFCCCCCC, kernel_crc32);
gfx_printf(&gfx_con, "%kKernel size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, pkg2_hdr->sec_size[PKG2_SEC_KERNEL]);
gfx_printf(&gfx_con, "%kINI1 size: %k0x%05X\n\n", 0xFFC7EA46, 0xFFCCCCCC, pkg2_hdr->sec_size[PKG2_SEC_INI1]);
// Dump pkg2.1.
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1],
"Backup/pkg2/pkg2_decr.bin"))
goto out;
gfx_puts(&gfx_con, "\nFull package2 dumped to pkg2_decr.bin\n");
// Dump kernel.
if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], "Backup/pkg2/kernel.bin"))
goto out;
gfx_puts(&gfx_con, "Kernel dumped to kernel.bin\n");
// Dump INI1.
if (sd_save_to_file(pkg2_hdr->data + pkg2_hdr->sec_size[PKG2_SEC_KERNEL],
pkg2_hdr->sec_size[PKG2_SEC_INI1], "Backup/pkg2/ini1.bin"))
goto out;
gfx_puts(&gfx_con, "INI1 kip1 package dumped to ini1.bin\n");
gfx_puts(&gfx_con, "\nDone. Press any key...\n");
out:;
@@ -1601,6 +1640,10 @@ out:;
free(secmon);
free(warmboot);
free(loader);
free(pkg2);
nx_emmc_gpt_free(&gpt);
sdmmc_storage_end(&storage);
sd_unmount();
btn_wait();
}
@@ -1812,6 +1855,9 @@ void auto_launch_firmware()
// Center logo if res < 720x1280.
bmpData.pos_x = (720 - bmpData.size_x) >> 1;
bmpData.pos_y = (1280 - bmpData.size_y) >> 1;
// Get background color from 1st pixel.
if (bmpData.size_x < 720 || bmpData.size_y < 1280)
gfx_clear_color(&gfx_ctxt, *(u32 *)BOOTLOGO);
bootlogoFound = 1;
}
@@ -1861,6 +1907,7 @@ void auto_launch_firmware()
}
out:;
gfx_clear_grey(&gfx_ctxt, 0x1B);
if (!ini_freed)
ini_free(&ini_sections);
ini_free_section(cfg_sec);
@@ -1876,7 +1923,7 @@ void toggle_autorcm(){
sdmmc_storage_t storage;
sdmmc_t sdmmc;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
if (!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4))
@@ -1906,70 +1953,83 @@ out:;
btn_wait();
}
int fix_attributes(char *path, u32 *total)
int fix_attributes(char *path, u32 *total, u32 is_root, u32 check_first_run)
{
FRESULT res;
DIR dir;
u32 i = 0;
u32 k = 0;
u32 dirLength = 0;
static FILINFO fno;
// Remove archive bit for selected "root" path.
f_chmod(path, 0, AM_ARC);
if (check_first_run)
{
// Read file attributes.
res = f_stat(path, &fno);
if (res != FR_OK)
return res;
// Check if archive bit is set.
if (fno.fattrib & AM_ARC)
{
*(u32 *)total = *(u32 *)total + 1;
f_chmod(path, 0, AM_ARC);
}
}
// Open directory.
res = f_opendir(&dir, path);
if (res == FR_OK)
if (res != FR_OK)
return res;
dirLength = strlen(path);
for (;;)
{
for (;;)
// Clear file or folder path.
path[dirLength] = 0;
// Read a directory item.
res = f_readdir(&dir, &fno);
// Break on error or end of dir.
if (res != FR_OK || fno.fname[0] == 0)
break;
// Skip official Nintendo dir.
if (is_root && !strcmp(fno.fname, "Nintendo"))
continue;
// Set new directory or file.
memcpy(&path[dirLength], "/", 1);
memcpy(&path[dirLength+1], fno.fname, strlen(fno.fname) + 1);
// Check if archive bit is set.
if (fno.fattrib & AM_ARC)
{
// Read a directory item.
res = f_readdir(&dir, &fno);
// Break on error or end of dir.
if (res != FR_OK || fno.fname[0] == 0)
break;
// Set new directory.
i = strlen(path);
memcpy(&path[i], "/", 1);
for (k = 0; k < 256; k++)
{
if (fno.fname[k] == 0)
break;
}
memcpy(&path[i+1], fno.fname, k + 1);
path[i + k + 2] = 0;
// 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?
if (fno.fattrib & AM_DIR)
{
// Enter the directory.
res = fix_attributes(path, total);
if (res != FR_OK)
break;
}
// Clear file or folder path.
path[i] = 0;
*(u32 *)total = *(u32 *)total + 1;
f_chmod(path, 0, AM_ARC);
}
// Is it a directory?
if (fno.fattrib & AM_DIR)
{
// Enter the directory.
res = fix_attributes(path, total, 0, 0);
if (res != FR_OK)
break;
}
f_closedir(&dir);
}
f_closedir(&dir);
return res;
}
void fix_sd_attr(u32 type)
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
char buff[256];
char path[256];
char label[14];
u32 total = 0;
if (sd_mount())
@@ -1977,25 +2037,26 @@ void fix_sd_attr(u32 type)
switch (type)
{
case 0:
gfx_printf(&gfx_con, "Traversing all switch folder files!\nThis may take some time, please wait...\n");
memcpy(buff, "/switch\0", 8);
memcpy(path, "/", 2);
memcpy(label, "SD Card", 8);
break;
case 1:
default:
gfx_printf(&gfx_con, "Traversing all sd card files!\nThis may take some time, please wait...\n");
memcpy(buff, "/\0", 2);
memcpy(path, "/switch", 8);
memcpy(label, "switch folder", 14);
break;
}
fix_attributes(buff, &total);
gfx_printf(&gfx_con, "\n%kTotal archive bits cleared: %d!%k\n\nDone! Press any key...", 0xFF96FF00, total, 0xFFCCCCCC);
gfx_printf(&gfx_con, "Traversing all %s files!\nThis may take some time, please wait...\n\n", label);
fix_attributes(path, &total, !type, type);
gfx_printf(&gfx_con, "%kTotal archive bits cleared: %d!%k\n\nDone! Press any key...", 0xFF96FF00, total, 0xFFCCCCCC);
sd_unmount();
}
btn_wait();
}
void fix_sd_switch_attr() { fix_sd_attr(0); }
void fix_sd_all_attr() { fix_sd_attr(1); }
void fix_sd_all_attr() { fix_sd_attr(0); }
void fix_sd_switch_attr() { fix_sd_attr(1); }
void print_fuel_gauge_info()
{
@@ -2123,7 +2184,7 @@ void print_battery_charger_info()
void print_battery_info()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
print_fuel_gauge_info();
@@ -2153,7 +2214,7 @@ void print_battery_info()
char fuelFilename[28];
f_mkdir("Backup");
f_mkdir("Backup/Dumps");
memcpy(fuelFilename, "Backup/Dumps/fuel_gauge.bin\0", 28);
memcpy(fuelFilename, "Backup/Dumps/fuel_gauge.bin", 28);
if (sd_save_to_file((u8 *)buf, 0x200, fuelFilename))
EPRINTF("\nError creating fuel.bin file.");
@@ -2169,7 +2230,7 @@ void print_battery_info()
/* void fix_fuel_gauge_configuration()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
int battVoltage, avgCurrent;
@@ -2222,7 +2283,7 @@ void print_battery_info()
{
int avgCurrent;
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%k\nThis will wipe your battery stats completely!\n"
@@ -2233,7 +2294,7 @@ void print_battery_info()
u32 btn = btn_wait();
if (btn & BTN_POWER)
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
gfx_printf(&gfx_con, "%kKeep the USB cable connected!%k\n\n", 0xFFFFDD00, 0xFFCCCCCC);
gfx_con_getpos(&gfx_con, &gfx_con.savedx, &gfx_con.savedy);
@@ -2268,7 +2329,7 @@ void print_battery_info()
void fix_battery_desync()
{
gfx_clear_grey(&gfx_ctxt, 0x1B);
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
gfx_con_setpos(&gfx_con, 0, 0);
max77620_low_battery_monitor_config();
@@ -2339,7 +2400,7 @@ ment_t ment_options[] = {
menu_t menu_options = {
ment_options,
"Launch options", 0, 0
"Launch Options", 0, 0
};
ment_t ment_cinfo[] = {
@@ -2360,7 +2421,7 @@ ment_t ment_cinfo[] = {
};
menu_t menu_cinfo = {
ment_cinfo,
"Console info", 0, 0
"Console Info", 0, 0
};
ment_t ment_autorcm[] = {
@@ -2399,7 +2460,7 @@ ment_t ment_restore[] = {
menu_t menu_restore = {
ment_restore,
"Restore options", 0, 0
"Restore Options", 0, 0
};
ment_t ment_backup[] = {
@@ -2417,7 +2478,7 @@ ment_t ment_backup[] = {
menu_t menu_backup = {
ment_backup,
"Backup options", 0, 0
"Backup Options", 0, 0
};
ment_t ment_tools[] = {
@@ -2429,10 +2490,10 @@ ment_t ment_tools[] = {
MDEF_HANDLER("Verification options", config_verification),
MDEF_CHGLINE(),
MDEF_CAPTION("-------- Misc --------", 0xFF0AB9E6),
MDEF_HANDLER("Dump package1", dump_package1),
MDEF_HANDLER("Dump package1/2", dump_packages12),
MDEF_HANDLER("Fix battery de-sync", fix_battery_desync),
MDEF_HANDLER("Remove archive bit (switch folder)", fix_sd_switch_attr),
//MDEF_HANDLER("Remove archive bit (all sd files)", fix_sd_all_attr),
MDEF_HANDLER("Unset archive bit (switch folder)", fix_sd_switch_attr),
MDEF_HANDLER("Unset archive bit (all sd files)", fix_sd_all_attr),
//MDEF_HANDLER("Fix fuel gauge configuration", fix_fuel_gauge_configuration),
//MDEF_HANDLER("Reset all battery cfg", reset_pmic_fuel_gauge_charger_config),
MDEF_CHGLINE(),
@@ -2484,7 +2545,6 @@ void ipl_main()
//display_color_screen(0xAABBCCDD);
u32 *fb = display_init_framebuffer();
gfx_init_ctxt(&gfx_ctxt, fb, 720, 1280, 768);
gfx_clear_grey(&gfx_ctxt, 0x1B);
#ifdef MENU_LOGO_ENABLE
Kc_MENU_LOGO = (u8 *)malloc(0x6000);

View File

@@ -36,6 +36,7 @@
#define APBDEV_PMC_REG_SHORT 0x2CC
#define APBDEV_PMC_WEAK_BIAS 0x2C8
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
#define APBDEV_PMC_CNTRL2 0x440
#define APBDEV_PMC_IO_DPD4_REQ 0x464
#define APBDEV_PMC_DDR_CNTRL 0x4E4

View File

@@ -259,7 +259,8 @@ int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u
}
// se_calc_sha256() was derived from Atmosphère's se_calculate_sha256.
int se_calc_sha256(void *dst, const void *src, u32 src_size) {
int se_calc_sha256(void *dst, const void *src, u32 src_size)
{
int res;
// Setup config for SHA256, size = BITS(src_size).
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
@@ -283,3 +284,4 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size) {
return res;
}

View File

@@ -18,15 +18,55 @@
#include "tui.h"
#include "btn.h"
#include "max17050.h"
#include "config.h"
#include "util.h"
#ifdef MENU_LOGO_ENABLE
extern u8 *Kc_MENU_LOGO;
#define X_MENU_LOGO 119
#define Y_MENU_LOGO 57
#define X_POS_MENU_LOGO 577
#define Y_POS_MENU_LOGO 1199
#define Y_POS_MENU_LOGO 1179
#endif //MENU_LOGO_ENABLE
extern hekate_config h_cfg;
void tui_sbar(gfx_con_t *con, int force_update)
{
u32 timePassed = get_tmr_s() - h_cfg.sbar_time_keeping;
if (!force_update)
if (timePassed < 5)
return;
u8 prevFontSize = con->fntsz;
con->fntsz = 16;
h_cfg.sbar_time_keeping = get_tmr_s();
u32 battPercent = 0;
int battVoltCurr = 0;
gfx_con_getpos(con, &con->savedx, &con->savedy);
gfx_con_setpos(con, 0, 1260);
max17050_get_property(MAX17050_RepSOC, (int *)&battPercent);
max17050_get_property(MAX17050_VCELL, &battVoltCurr);
gfx_clear_partial_grey(con->gfx_ctxt, 0x30, 1256, 24);
gfx_printf(con, "%K%k Battery: %d.%d%% (%d mV) - Charge:", 0xFF303030, 0xFF888888,
(battPercent >> 8) & 0xFF, (battPercent & 0xFF) / 26, battVoltCurr);
max17050_get_property(MAX17050_AvgCurrent, &battVoltCurr);
if (battVoltCurr >= 0)
gfx_printf(con, " %k+%d mA %k%K\n",
0xFF008000, battVoltCurr / 1000, 0xFFCCCCCC, 0xFF1B1B1B);
else
gfx_printf(con, " %k-%d mA %k%K\n",
0xFF800000, (~battVoltCurr) / 1000, 0xFFCCCCCC, 0xFF1B1B1B);
con->fntsz = prevFontSize;
gfx_con_setpos(con, con->savedx, con->savedy);
}
void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol)
{
u32 cx, cy;
@@ -48,15 +88,18 @@ void tui_pbar(gfx_con_t *con, int x, int y, u32 val, u32 fgcol, u32 bgcol)
}
gfx_con_setpos(con, cx, cy);
// Update status bar.
tui_sbar(con, 0);
}
void *tui_do_menu(gfx_con_t *con, menu_t *menu)
{
int idx = 0, prev_idx = 0, cnt = 0x7FFFFFFF;
u32 battPercent = 0;
int battVoltCurr = 0;
gfx_clear_grey(con->gfx_ctxt, 0x1B);
gfx_clear_partial_grey(con->gfx_ctxt, 0x1B, 0, 1256);
tui_sbar(con, 1);
#ifdef MENU_LOGO_ENABLE
gfx_set_rect_rgb(con->gfx_ctxt, Kc_MENU_LOGO,
X_MENU_LOGO, Y_MENU_LOGO, X_POS_MENU_LOGO, Y_POS_MENU_LOGO);
@@ -113,21 +156,8 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
// Print help and battery status.
gfx_con_getpos(con, &con->savedx, &con->savedy);
gfx_con_setpos(con, 0, 74 * 16);
gfx_printf(con, "%k VOL: Move up/down\n PWR: Select option\n\n", 0xFF555555);
max17050_get_property(MAX17050_RepSOC, (int *)&battPercent);
gfx_printf(con, " %d.%d%%", (battPercent >> 8) & 0xFF, (battPercent & 0xFF) / 26);
max17050_get_property(MAX17050_VCELL, &battVoltCurr);
gfx_printf(con, " (%d mV) ", battVoltCurr);
max17050_get_property(MAX17050_AvgCurrent, &battVoltCurr);
if (battVoltCurr >= 0)
gfx_printf(con, "\n %kCharging:%k %d mA %k\n",
0xFF008000, 0xFF555555, battVoltCurr / 1000, 0xFFCCCCCC);
else
gfx_printf(con, "\n %kDischarging:%k -%d mA %k\n",
0xFF800000, 0xFF555555, (~battVoltCurr) / 1000, 0xFFCCCCCC);
gfx_con_setpos(con, con->savedx, con->savedy);
gfx_con_setpos(con, 0, 1191);
gfx_printf(con, "%k VOL: Move up/down\n PWR: Select option%k", 0xFF555555, 0xFFCCCCCC);
// Wait for user command.
u32 btn = btn_wait();
@@ -161,12 +191,13 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
break;
}
con->fntsz = 16;
gfx_clear_grey(con->gfx_ctxt, 0x1B);
gfx_clear_partial_grey(con->gfx_ctxt, 0x1B, 0, 1256);
#ifdef MENU_LOGO_ENABLE
gfx_set_rect_rgb(con->gfx_ctxt, Kc_MENU_LOGO,
X_MENU_LOGO, Y_MENU_LOGO, X_POS_MENU_LOGO, Y_POS_MENU_LOGO);
#endif //MENU_LOGO_ENABLE
}
tui_sbar(con, 0);
}
return NULL;

View File

@@ -58,6 +58,7 @@ typedef struct _menu_t
#define MDEF_CAPTION(caption, color) { MENT_CAPTION, caption, color }
#define MDEF_CHGLINE() {MENT_CHGLINE}
void tui_sbar(gfx_con_t *con, int force_update);
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);

View File

@@ -26,13 +26,13 @@ u32 get_tmr_s()
u32 get_tmr_ms()
{
// The registers must be read with the following order:
// -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0x8)
// -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
return (RTC(0x10) | (RTC(0xC)<< 10));
}
u32 get_tmr_us()
{
return TMR(0x10); //TMRUS
return TMR(0x10); //TIMERUS_CNTR_1US
}
void msleep(u32 milliseconds)