summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/sm/sm_controller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/sm/sm_controller.cpp')
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp
new file mode 100644
index 000000000..b5fbc4569
--- /dev/null
+++ b/src/core/hle/service/sm/sm_controller.cpp
@@ -0,0 +1,80 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/k_client_port.h"
+#include "core/hle/kernel/k_client_session.h"
+#include "core/hle/kernel/k_port.h"
+#include "core/hle/kernel/k_scoped_resource_reservation.h"
+#include "core/hle/kernel/k_server_port.h"
+#include "core/hle/kernel/k_server_session.h"
+#include "core/hle/kernel/k_session.h"
+#include "core/hle/service/sm/sm_controller.h"
+
+namespace Service::SM {
+
+void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
+ ASSERT_MSG(!ctx.Session()->IsDomain(), "Session is already a domain");
+ LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
+ ctx.Session()->ConvertToDomain();
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push<u32>(1); // Converted sessions start with 1 request handler
+}
+
+void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service, "called");
+
+ auto& parent_session = *ctx.Session()->GetParent();
+ auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort();
+ auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
+
+ // Create a session.
+ Kernel::KClientSession* session{};
+ const ResultCode result = parent_port.CreateSession(std::addressof(session), session_manager);
+ if (result.IsError()) {
+ LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+ }
+
+ // We succeeded.
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
+ rb.Push(ResultSuccess);
+ rb.PushMoveObjects(session);
+}
+
+void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service, "called");
+
+ CloneCurrentObject(ctx);
+}
+
+void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push<u16>(0x8000);
+}
+
+// https://switchbrew.org/wiki/IPC_Marshalling
+Controller::Controller(Core::System& system_) : ServiceFramework{system_, "IpcController"} {
+ static const FunctionInfo functions[] = {
+ {0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"},
+ {1, nullptr, "CopyFromCurrentDomain"},
+ {2, &Controller::CloneCurrentObject, "CloneCurrentObject"},
+ {3, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"},
+ {4, &Controller::CloneCurrentObjectEx, "CloneCurrentObjectEx"},
+ };
+ RegisterHandlers(functions);
+}
+
+Controller::~Controller() = default;
+
+} // namespace Service::SM