summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/kernel/domain.cpp44
-rw-r--r--src/core/hle/kernel/domain.h45
-rw-r--r--src/core/hle/kernel/kernel.h17
-rw-r--r--src/core/hle/kernel/sync_object.h8
5 files changed, 112 insertions, 4 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 29abb703f..1e023303d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -29,6 +29,7 @@ set(SRCS
hle/kernel/address_arbiter.cpp
hle/kernel/client_port.cpp
hle/kernel/client_session.cpp
+ hle/kernel/domain.cpp
hle/kernel/event.cpp
hle/kernel/handle_table.cpp
hle/kernel/hle_ipc.cpp
@@ -118,6 +119,7 @@ set(HEADERS
hle/kernel/address_arbiter.h
hle/kernel/client_port.h
hle/kernel/client_session.h
+ hle/kernel/domain.h
hle/kernel/errors.h
hle/kernel/event.h
hle/kernel/handle_table.h
diff --git a/src/core/hle/kernel/domain.cpp b/src/core/hle/kernel/domain.cpp
new file mode 100644
index 000000000..19ba861f5
--- /dev/null
+++ b/src/core/hle/kernel/domain.cpp
@@ -0,0 +1,44 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/kernel/client_port.h"
+#include "core/hle/kernel/domain.h"
+#include "core/hle/kernel/handle_table.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/process.h"
+#include "core/hle/kernel/session.h"
+#include "core/hle/kernel/thread.h"
+
+namespace Kernel {
+
+ResultVal<SharedPtr<Domain>> Domain::Create(std::string name) {
+ SharedPtr<Domain> domain(new Domain);
+ domain->name = std::move(name);
+ return MakeResult(std::move(domain));
+}
+
+ResultVal<SharedPtr<Domain>> Domain::CreateFromSession(const Session& session) {
+ auto res = Create(session.port->GetName() + "_Domain");
+ auto& domain = res.Unwrap();
+ domain->request_handlers.push_back(std::move(session.server->hle_handler));
+ Kernel::g_handle_table.ConvertSessionToDomain(session, domain);
+ return res;
+}
+
+ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) {
+ Kernel::HLERequestContext context(this);
+ u32* cmd_buf = (u32*)Memory::GetPointer(Kernel::GetCurrentThread()->GetTLSAddress());
+ context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process,
+ Kernel::g_handle_table);
+
+ auto& domain_message_header = context.GetDomainMessageHeader();
+ if (domain_message_header) {
+ // If there is a DomainMessageHeader, then this is CommandType "Request"
+ const u32 object_id{context.GetDomainMessageHeader()->object_id};
+ return request_handlers[object_id - 1]->HandleSyncRequest(context);
+ }
+ return request_handlers.front()->HandleSyncRequest(context);
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/domain.h b/src/core/hle/kernel/domain.h
new file mode 100644
index 000000000..74f7ad0dd
--- /dev/null
+++ b/src/core/hle/kernel/domain.h
@@ -0,0 +1,45 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+#include "core/hle/kernel/sync_object.h"
+#include "core/hle/result.h"
+
+namespace Kernel {
+
+class Session;
+class SessionRequestHandler;
+
+class Domain final : public SyncObject {
+public:
+ std::string GetTypeName() const override {
+ return "Domain";
+ }
+
+ static const HandleType HANDLE_TYPE = HandleType::Domain;
+ HandleType GetHandleType() const override {
+ return HANDLE_TYPE;
+ }
+
+ static ResultVal<SharedPtr<Domain>> CreateFromSession(const Session& server);
+
+ ResultCode SendSyncRequest(SharedPtr<Thread> thread) override;
+
+ /// The name of this domain (optional)
+ std::string name;
+
+ std::vector<std::shared_ptr<SessionRequestHandler>> request_handlers;
+
+private:
+ Domain() = default;
+ ~Domain() override = default;
+
+ static ResultVal<SharedPtr<Domain>> Create(std::string name = "Unknown");
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 73fab3981..e43055bfd 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -31,6 +31,7 @@ enum class HandleType : u32 {
ServerPort,
ClientSession,
ServerSession,
+ Domain,
};
enum {
@@ -83,12 +84,28 @@ public:
case HandleType::CodeSet:
case HandleType::ClientPort:
case HandleType::ClientSession:
+ case HandleType::Domain:
return false;
}
UNREACHABLE();
}
+ /**
+ * Check if svcSendSyncRequest can be called on the object
+ * @return True svcSendSyncRequest can be called on the object, otherwise false
+ */
+ bool IsSyncable() const {
+ switch (GetHandleType()) {
+ case HandleType::ClientSession:
+ case HandleType::Domain:
+ return true;
+ }
+
+ UNREACHABLE();
+ }
+
+
public:
static unsigned int next_object_id;
diff --git a/src/core/hle/kernel/sync_object.h b/src/core/hle/kernel/sync_object.h
index ce2835ca4..5d715226e 100644
--- a/src/core/hle/kernel/sync_object.h
+++ b/src/core/hle/kernel/sync_object.h
@@ -16,10 +16,10 @@ class Thread;
class SyncObject : public Object {
public:
/**
- * Handle a sync request from the emulated application.
- * @param thread Thread that initiated the request.
- * @returns ResultCode from the operation.
- */
+ * Handle a sync request from the emulated application.
+ * @param thread Thread that initiated the request.
+ * @returns ResultCode from the operation.
+ */
virtual ResultCode SendSyncRequest(SharedPtr<Thread> thread) = 0;
};