diff --git a/nx/include/switch/services/time.h b/nx/include/switch/services/time.h index 9de42969..b37847ae 100644 --- a/nx/include/switch/services/time.h +++ b/nx/include/switch/services/time.h @@ -77,6 +77,9 @@ Service* timeGetServiceSession_SystemClock(TimeType type); /// Gets the Service object for ITimeZoneService. Service* timeGetServiceSession_TimeZoneService(void); +/// [6.0.0+] Gets the address of the SharedMemory. +void* timeGetSharedmemAddr(void); + /** * @brief Gets the time for the specified clock. * @param[in] type Clock to use. diff --git a/nx/source/services/time.c b/nx/source/services/time.c index 0e8f29ac..1ac49bea 100644 --- a/nx/source/services/time.c +++ b/nx/source/services/time.c @@ -1,5 +1,6 @@ #define NX_SERVICE_ASSUME_NON_DOMAIN #include "service_guard.h" +#include "kernel/shmem.h" #include "services/time.h" #include "runtime/hosversion.h" @@ -11,7 +12,10 @@ static Service g_timeNetworkSystemClock; static Service g_timeTimeZoneService; static Service g_timeLocalSystemClock; +static SharedMemory g_timeSharedmem; + static Result _timeCmdGetSession(Service* srv, Service* srv_out, u32 cmd_id); +static Result _timeGetSharedMemoryNativeHandle(Service* srv, Handle* out); NX_GENERATE_SERVICE_GUARD(time); @@ -41,10 +45,8 @@ Result _timeInitialize(void) { break; } - if (R_FAILED(rc)) - return rc; - - rc = _timeCmdGetSession(&g_timeSrv, &g_timeUserSystemClock, 0); + if (R_SUCCEEDED(rc)) + rc = _timeCmdGetSession(&g_timeSrv, &g_timeUserSystemClock, 0); if (R_SUCCEEDED(rc)) rc = _timeCmdGetSession(&g_timeSrv, &g_timeNetworkSystemClock, 1); @@ -55,10 +57,20 @@ Result _timeInitialize(void) { if (R_SUCCEEDED(rc)) rc = _timeCmdGetSession(&g_timeSrv, &g_timeLocalSystemClock, 4); + if (R_SUCCEEDED(rc) && hosversionAtLeast(6,0,0)) { + Handle shmem; + rc = _timeGetSharedMemoryNativeHandle(&g_timeSrv, &shmem); + if (R_SUCCEEDED(rc)) { + shmemLoadRemote(&g_timeSharedmem, shmem, 0x1000, Perm_R); + rc = shmemMap(&g_timeSharedmem); + } + } + return rc; } void _timeCleanup(void) { + shmemClose(&g_timeSharedmem); serviceClose(&g_timeLocalSystemClock); serviceClose(&g_timeTimeZoneService); serviceClose(&g_timeNetworkSystemClock); @@ -89,6 +101,10 @@ Service* timeGetServiceSession_TimeZoneService(void) { return &g_timeTimeZoneService; } +void* timeGetSharedmemAddr(void) { + return shmemGetAddr(&g_timeSharedmem); +} + static Result _timeCmdGetSession(Service* srv, Service* srv_out, u32 cmd_id) { return serviceDispatch(srv, cmd_id, .out_num_objects = 1, @@ -96,6 +112,13 @@ static Result _timeCmdGetSession(Service* srv, Service* srv_out, u32 cmd_id) { ); } +static Result _timeGetSharedMemoryNativeHandle(Service* srv, Handle* out) { + return serviceDispatch(srv, 20, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = out, + ); +} + static Result _timeCmdInU64NoOut(Service* srv, u64 inval, u32 cmd_id) { return serviceDispatchIn(srv, cmd_id, inval); }