mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-05 19:51:45 +00:00
Fix emummc nintendo dir redirection
This commit is contained in:
parent
c8f2d17d02
commit
0dcb496522
8 changed files with 66 additions and 26 deletions
|
@ -59,9 +59,9 @@ typedef struct {
|
||||||
emummc_partition_config_t partition_cfg;
|
emummc_partition_config_t partition_cfg;
|
||||||
emummc_file_config_t file_cfg;
|
emummc_file_config_t file_cfg;
|
||||||
};
|
};
|
||||||
//char emu_dir_path[EMUMMC_FILE_PATH_MAX];
|
char emu_dir_path[EMUMMC_FILE_PATH_MAX];
|
||||||
} exo_emummc_config_t;
|
} exo_emummc_config_t;
|
||||||
|
|
||||||
_Static_assert(sizeof(exo_emummc_config_t) == 0x90, "exo_emummc_config_t definition!");
|
_Static_assert(sizeof(exo_emummc_config_t) == 0x110, "exo_emummc_config_t definition!");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -228,46 +228,63 @@ uint32_t ams_write_address(smc_args_t *args) {
|
||||||
uint32_t ams_get_emummc_config(smc_args_t *args) {
|
uint32_t ams_get_emummc_config(smc_args_t *args) {
|
||||||
/* This retrieves configuration for the current emummc context. */
|
/* This retrieves configuration for the current emummc context. */
|
||||||
/* args->X[1] = MMC id, must be size-bytes aligned and readable by EL0. */
|
/* args->X[1] = MMC id, must be size-bytes aligned and readable by EL0. */
|
||||||
/* args->X[2] = Pointer to output (for path for filebased), must be at least 0x80 bytes. */
|
/* args->X[2] = Pointer to output (for paths for filebased + nintendo dir), must be at least 0x100 bytes. */
|
||||||
upage_ref_t page_ref;
|
|
||||||
const uint32_t mmc_id = (uint32_t)args->X[1];
|
const uint32_t mmc_id = (uint32_t)args->X[1];
|
||||||
void *user_address = (void *)args->X[2];
|
const uintptr_t dram_address = args->X[2];
|
||||||
|
const uintptr_t dram_page_offset = (dram_address & 0xFFFULL);
|
||||||
const exo_emummc_config_t *emummc_cfg = exosphere_get_emummc_config();
|
const exo_emummc_config_t *emummc_cfg = exosphere_get_emummc_config();
|
||||||
|
|
||||||
if (mmc_id != EMUMMC_MMC_NAND) {
|
if (mmc_id != EMUMMC_MMC_NAND) {
|
||||||
/* Emummc config for non-NAND storage is not yet implemented. */
|
/* Emummc config for non-NAND storage is not yet implemented. */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Require page alignment for input address. */
|
||||||
|
if (!ams_is_user_addr_valid(dram_address) || dram_page_offset > 0x1000 - 0x100) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map pages. */
|
||||||
|
ams_map_userpage(dram_address);
|
||||||
|
|
||||||
|
void *user_address = (void *)(AMS_USER_PAGE_SECURE_MONITOR_ADDR + dram_page_offset);
|
||||||
|
|
||||||
|
/* Copy redirection dir out to user. */
|
||||||
|
memcpy((void *)((uintptr_t)user_address + sizeof(emummc_cfg->file_cfg)), emummc_cfg->emu_dir_path, sizeof(emummc_cfg->emu_dir_path));
|
||||||
|
|
||||||
if (emummc_cfg->base_cfg.type == EMUMMC_TYPE_NONE) {
|
if (emummc_cfg->base_cfg.type == EMUMMC_TYPE_NONE) {
|
||||||
/* Just copy base config. */
|
/* Just copy base config. */
|
||||||
memset(args, 0, sizeof(*args));
|
memset(args, 0, sizeof(*args));
|
||||||
memcpy(&args->X[1], emummc_cfg, sizeof(emummc_cfg->base_cfg));
|
memcpy(&args->X[1], emummc_cfg, sizeof(emummc_cfg->base_cfg));
|
||||||
_Static_assert(sizeof(emummc_cfg->base_cfg) <= sizeof(*args) - sizeof(args->X[0]), "Emunand base config too big!");
|
_Static_assert(sizeof(emummc_cfg->base_cfg) <= sizeof(*args) - sizeof(args->X[0]), "Emunand base config too big!");
|
||||||
|
|
||||||
|
/* Unmap pages. */
|
||||||
|
ams_unmap_userpage();
|
||||||
return 0;
|
return 0;
|
||||||
} else if (emummc_cfg->base_cfg.type == EMUMMC_TYPE_PARTITION) {
|
} else if (emummc_cfg->base_cfg.type == EMUMMC_TYPE_PARTITION) {
|
||||||
/* Copy base config and partition config. */
|
/* Copy base config and partition config. */
|
||||||
memset(args, 0, sizeof(*args));
|
memset(args, 0, sizeof(*args));
|
||||||
memcpy(&args->X[1], emummc_cfg, sizeof(emummc_cfg->base_cfg) + sizeof(emummc_cfg->partition_cfg));
|
memcpy(&args->X[1], emummc_cfg, sizeof(emummc_cfg->base_cfg) + sizeof(emummc_cfg->partition_cfg));
|
||||||
_Static_assert(sizeof(emummc_cfg->base_cfg) + sizeof(emummc_cfg->partition_cfg) <= sizeof(*args) - sizeof(args->X[0]), "Emunand partition config too big!");
|
_Static_assert(sizeof(emummc_cfg->base_cfg) + sizeof(emummc_cfg->partition_cfg) <= sizeof(*args) - sizeof(args->X[0]), "Emunand partition config too big!");
|
||||||
|
|
||||||
|
/* Unmap pages. */
|
||||||
|
ams_unmap_userpage();
|
||||||
return 0;
|
return 0;
|
||||||
} else if (emummc_cfg->base_cfg.type == EMUMMC_TYPE_FILES) {
|
} else if (emummc_cfg->base_cfg.type == EMUMMC_TYPE_FILES) {
|
||||||
/* Copy path to userpage. */
|
/* Copy file dir path output to user. */
|
||||||
/* Initialize page reference. */
|
memcpy(user_address, &emummc_cfg->file_cfg, sizeof(emummc_cfg->file_cfg));
|
||||||
if (upage_init(&page_ref, user_address) == 0) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
/* Copy result output back to user. */
|
|
||||||
if (secure_copy_to_user(&page_ref, user_address, &emummc_cfg->file_cfg, sizeof(emummc_cfg->file_cfg)) == 0) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy base config afterwards, since this can't fail. */
|
/* Copy base config afterwards, since this can't fail. */
|
||||||
memset(args, 0, sizeof(*args));
|
memset(args, 0, sizeof(*args));
|
||||||
memcpy(&args->X[1], emummc_cfg, sizeof(emummc_cfg->base_cfg));
|
memcpy(&args->X[1], emummc_cfg, sizeof(emummc_cfg->base_cfg));
|
||||||
_Static_assert(sizeof(emummc_cfg->base_cfg) <= sizeof(*args) - sizeof(args->X[0]), "Emunand base config too big!");
|
_Static_assert(sizeof(emummc_cfg->base_cfg) <= sizeof(*args) - sizeof(args->X[0]), "Emunand base config too big!");
|
||||||
|
|
||||||
|
/* Unmap pages. */
|
||||||
|
ams_unmap_userpage();
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
/* Unmap pages. */
|
||||||
|
ams_unmap_userpage();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -98,9 +98,9 @@ typedef struct {
|
||||||
emummc_partition_config_t partition_cfg;
|
emummc_partition_config_t partition_cfg;
|
||||||
emummc_file_config_t file_cfg;
|
emummc_file_config_t file_cfg;
|
||||||
};
|
};
|
||||||
//char emu_dir_path[EMUMMC_FILE_PATH_MAX];
|
char emu_dir_path[EMUMMC_FILE_PATH_MAX];
|
||||||
} exo_emummc_config_t;
|
} exo_emummc_config_t;
|
||||||
|
|
||||||
_Static_assert(sizeof(exo_emummc_config_t) == 0x90, "exo_emummc_config_t definition!");
|
_Static_assert(sizeof(exo_emummc_config_t) == 0x110, "exo_emummc_config_t definition!");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,9 +112,14 @@ static int emummc_ini_handler(void *user, const char *section, const char *name,
|
||||||
uintptr_t sector = 0;
|
uintptr_t sector = 0;
|
||||||
sscanf(value, "%x", §or);
|
sscanf(value, "%x", §or);
|
||||||
emummc_cfg->sector = sector;
|
emummc_cfg->sector = sector;
|
||||||
|
} else if (strcmp(name, EMUMMC_ID_KEY) == 0) {
|
||||||
|
sscanf(value, "%lx", &emummc_cfg->id);
|
||||||
} else if (strcmp(name, EMUMMC_PATH_KEY) == 0) {
|
} else if (strcmp(name, EMUMMC_PATH_KEY) == 0) {
|
||||||
strncpy(emummc_cfg->path, value, sizeof(emummc_cfg->path) - 1);
|
strncpy(emummc_cfg->path, value, sizeof(emummc_cfg->path) - 1);
|
||||||
emummc_cfg->path[sizeof(emummc_cfg->path) - 1] = '\0';
|
emummc_cfg->path[sizeof(emummc_cfg->path) - 1] = '\0';
|
||||||
|
} else if (strcmp(name, EMUMMC_NINTENDO_PATH_KEY) == 0) {
|
||||||
|
strncpy(emummc_cfg->nintendo_path, value, sizeof(emummc_cfg->nintendo_path) - 1);
|
||||||
|
emummc_cfg->nintendo_path[sizeof(emummc_cfg->nintendo_path) - 1] = '\0';
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +214,7 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
|
static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
|
||||||
emummc_config_t emummc_cfg = {.enabled = false, .sector = -1, .path = ""};
|
emummc_config_t emummc_cfg = {.enabled = false, .id = 0, .sector = -1, .path = "", .nintendo_path = ""};
|
||||||
|
|
||||||
/* Load emummc settings from BCT.ini file. */
|
/* Load emummc settings from BCT.ini file. */
|
||||||
if (ini_parse_string(get_loader_ctx()->bct0, emummc_ini_handler, &emummc_cfg) < 0) {
|
if (ini_parse_string(get_loader_ctx()->bct0, emummc_ini_handler, &emummc_cfg) < 0) {
|
||||||
|
@ -219,8 +224,10 @@ static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
|
||||||
memset(exo_emummc_config, 0, sizeof(*exo_emummc_config));
|
memset(exo_emummc_config, 0, sizeof(*exo_emummc_config));
|
||||||
exo_emummc_config->base_cfg.magic = MAGIC_EMUMMC_CONFIG;
|
exo_emummc_config->base_cfg.magic = MAGIC_EMUMMC_CONFIG;
|
||||||
exo_emummc_config->base_cfg.type = EMUMMC_TYPE_NONE;
|
exo_emummc_config->base_cfg.type = EMUMMC_TYPE_NONE;
|
||||||
exo_emummc_config->base_cfg.id = 0; /* TODO: Multiple ID support. */
|
exo_emummc_config->base_cfg.id = emummc_cfg.id;
|
||||||
exo_emummc_config->base_cfg.fs_version = FS_VER_1_0_0; /* Will be filled out later. */
|
exo_emummc_config->base_cfg.fs_version = FS_VER_1_0_0; /* Will be filled out later. */
|
||||||
|
strncpy(exo_emummc_config->emu_dir_path, emummc_cfg.nintendo_path, sizeof(exo_emummc_config->emu_dir_path));
|
||||||
|
exo_emummc_config->emu_dir_path[sizeof(exo_emummc_config->emu_dir_path) - 1] = '\0';
|
||||||
|
|
||||||
if (emummc_cfg.enabled) {
|
if (emummc_cfg.enabled) {
|
||||||
if (emummc_cfg.sector >= 0) {
|
if (emummc_cfg.sector >= 0) {
|
||||||
|
@ -233,8 +240,9 @@ static bool nxboot_configure_emummc(exo_emummc_config_t *exo_emummc_config) {
|
||||||
}
|
}
|
||||||
} else if (is_valid_folder(emummc_cfg.path)) {
|
} else if (is_valid_folder(emummc_cfg.path)) {
|
||||||
exo_emummc_config->base_cfg.type = EMUMMC_TYPE_FILES;
|
exo_emummc_config->base_cfg.type = EMUMMC_TYPE_FILES;
|
||||||
strncpy(exo_emummc_config->file_cfg.path, emummc_cfg.path, sizeof(exo_emummc_config->file_cfg.path) - 1);
|
strncpy(exo_emummc_config->file_cfg.path, emummc_cfg.path, sizeof(exo_emummc_config->file_cfg.path));
|
||||||
|
exo_emummc_config->file_cfg.path[sizeof(exo_emummc_config->file_cfg.path) - 1] = '\0';
|
||||||
|
|
||||||
int num_parts = 0;
|
int num_parts = 0;
|
||||||
uint64_t part_limit = 0;
|
uint64_t part_limit = 0;
|
||||||
char emummc_boot0_path[0x300 + 1] = {0};
|
char emummc_boot0_path[0x300 + 1] = {0};
|
||||||
|
|
|
@ -22,11 +22,15 @@
|
||||||
#define EMUMMC_ENABLED_KEY "emummc_enabled"
|
#define EMUMMC_ENABLED_KEY "emummc_enabled"
|
||||||
#define EMUMMC_SECTOR_KEY "emummc_sector"
|
#define EMUMMC_SECTOR_KEY "emummc_sector"
|
||||||
#define EMUMMC_PATH_KEY "emummc_path"
|
#define EMUMMC_PATH_KEY "emummc_path"
|
||||||
|
#define EMUMMC_NINTENDO_PATH_KEY "emummc_nintendo_path"
|
||||||
|
#define EMUMMC_ID_KEY "emummc_id"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
uint32_t id;
|
||||||
uint64_t sector;
|
uint64_t sector;
|
||||||
char path[0x100];
|
char path[0x80];
|
||||||
|
char nintendo_path[0x80];
|
||||||
} emummc_config_t;
|
} emummc_config_t;
|
||||||
|
|
||||||
#define MAILBOX_NX_BOOTLOADER_BASE_100_620 0x40002E00
|
#define MAILBOX_NX_BOOTLOADER_BASE_100_620 0x40002E00
|
||||||
|
|
|
@ -163,11 +163,11 @@ Result FsMitmService::OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterf
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FsMitmService::OpenSdCardFileSystem(Out<std::shared_ptr<IFileSystemInterface>> out_fs) {
|
Result FsMitmService::OpenSdCardFileSystem(Out<std::shared_ptr<IFileSystemInterface>> out_fs) {
|
||||||
/* We only care about redirecting this for NS/Emunand. */
|
/* We only care about redirecting this for NS/Emummc. */
|
||||||
if (!IsEmunand()) {
|
if (this->title_id != TitleId_Ns) {
|
||||||
return ResultAtmosphereMitmShouldForwardToSession;
|
return ResultAtmosphereMitmShouldForwardToSession;
|
||||||
}
|
}
|
||||||
if (this->title_id != TitleId_Ns) {
|
if (!IsEmummc()) {
|
||||||
return ResultAtmosphereMitmShouldForwardToSession;
|
return ResultAtmosphereMitmShouldForwardToSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ Result FsMitmService::OpenSdCardFileSystem(Out<std::shared_ptr<IFileSystemInterf
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IFileSystem> redir_fs = std::make_shared<DirectoryRedirectionFileSystem>(new ProxyFileSystem(sd_fs), "/Nintendo", "/Emu/0000" /* TODO: Real Path */);
|
std::shared_ptr<IFileSystem> redir_fs = std::make_shared<DirectoryRedirectionFileSystem>(new ProxyFileSystem(sd_fs), "/Nintendo", GetEmummcNintendoDirPath());
|
||||||
fs = std::make_shared<IFileSystemInterface>(redir_fs);
|
fs = std::make_shared<IFileSystemInterface>(redir_fs);
|
||||||
if (out_fs.IsDomain()) {
|
if (out_fs.IsDomain()) {
|
||||||
out_domain_id = sd_fs.s.object_id;
|
out_domain_id = sd_fs.s.object_id;
|
||||||
|
|
|
@ -65,6 +65,9 @@ static FsFile g_cal0_file = {0};
|
||||||
static u8 g_cal0_storage_backup[ProdinfoSize];
|
static u8 g_cal0_storage_backup[ProdinfoSize];
|
||||||
static u8 g_cal0_backup[ProdinfoSize];
|
static u8 g_cal0_backup[ProdinfoSize];
|
||||||
|
|
||||||
|
/* Emummc-related file. */
|
||||||
|
static FsFile g_emummc_file = {0};
|
||||||
|
|
||||||
static bool IsHexadecimal(const char *str) {
|
static bool IsHexadecimal(const char *str) {
|
||||||
while (*str) {
|
while (*str) {
|
||||||
if (isxdigit(*str)) {
|
if (isxdigit(*str)) {
|
||||||
|
@ -196,6 +199,14 @@ void Utils::InitializeThreadFunc(void *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::RefreshConfiguration();
|
Utils::RefreshConfiguration();
|
||||||
|
|
||||||
|
/* If we're emummc, persist a write handle to prevent other processes from touching the image. */
|
||||||
|
if (IsEmummc()) {
|
||||||
|
const char *emummc_file_path = GetEmummcFilePath();
|
||||||
|
if (emummc_file_path != nullptr) {
|
||||||
|
fsFsOpenFile(&g_sd_filesystem, emummc_file_path, FS_OPEN_READ | FS_OPEN_WRITE, &g_emummc_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize set:sys. */
|
/* Initialize set:sys. */
|
||||||
DoWithSmSession([&]() {
|
DoWithSmSession([&]() {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 05c58ef00263552d4925ed29ac0828cacdfc2ed1
|
Subproject commit afcd075354dec43fae882c3ad4d5220336231d04
|
Loading…
Reference in a new issue