From dc376aa22200db4504ca2ef1c4f3c1e4e0689684 Mon Sep 17 00:00:00 2001 From: plutoo Date: Sat, 9 Sep 2017 06:38:56 +0200 Subject: [PATCH] More ipc --- nx/include/switch/ipc.h | 57 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/nx/include/switch/ipc.h b/nx/include/switch/ipc.h index b661b6da..5fbafd3d 100644 --- a/nx/include/switch/ipc.h +++ b/nx/include/switch/ipc.h @@ -1,3 +1,5 @@ +#define SFCI_MAGIC 0x49434653 + typedef struct { size_t NumSend; // A size_t NumRecv; // B @@ -8,7 +10,8 @@ typedef struct { u8 Flags[8]; bool SendPid; - size_t NumHandles; + size_t NumHandlesCopy; + size_t NumHandlesMove; Handle Handles[8]; } IpcCommand; @@ -22,6 +25,17 @@ static inline void ipcInitialize(IpcCommand* cmd) { cmd->NumHandles = 0; } +typedef struct { // todo: Make sure sizeof isn't 16 bytes! + u32 Size; + u32 Addr; + u32 Packed; +} IpcBufferDescriptor; + +typedef struct { + u32 Packed; + u32 Addr; +} IpcStaticSendDescriptor; + static inline void ipcAddSendBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 Flags) { size_t off = cmd->NumSend; cmd->Buffers[off] = buffer; @@ -41,3 +55,44 @@ static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, static inline void ipcSendPid(IpcCommand* cmd) { cmd->SendPid = true; } + +static inline void ipcSendHandleCopy(IpcCommand* cmd, Handle h) { + cmd->Handles[cmd->NumHandlesCopy++] = h; +} + +static inline void ipcSendHandleMove(IpcCommand* cmd, Handle h) { + cmd->Handles[cmd->NumHandlesCopy + cmd->NumHandlesMove++] = h; +} + +static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) { + u32* buf = armGetTlsPtr(); + *buf++ = 4 | (cmd->NumSend << 20) | (cmd->NumRecv << 24); + + u32 flag = 0; + if (cmd->SendPid || cmd->NumHandlesCopy > 0 || cmd->NumHandlesMove > 0) { + *buf++ = (sizeof_raw/4) | 0x80000000; + *buf++ = (!!cmd->SendPid) | (cmd->NumHandlesCopy << 1) | (cmd->NumHandlesMove << 1); + } + else { + *buf++ = sizeof_raw/4; + } + + size_t i; + for (i=0; i<(cmd->NumSend + cmd->NumRecv); i++, buf+=3) { + IpcBufferDescriptor* desc = (IpcBufferDescriptor*) buf; + desc->Size = cmd->Sizes[i]; + desc->Addr = cmd->Buffers[i]; + uintptr_t ptr = (uintptr_t) cmd->Buffers[i] + desc->Packed = + (((ptr) >> 36) << 28) | + (((ptr >> 32) & 15) << 28) | + cmd->Flags[i]; + } + + // todo: More + return (void*) ((uintptr_t)buf + 15) &~ 15; +} + +static inline Result ipcDispatch(Handle session) { + return svcSendSyncRequest(session); +}