From 75b4d1f56326885b5cc3980b496a5380a399ca18 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Mon, 1 Feb 2021 14:05:04 +0000 Subject: [PATCH] Add SDMMC speed info types, and more clock rates (#480) --- libctru/include/3ds/os.h | 20 ++++++++++++++++---- libctru/include/3ds/services/fs.h | 12 ++++++++++-- libctru/include/3ds/services/fspxi.h | 6 +++--- libctru/source/services/fs.c | 9 ++++----- libctru/source/services/fspxi.c | 12 ++++++------ 5 files changed, 39 insertions(+), 20 deletions(-) diff --git a/libctru/include/3ds/os.h b/libctru/include/3ds/os.h index 182fa1d..16dfb72 100644 --- a/libctru/include/3ds/os.h +++ b/libctru/include/3ds/os.h @@ -5,10 +5,22 @@ #pragma once #include "svc.h" -#define SYSCLOCK_SOC (16756991) -#define SYSCLOCK_ARM9 (SYSCLOCK_SOC * 8) -#define SYSCLOCK_ARM11 (SYSCLOCK_ARM9 * 2) -#define SYSCLOCK_ARM11_NEW (SYSCLOCK_ARM11 * 3) +///< The external clock rate for the SoC. +#define SYSCLOCK_SOC (16756991u) +///< The base system clock rate (for I2C, NDMA, etc.). +#define SYSCLOCK_SYS (SYSCLOCK_SOC * 2) +///< The base clock rate for the SDMMC controller (and some other peripherals). +#define SYSCLOCK_SDMMC (SYSCLOCK_SYS * 2) +///< The clock rate for the Arm9. +#define SYSCLOCK_ARM9 (SYSCLOCK_SYS * 4) +///< The clock rate for the Arm11 in CTR mode and in \ref svcGetSystemTick. +#define SYSCLOCK_ARM11 (SYSCLOCK_ARM9 * 2) +///< The clock rate for the Arm11 in LGR1 mode. +#define SYSCLOCK_ARM11_LGR1 (SYSCLOCK_ARM11 * 2) +///< The clock rate for the Arm11 in LGR2 mode. +#define SYSCLOCK_ARM11_LGR2 (SYSCLOCK_ARM11 * 3) +///< The highest possible clock rate for the Arm11 on known New 3DS units. +#define SYSCLOCK_ARM11_NEW SYSCLOCK_ARM11_LGR2 #define CPU_TICKS_PER_MSEC (SYSCLOCK_ARM11 / 1000.0) #define CPU_TICKS_PER_USEC (SYSCLOCK_ARM11 / 1000000.0) diff --git a/libctru/include/3ds/services/fs.h b/libctru/include/3ds/services/fs.h index 1d94630..5a3956d 100644 --- a/libctru/include/3ds/services/fs.h +++ b/libctru/include/3ds/services/fs.h @@ -235,6 +235,14 @@ typedef struct const void* data; ///< Pointer to FS path data. } FS_Path; +/// SDMC/NAND speed information +typedef struct +{ + bool highSpeedModeEnabled; ///< Whether or not High Speed Mode is enabled. + bool usesHighestClockRate; ///< Whether or not a clock divider of 2 is being used. + u16 sdClkCtrl; ///< The value of the SD_CLK_CTRL register. +} FS_SdMmcSpeedInfo; + /// Filesystem archive handle, providing access to a filesystem's contents. typedef u64 FS_Archive; @@ -467,13 +475,13 @@ Result FSUSER_GetNandCid(u8* out, u32 length); * @brief Gets the SDMC speed info. * @param speedInfo Pointer to output the speed info to. */ -Result FSUSER_GetSdmcSpeedInfo(u32 *speedInfo); +Result FSUSER_GetSdmcSpeedInfo(FS_SdMmcSpeedInfo *speedInfo); /** * @brief Gets the NAND speed info. * @param speedInfo Pointer to output the speed info to. */ -Result FSUSER_GetNandSpeedInfo(u32 *speedInfo); +Result FSUSER_GetNandSpeedInfo(FS_SdMmcSpeedInfo *speedInfo); /** * @brief Gets the SDMC log. diff --git a/libctru/include/3ds/services/fspxi.h b/libctru/include/3ds/services/fspxi.h index 53528a7..5644d11 100644 --- a/libctru/include/3ds/services/fspxi.h +++ b/libctru/include/3ds/services/fspxi.h @@ -193,7 +193,7 @@ Result FSPXI_CloseArchive(Handle serviceHandle, FSPXI_Archive archive); /** * @brief Unknown 0x17. Appears to be an "is archive handle valid" command? * @param archive Archive handle to check validity of. - * @param out Pointer to output validity to. + * @param out Pointer to output validity to. */ Result FSPXI_Unknown0x17(Handle serviceHandle, FSPXI_Archive archive, bool* out); @@ -251,13 +251,13 @@ Result FSPXI_GetNandCid(Handle serviceHandle, void* out, u32 size); * @brief Gets the SDMC speed info * @param out Buffer to output the speed info to. */ -Result FSPXI_GetSdmcSpeedInfo(Handle serviceHandle, u32* out); +Result FSPXI_GetSdmcSpeedInfo(Handle serviceHandle, FS_SdMmcSpeedInfo* out); /** * @brief Gets the NAND speed info * @param out Buffer to output the speed info to. */ -Result FSPXI_GetNandSpeedInfo(Handle serviceHandle, u32* out); +Result FSPXI_GetNandSpeedInfo(Handle serviceHandle, FS_SdMmcSpeedInfo* out); /** * @brief Gets the SDMC log diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 526e9f7..c7e9276 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -566,7 +566,7 @@ Result FSUSER_GetNandCid(u8* out, u32 length) return cmdbuf[1]; } -Result FSUSER_GetSdmcSpeedInfo(u32 *speedInfo) +Result FSUSER_GetSdmcSpeedInfo(FS_SdMmcSpeedInfo *speedInfo) { u32 *cmdbuf = getThreadCommandBuffer(); @@ -575,12 +575,11 @@ Result FSUSER_GetSdmcSpeedInfo(u32 *speedInfo) Result ret = 0; if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; - if(speedInfo) *speedInfo = cmdbuf[2]; - + if(speedInfo) memcpy(speedInfo, &cmdbuf[2], sizeof(FS_SdMmcSpeedInfo)); return cmdbuf[1]; } -Result FSUSER_GetNandSpeedInfo(u32 *speedInfo) +Result FSUSER_GetNandSpeedInfo(FS_SdMmcSpeedInfo *speedInfo) { u32 *cmdbuf = getThreadCommandBuffer(); @@ -589,7 +588,7 @@ Result FSUSER_GetNandSpeedInfo(u32 *speedInfo) Result ret = 0; if(R_FAILED(ret = svcSendSyncRequest(fsSession()))) return ret; - if(speedInfo) *speedInfo = cmdbuf[2]; + if(speedInfo) memcpy(speedInfo, &cmdbuf[2], sizeof(FS_SdMmcSpeedInfo)); return cmdbuf[1]; } diff --git a/libctru/source/services/fspxi.c b/libctru/source/services/fspxi.c index 6c3463e..dc337a8 100644 --- a/libctru/source/services/fspxi.c +++ b/libctru/source/services/fspxi.c @@ -572,7 +572,7 @@ Result FSPXI_GetNandCid(Handle serviceHandle, void* out, u32 size) return (Result) cmdbuf[1]; } -Result FSPXI_GetSdmcSpeedInfo(Handle serviceHandle, u32* out) +Result FSPXI_GetSdmcSpeedInfo(Handle serviceHandle, FS_SdMmcSpeedInfo* out) { Result ret = 0; u32* cmdbuf = getThreadCommandBuffer(); @@ -581,12 +581,12 @@ Result FSPXI_GetSdmcSpeedInfo(Handle serviceHandle, u32* out) if(R_FAILED(ret = svcSendSyncRequest(serviceHandle))) return ret; - if(out) *out = cmdbuf[2]; + if(out) memcpy(out, &cmdbuf[2], sizeof(FS_SdMmcSpeedInfo)); return (Result) cmdbuf[1]; } -Result FSPXI_GetNandSpeedInfo(Handle serviceHandle, u32* out) +Result FSPXI_GetNandSpeedInfo(Handle serviceHandle, FS_SdMmcSpeedInfo* out) { Result ret = 0; u32* cmdbuf = getThreadCommandBuffer(); @@ -595,7 +595,7 @@ Result FSPXI_GetNandSpeedInfo(Handle serviceHandle, u32* out) if(R_FAILED(ret = svcSendSyncRequest(serviceHandle))) return ret; - if(out) *out = cmdbuf[2]; + if(out) memcpy(out, &cmdbuf[2], sizeof(FS_SdMmcSpeedInfo)); return (Result) cmdbuf[1]; } @@ -1084,7 +1084,7 @@ Result FSPXI_GetArchiveResource(Handle serviceHandle, FS_ArchiveResource* archiv { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); - + cmdbuf[0] = IPC_MakeHeader(0x43, 1, 0); // 0x00430040 cmdbuf[1] = mediaType; @@ -1179,7 +1179,7 @@ Result FSPXI_ReadSpecialFile(Handle serviceHandle, u32* bytesRead, u64 fileOffse { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); - + cmdbuf[0] = IPC_MakeHeader(0x49, 4, 2); // 0x00490102 cmdbuf[1] = 0; cmdbuf[2] = (u32) fileOffset;