diff --git a/nx/include/switch/services/psc.h b/nx/include/switch/services/psc.h index fadf5882..67e8df7c 100644 --- a/nx/include/switch/services/psc.h +++ b/nx/include/switch/services/psc.h @@ -101,3 +101,45 @@ Result pscPmModuleAcknowledge(PscPmModule *module, PscPmState state); Result pscPmModuleFinalize(PscPmModule *module); void pscPmModuleClose(PscPmModule *module); + +/// Initialize ins:r. +Result insrInitialize(void); + +/// Exit ins:r. +void insrExit(void); + +/// Gets the Service object for the actual ins:r service session. +Service* insrGetServiceSession(void); + +/** + * @brief Retrieves the last system tick the event corresponding to the ID was signaled at. + * @param[in] id Ins request ID (should be 0..4). + * @param[out] tick. + * @return Result code. + */ +Result insrGetLastTick(u32 id, u64 *tick); + +/** + * @brief Retrieves the event corresponding to the ID. + * @param[in] id Ins request ID (should be 0..4). + * @param[out] out. + * @return Result code. + */ +Result insrGetReadableEvent(u32 id, Event *out); + +/// Initialize ins:s. +Result inssInitialize(void); + +/// Exit ins:s. +void inssExit(void); + +/// Gets the Service object for the actual ins:s service session. +Service* inssGetServiceSession(void); + +/** + * @brief Retrieves the event corresponding to the ID. + * @param[in] id Ins send ID (should be 0..11). + * @param[out] out. + * @return Result code. + */ +Result inssGetWritableEvent(u32 id, Event *out); diff --git a/nx/source/services/psc.c b/nx/source/services/psc.c index ec3332b6..7f4e807a 100644 --- a/nx/source/services/psc.c +++ b/nx/source/services/psc.c @@ -4,6 +4,9 @@ static Service g_pscmSrv; +static Service g_insrSrv; +static Service g_inssSrv; + NX_GENERATE_SERVICE_GUARD(pscm); Result _pscmInitialize(void) { @@ -100,3 +103,74 @@ void pscPmModuleClose(PscPmModule *module) { serviceAssumeDomain(&module->srv); serviceClose(&module->srv); } + +NX_GENERATE_SERVICE_GUARD(insr); + +Result _insrInitialize(void) { + return smGetService(&g_insrSrv, "ins:r"); +} + +void _insrCleanup(void) { + serviceClose(&g_insrSrv); +} + +Service* insrGetServiceSession(void) { + return &g_insrSrv; +} + +Result insrGetLastTick(u32 id, u64 *tick) { + return serviceDispatchInOut(&g_insrSrv, 0, id, *tick); +} + +Result insrGetReadableEvent(u32 id, Event *out) { + Handle tmp_handle; + struct { + u32 id; + u64 unk; + } in = { id, 0 }; + Result rc = serviceDispatchIn(&g_insrSrv, 1, in, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &tmp_handle, + ); + + if (R_SUCCEEDED(rc)) + eventLoadRemote(out, tmp_handle, false); + + return rc; +} + +NX_GENERATE_SERVICE_GUARD(inss); + +Result _inssInitialize(void) { + return smGetService(&g_inssSrv, "ins:s"); +} + +void _inssCleanup(void) { + serviceClose(&g_inssSrv); +} + +Service* inssGetServiceSession(void) { + return &g_inssSrv; +} + +Result inssGetWritableEvent(u32 id, Event *out) { + Handle tmp_handle; + struct { + u32 id; + u64 unk; + } in = { id, 0 }; + Result rc = serviceDispatchIn(&g_inssSrv, 0, in, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &tmp_handle, + ); + + if (R_SUCCEEDED(rc)) { + *out = (Event){ + .revent = INVALID_HANDLE, + .wevent = tmp_handle, + .autoclear = false, + }; + } + + return rc; +}