From 515f7db050c0537bc2e79f4e46a683035b1aece1 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 28 Jun 2019 15:06:48 -0700 Subject: [PATCH] pm: add bm cmds, BoostSystemThreadResourceLimit --- nx/include/switch/services/pm.h | 15 ++++ nx/source/services/pm.c | 126 +++++++++++++++++++++++++++++++- 2 files changed, 139 insertions(+), 2 deletions(-) diff --git a/nx/include/switch/services/pm.h b/nx/include/switch/services/pm.h index 295a742a..39ed72ff 100644 --- a/nx/include/switch/services/pm.h +++ b/nx/include/switch/services/pm.h @@ -46,6 +46,12 @@ typedef struct { u64 process_id; } PmProcessEventInfo; +typedef enum { + PmBootMode_Normal = 0, + PmBootMode_Maintenance = 1, + PmBootMode_SafeMode = 2, +} PmBootMode; + Result pmdmntInitialize(void); void pmdmntExit(void); @@ -61,6 +67,11 @@ void pmshellExit(void); Service* pmshellGetServiceSession(void); +Result pmbmInitialize(); +void pmbmExit(); + +Service* pmbmGetServiceSession(void); + Result pmdmntGetDebugProcesses(u32* out_count, u64* out_pids, size_t max_pids); Result pmdmntStartProcess(u64 pid); Result pmdmntGetTitlePid(u64* pid_out, u64 title_id); @@ -81,3 +92,7 @@ Result pmshellClearProcessExceptionOccurred(u64 pid); Result pmshellNotifyBootFinished(void); Result pmshellGetApplicationPid(u64* pid_out); Result pmshellBoostSystemMemoryResourceLimit(u64 boost_size); +Result pmshellBoostSystemThreadResourceLimit(void); + +Result pmbmGetBootMode(u32 *out); +Result pmbmSetMaintenanceBoot(void); diff --git a/nx/source/services/pm.c b/nx/source/services/pm.c index 3f0671cb..6b5284d6 100644 --- a/nx/source/services/pm.c +++ b/nx/source/services/pm.c @@ -7,8 +7,8 @@ #include "services/pm.h" #include "services/sm.h" -static Service g_pmdmntSrv, g_pmshellSrv, g_pminfoSrv; -static u64 g_pmdmntRefCnt, g_pmshellRefCnt, g_pminfoRefCnt; +static Service g_pmdmntSrv, g_pmshellSrv, g_pminfoSrv, g_pmbmSrv; +static u64 g_pmdmntRefCnt, g_pmshellRefCnt, g_pminfoRefCnt, g_pmbmRefCnt; Result pmdmntInitialize(void) { @@ -75,6 +75,28 @@ Service* pmshellGetServiceSession(void) return &g_pmshellSrv; } +Result pmbmInitialize(void) +{ + atomicIncrement64(&g_pmbmRefCnt); + + if (serviceIsActive(&g_pmbmSrv)) + return 0; + + return smGetService(&g_pmbmSrv, "pm:bm"); +} + +void pmbmExit(void) +{ + if (atomicDecrement64(&g_pmbmRefCnt) == 0) { + serviceClose(&g_pmbmSrv); + } +} + +Service* pmbmGetServiceSession(void) +{ + return &g_pmbmSrv; +} + Result pmdmntGetDebugProcesses(u32* out_count, u64* out_pids, size_t max_pids) { IpcCommand c; ipcInitialize(&c); @@ -713,3 +735,103 @@ Result pmshellBoostSystemMemoryResourceLimit(u64 boost_size) { return rc; } + +Result pmshellBoostSystemThreadResourceLimit(void) { + if (hosversionBefore(7,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 8; + + Result rc = serviceIpcDispatch(&g_pmshellSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result pmbmGetBootMode(u32 *out) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + + Result rc = serviceIpcDispatch(&g_pmbmSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 boot_mode; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + *out = resp->boot_mode; + } + } + + return rc; +} + +Result pmbmSetMaintenanceBoot(void) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 1; + + Result rc = serviceIpcDispatch(&g_pmbmSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +}