support for file based and sd partition based emusd
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 emummc_file_based.o emusd.o \
|
sdmmc.o sdmmc_driver.o emmc.o sd.o emummc.o emummc_file_based.o emusd.o \
|
||||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||||
hw_init.o boot_storage.o \
|
hw_init.o boot_storage.o emusd.o file_based_storage.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
# Utilities.
|
# Utilities.
|
||||||
|
|||||||
190
bdk/storage/file_based_storage.c
Normal file
190
bdk/storage/file_based_storage.c
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#include "file_based_storage.h"
|
||||||
|
#include <libs/fatfs/ff.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "gfx_utils.h"
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
FIL active_file;
|
||||||
|
s32 active_file_idx;
|
||||||
|
char base_path[0x80];
|
||||||
|
u32 part_sz_sct;
|
||||||
|
u32 base_path_len;
|
||||||
|
}file_based_storage_ctxt_t;
|
||||||
|
|
||||||
|
static file_based_storage_ctxt_t ctx;
|
||||||
|
|
||||||
|
int file_based_storage_init(const char *base_path) {
|
||||||
|
ctx.active_file_idx = -0xff;
|
||||||
|
ctx.base_path_len = strlen(base_path);
|
||||||
|
|
||||||
|
strcpy(ctx.base_path, base_path);
|
||||||
|
strcat(ctx.base_path, "00");
|
||||||
|
|
||||||
|
gfx_printf("file based init %d %s\n", ctx.base_path_len, ctx.base_path);
|
||||||
|
|
||||||
|
FILINFO fi;
|
||||||
|
if(f_stat(ctx.base_path, &fi) != FR_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fi.fsize) {
|
||||||
|
ctx.part_sz_sct = fi.fsize >> 9;
|
||||||
|
gfx_printf("file based init sz 0x%x\n", ctx.part_sz_sct);
|
||||||
|
}else{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ctx.part_sz_sct = fi.fsize;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_based_storage_end() {
|
||||||
|
if(ctx.active_file_idx != -0xff) {
|
||||||
|
f_close(&ctx.active_file);
|
||||||
|
}
|
||||||
|
ctx.active_file_idx = -0xff;
|
||||||
|
ctx.part_sz_sct = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_based_storage_change_file(const char *name, s32 idx) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if(ctx.active_file_idx == idx){
|
||||||
|
return FR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx.active_file_idx != -0xff){
|
||||||
|
f_close(&ctx.active_file);
|
||||||
|
ctx.active_file_idx = -0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(ctx.base_path + ctx.base_path_len, name);
|
||||||
|
|
||||||
|
#if FF_FS_READONLY == 1
|
||||||
|
res = f_open(&ctx.active_file, ctx.base_path, FA_READ);
|
||||||
|
#else
|
||||||
|
res = f_open(&ctx.active_file, ctx.base_path, FA_READ | FA_WRITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(res != FR_OK){
|
||||||
|
gfx_printf("file based open fail %s\n", ctx.base_path);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.active_file_idx = idx;
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_based_storage_readwrite_single(u32 sector, u32 num_sectors, void *buf, bool is_write){
|
||||||
|
#if FF_FS_READONLY == 1
|
||||||
|
if(is_write){
|
||||||
|
return FR_WRITE_PROTECTED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int res = f_lseek(&ctx.active_file, (u64)sector << 9);
|
||||||
|
if(res != FR_OK){
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_write){
|
||||||
|
res = f_write(&ctx.active_file, buf, (u64)num_sectors << 9, NULL);
|
||||||
|
}else{
|
||||||
|
res = f_read(&ctx.active_file, buf, (u64)num_sectors << 9, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res != FR_OK){
|
||||||
|
gfx_printf("file based rw fail %s 0x%x 0x%x \n", ctx.base_path, num_sectors, sector);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int file_based_storage_readwrite(u32 sector, u32 num_sectors, void *buf, bool is_write) {
|
||||||
|
#if FF_FS_READONLY == 1
|
||||||
|
if(is_write){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(ctx.part_sz_sct == 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res;
|
||||||
|
|
||||||
|
u32 scts_left = num_sectors;
|
||||||
|
u32 cur_sct = sector;
|
||||||
|
|
||||||
|
while(scts_left){
|
||||||
|
u32 offset = cur_sct % ctx.part_sz_sct;
|
||||||
|
u32 sct_cnt = ctx.part_sz_sct - offset;
|
||||||
|
sct_cnt = MIN(scts_left, sct_cnt);
|
||||||
|
|
||||||
|
u32 file_idx = cur_sct / ctx.part_sz_sct;
|
||||||
|
|
||||||
|
if((s32) file_idx != ctx.active_file_idx) {
|
||||||
|
char name[3];
|
||||||
|
if(file_idx < 10){
|
||||||
|
strcpy(name, "0");
|
||||||
|
}
|
||||||
|
itoa(file_idx, name + strlen(name), 10);
|
||||||
|
|
||||||
|
res = file_based_storage_change_file(name, file_idx);
|
||||||
|
if(res != FR_OK){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = file_based_storage_readwrite_single(offset, sct_cnt, buf + ((u64)(num_sectors - scts_left) << 9), is_write);
|
||||||
|
if(res != FR_OK){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_sct += sct_cnt;
|
||||||
|
scts_left -= sct_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_sync(&ctx.active_file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int file_based_storage_read(u32 sector, u32 num_sectors, void *buf) {
|
||||||
|
return file_based_storage_readwrite(sector, num_sectors, buf, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int file_based_storage_write(u32 sector, u32 num_sectors, void *buf) {
|
||||||
|
return file_based_storage_readwrite(sector, num_sectors, buf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 file_based_storage_get_total_size() {
|
||||||
|
u32 total_size_sct = 0;
|
||||||
|
char file_path[0x80];
|
||||||
|
u32 cur_idx = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
strcpy(file_path, ctx.base_path);
|
||||||
|
strcpy(file_path + ctx.base_path_len, "00");
|
||||||
|
|
||||||
|
FILINFO fi;
|
||||||
|
res = f_stat(file_path, &fi);
|
||||||
|
|
||||||
|
while(res == FR_OK){
|
||||||
|
cur_idx++;
|
||||||
|
total_size_sct += fi.fsize >> 9;
|
||||||
|
|
||||||
|
char name[3] = "0";
|
||||||
|
if(cur_idx >= 10){
|
||||||
|
name[0] = '\0';
|
||||||
|
}
|
||||||
|
itoa(cur_idx, name + strlen(name), 10);
|
||||||
|
|
||||||
|
strcpy(file_path + ctx.base_path_len, name);
|
||||||
|
|
||||||
|
res = f_stat(file_path, &fi);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_size_sct;
|
||||||
|
}
|
||||||
15
bdk/storage/file_based_storage.h
Normal file
15
bdk/storage/file_based_storage.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _FILE_BASED_STORAGE_H
|
||||||
|
#define _FILE_BASED_STORAGE_H
|
||||||
|
|
||||||
|
#include <bdk.h>
|
||||||
|
|
||||||
|
|
||||||
|
int file_based_storage_init(const char *base_path);
|
||||||
|
void file_based_storage_end();
|
||||||
|
|
||||||
|
int file_based_storage_read(u32 sector, u32 num_sectors, void *buf);
|
||||||
|
int file_based_storage_write(u32 sector, u32 num_sectors, void *buf);
|
||||||
|
|
||||||
|
u32 file_based_storage_get_total_size();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -35,6 +35,7 @@ typedef enum _sdmmc_type
|
|||||||
MMC_EMUMMC_RAW_SD = 3,
|
MMC_EMUMMC_RAW_SD = 3,
|
||||||
MMC_EMUMMC_RAW_EMMC = 4,
|
MMC_EMUMMC_RAW_EMMC = 4,
|
||||||
MMC_EMUMMC_FILE_EMMC = 5,
|
MMC_EMUMMC_FILE_EMMC = 5,
|
||||||
|
MMC_FILE_BASED = 6,
|
||||||
|
|
||||||
EMMC_GPP = 0,
|
EMMC_GPP = 0,
|
||||||
EMMC_BOOT0 = 1,
|
EMMC_BOOT0 = 1,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <storage/emmc.h>
|
#include <storage/emmc.h>
|
||||||
#include <storage/emummc_file_based.h>
|
#include <storage/emummc_file_based.h>
|
||||||
|
#include <storage/file_based_storage.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <usb/usbd.h>
|
#include <usb/usbd.h>
|
||||||
@@ -500,6 +501,10 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||||||
if(ums->lun.storage){
|
if(ums->lun.storage){
|
||||||
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, sdmmc_buf))
|
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, sdmmc_buf))
|
||||||
amount = 0;
|
amount = 0;
|
||||||
|
}else if (ums->lun.type == MMC_FILE_BASED) {
|
||||||
|
if(!file_based_storage_read(ums->lun.offset + lba_offset, amount, sdmmc_buf)){
|
||||||
|
amount = 0;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, sdmmc_buf)){
|
if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, sdmmc_buf)){
|
||||||
amount = 0;
|
amount = 0;
|
||||||
@@ -662,6 +667,10 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||||||
if (!sdmmc_storage_write(ums->lun.storage, ums->lun.offset + lba_offset,
|
if (!sdmmc_storage_write(ums->lun.storage, ums->lun.offset + lba_offset,
|
||||||
amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf))
|
amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf))
|
||||||
amount = 0;
|
amount = 0;
|
||||||
|
}else if(ums->lun.type == MMC_FILE_BASED){
|
||||||
|
if(!file_based_storage_write(ums->lun.offset + lba_offset, amount >> UMS_DISK_LBA_SHIFT, (u8*)bulk_ctxt->bulk_out_buf)){
|
||||||
|
amount = 0;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
if(!emummc_storage_file_based_write(ums->lun.offset + lba_offset, amount >> UMS_DISK_LBA_SHIFT, (u8*)bulk_ctxt->bulk_out_buf)){
|
if(!emummc_storage_file_based_write(ums->lun.offset + lba_offset, amount >> UMS_DISK_LBA_SHIFT, (u8*)bulk_ctxt->bulk_out_buf)){
|
||||||
amount = 0;
|
amount = 0;
|
||||||
@@ -739,6 +748,10 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
|||||||
if(ums->lun.storage){
|
if(ums->lun.storage){
|
||||||
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf))
|
if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf))
|
||||||
amount = 0;
|
amount = 0;
|
||||||
|
}else if(ums->lun.type == MMC_FILE_BASED){
|
||||||
|
if(!file_based_storage_read(ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)){
|
||||||
|
amount = 0;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)){
|
if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)){
|
||||||
amount = 0;
|
amount = 0;
|
||||||
@@ -1934,6 +1947,10 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
|||||||
}
|
}
|
||||||
ums.lun.storage = NULL;
|
ums.lun.storage = NULL;
|
||||||
ums.lun.sdmmc = NULL;
|
ums.lun.sdmmc = NULL;
|
||||||
|
}else if(usbs->type == MMC_FILE_BASED){
|
||||||
|
// file based must be initialized at this point
|
||||||
|
ums.lun.storage = NULL;
|
||||||
|
ums.lun.sdmmc = NULL;
|
||||||
} else{
|
} else{
|
||||||
if (!emmc_initialize(false))
|
if (!emmc_initialize(false))
|
||||||
{
|
{
|
||||||
@@ -1980,6 +1997,9 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
|||||||
case MMC_EMUMMC_RAW_EMMC:
|
case MMC_EMUMMC_RAW_EMMC:
|
||||||
ums.set_text(ums.label, "#FFDD00 No sector count set for emuMMC!#");
|
ums.set_text(ums.label, "#FFDD00 No sector count set for emuMMC!#");
|
||||||
break;
|
break;
|
||||||
|
case MMC_FILE_BASED:
|
||||||
|
ums.set_text(ums.label, "#FFDD00 No sector count set for emuSD!#");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -782,9 +782,15 @@ void hos_launch(ini_sec_t *cfg)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx_con.mute = false;
|
||||||
|
if (emusd_storage_init_mmc() || !emusd_mount()) {
|
||||||
|
_hos_crit_error("error: Failed to init emuSD.");
|
||||||
|
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if SD Card is GPT.
|
// Check if SD Card is GPT.
|
||||||
// TODO: not relevant with emuSD
|
if (emusd_is_gpt())
|
||||||
if (sd_is_gpt())
|
|
||||||
{
|
{
|
||||||
_hos_crit_error("SD has GPT only! Run Fix Hybrid MBR!");
|
_hos_crit_error("SD has GPT only! Run Fix Hybrid MBR!");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -804,6 +810,8 @@ void hos_launch(ini_sec_t *cfg)
|
|||||||
if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled()))
|
if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled()))
|
||||||
{
|
{
|
||||||
sdram_src_pllc(false);
|
sdram_src_pllc(false);
|
||||||
|
emummc_storage_end();
|
||||||
|
emusd_storage_end();
|
||||||
emmc_end();
|
emmc_end();
|
||||||
|
|
||||||
WPRINTF("\nRebooting to OFW in 5s...");
|
WPRINTF("\nRebooting to OFW in 5s...");
|
||||||
@@ -1053,7 +1061,7 @@ void hos_launch(ini_sec_t *cfg)
|
|||||||
{
|
{
|
||||||
bool exfat_compat = _get_fs_exfat_compatible(&kip1_info, &ctxt.exo_ctx.hos_revision);
|
bool exfat_compat = _get_fs_exfat_compatible(&kip1_info, &ctxt.exo_ctx.hos_revision);
|
||||||
|
|
||||||
if (sd_fs.fs_type == FS_EXFAT && !exfat_compat)
|
if (emusd_get_fs_type() == FS_EXFAT && !exfat_compat)
|
||||||
{
|
{
|
||||||
_hos_crit_error("SD Card is exFAT but installed HOS driver\nonly supports FAT32!");
|
_hos_crit_error("SD Card is exFAT but installed HOS driver\nonly supports FAT32!");
|
||||||
|
|
||||||
@@ -1086,6 +1094,8 @@ void 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.
|
||||||
|
emummc_storage_end();
|
||||||
|
emusd_storage_end();
|
||||||
boot_storage_end();
|
boot_storage_end();
|
||||||
sd_end();
|
sd_end();
|
||||||
emmc_end();
|
emmc_end();
|
||||||
@@ -1201,6 +1211,8 @@ void hos_launch(ini_sec_t *cfg)
|
|||||||
error:
|
error:
|
||||||
_free_launch_components(&ctxt);
|
_free_launch_components(&ctxt);
|
||||||
sdram_src_pllc(false);
|
sdram_src_pllc(false);
|
||||||
|
emummc_storage_end();
|
||||||
|
emusd_storage_end();
|
||||||
emmc_end();
|
emmc_end();
|
||||||
|
|
||||||
EPRINTF("\nFailed to launch HOS!");
|
EPRINTF("\nFailed to launch HOS!");
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <storage/boot_storage.h>
|
#include <storage/boot_storage.h>
|
||||||
|
#include "../storage/emusd.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <bdk.h>
|
#include <bdk.h>
|
||||||
@@ -30,7 +31,7 @@
|
|||||||
|
|
||||||
static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
|
static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
ctxt->warmboot = boot_storage_file_read(value, &ctxt->warmboot_size);
|
ctxt->warmboot = emusd_file_read(value, &ctxt->warmboot_size);
|
||||||
if (!ctxt->warmboot)
|
if (!ctxt->warmboot)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ static int _config_warmboot(launch_ctxt_t *ctxt, const char *value)
|
|||||||
|
|
||||||
static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
|
static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
ctxt->secmon = boot_storage_file_read(value, &ctxt->secmon_size);
|
ctxt->secmon = emusd_file_read(value, &ctxt->secmon_size);
|
||||||
if (!ctxt->secmon)
|
if (!ctxt->secmon)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ static int _config_secmon(launch_ctxt_t *ctxt, const char *value)
|
|||||||
|
|
||||||
static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
|
static int _config_kernel(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
ctxt->kernel = boot_storage_file_read(value, &ctxt->kernel_size);
|
ctxt->kernel = emusd_file_read(value, &ctxt->kernel_size);
|
||||||
if (!ctxt->kernel)
|
if (!ctxt->kernel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -62,7 +63,8 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||||||
if (value[strlen(value) - 1] == '*')
|
if (value[strlen(value) - 1] == '*')
|
||||||
{
|
{
|
||||||
char *dir = (char *)malloc(256);
|
char *dir = (char *)malloc(256);
|
||||||
strcpy(dir, value);
|
strcpy(dir, "emusd:");
|
||||||
|
strcat(dir, value);
|
||||||
|
|
||||||
u32 dirlen = 0;
|
u32 dirlen = 0;
|
||||||
dir[strlen(dir) - 2] = 0;
|
dir[strlen(dir) - 2] = 0;
|
||||||
@@ -82,7 +84,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||||||
strcpy(dir + dirlen, filelist->name[i]);
|
strcpy(dir + dirlen, filelist->name[i]);
|
||||||
|
|
||||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||||
mkip1->kip1 = boot_storage_file_read(dir, &size);
|
mkip1->kip1 = emusd_file_read(dir + 6, &size);
|
||||||
if (!mkip1->kip1)
|
if (!mkip1->kip1)
|
||||||
{
|
{
|
||||||
free(mkip1);
|
free(mkip1);
|
||||||
@@ -104,7 +106,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t));
|
||||||
mkip1->kip1 = boot_storage_file_read(value, &size);
|
mkip1->kip1 = emusd_file_read(value, &size);
|
||||||
if (!mkip1->kip1)
|
if (!mkip1->kip1)
|
||||||
{
|
{
|
||||||
free(mkip1);
|
free(mkip1);
|
||||||
@@ -263,7 +265,7 @@ static int _config_pkg3(launch_ctxt_t *ctxt, const char *value)
|
|||||||
|
|
||||||
static int _config_exo_fatal_payload(launch_ctxt_t *ctxt, const char *value)
|
static int _config_exo_fatal_payload(launch_ctxt_t *ctxt, const char *value)
|
||||||
{
|
{
|
||||||
ctxt->exofatal = boot_storage_file_read(value, &ctxt->exofatal_size);
|
ctxt->exofatal = emusd_file_read(value, &ctxt->exofatal_size);
|
||||||
if (!ctxt->exofatal)
|
if (!ctxt->exofatal)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <storage/boot_storage.h>
|
#include <storage/boot_storage.h>
|
||||||
|
#include "../storage/emusd.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -370,13 +371,13 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb)
|
|||||||
if (!ctxt->warmboot)
|
if (!ctxt->warmboot)
|
||||||
{
|
{
|
||||||
char path[128];
|
char path[128];
|
||||||
strcpy(path, "warmboot_mariko/wb_");
|
strcpy(path, "emusd:warmboot_mariko/wb_");
|
||||||
_warmboot_filename(path, fuses_fw);
|
_warmboot_filename(path, fuses_fw);
|
||||||
|
|
||||||
// Check if warmboot fw exists and save it.
|
// Check if warmboot fw exists and save it.
|
||||||
if (ctxt->warmboot_size && f_stat(path, NULL))
|
if (ctxt->warmboot_size && f_stat(path, NULL))
|
||||||
{
|
{
|
||||||
f_mkdir("warmboot_mariko");
|
f_mkdir("emusd:warmboot_mariko");
|
||||||
sd_save_to_file((void *)warmboot_base, ctxt->warmboot_size, path);
|
sd_save_to_file((void *)warmboot_base, ctxt->warmboot_size, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +390,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb)
|
|||||||
_warmboot_filename(path, burnt_fuses);
|
_warmboot_filename(path, burnt_fuses);
|
||||||
if (!f_stat(path, NULL))
|
if (!f_stat(path, NULL))
|
||||||
{
|
{
|
||||||
ctxt->warmboot = boot_storage_file_read(path, &ctxt->warmboot_size);
|
ctxt->warmboot = emusd_file_read(path + 6, &ctxt->warmboot_size);
|
||||||
burnt_fuses = tmp_fuses;
|
burnt_fuses = tmp_fuses;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ static void parse_external_kip_patches()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
LIST_INIT(ini_kip_sections);
|
LIST_INIT(ini_kip_sections);
|
||||||
|
// TODO: load frome emusd?
|
||||||
if (ini_patch_parse(&ini_kip_sections, "bootloader/patches.ini"))
|
if (ini_patch_parse(&ini_kip_sections, "bootloader/patches.ini"))
|
||||||
{
|
{
|
||||||
// Copy ids into a new patchset.
|
// Copy ids into a new patchset.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <storage/boot_storage.h>
|
#include <storage/boot_storage.h>
|
||||||
|
#include "../storage/emusd.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <bdk.h>
|
#include <bdk.h>
|
||||||
@@ -87,9 +88,9 @@ typedef struct _pkg3_content_t
|
|||||||
|
|
||||||
static void _pkg3_update_r2p()
|
static void _pkg3_update_r2p()
|
||||||
{
|
{
|
||||||
u8 *r2p_payload = boot_storage_file_read("atmosphere/reboot_payload.bin", NULL);
|
u8 *r2p_payload = emusd_file_read("atmosphere/reboot_payload.bin", NULL);
|
||||||
|
|
||||||
is_ipl_updated(r2p_payload, "atmosphere/reboot_payload.bin", h_cfg.updater2p ? true : false);
|
is_ipl_updated(r2p_payload, "emusd:atmosphere/reboot_payload.bin", h_cfg.updater2p ? true : false);
|
||||||
|
|
||||||
free(r2p_payload);
|
free(r2p_payload);
|
||||||
}
|
}
|
||||||
@@ -127,6 +128,10 @@ static int _pkg3_kip1_skip(char ***pkg3_kip1_skip, u32 *pkg3_kip1_skip_num, char
|
|||||||
|
|
||||||
int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
||||||
{
|
{
|
||||||
|
char *path1 = (char *)malloc(256);
|
||||||
|
strcpy(path1, "emusd:");
|
||||||
|
strcat(path1, path);
|
||||||
|
|
||||||
FIL fp;
|
FIL fp;
|
||||||
|
|
||||||
char **pkg3_kip1_skip = NULL;
|
char **pkg3_kip1_skip = NULL;
|
||||||
@@ -154,16 +159,25 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HOS_MARIKO_STOCK_SECMON
|
#ifdef HOS_MARIKO_STOCK_SECMON
|
||||||
if (stock && emummc_disabled && (pkg1_old || h_cfg.t210b01))
|
if (stock && emummc_disabled && (pkg1_old || h_cfg.t210b01)) {
|
||||||
|
free(path1);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (stock && emummc_disabled && pkg1_old)
|
if (stock && emummc_disabled && pkg1_old) {
|
||||||
|
free(path1);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try to open PKG3.
|
// Try to open PKG3.
|
||||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
if (f_open(&fp, path1, FA_READ) != FR_OK) {
|
||||||
|
free(path1);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void *pkg3 = malloc(f_size(&fp));
|
void *pkg3 = malloc(f_size(&fp));
|
||||||
|
|
||||||
@@ -269,6 +283,7 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path)
|
|||||||
_pkg3_update_r2p();
|
_pkg3_update_r2p();
|
||||||
|
|
||||||
free(pkg3_kip1_skip);
|
free(pkg3_kip1_skip);
|
||||||
|
free(path1);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ typedef struct
|
|||||||
union
|
union
|
||||||
{
|
{
|
||||||
emummc_partition_config_t partition_cfg;
|
emummc_partition_config_t partition_cfg;
|
||||||
|
emummc_file_config_t file_cfg;
|
||||||
};
|
};
|
||||||
} emummc_sd_config_t;
|
} emummc_sd_config_t;
|
||||||
|
|
||||||
@@ -226,7 +227,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||||||
if (!ctxt->stock)
|
if (!ctxt->stock)
|
||||||
{
|
{
|
||||||
LIST_INIT(ini_exo_sections);
|
LIST_INIT(ini_exo_sections);
|
||||||
if (ini_parse(&ini_exo_sections, "exosphere.ini", false))
|
if (ini_parse(&ini_exo_sections, "emusd:exosphere.ini", false))
|
||||||
{
|
{
|
||||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_exo_sections, link)
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_exo_sections, link)
|
||||||
{
|
{
|
||||||
@@ -265,7 +266,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||||||
if (!ctxt->exo_ctx.usb3_force)
|
if (!ctxt->exo_ctx.usb3_force)
|
||||||
{
|
{
|
||||||
LIST_INIT(ini_sys_sections);
|
LIST_INIT(ini_sys_sections);
|
||||||
if (ini_parse(&ini_sys_sections, "atmosphere/config/system_settings.ini", false))
|
if (ini_parse(&ini_sys_sections, "emusd:atmosphere/config/system_settings.ini", false))
|
||||||
{
|
{
|
||||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sys_sections, link)
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sys_sections, link)
|
||||||
{
|
{
|
||||||
@@ -375,12 +376,27 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base)
|
|||||||
{
|
{
|
||||||
exo_cfg->emummc_cfg.sd_cfg.base_cfg.fs_ver = emu_sd_cfg.fs_ver;
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.fs_ver = emu_sd_cfg.fs_ver;
|
||||||
exo_cfg->emummc_cfg.sd_cfg.partition_cfg.start_sector = emu_sd_cfg.sector;
|
exo_cfg->emummc_cfg.sd_cfg.partition_cfg.start_sector = emu_sd_cfg.sector;
|
||||||
if(emu_sd_cfg.enabled == 4 && emu_sd_cfg.sector) {
|
if (emu_sd_cfg.enabled == 4 && emu_sd_cfg.sector) {
|
||||||
|
// emmc partition based
|
||||||
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_Partition_Emmc;
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_Partition_Emmc;
|
||||||
}else {
|
} else if (emu_sd_cfg.enabled == 4 && !emu_sd_cfg.sector) {
|
||||||
|
// emmc file based
|
||||||
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_File_Emmc;
|
||||||
|
} else if (emu_sd_cfg.enabled == 1 && emu_sd_cfg.sector) {
|
||||||
|
// sd partition based
|
||||||
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_Partition_Sd;
|
||||||
|
} else if (emu_sd_cfg.enabled == 1 && !emu_sd_cfg.sector) {
|
||||||
|
// sd file based
|
||||||
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_File_Sd;
|
||||||
|
} else {
|
||||||
|
// disabled
|
||||||
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_None;
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emu_sd_cfg.sector)
|
||||||
|
exo_cfg->emummc_cfg.sd_cfg.partition_cfg.start_sector = emu_sd_cfg.sector;
|
||||||
|
else
|
||||||
|
strcpy((char *)exo_cfg->emummc_cfg.sd_cfg.file_cfg.path, emu_sd_cfg.path);
|
||||||
} else {
|
} else {
|
||||||
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_None;
|
exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_None;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
/* storage control modules to the FatFs module with a defined API. */
|
/* storage control modules to the FatFs module with a defined API. */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "../../storage/emusd.h"
|
||||||
#include <storage/sd.h>
|
#include <storage/sd.h>
|
||||||
#include <storage/sdmmc.h>
|
#include <storage/sdmmc.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <bdk.h>
|
#include <bdk.h>
|
||||||
|
|
||||||
@@ -28,6 +28,8 @@ static bool ensure_partition(BYTE pdrv){
|
|||||||
case DRIVE_EMMC:
|
case DRIVE_EMMC:
|
||||||
part = EMMC_GPP;
|
part = EMMC_GPP;
|
||||||
break;
|
break;
|
||||||
|
case DRIVE_EMUSD:
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -86,6 +88,9 @@ DRESULT disk_read (
|
|||||||
storage = &emmc_storage;
|
storage = &emmc_storage;
|
||||||
actual_sector = sector + (0x100000 / 512);
|
actual_sector = sector + (0x100000 / 512);
|
||||||
break;
|
break;
|
||||||
|
case DRIVE_EMUSD:
|
||||||
|
return emusd_storage_read(sector, count, buff) ? RES_OK : RES_ERROR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
|
|
||||||
@@ -122,6 +127,8 @@ DRESULT disk_write (
|
|||||||
storage = &emmc_storage;
|
storage = &emmc_storage;
|
||||||
actual_sector = sector + (0x100000 / 512);
|
actual_sector = sector + (0x100000 / 512);
|
||||||
break;
|
break;
|
||||||
|
case DRIVE_EMUSD:
|
||||||
|
return emusd_storage_write(sector, count, (void*)buff) ? RES_OK : RES_ERROR;
|
||||||
default:
|
default:
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
|
|
||||||
|
|||||||
@@ -179,12 +179,12 @@
|
|||||||
/ Drive/Volume Configurations
|
/ Drive/Volume Configurations
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define FF_VOLUMES 4
|
#define FF_VOLUMES 5
|
||||||
/* 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 1
|
#define FF_STR_VOLUME_ID 1
|
||||||
#define FF_VOLUME_STRS "sd", "boot1", "boot1_1mb", "emmc"
|
#define FF_VOLUME_STRS "sd", "boot1", "boot1_1mb", "emmc", "emusd"
|
||||||
/* 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
|
||||||
@@ -306,6 +306,7 @@ typedef enum {
|
|||||||
DRIVE_BOOT1 = 1,
|
DRIVE_BOOT1 = 1,
|
||||||
DRIVE_BOOT1_1MB = 2,
|
DRIVE_BOOT1_1MB = 2,
|
||||||
DRIVE_EMMC = 3,
|
DRIVE_EMMC = 3,
|
||||||
|
DRIVE_EMUSD = 4,
|
||||||
} DDRIVE;
|
} DDRIVE;
|
||||||
|
|
||||||
/*--- End of configuration options ---*/
|
/*--- End of configuration options ---*/
|
||||||
|
|||||||
@@ -418,7 +418,8 @@ static void _launch_ini_list()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (emusd_path && !emusd_set_path(emusd_path)){
|
if (emusd_path && !emusd_set_path(emusd_path)){
|
||||||
EPRINTF("emusdpath is wrong!");
|
EPRINTFARGS("path: %s", emusd_path);
|
||||||
|
EPRINTF("error: emusdpath is wrong!");
|
||||||
goto wrong_emupath;
|
goto wrong_emupath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,7 +580,8 @@ static void _launch_config()
|
|||||||
|
|
||||||
if (emusd_path && !emusd_set_path(emusd_path))
|
if (emusd_path && !emusd_set_path(emusd_path))
|
||||||
{
|
{
|
||||||
EPRINTF("emusdpath is wrong!");
|
EPRINTFARGS("path: %s", emusd_path);
|
||||||
|
EPRINTF("error: emusdpath is wrong!");
|
||||||
goto wrong_emupath;
|
goto wrong_emupath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1058,8 @@ skip_list:
|
|||||||
if (emusd_path && !emusd_set_path(emusd_path))
|
if (emusd_path && !emusd_set_path(emusd_path))
|
||||||
{
|
{
|
||||||
gfx_con.mute = false;
|
gfx_con.mute = false;
|
||||||
EPRINTF("emusdpath is wrong!");
|
EPRINTFARGS("path: %s", emusd_path);
|
||||||
|
EPRINTF("error: emusdpath is wrong!");
|
||||||
goto wrong_emupath;
|
goto wrong_emupath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include "emummc.h"
|
#include "emummc.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "gfx_utils.h"
|
|
||||||
#include <libs/fatfs/ff.h>
|
#include <libs/fatfs/ff.h>
|
||||||
#include <storage/emummc_file_based.h>
|
#include <storage/emummc_file_based.h>
|
||||||
|
|
||||||
@@ -174,11 +173,6 @@ static int emummc_raw_get_part_off(int part_idx)
|
|||||||
|
|
||||||
int emummc_storage_init_mmc()
|
int emummc_storage_init_mmc()
|
||||||
{
|
{
|
||||||
gfx_con.mute = false;
|
|
||||||
|
|
||||||
|
|
||||||
gfx_printf("en %d path %s\n", emu_cfg.enabled, emu_cfg.path);
|
|
||||||
|
|
||||||
// FILINFO fno;
|
// FILINFO fno;
|
||||||
emu_cfg.active_part = 0;
|
emu_cfg.active_part = 0;
|
||||||
|
|
||||||
@@ -263,33 +257,6 @@ int emummc_storage_read(u32 sector, u32 num_sectors, void *buf)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return emummc_storage_file_based_read(sector, num_sectors, buf);
|
return emummc_storage_file_based_read(sector, num_sectors, buf);
|
||||||
// if (!emu_cfg.active_part)
|
|
||||||
// {
|
|
||||||
// u32 file_part = sector / emu_cfg.file_based_part_size;
|
|
||||||
// sector = sector % emu_cfg.file_based_part_size;
|
|
||||||
// if (file_part >= 10)
|
|
||||||
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 2, 10);
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// emu_cfg.emummc_file_based_path[strlen(emu_cfg.emummc_file_based_path) - 2] = '0';
|
|
||||||
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_READ))
|
|
||||||
// {
|
|
||||||
// EPRINTF("Failed to open emuMMC image.");
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
// f_lseek(&fp, (u64)sector << 9);
|
|
||||||
// if (f_read(&fp, buf, (u64)num_sectors << 9, NULL))
|
|
||||||
// {
|
|
||||||
// EPRINTF("Failed to read emuMMC image.");
|
|
||||||
// f_close(&fp);
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// f_close(&fp);
|
|
||||||
// return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -310,31 +277,6 @@ int emummc_storage_write(u32 sector, u32 num_sectors, void *buf)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return emummc_storage_file_based_write(sector, num_sectors, buf);
|
return emummc_storage_file_based_write(sector, num_sectors, buf);
|
||||||
// if (!emu_cfg.active_part)
|
|
||||||
// {
|
|
||||||
// u32 file_part = sector / emu_cfg.file_based_part_size;
|
|
||||||
// sector = sector % emu_cfg.file_based_part_size;
|
|
||||||
// if (file_part >= 10)
|
|
||||||
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 2, 10);
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// emu_cfg.emummc_file_based_path[strlen(emu_cfg.emummc_file_based_path) - 2] = '0';
|
|
||||||
// itoa(file_part, emu_cfg.emummc_file_based_path + strlen(emu_cfg.emummc_file_based_path) - 1, 10);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (f_open(&fp, emu_cfg.emummc_file_based_path, FA_WRITE))
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
// f_lseek(&fp, (u64)sector << 9);
|
|
||||||
// if (f_write(&fp, buf, (u64)num_sectors << 9, NULL))
|
|
||||||
// {
|
|
||||||
// f_close(&fp);
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// f_close(&fp);
|
|
||||||
// return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
#include "emusd.h"
|
#include "emusd.h"
|
||||||
#include <bdk.h>
|
#include <bdk.h>
|
||||||
|
#include <storage/boot_storage.h>
|
||||||
|
#include <storage/emmc.h>
|
||||||
|
#include <storage/file_based_storage.h>
|
||||||
|
#include <storage/sd.h>
|
||||||
|
#include <storage/sdmmc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <utils/ini.h>
|
#include <utils/ini.h>
|
||||||
|
#include <libs/fatfs/ff.h>
|
||||||
|
#include "../config.h"
|
||||||
|
#include "gfx_utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
FATFS emusd_fs;
|
||||||
|
bool emusd_mounted = false;
|
||||||
|
bool emusd_initialized = false;
|
||||||
emusd_cfg_t emu_sd_cfg = {0};
|
emusd_cfg_t emu_sd_cfg = {0};
|
||||||
|
extern hekate_config h_cfg;
|
||||||
|
|
||||||
|
static bool emusd_get_mounted() {
|
||||||
|
return emusd_mounted;
|
||||||
|
}
|
||||||
|
|
||||||
void emusd_load_cfg()
|
void emusd_load_cfg()
|
||||||
{
|
{
|
||||||
@@ -14,7 +31,7 @@ void emusd_load_cfg()
|
|||||||
if(!emu_sd_cfg.path) {
|
if(!emu_sd_cfg.path) {
|
||||||
emu_sd_cfg.path = (char*)malloc(0x200);
|
emu_sd_cfg.path = (char*)malloc(0x200);
|
||||||
}
|
}
|
||||||
if(emu_sd_cfg.emummc_file_based_path){
|
if(!emu_sd_cfg.emummc_file_based_path){
|
||||||
emu_sd_cfg.emummc_file_based_path = (char*)malloc(0x200);
|
emu_sd_cfg.emummc_file_based_path = (char*)malloc(0x200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +52,8 @@ void emusd_load_cfg()
|
|||||||
emu_sd_cfg.enabled = atoi(kv->val);
|
emu_sd_cfg.enabled = atoi(kv->val);
|
||||||
} else if(!strcmp(kv->key, "sector")){
|
} else if(!strcmp(kv->key, "sector")){
|
||||||
emu_sd_cfg.sector = strtol(kv->val, NULL, 16);
|
emu_sd_cfg.sector = strtol(kv->val, NULL, 16);
|
||||||
|
} else if(!strcmp(kv->key, "path")){
|
||||||
|
emu_sd_cfg.path = kv->val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -43,19 +62,46 @@ void emusd_load_cfg()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool emusd_mount() {
|
||||||
|
if (emusd_mounted) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emusd_storage_init_mmc()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = f_mount(&emusd_fs, "emusd:", 1);
|
||||||
|
|
||||||
|
if(res) {
|
||||||
|
EPRINTFARGS("emusd mount fail %d", res);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emusd_unmount() {
|
||||||
|
f_mount(NULL, "emusd:", 1);
|
||||||
|
emusd_mounted = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool emusd_set_path(char *path) {
|
bool emusd_set_path(char *path) {
|
||||||
|
gfx_con.mute = false;
|
||||||
FIL fp;
|
FIL fp;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
char sd_path[0x80];
|
|
||||||
|
|
||||||
// TODO: use emu_sd.file_path instead
|
// TODO: use emu_sd.file_path instead
|
||||||
strcpy(sd_path, path);
|
strcat(emu_sd_cfg.emummc_file_based_path, "");
|
||||||
strcat(sd_path, "/raw_emmc_based");
|
strcpy(emu_sd_cfg.emummc_file_based_path, path);
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, "/raw_emmc_based");
|
||||||
if(!f_open(&fp, sd_path, FA_READ))
|
gfx_printf("1 %s \n", emu_sd_cfg.emummc_file_based_path);
|
||||||
|
if(!f_open(&fp, emu_sd_cfg.emummc_file_based_path, FA_READ))
|
||||||
{
|
{
|
||||||
|
gfx_printf("open done\n");
|
||||||
if(!f_read(&fp, &emu_sd_cfg.sector, 4, NULL)){
|
if(!f_read(&fp, &emu_sd_cfg.sector, 4, NULL)){
|
||||||
|
gfx_printf("found sct\n");
|
||||||
if(emu_sd_cfg.sector){
|
if(emu_sd_cfg.sector){
|
||||||
|
gfx_printf("!=0\n");
|
||||||
found = true;
|
found = true;
|
||||||
emu_sd_cfg.enabled = 4;
|
emu_sd_cfg.enabled = 4;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -63,8 +109,198 @@ bool emusd_set_path(char *path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: file based / SD partition based support
|
strcpy(emu_sd_cfg.emummc_file_based_path, "");
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, path);
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, "/raw_emmc_based");
|
||||||
|
gfx_printf("1 %s \n", emu_sd_cfg.emummc_file_based_path);
|
||||||
|
if (!f_open(&fp, emu_sd_cfg.emummc_file_based_path, FA_READ))
|
||||||
|
{
|
||||||
|
gfx_printf("open done\n");
|
||||||
|
if (!f_read(&fp, &emu_sd_cfg.sector, 4, NULL)){
|
||||||
|
gfx_printf("found sct\n");
|
||||||
|
if (emu_sd_cfg.sector){
|
||||||
|
gfx_printf("!=0\n");
|
||||||
|
found = true;
|
||||||
|
emu_sd_cfg.enabled = 4;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
// strcpy(emu_sd_cfg.emummc_file_based_path, "sd:");
|
||||||
|
strcpy(emu_sd_cfg.emummc_file_based_path, "");
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, path);
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, "/file_based");
|
||||||
|
gfx_printf("1 %s \n", emu_sd_cfg.emummc_file_based_path);
|
||||||
|
if (!f_stat(emu_sd_cfg.emummc_file_based_path, NULL))
|
||||||
|
{
|
||||||
|
gfx_printf("open done\n");
|
||||||
|
emu_sd_cfg.sector = 0;
|
||||||
|
emu_sd_cfg.path = path;
|
||||||
|
emu_sd_cfg.enabled = 1;
|
||||||
|
|
||||||
|
gfx_printf("path %s\n", emu_sd_cfg.path);
|
||||||
|
found = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// strcpy(emu_sd_cfg.emummc_file_based_path, "sd:");
|
||||||
|
strcpy(emu_sd_cfg.emummc_file_based_path, "");
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, path);
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, "/file_emmc_based");
|
||||||
|
gfx_printf("1 %s \n", emu_sd_cfg.emummc_file_based_path);
|
||||||
|
if (!f_stat(emu_sd_cfg.emummc_file_based_path, NULL))
|
||||||
|
{
|
||||||
|
gfx_printf("open done\n");
|
||||||
|
emu_sd_cfg.sector = 0;
|
||||||
|
emu_sd_cfg.path = path;
|
||||||
|
emu_sd_cfg.enabled = 4;
|
||||||
|
|
||||||
|
gfx_printf("path %s\n", emu_sd_cfg.path);
|
||||||
|
found = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int emusd_storage_init_mmc() {
|
||||||
|
if(!emusd_initialized) {
|
||||||
|
if (!emu_sd_cfg.enabled || h_cfg.emummc_force_disable) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file_based = false;
|
||||||
|
if(emu_sd_cfg.enabled == 4){
|
||||||
|
if(!emu_sd_cfg.sector){
|
||||||
|
//file based
|
||||||
|
if(!emmc_mount()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strcpy(emu_sd_cfg.emummc_file_based_path, "emmc:");
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, emu_sd_cfg.path);
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, "/SD/");
|
||||||
|
file_based = true;
|
||||||
|
}else{
|
||||||
|
if(!emmc_initialize(false)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!emu_sd_cfg.sector){
|
||||||
|
//file based
|
||||||
|
if(!sd_mount()){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strcpy(emu_sd_cfg.emummc_file_based_path, "sd:");
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, emu_sd_cfg.path);
|
||||||
|
strcat(emu_sd_cfg.emummc_file_based_path, "/SD/");
|
||||||
|
file_based = true;
|
||||||
|
}else{
|
||||||
|
if(!sd_initialize(false)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_based){
|
||||||
|
return file_based_storage_init(emu_sd_cfg.emummc_file_based_path) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
emusd_initialized = true;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int emusd_storage_end() {
|
||||||
|
if(!h_cfg.emummc_force_disable && emu_sd_cfg.enabled && !emu_sd_cfg.sector){
|
||||||
|
file_based_storage_end();
|
||||||
|
}
|
||||||
|
if(!emu_sd_cfg.enabled || h_cfg.emummc_force_disable || emu_sd_cfg.enabled == 1){
|
||||||
|
sd_unmount();
|
||||||
|
}else{
|
||||||
|
emmc_unmount();
|
||||||
|
}
|
||||||
|
emusd_initialized = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int emusd_storage_write(u32 sector, u32 num_sectors, void *buf) {
|
||||||
|
if(!emu_sd_cfg.enabled || h_cfg.emummc_force_disable){
|
||||||
|
return sdmmc_storage_write(&sd_storage, sector, num_sectors, buf);
|
||||||
|
}else if(emu_sd_cfg.sector){
|
||||||
|
sdmmc_storage_t *storage = emu_sd_cfg.enabled == 1 ? &sd_storage : &emmc_storage;
|
||||||
|
sector += emu_sd_cfg.sector;
|
||||||
|
return sdmmc_storage_write(storage, sector, num_sectors, buf);
|
||||||
|
}else{
|
||||||
|
return file_based_storage_write(sector, num_sectors, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int emusd_storage_read(u32 sector, u32 num_sectors, void *buf) {
|
||||||
|
if(!emu_sd_cfg.enabled || h_cfg.emummc_force_disable){
|
||||||
|
return sdmmc_storage_read(&sd_storage, sector, num_sectors, buf);
|
||||||
|
}else if(emu_sd_cfg.sector){
|
||||||
|
sdmmc_storage_t *storage = emu_sd_cfg.enabled == 1 ? &sd_storage : &emmc_storage;
|
||||||
|
sector += emu_sd_cfg.sector;
|
||||||
|
return sdmmc_storage_read(storage, sector, num_sectors, buf);
|
||||||
|
}else{
|
||||||
|
return file_based_storage_read(sector, num_sectors, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sdmmc_storage_t *emusd_get_storage() {
|
||||||
|
return emu_sd_cfg.enabled == 4 ? &emmc_storage : &sd_storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool emusd_is_gpt() {
|
||||||
|
if(emu_sd_cfg.enabled) {
|
||||||
|
return emusd_fs.part_type;
|
||||||
|
} else {
|
||||||
|
return sd_fs.part_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int emusd_get_fs_type() {
|
||||||
|
if(emu_sd_cfg.enabled) {
|
||||||
|
return emusd_fs.fs_type;
|
||||||
|
} else {
|
||||||
|
return sd_fs.fs_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *emusd_file_read(const char *path, u32 *fsize) {
|
||||||
|
if(emu_sd_cfg.enabled) {
|
||||||
|
char *path1 = malloc(0x100);
|
||||||
|
strcpy(path1, "emusd:");
|
||||||
|
strcat(path1, path);
|
||||||
|
FIL fp;
|
||||||
|
if (!emusd_get_mounted())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
u32 size = f_size(&fp);
|
||||||
|
if (fsize)
|
||||||
|
*fsize = size;
|
||||||
|
|
||||||
|
void *buf = malloc(size);
|
||||||
|
|
||||||
|
if (f_read(&fp, buf, size, NULL) != FR_OK)
|
||||||
|
{
|
||||||
|
free(buf);
|
||||||
|
f_close(&fp);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_close(&fp);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
} else {
|
||||||
|
return boot_storage_file_read(path, fsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,5 +40,10 @@ int emusd_storage_end();
|
|||||||
int emusd_storage_read(u32 sector, u32 num_sectors, void *buf);
|
int emusd_storage_read(u32 sector, u32 num_sectors, void *buf);
|
||||||
int emusd_storage_write(u32 sector, u32 num_sectors, void *buf);
|
int emusd_storage_write(u32 sector, u32 num_sectors, void *buf);
|
||||||
sdmmc_storage_t *emusd_get_storage();
|
sdmmc_storage_t *emusd_get_storage();
|
||||||
|
bool emusd_is_gpt();
|
||||||
|
int emusd_get_fs_type();
|
||||||
|
bool emusd_mount();
|
||||||
|
bool emusd_unmount();
|
||||||
|
void *emusd_file_read(const char *path, u32 *fsize);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -41,7 +41,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
|||||||
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
||||||
touch.o joycon.o tmp451.o fan.o \
|
touch.o joycon.o tmp451.o fan.o \
|
||||||
usbd.o xusbd.o usb_descriptors.o usb_gadget_ums.o usb_gadget_hid.o \
|
usbd.o xusbd.o usb_descriptors.o usb_gadget_ums.o usb_gadget_hid.o \
|
||||||
hw_init.o boot_storage.o sfd.o mbr_gpt.o emummc_file_based.o \
|
hw_init.o boot_storage.o sfd.o mbr_gpt.o emummc_file_based.o file_based_storage.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
# Utilities.
|
# Utilities.
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
#include <libs/fatfs/ff.h>
|
#include <libs/fatfs/ff.h>
|
||||||
#include <storage/emmc.h>
|
#include <storage/emmc.h>
|
||||||
#include <storage/mbr_gpt.h>
|
#include <storage/mbr_gpt.h>
|
||||||
|
#include <storage/sd.h>
|
||||||
#include <storage/sdmmc.h>
|
#include <storage/sdmmc.h>
|
||||||
#include <utils/list.h>
|
#include <utils/list.h>
|
||||||
#include <utils/ini.h>
|
#include <utils/ini.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "gfx_utils.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <utils/sprintf.h>
|
||||||
|
|
||||||
void load_emusd_cfg(emusd_cfg_t *emu_info){
|
void load_emusd_cfg(emusd_cfg_t *emu_info){
|
||||||
memset(emu_info, 0, sizeof(emusd_cfg_t));
|
memset(emu_info, 0, sizeof(emusd_cfg_t));
|
||||||
@@ -29,8 +32,10 @@ void load_emusd_cfg(emusd_cfg_t *emu_info){
|
|||||||
emu_info->enabled = atoi(kv->val);
|
emu_info->enabled = atoi(kv->val);
|
||||||
else if(!strcmp("sector", kv->key))
|
else if(!strcmp("sector", kv->key))
|
||||||
emu_info->sector = strtol(kv->val, NULL, 16);
|
emu_info->sector = strtol(kv->val, NULL, 16);
|
||||||
/*else (!strcmp("id", kv->key))
|
else if(!strcmp("path", kv->key)){
|
||||||
emu_info->id = strtol(kv->val, NULL, 16);*/
|
emu_info->path =(char*)malloc(strlen(kv->val)+1);
|
||||||
|
strcpy(emu_info->path, kv->val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -40,7 +45,7 @@ void load_emusd_cfg(emusd_cfg_t *emu_info){
|
|||||||
ini_free(&ini_sections);
|
ini_free(&ini_sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_emusd_cfg(u32 part_idx, u32 sector_start){
|
void save_emusd_cfg(u32 part_idx, u32 sector_start, const char *path, u8 drive){
|
||||||
boot_storage_mount();
|
boot_storage_mount();
|
||||||
|
|
||||||
char lbuf[16];
|
char lbuf[16];
|
||||||
@@ -53,7 +58,9 @@ void save_emusd_cfg(u32 part_idx, u32 sector_start){
|
|||||||
|
|
||||||
// Add config entry.
|
// Add config entry.
|
||||||
f_puts("[emusd]\nenabled=", &fp);
|
f_puts("[emusd]\nenabled=", &fp);
|
||||||
if(sector_start){
|
if((sector_start || path) && drive == DRIVE_SD) {
|
||||||
|
f_puts("1", &fp);
|
||||||
|
} else if((sector_start || path) && drive == DRIVE_EMMC){
|
||||||
f_puts("4", &fp);
|
f_puts("4", &fp);
|
||||||
}else{
|
}else{
|
||||||
f_puts("0", &fp);
|
f_puts("0", &fp);
|
||||||
@@ -66,13 +73,142 @@ void save_emusd_cfg(u32 part_idx, u32 sector_start){
|
|||||||
itoa(sector_start, lbuf, 16);
|
itoa(sector_start, lbuf, 16);
|
||||||
f_puts(lbuf, &fp);
|
f_puts(lbuf, &fp);
|
||||||
}
|
}
|
||||||
f_puts("\n", &fp);
|
|
||||||
|
|
||||||
|
if(path){
|
||||||
|
f_puts("\npath=", &fp);
|
||||||
|
f_puts(path, &fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_puts("\n", &fp);
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name){
|
static void update_base_path(char *path, int idx, int path_len) {
|
||||||
sfd_init(&emmc_storage, sector_start, sector_size);
|
if(idx < 10){
|
||||||
|
path[path_len] = '0';
|
||||||
|
itoa(idx, path + path_len + 1, 10);
|
||||||
|
}else{
|
||||||
|
itoa(idx, path + path_len, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_emusd_file(u32 size_sct, u8 drive) {
|
||||||
|
static const u32 file_max_scts = 0xfe000000 / 0x200;
|
||||||
|
|
||||||
|
char path[0x80];
|
||||||
|
if (drive == DRIVE_SD){
|
||||||
|
strcpy(path, "sd:emuSD/SD");
|
||||||
|
f_mkdir("sd:emuSD");
|
||||||
|
}else {
|
||||||
|
strcpy(path, "emmc:emuSD/EMMC");
|
||||||
|
f_mkdir("emmc:emuSD");
|
||||||
|
}
|
||||||
|
int path_len = strlen(path);
|
||||||
|
|
||||||
|
f_mkdir("emuSD");
|
||||||
|
|
||||||
|
for(int j = 0; j < 100; j++){
|
||||||
|
update_base_path(path, j, path_len);
|
||||||
|
if(f_stat(path, NULL) == FR_NO_FILE){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f_mkdir(path);
|
||||||
|
f_mkdir(path + (drive == DRIVE_SD ? 3 : 5));
|
||||||
|
|
||||||
|
u32 base_path_len = strlen(path);
|
||||||
|
|
||||||
|
strcat(path, "/SD");
|
||||||
|
f_mkdir(path);
|
||||||
|
|
||||||
|
strcat(path, "/");
|
||||||
|
path_len = strlen(path);
|
||||||
|
|
||||||
|
// allocate files for emusd
|
||||||
|
u32 sct_left = size_sct;
|
||||||
|
u32 idx = 0;
|
||||||
|
|
||||||
|
gfx_printf("sct left 0x%x\n", sct_left);
|
||||||
|
while(sct_left) {
|
||||||
|
update_base_path(path, idx, path_len);
|
||||||
|
|
||||||
|
u32 scts = MIN(sct_left, file_max_scts);
|
||||||
|
|
||||||
|
FIL f;
|
||||||
|
int res = f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
|
if(res != FR_OK) {
|
||||||
|
gfx_printf("open fail\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSIZE_t seek_bytes = (FSIZE_t)scts << 9;
|
||||||
|
res = f_lseek(&f, seek_bytes);
|
||||||
|
f_close(&f);
|
||||||
|
|
||||||
|
if(res != FR_OK){
|
||||||
|
f_unlink(path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sct_left -= scts;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
path[path_len] = '\0';
|
||||||
|
|
||||||
|
sfd_file_based_init(path);
|
||||||
|
|
||||||
|
u8 *buf = malloc(SZ_4M);
|
||||||
|
u32 cluster_size = 65536;
|
||||||
|
|
||||||
|
int res = f_mkfs("sfd:", FM_FAT32, cluster_size, buf, SZ_4M);
|
||||||
|
|
||||||
|
while (res != FR_OK && cluster_size > 4096){
|
||||||
|
cluster_size /= 2;
|
||||||
|
res = f_mkfs("sfd:", FM_FAT32, cluster_size, buf, SZ_4M);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res == FR_OK){
|
||||||
|
FATFS fs;
|
||||||
|
res = f_mount(&fs, "sfd:", 1);
|
||||||
|
|
||||||
|
if(res == FR_OK){
|
||||||
|
gfx_printf("mount fail %d\n", res);
|
||||||
|
char label[0x30];
|
||||||
|
strcpy(label, "sfd:emusd");
|
||||||
|
res = f_setlabel(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_mount(NULL, "sfd:", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sfd_end();
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
if(res != FR_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
path[base_path_len] = '\0';
|
||||||
|
s_printf(path + base_path_len, drive == DRIVE_SD ? "/file_based" : "/file_emmc_based");
|
||||||
|
FIL f;
|
||||||
|
res = f_open(&f, path + (drive == DRIVE_SD ? 3 : 5), FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
|
f_close(&f);
|
||||||
|
gfx_printf("%s %d\n", path, res);
|
||||||
|
|
||||||
|
path[base_path_len] = '\0';
|
||||||
|
save_emusd_cfg(0, 0, path + (drive == DRIVE_SD ? 3 : 5), drive);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name, u8 drive){
|
||||||
|
sdmmc_storage_t *storage = drive == DRIVE_SD ? &sd_storage : &emmc_storage;
|
||||||
|
|
||||||
|
sfd_init(storage, sector_start, sector_size);
|
||||||
|
|
||||||
u8 *buf = malloc(SZ_4M);
|
u8 *buf = malloc(SZ_4M);
|
||||||
FIL f;
|
FIL f;
|
||||||
@@ -109,7 +245,7 @@ int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size
|
|||||||
mbr.partitions[0].size_sct = sector_size;
|
mbr.partitions[0].size_sct = sector_size;
|
||||||
mbr.partitions[0].type = 0x0c;
|
mbr.partitions[0].type = 0x0c;
|
||||||
|
|
||||||
mkfs_error = sdmmc_storage_write(&emmc_storage, sector_mbr, 1, &mbr) ? FR_OK : FR_DISK_ERR;
|
mkfs_error = sdmmc_storage_write(storage, sector_mbr, 1, &mbr) ? FR_OK : FR_DISK_ERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,5 +255,22 @@ int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size
|
|||||||
|
|
||||||
sfd_end();
|
sfd_end();
|
||||||
|
|
||||||
return mkfs_error;
|
if(mkfs_error != FR_OK){
|
||||||
|
return mkfs_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[0x80];
|
||||||
|
strcpy(path, "emuSD");
|
||||||
|
f_mkdir(path);
|
||||||
|
s_printf(path + strlen(path), "/RAW_%s%d", drive == DRIVE_SD ? "SD" : "EMMC", part_idx);
|
||||||
|
f_mkdir(path);
|
||||||
|
strcat(path, "/raw_emmc_based");
|
||||||
|
|
||||||
|
f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
|
f_write(&f, §or_mbr, 4, NULL);
|
||||||
|
f_close(&f);
|
||||||
|
|
||||||
|
save_emusd_cfg(part_idx, sector_mbr, NULL, drive);
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,11 @@ typedef struct _emusd_cfg_t{
|
|||||||
// 0: disabled, 1: enabled
|
// 0: disabled, 1: enabled
|
||||||
int enabled;
|
int enabled;
|
||||||
u32 sector;
|
u32 sector;
|
||||||
|
char *path;
|
||||||
} emusd_cfg_t;
|
} emusd_cfg_t;
|
||||||
|
|
||||||
void load_emusd_cfg(emusd_cfg_t *emu_info);
|
void load_emusd_cfg(emusd_cfg_t *emu_info);
|
||||||
void save_emusd_cfg(u32 part_idx, u32 sector_start);
|
void save_emusd_cfg(u32 part_idx, u32 sector_start, const char *path, u8 drive);
|
||||||
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name);
|
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name, u8 drive);
|
||||||
|
int create_emusd_file(u32 size_sct, u8 drive);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -864,7 +864,7 @@ static lv_res_t _create_mbox_emummc_create(lv_obj_t *btn)
|
|||||||
"Welcome to #C7EA46 emuMMC# creation tool!\n\n"
|
"Welcome to #C7EA46 emuMMC# creation tool!\n\n"
|
||||||
"Please choose what type of emuMMC you want to create.\n"
|
"Please choose what type of emuMMC you want to create.\n"
|
||||||
"#FF8000 File based# is saved as files in\nthe SD or eMMC FAT partition.\n"
|
"#FF8000 File based# is saved as files in\nthe SD or eMMC FAT partition.\n"
|
||||||
"#FF8000 Partition based# is saved as raw image in a\navailable SD or eMMC partition.");
|
"#FF8000 Partition based# is saved as raw image in an\navailable SD or eMMC partition.");
|
||||||
|
|
||||||
lv_mbox_add_btns(mbox, mbox_btn_map, _create_emummc_select_type_action);
|
lv_mbox_add_btns(mbox, mbox_btn_map, _create_emummc_select_type_action);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@
|
|||||||
#include <storage/boot_storage.h>
|
#include <storage/boot_storage.h>
|
||||||
#include <storage/emmc.h>
|
#include <storage/emmc.h>
|
||||||
#include <storage/emummc_file_based.h>
|
#include <storage/emummc_file_based.h>
|
||||||
|
#include <storage/file_based_storage.h>
|
||||||
#include <storage/mbr_gpt.h>
|
#include <storage/mbr_gpt.h>
|
||||||
#include <storage/sd.h>
|
#include <storage/sd.h>
|
||||||
#include <storage/sdmmc.h>
|
#include <storage/sdmmc.h>
|
||||||
@@ -380,6 +381,12 @@ static lv_res_t _create_mbox_ums_error(int error)
|
|||||||
case 8:
|
case 8:
|
||||||
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuMMC!#");
|
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuMMC!#");
|
||||||
break;
|
break;
|
||||||
|
case 9:
|
||||||
|
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuSD!#");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 No emuSD found active!#");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
|
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
|
||||||
@@ -558,42 +565,103 @@ static lv_res_t _action_ums_emusd(lv_obj_t * btn){
|
|||||||
}
|
}
|
||||||
|
|
||||||
usb_ctxt_t usbs;
|
usb_ctxt_t usbs;
|
||||||
|
sdmmc_storage_t *storage;
|
||||||
emusd_cfg_t emu_info;
|
emusd_cfg_t emu_info;
|
||||||
|
|
||||||
|
bool file_based = false;
|
||||||
int error = !boot_storage_mount();
|
int error = !boot_storage_mount();
|
||||||
|
char path[0x80];
|
||||||
|
|
||||||
if(!error){
|
if(!error){
|
||||||
load_emusd_cfg(&emu_info);
|
load_emusd_cfg(&emu_info);
|
||||||
if(emu_info.enabled){
|
if(emu_info.enabled){
|
||||||
if(!emmc_initialize(false)){
|
error = 0;
|
||||||
error = 3;
|
if(emu_info.enabled == 4 && emu_info.sector){
|
||||||
}else{
|
if(!emmc_initialize(false)){
|
||||||
mbr_t mbr = {0};
|
|
||||||
|
|
||||||
if(sdmmc_storage_read(&emmc_storage, emu_info.sector, 1, &mbr)){
|
|
||||||
error = 0;
|
|
||||||
usbs.offset = emu_info.sector;
|
|
||||||
usbs.sectors = mbr.partitions[0].size_sct;
|
|
||||||
usbs.type = MMC_EMMC;
|
|
||||||
usbs.partition = EMMC_GPP + 1;
|
|
||||||
usbs.ro = false;
|
|
||||||
usbs.system_maintenance = &manual_system_maintenance;
|
|
||||||
usbs.set_text = &usb_gadget_set_text;
|
|
||||||
}else{
|
|
||||||
error = 3;
|
error = 3;
|
||||||
}
|
}
|
||||||
|
storage = &emmc_storage;
|
||||||
|
}else if(emu_info.enabled == 1 && emu_info.sector){
|
||||||
|
if(!sd_initialize(false)){
|
||||||
|
error = 4;
|
||||||
|
}
|
||||||
|
storage = &sd_storage;
|
||||||
|
}else if((emu_info.enabled == 1 || emu_info.enabled == 4) && !emu_info.sector){
|
||||||
|
if(emu_info.enabled == 1){
|
||||||
|
if(!sd_mount()){
|
||||||
|
error = 4;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!emmc_mount()){
|
||||||
|
error = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(error == 0){
|
||||||
|
file_based = true;
|
||||||
|
if(emu_info.enabled ==1){
|
||||||
|
strcpy(path, "sd:");
|
||||||
|
}else{
|
||||||
|
strcpy(path, "emmc:");
|
||||||
|
}
|
||||||
|
strcat(path, emu_info.path);
|
||||||
|
strcat(path, "/SD/");
|
||||||
|
if(!file_based_storage_init(path)){
|
||||||
|
error = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
error = 10;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
error = 7;
|
error = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(error == 0 && emu_info.enabled){
|
||||||
|
error = 6;
|
||||||
|
if(file_based){
|
||||||
|
usbs.offset = 0;
|
||||||
|
}else{
|
||||||
|
usbs.offset = emu_info.sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_based){
|
||||||
|
error = 9;
|
||||||
|
u32 sz = file_based_storage_get_total_size();
|
||||||
|
if(sz){
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
usbs.sectors = sz;
|
||||||
|
}else{
|
||||||
|
error = 3;
|
||||||
|
mbr_t mbr;
|
||||||
|
if(sdmmc_storage_read(storage, emu_info.sector, 1, &mbr)){
|
||||||
|
error = 0;
|
||||||
|
usbs.sectors = mbr.partitions[0].size_sct + mbr.partitions[0].start_sct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(emu_info.path){
|
||||||
|
free(emu_info.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(error){
|
if(error){
|
||||||
_create_mbox_ums_error(error);
|
_create_mbox_ums_error(error);
|
||||||
}else{
|
}else{
|
||||||
|
if(file_based){
|
||||||
|
usbs.type = MMC_FILE_BASED;
|
||||||
|
}else{
|
||||||
|
usbs.type = emu_info.enabled == 1 ? MMC_SD : MMC_EMMC;
|
||||||
|
}
|
||||||
|
usbs.partition = EMMC_GPP + 1;
|
||||||
|
usbs.ro = false;
|
||||||
|
usbs.system_maintenance = &manual_system_maintenance;
|
||||||
|
usbs.set_text = &usb_gadget_set_text;
|
||||||
_create_mbox_ums(&usbs, NYX_UMS_EMUSD);
|
_create_mbox_ums(&usbs, NYX_UMS_EMUSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file_based_storage_end();
|
||||||
boot_storage_unmount();
|
boot_storage_unmount();
|
||||||
|
|
||||||
return LV_RES_OK;
|
return LV_RES_OK;
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
#include "sfd.h"
|
#include "sfd.h"
|
||||||
#include <storage/emmc.h>
|
#include <storage/emmc.h>
|
||||||
#include <storage/sdmmc.h>
|
#include <storage/sdmmc.h>
|
||||||
|
#include <storage/file_based_storage.h>
|
||||||
#include <libs/fatfs/diskio.h>
|
#include <libs/fatfs/diskio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
static bool file_based;
|
||||||
static sdmmc_storage_t *_storage;
|
static sdmmc_storage_t *_storage;
|
||||||
static u32 _offset;
|
static u32 _offset;
|
||||||
static u32 _size;
|
static u32 _size;
|
||||||
@@ -14,7 +18,11 @@ static void ensure_partition(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
sdmmc_storage_t *sfd_get_storage(){
|
sdmmc_storage_t *sfd_get_storage(){
|
||||||
return _storage;
|
if(file_based){
|
||||||
|
return NULL;
|
||||||
|
}else{
|
||||||
|
return _storage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfd_read(u32 sector, u32 count, void *buff){
|
int sfd_read(u32 sector, u32 count, void *buff){
|
||||||
@@ -22,8 +30,13 @@ int sfd_read(u32 sector, u32 count, void *buff){
|
|||||||
if(sector + count > _size){
|
if(sector + count > _size){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ensure_partition();
|
|
||||||
res = sdmmc_storage_read(_storage, sector + _offset, count, buff);
|
if(file_based){
|
||||||
|
res = file_based_storage_read(sector, count, buff);
|
||||||
|
}else{
|
||||||
|
ensure_partition();
|
||||||
|
res = sdmmc_storage_read(_storage, sector + _offset, count, buff);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,8 +45,14 @@ int sfd_write(u32 sector, u32 count, void *buff){
|
|||||||
if(sector + count > _size){
|
if(sector + count > _size){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ensure_partition();
|
|
||||||
res = sdmmc_storage_write(_storage, sector + _offset, count, buff);
|
if(file_based){
|
||||||
|
res = file_based_storage_write(sector, count, buff);
|
||||||
|
}else{
|
||||||
|
ensure_partition();
|
||||||
|
res = sdmmc_storage_write(_storage, sector + _offset, count, buff);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,10 +64,23 @@ bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sfd_file_based_init(const char *base_path) {
|
||||||
|
file_based = true;
|
||||||
|
if(!file_based_storage_init(base_path)){
|
||||||
|
gfx_printf("file based init fail\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_size = file_based_storage_get_total_size();
|
||||||
|
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &_size);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void sfd_end(){
|
void sfd_end(){
|
||||||
_storage = NULL;
|
_storage = NULL;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
|
file_based = false;
|
||||||
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &size);
|
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &size);
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
int sfd_read(u32 sector, u32 count, void *buff);
|
int sfd_read(u32 sector, u32 count, void *buff);
|
||||||
int sfd_write(u32 sector, u32 count, void *buff);
|
int sfd_write(u32 sector, u32 count, void *buff);
|
||||||
|
|
||||||
|
bool sfd_file_based_init(const char *base_path);
|
||||||
bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size);
|
bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size);
|
||||||
void sfd_end();
|
void sfd_end();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user