diff --git a/emummc/.gitrepo b/emummc/.gitrepo index dd44508ef..17dfffbdc 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emuMMC branch = develop - commit = 5f51fa3b81d2b14b348f6e8579454007019fc7a6 - parent = e871a754a87631c3036ca985ff1c223e00ef4dda + commit = 5f5817e646d4c800ae4bd6db4a57eee6bde62eed + parent = 68091a28a23836032c98396259f7ee4796b312f9 method = rebase cmdver = 0.4.0 diff --git a/emummc/README.md b/emummc/README.md index fb0266cef..7126b193f 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 8.1.0** +**1.0.0 - 9.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index ac67d9a5b..e4bdcf4ac 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -41,6 +41,8 @@ #include "offsets/800_exfat.h" #include "offsets/810.h" #include "offsets/810_exfat.h" +#include "offsets/900.h" +#include "offsets/900_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -92,6 +94,8 @@ DEFINE_OFFSET_STRUCT(_800); DEFINE_OFFSET_STRUCT(_800_EXFAT); DEFINE_OFFSET_STRUCT(_810); DEFINE_OFFSET_STRUCT(_810_EXFAT); +DEFINE_OFFSET_STRUCT(_900); +DEFINE_OFFSET_STRUCT(_900_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -145,6 +149,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_810)); case FS_VER_8_1_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_810_EXFAT)); + case FS_VER_9_0_0: + return &(GET_OFFSET_STRUCT_NAME(_900)); + case FS_VER_9_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_900_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index e952ee48e..2acbac19a 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -59,6 +59,9 @@ enum FS_VER FS_VER_8_1_0, FS_VER_8_1_0_EXFAT, + FS_VER_9_0_0, + FS_VER_9_0_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/900.h b/emummc/source/FS/offsets/900.h new file mode 100644 index 000000000..7b66546c6 --- /dev/null +++ b/emummc/source/FS/offsets/900.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_900_H__ +#define __FS_900_H__ + +// Accessor vtable getters +#define FS_OFFSET_900_SDMMC_ACCESSOR_GC 0x1430F0 +#define FS_OFFSET_900_SDMMC_ACCESSOR_SD 0x141200 +#define FS_OFFSET_900_SDMMC_ACCESSOR_NAND 0x13C080 + +// Hooks +#define FS_OFFSET_900_SDMMC_WRAPPER_READ 0x1377E0 +#define FS_OFFSET_900_SDMMC_WRAPPER_WRITE 0x1378C0 +#define FS_OFFSET_900_RTLD 0x454 +#define FS_OFFSET_900_RTLD_DESTINATION 0x9C + +#define FS_OFFSET_900_CLKRST_SET_MIN_V_CLK_RATE 0x136A00 + +// Misc funcs +#define FS_OFFSET_900_LOCK_MUTEX 0x25280 +#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0 + +#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740 + +// Misc Data +#define FS_OFFSET_900_SD_MUTEX 0xE1D3E8 +#define FS_OFFSET_900_NAND_MUTEX 0xE18258 +#define FS_OFFSET_900_ACTIVE_PARTITION 0xE18298 +#define FS_OFFSET_900_SDMMC_DAS_HANDLE 0xDFEFA0 + +// NOPs +#define FS_OFFSET_900_SD_DAS_INIT 0x1472BC + +// Nintendo Paths +#define FS_OFFSET_900_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068A60, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00070A40, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00081CB4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00081EF4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0008211C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_900_H__ diff --git a/emummc/source/FS/offsets/900_exfat.h b/emummc/source/FS/offsets/900_exfat.h new file mode 100644 index 000000000..8a55f0a73 --- /dev/null +++ b/emummc/source/FS/offsets/900_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_900_EXFAT_H__ +#define __FS_900_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_GC 0x1430F0 +#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_SD 0x141200 +#define FS_OFFSET_900_EXFAT_SDMMC_ACCESSOR_NAND 0x13C080 + +// Hooks +#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_READ 0x1377E0 +#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_WRITE 0x1378C0 +#define FS_OFFSET_900_EXFAT_RTLD 0x454 +#define FS_OFFSET_900_EXFAT_RTLD_DESTINATION 0x9C + +#define FS_OFFSET_900_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x136A00 + +// Misc funcs +#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280 +#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0 + +#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740 + +// Misc Data +#define FS_OFFSET_900_EXFAT_SD_MUTEX 0xE2B3E8 +#define FS_OFFSET_900_EXFAT_NAND_MUTEX 0xE26258 +#define FS_OFFSET_900_EXFAT_ACTIVE_PARTITION 0xE26298 +#define FS_OFFSET_900_EXFAT_SDMMC_DAS_HANDLE 0xE0CFA0 + +// NOPs +#define FS_OFFSET_900_EXFAT_SD_DAS_INIT 0x1472BC + +// Nintendo Paths +#define FS_OFFSET_900_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068A60, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00070A40, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00081CB4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00081EF4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0008211C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_900_EXFAT_H__ diff --git a/emummc/source/utils/fatal.c b/emummc/source/utils/fatal.c index e76937b9f..0c912b604 100644 --- a/emummc/source/utils/fatal.c +++ b/emummc/source/utils/fatal.c @@ -15,13 +15,26 @@ * along with this program. If not, see . */ +#include #include "fatal.h" void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason) { + atmosphere_fatal_error_ctx error_ctx; + memset(&error_ctx, 0, sizeof(atmosphere_fatal_error_ctx)); + + // Basic error storage for Atmosphere + // TODO: Maybe include a small reboot2payload stub? + error_ctx.magic = ATMOSPHERE_REBOOT_TO_FATAL_MAGIC; + error_ctx.title_id = 0x0100000000000000; // FS + error_ctx.error_desc = abortReason; + + // Copy fatal context + smcCopyToIram(ATMOSPHERE_FATAL_ERROR_ADDR, &error_ctx, sizeof(atmosphere_fatal_error_ctx)); + // Reboot to RCM smcRebootToRcm(); - while(true) + while (true) ; // Should never be reached } diff --git a/emummc/source/utils/fatal.h b/emummc/source/utils/fatal.h index b553d5fe0..56c406194 100644 --- a/emummc/source/utils/fatal.h +++ b/emummc/source/utils/fatal.h @@ -18,7 +18,8 @@ #pragma once #include "../nx/smc.h" -enum FatalReason { +enum FatalReason +{ Fatal_InitMMC = 0, Fatal_InitSD, Fatal_InvalidAccessor, @@ -32,4 +33,45 @@ enum FatalReason { Fatal_Max }; +#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20 +#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100 + +/* Atmosphere reboot-to-fatal-error. */ +typedef struct +{ + uint32_t magic; + uint32_t error_desc; + uint64_t title_id; + union { + uint64_t gprs[32]; + struct + { + uint64_t _gprs[29]; + uint64_t fp; + uint64_t lr; + uint64_t sp; + }; + }; + uint64_t pc; + uint64_t module_base; + uint32_t pstate; + uint32_t afsr0; + uint32_t afsr1; + uint32_t esr; + uint64_t far; + uint64_t report_identifier; /* Normally just system tick. */ + uint64_t stack_trace_size; + uint64_t stack_dump_size; + uint64_t stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE]; + uint8_t stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP]; +} atmosphere_fatal_error_ctx; + +/* "AFE1" */ +#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x31454641 +/* "AFE0" */ +#define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC_0 0x30454641 + +#define ATMOSPHERE_FATAL_ERROR_ADDR 0x4003E000 +#define ATMOSPHERE_FATAL_ERROR_CONTEXT ((volatile atmosphere_fatal_error_ctx *)(ATMOSPHERE_FATAL_ERROR_ADDR)) + void __attribute__((noreturn)) fatal_abort(enum FatalReason abortReason);