mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
git subrepo pull emummc
subrepo: subdir: "emummc" merged: "2e001dd2" upstream: origin: "https://github.com/m4xw/emuMMC" branch: "develop" commit: "29deabb2" git-subrepo: version: "0.4.1" origin: "???" commit: "???"
This commit is contained in:
parent
45e5e8eb8e
commit
8859aefdd7
4 changed files with 107 additions and 44 deletions
2
emummc/.gitrepo
vendored
2
emummc/.gitrepo
vendored
|
@ -6,7 +6,7 @@
|
||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emuMMC
|
remote = https://github.com/m4xw/emuMMC
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = cbc294c390ed73bb281bc1028a8899c053427112
|
commit = 29deabb2cd46434c0d1b237cb74a823c02869f62
|
||||||
parent = 38f9a76ba028995ed3274da3a45b0254f09d1f59
|
parent = 38f9a76ba028995ed3274da3a45b0254f09d1f59
|
||||||
method = rebase
|
method = rebase
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|
11
emummc/source/FS/FS.h
vendored
11
emummc/source/FS/FS.h
vendored
|
@ -37,4 +37,15 @@
|
||||||
#define BOOT_PARTITION_SIZE 0x2000
|
#define BOOT_PARTITION_SIZE 0x2000
|
||||||
#define FS_READ_WRITE_ERROR 1048
|
#define FS_READ_WRITE_ERROR 1048
|
||||||
|
|
||||||
|
#define NAND_PATROL_SECTOR 0xC20
|
||||||
|
#define NAND_PATROL_OFFSET 0x184000
|
||||||
|
|
||||||
|
typedef struct _fs_nand_patrol_t
|
||||||
|
{
|
||||||
|
uint8_t hmac[0x20];
|
||||||
|
unsigned int offset;
|
||||||
|
unsigned int count;
|
||||||
|
uint8_t rsvd[0x1D8];
|
||||||
|
} fs_nand_patrol_t;
|
||||||
|
|
||||||
#endif /* __FS_H__ */
|
#endif /* __FS_H__ */
|
||||||
|
|
126
emummc/source/emuMMC/emummc.c
vendored
126
emummc/source/emuMMC/emummc.c
vendored
|
@ -89,7 +89,7 @@ static void _sdmmc_ensure_initialized(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _file_based_update_filename(char *outFilename, u32 sd_path_len, u32 part_idx)
|
static void _file_based_update_filename(char *outFilename, unsigned int sd_path_len, unsigned int part_idx)
|
||||||
{
|
{
|
||||||
snprintf(outFilename + sd_path_len, 3, "%02d", part_idx);
|
snprintf(outFilename + sd_path_len, 3, "%02d", part_idx);
|
||||||
}
|
}
|
||||||
|
@ -103,9 +103,7 @@ static void _file_based_emmc_finalize(void)
|
||||||
f_close(&f_emu.fp_boot1);
|
f_close(&f_emu.fp_boot1);
|
||||||
|
|
||||||
for (int i = 0; i < f_emu.parts; i++)
|
for (int i = 0; i < f_emu.parts; i++)
|
||||||
{
|
|
||||||
f_close(&f_emu.fp_gpp[i]);
|
f_close(&f_emu.fp_gpp[i]);
|
||||||
}
|
|
||||||
|
|
||||||
// Force unmount FAT volume.
|
// Force unmount FAT volume.
|
||||||
f_mount(NULL, "", 1);
|
f_mount(NULL, "", 1);
|
||||||
|
@ -114,12 +112,59 @@ static void _file_based_emmc_finalize(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _nand_patrol_ensure_integrity(void)
|
||||||
|
{
|
||||||
|
fs_nand_patrol_t nand_patrol;
|
||||||
|
static bool nand_patrol_checked = false;
|
||||||
|
|
||||||
|
if (!nand_patrol_checked)
|
||||||
|
{
|
||||||
|
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||||
|
{
|
||||||
|
unsigned int nand_patrol_sector = emuMMC_ctx.EMMC_StoragePartitionOffset + NAND_PATROL_SECTOR;
|
||||||
|
if (!sdmmc_storage_read(&sd_storage, nand_patrol_sector, 1, &nand_patrol))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
// Clear nand patrol if last offset exceeds storage.
|
||||||
|
if (nand_patrol.offset > sd_storage.sec_cnt)
|
||||||
|
{
|
||||||
|
memset(&nand_patrol, 0, sizeof(fs_nand_patrol_t));
|
||||||
|
sdmmc_storage_write(&sd_storage, nand_patrol_sector, 1, &nand_patrol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (emuMMC_ctx.EMMC_Type == emuMMC_SD_File && fat_mounted)
|
||||||
|
{
|
||||||
|
FIL *fp = &f_emu.fp_boot0;
|
||||||
|
if (f_lseek(fp, NAND_PATROL_OFFSET) != FR_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (f_read_fast(fp, &nand_patrol, sizeof(fs_nand_patrol_t)) != FR_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
// Clear nand patrol if last offset exceeds total file based size.
|
||||||
|
if (nand_patrol.offset > f_emu.total_sect)
|
||||||
|
{
|
||||||
|
memset(&nand_patrol, 0, sizeof(fs_nand_patrol_t));
|
||||||
|
|
||||||
|
if (f_lseek(fp, NAND_PATROL_OFFSET) != FR_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (f_write_fast(fp, &nand_patrol, sizeof(fs_nand_patrol_t)) != FR_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
f_sync(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
nand_patrol_checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sdmmc_finalize(void)
|
void sdmmc_finalize(void)
|
||||||
{
|
{
|
||||||
if (!sdmmc_storage_end(&sd_storage))
|
if (!sdmmc_storage_end(&sd_storage))
|
||||||
{
|
|
||||||
fatal_abort(Fatal_InitSD);
|
fatal_abort(Fatal_InitSD);
|
||||||
}
|
|
||||||
|
|
||||||
storageSDinitialized = false;
|
storageSDinitialized = false;
|
||||||
}
|
}
|
||||||
|
@ -137,14 +182,14 @@ static void _file_based_emmc_initialize(void)
|
||||||
memcpy(path + path_len, "BOOT0", 6);
|
memcpy(path + path_len, "BOOT0", 6);
|
||||||
if (f_open(&f_emu.fp_boot0, path, FA_READ | FA_WRITE) != FR_OK)
|
if (f_open(&f_emu.fp_boot0, path, FA_READ | FA_WRITE) != FR_OK)
|
||||||
fatal_abort(Fatal_FatfsFileOpen);
|
fatal_abort(Fatal_FatfsFileOpen);
|
||||||
if (!f_expand_cltbl(&f_emu.fp_boot0, 0x400, f_emu.clmt_boot0, f_size(&f_emu.fp_boot0)))
|
if (!f_expand_cltbl(&f_emu.fp_boot0, EMUMMC_FP_CLMT_COUNT, f_emu.clmt_boot0, f_size(&f_emu.fp_boot0)))
|
||||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||||
|
|
||||||
// Open BOOT1 physical partition.
|
// Open BOOT1 physical partition.
|
||||||
memcpy(path + path_len, "BOOT1", 6);
|
memcpy(path + path_len, "BOOT1", 6);
|
||||||
if (f_open(&f_emu.fp_boot1, path, FA_READ | FA_WRITE) != FR_OK)
|
if (f_open(&f_emu.fp_boot1, path, FA_READ | FA_WRITE) != FR_OK)
|
||||||
fatal_abort(Fatal_FatfsFileOpen);
|
fatal_abort(Fatal_FatfsFileOpen);
|
||||||
if (!f_expand_cltbl(&f_emu.fp_boot1, 0x400, f_emu.clmt_boot1, f_size(&f_emu.fp_boot1)))
|
if (!f_expand_cltbl(&f_emu.fp_boot1, EMUMMC_FP_CLMT_COUNT, f_emu.clmt_boot1, f_size(&f_emu.fp_boot1)))
|
||||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||||
|
|
||||||
// Open handles for GPP physical partition files.
|
// Open handles for GPP physical partition files.
|
||||||
|
@ -152,15 +197,14 @@ static void _file_based_emmc_initialize(void)
|
||||||
|
|
||||||
if (f_open(&f_emu.fp_gpp[0], path, FA_READ | FA_WRITE) != FR_OK)
|
if (f_open(&f_emu.fp_gpp[0], path, FA_READ | FA_WRITE) != FR_OK)
|
||||||
fatal_abort(Fatal_FatfsFileOpen);
|
fatal_abort(Fatal_FatfsFileOpen);
|
||||||
if (!f_expand_cltbl(&f_emu.fp_gpp[0], 0x400, &f_emu.clmt_gpp[0], f_size(&f_emu.fp_gpp[0])))
|
if (!f_expand_cltbl(&f_emu.fp_gpp[0], EMUMMC_FP_CLMT_COUNT, &f_emu.clmt_gpp[0], f_size(&f_emu.fp_gpp[0])))
|
||||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||||
|
|
||||||
f_emu.part_size = f_size(&f_emu.fp_gpp[0]) >> 9;
|
f_emu.part_size = (uint64_t)f_size(&f_emu.fp_gpp[0]) >> 9;
|
||||||
|
f_emu.total_sect = f_emu.part_size;
|
||||||
|
|
||||||
// Iterate folder for split parts and stop if next doesn't exist.
|
// Iterate folder for split parts and stop if next doesn't exist.
|
||||||
// Supports up to 32 parts of any size.
|
for (f_emu.parts = 1; f_emu.parts < EMUMMC_FILE_MAX_PARTS; f_emu.parts++)
|
||||||
// TODO: decide on max parts and define them. (hekate produces up to 30 parts on 1GB mode.)
|
|
||||||
for (f_emu.parts = 1; f_emu.parts < 32; f_emu.parts++)
|
|
||||||
{
|
{
|
||||||
_file_based_update_filename(path, path_len, f_emu.parts);
|
_file_based_update_filename(path, path_len, f_emu.parts);
|
||||||
|
|
||||||
|
@ -173,8 +217,13 @@ static void _file_based_emmc_initialize(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f_expand_cltbl(&f_emu.fp_gpp[f_emu.parts], 0x400, &f_emu.clmt_gpp[f_emu.parts * 0x400], f_size(&f_emu.fp_gpp[f_emu.parts])))
|
if (!f_expand_cltbl(&f_emu.fp_gpp[f_emu.parts], EMUMMC_FP_CLMT_COUNT,
|
||||||
|
&f_emu.clmt_gpp[f_emu.parts * EMUMMC_FP_CLMT_COUNT], f_size(&f_emu.fp_gpp[f_emu.parts])))
|
||||||
|
{
|
||||||
fatal_abort(Fatal_FatfsMemExhaustion);
|
fatal_abort(Fatal_FatfsMemExhaustion);
|
||||||
|
}
|
||||||
|
|
||||||
|
f_emu.total_sect += (uint64_t)f_size(&f_emu.fp_gpp[f_emu.parts]) >> 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +238,7 @@ bool sdmmc_initialize(void)
|
||||||
{
|
{
|
||||||
storageSDinitialized = true;
|
storageSDinitialized = true;
|
||||||
|
|
||||||
// File based emummc.
|
// Init file based emummc.
|
||||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
|
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_File) && !fat_mounted)
|
||||||
{
|
{
|
||||||
if (f_mount(&f_emu.sd_fs, "", 1) != FR_OK)
|
if (f_mount(&f_emu.sd_fs, "", 1) != FR_OK)
|
||||||
|
@ -200,6 +249,9 @@ bool sdmmc_initialize(void)
|
||||||
_file_based_emmc_initialize();
|
_file_based_emmc_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if nand patrol offset is inside limits.
|
||||||
|
_nand_patrol_ensure_integrity();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,9 +259,7 @@ bool sdmmc_initialize(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!storageSDinitialized)
|
if (!storageSDinitialized)
|
||||||
{
|
|
||||||
fatal_abort(Fatal_InitSD);
|
fatal_abort(Fatal_InitSD);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return storageSDinitialized;
|
return storageSDinitialized;
|
||||||
|
@ -239,19 +289,17 @@ sdmmc_accessor_t *sdmmc_accessor_get(int mmc_id)
|
||||||
void mutex_lock_handler(int mmc_id)
|
void mutex_lock_handler(int mmc_id)
|
||||||
{
|
{
|
||||||
if (custom_driver)
|
if (custom_driver)
|
||||||
{
|
|
||||||
lock_mutex(sd_mutex);
|
lock_mutex(sd_mutex);
|
||||||
}
|
|
||||||
lock_mutex(nand_mutex);
|
lock_mutex(nand_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutex_unlock_handler(int mmc_id)
|
void mutex_unlock_handler(int mmc_id)
|
||||||
{
|
{
|
||||||
unlock_mutex(nand_mutex);
|
unlock_mutex(nand_mutex);
|
||||||
|
|
||||||
if (custom_driver)
|
if (custom_driver)
|
||||||
{
|
|
||||||
unlock_mutex(sd_mutex);
|
unlock_mutex(sd_mutex);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sdmmc_nand_get_active_partition_index()
|
int sdmmc_nand_get_active_partition_index()
|
||||||
|
@ -271,12 +319,16 @@ int sdmmc_nand_get_active_partition_index()
|
||||||
|
|
||||||
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
|
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
|
||||||
{
|
{
|
||||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw))
|
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||||
{
|
{
|
||||||
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
|
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
|
||||||
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
|
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
|
||||||
// Set physical partition offset.
|
// Set physical partition offset.
|
||||||
sector += (sdmmc_nand_get_active_partition_index() * BOOT_PARTITION_SIZE);
|
sector += (sdmmc_nand_get_active_partition_index() * BOOT_PARTITION_SIZE);
|
||||||
|
|
||||||
|
if (__builtin_expect(sector + num_sectors > sd_storage.sec_cnt, 0))
|
||||||
|
return 0; // Out of bounds. Can only happen with Nand Patrol if resized.
|
||||||
|
|
||||||
if (!is_write)
|
if (!is_write)
|
||||||
return sdmmc_storage_read(&sd_storage, sector, num_sectors, buf);
|
return sdmmc_storage_read(&sd_storage, sector, num_sectors, buf);
|
||||||
else
|
else
|
||||||
|
@ -290,6 +342,9 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
|
||||||
case FS_EMMC_PARTITION_GPP:
|
case FS_EMMC_PARTITION_GPP:
|
||||||
if (f_emu.parts)
|
if (f_emu.parts)
|
||||||
{
|
{
|
||||||
|
if (__builtin_expect(sector + num_sectors > f_emu.total_sect, 0))
|
||||||
|
return 0; // Out of bounds. Can only happen with Nand Patrol if resized.
|
||||||
|
|
||||||
fp = &f_emu.fp_gpp[sector / f_emu.part_size];
|
fp = &f_emu.fp_gpp[sector / f_emu.part_size];
|
||||||
sector = sector % f_emu.part_size;
|
sector = sector % f_emu.part_size;
|
||||||
|
|
||||||
|
@ -300,21 +355,21 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
const unsigned int cur_sectors = MIN(remaining, f_emu.part_size - sector);
|
const unsigned int cur_sectors = MIN(remaining, f_emu.part_size - sector);
|
||||||
|
|
||||||
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
|
if (f_lseek(fp, (uint64_t)sector << 9) != FR_OK)
|
||||||
return 0; // Out of bounds.
|
return 0; // Out of bounds.
|
||||||
|
|
||||||
if (is_write)
|
if (!is_write)
|
||||||
{
|
{
|
||||||
if (f_write_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
|
if (f_read_fast(fp, buf, (uint64_t)cur_sectors << 9) != FR_OK)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (f_read_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
|
if (f_write_fast(fp, buf, (uint64_t)cur_sectors << 9) != FR_OK)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = (char *)buf + ((u64)cur_sectors << 9);
|
buf = (char *)buf + ((uint64_t)cur_sectors << 9);
|
||||||
remaining -= cur_sectors;
|
remaining -= cur_sectors;
|
||||||
sector = 0;
|
sector = 0;
|
||||||
++fp;
|
++fp;
|
||||||
|
@ -324,28 +379,25 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
fp = &f_emu.fp_gpp[0];
|
fp = &f_emu.fp_gpp[0];
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_EMMC_PARTITION_BOOT1:
|
case FS_EMMC_PARTITION_BOOT1:
|
||||||
fp = &f_emu.fp_boot1;
|
fp = &f_emu.fp_boot1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FS_EMMC_PARTITION_BOOT0:
|
case FS_EMMC_PARTITION_BOOT0:
|
||||||
fp = &f_emu.fp_boot0;
|
fp = &f_emu.fp_boot0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
|
if (f_lseek(fp, (uint64_t)sector << 9) != FR_OK)
|
||||||
return 0; // Out of bounds.
|
return 0; // Out of bounds. Can only happen with Nand Patrol if resized.
|
||||||
|
|
||||||
uint64_t res = 0;
|
|
||||||
if (!is_write)
|
if (!is_write)
|
||||||
res = !f_read_fast(fp, buf, (u64)num_sectors << 9);
|
return !f_read_fast(fp, buf, (uint64_t)num_sectors << 9);
|
||||||
else
|
else
|
||||||
res = !f_write_fast(fp, buf, (u64)num_sectors << 9);
|
return !f_write_fast(fp, buf, (uint64_t)num_sectors << 9);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controller open wrapper
|
// Controller open wrapper
|
||||||
|
@ -382,9 +434,7 @@ uint64_t sdmmc_wrapper_controller_close(int mmc_id)
|
||||||
if (_this != NULL)
|
if (_this != NULL)
|
||||||
{
|
{
|
||||||
if (mmc_id == FS_SDMMC_SD)
|
if (mmc_id == FS_SDMMC_SD)
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (mmc_id == FS_SDMMC_EMMC)
|
if (mmc_id == FS_SDMMC_EMMC)
|
||||||
{
|
{
|
||||||
|
@ -504,8 +554,6 @@ uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_s
|
||||||
mutex_lock_handler(mmc_id);
|
mutex_lock_handler(mmc_id);
|
||||||
_current_accessor = _this;
|
_current_accessor = _this;
|
||||||
|
|
||||||
sector += 0;
|
|
||||||
|
|
||||||
// Call hekates driver.
|
// Call hekates driver.
|
||||||
if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf))
|
if (sdmmc_storage_write(&sd_storage, sector, num_sectors, buf))
|
||||||
{
|
{
|
||||||
|
|
12
emummc/source/emuMMC/emummc.h
vendored
12
emummc/source/emuMMC/emummc.h
vendored
|
@ -36,6 +36,9 @@ extern "C" {
|
||||||
#include "../FS/FS.h"
|
#include "../FS/FS.h"
|
||||||
#include "../libs/fatfs/ff.h"
|
#include "../libs/fatfs/ff.h"
|
||||||
|
|
||||||
|
#define EMUMMC_FILE_MAX_PARTS 32
|
||||||
|
#define EMUMMC_FP_CLMT_COUNT 1024
|
||||||
|
|
||||||
// FS typedefs
|
// FS typedefs
|
||||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_gc)();
|
typedef sdmmc_accessor_t *(*_sdmmc_accessor_gc)();
|
||||||
typedef sdmmc_accessor_t *(*_sdmmc_accessor_sd)();
|
typedef sdmmc_accessor_t *(*_sdmmc_accessor_sd)();
|
||||||
|
@ -63,11 +66,12 @@ typedef struct _file_based_ctxt
|
||||||
uint64_t parts;
|
uint64_t parts;
|
||||||
uint64_t part_size;
|
uint64_t part_size;
|
||||||
FIL fp_boot0;
|
FIL fp_boot0;
|
||||||
DWORD clmt_boot0[0x400];
|
DWORD clmt_boot0[EMUMMC_FP_CLMT_COUNT];
|
||||||
FIL fp_boot1;
|
FIL fp_boot1;
|
||||||
DWORD clmt_boot1[0x400];
|
DWORD clmt_boot1[EMUMMC_FP_CLMT_COUNT];
|
||||||
FIL fp_gpp[32];
|
FIL fp_gpp[EMUMMC_FILE_MAX_PARTS];
|
||||||
DWORD clmt_gpp[0x8000];
|
DWORD clmt_gpp[EMUMMC_FILE_MAX_PARTS * EMUMMC_FP_CLMT_COUNT];
|
||||||
|
uint64_t total_sect;
|
||||||
} file_based_ctxt;
|
} file_based_ctxt;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in a new issue