aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service/sm/sm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/sm/sm.cpp')
-rw-r--r--src/core/hle/service/sm/sm.cpp205
1 files changed, 38 insertions, 167 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 5c196b3218..c75c5437df 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -18,16 +18,7 @@
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/sm/sm.h"
-#include "common/assert.h"
-#include "common/logging.h"
-#include "core/core.h"
-#include "core/hle/kernel/k_client_port.h"
-#include "core/hle/kernel/k_port.h"
-#include "core/hle/kernel/k_scoped_resource_reservation.h"
-#include "core/hle/kernel/k_server_session.h"
-#include "core/hle/kernel/k_session.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/server_manager.h"
+#include "core/hle/service/sm/sm_controller.h"
namespace Service::SM {
@@ -36,116 +27,6 @@ constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4);
constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6);
constexpr Result ResultNotRegistered(ErrorModule::SM, 7);
-class Controller final : public ServiceFramework<Controller> {
-public:
- // https://switchbrew.org/wiki/IPC_Marshalling
- explicit Controller(Core::System& system_) : ServiceFramework{system_, "IpcController"} {}
- ~Controller() override = default;
-
- void ConvertCurrentObjectToDomain(HLERequestContext& ctx) {
- ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Session is already a domain");
- LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
- ctx.GetManager()->ConvertToDomainOnRequestEnd();
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push<u32>(1); // Converted sessions start with 1 request handler
- }
-
- void CloneCurrentObject(HLERequestContext& ctx) {
- LOG_DEBUG(Service, "called");
-
- auto session_manager = ctx.GetManager();
-
- // FIXME: this is duplicated from the SVC, it should just call it instead
- // once this is a proper process
-
- // Reserve a new session from the process resource limit.
- Kernel::KScopedResourceReservation session_reservation(system.Kernel(), Kernel::GetCurrentProcessPointer(kernel), Kernel::LimitableResource::SessionCountMax);
- ASSERT(session_reservation.Succeeded());
-
- // Create the session.
- Kernel::KSession* session = Kernel::KSession::Create(kernel);
- ASSERT(session != nullptr);
-
- // Initialize the session.
- session->Initialize(kernel, nullptr, 0);
-
- // Commit the session reservation.
- session_reservation.Commit();
-
- // Register the session.
- Kernel::KSession::Register(kernel, session);
-
- // Register with server manager.
- session_manager->GetServerManager().RegisterSession(&session->GetServerSession(),
- session_manager);
-
- // We succeeded.
- IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
- rb.Push(ResultSuccess);
- rb.PushMoveObjects(ctx, session->GetClientSession());
- }
-
- void CloneCurrentObjectEx(HLERequestContext& ctx) {
- LOG_DEBUG(Service, "called");
-
- CloneCurrentObject(ctx);
- }
-
- void QueryPointerBufferSize(HLERequestContext& ctx) {
- LOG_DEBUG(Service, "called");
-
- auto* process = Kernel::GetCurrentProcessPointer(kernel);
- ASSERT(process != nullptr);
-
- u32 buffer_size = process->GetPointerBufferSize();
- if (buffer_size > (std::numeric_limits<u16>::max)()) {
- LOG_WARNING(Service, "Pointer buffer size exceeds u16 max, clamping");
- buffer_size = (std::numeric_limits<u16>::max)();
- }
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push<u16>(static_cast<u16>(buffer_size));
- }
-
- void SetPointerBufferSize(HLERequestContext& ctx) {
- LOG_DEBUG(Service, "called");
-
- auto* process = Kernel::GetCurrentProcessPointer(kernel);
- ASSERT(process != nullptr);
-
- IPC::RequestParser rp{ctx};
-
- u32 requested_size = rp.PopRaw<u32>();
-
- if (requested_size > (std::numeric_limits<u16>::max)()) {
- LOG_WARNING(Service, "Requested pointer buffer size too large, clamping to 0xFFFF");
- requested_size = (std::numeric_limits<u16>::max)();
- }
-
- process->SetPointerBufferSize(requested_size);
-
- LOG_INFO(Service, "Pointer buffer size dynamically updated to {:#x} bytes by process", requested_size);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
- }
-
- std::optional<FunctionInfoBase> FindRequest(u32 key) override {
- return HandlerTableGenerateWithFind(key, functions);
- }
- static constexpr auto functions = CreateStaticMap(
- FunctionInfo{0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"},
- FunctionInfo{1, nullptr, "CopyFromCurrentDomain"},
- FunctionInfo{2, &Controller::CloneCurrentObject, "CloneCurrentObject"},
- FunctionInfo{3, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"},
- FunctionInfo{4, &Controller::CloneCurrentObjectEx, "CloneCurrentObjectEx"},
- FunctionInfo{5, &Controller::SetPointerBufferSize, "SetPointerBufferSize"} //TODO: where does this come from
- );
-};
-
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
controller_interface = std::make_unique<Controller>(kernel.System());
}
@@ -231,51 +112,6 @@ Result ServiceManager::GetServicePort(Kernel::KClientPort** out_client_port,
return ResultSuccess;
}
-/// Interface to "sm:" service
-class SM final : public ServiceFramework<SM> {
-public:
- explicit SM(ServiceManager& service_manager_, Core::System& system_);
- ~SM() override;
-
-private:
- void Initialize(HLERequestContext& ctx);
- void GetServiceCmif(HLERequestContext& ctx);
- void GetServiceTipc(HLERequestContext& ctx);
- void RegisterServiceCmif(HLERequestContext& ctx);
- void RegisterServiceTipc(HLERequestContext& ctx);
- void UnregisterService(HLERequestContext& ctx);
- void AtmosphereHasService(HLERequestContext& ctx);
-
- Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
- void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count, bool is_light);
-
- // TODO: We reuse function list for both TIPC and non-TIPC
- std::optional<FunctionInfoBase> FindRequest(u32 key) override {
- return HandlerTableGenerateWithFind(key, functions);
- }
- std::optional<FunctionInfoBase> FindRequestTipc(u32 key) override {
- return HandlerTableGenerateWithFind(key, functions);
- }
- static constexpr auto functions = CreateStaticMap(
- FunctionInfo{0, &SM::Initialize, "Initialize"},
- FunctionInfo{1, &SM::GetServiceTipc, "GetService"},
- FunctionInfo{2, &SM::RegisterServiceTipc, "RegisterService"},
- FunctionInfo{3, &SM::UnregisterService, "UnregisterService"},
- FunctionInfo{4, nullptr, "DetachClient"},
- FunctionInfo{65000, nullptr, "AtmosphereInstallMitm"},
- FunctionInfo{65001, nullptr, "AtmosphereUninstallMitm"},
- FunctionInfo{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
- FunctionInfo{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
- FunctionInfo{65004, nullptr, "AtmosphereHasMitm"},
- FunctionInfo{65005, nullptr, "AtmosphereWaitMitm"},
- FunctionInfo{65006, nullptr, "AtmosphereDeclareFutureMitm"},
- FunctionInfo{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
- FunctionInfo{65101, nullptr, "AtmosphereWaitService"}
- );
-
- ServiceManager& service_manager;
-};
-
/**
* SM::Initialize service function
* Inputs:
@@ -358,7 +194,7 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques
// Create a new session.
Kernel::KClientSession* session{};
- if (const auto result = client_port->CreateSession(system.Kernel(), &session); result.IsError()) {
+ if (const auto result = client_port->CreateSession(kernel, &session); result.IsError()) {
LOG_ERROR(Service_SM, "called service={} -> error {:#08x}", name, result.raw);
return result;
}
@@ -429,7 +265,42 @@ void SM::AtmosphereHasService(HLERequestContext& ctx) {
SM::SM(ServiceManager& service_manager_, Core::System& system_)
: ServiceFramework{system_, "sm:", 64}
, service_manager{service_manager_}
-{}
+ , kernel{system_.Kernel()}
+{
+ RegisterHandlers({
+ {0, &SM::Initialize, "Initialize"},
+ {1, &SM::GetServiceCmif, "GetService"},
+ {2, &SM::RegisterServiceCmif, "RegisterService"},
+ {3, &SM::UnregisterService, "UnregisterService"},
+ {4, nullptr, "DetachClient"},
+ // TODO: are these non-TIPC as well?
+ {65000, nullptr, "AtmosphereInstallMitm"},
+ {65001, nullptr, "AtmosphereUninstallMitm"},
+ {65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
+ {65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
+ {65004, nullptr, "AtmosphereHasMitm"},
+ {65005, nullptr, "AtmosphereWaitMitm"},
+ {65006, nullptr, "AtmosphereDeclareFutureMitm"},
+ {65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
+ {65101, nullptr, "AtmosphereWaitService"},
+ });
+ RegisterHandlersTipc({
+ {0, &SM::Initialize, "Initialize"},
+ {1, &SM::GetServiceTipc, "GetService"},
+ {2, &SM::RegisterServiceTipc, "RegisterService"},
+ {3, &SM::UnregisterService, "UnregisterService"},
+ {4, nullptr, "DetachClient"},
+ {65000, nullptr, "AtmosphereInstallMitm"},
+ {65001, nullptr, "AtmosphereUninstallMitm"},
+ {65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
+ {65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
+ {65004, nullptr, "AtmosphereHasMitm"},
+ {65005, nullptr, "AtmosphereWaitMitm"},
+ {65006, nullptr, "AtmosphereDeclareFutureMitm"},
+ {65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
+ {65101, nullptr, "AtmosphereWaitService"},
+ });
+}
SM::~SM() = default;