diff --git a/nx/include/switch/kernel/tmem.h b/nx/include/switch/kernel/tmem.h index 4093812a..a5993ea3 100644 --- a/nx/include/switch/kernel/tmem.h +++ b/nx/include/switch/kernel/tmem.h @@ -27,6 +27,16 @@ typedef struct { */ Result tmemCreate(TransferMemory* t, size_t size, Permission perm); +/** + * @brief Creates a transfer memory object from existing memory. + * @param t Transfer memory information structure that will be filled in. + * @param buf Pointer to a page-aligned buffer. + * @param size Size of the transfer memory object to create. + * @param perm Permissions with which to protect the transfer memory in the local process. + * @return Result code. + */ +Result tmemCreateFromMemory(TransferMemory* t, void* buf, size_t size, Permission perm); + /** * @brief Loads a transfer memory object coming from a remote process. * @param t Transfer memory information structure which will be filled in. diff --git a/nx/source/kernel/tmem.c b/nx/source/kernel/tmem.c index 96975ab8..7fe67486 100644 --- a/nx/source/kernel/tmem.c +++ b/nx/source/kernel/tmem.c @@ -37,6 +37,26 @@ Result tmemCreate(TransferMemory* t, size_t size, Permission perm) return rc; } +Result tmemCreateFromMemory(TransferMemory* t, void* buf, size_t size, Permission perm) +{ + Result rc = 0; + + if (buf == NULL || ((uintptr_t)buf & 0xFFF)) { + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + } + + t->handle = INVALID_HANDLE; + t->size = size; + t->perm = perm; + t->map_addr = NULL; + t->src_addr = NULL; + + memset(buf, 0, size); + rc = svcCreateTransferMemory(&t->handle, buf, size, perm); + + return rc; +} + void tmemLoadRemote(TransferMemory* t, Handle handle, size_t size, Permission perm) { t->handle = handle; @@ -64,7 +84,7 @@ Result tmemMap(TransferMemory* t) } } else { - rc = LibnxError_AlreadyMapped; + rc = MAKERESULT(Module_Libnx, LibnxError_AlreadyMapped); } return rc;