Add support for reading boot files from FAT partition on BOOT1/GPP/SD in that order
Emummc config is read from boot partition, file based files still read from SD
This commit is contained in:
2
Makefile
2
Makefile
@@ -37,7 +37,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||||||
fuse.o kfuse.o \
|
fuse.o kfuse.o \
|
||||||
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o \
|
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o \
|
||||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||||
hw_init.o \
|
hw_init.o boot_storage.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
# Utilities.
|
# Utilities.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
static u16 emmc_errors[3] = { 0 }; // Init and Read/Write errors.
|
static u16 emmc_errors[3] = { 0 }; // Init and Read/Write errors.
|
||||||
static u32 emmc_mode = EMMC_MMC_HS400;
|
static u32 emmc_mode = EMMC_MMC_HS400;
|
||||||
|
static bool emmc_init_done = false;
|
||||||
|
|
||||||
sdmmc_t emmc_sdmmc;
|
sdmmc_t emmc_sdmmc;
|
||||||
sdmmc_storage_t emmc_storage;
|
sdmmc_storage_t emmc_storage;
|
||||||
@@ -61,7 +62,18 @@ u32 emmc_get_mode()
|
|||||||
return emmc_mode;
|
return emmc_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emmc_end() { sdmmc_storage_end(&emmc_storage); }
|
static void _emmc_deinit(){
|
||||||
|
if(emmc_init_done){
|
||||||
|
sdmmc_storage_end(&emmc_storage);
|
||||||
|
emmc_init_done = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void emmc_end() { _emmc_deinit(); }
|
||||||
|
|
||||||
|
bool emmc_get_initialized(){
|
||||||
|
return emmc_init_done;
|
||||||
|
}
|
||||||
|
|
||||||
int emmc_init_retry(bool power_cycle)
|
int emmc_init_retry(bool power_cycle)
|
||||||
{
|
{
|
||||||
@@ -97,7 +109,13 @@ int emmc_init_retry(bool power_cycle)
|
|||||||
emmc_mode = EMMC_MMC_HS400;
|
emmc_mode = EMMC_MMC_HS400;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type);
|
int res = sdmmc_storage_init_mmc(&emmc_storage, &emmc_sdmmc, bus_width, type);
|
||||||
|
if(res){
|
||||||
|
emmc_init_done = true;
|
||||||
|
}else{
|
||||||
|
emmc_init_done = false;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emmc_initialize(bool power_cycle)
|
bool emmc_initialize(bool power_cycle)
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ int emmc_init_retry(bool power_cycle);
|
|||||||
bool emmc_initialize(bool power_cycle);
|
bool emmc_initialize(bool power_cycle);
|
||||||
int emmc_set_partition(u32 partition);
|
int emmc_set_partition(u32 partition);
|
||||||
void emmc_end();
|
void emmc_end();
|
||||||
|
bool emmc_get_initialized();
|
||||||
|
|
||||||
void emmc_gpt_parse(link_t *gpt);
|
void emmc_gpt_parse(link_t *gpt);
|
||||||
void emmc_gpt_free(link_t *gpt);
|
void emmc_gpt_free(link_t *gpt);
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ bool sd_mount()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!sd_mounted)
|
if (!sd_mounted)
|
||||||
res = f_mount(&sd_fs, "0:", 1); // Volume 0 is SD.
|
res = f_mount(&sd_fs, XSTR(FF_DEV_SD) ":", 1); // Volume 0 is SD.
|
||||||
if (res == FR_OK)
|
if (res == FR_OK)
|
||||||
{
|
{
|
||||||
sd_mounted = true;
|
sd_mounted = true;
|
||||||
@@ -227,7 +227,7 @@ static void _sd_deinit(bool deinit)
|
|||||||
if (sd_init_done)
|
if (sd_init_done)
|
||||||
{
|
{
|
||||||
if (sd_mounted)
|
if (sd_mounted)
|
||||||
f_mount(NULL, "0:", 1); // Volume 0 is SD.
|
f_mount(NULL, XSTR(FF_DEV_SD) ":", 1); // Volume 0 is SD.
|
||||||
|
|
||||||
if (deinit)
|
if (deinit)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ typedef unsigned long uptr;
|
|||||||
#define likely(x) (__builtin_expect((x) != 0, 1))
|
#define likely(x) (__builtin_expect((x) != 0, 1))
|
||||||
#define unlikely(x) (__builtin_expect((x) != 0, 0))
|
#define unlikely(x) (__builtin_expect((x) != 0, 0))
|
||||||
|
|
||||||
|
#define XSTR(a) STR(a)
|
||||||
|
#define STR(a) #a
|
||||||
|
|
||||||
/* Bootloader/Nyx */
|
/* Bootloader/Nyx */
|
||||||
#define BOOT_CFG_AUTOBOOT_EN BIT(0)
|
#define BOOT_CFG_AUTOBOOT_EN BIT(0)
|
||||||
#define BOOT_CFG_FROM_LAUNCH BIT(1)
|
#define BOOT_CFG_FROM_LAUNCH BIT(1)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <storage/sd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <bdk.h>
|
#include <bdk.h>
|
||||||
@@ -232,20 +233,19 @@ void print_sdcard_info()
|
|||||||
sd_storage.ssr.app_class, sd_storage.csd.write_protect,
|
sd_storage.ssr.app_class, sd_storage.csd.write_protect,
|
||||||
sd_errors[0], sd_errors[1], sd_errors[2]); // SD_ERROR_INIT_FAIL, SD_ERROR_RW_FAIL, SD_ERROR_RW_RETRY.
|
sd_errors[0], sd_errors[1], sd_errors[2]); // SD_ERROR_INIT_FAIL, SD_ERROR_RW_FAIL, SD_ERROR_RW_RETRY.
|
||||||
|
|
||||||
int res = f_mount(&sd_fs, "", 1);
|
if (sd_mount())
|
||||||
if (!res)
|
|
||||||
{
|
{
|
||||||
gfx_puts("Acquiring FAT volume info...\n\n");
|
gfx_puts("Acquiring FAT volume info...\n\n");
|
||||||
f_getfree("", &sd_fs.free_clst, NULL);
|
f_getfree(XSTR(FF_DEV_SD) ":", &sd_fs.free_clst, NULL);
|
||||||
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
|
gfx_printf("%kFound %s volume:%k\n Free: %d MiB\n Cluster: %d KiB\n",
|
||||||
TXT_CLR_CYAN_L, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", TXT_CLR_DEFAULT,
|
TXT_CLR_CYAN_L, sd_fs.fs_type == FS_EXFAT ? "exFAT" : "FAT32", TXT_CLR_DEFAULT,
|
||||||
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
|
sd_fs.free_clst * sd_fs.csize >> SECTORS_TO_MIB_COEFF, (sd_fs.csize > 1) ? (sd_fs.csize >> 1) : 512);
|
||||||
f_mount(NULL, "", 1);
|
sd_end();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EPRINTFARGS("Failed to mount SD card (FatFS Error %d).\n"
|
EPRINTF("Failed to mount SD card.\n"
|
||||||
"Make sure that a FAT partition exists..", res);
|
"Make sure that a FAT partition exists..");
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_end();
|
sd_end();
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "../frontend/fe_tools.h"
|
#include "../frontend/fe_tools.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../storage/emummc.h"
|
#include "../storage/emummc.h"
|
||||||
|
#include "../storage/boot_storage.h"
|
||||||
|
|
||||||
extern hekate_config h_cfg;
|
extern hekate_config h_cfg;
|
||||||
|
|
||||||
@@ -1086,6 +1087,7 @@ int hos_launch(ini_sec_t *cfg)
|
|||||||
config_exosphere(&ctxt, warmboot_base);
|
config_exosphere(&ctxt, warmboot_base);
|
||||||
|
|
||||||
// Unmount SD card and eMMC.
|
// Unmount SD card and eMMC.
|
||||||
|
boot_storage_end();
|
||||||
sd_end();
|
sd_end();
|
||||||
emmc_end();
|
emmc_end();
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "../hos/pkg1.h"
|
#include "../hos/pkg1.h"
|
||||||
#include "l4t.h"
|
#include "l4t.h"
|
||||||
#include "l4t_config.inl"
|
#include "l4t_config.inl"
|
||||||
|
#include "../storage/boot_storage.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* API Revision info
|
* API Revision info
|
||||||
@@ -1025,7 +1026,7 @@ void launch_l4t(const ini_sec_t *ini_sec, int entry_idx, int is_list, bool t210b
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Done loading bootloaders/firmware.
|
// Done loading bootloaders/firmware.
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
// We don't need AHB aperture open.
|
// We don't need AHB aperture open.
|
||||||
mc_disable_ahb_redirect();
|
mc_disable_ahb_redirect();
|
||||||
|
|||||||
@@ -7,11 +7,37 @@
|
|||||||
/* storage control modules to the FatFs module with a defined API. */
|
/* storage control modules to the FatFs module with a defined API. */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <storage/sd.h>
|
||||||
|
#include <storage/sdmmc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <bdk.h>
|
#include <bdk.h>
|
||||||
|
|
||||||
#include <libs/fatfs/diskio.h> /* FatFs lower layer API */
|
#include <libs/fatfs/diskio.h> /* FatFs lower layer API */
|
||||||
|
#include "ffconf.h"
|
||||||
|
|
||||||
|
static bool ensure_partition(BYTE pdrv){
|
||||||
|
u8 part;
|
||||||
|
switch(pdrv){
|
||||||
|
case FF_DEV_SD:
|
||||||
|
return true;
|
||||||
|
case FF_DEV_BOOT1:
|
||||||
|
case FF_DEV_BOOT1_1MB:
|
||||||
|
part = EMMC_BOOT1;
|
||||||
|
break;
|
||||||
|
case FF_DEV_GPP:
|
||||||
|
part = EMMC_GPP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(emmc_storage.partition != part){
|
||||||
|
return emmc_set_partition(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Get Drive Status */
|
/* Get Drive Status */
|
||||||
@@ -43,7 +69,27 @@ DRESULT disk_read (
|
|||||||
UINT count /* Number of sectors to read */
|
UINT count /* Number of sectors to read */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
|
sdmmc_storage_t *storage = &sd_storage;
|
||||||
|
u32 actual_sector = sector;
|
||||||
|
switch(pdrv){
|
||||||
|
case FF_DEV_SD:
|
||||||
|
break;
|
||||||
|
case FF_DEV_BOOT1:
|
||||||
|
case FF_DEV_GPP:
|
||||||
|
storage = &emmc_storage;
|
||||||
|
break;
|
||||||
|
case FF_DEV_BOOT1_1MB:
|
||||||
|
storage = &emmc_storage;
|
||||||
|
actual_sector = sector + (0x100000 / 512);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return RES_ERROR;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_partition(pdrv);
|
||||||
|
|
||||||
|
return sdmmc_storage_read(storage, actual_sector, count, buff) ? RES_OK : RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
@@ -56,7 +102,27 @@ DRESULT disk_write (
|
|||||||
UINT count /* Number of sectors to write */
|
UINT count /* Number of sectors to write */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
sdmmc_storage_t *storage = &sd_storage;
|
||||||
|
u32 actual_sector = sector;
|
||||||
|
switch(pdrv){
|
||||||
|
case FF_DEV_SD:
|
||||||
|
break;
|
||||||
|
case FF_DEV_BOOT1:
|
||||||
|
case FF_DEV_GPP:
|
||||||
|
storage = &emmc_storage;
|
||||||
|
break;
|
||||||
|
case FF_DEV_BOOT1_1MB:
|
||||||
|
storage = &emmc_storage;
|
||||||
|
actual_sector = sector + (0x100000 / 512);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return RES_ERROR;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_partition(pdrv);
|
||||||
|
|
||||||
|
return sdmmc_storage_write(storage, actual_sector, count, (void*)buff) ? RES_OK : RES_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|||||||
@@ -166,7 +166,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_RPATH 0
|
#define FF_FS_RPATH 1
|
||||||
/* This option configures support for relative path.
|
/* This option configures support for relative path.
|
||||||
/
|
/
|
||||||
/ 0: Disable relative path and remove related functions.
|
/ 0: Disable relative path and remove related functions.
|
||||||
@@ -179,12 +179,12 @@
|
|||||||
/ Drive/Volume Configurations
|
/ Drive/Volume Configurations
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define FF_VOLUMES 1
|
#define FF_VOLUMES 4
|
||||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||||
|
|
||||||
|
|
||||||
#define FF_STR_VOLUME_ID 0
|
#define FF_STR_VOLUME_ID 0
|
||||||
#define FF_VOLUME_STRS "sd"
|
#define FF_VOLUME_STRS "sd", "boot1", "boot1_1mb", "gpp"
|
||||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||||
@@ -300,6 +300,9 @@
|
|||||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||||
/ included somewhere in the scope of ff.h. */
|
/ included somewhere in the scope of ff.h. */
|
||||||
|
|
||||||
|
#define FF_DEV_BOOT1 1
|
||||||
|
#define FF_DEV_BOOT1_1MB 2
|
||||||
|
#define FF_DEV_SD 0
|
||||||
|
#define FF_DEV_GPP 3
|
||||||
|
|
||||||
/*--- End of configuration options ---*/
|
/*--- End of configuration options ---*/
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <libs/compr/blz.h>
|
#include <libs/compr/blz.h>
|
||||||
#include <libs/fatfs/ff.h>
|
#include <libs/fatfs/ff.h>
|
||||||
#include "storage/emummc.h"
|
#include "storage/emummc.h"
|
||||||
|
#include "storage/boot_storage.h"
|
||||||
|
|
||||||
#include "frontend/fe_tools.h"
|
#include "frontend/fe_tools.h"
|
||||||
#include "frontend/fe_info.h"
|
#include "frontend/fe_info.h"
|
||||||
@@ -205,7 +206,7 @@ static void _launch_payload(char *path, bool update, bool clear_screen)
|
|||||||
if (update && is_ipl_updated(buf, path, false))
|
if (update && is_ipl_updated(buf, path, false))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
if (size < 0x30000)
|
if (size < 0x30000)
|
||||||
{
|
{
|
||||||
@@ -264,8 +265,8 @@ static void _launch_payloads()
|
|||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
if (!sd_mount())
|
if (!boot_storage_mount())
|
||||||
goto failed_sd_mount;
|
goto failed_boot_storage_mount;
|
||||||
|
|
||||||
ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
|
ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
|
||||||
|
|
||||||
@@ -308,7 +309,7 @@ static void _launch_payloads()
|
|||||||
free(ments);
|
free(ments);
|
||||||
free(dir);
|
free(dir);
|
||||||
free(filelist);
|
free(filelist);
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -324,11 +325,11 @@ static void _launch_payloads()
|
|||||||
_launch_payload(dir, false, true);
|
_launch_payload(dir, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
failed_sd_mount:
|
failed_boot_storage_mount:
|
||||||
free(dir);
|
free(dir);
|
||||||
free(ments);
|
free(ments);
|
||||||
free(filelist);
|
free(filelist);
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
btn_wait();
|
btn_wait();
|
||||||
}
|
}
|
||||||
@@ -346,7 +347,7 @@ static void _launch_ini_list()
|
|||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
if (!sd_mount())
|
if (!boot_storage_mount())
|
||||||
goto parse_failed;
|
goto parse_failed;
|
||||||
|
|
||||||
// Check that ini files exist and parse them.
|
// Check that ini files exist and parse them.
|
||||||
@@ -449,7 +450,7 @@ parse_failed:
|
|||||||
wrong_emupath:
|
wrong_emupath:
|
||||||
if (emummc_path)
|
if (emummc_path)
|
||||||
{
|
{
|
||||||
sd_mount();
|
boot_storage_mount();
|
||||||
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
|
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,7 +475,7 @@ static void _launch_config()
|
|||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
if (!sd_mount())
|
if (!boot_storage_mount())
|
||||||
goto parse_failed;
|
goto parse_failed;
|
||||||
|
|
||||||
// Load emuMMC configuration.
|
// Load emuMMC configuration.
|
||||||
@@ -557,7 +558,7 @@ static void _launch_config()
|
|||||||
if (!cfg_sec)
|
if (!cfg_sec)
|
||||||
{
|
{
|
||||||
free(ments);
|
free(ments);
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,13 +593,13 @@ parse_failed:
|
|||||||
wrong_emupath:
|
wrong_emupath:
|
||||||
if (emummc_path)
|
if (emummc_path)
|
||||||
{
|
{
|
||||||
sd_mount();
|
boot_storage_mount();
|
||||||
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
|
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
free(ments);
|
free(ments);
|
||||||
|
|
||||||
@@ -615,7 +616,7 @@ static void _nyx_load_run()
|
|||||||
if (!nyx)
|
if (!nyx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
render_static_bootlogo();
|
render_static_bootlogo();
|
||||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||||
@@ -1010,7 +1011,7 @@ skip_list:
|
|||||||
wrong_emupath:
|
wrong_emupath:
|
||||||
if (emummc_path || b_cfg.boot_cfg & BOOT_CFG_TO_EMUMMC)
|
if (emummc_path || b_cfg.boot_cfg & BOOT_CFG_TO_EMUMMC)
|
||||||
{
|
{
|
||||||
sd_mount();
|
boot_storage_mount();
|
||||||
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
|
emummc_load_cfg(); // Reload emuMMC config in case of emupath.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1482,7 +1483,8 @@ void ipl_main()
|
|||||||
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
|
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
|
||||||
|
|
||||||
// Mount SD Card.
|
// Mount SD Card.
|
||||||
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
|
// TODO: boot storage may not be sd card -> set proper error
|
||||||
|
h_cfg.errors |= !boot_storage_mount() ? ERR_SD_BOOT_EN : 0;
|
||||||
|
|
||||||
// Check if watchdog was fired previously.
|
// Check if watchdog was fired previously.
|
||||||
if (watchdog_fired())
|
if (watchdog_fired())
|
||||||
@@ -1525,7 +1527,7 @@ skip_lp0_minerva_config:
|
|||||||
_auto_launch();
|
_auto_launch();
|
||||||
|
|
||||||
// Failed to launch Nyx, unmount SD Card.
|
// Failed to launch Nyx, unmount SD Card.
|
||||||
sd_end();
|
boot_storage_end();
|
||||||
|
|
||||||
// Set ram to a freq that doesn't need periodic training.
|
// Set ram to a freq that doesn't need periodic training.
|
||||||
minerva_change_freq(FREQ_800);
|
minerva_change_freq(FREQ_800);
|
||||||
|
|||||||
154
bootloader/storage/boot_storage.c
Normal file
154
bootloader/storage/boot_storage.c
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
#include "boot_storage.h"
|
||||||
|
#include <libs/fatfs/ff.h>
|
||||||
|
#include "../libs/fatfs/ffconf.h"
|
||||||
|
#include <storage/sd.h>
|
||||||
|
#include <storage/emmc.h>
|
||||||
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
#define DEV_INVALID 0xff
|
||||||
|
|
||||||
|
static FATFS boot_storage_fs;
|
||||||
|
static BYTE drive = -1;
|
||||||
|
|
||||||
|
static const char* drive_base_paths[] = {
|
||||||
|
[FF_DEV_SD] = XSTR(FF_DEV_SD) ":",
|
||||||
|
[FF_DEV_BOOT1] = XSTR(FF_DEV_BOOT1) ":",
|
||||||
|
[FF_DEV_BOOT1_1MB] = XSTR(FF_DEV_BOOT1_1MB) ":",
|
||||||
|
[FF_DEV_GPP] = XSTR(FF_DEV_GPP) ":",
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool _is_eligible(){
|
||||||
|
if(f_stat(".no_boot_storage", NULL) == FR_OK){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool boot_storage_get_mounted(){
|
||||||
|
return drive != DEV_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool boot_storage_get_initialized(){
|
||||||
|
switch(drive){
|
||||||
|
case FF_DEV_BOOT1:
|
||||||
|
case FF_DEV_GPP:
|
||||||
|
case FF_DEV_BOOT1_1MB:
|
||||||
|
return emmc_get_initialized();
|
||||||
|
case FF_DEV_SD:
|
||||||
|
return sd_get_card_initialized();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _boot_storage_initialize(){
|
||||||
|
switch(drive){
|
||||||
|
case FF_DEV_BOOT1:
|
||||||
|
case FF_DEV_GPP:
|
||||||
|
case FF_DEV_BOOT1_1MB:
|
||||||
|
return emmc_initialize(false);
|
||||||
|
case FF_DEV_SD:
|
||||||
|
return sd_initialize(false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _boot_storage_end(bool deinit){
|
||||||
|
if(boot_storage_get_mounted()){
|
||||||
|
if(drive == FF_DEV_SD){
|
||||||
|
sd_unmount();
|
||||||
|
}else{
|
||||||
|
f_mount(NULL, drive_base_paths[drive], false);
|
||||||
|
}
|
||||||
|
drive = DEV_INVALID;
|
||||||
|
}
|
||||||
|
if(deinit){
|
||||||
|
if(drive == FF_DEV_SD){
|
||||||
|
sd_end();
|
||||||
|
}else{
|
||||||
|
emmc_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void boot_storage_unmount(){
|
||||||
|
_boot_storage_end(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void boot_storage_end(){
|
||||||
|
_boot_storage_end(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _boot_storage_mount(){
|
||||||
|
// may want to check sd card first and prioritize it
|
||||||
|
|
||||||
|
FRESULT res;
|
||||||
|
|
||||||
|
if(!emmc_get_initialized() && !emmc_initialize(false)){
|
||||||
|
goto emmc_init_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const BYTE emmc_drives[] = {FF_DEV_BOOT1_1MB, FF_DEV_BOOT1, FF_DEV_GPP};
|
||||||
|
|
||||||
|
for(BYTE i = 0; i < ARRAY_SIZE(emmc_drives); i++){
|
||||||
|
res = f_mount(&boot_storage_fs, drive_base_paths[i], true);
|
||||||
|
if(res == FR_OK){
|
||||||
|
res = f_chdrive(drive_base_paths[i]);
|
||||||
|
if(res == FR_OK && _is_eligible()){
|
||||||
|
drive = i;
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
f_mount(NULL, drive_base_paths[i],false);
|
||||||
|
res = FR_INVALID_DRIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res != FR_OK){
|
||||||
|
emmc_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res == FR_OK){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
emmc_init_fail:
|
||||||
|
if(!sd_initialize(false)){
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sd_mount()){
|
||||||
|
sd_end();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = f_chdrive(drive_base_paths[FF_DEV_SD]);
|
||||||
|
|
||||||
|
if(res == FR_OK && _is_eligible()){
|
||||||
|
drive = FF_DEV_SD;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd_end();
|
||||||
|
|
||||||
|
out:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool boot_storage_mount(){
|
||||||
|
bool mounted = boot_storage_get_mounted();
|
||||||
|
bool initialized = boot_storage_get_initialized();
|
||||||
|
if(mounted && initialized){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mounted){
|
||||||
|
// not mounted. mounting will also initialize.
|
||||||
|
return _boot_storage_mount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!initialized){
|
||||||
|
return _boot_storage_initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
16
bootloader/storage/boot_storage.h
Normal file
16
bootloader/storage/boot_storage.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _BOOT_STORAGE_H
|
||||||
|
#define _BOOT_STORAGE_H
|
||||||
|
|
||||||
|
#include <utils/types.h>
|
||||||
|
|
||||||
|
// check if boot1 (1mb), boot1, gpp, sd (in that order) have fat32 partition,
|
||||||
|
// mount the partition and set the current drive to it
|
||||||
|
bool boot_storage_mount();
|
||||||
|
|
||||||
|
void boot_storage_unmount();
|
||||||
|
void boot_storage_end();
|
||||||
|
|
||||||
|
bool boot_storage_get_mounted();
|
||||||
|
bool boot_storage_get_initialized();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include <libs/fatfs/ff.h>
|
#include <libs/fatfs/ff.h>
|
||||||
|
|
||||||
|
#define DEV_SD_BASE_PATH XSTR(FF_DEV_SD) ":"
|
||||||
|
|
||||||
extern hekate_config h_cfg;
|
extern hekate_config h_cfg;
|
||||||
emummc_cfg_t emu_cfg = { 0 };
|
emummc_cfg_t emu_cfg = { 0 };
|
||||||
|
|
||||||
@@ -77,7 +79,8 @@ bool emummc_set_path(char *path)
|
|||||||
FIL fp;
|
FIL fp;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
strcpy(emu_cfg.emummc_file_based_path, path);
|
strcpy(emu_cfg.emummc_file_based_path, DEV_SD_BASE_PATH);
|
||||||
|
strcat(emu_cfg.emummc_file_based_path, path);
|
||||||
strcat(emu_cfg.emummc_file_based_path, "/raw_based");
|
strcat(emu_cfg.emummc_file_based_path, "/raw_based");
|
||||||
|
|
||||||
if (!f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
|
if (!f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
|
||||||
@@ -88,7 +91,8 @@ bool emummc_set_path(char *path)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(emu_cfg.emummc_file_based_path, path);
|
strcpy(emu_cfg.emummc_file_based_path, DEV_SD_BASE_PATH);
|
||||||
|
strcat(emu_cfg.emummc_file_based_path, path);
|
||||||
strcat(emu_cfg.emummc_file_based_path, "/file_based");
|
strcat(emu_cfg.emummc_file_based_path, "/file_based");
|
||||||
|
|
||||||
if (!f_stat(emu_cfg.emummc_file_based_path, NULL))
|
if (!f_stat(emu_cfg.emummc_file_based_path, NULL))
|
||||||
@@ -149,7 +153,8 @@ int emummc_storage_init_mmc()
|
|||||||
|
|
||||||
if (!emu_cfg.sector)
|
if (!emu_cfg.sector)
|
||||||
{
|
{
|
||||||
strcpy(emu_cfg.emummc_file_based_path, emu_cfg.path);
|
strcpy(emu_cfg.emummc_file_based_path, DEV_SD_BASE_PATH);
|
||||||
|
strcat(emu_cfg.emummc_file_based_path, emu_cfg.path);
|
||||||
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
|
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
|
||||||
|
|
||||||
if (f_stat(emu_cfg.emummc_file_based_path, &fno))
|
if (f_stat(emu_cfg.emummc_file_based_path, &fno))
|
||||||
@@ -279,7 +284,8 @@ int emummc_storage_set_mmc_partition(u32 partition)
|
|||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(emu_cfg.emummc_file_based_path, emu_cfg.path);
|
strcpy(emu_cfg.emummc_file_based_path, DEV_SD_BASE_PATH);
|
||||||
|
strcat(emu_cfg.emummc_file_based_path, emu_cfg.path);
|
||||||
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
|
strcat(emu_cfg.emummc_file_based_path, "/eMMC");
|
||||||
|
|
||||||
switch (partition)
|
switch (partition)
|
||||||
|
|||||||
Reference in New Issue
Block a user