Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f085cbc4a4 | ||
|
|
d8b6aa3831 | ||
|
|
3e5ef39686 | ||
|
|
bc7c65447d | ||
|
|
a91378b9c1 | ||
|
|
7543234401 | ||
|
|
5b91c54936 | ||
|
|
322280757f | ||
|
|
b1636fbb96 | ||
|
|
cc18a7b146 | ||
|
|
5fe84a78ac | ||
|
|
822e0dcd98 | ||
|
|
a6be3714a3 | ||
|
|
f56d1bad04 | ||
|
|
c7ab404fc1 | ||
|
|
e8f41a03f3 | ||
|
|
8edc9971f9 | ||
|
|
54c36a7e46 | ||
|
|
afb820202d | ||
|
|
0ce973966f | ||
|
|
da8c040c08 |
@@ -67,6 +67,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| umsemmcrw=1 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
|
||||
|
||||
### Boot entry key/value combinations:
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 2
|
||||
BLVERSION_HOTFX := 0
|
||||
BLVERSION_HOTFX := 1
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 0
|
||||
NYXVERSION_MINOR := 9
|
||||
NYXVERSION_HOTFX := 0
|
||||
NYXVERSION_HOTFX := 1
|
||||
NYXVERSION_RSVD := 0
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "../soc/smmu.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../storage/emummc.h"
|
||||
#include "../storage/mbr_gpt.h"
|
||||
#include "../storage/nx_emmc.h"
|
||||
#include "../storage/nx_sd.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
@@ -51,8 +52,7 @@ extern hekate_config h_cfg;
|
||||
#define DPRINTF(...)
|
||||
|
||||
#define EHPRINTFARGS(text, args...) \
|
||||
({ display_backlight_brightness(h_cfg.backlight, 1000); \
|
||||
gfx_con.mute = false; \
|
||||
({ gfx_con.mute = false; \
|
||||
gfx_printf("%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC); })
|
||||
|
||||
#define PKG2_LOAD_ADDR 0xA9800000
|
||||
@@ -103,8 +103,6 @@ static void _hos_crit_error(const char *text)
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
gfx_printf("%k%s%k\n", 0xFFFF0000, text, 0xFFCCCCCC);
|
||||
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
}
|
||||
|
||||
static void _se_lock(bool lock_se)
|
||||
@@ -183,15 +181,42 @@ void _sysctr0_reset()
|
||||
SYSCTR0(SYSCTR0_COUNTERID11) = 0;
|
||||
}
|
||||
|
||||
bool hos_eks_rw_try(u8 *buf, bool write)
|
||||
{
|
||||
mbr_t *mbr = (mbr_t *)buf;
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (!write)
|
||||
{
|
||||
if (sdmmc_storage_read(&sd_storage, 0, 1, mbr))
|
||||
{
|
||||
if (mbr->partitions[0].status != 0xFF &&
|
||||
mbr->partitions[0].start_sct &&
|
||||
mbr->partitions[0].size_sct)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sdmmc_storage_write(&sd_storage, 0, 1, mbr))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void hos_eks_get()
|
||||
{
|
||||
// Check if EKS already found and parsed.
|
||||
if (!h_cfg.eks)
|
||||
{
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
|
||||
// Read EKS blob.
|
||||
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
// Decrypt EKS blob.
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10);
|
||||
@@ -208,6 +233,7 @@ void hos_eks_get()
|
||||
return;
|
||||
}
|
||||
|
||||
out:
|
||||
free(mbr);
|
||||
}
|
||||
}
|
||||
@@ -221,12 +247,29 @@ void hos_eks_save(u32 kb)
|
||||
if (key_idx > 5)
|
||||
return;
|
||||
|
||||
bool new_eks = false;
|
||||
if (!h_cfg.eks)
|
||||
{
|
||||
h_cfg.eks = calloc(512 , 1);
|
||||
new_eks = true;
|
||||
}
|
||||
|
||||
// If matching blob doesn't exist, create it.
|
||||
if (!(h_cfg.eks->enabled & (1 << key_idx)))
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
{
|
||||
if (new_eks)
|
||||
{
|
||||
free(h_cfg.eks);
|
||||
h_cfg.eks = NULL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Get keys.
|
||||
u8 *keys = (u8 *)calloc(0x1000, 1);
|
||||
se_get_aes_keys(keys + 0x800, keys, 0x10);
|
||||
@@ -244,20 +287,21 @@ void hos_eks_save(u32 kb)
|
||||
memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10);
|
||||
memcpy(h_cfg.eks->keys[key_idx].dkk, keys + 15 * 0x10, 0x10);
|
||||
|
||||
// Encrypt EKS.
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS to SD.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||
// Write EKS blob to SD.
|
||||
memset(mbr, 0, 0x10);
|
||||
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
|
||||
free(eks);
|
||||
free(mbr);
|
||||
free(keys);
|
||||
out:
|
||||
free(mbr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,21 +314,25 @@ void hos_eks_clear(u32 kb)
|
||||
u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
|
||||
if (h_cfg.eks->enabled & (1 << key_idx))
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
// Disable current Master key version.
|
||||
h_cfg.eks->enabled &= ~(1 << key_idx);
|
||||
|
||||
// Encrypt EKS.
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS to SD.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
free(eks);
|
||||
out:
|
||||
free(mbr);
|
||||
}
|
||||
}
|
||||
@@ -477,8 +525,8 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
||||
if (!ctxt->pkg1_id)
|
||||
{
|
||||
_hos_crit_error("Unknown pkg1 version.");
|
||||
EHPRINTFARGS("%sNot yet supported HOS version!",
|
||||
(emu_cfg.enabled && !h_cfg.emummc_force_disable) ? "Is emuMMC corrupt?\nOr " : "");
|
||||
EHPRINTFARGS("HOS version not supported!%s",
|
||||
(emu_cfg.enabled && !h_cfg.emummc_force_disable) ? "\nOr emuMMC corrupt!" : "");
|
||||
goto out;
|
||||
}
|
||||
gfx_printf("Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb);
|
||||
@@ -489,7 +537,7 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
out:
|
||||
sdmmc_storage_end(&storage);
|
||||
return res;
|
||||
}
|
||||
@@ -731,7 +779,10 @@ int hos_launch(ini_sec_t *cfg)
|
||||
// Read package2.
|
||||
u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt);
|
||||
if (!bootConfigBuf)
|
||||
{
|
||||
_hos_crit_error("Pkg2 read failed!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
gfx_printf("Read pkg2\n");
|
||||
|
||||
@@ -839,9 +890,6 @@ int hos_launch(ini_sec_t *cfg)
|
||||
|
||||
gfx_printf("Rebuilt & loaded pkg2\n");
|
||||
|
||||
// Unmount SD card.
|
||||
sd_unmount();
|
||||
|
||||
gfx_printf("\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
|
||||
|
||||
// Clear pkg1/pkg2 keys.
|
||||
@@ -896,6 +944,9 @@ int hos_launch(ini_sec_t *cfg)
|
||||
if (ctxt.atmosphere && ctxt.secmon)
|
||||
config_exosphere(&ctxt);
|
||||
|
||||
// Unmount SD card.
|
||||
sd_unmount();
|
||||
|
||||
// Finalize MC carveout.
|
||||
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_301)
|
||||
mc_config_carveout();
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct _hos_eks_mbr_t
|
||||
u32 rsvd2[3];
|
||||
} hos_eks_mbr_t;
|
||||
|
||||
static_assert(sizeof(hos_eks_mbr_t) < 424, "HOS EKS storage bigger than MBR!");
|
||||
static_assert(sizeof(hos_eks_mbr_t) == 416, "HOS EKS storage bigger than MBR!");
|
||||
|
||||
typedef struct _launch_ctxt_t
|
||||
{
|
||||
|
||||
@@ -223,7 +223,7 @@ static int _config_exo_user_pmu_access(launch_ctxt_t *ctxt, const char *value)
|
||||
static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
// Override key found.
|
||||
ctxt->exo_cfg.cal0_blank = calloc(1, 1);
|
||||
ctxt->exo_cfg.cal0_blank = calloc(sizeof(bool), 1);
|
||||
|
||||
if (*value == '1')
|
||||
{
|
||||
@@ -236,7 +236,7 @@ static int _config_exo_cal0_blanking(launch_ctxt_t *ctxt, const char *value)
|
||||
static int _config_exo_cal0_writes_enable(launch_ctxt_t *ctxt, const char *value)
|
||||
{
|
||||
// Override key found.
|
||||
ctxt->exo_cfg.cal0_allow_writes_sys = calloc(1, 1);
|
||||
ctxt->exo_cfg.cal0_allow_writes_sys = calloc(sizeof(bool), 1);
|
||||
|
||||
if (*value == '1')
|
||||
{
|
||||
|
||||
@@ -221,12 +221,12 @@ void config_exosphere(launch_ctxt_t *ctxt)
|
||||
if (ctxt->exo_cfg.user_pmu)
|
||||
exoFlags |= EXO_FLAG_USER_PMU;
|
||||
|
||||
// Check if exo ini value is overridden and enable prodinfo blanking.
|
||||
// Enable prodinfo blanking. Check if exo ini value is overridden. If not, check if enabled in exo ini.
|
||||
if ((ctxt->exo_cfg.cal0_blank && *ctxt->exo_cfg.cal0_blank)
|
||||
|| (!ctxt->exo_cfg.cal0_blank && cal0_blanking))
|
||||
exoFlags |= EXO_FLAG_CAL0_BLANKING;
|
||||
|
||||
// Check if exo ini value is overridden and allow prodinfo writes.
|
||||
// Allow prodinfo writes. Check if exo ini value is overridden. If not, check if enabled in exo ini.
|
||||
if ((ctxt->exo_cfg.cal0_allow_writes_sys && *ctxt->exo_cfg.cal0_allow_writes_sys)
|
||||
|| (!ctxt->exo_cfg.cal0_allow_writes_sys && cal0_allow_writes_sys))
|
||||
exoFlags |= EXO_FLAG_CAL0_WRITES_SYS;
|
||||
|
||||
@@ -5630,7 +5630,7 @@ FRESULT f_mkfs (
|
||||
UINT len /* Size of working buffer [byte] */
|
||||
)
|
||||
{
|
||||
const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_fats = 2; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */
|
||||
static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */
|
||||
static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */
|
||||
@@ -5918,6 +5918,9 @@ FRESULT f_mkfs (
|
||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
|
||||
|
||||
@@ -465,8 +465,11 @@ void ini_list_launcher()
|
||||
}
|
||||
}
|
||||
|
||||
if (emummc_path)
|
||||
emummc_set_path(emummc_path);
|
||||
if (emummc_path && !emummc_set_path(emummc_path))
|
||||
{
|
||||
EPRINTF("emupath is wrong!");
|
||||
goto wrong_emupath;
|
||||
}
|
||||
|
||||
if (cfg_sec && !payload_path)
|
||||
check_sept(cfg_sec);
|
||||
@@ -497,15 +500,13 @@ void ini_list_launcher()
|
||||
}
|
||||
else if (!hos_launch(cfg_sec))
|
||||
{
|
||||
EPRINTF("Failed to launch firmware.");
|
||||
|
||||
wrong_emupath:
|
||||
EPRINTF("Failed to launch HOS.");
|
||||
if (emummc_path)
|
||||
{
|
||||
sd_mount();
|
||||
emummc_load_cfg();
|
||||
}
|
||||
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -605,8 +606,11 @@ void launch_firmware()
|
||||
}
|
||||
}
|
||||
|
||||
if (emummc_path)
|
||||
emummc_set_path(emummc_path);
|
||||
if (emummc_path && !emummc_set_path(emummc_path))
|
||||
{
|
||||
EPRINTF("emupath is wrong!");
|
||||
goto wrong_emupath;
|
||||
}
|
||||
|
||||
if (cfg_sec && !payload_path)
|
||||
check_sept(cfg_sec);
|
||||
@@ -642,7 +646,8 @@ void launch_firmware()
|
||||
}
|
||||
else if (!hos_launch(cfg_sec))
|
||||
{
|
||||
EPRINTF("Failed to launch firmware.");
|
||||
wrong_emupath:
|
||||
EPRINTF("Failed to launch HOS.");
|
||||
if (emummc_path)
|
||||
{
|
||||
sd_mount();
|
||||
@@ -1034,8 +1039,13 @@ skip_list:
|
||||
{
|
||||
if (b_cfg.boot_cfg & BOOT_CFG_TO_EMUMMC)
|
||||
emummc_set_path(b_cfg.emummc_path);
|
||||
else if (emummc_path)
|
||||
emummc_set_path(emummc_path);
|
||||
else if (emummc_path && !emummc_set_path(emummc_path))
|
||||
{
|
||||
gfx_con.mute = false;
|
||||
EPRINTF("emupath is wrong!");
|
||||
goto wrong_emupath;
|
||||
}
|
||||
|
||||
check_sept(cfg_sec);
|
||||
hos_launch(cfg_sec);
|
||||
|
||||
@@ -1045,6 +1055,8 @@ skip_list:
|
||||
emummc_load_cfg();
|
||||
}
|
||||
|
||||
wrong_emupath:
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
EPRINTF("\nFailed to launch HOS!");
|
||||
gfx_printf("\nPress any key...\n");
|
||||
msleep(500);
|
||||
@@ -1432,7 +1444,7 @@ ment_t ment_top[] = {
|
||||
MDEF_END()
|
||||
};
|
||||
|
||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.2.0", 0, 0 };
|
||||
menu_t menu_top = { ment_top, "hekate - CTCaer mod v5.2.1", 0, 0 };
|
||||
|
||||
extern void pivot_stack(u32 stack_top);
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ void *malloc(u32 size)
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(&_heap, num * size);
|
||||
memset(res, 0, num * size);
|
||||
memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
count, node->used, (u32)node + sizeof(hnode_t), node->size);
|
||||
|
||||
count++;
|
||||
|
||||
|
||||
if (node->next)
|
||||
node = node->next;
|
||||
else
|
||||
|
||||
@@ -119,7 +119,7 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
||||
time->weekday = 0; //! TODO.
|
||||
}
|
||||
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding)
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
||||
{
|
||||
u32 year, month, epoch;
|
||||
|
||||
@@ -128,39 +128,17 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding)
|
||||
//Month of year
|
||||
month = time->month;
|
||||
|
||||
if (!hos_encoding)
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
year -= 2000;
|
||||
month++;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
month += 9;
|
||||
year--;
|
||||
}
|
||||
else
|
||||
month -= 3;
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
|
||||
if (!hos_encoding)
|
||||
{
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
}
|
||||
else
|
||||
epoch += (30 * month) + ((3 * month + 2) / 5) + 59 + time->day; // Months to days.
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
|
||||
epoch *= 86400; // Days to seconds.
|
||||
epoch += (3600 * time->hour) + (60 * time->min) + time->sec; // Add hours, minutes and seconds.
|
||||
|
||||
@@ -72,6 +72,6 @@ typedef struct _rtc_time_t {
|
||||
void max77620_rtc_get_time(rtc_time_t *time);
|
||||
void max77620_rtc_stop_alarm();
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
|
||||
#endif /* _MFD_MAX77620_RTC_H_ */
|
||||
|
||||
@@ -72,7 +72,7 @@ void emummc_load_cfg()
|
||||
}
|
||||
}
|
||||
|
||||
void emummc_set_path(char *path)
|
||||
bool emummc_set_path(char *path)
|
||||
{
|
||||
FIL fp;
|
||||
bool found = false;
|
||||
@@ -105,8 +105,10 @@ void emummc_set_path(char *path)
|
||||
emu_cfg.enabled = 1;
|
||||
emu_cfg.id = 0;
|
||||
strcpy(emu_cfg.nintendo_path, path);
|
||||
strcpy(emu_cfg.nintendo_path, "/Nintendo");
|
||||
strcat(emu_cfg.nintendo_path, "/Nintendo");
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static int emummc_raw_get_part_off(int part_idx)
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef struct _emummc_cfg_t
|
||||
emummc_cfg_t emu_cfg;
|
||||
|
||||
void emummc_load_cfg();
|
||||
void emummc_set_path(char *path);
|
||||
bool emummc_set_path(char *path);
|
||||
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
|
||||
int emummc_storage_end(sdmmc_storage_t *storage);
|
||||
int emummc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf);
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct _mbr_part_t
|
||||
|
||||
typedef struct _mbr_t
|
||||
{
|
||||
u8 bootstrap[0x1B8];
|
||||
u8 bootstrap[440];
|
||||
u32 signature;
|
||||
u16 copy_protected;
|
||||
mbr_part_t partitions[4];
|
||||
|
||||
@@ -63,7 +63,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
lv_hal_disp.o lv_hal_indev.o lv_hal_tick.o \
|
||||
interui_20.o interui_30.o ubuntu_mono.o hekate_symbol_20.o hekate_symbol_30.o hekate_symbol_120.o lv_font_builtin.o \
|
||||
lv_anim.o lv_area.o lv_circ.o lv_color.o lv_font.o lv_ll.o lv_math.o lv_mem.o lv_task.o lv_txt.o lv_gc.o \
|
||||
lv_bar.o lv_btn.o lv_btnm.o lv_cb.o lv_cont.o lv_ddlist.o lv_img.o lv_kb.o lv_label.o lv_line.o lv_list.o lv_lmeter.o lv_mbox.o \
|
||||
lv_bar.o lv_btn.o lv_btnm.o lv_cb.o lv_cont.o lv_ddlist.o lv_img.o lv_label.o lv_line.o lv_list.o lv_lmeter.o lv_mbox.o \
|
||||
lv_page.o lv_roller.o lv_slider.o lv_sw.o lv_tabview.o lv_ta.o lv_win.o lv_log.o lv_imgbtn.o \
|
||||
lv_theme.o lv_theme_hekate.o \
|
||||
)
|
||||
|
||||
@@ -4,6 +4,10 @@ The background for Nyx, must be a 1280 x 720 32-bit BMP. Alpha blending is taken
|
||||
|
||||
The icons supported are 192 x 192 32-bit BMP. You can utilize transparency at will and make nice mixes with the button background.
|
||||
|
||||
Additionally, using the `icon={sd path}`, the icon will get colorized if the name ends in `_hue.bmp`. That only works nicely if the icon is a white layout with transparency.
|
||||
|
||||
The default system icons (`icon_switch.bmp` and `icon_payload.bmp`) can be replaced with white layouts that have transparency. They can also be replaced with normal icons if the following exist: `icon_switch_custom.bmp` or/and `icon_payload_custom.bmp`
|
||||
|
||||
|
||||
## How to configure
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ void set_nyx_default_configuration()
|
||||
n_cfg.timeoff = 0;
|
||||
n_cfg.home_screen = 0;
|
||||
n_cfg.verification = 1;
|
||||
n_cfg.ums_emmc_rw = 0;
|
||||
}
|
||||
|
||||
int create_config_entry()
|
||||
@@ -194,7 +195,7 @@ int create_nyx_config_entry()
|
||||
itoa(n_cfg.themecolor, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\ntimeoff=", &fp);
|
||||
itoa(n_cfg.timeoff, lbuf, 10);
|
||||
itoa(n_cfg.timeoff, lbuf, 16);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nhomescreen=", &fp);
|
||||
itoa(n_cfg.home_screen, lbuf, 10);
|
||||
@@ -202,6 +203,9 @@ int create_nyx_config_entry()
|
||||
f_puts("\nverification=", &fp);
|
||||
itoa(n_cfg.verification, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\numsemmcrw=", &fp);
|
||||
itoa(n_cfg.ums_emmc_rw, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\n", &fp);
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
@@ -45,9 +45,10 @@ typedef struct _hekate_config
|
||||
typedef struct _nyx_config
|
||||
{
|
||||
u32 themecolor;
|
||||
s32 timeoff;
|
||||
u32 timeoff;
|
||||
u32 home_screen;
|
||||
u32 verification;
|
||||
u32 ums_emmc_rw;
|
||||
} nyx_config;
|
||||
|
||||
void set_default_configuration();
|
||||
|
||||
@@ -1145,7 +1145,7 @@ static void _update_status_bar(void *params)
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = (u32)((s32)max77620_rtc_date_to_epoch(&time, true) + (s32)n_cfg.timeoff);
|
||||
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
soc_temp = tmp451_get_soc_temp(false);
|
||||
@@ -1293,7 +1293,7 @@ static lv_res_t _win_launch_close_action(lv_obj_t * btn)
|
||||
lv_img_dsc_t *src = (lv_img_dsc_t *)lv_img_get_src(img);
|
||||
|
||||
// Avoid freeing base icons.
|
||||
if ((src != icon_switch) && (src != icon_payload) && (src != icon_lakka))
|
||||
if ((src != icon_switch) && (src != icon_payload))
|
||||
free(src);
|
||||
}
|
||||
}
|
||||
@@ -1503,6 +1503,12 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
|
||||
launch_ctxt[btn_idx + 1] = boot_entry_label;
|
||||
}
|
||||
|
||||
// Create colorized icon style based on its parrent style.
|
||||
static lv_style_t img_style;
|
||||
lv_style_copy(&img_style, &lv_style_plain);
|
||||
img_style.image.color = lv_color_hsv_to_rgb(n_cfg.themecolor, 100, 100);
|
||||
img_style.image.intense = LV_OPA_COVER;
|
||||
|
||||
// Parse ini boot entries and set buttons/icons.
|
||||
char *tmp_path = malloc(1024);
|
||||
u32 curr_btn_idx = 0; // Active buttons.
|
||||
@@ -1510,6 +1516,10 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
// Check if we use custom system icons.
|
||||
bool icon_sw_custom = !f_stat("bootloader/res/icon_switch_custom.bmp", NULL);
|
||||
bool icon_pl_custom = !f_stat("bootloader/res/icon_payload_custom.bmp", NULL);
|
||||
|
||||
// Choose what to parse.
|
||||
bool ini_parse_success = false;
|
||||
if (!more_cfg)
|
||||
@@ -1539,6 +1549,7 @@ ini_parsing:
|
||||
|
||||
icon_path = NULL;
|
||||
u32 payload = 0;
|
||||
bool img_colorize = false;
|
||||
lv_img_dsc_t *bmp = NULL;
|
||||
lv_obj_t *img = NULL;
|
||||
|
||||
@@ -1565,26 +1576,49 @@ ini_parsing:
|
||||
bmp = bmp_to_lvimg_obj(tmp_path);
|
||||
if (!bmp)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "Lakka"))
|
||||
bmp = icon_lakka;
|
||||
else if (payload)
|
||||
bmp = icon_payload;
|
||||
s_printf(tmp_path, "bootloader/res/%s_hue.bmp", ini_sec->name);
|
||||
bmp = bmp_to_lvimg_obj(tmp_path);
|
||||
if (bmp)
|
||||
img_colorize = true;
|
||||
}
|
||||
|
||||
if (!bmp && payload)
|
||||
{
|
||||
bmp = icon_payload;
|
||||
|
||||
if (!icon_pl_custom)
|
||||
img_colorize = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bmp = bmp_to_lvimg_obj(icon_path);
|
||||
|
||||
// Check if colorization is enabled.
|
||||
if (bmp && strlen(icon_path) > 8 && !memcmp(icon_path + strlen(icon_path) - 8, "_hue", 4))
|
||||
img_colorize = true;
|
||||
}
|
||||
|
||||
// Enable button.
|
||||
lv_obj_set_opa_scale(launch_ctxt[curr_btn_idx], LV_OPA_COVER);
|
||||
|
||||
// Default to switch logo if no icon found at all.
|
||||
if (!bmp)
|
||||
{
|
||||
bmp = icon_switch;
|
||||
|
||||
if (!icon_sw_custom)
|
||||
img_colorize = true;
|
||||
}
|
||||
|
||||
//Set icon.
|
||||
if (bmp)
|
||||
{
|
||||
img = lv_img_create(launch_ctxt[curr_btn_idx], NULL);
|
||||
|
||||
if (img_colorize)
|
||||
lv_img_set_style(img, &img_style);
|
||||
|
||||
lv_img_set_src(img, bmp);
|
||||
}
|
||||
|
||||
@@ -1801,6 +1835,8 @@ static lv_res_t _save_options_action(lv_obj_t *btn)
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, NULL);
|
||||
lv_obj_set_top(mbox, true);
|
||||
|
||||
nyx_options_clear_ini_changes_made();
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
@@ -1866,6 +1902,44 @@ static void _create_status_bar(lv_theme_t * th)
|
||||
lv_btn_set_action(btn_mid, LV_BTN_ACTION_CLICK, _save_options_action);
|
||||
}
|
||||
|
||||
static lv_res_t _create_mbox_save_changes_action(lv_obj_t *btns, const char * txt)
|
||||
{
|
||||
int btn_idx = lv_btnm_get_pressed(btns);
|
||||
|
||||
mbox_action(btns, txt);
|
||||
|
||||
if (!btn_idx)
|
||||
_save_options_action(NULL);
|
||||
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
void nyx_check_ini_changes()
|
||||
{
|
||||
if (nyx_options_get_ini_changes_made())
|
||||
{
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\222Save", "\222Cancel", "" };
|
||||
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
|
||||
lv_mbox_set_text(mbox,
|
||||
"#FF8000 Main configuration#\n\n"
|
||||
"You changed your configuration!\n\n"
|
||||
"Do you want to save it?");
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, _create_mbox_save_changes_action);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_top(mbox, true);
|
||||
|
||||
nyx_options_clear_ini_changes_made();
|
||||
}
|
||||
}
|
||||
|
||||
static lv_res_t _show_hide_save_button(lv_obj_t *tv, uint16_t tab_idx)
|
||||
{
|
||||
if (tab_idx == 4) // Options.
|
||||
@@ -1879,6 +1953,8 @@ static lv_res_t _show_hide_save_button(lv_obj_t *tv, uint16_t tab_idx)
|
||||
lv_obj_set_click(status_bar.mid, false);
|
||||
}
|
||||
|
||||
nyx_check_ini_changes();
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,15 +49,8 @@ extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_st
|
||||
|
||||
static lv_res_t _create_window_dump_done(int error, char *dump_filenames)
|
||||
{
|
||||
lv_style_t *darken;
|
||||
darken = (lv_style_t *)malloc(sizeof(lv_style_t));
|
||||
lv_style_copy(darken, &lv_style_plain);
|
||||
darken->body.main_color = LV_COLOR_BLACK;
|
||||
darken->body.grad_color = darken->body.main_color;
|
||||
darken->body.opa = LV_OPA_30;
|
||||
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, darken);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
|
||||
@@ -705,15 +698,8 @@ static lv_res_t _create_mbox_benchmark(bool sd_bench)
|
||||
sdmmc_storage_t emmc_storage;
|
||||
sdmmc_storage_t *storage;
|
||||
|
||||
lv_style_t *darken;
|
||||
darken = (lv_style_t *)malloc(sizeof(lv_style_t));
|
||||
lv_style_copy(darken, &lv_style_plain);
|
||||
darken->body.main_color = LV_COLOR_BLACK;
|
||||
darken->body.grad_color = darken->body.main_color;
|
||||
darken->body.opa = LV_OPA_30;
|
||||
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, darken);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
|
||||
@@ -1134,7 +1120,7 @@ static lv_res_t _create_window_sdcard_info_status(lv_obj_t *btn)
|
||||
lv_obj_set_width(lb_desc4, lv_obj_get_width(desc4));
|
||||
|
||||
lv_label_set_text(lb_desc4,
|
||||
"#00DDFF SDMMC1 Error Counts:#\n"
|
||||
"#00DDFF SDMMC1 Errors:#\n"
|
||||
"Init fails:\n"
|
||||
"Read/Write fails:\n"
|
||||
"Read/Write errors:"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../input/joycon.h"
|
||||
#include "../libs/lvgl/lvgl.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../rtc/max77620-rtc.h"
|
||||
#include "../storage/nx_sd.h"
|
||||
#include "../utils/list.h"
|
||||
#include "../utils/sprintf.h"
|
||||
@@ -34,9 +35,22 @@ extern nyx_config n_cfg;
|
||||
static lv_obj_t *autoboot_btn;
|
||||
static bool autoboot_first_time = true;
|
||||
|
||||
static bool ini_changes_made = false;
|
||||
|
||||
void nyx_options_clear_ini_changes_made()
|
||||
{
|
||||
ini_changes_made = false;
|
||||
}
|
||||
|
||||
bool nyx_options_get_ini_changes_made()
|
||||
{
|
||||
return ini_changes_made;
|
||||
}
|
||||
|
||||
static lv_res_t auto_hos_poweroff_toggle(lv_obj_t *btn)
|
||||
{
|
||||
h_cfg.autohosoff = !h_cfg.autohosoff;
|
||||
ini_changes_made = true;
|
||||
|
||||
if (!h_cfg.autohosoff)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
@@ -51,6 +65,7 @@ static lv_res_t auto_hos_poweroff_toggle(lv_obj_t *btn)
|
||||
static lv_res_t auto_nogc_toggle(lv_obj_t *btn)
|
||||
{
|
||||
h_cfg.autonogc = !h_cfg.autonogc;
|
||||
ini_changes_made = true;
|
||||
|
||||
if (!h_cfg.autonogc)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
@@ -65,6 +80,7 @@ static lv_res_t auto_nogc_toggle(lv_obj_t *btn)
|
||||
static lv_res_t _update_r2p_action(lv_obj_t *btn)
|
||||
{
|
||||
h_cfg.updater2p = !h_cfg.updater2p;
|
||||
ini_changes_made = true;
|
||||
|
||||
if (!h_cfg.updater2p)
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
@@ -117,6 +133,7 @@ static lv_res_t _autoboot_disable_action(lv_obj_t *btn)
|
||||
{
|
||||
h_cfg.autoboot = 0;
|
||||
h_cfg.autoboot_list = 0;
|
||||
ini_changes_made = true;
|
||||
|
||||
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_REL);
|
||||
nyx_generic_onoff_toggle(autoboot_btn);
|
||||
@@ -134,6 +151,7 @@ static lv_res_t _autoboot_enable_main_action(lv_obj_t *btn)
|
||||
{
|
||||
h_cfg.autoboot = lv_list_get_btn_index(auto_main_list, btn) + 1;
|
||||
h_cfg.autoboot_list = 0;
|
||||
ini_changes_made = true;
|
||||
|
||||
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_TGL_REL);
|
||||
nyx_generic_onoff_toggle(autoboot_btn);
|
||||
@@ -150,6 +168,7 @@ static lv_res_t _autoboot_enable_more_action(lv_obj_t *btn)
|
||||
{
|
||||
h_cfg.autoboot = lv_list_get_btn_index(auto_more_list, btn) + 1;
|
||||
h_cfg.autoboot_list = 1;
|
||||
ini_changes_made = true;
|
||||
|
||||
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_TGL_REL);
|
||||
nyx_generic_onoff_toggle(autoboot_btn);
|
||||
@@ -280,6 +299,7 @@ static lv_res_t _autoboot_hide_delay_action(lv_obj_t *btn)
|
||||
static lv_res_t _autoboot_delay_action(lv_obj_t *ddlist)
|
||||
{
|
||||
h_cfg.bootwait = lv_ddlist_get_selected(ddlist);
|
||||
ini_changes_made = true;
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
@@ -288,6 +308,7 @@ static lv_res_t _slider_brightness_action(lv_obj_t * slider)
|
||||
{
|
||||
display_backlight_brightness(lv_slider_get_value(slider) - 20, 0);
|
||||
h_cfg.backlight = lv_slider_get_value(slider);
|
||||
ini_changes_made = true;
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
@@ -516,13 +537,61 @@ static lv_res_t _create_window_nyx_colors(lv_obj_t *btn)
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
lv_obj_t *epoch_ta;
|
||||
static lv_res_t _create_mbox_clock_edit_action(lv_obj_t * btns, const char * txt)
|
||||
typedef struct _time_edit_obj_t
|
||||
{
|
||||
lv_obj_t *year;
|
||||
lv_obj_t *month;
|
||||
lv_obj_t *day;
|
||||
lv_obj_t *hour;
|
||||
lv_obj_t *min;
|
||||
} time_edit_obj_t;
|
||||
|
||||
time_edit_obj_t clock_ctxt;
|
||||
|
||||
static lv_res_t _action_clock_edit(lv_obj_t *btns, const char * txt)
|
||||
{
|
||||
int btn_idx = lv_btnm_get_pressed(btns);
|
||||
|
||||
if (btn_idx == 1)
|
||||
n_cfg.timeoff = strtol(lv_ta_get_text(epoch_ta), NULL, 16);
|
||||
{
|
||||
rtc_time_t time;
|
||||
max77620_rtc_get_time(&time);
|
||||
u32 epoch = max77620_rtc_date_to_epoch(&time);
|
||||
|
||||
u32 year = lv_roller_get_selected(clock_ctxt.year);
|
||||
u32 month = lv_roller_get_selected(clock_ctxt.month) + 1;
|
||||
u32 day = lv_roller_get_selected(clock_ctxt.day) + 1;
|
||||
u32 hour = lv_roller_get_selected(clock_ctxt.hour);
|
||||
u32 min = lv_roller_get_selected(clock_ctxt.min);
|
||||
|
||||
switch (month)
|
||||
{
|
||||
case 2:
|
||||
if (!(year % 4) && day > 29)
|
||||
day = 29;
|
||||
else if (day > 28)
|
||||
day = 28;
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
if (day > 30)
|
||||
day = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
time.year = year + 2020;
|
||||
time.month = month;
|
||||
time.day = day;
|
||||
time.hour = hour;
|
||||
time.min = min;
|
||||
|
||||
u32 new_epoch = max77620_rtc_date_to_epoch(&time);
|
||||
|
||||
n_cfg.timeoff = new_epoch - epoch;
|
||||
}
|
||||
|
||||
mbox_action(btns, txt);
|
||||
|
||||
@@ -531,15 +600,8 @@ static lv_res_t _create_mbox_clock_edit_action(lv_obj_t * btns, const char * txt
|
||||
|
||||
static lv_res_t _create_mbox_clock_edit(lv_obj_t *btn)
|
||||
{
|
||||
lv_style_t *darken;
|
||||
darken = malloc(sizeof(lv_style_t));
|
||||
lv_style_copy(darken, &lv_style_plain);
|
||||
darken->body.main_color = LV_COLOR_BLACK;
|
||||
darken->body.grad_color = darken->body.main_color;
|
||||
darken->body.opa = LV_OPA_30;
|
||||
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, darken);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\211", "\222Done", "\222Cancel", "\211", "" };
|
||||
@@ -547,28 +609,94 @@ static lv_res_t _create_mbox_clock_edit(lv_obj_t *btn)
|
||||
lv_mbox_set_recolor_text(mbox, true);
|
||||
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
|
||||
|
||||
lv_mbox_set_text(mbox, "Type the #C7EA46 epoch# offset in HEX s32:");
|
||||
lv_mbox_set_text(mbox, "Enter #C7EA46 Date# and #C7EA46 Time#");
|
||||
|
||||
lv_obj_t *ta = lv_ta_create(mbox, NULL);
|
||||
lv_obj_set_size(ta, LV_HOR_RES / 5, LV_VER_RES / 10);
|
||||
lv_obj_align(ta, NULL, LV_ALIGN_IN_TOP_RIGHT, -LV_DPI / 10, LV_DPI / 10);
|
||||
lv_ta_set_cursor_type(ta, LV_CURSOR_LINE);
|
||||
lv_ta_set_one_line(ta, true);
|
||||
epoch_ta = ta;
|
||||
rtc_time_t time;
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff;
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
if (time.year < 2020)
|
||||
time.year = 2020;
|
||||
else if (time.year > 2030)
|
||||
time.year = 2030;
|
||||
|
||||
static char epoch_off[16];
|
||||
s_printf(epoch_off, "%X", n_cfg.timeoff);
|
||||
lv_ta_set_text(ta, epoch_off);
|
||||
lv_ta_set_max_length(ta, 8);
|
||||
time.year -= 2020;
|
||||
|
||||
lv_obj_t *kb = lv_kb_create(mbox, NULL);
|
||||
lv_obj_set_size(kb, 2 * LV_HOR_RES / 3, LV_VER_RES / 3);
|
||||
lv_obj_align(kb, ta, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI);
|
||||
lv_kb_set_mode(kb, LV_KB_MODE_HEX);
|
||||
lv_kb_set_ta(kb, ta);
|
||||
lv_kb_set_cursor_manage(kb, true);
|
||||
lv_obj_t *h1 = lv_cont_create(mbox, NULL);
|
||||
lv_cont_set_fit(h1, true, true);
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, _create_mbox_clock_edit_action); // Important. After set_text.
|
||||
lv_obj_t *roller_year = lv_roller_create(h1, NULL);
|
||||
lv_roller_set_options(roller_year,
|
||||
"2020\n"
|
||||
"2021\n"
|
||||
"2022\n"
|
||||
"2023\n"
|
||||
"2024\n"
|
||||
"2025\n"
|
||||
"2026\n"
|
||||
"2027\n"
|
||||
"2028\n"
|
||||
"2029\n"
|
||||
"2030");
|
||||
lv_roller_set_selected(roller_year, time.year, false);
|
||||
lv_roller_set_visible_row_count(roller_year, 3);
|
||||
clock_ctxt.year = roller_year;
|
||||
|
||||
lv_obj_t *roller_month = lv_roller_create(h1, roller_year);
|
||||
lv_roller_set_options(roller_month,
|
||||
"January\n"
|
||||
"February\n"
|
||||
"March\n"
|
||||
"April\n"
|
||||
"May\n"
|
||||
"June\n"
|
||||
"July\n"
|
||||
"August\n"
|
||||
"September\n"
|
||||
"October\n"
|
||||
"November\n"
|
||||
"December");
|
||||
lv_roller_set_selected(roller_month, time.month - 1, false);
|
||||
lv_obj_align(roller_month, roller_year, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
||||
clock_ctxt.month = roller_month;
|
||||
|
||||
static char days[256];
|
||||
days[0] = 0;
|
||||
for (u32 i = 1; i < 32; i++)
|
||||
s_printf(days + strlen(days), " %d \n", i);
|
||||
days[strlen(days) - 1] = 0;
|
||||
lv_obj_t *roller_day = lv_roller_create(h1, roller_year);
|
||||
lv_roller_set_options(roller_day, days);
|
||||
lv_roller_set_selected(roller_day, time.day - 1, false);
|
||||
lv_obj_align(roller_day, roller_month, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
||||
clock_ctxt.day = roller_day;
|
||||
|
||||
static char hours[256];
|
||||
hours[0] = 0;
|
||||
for (u32 i = 0; i < 24; i++)
|
||||
s_printf(hours + strlen(hours), " %d \n", i);
|
||||
hours[strlen(hours) - 1] = 0;
|
||||
lv_obj_t *roller_hour = lv_roller_create(h1, roller_year);
|
||||
lv_roller_set_options(roller_hour, hours);
|
||||
lv_roller_set_selected(roller_hour, time.hour, false);
|
||||
lv_obj_align(roller_hour, roller_day, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
|
||||
clock_ctxt.hour = roller_hour;
|
||||
|
||||
static char minutes[512];
|
||||
minutes[0] = 0;
|
||||
for (u32 i = 0; i < 60; i++)
|
||||
s_printf(minutes + strlen(minutes), " %02d \n", i);
|
||||
minutes[strlen(minutes) - 1] = 0;
|
||||
lv_obj_t *roller_minute = lv_roller_create(h1, roller_year);
|
||||
lv_roller_set_options(roller_minute, minutes);
|
||||
lv_roller_set_selected(roller_minute, time.min, false);
|
||||
lv_obj_align(roller_minute, roller_hour, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
||||
clock_ctxt.min = roller_minute;
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, _action_clock_edit); // Important. After set_text.
|
||||
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_top(mbox, true);
|
||||
@@ -626,15 +754,8 @@ static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
|
||||
sd_unmount(false);
|
||||
}
|
||||
|
||||
lv_style_t *darken;
|
||||
darken = (lv_style_t *)malloc(sizeof(lv_style_t));
|
||||
lv_style_copy(darken, &lv_style_plain);
|
||||
darken->body.main_color = LV_COLOR_BLACK;
|
||||
darken->body.grad_color = darken->body.main_color;
|
||||
darken->body.opa = LV_OPA_30;
|
||||
|
||||
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(dark_bg, darken);
|
||||
lv_obj_set_style(dark_bg, &mbox_darken);
|
||||
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
static const char * mbox_btn_map[] = { "\211", "\222OK", "\211", "" };
|
||||
@@ -781,23 +902,16 @@ lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
|
||||
lv_obj_t *btn2 = lv_btn_create(sw_h2, NULL);
|
||||
lv_obj_t *label_btn2 = lv_label_create(btn2, NULL);
|
||||
lv_btn_set_fit(btn2, true, true);
|
||||
lv_label_set_static_text(label_btn2, SYMBOL_CLOCK" Clock (HOS)");
|
||||
lv_label_set_static_text(label_btn2, SYMBOL_CLOCK" Clock (Offset)");
|
||||
lv_obj_align(btn2, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
|
||||
lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_mbox_clock_edit); //TODO: Add support.
|
||||
lv_btn_set_state(btn2, LV_BTN_STATE_INA); //TODO: Add support.
|
||||
|
||||
lv_obj_t *btn4 = lv_btn_create(sw_h2, btn2);
|
||||
label_btn2 = lv_label_create(btn4, NULL);
|
||||
lv_label_set_static_text(label_btn2, " "SYMBOL_EDIT" Manually ");
|
||||
lv_obj_align(btn4, btn2, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 8, 0);
|
||||
lv_btn_set_action(btn4, LV_BTN_ACTION_CLICK, _create_mbox_clock_edit);
|
||||
lv_btn_set_state(btn4, LV_BTN_STATE_REL);
|
||||
lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_mbox_clock_edit);
|
||||
|
||||
label_txt2 = lv_label_create(sw_h2, NULL);
|
||||
lv_label_set_recolor(label_txt2, true);
|
||||
lv_label_set_static_text(label_txt2,
|
||||
"#FF8000 Clock (HOS):# #C7EA46 Change clock offset based on what HOS uses.#\n"
|
||||
"#FF8000 Manually:# #C7EA46 Edit the clock offset manually.#");
|
||||
"Change clock offset manually.\n"
|
||||
"#C7EA46 The entered Date and Time will be converted to an offset#\n"
|
||||
"#C7EA46 automatically. This will be also used for FatFS operations.#");
|
||||
lv_obj_set_style(label_txt2, &hint_small_style);
|
||||
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "../libs/lvgl/lvgl.h"
|
||||
|
||||
void nyx_options_clear_ini_changes_made();
|
||||
bool nyx_options_get_ini_changes_made();
|
||||
lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn);
|
||||
void create_tab_options(lv_theme_t *th, lv_obj_t *parent);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
extern volatile boot_cfg_t *b_cfg;
|
||||
extern hekate_config h_cfg;
|
||||
extern nyx_config n_cfg;
|
||||
|
||||
extern void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
|
||||
|
||||
@@ -643,8 +644,6 @@ static lv_res_t _create_window_usb_tools(lv_obj_t *parent)
|
||||
{
|
||||
lv_obj_t *win = nyx_create_standard_window(SYMBOL_USB" USB Tools");
|
||||
|
||||
usb_msc_emmc_read_only = true;
|
||||
|
||||
static lv_style_t h_style;
|
||||
lv_style_copy(&h_style, &lv_style_transp);
|
||||
h_style.body.padding.inner = 0;
|
||||
@@ -747,7 +746,8 @@ static lv_res_t _create_window_usb_tools(lv_obj_t *parent)
|
||||
lv_obj_t *btn_write_access = lv_btn_create(h_write, NULL);
|
||||
nyx_create_onoff_button(lv_theme_get_current(), h_write,
|
||||
btn_write_access, SYMBOL_EDIT" Read-Only", _emmc_read_only_toggle, false);
|
||||
lv_btn_set_state(btn_write_access, LV_BTN_STATE_TGL_REL);
|
||||
if (!n_cfg.ums_emmc_rw)
|
||||
lv_btn_set_state(btn_write_access, LV_BTN_STATE_TGL_REL);
|
||||
_emmc_read_only_toggle(btn_write_access);
|
||||
|
||||
// Create USB Input Devices container.
|
||||
@@ -1649,8 +1649,8 @@ void create_tab_tools(lv_theme_t *th, lv_obj_t *parent)
|
||||
lv_tabview_set_sliding(tv, false);
|
||||
lv_tabview_set_btns_pos(tv, LV_TABVIEW_BTNS_POS_BOTTOM);
|
||||
|
||||
lv_obj_t *tab1= lv_tabview_add_tab(tv, "eMMC "SYMBOL_DOT" Dump Pkg1/2 "SYMBOL_DOT" USB Tools");
|
||||
lv_obj_t *tab2 = lv_tabview_add_tab(tv, "Archive bit "SYMBOL_DOT" AutoRCM "SYMBOL_DOT" Touch Tuning");
|
||||
lv_obj_t *tab1= lv_tabview_add_tab(tv, "eMMC "SYMBOL_DOT" Pkg1/2 "SYMBOL_DOT" USB Tools");
|
||||
lv_obj_t *tab2 = lv_tabview_add_tab(tv, "Arch bit "SYMBOL_DOT" RCM "SYMBOL_DOT" Touch "SYMBOL_DOT" Partitions");
|
||||
|
||||
lv_obj_t *line_sep = lv_line_create(tv, NULL);
|
||||
static const lv_point_t line_pp[] = { {0, 0}, { 0, LV_DPI / 4} };
|
||||
|
||||
@@ -223,6 +223,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
mbr.partitions[mbr_idx].type = 0x83; // Linux system partition.
|
||||
mbr.partitions[mbr_idx].start_sct = 0x8000 + (part_info.hos_size << 11);
|
||||
mbr.partitions[mbr_idx].size_sct = part_info.l4t_size << 11;
|
||||
sdmmc_storage_write(&sd_storage, mbr.partitions[mbr_idx].start_sct, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
mbr_idx++;
|
||||
}
|
||||
|
||||
@@ -301,6 +302,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + (part_info.l4t_size << 11) - 1;
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'l', 0, '4', 0, 't', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
|
||||
curr_part_lba += (part_info.l4t_size << 11);
|
||||
gpt_idx++;
|
||||
@@ -313,6 +315,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x200000 - 1; // 1GB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'v', 0, 'e', 0, 'n', 0, 'd', 0, 'o', 0, 'r', 0 }, 12);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += 0x200000;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -323,6 +326,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x400000 - 1; // 2GB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'A', 0, 'P', 0, 'P', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += 0x400000;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -333,6 +337,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x10000 - 1; // 32MB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'L', 0, 'N', 0, 'X', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += 0x10000;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -343,6 +348,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x20000 - 1; // 64MB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'S', 0, 'O', 0, 'S', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += 0x20000;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -353,6 +359,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x800 - 1; // 1MB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'D', 0, 'T', 0, 'B', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += 0x800;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -363,6 +370,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x8000 - 1; // 16MB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'M', 0, 'D', 0, 'A', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x8000, (void *)SDMMC_UPPER_BUFFER); // Clear 16MB.
|
||||
curr_part_lba += 0x8000;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -373,6 +381,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + 0x15E000 - 1; // 700MB.
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'C', 0, 'A', 0, 'C', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += 0x15E000;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -388,6 +397,7 @@ static void _prepare_and_flash_mbr_gpt()
|
||||
gpt.entries[gpt_idx].lba_start = curr_part_lba;
|
||||
gpt.entries[gpt_idx].lba_end = curr_part_lba + user_size - 1;
|
||||
memcpy(gpt.entries[gpt_idx].name, (char[]) { 'U', 0, 'D', 0, 'A', 0 }, 6);
|
||||
sdmmc_storage_write(&sd_storage, curr_part_lba, 0x800, (void *)SDMMC_UPPER_BUFFER); // Clear the first 1MB.
|
||||
curr_part_lba += user_size;
|
||||
gpt_idx++;
|
||||
|
||||
@@ -1325,12 +1335,14 @@ static lv_res_t _create_mbox_start_partitioning(lv_obj_t *btn)
|
||||
if (f_mkfs("sd:", FM_FAT32, cluster_size, buf, 0x400000))
|
||||
{
|
||||
// Retry.
|
||||
if (f_mkfs("sd:", FM_FAT32, cluster_size, buf, 0x400000))
|
||||
u32 error = f_mkfs("sd:", FM_FAT32, cluster_size, buf, 0x400000);
|
||||
if (error)
|
||||
{
|
||||
// Failed to format.
|
||||
lv_label_set_text(lbl_status,
|
||||
"#FFDD00 Error:# Failed to format disk!\n\n"
|
||||
"Remove the SD card and check that is OK. If not, format it and press any key!");
|
||||
s_printf((char *)buf, "#FFDD00 Error:# Failed to format disk (%d)!\n\n"
|
||||
"Remove the SD card and check that is OK.\nIf not, format it, reinsert it and\npress #FF8000 POWER#!", error);
|
||||
lv_label_set_text(lbl_status, (char *)buf);
|
||||
lv_label_set_text(lbl_paths[0], " ");
|
||||
manual_system_maintenance(true);
|
||||
|
||||
sd_unmount(true);
|
||||
@@ -1569,7 +1581,23 @@ static lv_res_t _action_slider_emu(lv_obj_t *slider)
|
||||
lv_label_set_text(part_info.lbl_emu, lbl_text);
|
||||
}
|
||||
else
|
||||
lv_slider_set_value(slider, 0);
|
||||
{
|
||||
int new_slider_val;
|
||||
switch (part_info.emu_size)
|
||||
{
|
||||
case 29856:
|
||||
new_slider_val = 1;
|
||||
break;
|
||||
case 59712:
|
||||
new_slider_val = 2;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
new_slider_val = 0;
|
||||
break;
|
||||
}
|
||||
lv_slider_set_value(slider, new_slider_val);
|
||||
}
|
||||
|
||||
_update_partition_bar();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/smmu.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../storage/mbr_gpt.h"
|
||||
#include "../storage/nx_emmc.h"
|
||||
#include "../storage/nx_sd.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
@@ -90,15 +91,42 @@ static const u8 master_keyseed_620[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 };
|
||||
|
||||
bool hos_eks_rw_try(u8 *buf, bool write)
|
||||
{
|
||||
mbr_t *mbr = (mbr_t *)buf;
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (!write)
|
||||
{
|
||||
if (sdmmc_storage_read(&sd_storage, 0, 1, mbr))
|
||||
{
|
||||
if (mbr->partitions[0].status != 0xFF &&
|
||||
mbr->partitions[0].start_sct &&
|
||||
mbr->partitions[0].size_sct)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sdmmc_storage_write(&sd_storage, 0, 1, mbr))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void hos_eks_get()
|
||||
{
|
||||
// Check if EKS already found and parsed.
|
||||
if (!h_cfg.eks)
|
||||
{
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
|
||||
// Read EKS blob.
|
||||
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
// Decrypt EKS blob.
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x10);
|
||||
@@ -115,6 +143,7 @@ void hos_eks_get()
|
||||
return;
|
||||
}
|
||||
|
||||
out:
|
||||
free(mbr);
|
||||
}
|
||||
}
|
||||
@@ -128,12 +157,29 @@ void hos_eks_save(u32 kb)
|
||||
if (key_idx > 5)
|
||||
return;
|
||||
|
||||
bool new_eks = false;
|
||||
if (!h_cfg.eks)
|
||||
{
|
||||
h_cfg.eks = calloc(512 , 1);
|
||||
new_eks = true;
|
||||
}
|
||||
|
||||
// If matching blob doesn't exist, create it.
|
||||
if (!(h_cfg.eks->enabled & (1 << key_idx)))
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
{
|
||||
if (new_eks)
|
||||
{
|
||||
free(h_cfg.eks);
|
||||
h_cfg.eks = NULL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Get keys.
|
||||
u8 *keys = (u8 *)calloc(0x1000, 1);
|
||||
se_get_aes_keys(keys + 0x800, keys, 0x10);
|
||||
@@ -151,20 +197,21 @@ void hos_eks_save(u32 kb)
|
||||
memcpy(h_cfg.eks->keys[key_idx].fdk, keys + 13 * 0x10, 0x10);
|
||||
memcpy(h_cfg.eks->keys[key_idx].dkk, keys + 15 * 0x10, 0x10);
|
||||
|
||||
// Encrypt EKS.
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS to SD.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||
// Write EKS blob to SD.
|
||||
memset(mbr, 0, 0x10);
|
||||
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
|
||||
free(eks);
|
||||
free(mbr);
|
||||
free(keys);
|
||||
out:
|
||||
free(mbr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,25 +224,30 @@ void hos_eks_clear(u32 kb)
|
||||
u8 key_idx = kb - KB_FIRMWARE_VERSION_700;
|
||||
if (h_cfg.eks->enabled & (1 << key_idx))
|
||||
{
|
||||
// Read EKS blob.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
if (!hos_eks_rw_try(mbr, false))
|
||||
goto out;
|
||||
|
||||
// Disable current Master key version.
|
||||
h_cfg.eks->enabled &= ~(1 << key_idx);
|
||||
|
||||
// Encrypt EKS.
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = calloc(512 , 1);
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, 1, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS to SD.
|
||||
u8 *mbr = calloc(512 , 1);
|
||||
sdmmc_storage_read(&sd_storage, 0, 1, mbr);
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x10, eks, sizeof(hos_eks_mbr_t));
|
||||
sdmmc_storage_write(&sd_storage, 0, 1, mbr);
|
||||
hos_eks_rw_try(mbr, true);
|
||||
|
||||
free(eks);
|
||||
out:
|
||||
free(mbr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int hos_keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
|
||||
{
|
||||
u8 tmp[0x20];
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct _hos_eks_mbr_t
|
||||
u32 rsvd2[3];
|
||||
} hos_eks_mbr_t;
|
||||
|
||||
static_assert(sizeof(hos_eks_mbr_t) < 424, "HOS EKS storage bigger than MBR!");
|
||||
static_assert(sizeof(hos_eks_mbr_t) == 416, "HOS EKS storage bigger than MBR!");
|
||||
|
||||
typedef struct _launch_ctxt_t
|
||||
{
|
||||
|
||||
@@ -5842,7 +5842,7 @@ FRESULT f_mkfs (
|
||||
UINT len /* Size of working buffer [byte] */
|
||||
)
|
||||
{
|
||||
const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_fats = 2; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */
|
||||
static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */
|
||||
static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */
|
||||
@@ -6130,6 +6130,9 @@ FRESULT f_mkfs (
|
||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ DWORD get_fattime (
|
||||
max77620_rtc_get_time(&time);
|
||||
if (n_cfg.timeoff)
|
||||
{
|
||||
u32 epoch = (u32)((s32)max77620_rtc_date_to_epoch(&time, true) + (s32)n_cfg.timeoff);
|
||||
u32 epoch = (u32)((s32)max77620_rtc_date_to_epoch(&time) + (s32)n_cfg.timeoff);
|
||||
max77620_rtc_epoch_to_date(epoch, &time);
|
||||
}
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
#define USE_LV_BTNM 1
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define USE_LV_KB 1
|
||||
#define USE_LV_KB 0
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define USE_LV_CB 1
|
||||
|
||||
@@ -136,7 +136,7 @@ void *malloc(u32 size)
|
||||
void *calloc(u32 num, u32 size)
|
||||
{
|
||||
void *res = (void *)_heap_alloc(&_heap, num * size);
|
||||
memset(res, 0, num * size);
|
||||
memset(res, 0, ALIGN(num * size, sizeof(hnode_t))); // Clear the aligned size.
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ void heap_monitor(heap_monitor_t *mon, bool print_node_stats)
|
||||
count, node->used, (u32)node + sizeof(hnode_t), node->size);
|
||||
|
||||
count++;
|
||||
|
||||
|
||||
if (node->next)
|
||||
node = node->next;
|
||||
else
|
||||
|
||||
@@ -270,6 +270,8 @@ void load_saved_configuration()
|
||||
n_cfg.home_screen = atoi(kv->val);
|
||||
else if (!strcmp("verification", kv->key))
|
||||
n_cfg.verification = atoi(kv->val);
|
||||
else if (!strcmp("umsemmcrw", kv->key))
|
||||
n_cfg.ums_emmc_rw = atoi(kv->val) == 1;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -361,9 +363,19 @@ void nyx_init_load_res()
|
||||
f_read(&fp, (void *)NYX_RES_ADDR, f_size(&fp), NULL);
|
||||
f_close(&fp);
|
||||
|
||||
icon_switch = bmp_to_lvimg_obj("bootloader/res/icon_switch.bmp");
|
||||
icon_payload = bmp_to_lvimg_obj("bootloader/res/icon_payload.bmp");
|
||||
icon_lakka = bmp_to_lvimg_obj("bootloader/res/icon_lakka.bmp");
|
||||
// If no custom switch icon exists, load normal.
|
||||
if (f_stat("bootloader/res/icon_switch_custom.bmp", NULL))
|
||||
icon_switch = bmp_to_lvimg_obj("bootloader/res/icon_switch.bmp");
|
||||
else
|
||||
icon_switch = bmp_to_lvimg_obj("bootloader/res/icon_switch_custom.bmp");
|
||||
|
||||
// If no custom payload icon exists, load normal.
|
||||
if (f_stat("bootloader/res/icon_payload_custom.bmp", NULL))
|
||||
icon_payload = bmp_to_lvimg_obj("bootloader/res/icon_payload.bmp");
|
||||
else
|
||||
icon_payload = bmp_to_lvimg_obj("bootloader/res/icon_payload_custom.bmp");
|
||||
|
||||
// Load background resource if any.
|
||||
hekate_bg = bmp_to_lvimg_obj("bootloader/res/background.bmp");
|
||||
|
||||
sd_unmount(false);
|
||||
|
||||
@@ -119,7 +119,7 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
|
||||
time->weekday = 0; //! TODO.
|
||||
}
|
||||
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding)
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time)
|
||||
{
|
||||
u32 year, month, epoch;
|
||||
|
||||
@@ -128,39 +128,17 @@ u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding)
|
||||
//Month of year
|
||||
month = time->month;
|
||||
|
||||
if (!hos_encoding)
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
year -= 2000;
|
||||
month++;
|
||||
|
||||
// Month/Year offset.
|
||||
if(month < 3)
|
||||
{
|
||||
month += 9;
|
||||
year--;
|
||||
}
|
||||
else
|
||||
month -= 3;
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
|
||||
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
|
||||
|
||||
if (!hos_encoding)
|
||||
{
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
}
|
||||
else
|
||||
epoch += (30 * month) + ((3 * month + 2) / 5) + 59 + time->day; // Months to days.
|
||||
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
|
||||
epoch -= 719561; // Epoch time is 1/1/1970.
|
||||
|
||||
epoch *= 86400; // Days to seconds.
|
||||
epoch += (3600 * time->hour) + (60 * time->min) + time->sec; // Add hours, minutes and seconds.
|
||||
|
||||
@@ -72,6 +72,6 @@ typedef struct _rtc_time_t {
|
||||
void max77620_rtc_get_time(rtc_time_t *time);
|
||||
void max77620_rtc_stop_alarm();
|
||||
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding);
|
||||
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);
|
||||
|
||||
#endif /* _MFD_MAX77620_RTC_H_ */
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct _mbr_part_t
|
||||
|
||||
typedef struct _mbr_t
|
||||
{
|
||||
u8 bootstrap[0x1B8];
|
||||
u8 bootstrap[440];
|
||||
u32 signature;
|
||||
u16 copy_protected;
|
||||
mbr_part_t partitions[4];
|
||||
|
||||
@@ -1740,6 +1740,25 @@ static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _system_maintainance(usbd_gadget_ums_t *ums)
|
||||
{
|
||||
static u32 timer_dram = 0;
|
||||
static u32 timer_status_bar = 0;
|
||||
|
||||
u32 time = get_tmr_ms();
|
||||
|
||||
if (timer_dram < time)
|
||||
{
|
||||
minerva_periodic_training();
|
||||
timer_dram = get_tmr_ms() + 100;
|
||||
}
|
||||
else if (timer_status_bar < time)
|
||||
{
|
||||
ums->system_maintenance(true);
|
||||
timer_status_bar = get_tmr_ms() + 30000;
|
||||
}
|
||||
}
|
||||
|
||||
int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -1818,7 +1837,8 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
|
||||
do
|
||||
{
|
||||
minerva_periodic_training();
|
||||
// Do DRAM training and update system tasks.
|
||||
_system_maintainance(&ums);
|
||||
|
||||
// Check for force unmount button combo.
|
||||
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
|
||||
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
BIN
nyx/resources/icon_lakka_hue.bmp
Normal file
|
After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |