diff --git a/nx/include/switch/services/hiddbg.h b/nx/include/switch/services/hiddbg.h index df4aaf3d..c5c6c5b7 100644 --- a/nx/include/switch/services/hiddbg.h +++ b/nx/include/switch/services/hiddbg.h @@ -137,6 +137,12 @@ Result hiddbgAcquireOperationEventHandle(Event* out_event, bool autoclear, u64 U /// Only available with [6.0.0+]. Result hiddbgReadSerialFlash(u32 offset, void* buffer, size_t size, u64 UniquePadId); +/// Writes spi-flash for the specified controller. See hidsys.h for UniquePadId. +/// buffer and tmem_size must be page-aligned. size is the actual transfer size. +/// This also uses \ref hiddbgAcquireOperationEventHandle to wait for the operation to finish, then \ref hiddbgGetOperationResult is used. +/// Only available with [6.0.0+]. +Result hiddbgWriteSerialFlash(u32 offset, void* buffer, size_t tmem_size, size_t size, u64 UniquePadId); + /// Get the Result for the Operation and handles cleanup, for the specified controller. See hidsys.h for UniquePadId. /// Only available with [6.0.0+]. Result hiddbgGetOperationResult(u64 UniquePadId); diff --git a/nx/source/services/hiddbg.c b/nx/source/services/hiddbg.c index f4372cae..7165b99c 100644 --- a/nx/source/services/hiddbg.c +++ b/nx/source/services/hiddbg.c @@ -130,7 +130,21 @@ static Result _hiddbgReadSerialFlash(TransferMemory *tmem, u32 offset, u64 size, ); } -// sdk-nso doesn't use hiddbgAcquireOperationEventHandle/hiddbgGetOperationResult in the ReadSerialFlash impl, those are used seperately by the user. +static Result _hiddbgWriteSerialFlash(TransferMemory *tmem, u32 offset, u64 tmem_size, u64 size, u64 UniquePadId) { + const struct { + u32 offset; + u64 tmem_size; + u64 size; + u64 UniquePadId; + } in = { offset, tmem_size, size, UniquePadId }; + + return serviceDispatchIn(&g_hiddbgSrv, 230, in, + .in_num_handles = 1, + .in_handles = { tmem->handle }, + ); +} + +// sdk-nso doesn't use hiddbgAcquireOperationEventHandle/hiddbgGetOperationResult in the *SerialFlash impl, those are used seperately by the user. [9.0.0+] sdk-nso no longer exposes *SerialFlash and related functionality. Result hiddbgReadSerialFlash(u32 offset, void* buffer, size_t size, u64 UniquePadId) { Result rc=0; Event tmpevent={0}; @@ -153,6 +167,26 @@ Result hiddbgReadSerialFlash(u32 offset, void* buffer, size_t size, u64 UniquePa return rc; } +Result hiddbgWriteSerialFlash(u32 offset, void* buffer, size_t tmem_size, size_t size, u64 UniquePadId) { + Result rc=0; + Event tmpevent={0}; + TransferMemory tmem; + + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + rc = tmemCreateFromMemory(&tmem, buffer, tmem_size, Perm_R); + if (R_FAILED(rc)) return rc; + + rc = hiddbgAcquireOperationEventHandle(&tmpevent, true, UniquePadId); // *Must* be used before _hiddbgWriteSerialFlash. + if (R_SUCCEEDED(rc)) rc = _hiddbgWriteSerialFlash(&tmem, offset, tmem_size, size, UniquePadId); + if (R_SUCCEEDED(rc)) rc = eventWait(&tmpevent, U64_MAX); + if (R_SUCCEEDED(rc)) rc = hiddbgGetOperationResult(UniquePadId); + eventClose(&tmpevent); + tmemClose(&tmem); + return rc; +} + Result hiddbgGetOperationResult(u64 UniquePadId) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);