From 71b44cfb02400c2ee8ff793c5cff3fa6013cc387 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 18 Oct 2019 23:50:11 -0700 Subject: [PATCH] psc: update for new-ipc --- nx/include/switch/services/psc.h | 75 ++++++++- nx/source/services/psc.c | 270 ++++++------------------------- 2 files changed, 117 insertions(+), 228 deletions(-) diff --git a/nx/include/switch/services/psc.h b/nx/include/switch/services/psc.h index 781bd941..6b9ef70a 100644 --- a/nx/include/switch/services/psc.h +++ b/nx/include/switch/services/psc.h @@ -7,7 +7,7 @@ #pragma once #include "../types.h" #include "../kernel/event.h" -#include "../services/sm.h" +#include "../sf/service.h" typedef enum { PscPmState_Awake = 0, ///< Everything is awake. @@ -18,18 +18,81 @@ typedef enum { PscPmState_ReadyShutdown = 5, ///< Preparing to transition to shutdown. } PscPmState; +typedef enum { + PscPmModuleId_Usb = 4, + PscPmModuleId_Ethernet = 5, + PscPmModuleId_Fgm = 6, + PscPmModuleId_PcvClock = 7, + PscPmModuleId_PcvVoltage = 8, + PscPmModuleId_Gpio = 9, + PscPmModuleId_Pinmux = 10, + PscPmModuleId_Uart = 11, + PscPmModuleId_I2c = 12, + PscPmModuleId_I2cPcv = 13, + PscPmModuleId_Spi = 14, + PscPmModuleId_Pwm = 15, + PscPmModuleId_Psm = 16, + PscPmModuleId_Tc = 17, + PscPmModuleId_Omm = 18, + PscPmModuleId_Pcie = 19, + PscPmModuleId_Lbl = 20, + PscPmModuleId_Display = 21, + + PscPmModuleId_Hid = 24, + PscPmModuleId_WlanSockets = 25, + + PscPmModuleId_Fs = 27, + PscPmModuleId_Audio = 28, + + PscPmModuleId_TmaHostIo = 30, + PscPmModuleId_Bluetooth = 31, + PscPmModuleId_Bpc = 32, + PscPmModuleId_Fan = 33, + PscPmModuleId_Pcm = 34, + PscPmModuleId_Nfc = 35, + PscPmModuleId_Apm = 36, + PscPmModuleId_Btm = 37, + PscPmModuleId_Nifm = 38, + PscPmModuleId_GpioLow = 39, + PscPmModuleId_Npns = 40, + PscPmModuleId_Lm = 41, + PscPmModuleId_Bcat = 42, + PscPmModuleId_Time = 43, + PscPmModuleId_Pctl = 44, + PscPmModuleId_Erpt = 45, + PscPmModuleId_Eupld = 46, + PscPmModuleId_Friends = 47, + PscPmModuleId_Bgtc = 48, + PscPmModuleId_Account = 49, + PscPmModuleId_Sasbus = 50, + PscPmModuleId_Ntc = 51, + PscPmModuleId_Idle = 52, + PscPmModuleId_Tcap = 53, + PscPmModuleId_PsmLow = 54, + PscPmModuleId_Ndd = 55, + PscPmModuleId_Olsc = 56, + + PscPmModuleId_Ns = 61, + + PscPmModuleId_Nvservices = 101, + + PscPmModuleId_Spsm = 127, +} PscPmModuleId; + typedef struct { Event event; Service srv; - u16 module_id; + PscPmModuleId module_id; } PscPmModule; -Result pscInitialize(void); -void pscExit(void); -Service* pscGetServiceSession(void); +Result pscmInitialize(void); +void pscmExit(void); +Service* pscmGetServiceSession(void); -Result pscGetPmModule(PscPmModule *out, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear); +Result pscmGetPmModule(PscPmModule *out, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear); Result pscPmModuleGetRequest(PscPmModule *module, PscPmState *out_state, u32 *out_flags); Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state); Result pscPmModuleFinalize(PscPmModule *module); + +void pscPmModuleClose(PscPmModule *module); diff --git a/nx/source/services/psc.c b/nx/source/services/psc.c index 2b854a52..669de1a5 100644 --- a/nx/source/services/psc.c +++ b/nx/source/services/psc.c @@ -1,276 +1,102 @@ -/** - * @file psc.h - * @brief PSC service IPC wrapper. - * @author SciresM - * @copyright libnx Authors - */ -#include "types.h" -#include "result.h" -#include "arm/atomics.h" -#include "kernel/ipc.h" -#include "kernel/event.h" +#include "service_guard.h" #include "services/psc.h" -#include "services/sm.h" #include "runtime/hosversion.h" -static Service g_pscSrv; -static u64 g_refCnt; +static Service g_pscmSrv; -static Result _pscPmModuleInitialize(PscPmModule *module, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear); -static Result _pscPmModuleAcknowledge(PscPmModule *module); -static Result _pscPmModuleAcknowledgeEx(PscPmModule *module, PscPmState state); +NX_GENERATE_SERVICE_GUARD(pscm); -Result pscInitialize(void) { - Result rc = 0; - - atomicIncrement64(&g_refCnt); - - if (serviceIsActive(&g_pscSrv)) - return rc; - - rc = smGetService(&g_pscSrv, "psc:m"); +Result _pscmInitialize(void) { + Result rc = smGetService(&g_pscmSrv, "psc:m"); if (R_SUCCEEDED(rc)) { - rc = serviceConvertToDomain(&g_pscSrv); + rc = serviceConvertToDomain(&g_pscmSrv); } - if (R_FAILED(rc)) pscExit(); - return rc; } -void pscExit(void) { - if (atomicDecrement64(&g_refCnt) == 0) { - serviceClose(&g_pscSrv); - } +void _pscmCleanup(void) { + serviceClose(&g_pscmSrv); } -Service* pscGetServiceSession(void) { - return &g_pscSrv; +Service* pscmGetServiceSession(void) { + return &g_pscmSrv; } -Result pscGetPmModule(PscPmModule *out, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) { - IpcCommand c; - ipcInitialize(&c); - struct { - u64 magic; - u64 cmd_id; - } *raw; +NX_INLINE Result _pscPmModuleInitialize(PscPmModule *module, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear); - raw = serviceIpcPrepareHeader(&g_pscSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - - Result rc = serviceIpcDispatch(&g_pscSrv); +Result pscmGetPmModule(PscPmModule *out, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) { + serviceAssumeDomain(&g_pscmSrv); + Result rc = serviceDispatch(&g_pscmSrv, 0, + .out_num_objects = 1, + .out_objects = &out->srv, + ); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_pscSrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - serviceCreateSubservice(&out->srv, &g_pscSrv, &r, 0); - - rc = _pscPmModuleInitialize(out, module_id, dependencies, dependency_count, autoclear); - if (R_FAILED(rc)) { - serviceClose(&out->srv); - } + if (R_FAILED((rc = _pscPmModuleInitialize(out, module_id, dependencies, dependency_count, autoclear)))) { + pscPmModuleClose(out); } } return rc; } -Result _pscPmModuleInitialize(PscPmModule *module, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) { - IpcCommand c; - ipcInitialize(&c); - ipcAddSendBuffer(&c, dependencies, dependency_count * sizeof(u16), BufferType_Normal); +Result _pscPmModuleInitialize(PscPmModule *module, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) { + _Static_assert(sizeof(module_id) == sizeof(u32), "PscPmModuleId size"); - struct { - u64 magic; - u64 cmd_id; - u32 module_id; - } *raw; - - raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->module_id = module_id; - - Result rc = serviceIpcDispatch(&module->srv); + Handle evt_handle = INVALID_HANDLE; + serviceAssumeDomain(&module->srv); + Result rc = serviceDispatchIn(&module->srv, 0, module_id, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, + .buffers = { { dependencies, dependency_count * sizeof(*dependencies) } }, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &evt_handle, + ); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&module->srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - eventLoadRemote(&module->event, r.Handles[0], autoclear); - module->module_id = module_id; - } + eventLoadRemote(&module->event, evt_handle, autoclear); + module->module_id = module_id; } return rc; } Result pscPmModuleGetRequest(PscPmModule *module, PscPmState *out_state, u32 *out_flags) { - IpcCommand c; - ipcInitialize(&c); - struct { - u64 magic; - u64 cmd_id; - } *raw; + u32 state; + u32 flags; + } out; - raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 1; - - Result rc = serviceIpcDispatch(&module->srv); + serviceAssumeDomain(&module->srv); + Result rc = serviceDispatchOut(&module->srv, 1, out); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u32 state; - u32 flags; - } *resp; - - serviceIpcParse(&module->srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out_state = (PscPmState)resp->state; - *out_flags = resp->flags; - } + if (out_state) *out_state = (PscPmState)out.state; + if (out_flags) *out_flags = out.flags; } return rc; } Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state) { + serviceAssumeDomain(&module->srv); + if (hosversionAtLeast(6,0,0)) { - return _pscPmModuleAcknowledgeEx(module, state); + _Static_assert(sizeof(state) == sizeof(u32), "PscPmState size"); + return serviceDispatchIn(&module->srv, 4, state); } else { - return _pscPmModuleAcknowledge(module); + return serviceDispatch(&module->srv, 2); } } Result pscPmModuleFinalize(PscPmModule *module) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 3; - - Result rc = serviceIpcDispatch(&module->srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&module->srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + serviceAssumeDomain(&module->srv); + return serviceDispatch(&module->srv, 3); } -static Result _pscPmModuleAcknowledge(PscPmModule *module) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 2; - - Result rc = serviceIpcDispatch(&module->srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&module->srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - -static Result _pscPmModuleAcknowledgeEx(PscPmModule *module, PscPmState state) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 state; - } *raw; - - raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 4; - raw->state = state; - - Result rc = serviceIpcDispatch(&module->srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&module->srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; +void pscPmModuleClose(PscPmModule *module) { + serviceAssumeDomain(&module->srv); + serviceClose(&module->srv); }