psc: update for new-ipc

This commit is contained in:
Michael Scire 2019-10-18 23:50:11 -07:00 committed by fincs
parent 61fabbe1bc
commit 71b44cfb02
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 117 additions and 228 deletions

View File

@ -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);

View File

@ -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);
}