Compare commits
2 Commits
v1.9.5
...
emmc-emumm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
886fa9cc97 | ||
|
|
633bb63fc2 |
@@ -279,12 +279,31 @@ namespace ams::secmon::smc {
|
|||||||
break;
|
break;
|
||||||
case ConfigItem::ExosphereAllowCalWrites:
|
case ConfigItem::ExosphereAllowCalWrites:
|
||||||
/* Get whether this unit should allow writing to the calibration partition. */
|
/* Get whether this unit should allow writing to the calibration partition. */
|
||||||
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() || GetSecmonConfiguration().AllowWritingToCalibrationBinarySysmmc());
|
args.r[1] = (GetEmummcEmmcConfiguration().IsActive() || GetSecmonConfiguration().AllowWritingToCalibrationBinarySysmmc());
|
||||||
break;
|
break;
|
||||||
case ConfigItem::ExosphereEmummcType:
|
case ConfigItem::ExosphereEmummcEmmcType:
|
||||||
/* Get what kind of emummc this unit has active. */
|
/* Get what kind of eMMC redirection this unit has active. */
|
||||||
/* NOTE: This may return values other than 1 in the future. */
|
/* NOTE: Even when returning 0, the emummc driver may be used if SD is redirected */
|
||||||
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() ? 1 : 0);
|
{
|
||||||
|
auto &cfg = GetEmummcEmmcConfiguration();
|
||||||
|
if(cfg.IsActive()) {
|
||||||
|
args.r[1] = cfg.base_cfg.type;
|
||||||
|
}else{
|
||||||
|
args.r[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ConfigItem::ExosphereEmummcSdType:
|
||||||
|
/* Get what kind of SD redirection this unit has active. */
|
||||||
|
/* NOTE: Even when returning 0, the emummc driver may be used if eMMC is redirected */
|
||||||
|
{
|
||||||
|
auto &cfg = GetEmummcSdConfiguration();
|
||||||
|
if(cfg.IsActive()) {
|
||||||
|
args.r[1] = cfg.base_cfg.type;
|
||||||
|
}else{
|
||||||
|
args.r[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ConfigItem::ExospherePayloadAddress:
|
case ConfigItem::ExospherePayloadAddress:
|
||||||
/* Gets the physical address of the reboot payload buffer, if one exists. */
|
/* Gets the physical address of the reboot payload buffer, if one exists. */
|
||||||
@@ -421,49 +440,65 @@ namespace ams::secmon::smc {
|
|||||||
const uintptr_t user_offset = user_address % 4_KB;
|
const uintptr_t user_offset = user_address % 4_KB;
|
||||||
|
|
||||||
/* Validate arguments. */
|
/* Validate arguments. */
|
||||||
/* NOTE: In the future, configuration for non-NAND storage may be implemented. */
|
/* NOTE: Only eMMC and SD redirection supported. GC redirection may be supported in the future */
|
||||||
SMC_R_UNLESS(mmc == EmummcMmc_Nand, NotSupported);
|
SMC_R_UNLESS(mmc == EmummcMmc_Nand || mmc == EmummcMmc_Sd, NotSupported);
|
||||||
SMC_R_UNLESS(user_offset + 2 * sizeof(EmummcFilePath) <= 4_KB, InvalidArgument);
|
SMC_R_UNLESS(mmc != EmummcMmc_Nand || user_offset + 2 * sizeof(EmummcFilePath) <= 4_KB, InvalidArgument);
|
||||||
|
|
||||||
/* Get the emummc config. */
|
|
||||||
const auto &cfg = GetEmummcConfiguration();
|
|
||||||
static_assert(sizeof(cfg.file_cfg) == sizeof(EmummcFilePath));
|
|
||||||
static_assert(sizeof(cfg.emu_dir_path) == sizeof(EmummcFilePath));
|
|
||||||
|
|
||||||
/* Clear the output. */
|
|
||||||
constexpr size_t InlineOutputSize = sizeof(args) - sizeof(args.r[0]);
|
constexpr size_t InlineOutputSize = sizeof(args) - sizeof(args.r[0]);
|
||||||
u8 * const inline_output = static_cast<u8 *>(static_cast<void *>(std::addressof(args.r[1])));
|
u8 * const inline_output = static_cast<u8 *>(static_cast<void *>(std::addressof(args.r[1])));
|
||||||
std::memset(inline_output, 0, InlineOutputSize);
|
std::memset(inline_output, 0, InlineOutputSize);
|
||||||
|
|
||||||
/* Copy out the configuration. */
|
if(mmc == EmummcMmc_Nand){
|
||||||
{
|
/* Copy emummc config for eMMC redirection */
|
||||||
/* Map the user output page. */
|
|
||||||
AtmosphereUserPageMapper mapper(user_address);
|
/* Get emummc config for eMMC redirection */
|
||||||
SMC_R_UNLESS(mapper.Map(), InvalidArgument);
|
const auto &cfg = GetEmummcEmmcConfiguration();
|
||||||
|
|
||||||
/* Copy the base configuration. */
|
|
||||||
static_assert(sizeof(cfg.base_cfg) <= InlineOutputSize);
|
static_assert(sizeof(cfg.base_cfg) <= InlineOutputSize);
|
||||||
std::memcpy(inline_output, std::addressof(cfg.base_cfg), sizeof(cfg.base_cfg));
|
std::memcpy(inline_output, std::addressof(cfg.base_cfg), sizeof(cfg.base_cfg));
|
||||||
|
|
||||||
/* Copy out type-specific data. */
|
AtmosphereUserPageMapper mapper(user_address);
|
||||||
switch (cfg.base_cfg.type) {
|
SMC_R_UNLESS(mapper.Map(), InvalidArgument);
|
||||||
case EmummcType_None:
|
|
||||||
/* No additional configuration needs to be copied. */
|
switch(cfg.base_cfg.type){
|
||||||
|
case EmummcEmmcType_None:
|
||||||
|
/* Nothing to copy if disabled */
|
||||||
break;
|
break;
|
||||||
case EmummcType_Partition:
|
case EmummcEmmcType_Partition_Emmc:
|
||||||
/* Copy the partition config. */
|
case EmummcEmmcType_Partition_Sd:
|
||||||
|
/* Copy file config, if file based */
|
||||||
static_assert(sizeof(cfg.base_cfg) + sizeof(cfg.partition_cfg) <= InlineOutputSize);
|
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));
|
std::memcpy(inline_output + sizeof(cfg.base_cfg), std::addressof(cfg.partition_cfg), sizeof(cfg.partition_cfg));
|
||||||
break;
|
break;
|
||||||
case EmummcType_File:
|
case EmummcEmmcType_File_Emmc:
|
||||||
/* Copy the file config. */
|
case EmummcEmmcType_File_Sd:
|
||||||
|
/* Copy partition config, if partition based */
|
||||||
SMC_R_UNLESS(mapper.CopyToUser(user_address, std::addressof(cfg.file_cfg), sizeof(cfg.file_cfg)), InvalidArgument);
|
SMC_R_UNLESS(mapper.CopyToUser(user_address, std::addressof(cfg.file_cfg), sizeof(cfg.file_cfg)), InvalidArgument);
|
||||||
break;
|
break;
|
||||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the redirection directory path to the user page. */
|
/* Copy the redirection directory path to the user page */
|
||||||
SMC_R_UNLESS(mapper.CopyToUser(user_address + sizeof(EmummcFilePath), std::addressof(cfg.emu_dir_path), sizeof(cfg.emu_dir_path)), InvalidArgument);
|
SMC_R_UNLESS(mapper.CopyToUser(user_address + sizeof(cfg.file_cfg), std::addressof(cfg.emu_dir_path), sizeof(cfg.emu_dir_path)), InvalidArgument);
|
||||||
|
}else if(mmc == EmummcMmc_Sd){
|
||||||
|
/* Copy emummc config for SD redirection */
|
||||||
|
|
||||||
|
/* Get emummc config for SD redirection */
|
||||||
|
const auto &cfg = GetEmummcSdConfiguration();
|
||||||
|
|
||||||
|
static_assert(sizeof(cfg.base_cfg) <= InlineOutputSize);
|
||||||
|
std::memcpy(inline_output, std::addressof(cfg.base_cfg), sizeof(cfg.base_cfg));
|
||||||
|
|
||||||
|
switch(cfg.base_cfg.type) {
|
||||||
|
case EmummcSdType_None:
|
||||||
|
break;
|
||||||
|
case EmummcSdType_Partition_Emmc:
|
||||||
|
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));
|
||||||
|
break;
|
||||||
|
/* File based and SD partition based (currently) not supported for SD redirection */
|
||||||
|
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SmcResult::Success;
|
return SmcResult::Success;
|
||||||
|
|||||||
@@ -47,12 +47,13 @@ namespace ams::secmon::smc {
|
|||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcEmmcType = 65007,
|
||||||
ExospherePayloadAddress = 65008,
|
ExospherePayloadAddress = 65008,
|
||||||
ExosphereLogConfiguration = 65009,
|
ExosphereLogConfiguration = 65009,
|
||||||
ExosphereForceEnableUsb30 = 65010,
|
ExosphereForceEnableUsb30 = 65010,
|
||||||
ExosphereSupportedHosVersion = 65011,
|
ExosphereSupportedHosVersion = 65011,
|
||||||
ExosphereApproximateApiVersion = 65012,
|
ExosphereApproximateApiVersion = 65012,
|
||||||
|
ExosphereEmummcSdType = 65013,
|
||||||
};
|
};
|
||||||
|
|
||||||
SmcResult SmcGetConfigUser(SmcArguments &args);
|
SmcResult SmcGetConfigUser(SmcArguments &args);
|
||||||
|
|||||||
5
fusee/program/source/fatfs/ff.h
vendored
5
fusee/program/source/fatfs/ff.h
vendored
@@ -172,8 +172,7 @@ typedef struct {
|
|||||||
LBA_t bitbase; /* Allocation bitmap base sector */
|
LBA_t bitbase; /* Allocation bitmap base sector */
|
||||||
#endif
|
#endif
|
||||||
LBA_t winsect; /* Current sector appearing in the win[] */
|
LBA_t winsect; /* Current sector appearing in the win[] */
|
||||||
BYTE pad[4];
|
__attribute__((aligned(8))) BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
|
||||||
} FATFS;
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
@@ -218,7 +217,7 @@ typedef struct {
|
|||||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||||
#endif
|
#endif
|
||||||
#if !FF_FS_TINY
|
#if !FF_FS_TINY
|
||||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
__attribute__((aligned(8))) BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||||
#endif
|
#endif
|
||||||
} FIL;
|
} FIL;
|
||||||
|
|
||||||
|
|||||||
5
fusee/program/source/fatfs/fusee_diskio.cpp
vendored
5
fusee/program/source/fatfs/fusee_diskio.cpp
vendored
@@ -16,7 +16,7 @@
|
|||||||
#include <exosphere.hpp>
|
#include <exosphere.hpp>
|
||||||
#include "diskio_cpp.h"
|
#include "diskio_cpp.h"
|
||||||
#include "../fusee_sd_card.hpp"
|
#include "../fusee_sd_card.hpp"
|
||||||
#include "../fusee_emummc.hpp"
|
#include "../fusee_mmc.hpp"
|
||||||
|
|
||||||
bool diskio_read_sd_card(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
bool diskio_read_sd_card(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||||
return R_SUCCEEDED(::ams::nxboot::ReadSdCard(dst, size, sector_index, sector_count));
|
return R_SUCCEEDED(::ams::nxboot::ReadSdCard(dst, size, sector_index, sector_count));
|
||||||
@@ -27,9 +27,10 @@ bool diskio_write_sd_card(size_t sector_index, size_t sector_count, const void *
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool diskio_read_system(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
bool diskio_read_system(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||||
return false;
|
return R_SUCCEEDED(::ams::nxboot::ReadMmc(dst, size, ::ams::sdmmc::MmcPartition::MmcPartition_UserData, sector_index, sector_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool diskio_write_system(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
bool diskio_write_system(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||||
|
/* Don't allow writes to eMMC GPP partition */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,11 @@ namespace ams::fs {
|
|||||||
constexpr size_t MaxFiles = 8 + 64;
|
constexpr size_t MaxFiles = 8 + 64;
|
||||||
constexpr size_t MaxDirectories = 2;
|
constexpr size_t MaxDirectories = 2;
|
||||||
|
|
||||||
constinit bool g_is_sd_mounted = false;
|
constinit bool g_is_sd_mounted = false;
|
||||||
|
constinit bool g_is_sys_mounted = false;
|
||||||
|
|
||||||
alignas(0x10) constinit FATFS g_sd_fs = {};
|
alignas(0x10) constinit FATFS g_sd_fs = {};
|
||||||
|
alignas(0x10) constinit FATFS g_sys_fs = {};
|
||||||
|
|
||||||
alignas(0x10) constinit FIL g_files[MaxFiles] = {};
|
alignas(0x10) constinit FIL g_files[MaxFiles] = {};
|
||||||
alignas(0x10) constinit DIR g_dirs[MaxDirectories] = {};
|
alignas(0x10) constinit DIR g_dirs[MaxDirectories] = {};
|
||||||
@@ -117,6 +119,18 @@ namespace ams::fs {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MountSys() {
|
||||||
|
AMS_ASSERT(!g_is_sys_mounted);
|
||||||
|
g_is_sys_mounted = f_mount(std::addressof(g_sys_fs), "sys:", 1) == FR_OK;
|
||||||
|
return g_is_sys_mounted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnmountSys() {
|
||||||
|
AMS_ASSERT(g_is_sys_mounted);
|
||||||
|
f_unmount("sys:");
|
||||||
|
g_is_sys_mounted = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool MountSdCard() {
|
bool MountSdCard() {
|
||||||
AMS_ASSERT(!g_is_sd_mounted);
|
AMS_ASSERT(!g_is_sd_mounted);
|
||||||
g_is_sd_mounted = f_mount(std::addressof(g_sd_fs), "sdmc:", 1) == FR_OK;
|
g_is_sd_mounted = f_mount(std::addressof(g_sd_fs), "sdmc:", 1) == FR_OK;
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ namespace ams::fs {
|
|||||||
bool MountSdCard();
|
bool MountSdCard();
|
||||||
void UnmountSdCard();
|
void UnmountSdCard();
|
||||||
|
|
||||||
|
bool MountSys();
|
||||||
|
void UnmountSys();
|
||||||
|
|
||||||
Result GetEntryType(DirectoryEntryType *out_entry_type, bool *out_archive, const char *path);
|
Result GetEntryType(DirectoryEntryType *out_entry_type, bool *out_archive, const char *path);
|
||||||
|
|
||||||
Result CreateFile(const char *path, s64 size);
|
Result CreateFile(const char *path, s64 size);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace ams::nxboot {
|
|||||||
u32 num_sectors;
|
u32 num_sectors;
|
||||||
R_TRY(GetMmcMemoryCapacity(std::addressof(num_sectors), Partition));
|
R_TRY(GetMmcMemoryCapacity(std::addressof(num_sectors), Partition));
|
||||||
|
|
||||||
*out = num_sectors * sdmmc::SectorSize;
|
*out = static_cast<s64>(num_sectors) * static_cast<s64>(sdmmc::SectorSize);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeEmummc(bool emummc_enabled, const secmon::EmummcConfiguration &emummc_cfg) {
|
void InitializeEmummc(bool emummc_enabled, const secmon::EmummcEmmcConfiguration &emummc_cfg) {
|
||||||
Result result;
|
Result result;
|
||||||
if (emummc_enabled) {
|
if (emummc_enabled) {
|
||||||
/* Get sd card size. */
|
/* Get sd card size. */
|
||||||
@@ -242,34 +242,65 @@ namespace ams::nxboot {
|
|||||||
ShowFatalError("Failed to get sd card size: 0x%08" PRIx32 "!\n", result.GetValue());
|
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::EmummcEmmcType_Partition_Emmc || emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_Partition_Sd) {
|
||||||
const s64 partition_start = emummc_cfg.partition_cfg.start_sector * sdmmc::SectorSize;
|
/* Partition based emummc */
|
||||||
g_boot0_storage = AllocateObject<fs::SubStorage>(g_sd_card_storage, partition_start, 4_MB);
|
if(emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_Partition_Emmc) {
|
||||||
g_user_storage = AllocateObject<fs::SubStorage>(g_sd_card_storage, partition_start + 8_MB, sd_card_size - (partition_start + 8_MB));
|
/* When emmc based, init eMMC */
|
||||||
} else if (emummc_cfg.base_cfg.type == secmon::EmummcType_File) {
|
if (R_FAILED((result = InitializeMmc()))) {
|
||||||
/* Get the base emummc path. */
|
ShowFatalError("Failed to initialize mmc: 0x%08" PRIx32 "\n", result.GetValue());
|
||||||
std::memcpy(g_emummc_path, emummc_cfg.file_cfg.path.str, sizeof(emummc_cfg.file_cfg.path.str));
|
}
|
||||||
|
|
||||||
/* Get path length. */
|
|
||||||
auto len = std::strlen(g_emummc_path);
|
|
||||||
|
|
||||||
/* Append emmc. */
|
|
||||||
std::memcpy(g_emummc_path + len, "/eMMC", 6);
|
|
||||||
len += 5;
|
|
||||||
|
|
||||||
/* Open boot0. */
|
|
||||||
fs::FileHandle boot0_file;
|
|
||||||
std::memcpy(g_emummc_path + len, "/boot0", 7);
|
|
||||||
if (R_FAILED((result = fs::OpenFile(std::addressof(boot0_file), g_emummc_path, fs::OpenMode_Read)))) {
|
|
||||||
ShowFatalError("Failed to open emummc boot0 file: 0x%08" PRIx32 "!\n", result.GetValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open boot1. */
|
/* Get SD or eMMC storage */
|
||||||
g_emummc_path[len + 5] = '1';
|
fs::IStorage &storage = emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_Partition_Sd ? static_cast<fs::IStorage&>(g_sd_card_storage) : static_cast<fs::IStorage&>(g_mmc_user_storage);
|
||||||
|
|
||||||
|
/* Get total storage size */
|
||||||
|
s64 storage_size;
|
||||||
|
if (R_FAILED((result = storage.GetSize(std::addressof(storage_size))))) {
|
||||||
|
ShowFatalError("Failed to get storage size: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
const s64 partition_start = emummc_cfg.partition_cfg.start_sector * sdmmc::SectorSize;
|
||||||
|
g_boot0_storage = AllocateObject<fs::SubStorage>(storage, partition_start, 4_MB);
|
||||||
|
g_user_storage = AllocateObject<fs::SubStorage>(storage, partition_start + 8_MB, storage_size - (partition_start + 8_MB));
|
||||||
|
} else if (emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_File_Emmc || emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_File_Sd) {
|
||||||
|
/* File based emummc */
|
||||||
|
if(emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_File_Emmc) {
|
||||||
|
/* When emmc based, init eMMC */
|
||||||
|
if (R_FAILED((result = InitializeMmc()))) {
|
||||||
|
ShowFatalError("Failed to initialize mmc: 0x%08" PRIx32 "\n", result.GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs::MountSys()) {
|
||||||
|
ShowFatalError("Failed to mount mmc!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set drive to read from */
|
||||||
|
if (emummc_cfg.base_cfg.type == secmon::EmummcEmmcType_File_Sd) {
|
||||||
|
std::strcpy(g_emummc_path, "sdmc:");
|
||||||
|
} else {
|
||||||
|
std::strcpy(g_emummc_path, "sys:");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(g_emummc_path + std::strlen(g_emummc_path), emummc_cfg.file_cfg.path.str, sizeof(emummc_cfg.file_cfg.path.str));
|
||||||
|
std::strcat(g_emummc_path, "/eMMC");
|
||||||
|
|
||||||
|
auto len = std::strlen(g_emummc_path);
|
||||||
|
|
||||||
|
/* Open boot0 file */
|
||||||
|
fs::FileHandle boot0_file;
|
||||||
|
std::strcat(g_emummc_path, "/boot0");
|
||||||
|
if(R_FAILED((result = fs::OpenFile(std::addressof(boot0_file), g_emummc_path, fs::OpenMode_Read)))) {
|
||||||
|
ShowFatalError("Failed to open emummc boot0 file: 0x%08" PRIx32 " %s!\n", result.GetValue(), g_emummc_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if boot1 file exists */
|
||||||
|
std::strcpy(g_emummc_path + len, "/boot1");
|
||||||
{
|
{
|
||||||
fs::DirectoryEntryType entry_type;
|
fs::DirectoryEntryType entry_type;
|
||||||
bool is_archive;
|
bool is_archive;
|
||||||
if (R_FAILED((result = fs::GetEntryType(std::addressof(entry_type), std::addressof(is_archive), g_emummc_path)))) {
|
if (R_FAILED((result = fs::GetEntryType(std::addressof(entry_type), std::addressof(is_archive), g_emummc_path)))){
|
||||||
ShowFatalError("Failed to find emummc boot1 file: 0x%08" PRIx32 "!\n", result.GetValue());
|
ShowFatalError("Failed to find emummc boot1 file: 0x%08" PRIx32 "!\n", result.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,16 +309,16 @@ namespace ams::nxboot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open userdata. */
|
/* Open userdata */
|
||||||
std::memcpy(g_emummc_path + len, "/00", 4);
|
std::strcpy(g_emummc_path + len, "/00");
|
||||||
fs::FileHandle user00_file;
|
fs::FileHandle user00_file;
|
||||||
if (R_FAILED((result = fs::OpenFile(std::addressof(user00_file), g_emummc_path, fs::OpenMode_Read)))) {
|
if(R_FAILED((result = fs::OpenFile(std::addressof(user00_file), g_emummc_path, fs::OpenMode_Read)))) {
|
||||||
ShowFatalError("Failed to open emummc user %02d file: 0x%08" PRIx32 "!\n", 0, result.GetValue());
|
ShowFatalError("Failed to open emummc user %02d file: 0x%08" PRIx32 "!\n", 0, result.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create partitions. */
|
/* Create partition */
|
||||||
g_boot0_storage = AllocateObject<fs::FileHandleStorage>(boot0_file);
|
g_boot0_storage = AllocateObject<fs::FileHandleStorage>(boot0_file);
|
||||||
g_user_storage = AllocateObject<EmummcFileStorage>(user00_file, len + 1);
|
g_user_storage = AllocateObject<EmummcFileStorage>(user00_file, len + 1);
|
||||||
} else {
|
} else {
|
||||||
ShowFatalError("Unknown emummc type %d\n", static_cast<int>(emummc_cfg.base_cfg.type));
|
ShowFatalError("Unknown emummc type %d\n", static_cast<int>(emummc_cfg.base_cfg.type));
|
||||||
}
|
}
|
||||||
@@ -304,6 +335,7 @@ namespace ams::nxboot {
|
|||||||
g_boot0_storage = std::addressof(g_mmc_boot0_storage);
|
g_boot0_storage = std::addressof(g_mmc_boot0_storage);
|
||||||
g_user_storage = std::addressof(g_mmc_user_storage);
|
g_user_storage = std::addressof(g_mmc_user_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_boot0_storage == nullptr) {
|
if (g_boot0_storage == nullptr) {
|
||||||
ShowFatalError("Failed to initialize BOOT0\n");
|
ShowFatalError("Failed to initialize BOOT0\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::nxboot {
|
namespace ams::nxboot {
|
||||||
|
|
||||||
void InitializeEmummc(bool emummc_enabled, const secmon::EmummcConfiguration &emummc_cfg);
|
void InitializeEmummc(bool emummc_enabled, const secmon::EmummcEmmcConfiguration &emummc_cfg);
|
||||||
|
|
||||||
Result ReadBoot0(s64 offset, void *dst, size_t size);
|
Result ReadBoot0(s64 offset, void *dst, size_t size);
|
||||||
Result ReadPackage2(s64 offset, void *dst, size_t size);
|
Result ReadPackage2(s64 offset, void *dst, size_t size);
|
||||||
|
|||||||
@@ -126,27 +126,33 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
bool ConfigureEmummc() {
|
bool ConfigureEmummc() {
|
||||||
/* Set magic. */
|
/* Set magic. */
|
||||||
g_emummc_cfg.base_cfg.magic = secmon::EmummcBaseConfiguration::Magic;
|
auto &sd_cfg = g_emummc_cfg.sd_cfg;
|
||||||
|
auto &emmc_cfg = g_emummc_cfg.emmc_cfg;
|
||||||
|
|
||||||
/* Parse ini. */
|
emmc_cfg.base_cfg.magic = secmon::EmummcEmmcBaseConfiguration::Magic;
|
||||||
bool enabled = false;
|
sd_cfg.base_cfg.magic = secmon::EmummcSdBaseConfiguration::Magic;
|
||||||
|
|
||||||
|
bool emummc_driver_enabled = false;
|
||||||
|
|
||||||
|
/* Parse emummc ini. */
|
||||||
|
u32 enabled = 0;
|
||||||
u32 id = 0;
|
u32 id = 0;
|
||||||
u32 sector = 0;
|
u32 sector = 0;
|
||||||
const char *path = "";
|
const char *path = "";
|
||||||
const char *n_path = "";
|
const char *n_path = "";
|
||||||
|
|
||||||
{
|
{
|
||||||
IniSectionList sections;
|
IniSectionList sections;
|
||||||
if (ParseIniSafe(sections, "sdmc:/emummc/emummc.ini")) {
|
if (ParseIniSafe(sections, "sdmc:/emummc/emummc.ini")) {
|
||||||
for (const auto §ion : sections) {
|
for (const auto §ion : sections){
|
||||||
/* We only care about the [emummc] section. */
|
/* Skip non-emummc sections */
|
||||||
if (std::strcmp(section.name, "emummc")) {
|
if (std::strcmp(section.name, "emummc")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle individual fields. */
|
|
||||||
for (const auto &entry : section.kv_list) {
|
for (const auto &entry : section.kv_list) {
|
||||||
if (std::strcmp(entry.key, "enabled") == 0) {
|
if(std::strcmp(entry.key, "enabled") == 0) {
|
||||||
enabled = entry.value[0] != '0';
|
enabled = ParseDecimalInteger(entry.value);
|
||||||
} else if (std::strcmp(entry.key, "id") == 0) {
|
} else if (std::strcmp(entry.key, "id") == 0) {
|
||||||
id = ParseHexInteger(entry.value);
|
id = ParseHexInteger(entry.value);
|
||||||
} else if (std::strcmp(entry.key, "sector") == 0) {
|
} else if (std::strcmp(entry.key, "sector") == 0) {
|
||||||
@@ -161,26 +167,88 @@ namespace ams::nxboot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set values parsed from config. */
|
/* Set parsed values to config */
|
||||||
g_emummc_cfg.base_cfg.id = id;
|
constexpr const char *emummc_err_str = "Invalid emummc setting!\n";
|
||||||
std::strncpy(g_emummc_cfg.emu_dir_path.str, n_path, sizeof(g_emummc_cfg.emu_dir_path.str));
|
|
||||||
g_emummc_cfg.emu_dir_path.str[sizeof(g_emummc_cfg.emu_dir_path.str) - 1] = '\x00';
|
|
||||||
|
|
||||||
if (enabled) {
|
emmc_cfg.base_cfg.id = id;
|
||||||
|
std::strncpy(emmc_cfg.emu_dir_path.str, n_path, sizeof(emmc_cfg.emu_dir_path.str));
|
||||||
|
emmc_cfg.emu_dir_path.str[sizeof(emmc_cfg.emu_dir_path.str) - 1] = '\x00';
|
||||||
|
|
||||||
|
if (enabled == 1) {
|
||||||
|
/* SD based */
|
||||||
|
emummc_driver_enabled = true;
|
||||||
if (sector > 0) {
|
if (sector > 0) {
|
||||||
g_emummc_cfg.base_cfg.type = secmon::EmummcType_Partition;
|
emmc_cfg.base_cfg.type = secmon::EmummcEmmcType::EmummcEmmcType_Partition_Sd;
|
||||||
g_emummc_cfg.partition_cfg.start_sector = sector;
|
emmc_cfg.partition_cfg.start_sector = sector;
|
||||||
} else if (path[0] != '\x00' && IsDirectoryExist(path)) {
|
} else if (path[0] != '\x00' && IsDirectoryExist(path)) {
|
||||||
g_emummc_cfg.base_cfg.type = secmon::EmummcType_File;
|
emmc_cfg.base_cfg.type = secmon::EmummcEmmcType::EmummcEmmcType_File_Sd;
|
||||||
|
std::strncpy(emmc_cfg.file_cfg.path.str, path, sizeof(emmc_cfg.file_cfg.path.str));
|
||||||
std::strncpy(g_emummc_cfg.file_cfg.path.str, path, sizeof(g_emummc_cfg.file_cfg.path.str));
|
emmc_cfg.file_cfg.path.str[sizeof(emmc_cfg.file_cfg.path.str) - 1] = '\x00';
|
||||||
g_emummc_cfg.file_cfg.path.str[sizeof(g_emummc_cfg.file_cfg.path.str) - 1] = '\x00';
|
|
||||||
} else {
|
} else {
|
||||||
ShowFatalError("Invalid emummc setting!\n");
|
ShowFatalError(emummc_err_str);
|
||||||
|
}
|
||||||
|
} else if (enabled == 4){
|
||||||
|
/* eMMC based */
|
||||||
|
emummc_driver_enabled = true;
|
||||||
|
if (sector > 0) {
|
||||||
|
emmc_cfg.base_cfg.type = secmon::EmummcEmmcType::EmummcEmmcType_Partition_Emmc;
|
||||||
|
emmc_cfg.partition_cfg.start_sector = sector;
|
||||||
|
} else if (path[0] != '\x00' /* && IsDirectoryExist(path) */) {
|
||||||
|
/* TODO: Should check if directory exist on *eMMC* fat partition instead of SD */
|
||||||
|
emmc_cfg.base_cfg.type = secmon::EmummcEmmcType::EmummcEmmcType_File_Emmc;
|
||||||
|
std::strncpy(emmc_cfg.file_cfg.path.str, path, sizeof(emmc_cfg.file_cfg.path.str));
|
||||||
|
emmc_cfg.file_cfg.path.str[sizeof(emmc_cfg.file_cfg.path.str) - 1] = '\x00';
|
||||||
|
} else {
|
||||||
|
ShowFatalError(emummc_err_str);
|
||||||
|
}
|
||||||
|
} else if (enabled == 0) {
|
||||||
|
emmc_cfg.base_cfg.type = secmon::EmummcEmmcType::EmummcEmmcType_None;
|
||||||
|
} else {
|
||||||
|
ShowFatalError(emummc_err_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse emusd ini. */
|
||||||
|
constexpr const char *emusd_err_str = "Invalid emusd setting!\n";
|
||||||
|
|
||||||
|
u32 sd_enabled = 0;
|
||||||
|
u32 sd_sector = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
IniSectionList sections;
|
||||||
|
if (ParseIniSafe(sections, "sdmc:/emusd/emusd.ini")) {
|
||||||
|
for (const auto §ion : sections){
|
||||||
|
/* Skip non-emummc sections */
|
||||||
|
if (std::strcmp(section.name, "emusd")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &entry : section.kv_list) {
|
||||||
|
if(std::strcmp(entry.key, "enabled") == 0) {
|
||||||
|
sd_enabled = ParseDecimalInteger(entry.value);
|
||||||
|
} else if (std::strcmp(entry.key, "sector") == 0) {
|
||||||
|
sd_sector = ParseHexInteger(entry.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return enabled;
|
/* Set parsed values to config */
|
||||||
|
if (sd_enabled == 4) {
|
||||||
|
emummc_driver_enabled = true;
|
||||||
|
if (sd_sector > 0) {
|
||||||
|
sd_cfg.partition_cfg.start_sector = sd_sector;
|
||||||
|
sd_cfg.base_cfg.type = secmon::EmummcSdType::EmummcSdType_Partition_Emmc;
|
||||||
|
} else {
|
||||||
|
ShowFatalError(emusd_err_str);
|
||||||
|
}
|
||||||
|
} else if (sd_enabled == 0) {
|
||||||
|
sd_cfg.base_cfg.type = secmon::EmummcSdType::EmummcSdType_None;
|
||||||
|
} else {
|
||||||
|
ShowFatalError(emusd_err_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return emummc_driver_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *LoadPackage1(fuse::SocType soc_type) {
|
u8 *LoadPackage1(fuse::SocType soc_type) {
|
||||||
@@ -502,7 +570,8 @@ namespace ams::nxboot {
|
|||||||
storage_ctx.log_baud_rate = 115200;
|
storage_ctx.log_baud_rate = 115200;
|
||||||
|
|
||||||
/* Set the fs version. */
|
/* Set the fs version. */
|
||||||
storage_ctx.emummc_cfg.base_cfg.fs_version = fs_version;
|
storage_ctx.emummc_cfg.emmc_cfg.base_cfg.fs_version = fs_version;
|
||||||
|
storage_ctx.emummc_cfg.sd_cfg.base_cfg.fs_version = fs_version;
|
||||||
|
|
||||||
/* Parse fields from exosphere.ini */
|
/* Parse fields from exosphere.ini */
|
||||||
{
|
{
|
||||||
@@ -730,11 +799,12 @@ namespace ams::nxboot {
|
|||||||
DeriveAllKeys(soc_type);
|
DeriveAllKeys(soc_type);
|
||||||
|
|
||||||
/* Determine whether we're using emummc. */
|
/* Determine whether we're using emummc. */
|
||||||
const bool emummc_enabled = ConfigureEmummc();
|
const bool emummc_driver_enabled = ConfigureEmummc();
|
||||||
|
const bool emummc_enabled = g_emummc_cfg.emmc_cfg.base_cfg.type != secmon::EmummcEmmcType_None;
|
||||||
|
|
||||||
/* Initialize emummc. */
|
/* Initialize emummc. */
|
||||||
/* NOTE: SYSTEM:/ accessible past this point. */
|
/* NOTE: SYSTEM:/ accessible past this point. */
|
||||||
InitializeEmummc(emummc_enabled, g_emummc_cfg);
|
InitializeEmummc(emummc_enabled, g_emummc_cfg.emmc_cfg);
|
||||||
|
|
||||||
/* Read bootloader. */
|
/* Read bootloader. */
|
||||||
const u8 * const package1 = LoadPackage1(soc_type);
|
const u8 * const package1 = LoadPackage1(soc_type);
|
||||||
@@ -752,7 +822,7 @@ namespace ams::nxboot {
|
|||||||
const bool nogc_enabled = IsNogcEnabled(target_firmware);
|
const bool nogc_enabled = IsNogcEnabled(target_firmware);
|
||||||
|
|
||||||
/* Decide what KIPs/patches we're loading. */
|
/* Decide what KIPs/patches we're loading. */
|
||||||
const auto fs_version = ConfigureStratosphere(package2, target_firmware, emummc_enabled, nogc_enabled);
|
const auto fs_version = ConfigureStratosphere(package2, target_firmware, emummc_driver_enabled, nogc_enabled);
|
||||||
|
|
||||||
/* Setup exosphere. */
|
/* Setup exosphere. */
|
||||||
ConfigureExosphere(soc_type, target_firmware, emummc_enabled, fs_version);
|
ConfigureExosphere(soc_type, target_firmware, emummc_enabled, fs_version);
|
||||||
@@ -761,7 +831,7 @@ namespace ams::nxboot {
|
|||||||
StartCpu();
|
StartCpu();
|
||||||
|
|
||||||
/* Build modified package2. */
|
/* Build modified package2. */
|
||||||
RebuildPackage2(target_firmware, emummc_enabled);
|
RebuildPackage2(target_firmware, emummc_driver_enabled);
|
||||||
|
|
||||||
/* Wait for confirmation that exosphere is ready. */
|
/* Wait for confirmation that exosphere is ready. */
|
||||||
WaitSecureMonitorState(pkg1::SecureMonitorState_Initialized);
|
WaitSecureMonitorState(pkg1::SecureMonitorState_Initialized);
|
||||||
|
|||||||
@@ -764,7 +764,7 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ConfigureStratosphere(const u8 *nn_package2, ams::TargetFirmware target_firmware, bool emummc_enabled, bool nogc_enabled) {
|
u32 ConfigureStratosphere(const u8 *nn_package2, ams::TargetFirmware target_firmware, bool emummc_driver_enabled, bool nogc_enabled) {
|
||||||
/* Load KIPs off the SD card. */
|
/* Load KIPs off the SD card. */
|
||||||
{
|
{
|
||||||
/* Create kip dir path. */
|
/* Create kip dir path. */
|
||||||
@@ -852,13 +852,13 @@ namespace ams::nxboot {
|
|||||||
/* Get FS version. */
|
/* Get FS version. */
|
||||||
const auto fs_version = GetFsVersion(fs_meta->kip_hash);
|
const auto fs_version = GetFsVersion(fs_meta->kip_hash);
|
||||||
if (fs_version >= FsVersion_Count) {
|
if (fs_version >= FsVersion_Count) {
|
||||||
if (emummc_enabled || nogc_enabled) {
|
if (emummc_driver_enabled || nogc_enabled) {
|
||||||
ShowFatalError("Failed to identify FS!\n");
|
ShowFatalError("Failed to identify FS!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If emummc is enabled, we need to decompress fs .text. */
|
/* If emummc is enabled, we need to decompress fs .text. */
|
||||||
if (emummc_enabled) {
|
if (emummc_driver_enabled) {
|
||||||
fs_meta->patch_segments |= (1 << 0);
|
fs_meta->patch_segments |= (1 << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,7 +876,7 @@ namespace ams::nxboot {
|
|||||||
return static_cast<u32>(fs_version);
|
return static_cast<u32>(fs_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RebuildPackage2(ams::TargetFirmware target_firmware, bool emummc_enabled) {
|
void RebuildPackage2(ams::TargetFirmware target_firmware, bool emummc_driver_enabled) {
|
||||||
/* Get the external package. */
|
/* Get the external package. */
|
||||||
const auto &external_package = GetExternalPackage();
|
const auto &external_package = GetExternalPackage();
|
||||||
|
|
||||||
@@ -909,7 +909,7 @@ namespace ams::nxboot {
|
|||||||
/* Read emummc, if needed. */
|
/* Read emummc, if needed. */
|
||||||
const InitialProcessHeader *emummc;
|
const InitialProcessHeader *emummc;
|
||||||
s64 emummc_size;
|
s64 emummc_size;
|
||||||
if (emummc_enabled) {
|
if (emummc_driver_enabled) {
|
||||||
emummc = static_cast<const InitialProcessHeader *>(ReadFile(std::addressof(emummc_size), "sdmc:/atmosphere/emummc.kip"));
|
emummc = static_cast<const InitialProcessHeader *>(ReadFile(std::addressof(emummc_size), "sdmc:/atmosphere/emummc.kip"));
|
||||||
if (emummc == nullptr) {
|
if (emummc == nullptr) {
|
||||||
emummc = reinterpret_cast<const InitialProcessHeader *>(external_package.kips + external_package.header.emummc_meta.offset);
|
emummc = reinterpret_cast<const InitialProcessHeader *>(external_package.kips + external_package.header.emummc_meta.offset);
|
||||||
@@ -958,7 +958,7 @@ namespace ams::nxboot {
|
|||||||
|
|
||||||
/* If necessary, inject emummc. */
|
/* If necessary, inject emummc. */
|
||||||
u32 addl_text_offset = 0;
|
u32 addl_text_offset = 0;
|
||||||
if (dst_kip->program_id == FsProgramId && emummc_enabled) {
|
if (dst_kip->program_id == FsProgramId && emummc_driver_enabled) {
|
||||||
/* Get emummc extents. */
|
/* Get emummc extents. */
|
||||||
addl_text_offset = emummc->bss_address + emummc->bss_size;
|
addl_text_offset = emummc->bss_address + emummc->bss_size;
|
||||||
if ((emummc->flags & 7) || !util::IsAligned(addl_text_offset, 0x1000)) {
|
if ((emummc->flags & 7) || !util::IsAligned(addl_text_offset, 0x1000)) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace ams::secmon {
|
|||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
EmummcConfiguration emummc_cfg;
|
EmummcConfiguration emummc_cfg;
|
||||||
u8 _raw_emummc_config[0x120];
|
u8 _raw_emummc_config[0x128];
|
||||||
};
|
};
|
||||||
u8 sealed_device_keys[pkg1::KeyGeneration_Max][se::AesBlockSize];
|
u8 sealed_device_keys[pkg1::KeyGeneration_Max][se::AesBlockSize];
|
||||||
u8 sealed_master_keys[pkg1::KeyGeneration_Max][se::AesBlockSize];
|
u8 sealed_master_keys[pkg1::KeyGeneration_Max][se::AesBlockSize];
|
||||||
@@ -88,8 +88,12 @@ namespace ams::secmon {
|
|||||||
return GetConfigurationContext().secmon_cfg;
|
return GetConfigurationContext().secmon_cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE const EmummcConfiguration &GetEmummcConfiguration() {
|
ALWAYS_INLINE const EmummcEmmcConfiguration &GetEmummcEmmcConfiguration() {
|
||||||
return GetConfigurationContext().emummc_cfg;
|
return GetConfigurationContext().emummc_cfg.emmc_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE const EmummcSdConfiguration &GetEmummcSdConfiguration() {
|
||||||
|
return GetConfigurationContext().emummc_cfg.sd_cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE const pkg1::BootConfig &GetBootConfig() {
|
ALWAYS_INLINE const pkg1::BootConfig &GetBootConfig() {
|
||||||
|
|||||||
@@ -18,10 +18,21 @@
|
|||||||
|
|
||||||
namespace ams::secmon {
|
namespace ams::secmon {
|
||||||
|
|
||||||
enum EmummcType : u32 {
|
enum EmummcEmmcType : u32 {
|
||||||
EmummcType_None = 0,
|
EmummcEmmcType_None = 0,
|
||||||
EmummcType_Partition = 1,
|
EmummcEmmcType_Partition_Sd = 1,
|
||||||
EmummcType_File = 2,
|
EmummcEmmcType_File_Sd = 2,
|
||||||
|
EmummcEmmcType_Partition_Emmc = 3,
|
||||||
|
EmummcEmmcType_File_Emmc = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EmummcSdType : u32 {
|
||||||
|
EmummcSdType_None = 0,
|
||||||
|
EmummcSdType_Partition_Emmc = 3,
|
||||||
|
// Not (currently) supported
|
||||||
|
// EmummcSdType_Partition_Sd = 1,
|
||||||
|
// EmummcSdType_File_Sd = 2,
|
||||||
|
// EmummcSdType_File_Emmc = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EmummcMmc {
|
enum EmummcMmc {
|
||||||
@@ -38,24 +49,6 @@ namespace ams::secmon {
|
|||||||
static_assert(util::is_pod<EmummcFilePath>::value);
|
static_assert(util::is_pod<EmummcFilePath>::value);
|
||||||
static_assert(sizeof(EmummcFilePath) == EmummcFilePathLengthMax);
|
static_assert(sizeof(EmummcFilePath) == EmummcFilePathLengthMax);
|
||||||
|
|
||||||
struct EmummcBaseConfiguration {
|
|
||||||
static constexpr u32 Magic = util::FourCC<'E','F','S','0'>::Code;
|
|
||||||
|
|
||||||
u32 magic;
|
|
||||||
EmummcType type;
|
|
||||||
u32 id;
|
|
||||||
u32 fs_version;
|
|
||||||
|
|
||||||
constexpr bool IsValid() const {
|
|
||||||
return this->magic == Magic;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool IsEmummcActive() const {
|
|
||||||
return this->IsValid() && this->type != EmummcType_None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<EmummcBaseConfiguration>::value);
|
|
||||||
static_assert(sizeof(EmummcBaseConfiguration) == 0x10);
|
|
||||||
|
|
||||||
struct EmummcPartitionConfiguration {
|
struct EmummcPartitionConfiguration {
|
||||||
u64 start_sector;
|
u64 start_sector;
|
||||||
@@ -67,8 +60,27 @@ namespace ams::secmon {
|
|||||||
};
|
};
|
||||||
static_assert(util::is_pod<EmummcFileConfiguration>::value);
|
static_assert(util::is_pod<EmummcFileConfiguration>::value);
|
||||||
|
|
||||||
struct EmummcConfiguration {
|
struct EmummcEmmcBaseConfiguration {
|
||||||
EmummcBaseConfiguration base_cfg;
|
static constexpr u32 Magic = util::FourCC<'E','F','S','0'>::Code;
|
||||||
|
u32 magic;
|
||||||
|
EmummcEmmcType type;
|
||||||
|
u32 id;
|
||||||
|
u32 fs_version;
|
||||||
|
|
||||||
|
constexpr bool IsValid() const {
|
||||||
|
return this->magic == Magic;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsActive() const {
|
||||||
|
return this->IsValid() && this->type != EmummcEmmcType::EmummcEmmcType_None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(util::is_pod<EmummcEmmcBaseConfiguration>::value);
|
||||||
|
static_assert(sizeof(EmummcEmmcBaseConfiguration) == 0x10);
|
||||||
|
|
||||||
|
|
||||||
|
struct EmummcEmmcConfiguration {
|
||||||
|
EmummcEmmcBaseConfiguration base_cfg;
|
||||||
union {
|
union {
|
||||||
EmummcPartitionConfiguration partition_cfg;
|
EmummcPartitionConfiguration partition_cfg;
|
||||||
EmummcFileConfiguration file_cfg;
|
EmummcFileConfiguration file_cfg;
|
||||||
@@ -79,10 +91,55 @@ namespace ams::secmon {
|
|||||||
return this->base_cfg.IsValid();
|
return this->base_cfg.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool IsEmummcActive() const {
|
constexpr bool IsActive() const {
|
||||||
return this->base_cfg.IsEmummcActive();
|
return this->base_cfg.IsActive();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
static_assert(util::is_pod<EmummcEmmcConfiguration>::value);
|
||||||
|
static_assert(sizeof(EmummcEmmcConfiguration) == 0x110);
|
||||||
|
|
||||||
|
struct EmummcSdBaseConfiguration {
|
||||||
|
static constexpr u32 Magic = util::FourCC<'E','F','S','0'>::Code;
|
||||||
|
u32 magic;
|
||||||
|
EmummcSdType type;
|
||||||
|
/* id currently unused */
|
||||||
|
u32 id;
|
||||||
|
u32 fs_version;
|
||||||
|
|
||||||
|
constexpr bool IsValid() const {
|
||||||
|
return this->magic == Magic;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsActive() const {
|
||||||
|
return this->IsValid() && this->type != EmummcSdType::EmummcSdType_None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(util::is_pod<EmummcSdBaseConfiguration>::value);
|
||||||
|
static_assert(sizeof(EmummcSdBaseConfiguration) == 0x10);
|
||||||
|
|
||||||
|
struct EmummcSdConfiguration {
|
||||||
|
EmummcSdBaseConfiguration base_cfg;
|
||||||
|
union {
|
||||||
|
EmummcPartitionConfiguration partition_cfg;
|
||||||
|
/* File based currently not supported */
|
||||||
|
/* EmummcFileConfiguration file_cfg */
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr bool IsValid() const {
|
||||||
|
return this->base_cfg.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsActive() const {
|
||||||
|
return this->base_cfg.IsActive();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(util::is_pod<EmummcSdConfiguration>::value);
|
||||||
|
static_assert(sizeof(EmummcSdConfiguration) == 0x18);
|
||||||
|
|
||||||
|
struct EmummcConfiguration {
|
||||||
|
EmummcEmmcConfiguration emmc_cfg;
|
||||||
|
EmummcSdConfiguration sd_cfg;
|
||||||
|
};
|
||||||
static_assert(util::is_pod<EmummcConfiguration>::value);
|
static_assert(util::is_pod<EmummcConfiguration>::value);
|
||||||
static_assert(sizeof(EmummcConfiguration) <= 0x200);
|
static_assert(sizeof(EmummcConfiguration) <= 0x200);
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace ams::secmon {
|
|||||||
constexpr bool IsValid() const { return this->magic == Magic; }
|
constexpr bool IsValid() const { return this->magic == Magic; }
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<SecureMonitorStorageConfiguration>::value);
|
static_assert(util::is_pod<SecureMonitorStorageConfiguration>::value);
|
||||||
static_assert(sizeof(SecureMonitorStorageConfiguration) == 0x130);
|
static_assert(sizeof(SecureMonitorStorageConfiguration) == 0x148);
|
||||||
|
|
||||||
struct SecureMonitorConfiguration {
|
struct SecureMonitorConfiguration {
|
||||||
ams::TargetFirmware target_firmware;
|
ams::TargetFirmware target_firmware;
|
||||||
|
|||||||
Reference in New Issue
Block a user