clkrst: update for new-ipc

This commit is contained in:
Michael Scire 2019-10-18 22:45:24 -07:00 committed by fincs
parent 960f99e7a2
commit 040767ce57
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 20 additions and 128 deletions

View File

@ -6,13 +6,14 @@
*/ */
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../services/sm.h" #include "../sf/service.h"
#include "../services/pcv.h" #include "../services/pcv.h"
typedef struct { typedef struct {
Service s; Service s;
} ClkrstSession; } ClkrstSession;
/// Only available on [8.0.0+].
Result clkrstInitialize(void); Result clkrstInitialize(void);
void clkrstExit(void); void clkrstExit(void);
Service* clkrstGetServiceSession(void); Service* clkrstGetServiceSession(void);

View File

@ -1,40 +1,22 @@
#include "types.h" #define NX_SERVICE_ASSUME_NON_DOMAIN
#include "result.h" #include "service_guard.h"
#include "arm/atomics.h"
#include "kernel/ipc.h"
#include "services/pcv.h" #include "services/pcv.h"
#include "runtime/hosversion.h"
#include "services/sm.h"
#include "services/clkrst.h" #include "services/clkrst.h"
#include "runtime/hosversion.h"
static Service g_clkrstSrv; static Service g_clkrstSrv;
static u64 g_refCnt;
Result clkrstInitialize(void) { NX_GENERATE_SERVICE_GUARD(clkrst);
if(hosversionBefore(8,0,0)) {
Result _clkrstInitialize(void) {
if(hosversionBefore(8,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
}
atomicIncrement64(&g_refCnt); return smGetService(&g_clkrstSrv, "clkrst");
if (serviceIsActive(&g_clkrstSrv)) {
return 0;
}
Result rc = smGetService(&g_clkrstSrv, "clkrst");
if (R_FAILED(rc)) {
clkrstExit();
}
return rc;
} }
void _clkrstCleanup(void) {
void clkrstExit(void) { serviceClose(&g_clkrstSrv);
if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_clkrstSrv);
}
} }
Service* clkrstGetServiceSession(void) { Service* clkrstGetServiceSession(void) {
@ -42,115 +24,24 @@ Service* clkrstGetServiceSession(void) {
} }
Result clkrstOpenSession(ClkrstSession* session_out, PcvModuleId module_id, u32 unk) { Result clkrstOpenSession(ClkrstSession* session_out, PcvModuleId module_id, u32 unk) {
IpcCommand c; const struct {
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 module_id; u32 module_id;
u32 unk; u32 unk;
} *raw; } in = { module_id, unk };
return serviceDispatchIn(&g_clkrstSrv, 0, in,
raw = ipcPrepareHeader(&c, sizeof(*raw)); .out_num_objects = 1,
.out_objects = &session_out->s,
raw->magic = SFCI_MAGIC; );
raw->cmd_id = 0;
raw->module_id = module_id;
raw->unk = unk;
Result rc = serviceIpcDispatch(&g_clkrstSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreate(&session_out->s, r.Handles[0]);
}
}
return rc;
} }
void clkrstCloseSession(ClkrstSession* session) { void clkrstCloseSession(ClkrstSession* session) {
serviceClose(&session->s); serviceClose(&session->s);
} }
Result clkrstSetClockRate(ClkrstSession* session, u32 hz) { Result clkrstSetClockRate(ClkrstSession* session, u32 hz) {
IpcCommand c; return serviceDispatchIn(&session->s, 7, hz);
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 hz;
} *raw;
raw = serviceIpcPrepareHeader(&session->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 7;
raw->hz = hz;
Result rc = serviceIpcDispatch(&session->s);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&session->s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
} }
Result clkrstGetClockRate(ClkrstSession* session, u32 *out_hz) { Result clkrstGetClockRate(ClkrstSession* session, u32 *out_hz) {
IpcCommand c; return serviceDispatchOut(&session->s, 8, *out_hz);
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&session->s, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 8;
Result rc = serviceIpcDispatch(&session->s);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
u32 hz;
} *resp;
serviceIpcParse(&session->s, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
*out_hz = resp->hz;
}
}
return rc;
} }