From b791718a032f249e4ac949e9ca78cf0362daf4b7 Mon Sep 17 00:00:00 2001 From: fincs Date: Sun, 28 Jan 2018 17:07:17 +0100 Subject: [PATCH] Document ipc.h --- nx/include/switch/ipc.h | 156 ++++++++++++++++++++++++++++++++++------ 1 file changed, 136 insertions(+), 20 deletions(-) diff --git a/nx/include/switch/ipc.h b/nx/include/switch/ipc.h index 2ceea7ac..ffd1b4a5 100644 --- a/nx/include/switch/ipc.h +++ b/nx/include/switch/ipc.h @@ -16,7 +16,10 @@ #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -/// IPC command structure. +///@name IPC request building +///@{ + +/// IPC command (request) structure. typedef struct { size_t NumSend; // A size_t NumRecv; // B @@ -37,6 +40,10 @@ typedef struct { Handle Handles[8]; } IpcCommand; +/** + * @brief Initializes an IPC command structure. + * @param cmd IPC command structure. + */ static inline void ipcInitialize(IpcCommand* cmd) { cmd->NumSend = 0; cmd->NumRecv = 0; @@ -50,22 +57,35 @@ static inline void ipcInitialize(IpcCommand* cmd) { cmd->NumHandlesMove = 0; } -typedef struct { // todo: Make sure sizeof isn't 16 bytes! - u32 Size; - u32 Addr; - u32 Packed; +/** + * @brief IPC buffer descriptor. + * @todo Make sure sizeof isn't 16 bytes! + */ +typedef struct { + u32 Size; ///< Size of the buffer. + u32 Addr; ///< Lower 32-bits of the address of the buffer + u32 Packed; ///< Packed data (including higher bits of the address) } IpcBufferDescriptor; +/// IPC static send-buffer descriptor. typedef struct { - u32 Packed; - u32 Addr; + u32 Packed; ///< Packed data (including higher bits of the address) + u32 Addr; ///< Lower 32-bits of the address } IpcStaticSendDescriptor; +/// IPC static receive-buffer descriptor. typedef struct { - u32 Addr; - u32 Packed; + u32 Addr; ///< Lower 32-bits of the address of the buffer + u32 Packed; ///< Packed data (including higher bits of the address) } IpcStaticRecvDescriptor; +/** + * @brief Adds a buffer to an IPC command structure. + * @param cmd IPC command structure. + * @param buffer Address of the buffer. + * @param size Size of the buffer. + * @param flags Flags to attach to the buffer. + */ static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t size, u8 flags) { size_t off = cmd->NumSend; cmd->Buffers[off] = buffer; @@ -74,6 +94,13 @@ static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t cmd->NumSend++; } +/** + * @brief Adds a receive-buffer to an IPC command structure. + * @param cmd IPC command structure. + * @param buffer Address of the buffer. + * @param size Size of the buffer. + * @param flags Flags to attach to the buffer. + */ static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) { size_t off = cmd->NumSend + cmd->NumRecv; cmd->Buffers[off] = buffer; @@ -82,6 +109,13 @@ static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, cmd->NumRecv++; } +/** + * @brief Adds a transfer-buffer to an IPC command structure. + * @param cmd IPC command structure. + * @param buffer Address of the buffer. + * @param size Size of the buffer. + * @param flags Flags to attach to the buffer. + */ static inline void ipcAddTransferBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) { size_t off = cmd->NumSend + cmd->NumRecv + cmd->NumTransfer; cmd->Buffers[off] = buffer; @@ -90,6 +124,13 @@ static inline void ipcAddTransferBuffer(IpcCommand* cmd, void* buffer, size_t si cmd->NumTransfer++; } +/** + * @brief Adds a static-buffer to an IPC command structure. + * @param cmd IPC command structure. + * @param buffer Address of the buffer. + * @param size Size of the buffer. + * @param flags Flags to attach to the buffer. + */ static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t size, u8 index) { size_t off = cmd->NumStaticIn; cmd->Statics[off] = buffer; @@ -98,6 +139,13 @@ static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t cmd->NumStaticIn++; } +/** + * @brief Adds a static-receive-buffer to an IPC command structure. + * @param cmd IPC command structure. + * @param buffer Address of the buffer. + * @param size Size of the buffer. + * @param flags Flags to attach to the buffer. + */ static inline void ipcAddRecvStatic(IpcCommand* cmd, void* buffer, size_t size, u8 index) { size_t off = cmd->NumStaticIn + cmd->NumStaticOut; cmd->Statics[off] = buffer; @@ -106,18 +154,40 @@ static inline void ipcAddRecvStatic(IpcCommand* cmd, void* buffer, size_t size, cmd->NumStaticOut++; } +/** + * @brief Tags an IPC command structure to send the PID. + * @param cmd IPC command structure. + */ static inline void ipcSendPid(IpcCommand* cmd) { cmd->SendPid = true; } +/** + * @brief Adds a copy-handle to be sent through an IPC command structure. + * @param cmd IPC command structure. + * @param h Handle to send. + * @remark The receiving process gets a copy of the handle. + */ static inline void ipcSendHandleCopy(IpcCommand* cmd, Handle h) { cmd->Handles[cmd->NumHandlesCopy++] = h; } +/** + * @brief Adds a move-handle to be sent through an IPC command structure. + * @param cmd IPC command structure. + * @param h Handle to send. + * @remark The sending process loses ownership of the handle, which is transferred to the receiving process. + */ static inline void ipcSendHandleMove(IpcCommand* cmd, Handle h) { cmd->Handles[cmd->NumHandlesCopy + cmd->NumHandlesMove++] = h; } +/** + * @brief Prepares the header of an IPC command structure. + * @param cmd IPC command structure. + * @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request + * @return Pointer to the raw embedded data structure in the request, ready to be filled out. + */ static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) { u32* buf = (u32*)armGetTls(); size_t i; @@ -198,26 +268,41 @@ static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) { return (void*) raw; } +/** + * @brief Dispatches an IPC command structure. + * @param cmd IPC command structure. + * @return Result code. + */ static inline Result ipcDispatch(Handle session) { return svcSendSyncRequest(session); } -// Response parsing +///@} + +///@name IPC response parsing +///@{ + +/// IPC parsed command (response) structure. typedef struct { - bool HasPid; - u64 Pid; + bool HasPid; ///< true if the 'Pid' field is filled out. + u64 Pid; ///< PID included in the response (only if HasPid is true) - size_t NumHandles; - Handle Handles[8]; + size_t NumHandles; ///< Number of handles in the response. + Handle Handles[8]; ///< Handles. - size_t NumBuffers; - void* Buffers[4]; - size_t BufferSizes[4]; + size_t NumBuffers; ///< Number of buffers in the response. + void* Buffers[4]; ///< Pointers to the buffers. + size_t BufferSizes[4]; ///< Sizes of the buffers. - void* Raw; - size_t RawSize; + void* Raw; ///< Pointer to the raw embedded data structure in the response. + size_t RawSize; ///< Size of the raw embedded data. } IpcParsedCommand; +/** + * @brief Parse an IPC command response into an IPC parsed command structure. + * @param IPC parsed command structure to fill in. + * @return Result code. + */ static inline Result ipcParse(IpcParsedCommand* r) { u32* buf = (u32*)armGetTls(); u32 ctrl0 = *buf++; @@ -271,6 +356,12 @@ static inline Result ipcParse(IpcParsedCommand* r) { return 0; } +/** + * @brief Queries the size of an IPC pointer buffer. + * @param session IPC session handle. + * @param size Output variable in which to store the size. + * @return Result code. + */ static inline Result ipcQueryPointerBufferSize(Handle session, size_t *size) { u32* buf = (u32*)armGetTls(); @@ -305,7 +396,17 @@ static inline Result ipcQueryPointerBufferSize(Handle session, size_t *size) { return rc; } -// Domain shit +///@} + +///@name IPC domain handling +///@{ + +/** + * @brief Converts an IPC session handle into a domain. + * @param session IPC session handle. + * @param object_id_out Output variable in which to store the object ID. + * @return Result code. + */ static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_out) { u32* buf = (u32*)armGetTls(); @@ -338,6 +439,7 @@ static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_ou return rc; } +/// IPC domain message header. typedef struct { u8 Type; u8 Pad0; @@ -346,6 +448,13 @@ typedef struct { u32 Pad1[2]; } DomainMessageHeader; +/** + * @brief Prepares the header of an IPC command structure (domain version). + * @param cmd IPC command structure. + * @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request + * @oaram object_id Domain object ID. + * @return Pointer to the raw embedded data structure in the request, ready to be filled out. + */ static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw, size_t object_id) { void* raw = ipcPrepareHeader(cmd, sizeof_raw + sizeof(DomainMessageHeader)); DomainMessageHeader* hdr = (DomainMessageHeader*) raw; @@ -359,6 +468,11 @@ static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw return (void*)(((uintptr_t) raw) + sizeof(DomainMessageHeader)); } +/** + * @brief Parse an IPC command response into an IPC parsed command structure (domain version). + * @param IPC parsed command structure to fill in. + * @return Result code. + */ static inline Result ipcParseForDomain(IpcParsedCommand* r) { Result rc = ipcParse(r); @@ -368,3 +482,5 @@ static inline Result ipcParseForDomain(IpcParsedCommand* r) { return rc; } + +///@}