Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fac8db4238 | ||
|
|
04ac8ebd43 | ||
|
|
1392e6eaf4 | ||
|
|
381d5c9236 | ||
|
|
2f43b20124 |
2
Makefile
2
Makefile
@@ -6,7 +6,7 @@ include $(DEVKITARM)/base_rules
|
|||||||
|
|
||||||
TARGET := hekate
|
TARGET := hekate
|
||||||
BLVERSION_MAJOR := 4
|
BLVERSION_MAJOR := 4
|
||||||
BLVERSION_MINOR := 1
|
BLVERSION_MINOR := 2
|
||||||
BUILD := build
|
BUILD := build
|
||||||
OUTPUT := output
|
OUTPUT := output
|
||||||
SOURCEDIR = bootloader
|
SOURCEDIR = bootloader
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||||
| customlogo=0 | 0: Use default hekate bootlogo, 1: Use bootlogo.bmp. |
|
| customlogo=0 | 0: Use default hekate bootlogo, 1: Use bootlogo.bmp. |
|
||||||
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||||
|
| autohosoff=1 | If woke up from HOS via an rtc alarm, power off completely.|
|
||||||
| backlight=100 | Screen backlight level. 0-255. |
|
| backlight=100 | Screen backlight level. 0-255. |
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
|
|||||||
| secmon={SD path} | Replaces the security monitor binary |
|
| secmon={SD path} | Replaces the security monitor binary |
|
||||||
| kernel={SD path} | Replaces the kernel binary |
|
| kernel={SD path} | Replaces the kernel binary |
|
||||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||||
|
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||||
| kip1patch=patchname| Enables a kip1 patch. Specify with multiple lines and/or as CSV. Implemented patches right now are nosigchk,nogc |
|
| kip1patch=patchname| Enables a kip1 patch. Specify with multiple lines and/or as CSV. Implemented patches right now are nosigchk,nogc |
|
||||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||||
| debugmode=1 | Enables Debug mode |
|
| debugmode=1 | Enables Debug mode |
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ void set_default_configuration()
|
|||||||
h_cfg.se_keygen_done = 0;
|
h_cfg.se_keygen_done = 0;
|
||||||
h_cfg.sbar_time_keeping = 0;
|
h_cfg.sbar_time_keeping = 0;
|
||||||
h_cfg.backlight = 100;
|
h_cfg.backlight = 100;
|
||||||
|
h_cfg.autohosoff = 1;
|
||||||
h_cfg.errors = 0;
|
h_cfg.errors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +102,9 @@ int create_config_entry()
|
|||||||
f_puts("\nbacklight=", &fp);
|
f_puts("\nbacklight=", &fp);
|
||||||
itoa(h_cfg.backlight, lbuf, 10);
|
itoa(h_cfg.backlight, lbuf, 10);
|
||||||
f_puts(lbuf, &fp);
|
f_puts(lbuf, &fp);
|
||||||
|
f_puts("\nautohosoff=", &fp);
|
||||||
|
itoa(h_cfg.autohosoff, lbuf, 10);
|
||||||
|
f_puts(lbuf, &fp);
|
||||||
f_puts("\n", &fp);
|
f_puts("\n", &fp);
|
||||||
|
|
||||||
if (mainIniFound)
|
if (mainIniFound)
|
||||||
@@ -280,7 +284,7 @@ void config_autoboot()
|
|||||||
|
|
||||||
ments[1].type = MENT_CHGLINE;
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
ments[2].type = MENT_CHOICE;
|
ments[2].type = MENT_DATA;
|
||||||
if (!h_cfg.autoboot)
|
if (!h_cfg.autoboot)
|
||||||
ments[2].caption = "*Disable";
|
ments[2].caption = "*Disable";
|
||||||
else
|
else
|
||||||
@@ -395,7 +399,7 @@ void config_bootdelay()
|
|||||||
|
|
||||||
ments[1].type = MENT_CHGLINE;
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
ments[2].type = MENT_CHOICE;
|
ments[2].type = MENT_DATA;
|
||||||
if (h_cfg.bootwait)
|
if (h_cfg.bootwait)
|
||||||
ments[2].caption = " 0 seconds (Bootlogo disabled)";
|
ments[2].caption = " 0 seconds (Bootlogo disabled)";
|
||||||
else
|
else
|
||||||
@@ -412,7 +416,7 @@ void config_bootdelay()
|
|||||||
delay_text[i * 32 + 1] = i + '0';
|
delay_text[i * 32 + 1] = i + '0';
|
||||||
memcpy(delay_text + i * 32 + 2, " seconds", 9);
|
memcpy(delay_text + i * 32 + 2, " seconds", 9);
|
||||||
|
|
||||||
ments[i + 2].type = MENT_CHOICE;
|
ments[i + 2].type = MENT_DATA;
|
||||||
ments[i + 2].caption = delay_text + i * 32;
|
ments[i + 2].caption = delay_text + i * 32;
|
||||||
ments[i + 2].data = &delay_values[i];
|
ments[i + 2].data = &delay_values[i];
|
||||||
}
|
}
|
||||||
@@ -455,7 +459,7 @@ void config_customlogo()
|
|||||||
for (u32 j = 0; j < 2; j++)
|
for (u32 j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
cb_values[j] = j;
|
cb_values[j] = j;
|
||||||
ments[j + 2].type = MENT_CHOICE;
|
ments[j + 2].type = MENT_DATA;
|
||||||
ments[j + 2].data = &cb_values[j];
|
ments[j + 2].data = &cb_values[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +518,7 @@ void config_verification()
|
|||||||
for (u32 j = 0; j < 3; j++)
|
for (u32 j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
vr_values[j] = j;
|
vr_values[j] = j;
|
||||||
ments[j + 2].type = MENT_CHOICE;
|
ments[j + 2].type = MENT_DATA;
|
||||||
ments[j + 2].data = &vr_values[j];
|
ments[j + 2].data = &vr_values[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,7 +608,7 @@ void config_backlight()
|
|||||||
else
|
else
|
||||||
memcpy(bri_text + i * 32 + 1, "100%", 5);
|
memcpy(bri_text + i * 32 + 1, "100%", 5);
|
||||||
|
|
||||||
ments[i + 1].type = MENT_CHOICE;
|
ments[i + 1].type = MENT_DATA;
|
||||||
ments[i + 1].caption = bri_text + i * 32;
|
ments[i + 1].caption = bri_text + i * 32;
|
||||||
ments[i + 1].data = &bri_values[i];
|
ments[i + 1].data = &bri_values[i];
|
||||||
}
|
}
|
||||||
@@ -635,3 +639,61 @@ void config_backlight()
|
|||||||
return;
|
return;
|
||||||
btn_wait();
|
btn_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void config_auto_hos_poweroff()
|
||||||
|
{
|
||||||
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 5);
|
||||||
|
u32 *hp_values = (u32 *)malloc(sizeof(u32) * 2);
|
||||||
|
|
||||||
|
for (u32 j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
hp_values[j] = j;
|
||||||
|
ments[j + 2].type = MENT_DATA;
|
||||||
|
ments[j + 2].data = &hp_values[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
ments[0].type = MENT_BACK;
|
||||||
|
ments[0].caption = "Back";
|
||||||
|
|
||||||
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
|
if (h_cfg.autohosoff)
|
||||||
|
{
|
||||||
|
ments[2].caption = " Disable";
|
||||||
|
ments[3].caption = "*Enable";
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ments[2].caption = "*Disable";
|
||||||
|
ments[3].caption = " Enable";
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ments[4], 0, sizeof(ment_t));
|
||||||
|
menu_t menu = {ments, "Power off if woke up from HOS", 0, 0};
|
||||||
|
|
||||||
|
u32 *temp_autohosoff = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||||
|
if (temp_autohosoff != NULL)
|
||||||
|
{
|
||||||
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
h_cfg.autohosoff = *(u32 *)temp_autohosoff;
|
||||||
|
// Save choice to ini file.
|
||||||
|
if (!create_config_entry())
|
||||||
|
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||||
|
else
|
||||||
|
EPRINTF("\nConfiguration saving failed!");
|
||||||
|
gfx_puts(&gfx_con, "\nPress any key...");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ments);
|
||||||
|
free(hp_values);
|
||||||
|
|
||||||
|
if (temp_autohosoff == NULL)
|
||||||
|
return;
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,16 +21,18 @@
|
|||||||
|
|
||||||
typedef struct _hekate_config
|
typedef struct _hekate_config
|
||||||
{
|
{
|
||||||
|
// Non-volatile config.
|
||||||
u32 autoboot;
|
u32 autoboot;
|
||||||
u32 autoboot_list;
|
u32 autoboot_list;
|
||||||
u32 bootwait;
|
u32 bootwait;
|
||||||
u32 customlogo;
|
u32 customlogo;
|
||||||
u32 verification;
|
u32 verification;
|
||||||
|
u32 backlight;
|
||||||
|
u32 autohosoff;
|
||||||
|
u32 errors;
|
||||||
// Global temporary config.
|
// Global temporary config.
|
||||||
int se_keygen_done;
|
int se_keygen_done;
|
||||||
u32 sbar_time_keeping;
|
u32 sbar_time_keeping;
|
||||||
u32 backlight;
|
|
||||||
u32 errors;
|
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@@ -45,5 +47,6 @@ void config_bootdelay();
|
|||||||
void config_customlogo();
|
void config_customlogo();
|
||||||
void config_verification();
|
void config_verification();
|
||||||
void config_backlight();
|
void config_backlight();
|
||||||
|
void config_auto_hos_poweroff();
|
||||||
|
|
||||||
#endif /* _CONFIG_H_ */
|
#endif /* _CONFIG_H_ */
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||||||
|
|
||||||
if (is_dir)
|
if (is_dir)
|
||||||
{
|
{
|
||||||
filelist = dirlist(filename);
|
filelist = dirlist(filename, "*.ini");
|
||||||
if (!filelist)
|
if (!filelist)
|
||||||
{
|
{
|
||||||
free(filename);
|
free(filename);
|
||||||
|
|||||||
@@ -177,11 +177,17 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
|
|||||||
if (btn & BTN_VOL_DOWN && idx < (cnt - 1))
|
if (btn & BTN_VOL_DOWN && idx < (cnt - 1))
|
||||||
idx++;
|
idx++;
|
||||||
else if (btn & BTN_VOL_DOWN && idx == (cnt - 1))
|
else if (btn & BTN_VOL_DOWN && idx == (cnt - 1))
|
||||||
|
{
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
prev_idx = -1;
|
||||||
|
}
|
||||||
if (btn & BTN_VOL_UP && idx > 0)
|
if (btn & BTN_VOL_UP && idx > 0)
|
||||||
idx--;
|
idx--;
|
||||||
else if (btn & BTN_VOL_UP && idx == 0)
|
else if (btn & BTN_VOL_UP && idx == 0)
|
||||||
|
{
|
||||||
idx = cnt - 1;
|
idx = cnt - 1;
|
||||||
|
prev_idx = cnt;
|
||||||
|
}
|
||||||
if (btn & BTN_POWER)
|
if (btn & BTN_POWER)
|
||||||
{
|
{
|
||||||
ment_t *ent = &menu->ents[idx];
|
ment_t *ent = &menu->ents[idx];
|
||||||
@@ -193,7 +199,7 @@ void *tui_do_menu(gfx_con_t *con, menu_t *menu)
|
|||||||
case MENT_MENU:
|
case MENT_MENU:
|
||||||
return tui_do_menu(con, ent->menu);
|
return tui_do_menu(con, ent->menu);
|
||||||
break;
|
break;
|
||||||
case MENT_CHOICE:
|
case MENT_DATA:
|
||||||
return ent->data;
|
return ent->data;
|
||||||
break;
|
break;
|
||||||
case MENT_BACK:
|
case MENT_BACK:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#define MENT_END 0
|
#define MENT_END 0
|
||||||
#define MENT_HANDLER 1
|
#define MENT_HANDLER 1
|
||||||
#define MENT_MENU 2
|
#define MENT_MENU 2
|
||||||
#define MENT_CHOICE 3
|
#define MENT_DATA 3
|
||||||
#define MENT_BACK 4
|
#define MENT_BACK 4
|
||||||
#define MENT_CAPTION 5
|
#define MENT_CAPTION 5
|
||||||
#define MENT_CHGLINE 6
|
#define MENT_CHGLINE 6
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include "../mem/mc.h"
|
#include "../mem/mc.h"
|
||||||
#include "../soc/fuse.h"
|
#include "../soc/fuse.h"
|
||||||
|
#include "../utils/dirlist.h"
|
||||||
|
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
extern gfx_ctxt_t gfx_ctxt;
|
extern gfx_ctxt_t gfx_ctxt;
|
||||||
@@ -149,6 +150,36 @@ static void _se_lock()
|
|||||||
gfx_hexdump(&gfx_con, SE_BASE, (void *)SE_BASE, 0x400);*/
|
gfx_hexdump(&gfx_con, SE_BASE, (void *)SE_BASE, 0x400);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _pmc_scratch_lock(u32 kb)
|
||||||
|
{
|
||||||
|
switch (kb)
|
||||||
|
{
|
||||||
|
case KB_FIRMWARE_VERSION_100_200:
|
||||||
|
case KB_FIRMWARE_VERSION_300:
|
||||||
|
case KB_FIRMWARE_VERSION_301:
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE) = 0x7FFFF3;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE2) = 0xFFFFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE3) = 0xFFAFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE4) = 0xFFFFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE6) = 0xFFFFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE7) = 0xFFFFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE8) = 0xFFAAFFFF;
|
||||||
|
break;
|
||||||
|
case KB_FIRMWARE_VERSION_400:
|
||||||
|
case KB_FIRMWARE_VERSION_500:
|
||||||
|
case KB_FIRMWARE_VERSION_600:
|
||||||
|
default:
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE6) |= 0xF3FFC00F;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE7) |= 0x3FFFFF;
|
||||||
|
PMC(APBDEV_PMC_SEC_DISABLE8) |= 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
|
int keygen(u8 *keyblob, u32 kb, void *tsec_fw)
|
||||||
{
|
{
|
||||||
u8 tmp[0x10];
|
u8 tmp[0x10];
|
||||||
@@ -337,14 +368,61 @@ static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
|
|||||||
static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
if (f_open(&fp, value, FA_READ) != FR_OK)
|
|
||||||
return 0;
|
if (!memcmp(value + strlen(value) - 1, "*", 1))
|
||||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
{
|
||||||
mkip1->kip1 = malloc(f_size(&fp));
|
char *dir = (char *)malloc(256);
|
||||||
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
|
memcpy(dir, value, strlen(value) + 1);
|
||||||
DPRINTF("Loaded kip1 from SD (size %08X)\n", f_size(&fp));
|
|
||||||
f_close(&fp);
|
u32 dirlen = 0;
|
||||||
list_append(&ctxt->kip1_list, &mkip1->link);
|
dir[strlen(dir) - 2] = 0;
|
||||||
|
char *filelist = dirlist(dir, "*.kip*");
|
||||||
|
|
||||||
|
memcpy(dir + strlen(dir), "/", 2);
|
||||||
|
dirlen = strlen(dir);
|
||||||
|
|
||||||
|
u32 i = 0;
|
||||||
|
if (filelist)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!filelist[i * 256])
|
||||||
|
break;
|
||||||
|
|
||||||
|
memcpy(dir + dirlen, &filelist[i * 256], strlen(&filelist[i * 256]) + 1);
|
||||||
|
if (f_open(&fp, dir, FA_READ))
|
||||||
|
{
|
||||||
|
free(dir);
|
||||||
|
free(filelist);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||||
|
mkip1->kip1 = malloc(f_size(&fp));
|
||||||
|
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
|
||||||
|
DPRINTF("Loaded kip1 from SD (size %08X)\n", f_size(&fp));
|
||||||
|
f_close(&fp);
|
||||||
|
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dir);
|
||||||
|
free(filelist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (f_open(&fp, value, FA_READ))
|
||||||
|
return 0;
|
||||||
|
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||||
|
mkip1->kip1 = malloc(f_size(&fp));
|
||||||
|
f_read(&fp, mkip1->kip1, f_size(&fp), NULL);
|
||||||
|
DPRINTF("Loaded kip1 from SD (size %08X)\n", f_size(&fp));
|
||||||
|
f_close(&fp);
|
||||||
|
list_append(&ctxt->kip1_list, &mkip1->link);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,9 +682,9 @@ int hos_launch(ini_sec_t *cfg)
|
|||||||
case KB_FIRMWARE_VERSION_300:
|
case KB_FIRMWARE_VERSION_300:
|
||||||
case KB_FIRMWARE_VERSION_301:
|
case KB_FIRMWARE_VERSION_301:
|
||||||
if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_300)
|
if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_300)
|
||||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 security check.
|
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id.
|
||||||
else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
|
else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301)
|
||||||
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 security check.
|
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id.
|
||||||
se_key_acc_ctrl(12, 0xFF);
|
se_key_acc_ctrl(12, 0xFF);
|
||||||
se_key_acc_ctrl(13, 0xFF);
|
se_key_acc_ctrl(13, 0xFF);
|
||||||
bootStateDramPkg2 = 2;
|
bootStateDramPkg2 = 2;
|
||||||
@@ -664,6 +742,9 @@ int hos_launch(ini_sec_t *cfg)
|
|||||||
mc_config_carveout_finalize();
|
mc_config_carveout_finalize();
|
||||||
_se_lock();
|
_se_lock();
|
||||||
|
|
||||||
|
//TODO: pkg1.1 locks PMC scratches, we can do that too at some point. For <4.0.0 after secmon?
|
||||||
|
//_pmc_scratch_lock(ctxt.pkg1_id->kb);
|
||||||
|
|
||||||
// < 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 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 ready, 4: pkg2 ready and continue boot.
|
||||||
vu32 *mb_in = (vu32 *)0x40002EF8;
|
vu32 *mb_in = (vu32 *)0x40002EF8;
|
||||||
@@ -682,16 +763,6 @@ int hos_launch(ini_sec_t *cfg)
|
|||||||
while (!*mb_out)
|
while (!*mb_out)
|
||||||
usleep(1); // This only works when in IRAM or with a trained DRAM.
|
usleep(1); // This only works when in IRAM or with a trained DRAM.
|
||||||
|
|
||||||
//TODO: pkg1.1 locks PMC scratches, we can do that too at some point.
|
|
||||||
/*PMC(0x4) = 0x7FFFF3;
|
|
||||||
PMC(0x2C4) = 0xFFFFFFFF;
|
|
||||||
PMC(0x2D8) = 0xFFAFFFFF;
|
|
||||||
PMC(0x5B0) = 0xFFFFFFFF;
|
|
||||||
PMC(0x5B4) = 0xFFFFFFFF;
|
|
||||||
PMC(0x5B8) = 0xFFFFFFFF;
|
|
||||||
PMC(0x5BC) = 0xFFFFFFFF;
|
|
||||||
PMC(0x5C0) = 0xFFAAFFFF;*/
|
|
||||||
|
|
||||||
// Signal pkg2 ready and continue boot.
|
// Signal pkg2 ready and continue boot.
|
||||||
*mb_in = bootStatePkg2Continue;
|
*mb_in = bootStatePkg2Continue;
|
||||||
|
|
||||||
|
|||||||
@@ -57,18 +57,18 @@ PATCHSET_DEF(_secmon_4_patchset,
|
|||||||
|
|
||||||
PATCHSET_DEF(_secmon_5_patchset,
|
PATCHSET_DEF(_secmon_5_patchset,
|
||||||
// Patch package2 decryption and signature/hash checks.
|
// Patch package2 decryption and signature/hash checks.
|
||||||
{ 0xDA8 + 0x9D8 , _NOP() }, //package2 structure.
|
{ 0xDA8 + 0x9D8, _NOP() }, //package2 structure.
|
||||||
{ 0xDA8 + 0x9E4 , _NOP() }, //Version.
|
{ 0xDA8 + 0x9E4, _NOP() }, //Version.
|
||||||
{ 0xDA8 + 0xC9C , _NOP() }, //Header signature.
|
{ 0xDA8 + 0xC9C, _NOP() }, //Header signature.
|
||||||
{ 0xDA8 + 0x1038 , _NOP() } //Sections SHA2.
|
{ 0xDA8 + 0x1038, _NOP() } //Sections SHA2.
|
||||||
);
|
);
|
||||||
|
|
||||||
PATCHSET_DEF(_secmon_6_patchset,
|
PATCHSET_DEF(_secmon_6_patchset,
|
||||||
// Patch package2 decryption and signature/hash checks.
|
// Patch package2 decryption and signature/hash checks.
|
||||||
{ 0xDC8 + 0x820 , _NOP() }, //package2 structure.
|
{ 0xDC8 + 0x820, _NOP() }, //package2 structure.
|
||||||
{ 0xDC8 + 0x82C , _NOP() }, //Version.
|
{ 0xDC8 + 0x82C, _NOP() }, //Version.
|
||||||
{ 0xDC8 + 0xE90 , _NOP() }, //Header signature.
|
{ 0xDC8 + 0xE90, _NOP() }, //Header signature.
|
||||||
{ 0xDC8 + 0x112C , _NOP() } //Sections SHA2.
|
{ 0xDC8 + 0x112C, _NOP() } //Sections SHA2.
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
/ 2: Enable with LF-CRLF conversion. */
|
/ 2: Enable with LF-CRLF conversion. */
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_FIND 0
|
#define FF_USE_FIND 1
|
||||||
/* This option switches filtered directory read functions, f_findfirst() and
|
/* This option switches filtered directory read functions, f_findfirst() and
|
||||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||||
|
|
||||||
|
|||||||
@@ -259,15 +259,18 @@ void check_power_off_from_hos()
|
|||||||
u8 hosWakeup = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_IRQTOP);
|
u8 hosWakeup = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_IRQTOP);
|
||||||
if (hosWakeup & MAX77620_IRQ_TOP_RTC_MASK)
|
if (hosWakeup & MAX77620_IRQ_TOP_RTC_MASK)
|
||||||
{
|
{
|
||||||
|
sd_unmount();
|
||||||
|
|
||||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
u8 *BOOTLOGO = (void *)malloc(0x4000);
|
u8 *BOOTLOGO = (void *)malloc(0x4000);
|
||||||
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
blz_uncompress_srcdest(BOOTLOGO_BLZ, SZ_BOOTLOGO_BLZ, BOOTLOGO, SZ_BOOTLOGO);
|
||||||
gfx_set_rect_grey(&gfx_ctxt, BOOTLOGO, X_BOOTLOGO, Y_BOOTLOGO, 326, 544);
|
gfx_set_rect_grey(&gfx_ctxt, BOOTLOGO, X_BOOTLOGO, Y_BOOTLOGO, 326, 544);
|
||||||
usleep(2000000);
|
|
||||||
display_backlight_brightness(10, 5000);
|
display_backlight_brightness(10, 5000);
|
||||||
display_backlight_brightness(100, 25000);
|
display_backlight_brightness(100, 25000);
|
||||||
usleep(600000);
|
usleep(600000);
|
||||||
display_backlight_brightness(0, 20000);
|
display_backlight_brightness(0, 20000);
|
||||||
|
|
||||||
power_off();
|
power_off();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,6 +460,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
|||||||
|
|
||||||
if (extra_reconfig)
|
if (extra_reconfig)
|
||||||
{
|
{
|
||||||
|
msleep(10);
|
||||||
PMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);
|
PMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);
|
||||||
|
|
||||||
clock_disable_cl_dvfs();
|
clock_disable_cl_dvfs();
|
||||||
@@ -476,8 +480,9 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
|
|||||||
{
|
{
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) |= (1 << 22);
|
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) |= (1 << 22);
|
||||||
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0);
|
sdmmc_init(&sd_sdmmc, SDMMC_1, SDMMC_POWER_3_3, SDMMC_BUS_WIDTH_1, 5, 0);
|
||||||
|
clock_disable_cl_dvfs();
|
||||||
|
|
||||||
msleep(500);
|
msleep(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,6 +840,7 @@ out:
|
|||||||
int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part)
|
int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFilename, emmc_part_t *part)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
|
u32 btn = 0;
|
||||||
u32 prevPct = 200;
|
u32 prevPct = 200;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
@@ -893,7 +899,7 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFilename,
|
|||||||
default:
|
default:
|
||||||
se_calc_sha256(&hashEm, bufEm, num << 9);
|
se_calc_sha256(&hashEm, bufEm, num << 9);
|
||||||
se_calc_sha256(&hashSd, bufSd, num << 9);
|
se_calc_sha256(&hashSd, bufSd, num << 9);
|
||||||
res = memcmp(hashEm, hashSd, 0x20);
|
res = memcmp(hashEm, hashSd, 0x10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
@@ -916,6 +922,21 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char *outFilename,
|
|||||||
|
|
||||||
lba_curr += num;
|
lba_curr += num;
|
||||||
totalSectorsVer -= num;
|
totalSectorsVer -= num;
|
||||||
|
|
||||||
|
btn = btn_wait_timeout(0, BTN_VOL_DOWN | BTN_VOL_UP);
|
||||||
|
if ((btn & BTN_VOL_DOWN) && (btn & BTN_VOL_UP))
|
||||||
|
{
|
||||||
|
gfx_con.fntsz = 16;
|
||||||
|
WPRINTF("\n\nThe verification was cancelled!");
|
||||||
|
EPRINTF("\nPress any key...\n");
|
||||||
|
msleep(1500);
|
||||||
|
|
||||||
|
free(bufEm);
|
||||||
|
free(bufSd);
|
||||||
|
f_close(&fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(bufEm);
|
free(bufEm);
|
||||||
free(bufSd);
|
free(bufSd);
|
||||||
@@ -1236,7 +1257,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part)
|
|||||||
{
|
{
|
||||||
gfx_con.fntsz = 16;
|
gfx_con.fntsz = 16;
|
||||||
WPRINTF("\n\nThe backup was cancelled!");
|
WPRINTF("\n\nThe backup was cancelled!");
|
||||||
EPRINTF("\nPress any key and try again...\n");
|
EPRINTF("\nPress any key...\n");
|
||||||
msleep(1500);
|
msleep(1500);
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
@@ -1891,7 +1912,11 @@ int launch_payload(char *path, bool update)
|
|||||||
*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR = BOOTLOADER_UPDATED_MAGIC;
|
*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR = BOOTLOADER_UPDATED_MAGIC;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
free(update_ft);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
free(update_ft);
|
free(update_ft);
|
||||||
}
|
}
|
||||||
sd_unmount();
|
sd_unmount();
|
||||||
@@ -1959,7 +1984,7 @@ void launch_tools(u8 type)
|
|||||||
else
|
else
|
||||||
memcpy(dir, "bootloader/libtools", 20);
|
memcpy(dir, "bootloader/libtools", 20);
|
||||||
|
|
||||||
filelist = dirlist(dir);
|
filelist = dirlist(dir, NULL);
|
||||||
|
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
|
|
||||||
@@ -2317,6 +2342,8 @@ void auto_launch_firmware()
|
|||||||
h_cfg.verification = atoi(kv->val);
|
h_cfg.verification = atoi(kv->val);
|
||||||
else if (!strcmp("backlight", kv->key))
|
else if (!strcmp("backlight", kv->key))
|
||||||
h_cfg.backlight = atoi(kv->val);
|
h_cfg.backlight = atoi(kv->val);
|
||||||
|
else if (!strcmp("autohosoff", kv->key))
|
||||||
|
h_cfg.autohosoff = atoi(kv->val);
|
||||||
}
|
}
|
||||||
boot_entry_id++;
|
boot_entry_id++;
|
||||||
continue;
|
continue;
|
||||||
@@ -2337,6 +2364,9 @@ void auto_launch_firmware()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (h_cfg.autohosoff)
|
||||||
|
check_power_off_from_hos();
|
||||||
|
|
||||||
if (h_cfg.autoboot_list)
|
if (h_cfg.autoboot_list)
|
||||||
{
|
{
|
||||||
ini_free(&ini_sections);
|
ini_free(&ini_sections);
|
||||||
@@ -2503,6 +2533,8 @@ void toggle_autorcm(bool enable)
|
|||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
|
|
||||||
|
u8 randomXor = 0;
|
||||||
|
|
||||||
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
|
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
|
||||||
gfx_con_setpos(&gfx_con, 0, 0);
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
@@ -2520,8 +2552,16 @@ void toggle_autorcm(bool enable)
|
|||||||
{
|
{
|
||||||
sect = (0x200 + (0x4000 * i)) / NX_EMMC_BLOCKSIZE;
|
sect = (0x200 + (0x4000 * i)) / NX_EMMC_BLOCKSIZE;
|
||||||
sdmmc_storage_read(&storage, sect, 1, tempbuf);
|
sdmmc_storage_read(&storage, sect, 1, tempbuf);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
tempbuf[0x10] ^= get_tmr_us() & 0xFF; // Bricmii style of bricking.
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
randomXor = get_tmr_us() & 0xFF; // Bricmii style of bricking.
|
||||||
|
} while (!randomXor); // Avoid the lottery.
|
||||||
|
|
||||||
|
tempbuf[0x10] ^= randomXor;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
tempbuf[0x10] = 0xF7;
|
tempbuf[0x10] = 0xF7;
|
||||||
sdmmc_storage_write(&storage, sect, 1, tempbuf);
|
sdmmc_storage_write(&storage, sect, 1, tempbuf);
|
||||||
@@ -3003,6 +3043,8 @@ void bootrom_ipatches_info()
|
|||||||
{
|
{
|
||||||
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
|
gfx_clear_partial_grey(&gfx_ctxt, 0x1B, 0, 1256);
|
||||||
gfx_con_setpos(&gfx_con, 0, 0);
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
static const u32 BOOTROM_SIZE = 0x18000;
|
||||||
|
|
||||||
u32 res = fuse_read_ipatch(ipatch_process);
|
u32 res = fuse_read_ipatch(ipatch_process);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
@@ -3114,6 +3156,7 @@ ment_t ment_options[] = {
|
|||||||
MDEF_HANDLER("Auto boot", config_autoboot),
|
MDEF_HANDLER("Auto boot", config_autoboot),
|
||||||
MDEF_HANDLER("Boot time delay", config_bootdelay),
|
MDEF_HANDLER("Boot time delay", config_bootdelay),
|
||||||
MDEF_HANDLER("Custom boot logo", config_customlogo),
|
MDEF_HANDLER("Custom boot logo", config_customlogo),
|
||||||
|
MDEF_HANDLER("Auto HOS power off", config_auto_hos_poweroff),
|
||||||
MDEF_HANDLER("Backlight", config_backlight),
|
MDEF_HANDLER("Backlight", config_backlight),
|
||||||
MDEF_END()
|
MDEF_END()
|
||||||
};
|
};
|
||||||
@@ -3222,7 +3265,7 @@ ment_t ment_top[] = {
|
|||||||
};
|
};
|
||||||
menu_t menu_top = {
|
menu_t menu_top = {
|
||||||
ment_top,
|
ment_top,
|
||||||
"hekate - CTCaer mod v4.1", 0, 0
|
"hekate - CTCaer mod v4.2", 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void pivot_stack(u32 stack_top);
|
extern void pivot_stack(u32 stack_top);
|
||||||
@@ -3264,8 +3307,6 @@ void ipl_main()
|
|||||||
display_backlight_pwm_init();
|
display_backlight_pwm_init();
|
||||||
//display_backlight_brightness(h_cfg.backlight, 1000);
|
//display_backlight_brightness(h_cfg.backlight, 1000);
|
||||||
|
|
||||||
check_power_off_from_hos();
|
|
||||||
|
|
||||||
// Load saved configuration and auto boot if enabled.
|
// Load saved configuration and auto boot if enabled.
|
||||||
auto_launch_firmware();
|
auto_launch_firmware();
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#define _PMC_H_
|
#define _PMC_H_
|
||||||
|
|
||||||
/*! PMC registers. */
|
/*! PMC registers. */
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE 0x4
|
||||||
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
#define APBDEV_PMC_PWRGATE_TOGGLE 0x30
|
||||||
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
#define APBDEV_PMC_PWRGATE_STATUS 0x38
|
||||||
#define APBDEV_PMC_NO_IOPOWER 0x44
|
#define APBDEV_PMC_NO_IOPOWER 0x44
|
||||||
@@ -35,8 +36,10 @@
|
|||||||
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
#define APBDEV_PMC_VDDP_SEL 0x1CC
|
||||||
#define APBDEV_PMC_SCRATCH49 0x244
|
#define APBDEV_PMC_SCRATCH49 0x244
|
||||||
#define APBDEV_PMC_TSC_MULT 0x2B4
|
#define APBDEV_PMC_TSC_MULT 0x2B4
|
||||||
#define APBDEV_PMC_REG_SHORT 0x2CC
|
#define APBDEV_PMC_SEC_DISABLE2 0x2C4
|
||||||
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
#define APBDEV_PMC_WEAK_BIAS 0x2C8
|
||||||
|
#define APBDEV_PMC_REG_SHORT 0x2CC
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE3 0x2D8
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
#define APBDEV_PMC_SECURE_SCRATCH21 0x334
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
#define APBDEV_PMC_SECURE_SCRATCH32 0x360
|
||||||
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
#define APBDEV_PMC_SECURE_SCRATCH49 0x3A4
|
||||||
@@ -45,6 +48,11 @@
|
|||||||
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
#define APBDEV_PMC_UTMIP_PAD_CFG1 0x4C4
|
||||||
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
#define APBDEV_PMC_UTMIP_PAD_CFG3 0x4CC
|
||||||
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
#define APBDEV_PMC_DDR_CNTRL 0x4E4
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE4 0x5B0
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE5 0x5B4
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE6 0x5B8
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE7 0x5BC
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE8 0x5C0
|
||||||
#define APBDEV_PMC_SCRATCH188 0x810
|
#define APBDEV_PMC_SCRATCH188 0x810
|
||||||
#define APBDEV_PMC_SCRATCH190 0x818
|
#define APBDEV_PMC_SCRATCH190 0x818
|
||||||
#define APBDEV_PMC_SCRATCH200 0x840
|
#define APBDEV_PMC_SCRATCH200 0x840
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
#define BOOTROM_SIZE 0x18000
|
|
||||||
#define BOOTROM_BASE 0x100000
|
#define BOOTROM_BASE 0x100000
|
||||||
#define HOST1X_BASE 0x50000000
|
#define HOST1X_BASE 0x50000000
|
||||||
#define BPMP_CACHE_BASE 0x50040000
|
#define BPMP_CACHE_BASE 0x50040000
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
char *dirlist(char *directory)
|
char *dirlist(const char *directory, const char *pattern)
|
||||||
{
|
{
|
||||||
u8 max_entries = 61;
|
u8 max_entries = 61;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ char *dirlist(char *directory)
|
|||||||
char *dir_entries = (char *)calloc(max_entries, 256);
|
char *dir_entries = (char *)calloc(max_entries, 256);
|
||||||
char *temp = (char *)calloc(1, 256);
|
char *temp = (char *)calloc(1, 256);
|
||||||
|
|
||||||
if (!f_opendir(&dir, directory))
|
if (!pattern && !f_opendir(&dir, directory))
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -47,22 +47,30 @@ char *dirlist(char *directory)
|
|||||||
if (k > (max_entries - 1))
|
if (k > (max_entries - 1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
f_closedir(&dir);
|
f_closedir(&dir);
|
||||||
|
|
||||||
if (!k)
|
|
||||||
{
|
|
||||||
free(temp);
|
|
||||||
free(dir_entries);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else if (pattern && !f_findfirst(&dir, &fno, directory, pattern) && fno.fname[0])
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!(fno.fattrib & AM_DIR))
|
||||||
|
{
|
||||||
|
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
||||||
|
k++;
|
||||||
|
if (k > (max_entries - 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res = f_findnext(&dir, &fno);
|
||||||
|
} while (fno.fname[0] && !res);
|
||||||
|
f_closedir(&dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!k)
|
||||||
{
|
{
|
||||||
free(temp);
|
free(temp);
|
||||||
free(dir_entries);
|
free(dir_entries);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,4 +16,4 @@
|
|||||||
|
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
char *dirlist(char *directory);
|
char *dirlist(const char *directory, const char *pattern);
|
||||||
|
|||||||
Reference in New Issue
Block a user