mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-23 05:12:39 +02:00
Document ipc.h
This commit is contained in:
parent
475cc5e941
commit
b791718a03
@ -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;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
Loading…
Reference in New Issue
Block a user