From 8e939331571179f593e0b710568cf7e1db2c442d Mon Sep 17 00:00:00 2001 From: yellows8 Date: Fri, 17 Sep 2021 11:23:11 -0400 Subject: [PATCH] hiddbg: hdls 13.0.0 support --- nx/include/switch/services/hiddbg.h | 23 +++++++--- nx/source/services/hiddbg.c | 70 +++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/nx/include/switch/services/hiddbg.h b/nx/include/switch/services/hiddbg.h index 38e74903..fcf476f8 100644 --- a/nx/include/switch/services/hiddbg.h +++ b/nx/include/switch/services/hiddbg.h @@ -56,6 +56,11 @@ typedef struct { u64 handle; ///< Handle } HiddbgHdlsHandle; +/// HdlsSessionId, returned by \ref hiddbgAttachHdlsWorkBuffer. +typedef struct { + u64 id; ///< Id +} HiddbgHdlsSessionId; + /// HdlsDeviceInfo, for [7.0.0-8.1.0]. typedef struct { u32 deviceTypeInternal; ///< Only one bit can be set. BIT(N*4+0) = Pro-Controller, BIT(N*4+1) = Joy-Con Left, BIT(N*4+2) = Joy-Con Right, BIT(N*4+3) = invalid. Where N is 0-1. BIT(8-10) = Pro-Controller, BIT(11) = Famicom-Controller, BIT(12) = Famicom-Controller II with microphone, BIT(13) = NES-Controller(DeviceType=0x200), BIT(14) = NES-Controller(DeviceType=0x400), BIT(15-16) = invalid, BIT(17) = unknown(DeviceType=0x8000), BIT(18-20) = invalid, BIT(21-23) = unknown(DeviceType=0x80000000). @@ -396,14 +401,16 @@ Result hiddbgUnsetAllAutoPilotVirtualPadState(void); /** * @brief Initialize Hdls. * @note Only available with [7.0.0+]. + * @param[out] session_id [13.0.0+] \ref HiddbgHdlsSessionId */ -Result hiddbgAttachHdlsWorkBuffer(void); +Result hiddbgAttachHdlsWorkBuffer(HiddbgHdlsSessionId *session_id); /** * @brief Exit Hdls, must be called at some point prior to \ref hiddbgExit. * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId */ -Result hiddbgReleaseHdlsWorkBuffer(void); +Result hiddbgReleaseHdlsWorkBuffer(HiddbgHdlsSessionId session_id); /** * @brief Checks if the given device is still attached. @@ -416,32 +423,36 @@ Result hiddbgIsHdlsVirtualDeviceAttached(HiddbgHdlsHandle handle, bool *out); /** * @brief Gets state for \ref HiddbgHdlsNpadAssignment. * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId * @param[out] state \ref HiddbgHdlsNpadAssignment */ -Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsNpadAssignment *state); +Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, HiddbgHdlsNpadAssignment *state); /** * @brief Gets state for \ref HiddbgHdlsStateList. * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId * @param[out] state \ref HiddbgHdlsStateList */ -Result hiddbgDumpHdlsStates(HiddbgHdlsStateList *state); +Result hiddbgDumpHdlsStates(HiddbgHdlsSessionId session_id, HiddbgHdlsStateList *state); /** * @brief Sets state for \ref HiddbgHdlsNpadAssignment. * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId * @param[in] state \ref HiddbgHdlsNpadAssignment * @param[in] flag Flag */ -Result hiddbgApplyHdlsNpadAssignmentState(const HiddbgHdlsNpadAssignment *state, bool flag); +Result hiddbgApplyHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, const HiddbgHdlsNpadAssignment *state, bool flag); /** * @brief Sets state for \ref HiddbgHdlsStateList. * @note The \ref HiddbgHdlsState will be applied for each \ref HiddbgHdlsHandle. If a \ref HiddbgHdlsHandle is not found, code similar to \ref hiddbgAttachHdlsVirtualDevice will run with the \ref HiddbgHdlsDeviceInfo, then it will continue with applying state with the new device. * @note Only available with [7.0.0+]. + * @param[in] session_id [13.0.0+] \ref HiddbgHdlsSessionId * @param[in] state \ref HiddbgHdlsStateList */ -Result hiddbgApplyHdlsStateList(const HiddbgHdlsStateList *state); +Result hiddbgApplyHdlsStateList(HiddbgHdlsSessionId session_id, const HiddbgHdlsStateList *state); /** * @brief Attach a device with the input info. diff --git a/nx/source/services/hiddbg.c b/nx/source/services/hiddbg.c index 9491e653..03905979 100644 --- a/nx/source/services/hiddbg.c +++ b/nx/source/services/hiddbg.c @@ -72,10 +72,21 @@ static Result _hiddbgCmdInHandle64NoOut(Handle handle, u64 inval, u32 cmd_id) { ); } +static Result _hiddbgCmdInHandle64OutU64(Handle handle, u64 inval, u64 *out, u32 cmd_id) { + return serviceDispatchInOut(&g_hiddbgSrv, cmd_id, inval, *out, + .in_num_handles = 1, + .in_handles = { handle }, + ); +} + static Result _hiddbgCmdInTmemNoOut(TransferMemory *tmem, u32 cmd_id) { return _hiddbgCmdInHandle64NoOut(tmem->handle, tmem->size, cmd_id); } +static Result _hiddbgCmdInTmemOutU64(TransferMemory *tmem, u64 *out, u32 cmd_id) { + return _hiddbgCmdInHandle64OutU64(tmem->handle, tmem->size, out, cmd_id); +} + Result hiddbgSetDebugPadAutoPilotState(const HiddbgDebugPadAutoPilotState *state) { return serviceDispatchIn(&g_hiddbgSrv, 1, *state); } @@ -449,13 +460,18 @@ static void _hiddbgConvertHdlsStateListFromV9(HiddbgHdlsStateList *out, const Hi } } -static Result _hiddbgAttachHdlsWorkBuffer(TransferMemory *tmem) { - return _hiddbgCmdInTmemNoOut(tmem, 324); +static Result _hiddbgAttachHdlsWorkBuffer(HiddbgHdlsSessionId *session_id, TransferMemory *tmem) { + if (hosversionBefore(13,0,0)) + return _hiddbgCmdInTmemNoOut(tmem, 324); + else + return _hiddbgCmdInTmemOutU64(tmem, &session_id->id, 324); } -Result hiddbgAttachHdlsWorkBuffer(void) { +Result hiddbgAttachHdlsWorkBuffer(HiddbgHdlsSessionId *session_id) { Result rc=0; + if (session_id) session_id->id = 0; + if (hosversionBefore(7,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -466,13 +482,13 @@ Result hiddbgAttachHdlsWorkBuffer(void) { rc = tmemCreate(&g_hiddbgHdlsTmem, 0x1000, Perm_Rw); if (R_FAILED(rc)) return rc; - rc = _hiddbgAttachHdlsWorkBuffer(&g_hiddbgHdlsTmem); + rc = _hiddbgAttachHdlsWorkBuffer(session_id, &g_hiddbgHdlsTmem); if (R_FAILED(rc)) tmemClose(&g_hiddbgHdlsTmem); if (R_SUCCEEDED(rc)) g_hiddbgHdlsInitialized = true; return rc; } -Result hiddbgReleaseHdlsWorkBuffer(void) { +Result hiddbgReleaseHdlsWorkBuffer(HiddbgHdlsSessionId session_id) { Result rc=0; if (hosversionBefore(7,0,0)) @@ -483,7 +499,11 @@ Result hiddbgReleaseHdlsWorkBuffer(void) { g_hiddbgHdlsInitialized = false; - rc = _hiddbgCmdNoIO(325); + if (hosversionBefore(13,0,0)) + rc = _hiddbgCmdNoIO(325); + else + rc = _hiddbgCmdInU64NoOut(session_id.id, 325); + tmemClose(&g_hiddbgHdlsTmem); return rc; } @@ -532,7 +552,7 @@ Result hiddbgIsHdlsVirtualDeviceAttached(HiddbgHdlsHandle handle, bool *out) { return rc; } -Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsNpadAssignment *state) { +Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, HiddbgHdlsNpadAssignment *state) { Result rc=0; if (hosversionBefore(7,0,0)) @@ -541,13 +561,17 @@ Result hiddbgDumpHdlsNpadAssignmentState(HiddbgHdlsNpadAssignment *state) { if (!g_hiddbgHdlsInitialized) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - rc = _hiddbgCmdNoIO(326); + if (hosversionBefore(13,0,0)) + rc = _hiddbgCmdNoIO(326); + else + rc = _hiddbgCmdInU64NoOut(session_id.id, 326); + if (R_FAILED(rc)) return rc; if (state) memcpy(state, g_hiddbgHdlsTmem.src_addr, sizeof(*state)); return rc; } -Result hiddbgDumpHdlsStates(HiddbgHdlsStateList *state) { +Result hiddbgDumpHdlsStates(HiddbgHdlsSessionId session_id, HiddbgHdlsStateList *state) { Result rc=0; if (hosversionBefore(7,0,0)) @@ -556,7 +580,11 @@ Result hiddbgDumpHdlsStates(HiddbgHdlsStateList *state) { if (!g_hiddbgHdlsInitialized) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); - rc = _hiddbgCmdNoIO(327); + if (hosversionBefore(13,0,0)) + rc = _hiddbgCmdNoIO(327); + else + rc = _hiddbgCmdInU64NoOut(session_id.id, 327); + if (R_FAILED(rc)) return rc; if (state) { if (hosversionBefore(9,0,0)) { @@ -575,7 +603,7 @@ Result hiddbgDumpHdlsStates(HiddbgHdlsStateList *state) { return rc; } -Result hiddbgApplyHdlsNpadAssignmentState(const HiddbgHdlsNpadAssignment *state, bool flag) { +Result hiddbgApplyHdlsNpadAssignmentState(HiddbgHdlsSessionId session_id, const HiddbgHdlsNpadAssignment *state, bool flag) { if (hosversionBefore(7,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -586,10 +614,21 @@ Result hiddbgApplyHdlsNpadAssignmentState(const HiddbgHdlsNpadAssignment *state, return MAKERESULT(Module_Libnx, LibnxError_BadInput); memcpy(g_hiddbgHdlsTmem.src_addr, state, sizeof(*state)); - return _hiddbgCmdInBoolNoOut(flag, 328); + + if (hosversionBefore(13,0,0)) + return _hiddbgCmdInBoolNoOut(flag, 328); + else { + const struct { + u8 flag; + u8 pad[7]; + HiddbgHdlsSessionId session_id; + } in = { flag, {0}, session_id }; + + return serviceDispatchIn(&g_hiddbgSrv, 328, in); + } } -Result hiddbgApplyHdlsStateList(const HiddbgHdlsStateList *state) { +Result hiddbgApplyHdlsStateList(HiddbgHdlsSessionId session_id, const HiddbgHdlsStateList *state) { if (hosversionBefore(7,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -612,7 +651,10 @@ Result hiddbgApplyHdlsStateList(const HiddbgHdlsStateList *state) { else memcpy(g_hiddbgHdlsTmem.src_addr, state, sizeof(*state)); - return _hiddbgCmdNoIO(329); + if (hosversionBefore(13,0,0)) + return _hiddbgCmdNoIO(329); + else + return _hiddbgCmdInU64NoOut(session_id.id, 329); } static Result _hiddbgAttachHdlsVirtualDeviceV7(HiddbgHdlsHandle *handle, const HiddbgHdlsDeviceInfoV7 *info) {