From ed17414b504f6861fcc626495df8b7b9a484b200 Mon Sep 17 00:00:00 2001 From: Christoph Baumann Date: Wed, 19 Feb 2025 14:44:19 +0100 Subject: [PATCH] initial support for emummc on emmc --- .../program/source/smc/secmon_smc_info.cpp | 5 ++- fusee/program/source/fusee_emummc.cpp | 40 ++++++++++++++++--- fusee/program/source/fusee_setup_horizon.cpp | 17 +++++++- .../secmon/secmon_emummc_context.hpp | 9 +++-- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 11f4a693a..01cc412d6 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -447,10 +447,11 @@ namespace ams::secmon::smc { /* Copy out type-specific data. */ switch (cfg.base_cfg.type) { - case EmummcType_None: + case EmummcType_Raw_Emmc: /* No additional configuration needs to be copied. */ break; - case EmummcType_Partition: + case EmummcType_Partition_Sd: + case EmummcType_Partition_Emmc: /* Copy the partition config. */ static_assert(sizeof(cfg.base_cfg) + sizeof(cfg.partition_cfg) <= InlineOutputSize); std::memcpy(inline_output + sizeof(cfg.base_cfg), std::addressof(cfg.partition_cfg), sizeof(cfg.partition_cfg)); diff --git a/fusee/program/source/fusee_emummc.cpp b/fusee/program/source/fusee_emummc.cpp index b56f5d005..f8ad077ea 100644 --- a/fusee/program/source/fusee_emummc.cpp +++ b/fusee/program/source/fusee_emummc.cpp @@ -236,16 +236,34 @@ namespace ams::nxboot { void InitializeEmummc(bool emummc_enabled, const secmon::EmummcConfiguration &emummc_cfg) { Result result; if (emummc_enabled) { - /* Get sd card size. */ - s64 sd_card_size; - if (R_FAILED((result = g_sd_card_storage.GetSize(std::addressof(sd_card_size))))) { - ShowFatalError("Failed to get sd card size: 0x%08" PRIx32 "!\n", result.GetValue()); - } - if (emummc_cfg.base_cfg.type == secmon::EmummcType_Partition) { + if (emummc_cfg.base_cfg.type == secmon::EmummcType_Partition_Sd) { + /* Get sd card size. */ + s64 sd_card_size; + if (R_FAILED((result = g_sd_card_storage.GetSize(std::addressof(sd_card_size))))) { + ShowFatalError("Failed to get sd card size: 0x%08" PRIx32 "!\n", result.GetValue()); + } + const s64 partition_start = emummc_cfg.partition_cfg.start_sector * sdmmc::SectorSize; g_boot0_storage = AllocateObject(g_sd_card_storage, partition_start, 4_MB); g_user_storage = AllocateObject(g_sd_card_storage, partition_start + 8_MB, sd_card_size - (partition_start + 8_MB)); + } else if (emummc_cfg.base_cfg.type == secmon::EmummcType_Partition_Emmc) { + { + const Result result = InitializeMmc(); + if (R_FAILED(result)) { + ShowFatalError("Failed to initialize mmc: 0x%08" PRIx32 "\n", result.GetValue()); + } + } + + /* Get emmc size. */ + s64 emmc_size; + if (R_FAILED((result = g_mmc_user_storage.GetSize(std::addressof(emmc_size))))) { + ShowFatalError("Failed to get emmc size: 0x%08" PRIx32 "!\n", result.GetValue()); + } + + const s64 partition_start = emummc_cfg.partition_cfg.start_sector * sdmmc::SectorSize; + g_boot0_storage = AllocateObject(g_mmc_user_storage, partition_start, 4_MB); + g_user_storage = AllocateObject(g_mmc_user_storage, partition_start + 8_MB, emmc_size - (partition_start + 8_MB)); } else if (emummc_cfg.base_cfg.type == secmon::EmummcType_File) { /* Get the base emummc path. */ std::memcpy(g_emummc_path, emummc_cfg.file_cfg.path.str, sizeof(emummc_cfg.file_cfg.path.str)); @@ -288,6 +306,16 @@ namespace ams::nxboot { /* Create partitions. */ g_boot0_storage = AllocateObject(boot0_file); g_user_storage = AllocateObject(user00_file, len + 1); + } else if (emummc_cfg.base_cfg.type == secmon::EmummcType_Raw_Emmc) { + { + const Result result = InitializeMmc(); + if(R_FAILED(result)) { + ShowFatalError("Failed to initialize mmc: 0x%08" PRIx32 "\n", result.GetValue()); + } + } + + g_boot0_storage = std::addressof(g_mmc_boot0_storage); + g_user_storage = std::addressof(g_mmc_user_storage); } else { ShowFatalError("Unknown emummc type %d\n", static_cast(emummc_cfg.base_cfg.type)); } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 6d0d6a384..52cad9d3f 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -134,6 +134,7 @@ namespace ams::nxboot { u32 sector = 0; const char *path = ""; const char *n_path = ""; + const char *device = ""; { IniSectionList sections; if (ParseIniSafe(sections, "sdmc:/emummc/emummc.ini")) { @@ -155,6 +156,8 @@ namespace ams::nxboot { path = entry.value; } else if (std::strcmp(entry.key, "nintendo_path") == 0) { n_path = entry.value; + } else if (std::strcmp(entry.key, "device") == 0) { + device = entry.value; } } } @@ -167,8 +170,18 @@ namespace ams::nxboot { g_emummc_cfg.emu_dir_path.str[sizeof(g_emummc_cfg.emu_dir_path.str) - 1] = '\x00'; if (enabled) { - if (sector > 0) { - g_emummc_cfg.base_cfg.type = secmon::EmummcType_Partition; + // TODO: proper ini config + if (std::strcmp(device, "no_redirect") == 0 ) { + g_emummc_cfg.base_cfg.type = secmon::EmummcType_Raw_Emmc; + } else if (sector > 0) { + if (std::strcmp(device, "sd") == 0 || device[0] == '\x00' ) { + g_emummc_cfg.base_cfg.type = secmon::EmummcType_Partition_Sd; + } else if (std::strcmp(device, "internal") == 0) { + g_emummc_cfg.base_cfg.type = secmon::EmummcType_Partition_Emmc; + } else { + ShowFatalError("Invalid emummc setting!"); + } + g_emummc_cfg.partition_cfg.start_sector = sector; } else if (path[0] != '\x00' && IsDirectoryExist(path)) { g_emummc_cfg.base_cfg.type = secmon::EmummcType_File; diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_emummc_context.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_emummc_context.hpp index d42d4e2fc..1a54179dc 100644 --- a/libraries/libexosphere/include/exosphere/secmon/secmon_emummc_context.hpp +++ b/libraries/libexosphere/include/exosphere/secmon/secmon_emummc_context.hpp @@ -19,9 +19,10 @@ namespace ams::secmon { enum EmummcType : u32 { - EmummcType_None = 0, - EmummcType_Partition = 1, - EmummcType_File = 2, + EmummcType_Raw_Emmc = 0, + EmummcType_Partition_Sd = 1, + EmummcType_Partition_Emmc = 2, + EmummcType_File = 3, }; enum EmummcMmc { @@ -51,7 +52,7 @@ namespace ams::secmon { } constexpr bool IsEmummcActive() const { - return this->IsValid() && this->type != EmummcType_None; + return this->IsValid() && this->type != EmummcType_Raw_Emmc; } }; static_assert(util::is_pod::value);