mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-07 08:39:24 +02:00
psc: update for new-ipc
This commit is contained in:
parent
61fabbe1bc
commit
71b44cfb02
@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "../kernel/event.h"
|
#include "../kernel/event.h"
|
||||||
#include "../services/sm.h"
|
#include "../sf/service.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PscPmState_Awake = 0, ///< Everything is awake.
|
PscPmState_Awake = 0, ///< Everything is awake.
|
||||||
@ -18,18 +18,81 @@ typedef enum {
|
|||||||
PscPmState_ReadyShutdown = 5, ///< Preparing to transition to shutdown.
|
PscPmState_ReadyShutdown = 5, ///< Preparing to transition to shutdown.
|
||||||
} PscPmState;
|
} 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 {
|
typedef struct {
|
||||||
Event event;
|
Event event;
|
||||||
Service srv;
|
Service srv;
|
||||||
u16 module_id;
|
PscPmModuleId module_id;
|
||||||
} PscPmModule;
|
} PscPmModule;
|
||||||
|
|
||||||
Result pscInitialize(void);
|
Result pscmInitialize(void);
|
||||||
void pscExit(void);
|
void pscmExit(void);
|
||||||
Service* pscGetServiceSession(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 pscPmModuleGetRequest(PscPmModule *module, PscPmState *out_state, u32 *out_flags);
|
||||||
Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state);
|
Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state);
|
||||||
Result pscPmModuleFinalize(PscPmModule *module);
|
Result pscPmModuleFinalize(PscPmModule *module);
|
||||||
|
|
||||||
|
void pscPmModuleClose(PscPmModule *module);
|
||||||
|
@ -1,276 +1,102 @@
|
|||||||
/**
|
#include "service_guard.h"
|
||||||
* @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 "services/psc.h"
|
#include "services/psc.h"
|
||||||
#include "services/sm.h"
|
|
||||||
#include "runtime/hosversion.h"
|
#include "runtime/hosversion.h"
|
||||||
|
|
||||||
static Service g_pscSrv;
|
static Service g_pscmSrv;
|
||||||
static u64 g_refCnt;
|
|
||||||
|
|
||||||
static Result _pscPmModuleInitialize(PscPmModule *module, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear);
|
NX_GENERATE_SERVICE_GUARD(pscm);
|
||||||
static Result _pscPmModuleAcknowledge(PscPmModule *module);
|
|
||||||
static Result _pscPmModuleAcknowledgeEx(PscPmModule *module, PscPmState state);
|
|
||||||
|
|
||||||
Result pscInitialize(void) {
|
Result _pscmInitialize(void) {
|
||||||
Result rc = 0;
|
Result rc = smGetService(&g_pscmSrv, "psc:m");
|
||||||
|
|
||||||
atomicIncrement64(&g_refCnt);
|
|
||||||
|
|
||||||
if (serviceIsActive(&g_pscSrv))
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = smGetService(&g_pscSrv, "psc:m");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
rc = serviceConvertToDomain(&g_pscSrv);
|
rc = serviceConvertToDomain(&g_pscmSrv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc)) pscExit();
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pscExit(void) {
|
void _pscmCleanup(void) {
|
||||||
if (atomicDecrement64(&g_refCnt) == 0) {
|
serviceClose(&g_pscmSrv);
|
||||||
serviceClose(&g_pscSrv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Service* pscGetServiceSession(void) {
|
Service* pscmGetServiceSession(void) {
|
||||||
return &g_pscSrv;
|
return &g_pscmSrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pscGetPmModule(PscPmModule *out, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) {
|
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
NX_INLINE Result _pscPmModuleInitialize(PscPmModule *module, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear);
|
||||||
u64 magic;
|
|
||||||
u64 cmd_id;
|
|
||||||
} *raw;
|
|
||||||
|
|
||||||
raw = serviceIpcPrepareHeader(&g_pscSrv, &c, sizeof(*raw));
|
Result pscmGetPmModule(PscPmModule *out, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) {
|
||||||
|
serviceAssumeDomain(&g_pscmSrv);
|
||||||
raw->magic = SFCI_MAGIC;
|
Result rc = serviceDispatch(&g_pscmSrv, 0,
|
||||||
raw->cmd_id = 0;
|
.out_num_objects = 1,
|
||||||
|
.out_objects = &out->srv,
|
||||||
Result rc = serviceIpcDispatch(&g_pscSrv);
|
);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcParsedCommand r;
|
if (R_FAILED((rc = _pscPmModuleInitialize(out, module_id, dependencies, dependency_count, autoclear)))) {
|
||||||
struct {
|
pscPmModuleClose(out);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result _pscPmModuleInitialize(PscPmModule *module, u16 module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) {
|
Result _pscPmModuleInitialize(PscPmModule *module, PscPmModuleId module_id, const u16 *dependencies, size_t dependency_count, bool autoclear) {
|
||||||
IpcCommand c;
|
_Static_assert(sizeof(module_id) == sizeof(u32), "PscPmModuleId size");
|
||||||
ipcInitialize(&c);
|
|
||||||
ipcAddSendBuffer(&c, dependencies, dependency_count * sizeof(u16), BufferType_Normal);
|
|
||||||
|
|
||||||
struct {
|
Handle evt_handle = INVALID_HANDLE;
|
||||||
u64 magic;
|
serviceAssumeDomain(&module->srv);
|
||||||
u64 cmd_id;
|
Result rc = serviceDispatchIn(&module->srv, 0, module_id,
|
||||||
u32 module_id;
|
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
|
||||||
} *raw;
|
.buffers = { { dependencies, dependency_count * sizeof(*dependencies) } },
|
||||||
|
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
|
||||||
raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw));
|
.out_handles = &evt_handle,
|
||||||
|
);
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 0;
|
|
||||||
raw->module_id = module_id;
|
|
||||||
|
|
||||||
Result rc = serviceIpcDispatch(&module->srv);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcParsedCommand r;
|
eventLoadRemote(&module->event, evt_handle, autoclear);
|
||||||
struct {
|
module->module_id = module_id;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pscPmModuleGetRequest(PscPmModule *module, PscPmState *out_state, u32 *out_flags) {
|
Result pscPmModuleGetRequest(PscPmModule *module, PscPmState *out_state, u32 *out_flags) {
|
||||||
IpcCommand c;
|
|
||||||
ipcInitialize(&c);
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u32 state;
|
||||||
u64 cmd_id;
|
u32 flags;
|
||||||
} *raw;
|
} out;
|
||||||
|
|
||||||
raw = serviceIpcPrepareHeader(&module->srv, &c, sizeof(*raw));
|
serviceAssumeDomain(&module->srv);
|
||||||
|
Result rc = serviceDispatchOut(&module->srv, 1, out);
|
||||||
raw->magic = SFCI_MAGIC;
|
|
||||||
raw->cmd_id = 1;
|
|
||||||
|
|
||||||
Result rc = serviceIpcDispatch(&module->srv);
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcParsedCommand r;
|
if (out_state) *out_state = (PscPmState)out.state;
|
||||||
struct {
|
if (out_flags) *out_flags = out.flags;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state) {
|
Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state) {
|
||||||
|
serviceAssumeDomain(&module->srv);
|
||||||
|
|
||||||
if (hosversionAtLeast(6,0,0)) {
|
if (hosversionAtLeast(6,0,0)) {
|
||||||
return _pscPmModuleAcknowledgeEx(module, state);
|
_Static_assert(sizeof(state) == sizeof(u32), "PscPmState size");
|
||||||
|
return serviceDispatchIn(&module->srv, 4, state);
|
||||||
} else {
|
} else {
|
||||||
return _pscPmModuleAcknowledge(module);
|
return serviceDispatch(&module->srv, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pscPmModuleFinalize(PscPmModule *module) {
|
Result pscPmModuleFinalize(PscPmModule *module) {
|
||||||
IpcCommand c;
|
serviceAssumeDomain(&module->srv);
|
||||||
ipcInitialize(&c);
|
return serviceDispatch(&module->srv, 3);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result _pscPmModuleAcknowledge(PscPmModule *module) {
|
void pscPmModuleClose(PscPmModule *module) {
|
||||||
IpcCommand c;
|
serviceAssumeDomain(&module->srv);
|
||||||
ipcInitialize(&c);
|
serviceClose(&module->srv);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user