From 722450ae25f79cbadfa8e27edcc338451c2d912a Mon Sep 17 00:00:00 2001 From: XorTroll <33005497+XorTroll@users.noreply.github.com> Date: Fri, 24 Aug 2018 16:21:16 +0200 Subject: [PATCH] Add bpc service with ShutdownSystem and RebootSystem commands (#144) --- nx/include/switch/services/bpc.h | 14 +++++ nx/source/services/bpc.c | 93 ++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 nx/include/switch/services/bpc.h create mode 100644 nx/source/services/bpc.c diff --git a/nx/include/switch/services/bpc.h b/nx/include/switch/services/bpc.h new file mode 100644 index 00000000..96e6d870 --- /dev/null +++ b/nx/include/switch/services/bpc.h @@ -0,0 +1,14 @@ +/** + * @file bpc.h + * @brief Board power control (bpc) service IPC wrapper. + * @author XorTroll + * @copyright libnx Authors + */ +#pragma once +#include "../types.h" + +Result bpcInitialize(void); +void bpcExit(void); + +Result bpcShutdownSystem(void); +Result bpcRebootSystem(void); diff --git a/nx/source/services/bpc.c b/nx/source/services/bpc.c new file mode 100644 index 00000000..4be0c93c --- /dev/null +++ b/nx/source/services/bpc.c @@ -0,0 +1,93 @@ +#include "types.h" +#include "result.h" +#include "arm/atomics.h" +#include "kernel/ipc.h" +#include "kernel/detect.h" +#include "services/bpc.h" +#include "services/sm.h" + +static Service g_bpcSrv; +static u64 g_refCnt; + +Result bpcInitialize(void) +{ + Result rc = 0; + + atomicIncrement64(&g_refCnt); + + if (serviceIsActive(&g_bpcSrv)) + return 0; + + rc = smGetService(&g_bpcSrv, kernelAbove200() ? "bpc" : "bpc:c"); + + return rc; +} + +void bpcExit(void) +{ + if (atomicDecrement64(&g_refCnt) == 0) + serviceClose(&g_bpcSrv); +} + +Result bpcShutdownSystem(void) +{ + 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_bpcSrv); + + if(R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +Result bpcRebootSystem(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_bpcSrv); + + if(R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +}