From c07f54f3709a4710e0aead6c91139fa0893b5e5c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 14 Apr 2020 11:15:19 -0700 Subject: [PATCH] emummc: fix for svcQueryIoMapping abi change --- emummc/source/emuMMC/emummc.c | 3 +-- emummc/source/nx/svc.h | 12 +++++++++++- emummc/source/nx/svc.s | 9 +++++++++ emummc/source/utils/fatal.h | 3 ++- emummc/source/utils/util.c | 11 +++++++++-- emummc/source/utils/util.h | 3 +++ .../libstratosphere/source/dd/dd_io_mappings.cpp | 2 +- stratosphere/ncm/source/ncm_main.cpp | 2 +- 8 files changed, 37 insertions(+), 8 deletions(-) diff --git a/emummc/source/emuMMC/emummc.c b/emummc/source/emuMMC/emummc.c index 59dc45e3d..ac4050a4e 100644 --- a/emummc/source/emuMMC/emummc.c +++ b/emummc/source/emuMMC/emummc.c @@ -36,7 +36,6 @@ sdmmc_storage_t sd_storage; // init vars bool custom_driver = true; -extern const volatile emuMMC_ctx_t emuMMC_ctx; // FS funcs _sdmmc_accessor_gc sdmmc_accessor_gc; @@ -344,7 +343,7 @@ uint64_t sdmmc_wrapper_controller_close(int mmc_id) { return 0; } - + if (mmc_id == FS_SDMMC_EMMC) { // Close file handles and unmount diff --git a/emummc/source/nx/svc.h b/emummc/source/nx/svc.h index 69819ec34..05d51b9ec 100644 --- a/emummc/source/nx/svc.h +++ b/emummc/source/nx/svc.h @@ -50,8 +50,18 @@ extern "C" { * @return Result code. * @note Syscall number 0x55. * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning Only exists on [10.0.0+]. For older versions use \ref svcLegacyQueryIoMapping. */ -Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size); +Result svcQueryIoMapping(u64* virtaddr, u64* out_size, u64 physaddr, u64 size); + +/** + * @brief Returns a virtual address mapped to a given IO range. + * @return Result code. + * @note Syscall number 0x55. + * @warning This is a privileged syscall. Use \ref envIsSyscallHinted to check if it is available. + * @warning Only exists on [1.0.0-9.2.0]. For newer versions use \ref svcQueryIoMapping. + */ +Result svcLegacyQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size); /** * @brief Attaches a device address space to a device. diff --git a/emummc/source/nx/svc.s b/emummc/source/nx/svc.s index 360d9c0ef..9a2c61524 100644 --- a/emummc/source/nx/svc.s +++ b/emummc/source/nx/svc.s @@ -17,6 +17,15 @@ .endm SVC_BEGIN svcQueryIoMapping + STP X0, X1, [SP, #-16]! + SVC 0x55 + LDP X3, X4, [SP], #16 + STR X1, [X3] + STR X2, [X4] + RET +SVC_END + +SVC_BEGIN svcLegacyQueryIoMapping STR X0, [SP, #-16]! SVC 0x55 LDR X2, [SP], #16 diff --git a/emummc/source/utils/fatal.h b/emummc/source/utils/fatal.h index 56c406194..f2d42fd6f 100644 --- a/emummc/source/utils/fatal.h +++ b/emummc/source/utils/fatal.h @@ -25,11 +25,12 @@ enum FatalReason Fatal_InvalidAccessor, Fatal_ReadNoAccessor, Fatal_WriteNoAccessor, - Fatal_IoMapping, + Fatal_IoMappingLegacy, Fatal_UnknownVersion, Fatal_BadResult, Fatal_GetConfig, Fatal_CloseAccessor, + Fatal_IoMapping, Fatal_Max }; diff --git a/emummc/source/utils/util.c b/emummc/source/utils/util.c index ee95032b0..274be7e4f 100644 --- a/emummc/source/utils/util.c +++ b/emummc/source/utils/util.c @@ -38,8 +38,15 @@ static inline uintptr_t _GetIoMapping(u64 io_addr, u64 io_size) u64 vaddr; u64 aligned_addr = (io_addr & ~0xFFFul); u64 aligned_size = io_size + (io_addr - aligned_addr); - if (svcQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) { - fatal_abort(Fatal_IoMapping); + if (emuMMC_ctx.fs_ver >= FS_VER_10_0_0) { + u64 out_size; + if (svcQueryIoMapping(&vaddr, &out_size, aligned_addr, aligned_size) != 0) { + fatal_abort(Fatal_IoMapping); + } + } else { + if (svcLegacyQueryIoMapping(&vaddr, aligned_addr, aligned_size) != 0) { + fatal_abort(Fatal_IoMappingLegacy); + } } return (uintptr_t)(vaddr + (io_addr - aligned_addr)); } diff --git a/emummc/source/utils/util.h b/emummc/source/utils/util.h index 0571d01c5..843e969aa 100644 --- a/emummc/source/utils/util.h +++ b/emummc/source/utils/util.h @@ -19,6 +19,7 @@ #define _UTIL_H_ #include "types.h" +#include "../emuMMC/emummc_ctx.h" intptr_t QueryIoMapping(u64 addr, u64 size); #define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \ @@ -37,4 +38,6 @@ void usleep(u64 ticks); void msleep(u64 milliseconds); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); +extern volatile emuMMC_ctx_t emuMMC_ctx; + #endif diff --git a/libraries/libstratosphere/source/dd/dd_io_mappings.cpp b/libraries/libstratosphere/source/dd/dd_io_mappings.cpp index 7966defac..8bc84442c 100644 --- a/libraries/libstratosphere/source/dd/dd_io_mappings.cpp +++ b/libraries/libstratosphere/source/dd/dd_io_mappings.cpp @@ -26,7 +26,7 @@ namespace ams::dd { u64 region_size; R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, ®ion_size, aligned_addr, aligned_size)) { /* Official software handles this by returning 0. */ - R_CATCH(svc::ResultNotFound) { exosphere::ForceRebootToRcm(); return 0; } + R_CATCH(svc::ResultNotFound) { return 0; } } R_END_TRY_CATCH_WITH_ABORT_UNLESS; AMS_ASSERT(region_size >= aligned_size); } else { diff --git a/stratosphere/ncm/source/ncm_main.cpp b/stratosphere/ncm/source/ncm_main.cpp index 1c2a63d66..dfd4df1d1 100644 --- a/stratosphere/ncm/source/ncm_main.cpp +++ b/stratosphere/ncm/source/ncm_main.cpp @@ -66,7 +66,7 @@ namespace { } void InitializeHeap() { - g_heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_None); + g_heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_ThreadSafe); ncm::GetHeapState().Initialize(g_heap_handle); }