diff --git a/Makefile b/Makefile index 00f20cd3..1d1b89e8 100755 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ fuse.o kfuse.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 \ - hw_init.o boot_storage.o \ + hw_init.o boot_storage.o emusd.o file_based_storage.o \ ) # Utilities. diff --git a/bdk/storage/file_based_storage.c b/bdk/storage/file_based_storage.c new file mode 100644 index 00000000..3ba9e0e1 --- /dev/null +++ b/bdk/storage/file_based_storage.c @@ -0,0 +1,190 @@ +#include "file_based_storage.h" +#include +#include +#include +#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; +} \ No newline at end of file diff --git a/bdk/storage/file_based_storage.h b/bdk/storage/file_based_storage.h new file mode 100644 index 00000000..3de29b4b --- /dev/null +++ b/bdk/storage/file_based_storage.h @@ -0,0 +1,15 @@ +#ifndef _FILE_BASED_STORAGE_H +#define _FILE_BASED_STORAGE_H + +#include + + +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 \ No newline at end of file diff --git a/bdk/storage/sdmmc.h b/bdk/storage/sdmmc.h index 9808e476..db3b0693 100644 --- a/bdk/storage/sdmmc.h +++ b/bdk/storage/sdmmc.h @@ -35,6 +35,7 @@ typedef enum _sdmmc_type MMC_EMUMMC_RAW_SD = 3, MMC_EMUMMC_RAW_EMMC = 4, MMC_EMUMMC_FILE_EMMC = 5, + MMC_FILE_BASED = 6, EMMC_GPP = 0, EMMC_BOOT0 = 1, diff --git a/bdk/usb/usb_gadget_ums.c b/bdk/usb/usb_gadget_ums.c index 693314d0..42124792 100644 --- a/bdk/usb/usb_gadget_ums.c +++ b/bdk/usb/usb_gadget_ums.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -500,6 +501,10 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) if(ums->lun.storage){ if (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, sdmmc_buf)) 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{ if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, sdmmc_buf)){ 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, amount >> UMS_DISK_LBA_SHIFT, (u8 *)bulk_ctxt->bulk_out_buf)) 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{ if(!emummc_storage_file_based_write(ums->lun.offset + lba_offset, amount >> UMS_DISK_LBA_SHIFT, (u8*)bulk_ctxt->bulk_out_buf)){ 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 (!sdmmc_storage_read(ums->lun.storage, ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)) 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{ if(!emummc_storage_file_based_read(ums->lun.offset + lba_offset, amount, bulk_ctxt->bulk_in_buf)){ amount = 0; @@ -1934,6 +1947,10 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) } ums.lun.storage = 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{ if (!emmc_initialize(false)) { @@ -1980,6 +1997,9 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs) case MMC_EMUMMC_RAW_EMMC: ums.set_text(ums.label, "#FFDD00 No sector count set for emuMMC!#"); break; + case MMC_FILE_BASED: + ums.set_text(ums.label, "#FFDD00 No sector count set for emuSD!#"); + break; } } diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 2c888fe7..693e45f0 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -782,9 +782,15 @@ void hos_launch(ini_sec_t *cfg) 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. - // TODO: not relevant with emuSD - if (sd_is_gpt()) + if (emusd_is_gpt()) { _hos_crit_error("SD has GPT only! Run Fix Hybrid MBR!"); goto error; @@ -804,6 +810,8 @@ void hos_launch(ini_sec_t *cfg) if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled())) { sdram_src_pllc(false); + emummc_storage_end(); + emusd_storage_end(); emmc_end(); 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); - 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!"); @@ -1086,6 +1094,8 @@ void hos_launch(ini_sec_t *cfg) config_exosphere(&ctxt, warmboot_base); // Unmount SD card and eMMC. + emummc_storage_end(); + emusd_storage_end(); boot_storage_end(); sd_end(); emmc_end(); @@ -1201,6 +1211,8 @@ void hos_launch(ini_sec_t *cfg) error: _free_launch_components(&ctxt); sdram_src_pllc(false); + emummc_storage_end(); + emusd_storage_end(); emmc_end(); EPRINTF("\nFailed to launch HOS!"); diff --git a/bootloader/hos/hos_config.c b/bootloader/hos/hos_config.c index ea7e8a07..05822b77 100644 --- a/bootloader/hos/hos_config.c +++ b/bootloader/hos/hos_config.c @@ -16,6 +16,7 @@ */ #include +#include "../storage/emusd.h" #include #include @@ -30,7 +31,7 @@ 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) 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) { - ctxt->secmon = boot_storage_file_read(value, &ctxt->secmon_size); + ctxt->secmon = emusd_file_read(value, &ctxt->secmon_size); if (!ctxt->secmon) 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) { - ctxt->kernel = boot_storage_file_read(value, &ctxt->kernel_size); + ctxt->kernel = emusd_file_read(value, &ctxt->kernel_size); if (!ctxt->kernel) return 0; @@ -62,7 +63,8 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value) if (value[strlen(value) - 1] == '*') { char *dir = (char *)malloc(256); - strcpy(dir, value); + strcpy(dir, "emusd:"); + strcat(dir, value); u32 dirlen = 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]); 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) { free(mkip1); @@ -104,7 +106,7 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value) else { 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) { 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) { - ctxt->exofatal = boot_storage_file_read(value, &ctxt->exofatal_size); + ctxt->exofatal = emusd_file_read(value, &ctxt->exofatal_size); if (!ctxt->exofatal) return 0; diff --git a/bootloader/hos/pkg1.c b/bootloader/hos/pkg1.c index e1d52b07..071caf31 100644 --- a/bootloader/hos/pkg1.c +++ b/bootloader/hos/pkg1.c @@ -18,6 +18,7 @@ */ #include +#include "../storage/emusd.h" #include #include @@ -370,13 +371,13 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb) if (!ctxt->warmboot) { char path[128]; - strcpy(path, "warmboot_mariko/wb_"); + strcpy(path, "emusd:warmboot_mariko/wb_"); _warmboot_filename(path, fuses_fw); // Check if warmboot fw exists and save it. 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); } @@ -389,7 +390,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb) _warmboot_filename(path, burnt_fuses); 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; break; } diff --git a/bootloader/hos/pkg2.c b/bootloader/hos/pkg2.c index 6a71f5bc..7bcf2ad7 100644 --- a/bootloader/hos/pkg2.c +++ b/bootloader/hos/pkg2.c @@ -77,6 +77,7 @@ static void parse_external_kip_patches() return; LIST_INIT(ini_kip_sections); + // TODO: load frome emusd? if (ini_patch_parse(&ini_kip_sections, "bootloader/patches.ini")) { // Copy ids into a new patchset. diff --git a/bootloader/hos/pkg3.c b/bootloader/hos/pkg3.c index f069c13c..d4b8e512 100644 --- a/bootloader/hos/pkg3.c +++ b/bootloader/hos/pkg3.c @@ -17,6 +17,7 @@ */ #include +#include "../storage/emusd.h" #include #include @@ -87,9 +88,9 @@ typedef struct _pkg3_content_t 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); } @@ -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) { + char *path1 = (char *)malloc(256); + strcpy(path1, "emusd:"); + strcat(path1, path); + FIL fp; char **pkg3_kip1_skip = NULL; @@ -154,16 +159,25 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path) } #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; + } + #else - if (stock && emummc_disabled && pkg1_old) + if (stock && emummc_disabled && pkg1_old) { + free(path1); return 1; + } + #endif // 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; + } + void *pkg3 = malloc(f_size(&fp)); @@ -269,6 +283,7 @@ int parse_pkg3(launch_ctxt_t *ctxt, const char *path) _pkg3_update_r2p(); free(pkg3_kip1_skip); + free(path1); return 1; } diff --git a/bootloader/hos/secmon_exo.c b/bootloader/hos/secmon_exo.c index ea95442b..43156784 100644 --- a/bootloader/hos/secmon_exo.c +++ b/bootloader/hos/secmon_exo.c @@ -77,6 +77,7 @@ typedef struct union { emummc_partition_config_t partition_cfg; + emummc_file_config_t file_cfg; }; } emummc_sd_config_t; @@ -226,7 +227,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base) if (!ctxt->stock) { 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) { @@ -265,7 +266,7 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base) if (!ctxt->exo_ctx.usb3_force) { 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) { @@ -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.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; - }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; } + 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 { exo_cfg->emummc_cfg.sd_cfg.base_cfg.type = EmummcType_None; } diff --git a/bootloader/libs/fatfs/diskio.c b/bootloader/libs/fatfs/diskio.c index 3404bc4a..df8f3371 100644 --- a/bootloader/libs/fatfs/diskio.c +++ b/bootloader/libs/fatfs/diskio.c @@ -7,9 +7,9 @@ /* storage control modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ +#include "../../storage/emusd.h" #include #include -#include #include @@ -28,6 +28,8 @@ static bool ensure_partition(BYTE pdrv){ case DRIVE_EMMC: part = EMMC_GPP; break; + case DRIVE_EMUSD: + return true; default: return false; } @@ -86,6 +88,9 @@ DRESULT disk_read ( storage = &emmc_storage; actual_sector = sector + (0x100000 / 512); break; + case DRIVE_EMUSD: + return emusd_storage_read(sector, count, buff) ? RES_OK : RES_ERROR; + break; default: return RES_ERROR; @@ -122,6 +127,8 @@ DRESULT disk_write ( storage = &emmc_storage; actual_sector = sector + (0x100000 / 512); break; + case DRIVE_EMUSD: + return emusd_storage_write(sector, count, (void*)buff) ? RES_OK : RES_ERROR; default: return RES_ERROR; diff --git a/bootloader/libs/fatfs/ffconf.h b/bootloader/libs/fatfs/ffconf.h index 7de7fc44..5cacafdc 100644 --- a/bootloader/libs/fatfs/ffconf.h +++ b/bootloader/libs/fatfs/ffconf.h @@ -179,12 +179,12 @@ / Drive/Volume Configurations /---------------------------------------------------------------------------*/ -#define FF_VOLUMES 4 +#define FF_VOLUMES 5 /* Number of volumes (logical drives) to be used. (1-10) */ #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. / 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 @@ -306,6 +306,7 @@ typedef enum { DRIVE_BOOT1 = 1, DRIVE_BOOT1_1MB = 2, DRIVE_EMMC = 3, + DRIVE_EMUSD = 4, } DDRIVE; /*--- End of configuration options ---*/ diff --git a/bootloader/main.c b/bootloader/main.c index 11083e80..b63995ed 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -418,7 +418,8 @@ static void _launch_ini_list() } 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; } } @@ -579,7 +580,8 @@ static void _launch_config() 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; } } @@ -1056,7 +1058,8 @@ skip_list: if (emusd_path && !emusd_set_path(emusd_path)) { gfx_con.mute = false; - EPRINTF("emusdpath is wrong!"); + EPRINTFARGS("path: %s", emusd_path); + EPRINTF("error: emusdpath is wrong!"); goto wrong_emupath; } diff --git a/bootloader/storage/emummc.c b/bootloader/storage/emummc.c index 36b192fd..b1e14a41 100644 --- a/bootloader/storage/emummc.c +++ b/bootloader/storage/emummc.c @@ -24,7 +24,6 @@ #include "emummc.h" #include "../config.h" -#include "gfx_utils.h" #include #include @@ -174,11 +173,6 @@ static int emummc_raw_get_part_off(int part_idx) int emummc_storage_init_mmc() { - gfx_con.mute = false; - - - gfx_printf("en %d path %s\n", emu_cfg.enabled, emu_cfg.path); - // FILINFO fno; emu_cfg.active_part = 0; @@ -263,33 +257,6 @@ int emummc_storage_read(u32 sector, u32 num_sectors, void *buf) else { 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; @@ -310,31 +277,6 @@ int emummc_storage_write(u32 sector, u32 num_sectors, void *buf) else { 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; } } diff --git a/bootloader/storage/emusd.c b/bootloader/storage/emusd.c index 89a1aa7e..7d0c33a7 100644 --- a/bootloader/storage/emusd.c +++ b/bootloader/storage/emusd.c @@ -1,9 +1,26 @@ #include "emusd.h" #include +#include +#include +#include +#include +#include #include #include +#include +#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}; +extern hekate_config h_cfg; + +static bool emusd_get_mounted() { + return emusd_mounted; +} void emusd_load_cfg() { @@ -14,7 +31,7 @@ void emusd_load_cfg() if(!emu_sd_cfg.path) { 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); } @@ -35,6 +52,8 @@ void emusd_load_cfg() emu_sd_cfg.enabled = atoi(kv->val); } else if(!strcmp(kv->key, "sector")){ emu_sd_cfg.sector = strtol(kv->val, NULL, 16); + } else if(!strcmp(kv->key, "path")){ + emu_sd_cfg.path = kv->val; } } 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) { + gfx_con.mute = false; FIL fp; bool found = false; - char sd_path[0x80]; - // TODO: use emu_sd.file_path instead - strcpy(sd_path, path); - strcat(sd_path, "/raw_emmc_based"); - - if(!f_open(&fp, sd_path, FA_READ)) + strcat(emu_sd_cfg.emummc_file_based_path, ""); + strcpy(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; @@ -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; +} + +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); + } } \ No newline at end of file diff --git a/bootloader/storage/emusd.h b/bootloader/storage/emusd.h index f6839677..1ae7a9bb 100644 --- a/bootloader/storage/emusd.h +++ b/bootloader/storage/emusd.h @@ -40,5 +40,10 @@ int emusd_storage_end(); int emusd_storage_read(u32 sector, u32 num_sectors, void *buf); int emusd_storage_write(u32 sector, u32 num_sectors, void *buf); 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 \ No newline at end of file diff --git a/nyx/Makefile b/nyx/Makefile index efc04a53..d9b2dc81 100644 --- a/nyx/Makefile +++ b/nyx/Makefile @@ -41,7 +41,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \ touch.o joycon.o tmp451.o fan.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. diff --git a/nyx/nyx_gui/frontend/fe_emusd_tools.c b/nyx/nyx_gui/frontend/fe_emusd_tools.c index 877e0344..426a9876 100644 --- a/nyx/nyx_gui/frontend/fe_emusd_tools.c +++ b/nyx/nyx_gui/frontend/fe_emusd_tools.c @@ -5,11 +5,14 @@ #include #include #include +#include #include #include #include #include +#include "gfx_utils.h" #include +#include void load_emusd_cfg(emusd_cfg_t *emu_info){ 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); else if(!strcmp("sector", kv->key)) emu_info->sector = strtol(kv->val, NULL, 16); - /*else (!strcmp("id", kv->key)) - emu_info->id = strtol(kv->val, NULL, 16);*/ + else if(!strcmp("path", kv->key)){ + emu_info->path =(char*)malloc(strlen(kv->val)+1); + strcpy(emu_info->path, kv->val); + } } break; @@ -40,7 +45,7 @@ void load_emusd_cfg(emusd_cfg_t *emu_info){ 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(); char lbuf[16]; @@ -53,7 +58,9 @@ void save_emusd_cfg(u32 part_idx, u32 sector_start){ // Add config entry. 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); }else{ f_puts("0", &fp); @@ -66,13 +73,142 @@ void save_emusd_cfg(u32 part_idx, u32 sector_start){ itoa(sector_start, lbuf, 16); 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); } -int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name){ - sfd_init(&emmc_storage, sector_start, sector_size); +static void update_base_path(char *path, int idx, int path_len) { + 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); 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].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(); - 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; } \ No newline at end of file diff --git a/nyx/nyx_gui/frontend/fe_emusd_tools.h b/nyx/nyx_gui/frontend/fe_emusd_tools.h index 2eddc296..b53f977f 100644 --- a/nyx/nyx_gui/frontend/fe_emusd_tools.h +++ b/nyx/nyx_gui/frontend/fe_emusd_tools.h @@ -7,10 +7,11 @@ typedef struct _emusd_cfg_t{ // 0: disabled, 1: enabled int enabled; u32 sector; + char *path; } emusd_cfg_t; void load_emusd_cfg(emusd_cfg_t *emu_info); -void save_emusd_cfg(u32 part_idx, u32 sector_start); -int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name); - +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, u8 drive); +int create_emusd_file(u32 size_sct, u8 drive); #endif diff --git a/nyx/nyx_gui/frontend/gui_emummc_tools.c b/nyx/nyx_gui/frontend/gui_emummc_tools.c index d02f8747..2fc669d6 100644 --- a/nyx/nyx_gui/frontend/gui_emummc_tools.c +++ b/nyx/nyx_gui/frontend/gui_emummc_tools.c @@ -864,7 +864,7 @@ static lv_res_t _create_mbox_emummc_create(lv_obj_t *btn) "Welcome to #C7EA46 emuMMC# creation tool!\n\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 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); diff --git a/nyx/nyx_gui/frontend/gui_emusd_tools.c b/nyx/nyx_gui/frontend/gui_emusd_tools.c index aef18c51..0c9217c7 100644 --- a/nyx/nyx_gui/frontend/gui_emusd_tools.c +++ b/nyx/nyx_gui/frontend/gui_emusd_tools.c @@ -2,6 +2,7 @@ #include "fe_emusd_tools.h" #include "gui_tools_partition_manager.h" #include "gui.h" +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +33,7 @@ typedef struct _gpt_ctxt_t{ } gpt_ctxt_t; static gpt_ctxt_t gpt_ctxt; - +static u8 emusd_drive; static lv_obj_t *emusd_parent_cont; static lv_res_t (*emusd_tools)(lv_obj_t *parent); @@ -71,74 +73,53 @@ static lv_res_t _close_mbox_and_reload(lv_obj_t *btns, const char *txt){ return LV_RES_INV; } -static void _create_emusd(u8 idx){ - boot_storage_mount(); - emmc_initialize(false); - - - static const char *mbox_btn_map[] = { "\251", "\222OK", "\251", "" }; - - lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); - lv_obj_set_style(dark_bg, &mbox_darken); - lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); - - lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); - lv_mbox_set_recolor_text(mbox, true); - lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); - - char *txt_buf = malloc(SZ_16K); - - strcpy(txt_buf, "#FF8000 emuSD creation tool#\n\n" - "#00DDFF Status:# Formatting emuSD partition..."); - - lv_mbox_set_text(mbox, txt_buf); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_top(mbox, true); - - manual_system_maintenance(true); - - int res = create_emusd(gpt_ctxt.part_idx[idx], gpt_ctxt.sector_mbr[idx], gpt_ctxt.sector[idx], gpt_ctxt.size[idx], gpt_ctxt.name[idx]); - - if(res == FR_OK){ - strcpy(txt_buf, "#FF8000 emuSD creation tool#\n\n" - "#00DDFF Status:# Done!"); - - char path[0x80]; - strcpy(path, "emuSD"); - f_mkdir(path); - s_printf(path + strlen(path), "/RAW_EMMC%d", gpt_ctxt.part_idx[idx]); - f_mkdir(path); - strcat(path, "/raw_emmc_based"); - - FIL f; - f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE); - f_write(&f, &gpt_ctxt.sector_mbr[idx], 4, NULL); - f_close(&f); - - save_emusd_cfg(gpt_ctxt.part_idx[idx], gpt_ctxt.sector_mbr[idx]); - }else{ - strcpy(txt_buf, "#FF8000 emuSD creation tool#\n\n" - "#00DDFF Status:# Failed to format partition!"); - } - - lv_mbox_set_text(mbox, txt_buf); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - lv_mbox_add_btns(mbox, mbox_btn_map, _close_mbox_and_reload); - manual_system_maintenance(true); - - boot_storage_unmount(); - emmc_end(); - - free(txt_buf); -} - static lv_res_t _emusd_create_action(lv_obj_t *btns, const char *txt){ - u32 idx = lv_btnm_get_pressed(btns); - + int idx = lv_btnm_get_pressed(btns); mbox_action(btns, txt); - if(idx < gpt_ctxt.cnt){ - _create_emusd(idx); + if(idx < gpt_ctxt.cnt) { + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char *mbox_btns_map[] = { "\251", "\222OK", "\251", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); + + lv_mbox_set_text(mbox, + "#FF8000 emuSD creation tool#\n\n" + "#00DDFF Status:# Creating partition based emuSD..."); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + manual_system_maintenance(true); + + if(emusd_drive == DRIVE_SD){ + sd_initialize(false); + }else{ + emmc_initialize(false); + } + boot_storage_mount(); + int res = create_emusd(gpt_ctxt.part_idx[idx], gpt_ctxt.sector_mbr[idx], gpt_ctxt.sector[idx], gpt_ctxt.size[idx], gpt_ctxt.name[idx], emusd_drive); + boot_storage_unmount(); + if(emusd_drive == DRIVE_SD){ + sd_end(false); + }else{ + emmc_end(false); + } + if(res){ + lv_mbox_set_text(mbox, + "#FF8000 emuSD creation tool#\n\n" + "#00DDFF Status:# Done!"); + }else{ + lv_mbox_set_text(mbox, + "#FF8000 emuSD creation tool#\n\n" + "#00DDFF Status:# Failed to create emuSD!"); + } + + lv_mbox_add_btns(mbox, mbox_btns_map, _close_mbox_and_reload); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); } return LV_RES_INV; @@ -149,40 +130,96 @@ static lv_res_t _emusd_format_action(lv_obj_t *btns, const char *txt){ mbox_action(btns, txt); - if(idx){ - create_window_partition_manager(btns, DRIVE_EMMC); + if(!idx){ + create_window_partition_manager(btns, emusd_drive); } return LV_RES_INV; } -static void _change_emusd(u8 idx){ - boot_storage_mount(); - save_emusd_cfg(gpt_ctxt.part_idx[gpt_ctxt.valid_parts[idx]], gpt_ctxt.sector_mbr[gpt_ctxt.valid_parts[idx]]); - boot_storage_unmount(); +typedef struct _slider_ctx_t{ + lv_obj_t *label; + u32 emu_size; // mb +} slider_ctx_t; + +static slider_ctx_t slider_ctx; + +static lv_res_t _action_slider_emusd_file(lv_obj_t *slider){ + u32 slider_val = lv_slider_get_value(slider); + u32 size = slider_val <<= 10; + + slider_ctx.emu_size = size; + + char txt_buf[0x20]; + s_printf(txt_buf, "#FF00D6 %d GiB#", size >> 10); + + lv_label_set_text(slider_ctx.label, txt_buf); + + return LV_RES_OK; } -static lv_res_t _emusd_change_action(lv_obj_t *btns, const char *txt){ - u32 idx = lv_btnm_get_pressed(btns); +static lv_res_t _create_emusd_file_based_action(lv_obj_t *btns, const char *txt){ + int idx = lv_btnm_get_pressed(btns); + mbox_action(btns, txt); - if(idx < gpt_ctxt.valid_cnt){ - _change_emusd(idx); - _close_mbox_and_reload(btns, txt); - }else if(idx == gpt_ctxt.valid_cnt){ + if(!idx && slider_ctx.emu_size) { + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char *mbox_btns_map[] = { "\251", "\222OK", "\251", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); + + lv_mbox_set_text(mbox, + "#FF8000 emuSD creation tool#\n\n" + "#00DDFF Status:# Creating file based emuSD..."); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + manual_system_maintenance(true); + + int res = 0; + if(emusd_drive == DRIVE_SD){ + if(!sd_mount()){ + res = FR_DISK_ERR; + } + }else{ + if(!emmc_mount()){ + res = FR_DISK_ERR; + } + } boot_storage_mount(); - save_emusd_cfg(0, 0); - boot_storage_unmount(); - _close_mbox_and_reload(btns, txt); - }else{ - mbox_action(btns, txt); + if(!res){ + res = create_emusd_file(slider_ctx.emu_size << 11, emusd_drive); + } + boot_storage_unmount(); + if(emusd_drive == DRIVE_SD){ + sd_unmount(); + }else{ + emmc_unmount(); + } + + if(res){ + lv_mbox_set_text(mbox, + "#FF8000 emuSD creation tool#\n\n" + "#00DDFF Status:# Done!"); + }else{ + lv_mbox_set_text(mbox, + "#FF8000 emuSD creation tool#\n\n" + "#00DDFF Status:# Failed to create emuSD!"); + } + + lv_mbox_add_btns(mbox, mbox_btns_map, _close_mbox_and_reload); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); } return LV_RES_INV; } -static lv_res_t _create_mbox_change_emusd(lv_obj_t *btn){ - boot_storage_mount(); - emmc_initialize(false); +static void _create_mbox_emusd_file_based(){ + char *txt_buf = malloc(SZ_4K); lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); lv_obj_set_style(dark_bg, &mbox_darken); @@ -192,81 +229,143 @@ static lv_res_t _create_mbox_change_emusd(lv_obj_t *btn){ lv_mbox_set_recolor_text(mbox, true); lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); - static char mbox_part_strs[6][0x10]; - static char *mbox_btn_parts[] = {mbox_part_strs[0], mbox_part_strs[1], mbox_part_strs[2], mbox_part_strs[3], mbox_part_strs[4], mbox_part_strs[5]}; + static const char *mbox_btns[] = { "\222Continue", "\222Cancel", "" }; + static const char *mbox_btns_ok[] = { "\251", "\222OK", "\251", "" }; - dirlist_t *emusd_dir_list = dirlist("emuSD", NULL, false, true); - char path[0x80]; - mbr_t mbr = {0}; - gpt_t *gpt = NULL; - char *txt_buf = malloc(SZ_16K); + lv_mbox_set_text(mbox, "#FF8000 emuSD creation tool#\n\n" + "#C7EA46 Select emuSD size!#\n\n" + "#00DDFF Status:# Checking for available free space..."); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + manual_system_maintenance(true); - u32 emusd_idx = 0; - FIL f; - - sdmmc_storage_read(&emmc_storage, 0, 1, &mbr); - - if(!mbr_has_gpt(&mbr)){ - goto out; - } - - gpt = zalloc(sizeof(*gpt)); - sdmmc_storage_read(&emmc_storage, 1, sizeof(*gpt) / 0x200, gpt); - - _get_emusd_parts(gpt); - - u8 cnt = 0; - - while(emusd_dir_list && emusd_dir_list->name[emusd_idx]){ - s_printf(path, "emuSD/%s/raw_emmc_based", emusd_dir_list->name[emusd_idx]); - if(f_stat(path, NULL) == FR_OK){ - f_open(&f, path, FA_READ); - u32 sector = 0; - f_read(&f, §or, 4, NULL); - f_close(&f); - - for(u32 i = 0; i < gpt_ctxt.cnt ; i++){ - if(sector == gpt_ctxt.sector_mbr[i]){ - s_printf(mbox_btn_parts[cnt], "Part %d", gpt_ctxt.part_idx[i]); - gpt_ctxt.valid_parts[cnt] = i; - cnt++; - } - } - } - emusd_idx++; - } - - gpt_ctxt.valid_cnt = cnt; - - strcpy(mbox_btn_parts[cnt], "Disable"); - strcpy(mbox_btn_parts[cnt + 1], "Cancel"); - mbox_btn_parts[cnt + 2][0] = 0; - - if(cnt){ - strcpy(txt_buf, "#C7EA46 Found emuSD partition(s)!#\n" - "#FF8000 Choose a partition or disable emuSD.#\n\n"); - for(u32 i = 0; i < cnt; i++){ - s_printf(txt_buf + strlen(txt_buf), "Part %d (%s): Start: 0x%x, Size: 0x%x\n", gpt_ctxt.part_idx[gpt_ctxt.valid_parts[i]], gpt_ctxt.name[gpt_ctxt.valid_parts[i]], gpt_ctxt.sector[gpt_ctxt.valid_parts[i]], gpt_ctxt.size[gpt_ctxt.valid_parts[i]]); - } + FATFS *fs; + if(emusd_drive == DRIVE_SD){ + sd_mount(); + fs = &sd_fs; + f_getfree("sd:", &fs->free_clst, NULL); }else{ - strcpy(txt_buf, "#FF8000 No set up emuSD partitions found.\nFirst, create an emuSD\n#"); + emmc_mount(); + fs = &emmc_fs; + f_getfree("emmc:", &fs->free_clst, NULL); + } + emmc_initialize(false); + if(emusd_drive == DRIVE_SD){ + sd_unmount(); + }else{ + emmc_unmount(); } - lv_mbox_set_text(mbox, txt_buf); - lv_mbox_add_btns(mbox, (const char **)mbox_btn_parts, _emusd_change_action); + // leave 1gb free + u32 available = fs->free_clst * fs->csize; + available >>= 11; + available = available >= (2 * 1024) ? available - (1 * 1024) : 0; + + if(available == 0){ + s_printf(txt_buf, "#FF8000 emuSD creation tool#\n\n" + "#FFDD00 Note:# Not enough free space on %s", emusd_drive == DRIVE_SD ? "SD" : "eMMC"); + lv_mbox_set_text(mbox, txt_buf); + + }else{ + lv_mbox_set_text(mbox, "#FF8000 emuSD creation tool#\n\n" + "#C7EA46 Select emuSD size!#"); + } lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - out: - free(gpt); - free(emusd_dir_list); + slider_ctx.emu_size = 1024; - boot_storage_unmount(); - emmc_end(); + if(available){ - return LV_RES_OK; + lv_coord_t pad = lv_mbox_get_style(mbox, LV_MBOX_STYLE_BG)->body.padding.hor; + lv_coord_t w = lv_obj_get_width(mbox) - 2 * pad - 2 * LV_DPI; + + // Set eMUMMC bar styles. + static lv_style_t bar_emu_bg, bar_emu_ind, bar_emu_btn; + lv_style_copy(&bar_emu_bg, lv_theme_get_current()->bar.bg); + bar_emu_bg.body.main_color = LV_COLOR_HEX(0x96007e); + bar_emu_bg.body.grad_color = bar_emu_bg.body.main_color; + lv_style_copy(&bar_emu_ind, lv_theme_get_current()->bar.indic); + bar_emu_ind.body.main_color = LV_COLOR_HEX(0xff00d6); + bar_emu_ind.body.grad_color = bar_emu_ind.body.main_color; + lv_style_copy(&bar_emu_btn, lv_theme_get_current()->slider.knob); + bar_emu_btn.body.main_color = LV_COLOR_HEX(0xc700a7); + bar_emu_btn.body.grad_color = bar_emu_btn.body.main_color; + + lv_obj_t *slider_cont = lv_cont_create(mbox, NULL); + lv_cont_set_fit(slider_cont, false, true); + lv_cont_set_style(slider_cont, &lv_style_transp); + lv_obj_set_width(slider_cont, lv_obj_get_width(mbox)); + + lv_obj_t *slider = lv_slider_create(slider_cont, NULL); + lv_obj_set_size(slider, w, LV_DPI / 3); + lv_slider_set_range(slider, 1, available >> 10); + lv_slider_set_value(slider, slider_ctx.emu_size >> 10); + lv_slider_set_style(slider, LV_SLIDER_STYLE_BG, &bar_emu_bg); + lv_slider_set_style(slider, LV_SLIDER_STYLE_INDIC, &bar_emu_ind); + lv_slider_set_style(slider, LV_SLIDER_STYLE_KNOB, &bar_emu_btn); + lv_slider_set_action(slider, _action_slider_emusd_file); + lv_obj_align(slider, slider_cont, LV_ALIGN_CENTER, - (LV_DPI / 2), 0); + + lv_obj_t *label = lv_label_create(slider_cont, NULL); + lv_label_set_recolor(label, true); + s_printf(txt_buf, "#FF00D6 %d GiB#", slider_ctx.emu_size >> 10); + + lv_label_set_text(label, txt_buf); + lv_obj_align(label, slider, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 2 / 5, 0); + + slider_ctx.label = label; + } + + if(available){ + lv_mbox_add_btns(mbox, mbox_btns, _create_emusd_file_based_action); + }else{ + lv_mbox_add_btns(mbox, mbox_btns_ok, _create_emusd_file_based_action); + } + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); } -static lv_res_t _create_mbox_emusd_create(lv_obj_t *btn){ +static lv_res_t _create_emusd_select_file_type_action(lv_obj_t *btns, const char *txt){ + int btn_idx = lv_btnm_get_pressed(btns); + + mbox_action(btns, txt); + + switch(btn_idx){ + case 0: + emusd_drive = DRIVE_SD; + _create_mbox_emusd_file_based(); + break; + case 1: + emusd_drive = DRIVE_EMMC; + _create_mbox_emusd_file_based(); + break; + case 2: + break; + } + + return LV_RES_INV; +} + +static void _create_mbox_emusd_select_file_type(){ + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char * mbox_btn_map[] = { "\222SD file", "\222eMMC file", "\222Cancel", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); + + lv_mbox_set_text(mbox, + "Welcome to #C7EA46 emuSD# creation tool!\n\n" + "Please choose what type of file based emuSD to create."); + + lv_mbox_add_btns(mbox, mbox_btn_map, _create_emusd_select_file_type_action); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); +} + +static void _create_mbox_emusd_raw() { lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); lv_obj_set_style(dark_bg, &mbox_darken); lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); @@ -281,18 +380,24 @@ static lv_res_t _create_mbox_emusd_create(lv_obj_t *btn){ char *txt_buf = (char*)malloc(SZ_16K); - emmc_initialize(false); - emmc_set_partition(EMMC_GPP); + if(emusd_drive == DRIVE_EMMC) { + emmc_initialize(false); + emmc_set_partition(EMMC_GPP); + }else{ + sd_initialize(false); + } + + sdmmc_storage_t *storage = emusd_drive == DRIVE_SD ? &sd_storage : &emmc_storage; gpt_t *gpt = NULL; mbr_t mbr = {0}; u8 cnt = 0; - sdmmc_storage_read(&emmc_storage, 0, 1, &mbr); + sdmmc_storage_read(storage, 0, 1, &mbr); if(mbr_has_gpt(&mbr)){ gpt = zalloc(sizeof(*gpt)); - sdmmc_storage_read(&emmc_storage, 1, sizeof(*gpt) / 0x200, gpt); + sdmmc_storage_read(storage, 1, sizeof(*gpt) / 0x200, gpt); _get_emusd_parts(gpt); @@ -301,8 +406,8 @@ static lv_res_t _create_mbox_emusd_create(lv_obj_t *btn){ if(cnt){ s_printf(txt_buf, - "#C7EA46 Found applicable eMMC partition(s)!#\n" - "#FF8000 Choose a partition to continue:#\n\n"); + "#C7EA46 Found applicable %s partition(s)!#\n" + "#FF8000 Choose a partition to continue:#\n\n", emusd_drive == DRIVE_SD ? "SD" : "eMMC"); for(u32 i = 0; i < cnt; i++){ char name[36]; u8 idx = gpt_ctxt.part_idx[i]; @@ -318,18 +423,569 @@ static lv_res_t _create_mbox_emusd_create(lv_obj_t *btn){ lv_mbox_add_btns(mbox, (const char **)mbox_btn_parts, _emusd_create_action); }else{ s_printf(txt_buf, "#FFDD00 Failed to find applicable partition!#\n\n" - "#FF8000 Do you want to partition the eMMC?#\n" - "#FF8000 (You will be asked on how to proceed)#"); + "#FF8000 Do you want to partition the %s?#\n" + "#FF8000 (You will be asked on how to proceed)#", emusd_drive == DRIVE_SD ? "SD Card" : "eMMC"); lv_mbox_add_btns(mbox, mbox_btn_format, _emusd_format_action); } lv_mbox_set_text(mbox, txt_buf); lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - emmc_end(); + if(emusd_drive == DRIVE_EMMC){ + emmc_end(); + }else{ + sd_end(); + } free(txt_buf); free(gpt); +} + +static lv_res_t _create_emusd_select_raw_type_action(lv_obj_t *btns, const char *txt){ + int btn_idx = lv_btnm_get_pressed(btns); + + mbox_action(btns, txt); + + switch(btn_idx){ + case 0: + emusd_drive = DRIVE_SD; + _create_mbox_emusd_raw(); + break; + case 1: + emusd_drive = DRIVE_EMMC; + _create_mbox_emusd_raw(); + break; + case 2: + break; + } + + return LV_RES_INV; +} + +static void _create_mbox_emusd_select_raw_type(){ + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char * mbox_btn_map[] = { "\222SD partition", "\222eMMC partition", "\222Cancel", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); + + lv_mbox_set_text(mbox, + "Welcome to #C7EA46 emuSD# creation tool!\n\n" + "Please choose what type of partition based emuSD to create."); + + lv_mbox_add_btns(mbox, mbox_btn_map, _create_emusd_select_raw_type_action); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); +} + +static lv_res_t _create_emusd_select_type_action(lv_obj_t *btns, const char *txt){ + int btn_idx = lv_btnm_get_pressed(btns); + + mbox_action(btns, txt); + + switch(btn_idx){ + case 0: + _create_mbox_emusd_select_file_type(); + break; + case 1: + _create_mbox_emusd_select_raw_type(); + break; + case 2: + break; + } + + return LV_RES_INV; +} + +static lv_res_t _create_mbox_emusd_create(lv_obj_t *btn){ + if(!nyx_emmc_check_battery_enough()){ + return LV_RES_OK; + } + + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char * mbox_btn_map[] = { "\222File based", "\222Partition Based", "\222Cancel", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6); + + lv_mbox_set_text(mbox, + "Welcome to #C7EA46 emuSD# creation tool!\n\n" + "Please choose what type of emuSD you want to create.\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 an\navailable SD or eMMC partition."); + + lv_mbox_add_btns(mbox, mbox_btn_map, _create_emusd_select_type_action); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); + + return LV_RES_OK; +} + +typedef struct _emusd_images_t +{ + dirlist_t *dirlist; + + u32 emmc_part_sector[3]; + u32 emmc_part_end[3]; + u32 emmc_part_idx[3]; + char emmc_part_path[3][128]; + + u32 part_sector[3]; + u32 part_end[3]; + u32 part_idx[3]; + char part_path[3][128]; + lv_obj_t *win; +} emusd_images_t; + +static emusd_images_t *emusd_img; + +static lv_res_t _save_emusd_cfg_mbox_action(lv_obj_t *btns, const char *txt) +{ + // Free components, delete main emuMMC and popup windows and relaunch main emuMMC window. + free(emusd_img->dirlist); + lv_obj_del(emusd_img->win); + free(emusd_img); + + _close_mbox_and_reload(btns, txt); + return LV_RES_INV; +} + +static void _create_emusd_saved_mbox() +{ + lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_style(dark_bg, &mbox_darken); + lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES); + + static const char *mbox_btn_map[] = { "\251", "OK", "\251", "" }; + lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL); + lv_mbox_set_recolor_text(mbox, true); + lv_obj_set_width(mbox, LV_HOR_RES / 9 * 4); + + lv_mbox_set_text(mbox, + "#FF8000 emuSD Configuration#\n\n" + "#96FF00 The emuSD configuration#\n#96FF00 was saved!#"); + + lv_mbox_add_btns(mbox, mbox_btn_map, _save_emusd_cfg_mbox_action); + + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_top(mbox, true); +} + +static lv_res_t _save_disable_emusd_cfg_action(lv_obj_t * btn) +{ + save_emusd_cfg(0, 0, NULL, 0); + _create_emusd_saved_mbox(); + sd_unmount(); + boot_storage_unmount(); + + return LV_RES_INV; +} + +static lv_res_t _save_file_emusd_emmc_cfg_action(lv_obj_t *btn) +{ + const char *btn_txt = lv_list_get_btn_text(btn); + gfx_printf("save emu %s\n", btn_txt); + save_emusd_cfg(0, 0, btn_txt, DRIVE_EMMC); + _create_emusd_saved_mbox(); + sd_unmount(); + boot_storage_unmount(); + + return LV_RES_INV; +} + +static lv_res_t _save_file_emusd_cfg_action(lv_obj_t *btn) +{ + const char *btn_txt = lv_list_get_btn_text(btn); + gfx_printf("save sd %s\n", btn_txt); + save_emusd_cfg(0, 0, btn_txt, DRIVE_SD); + _create_emusd_saved_mbox(); + sd_unmount(); + boot_storage_unmount(); + + return LV_RES_INV; +} + +static lv_res_t _save_raw_emusd_cfg_action(lv_obj_t * btn) +{ + lv_btn_ext_t *ext = lv_obj_get_ext_attr(btn); + switch (ext->idx) + { + case 0: + save_emusd_cfg(1, emusd_img->part_sector[0], &emusd_img->part_path[0][0], DRIVE_SD); + break; + case 1: + save_emusd_cfg(2, emusd_img->part_sector[1], &emusd_img->part_path[1][0], DRIVE_SD); + break; + case 2: + save_emusd_cfg(3, emusd_img->part_sector[2], &emusd_img->part_path[2][0], DRIVE_SD); + break; + } + + _create_emusd_saved_mbox(); + sd_unmount(); + + return LV_RES_INV; +} + +static lv_res_t _save_emmc_raw_emusd_cfg_action(lv_obj_t * btn) +{ + lv_btn_ext_t *ext = lv_obj_get_ext_attr(btn); + switch (ext->idx) + { + case 0: + save_emusd_cfg(1, emusd_img->emmc_part_sector[0], &emusd_img->emmc_part_path[0][0], DRIVE_EMMC); + break; + case 1: + save_emusd_cfg(2, emusd_img->emmc_part_sector[1], &emusd_img->emmc_part_path[1][0], DRIVE_EMMC); + break; + case 2: + save_emusd_cfg(3, emusd_img->emmc_part_sector[2], &emusd_img->emmc_part_path[2][0], DRIVE_EMMC); + break; + } + + _create_emusd_saved_mbox(); + sd_unmount(); + + return LV_RES_INV; +} + +static lv_res_t _create_change_emusd_window(lv_obj_t *btn_caller) +{ + lv_obj_t *win = nyx_create_standard_window(SYMBOL_SETTINGS" Change emuSD"); + lv_win_add_btn(win, NULL, SYMBOL_POWER" Disable", _save_disable_emusd_cfg_action); + + boot_storage_mount(); + sd_mount(); + emmc_mount(); + + emusd_img = zalloc(sizeof(*emusd_img)); + emusd_img->win = win; + + mbr_t *mbr = (mbr_t *)malloc(sizeof(mbr_t)); + gpt_t *gpt = (gpt_t*)malloc(sizeof(gpt_t)); + char *path = malloc(512); + + sdmmc_storage_read(&sd_storage, 0, 1, mbr); + + memset(emusd_img->part_path, 0, 3 * 128); + + emusd_img->dirlist = dirlist("emuSD", NULL, false, true); + + if(!emusd_img->dirlist){ + goto out0; + } + + u32 emusd_idx = 0; + FIL fp; + + // Look for emuSD partitions on SD + u32 emmc_cnt = 0; + sdmmc_storage_read(&sd_storage, 0, 1, mbr); + if(mbr_has_gpt(mbr)){ + sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) / 0x200, gpt); + s32 gpt_idx = gpt_get_part_by_name(gpt, "emusd_mbr", -1); + while(gpt_idx != -1 && emmc_cnt < 3){ + emusd_img->part_sector[emmc_cnt] = gpt->entries[gpt_idx].lba_start; + emusd_img->part_end[emmc_cnt] = gpt->entries[gpt_idx + 1].lba_end; + emusd_img->part_idx[emmc_cnt] = gpt_idx; + + emmc_cnt++; + gpt_idx = gpt_get_part_by_name(gpt, "emusd_mbr", gpt_idx); + } + } + + emusd_idx = 0; + + // Check for eMMC raw partitions, based on the folders in /emuMMC + while(emusd_img->dirlist->name[emusd_idx]){ + s_printf(path, "emuSD/%s/raw_based", emusd_img->dirlist->name[emusd_idx]); + + if(!f_stat(path, NULL)){ + f_open(&fp, path, FA_READ); + u32 sector = 0; + f_read(&fp, §or, 4, NULL); + f_close(&fp); + + for(u32 i = 0; i < emmc_cnt; i++){ + if(sector && sector >= emusd_img->part_sector[i] && sector <= emusd_img->part_end[i]){ + emusd_img->part_sector[i] = sector; + emusd_img->part_end[i] = 0; + s_printf((char*)&emusd_img->part_path[i], "emuSD/%s", emusd_img->dirlist->name[emusd_idx]); + } + } + } + emusd_idx++; + } + + + // Look for emuSD partitions on eMMC + emmc_cnt = 0; + sdmmc_storage_read(&emmc_storage, 0, 1, mbr); + if(mbr_has_gpt(mbr)){ + sdmmc_storage_read(&emmc_storage, 1, sizeof(gpt_t) / 0x200, gpt); + + s32 gpt_idx = gpt_get_part_by_name(gpt, "emusd_mbr", -1); + while(gpt_idx != -1 && emmc_cnt < 3){ + emusd_img->emmc_part_sector[emmc_cnt] = gpt->entries[gpt_idx].lba_start; + emusd_img->emmc_part_end[emmc_cnt] = gpt->entries[gpt_idx + 1].lba_end; + emusd_img->emmc_part_idx[emmc_cnt] = gpt_idx; + + emmc_cnt++; + gpt_idx = gpt_get_part_by_name(gpt, "emusd_mbr", gpt_idx); + } + } + + free(gpt); + free(mbr); + + emusd_idx = 0; + + // Check for eMMC raw partitions, based on the folders in /emuMMC + while(emusd_img->dirlist->name[emusd_idx]){ + s_printf(path, "emuSD/%s/raw_emmc_based", emusd_img->dirlist->name[emusd_idx]); + + if(!f_stat(path, NULL)){ + f_open(&fp, path, FA_READ); + u32 sector = 0; + f_read(&fp, §or, 4, NULL); + f_close(&fp); + + for(u32 i = 0; i < emmc_cnt; i++){ + if(sector && sector >= emusd_img->emmc_part_sector[i] && sector <= emusd_img->emmc_part_end[i]){ + emusd_img->emmc_part_sector[i] = sector; + emusd_img->emmc_part_end[i] = 0; + s_printf((char*)&emusd_img->emmc_part_path[i], "emuSD/%s", emusd_img->dirlist->name[emusd_idx]); + } + } + } + emusd_idx++; + } + + u32 file_based_idx = 0; + emusd_idx = 0; + + // Sanitize the directory list with sd file based ones. + u8 file_based_drives[DIR_MAX_ENTRIES]; + while (emusd_img->dirlist->name[emusd_idx]) + { + s_printf(path, "emuSD/%s/file_based", emusd_img->dirlist->name[emusd_idx]); + + if (!f_stat(path, NULL)) + { + char *tmp = emusd_img->dirlist->name[emusd_idx]; + memcpy(emusd_img->dirlist->name[file_based_idx], tmp, strlen(tmp) + 1); + file_based_drives[file_based_idx] = DRIVE_SD; + file_based_idx++; + } + + s_printf(path, "emuSD/%s/file_emmc_based", emusd_img->dirlist->name[emusd_idx]); + if (!f_stat(path, NULL)) + { + char *tmp = emusd_img->dirlist->name[emusd_idx]; + memcpy(emusd_img->dirlist->name[file_based_idx], tmp, strlen(tmp) + 1); + file_based_drives[file_based_idx] = DRIVE_EMMC; + file_based_idx++; + } + emusd_idx++; + } + emusd_img->dirlist->name[file_based_idx] = NULL; + +out0: + static lv_style_t h_style; + lv_style_copy(&h_style, &lv_style_transp); + h_style.body.padding.inner = 0; + h_style.body.padding.hor = LV_DPI - (LV_DPI / 4); + h_style.body.padding.ver = LV_DPI / 6; + + // Create SD Raw Partitions container. + lv_obj_t *h1 = lv_cont_create(win, NULL); + lv_cont_set_style(h1, &h_style); + lv_cont_set_fit(h1, false, true); + lv_obj_set_width(h1, (LV_HOR_RES / 17) * 4); + lv_obj_set_click(h1, false); + lv_cont_set_layout(h1, LV_LAYOUT_OFF); + + lv_obj_t *label_sep = lv_label_create(h1, NULL); + lv_label_set_static_text(label_sep, ""); + + lv_obj_t *label_txt = lv_label_create(h1, NULL); + lv_label_set_static_text(label_txt, "SD Raw Partitions"); + lv_obj_set_style(label_txt, lv_theme_get_current()->label.prim); + lv_obj_align(label_txt, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -(LV_DPI / 2)); + + lv_obj_t *line_sep = lv_line_create(h1, NULL); + static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 2)) * 2, 0} }; + lv_line_set_points(line_sep, line_pp, 2); + lv_line_set_style(line_sep, lv_theme_get_current()->line.decor); + lv_obj_align(line_sep, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8); + + lv_obj_t *btn = NULL; + lv_btn_ext_t *ext; + lv_obj_t *btn_label = NULL; + lv_obj_t *lv_desc = NULL; + char *txt_buf = malloc(SZ_16K); + + // Create RAW buttons. + for (u32 i = 0; i < 3; i++) + { + btn = lv_btn_create(h1, btn); + ext = lv_obj_get_ext_attr(btn); + ext->idx = i; + btn_label = lv_label_create(btn, btn_label); + + lv_btn_set_state(btn, LV_BTN_STATE_REL); + lv_obj_set_click(btn, true); + + s_printf(txt_buf, "SD RAW %d", i + 1); + lv_label_set_text(btn_label, txt_buf); + + if (!emusd_img->part_sector[i] || !emusd_img->part_path[i][0]) + { + lv_btn_set_state(btn, LV_BTN_STATE_INA); + lv_obj_set_click(btn, false); + } + + if (!i) + { + lv_btn_set_fit(btn, false, true); + lv_obj_set_width(btn, LV_DPI * 2 + LV_DPI / 2); + lv_obj_align(btn, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 3, LV_DPI / 5); + } + else + lv_obj_align(btn, lv_desc, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3); + + lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _save_raw_emusd_cfg_action); + + lv_desc = lv_label_create(h1, lv_desc); + lv_label_set_recolor(lv_desc, true); + lv_obj_set_style(lv_desc, &hint_small_style); + + s_printf(txt_buf, "Sector start: 0x%08X\nFolder: %s", emusd_img->part_sector[i], &emusd_img->part_path[i][0]); + lv_label_set_text(lv_desc, txt_buf); + lv_obj_align(lv_desc, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 5); + } + + + // Create eMMC Raw container + lv_obj_t *h3 = lv_cont_create(win, NULL); + lv_cont_set_style(h3, &h_style); + lv_cont_set_fit(h3, false, true); + lv_obj_set_width(h3, (LV_HOR_RES / 17) * 4); + lv_obj_set_click(h3, false); + lv_cont_set_layout(h3, LV_LAYOUT_OFF); + + label_sep = lv_label_create(h3, NULL); + lv_label_set_static_text(label_sep, ""); + + lv_obj_t *label_txt2 = lv_label_create(h3, NULL); + lv_label_set_static_text(label_txt2, "eMMC Raw Partitions"); + lv_obj_set_style(label_txt2, lv_theme_get_current()->label.prim); + lv_obj_align(label_txt2, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI * 2 / 9, -(LV_DPI / 2)); + + line_sep = lv_line_create(h3, line_sep); + lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8); + lv_line_set_style(line_sep, lv_theme_get_current()->line.decor); + + for (u32 i = 0; i < 3; i++){ + btn = lv_btn_create(h3, btn); + ext = lv_obj_get_ext_attr(btn); + ext->idx = i; + btn_label = lv_label_create(btn, btn_label); + + lv_btn_set_state(btn, LV_BTN_STATE_REL); + lv_obj_set_click(btn, true); + + s_printf(txt_buf, "eMMC RAW %d", i + 1); + lv_label_set_text(btn_label, txt_buf); + + if (!emusd_img->emmc_part_sector[i] || !emusd_img->emmc_part_path[i][0]) + { + lv_btn_set_state(btn, LV_BTN_STATE_INA); + lv_obj_set_click(btn, false); + } + + if (!i) + { + lv_btn_set_fit(btn, false, true); + lv_obj_set_width(btn, LV_DPI * 2 + LV_DPI / 2); + lv_obj_align(btn, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 3, LV_DPI / 5); + } + else + lv_obj_align(btn, lv_desc, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3); + + lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _save_emmc_raw_emusd_cfg_action); + + lv_desc = lv_label_create(h3, lv_desc); + lv_label_set_recolor(lv_desc, true); + lv_obj_set_style(lv_desc, &hint_small_style); + + s_printf(txt_buf, "Sector start: 0x%08X\nFolder: %s", emusd_img->emmc_part_sector[i], (char*)&emusd_img->emmc_part_path[i]); + lv_label_set_text(lv_desc, txt_buf); + lv_obj_align(lv_desc, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 5); + } + + lv_obj_align(h3, h1, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI / 2, 0); + + free(txt_buf); + + // Create SD File Based container. + lv_obj_t *h2 = lv_cont_create(win, NULL); + lv_cont_set_style(h2, &h_style); + lv_cont_set_fit(h2, false, true); + lv_obj_set_width(h2, LV_HOR_RES * 2 / 5); + lv_obj_set_click(h2, false); + lv_cont_set_layout(h2, LV_LAYOUT_OFF); + lv_obj_align(h2, h3, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI / 2, 0); + + label_sep = lv_label_create(h2, NULL); + lv_label_set_static_text(label_sep, ""); + + lv_obj_t *label_txt3 = lv_label_create(h2, NULL); + lv_label_set_static_text(label_txt3, "SD/eMMC File Based"); + lv_obj_set_style(label_txt3, lv_theme_get_current()->label.prim); + lv_obj_align(label_txt3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI * 2 / 9, -LV_DPI / 7); + + line_sep = lv_line_create(h2, line_sep); + lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 2), LV_DPI / 8); + lv_line_set_style(line_sep, lv_theme_get_current()->line.decor); + + lv_obj_t *list_sd_based = lv_list_create(h2, NULL); + lv_obj_align(list_sd_based, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 2, LV_DPI / 4); + + lv_obj_set_size(list_sd_based, LV_HOR_RES * 4 / 10 - (LV_DPI / 2), LV_VER_RES * 6 / 10); + lv_list_set_single_mode(list_sd_based, true); + + if (!emusd_img->dirlist) + goto out1; + + emusd_idx = 0; + + // Add file based to the list. + while (emusd_img->dirlist->name[emusd_idx]) + { + s_printf(path, "emuSD/%s", emusd_img->dirlist->name[emusd_idx]); + + if(file_based_drives[emusd_idx] == DRIVE_SD){ + lv_list_add(list_sd_based, NULL, path, _save_file_emusd_cfg_action); + }else{ + lv_list_add(list_sd_based, NULL, path, _save_file_emusd_emmc_cfg_action); + } + + emusd_idx++; + } + +out1: + free(path); + sd_unmount(); + boot_storage_unmount(); return LV_RES_OK; } @@ -386,14 +1042,33 @@ lv_res_t create_tab_emusd_tools(lv_obj_t *parent) if (emu_info.enabled) { - s_printf(txt_buf, "#00DDFF Type:# eMMC Raw Partition\n#00DDFF Sector:# 0x%08X", - emu_info.sector); + if(emu_info.enabled == 4){ + if(emu_info.sector){ + s_printf(txt_buf, "#00DDFF Type:# eMMC Raw Partition\n#00DDFF Sector:# 0x%08X", + emu_info.sector); + }else{ + s_printf(txt_buf, "#00DDFF Type:# eMMC File\n#00DDFF Base folder:# %s", + emu_info.path ? emu_info.path : ""); + } + }else{ + if (emu_info.sector){ + s_printf(txt_buf, "#00DDFF Type:# SD Raw Partition\n#00DDFF Sector:# 0x%08X", + emu_info.sector); + }else{ + s_printf(txt_buf, "#00DDFF Type:# SD File\n#00DDFF Base folder:# %s", + emu_info.path ? emu_info.path : ""); + } + } lv_label_set_text(label_txt2, txt_buf); } else { - lv_label_set_static_text(label_txt2, "emuSD is disabled and SD will be used for boot.\n\n"); + lv_label_set_static_text(label_txt2, "emuSD is disabled, SD will be used for boot.\n\n"); + } + + if(emu_info.path){ + free(emu_info.path); } free(txt_buf); @@ -407,7 +1082,7 @@ lv_res_t create_tab_emusd_tools(lv_obj_t *parent) label_btn = lv_label_create(btn2, NULL); lv_label_set_static_text(label_btn, SYMBOL_SETTINGS" Change emuSD"); lv_obj_align(btn2, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 6 / 10); - lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_mbox_change_emusd); + lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_change_emusd_window); label_txt2 = lv_label_create(h1, NULL); lv_label_set_recolor(label_txt2, true); diff --git a/nyx/nyx_gui/frontend/gui_tools.c b/nyx/nyx_gui/frontend/gui_tools.c index 92148edc..e62cda93 100644 --- a/nyx/nyx_gui/frontend/gui_tools.c +++ b/nyx/nyx_gui/frontend/gui_tools.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -380,6 +381,12 @@ static lv_res_t _create_mbox_ums_error(int error) case 8: lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuMMC!#"); 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); @@ -558,42 +565,103 @@ static lv_res_t _action_ums_emusd(lv_obj_t * btn){ } usb_ctxt_t usbs; + sdmmc_storage_t *storage; emusd_cfg_t emu_info; + bool file_based = false; int error = !boot_storage_mount(); + char path[0x80]; if(!error){ load_emusd_cfg(&emu_info); if(emu_info.enabled){ - if(!emmc_initialize(false)){ - error = 3; - }else{ - 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 = 0; + if(emu_info.enabled == 4 && emu_info.sector){ + if(!emmc_initialize(false)){ 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{ - 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){ _create_mbox_ums_error(error); }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); } + file_based_storage_end(); boot_storage_unmount(); return LV_RES_OK; diff --git a/nyx/nyx_gui/storage/sfd.c b/nyx/nyx_gui/storage/sfd.c index bf16dd26..20f75808 100644 --- a/nyx/nyx_gui/storage/sfd.c +++ b/nyx/nyx_gui/storage/sfd.c @@ -1,8 +1,12 @@ #include "sfd.h" #include #include +#include #include +#include + +static bool file_based; static sdmmc_storage_t *_storage; static u32 _offset; static u32 _size; @@ -14,7 +18,11 @@ static void ensure_partition(){ } 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){ @@ -22,8 +30,13 @@ int sfd_read(u32 sector, u32 count, void *buff){ if(sector + count > _size){ 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; } @@ -32,8 +45,14 @@ int sfd_write(u32 sector, u32 count, void *buff){ if(sector + count > _size){ 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; } @@ -45,10 +64,23 @@ bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size){ 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(){ _storage = NULL; _offset = 0; _size = 0; u32 size = 0; + file_based = false; disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &size); } \ No newline at end of file diff --git a/nyx/nyx_gui/storage/sfd.h b/nyx/nyx_gui/storage/sfd.h index 38daf508..30549f94 100644 --- a/nyx/nyx_gui/storage/sfd.h +++ b/nyx/nyx_gui/storage/sfd.h @@ -7,6 +7,7 @@ int sfd_read(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); void sfd_end();