smm: support tipc/cmif

This commit is contained in:
Michael Scire 2021-04-10 15:57:31 -07:00 committed by fincs
parent 7416b23ef9
commit eb8ee97f1c
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 113 additions and 14 deletions

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include "../types.h" #include "../types.h"
#include "../sf/service.h" #include "../sf/service.h"
#include "../sf/tipc.h"
/// Initialize sm:m. /// Initialize sm:m.
Result smManagerInitialize(void); Result smManagerInitialize(void);
@ -14,8 +15,29 @@ Result smManagerInitialize(void);
/// Exit sm:m. /// Exit sm:m.
void smManagerExit(void); void smManagerExit(void);
/// Gets the Service object for the actual sm:m service session.
Service* smManagerGetServiceSession(void);
Result smManagerRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size); Result smManagerRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size);
Result smManagerUnregisterProcess(u64 pid); Result smManagerUnregisterProcess(u64 pid);
/// Initialize sm:m exclusively for tipc (requires <12.0.0 and non-Atmosphere).
Result smManagerCmifInitialize(void);
/// Exit sm:m exclusively for tipc (requires <12.0.0 and non-Atmosphere).
void smManagerCmifExit(void);
/// Gets the Service object for the actual sm:m service session (requires <12.0.0 and non-Atmosphere).
Service* smManagerCmifGetServiceSession(void);
Result smManagerCmifRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size);
Result smManagerCmifUnregisterProcess(u64 pid);
/// Initialize sm:m exclusively for tipc (requires 12.0.0+ or Atmosphere).
Result smManagerTipcInitialize(void);
/// Exit sm:m exclusively for tipc (requires 12.0.0+ or Atmosphere).
void smManagerTipcExit(void);
/// Gets the TipcService object for the actual sm:m service session (requires 12.0.0+ or Atmosphere).
TipcService* smManagerTipcGetServiceSession(void);
Result smManagerTipcRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size);
Result smManagerTipcUnregisterProcess(u64 pid);

View File

@ -3,24 +3,63 @@
#include "services/smm.h" #include "services/smm.h"
#include "runtime/hosversion.h" #include "runtime/hosversion.h"
static Service g_smManagerSrv; static Service g_smManagerCmifSrv;
static TipcService g_smManagerTipcSrv;
NX_GENERATE_SERVICE_GUARD(smManager); NX_GENERATE_SERVICE_GUARD(smManagerCmif);
NX_GENERATE_SERVICE_GUARD(smManagerTipc);
Result _smManagerInitialize(void) { NX_INLINE bool _smManagerUseTipc(void) {
return smGetService(&g_smManagerSrv, "sm:m"); return hosversionIsAtmosphere() || hosversionAtLeast(12,0,0);
} }
void _smManagerCleanup(void) { Result smManagerInitialize(void) {
serviceClose(&g_smManagerSrv); if (_smManagerUseTipc()) {
return smManagerTipcInitialize();
} else {
return smManagerCmifInitialize();
}
} }
Service* smManagerGetServiceSession(void) { void smManagerExit(void) {
return &g_smManagerSrv; if (_smManagerUseTipc()) {
return smManagerTipcExit();
} else {
return smManagerCmifExit();
}
} }
Result smManagerRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size) { Result smManagerRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size) {
return serviceDispatchIn(&g_smManagerSrv, 0, pid, if (_smManagerUseTipc()) {
return smManagerTipcRegisterProcess(pid, acid_sac, acid_sac_size, aci0_sac, aci0_sac_size);
} else {
return smManagerCmifRegisterProcess(pid, acid_sac, acid_sac_size, aci0_sac, aci0_sac_size);
}
}
Result smManagerUnregisterProcess(u64 pid) {
if (_smManagerUseTipc()) {
return smManagerTipcUnregisterProcess(pid);
} else {
return smManagerCmifUnregisterProcess(pid);
}
}
Result _smManagerCmifInitialize(void) {
if (_smManagerUseTipc()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return smGetService(&g_smManagerCmifSrv, "sm:m");
}
void _smManagerCmifCleanup(void) {
serviceClose(&g_smManagerCmifSrv);
}
Service* smManagerCmifGetServiceSession(void) {
return &g_smManagerCmifSrv;
}
Result smManagerCmifRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size) {
return serviceDispatchIn(&g_smManagerCmifSrv, 0, pid,
.buffer_attrs = { .buffer_attrs = {
SfBufferAttr_In | SfBufferAttr_HipcMapAlias, SfBufferAttr_In | SfBufferAttr_HipcMapAlias,
SfBufferAttr_In | SfBufferAttr_HipcMapAlias, SfBufferAttr_In | SfBufferAttr_HipcMapAlias,
@ -32,6 +71,44 @@ Result smManagerRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_s
); );
} }
Result smManagerUnregisterProcess(u64 pid) { Result smManagerCmifUnregisterProcess(u64 pid) {
return serviceDispatchIn(&g_smManagerSrv, 1, pid); return serviceDispatchIn(&g_smManagerCmifSrv, 1, pid);
}
Result _smManagerTipcInitialize(void) {
if (!_smManagerUseTipc()) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Handle handle;
Result rc = smGetServiceOriginal(&handle, smEncodeName("sm:m"));
if (R_SUCCEEDED(rc)) {
tipcCreate(&g_smManagerTipcSrv, handle);
}
return rc;
}
void _smManagerTipcCleanup(void) {
tipcClose(&g_smManagerTipcSrv);
}
TipcService* smManagerTipcGetServiceSession(void) {
return &g_smManagerTipcSrv;
}
Result smManagerTipcRegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size) {
return tipcDispatchIn(&g_smManagerTipcSrv, 0, pid,
.buffer_attrs = {
SfBufferAttr_In | SfBufferAttr_HipcMapAlias,
SfBufferAttr_In | SfBufferAttr_HipcMapAlias,
},
.buffers = {
{ acid_sac, acid_sac_size },
{ aci0_sac, aci0_sac_size },
},
);
}
Result smManagerTipcUnregisterProcess(u64 pid) {
return tipcDispatchIn(&g_smManagerTipcSrv, 1, pid);
} }