From 89021287f8db5d46c2d7ee228645d0fa4680e895 Mon Sep 17 00:00:00 2001 From: plutoo Date: Thu, 1 Feb 2018 00:26:39 +0100 Subject: [PATCH] Revert "We don't understand Auto -- disable for now" This reverts commit 20c4bfd54a2d2116c99cb40c87d03a95e24d645b. --- nx/include/switch/gfx/binder.h | 1 + nx/source/gfx/binder.c | 77 +++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/nx/include/switch/gfx/binder.h b/nx/include/switch/gfx/binder.h index 1777ec58..44e87cde 100644 --- a/nx/include/switch/gfx/binder.h +++ b/nx/include/switch/gfx/binder.h @@ -10,6 +10,7 @@ typedef struct { s32 id; Handle nativeHandle; size_t ipcBufferSize; + bool hasTransactAuto; } Binder; // binderExitSession will not close the sessionHandle since it's user-specified via binderCreateSession and may be used elsewhere. diff --git a/nx/source/gfx/binder.c b/nx/source/gfx/binder.c index 3e6bf1bd..6c98152e 100644 --- a/nx/source/gfx/binder.c +++ b/nx/source/gfx/binder.c @@ -12,6 +12,7 @@ void binderCreateSession(Binder *session, Handle sessionHandle, s32 id) session->sessionHandle = sessionHandle; session->id = id; session->nativeHandle = INVALID_HANDLE; + session->hasTransactAuto = 0; } Result binderInitSession(Binder *session, u32 unk0) @@ -57,6 +58,10 @@ Result binderInitSession(Binder *session, u32 unk0) return rc; } + // Use TransactParcelAuto when available. + if (kernelAbove300()) + session->hasTransactAuto = 1; + return rc; } @@ -127,6 +132,73 @@ static Result _binderTransactParcel( return rc; } +static Result _binderTransactParcelAuto( + Binder *session, u32 code, + void* parcel_data, size_t parcel_data_size, + void* parcel_reply, size_t parcel_reply_size, + u32 flags) +{ + if (!session->created || !session->initialized) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + s32 session_id; + u32 code; + u32 flags; + } *raw; + + void* buf_static[2] = {parcel_data, parcel_reply}; + void* buf_transfer[2] = {parcel_data, parcel_reply}; + size_t buf_static_size[2] = {parcel_data_size, parcel_reply_size}; + size_t buf_transfer_size[2] = {parcel_data_size, parcel_reply_size}; + + if(session->ipcBufferSize!=0 && buf_static_size[0] <= session->ipcBufferSize) { + buf_transfer[0] = NULL; + buf_transfer[1] = NULL; + buf_transfer_size[0] = 0; + buf_transfer_size[1] = 0; + } + else { + buf_static[0] = NULL; + buf_static[1] = NULL; + buf_static_size[0] = 0; + buf_static_size[1] = 0; + } + + ipcAddSendBuffer(&c, buf_transfer[0], buf_transfer_size[0], 0); + ipcAddRecvBuffer(&c, buf_transfer[1], buf_transfer_size[1], 0); + + ipcAddSendStatic(&c, buf_static[0], buf_static_size[0], 0); + ipcAddRecvStatic(&c, buf_static[1], buf_static_size[1], 0); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + raw->magic = SFCI_MAGIC; + raw->cmd_id = 3; + raw->session_id = session->id; + raw->code = code; + raw->flags = flags; + + Result rc = ipcDispatch(session->sessionHandle); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + Result binderTransactParcel( Binder *session, u32 code, void* parcel_data, size_t parcel_data_size, @@ -135,7 +207,10 @@ Result binderTransactParcel( { Result rc = 0; - rc = _binderTransactParcel(session, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags); + if (session->hasTransactAuto) + rc = _binderTransactParcelAuto(session, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags); + else + rc = _binderTransactParcel(session, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags); return rc; }