diff options
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r-- | src/core/hle/kernel/domain.cpp | 44 | ||||
-rw-r--r-- | src/core/hle/kernel/domain.h | 45 | ||||
-rw-r--r-- | src/core/hle/kernel/kernel.h | 17 | ||||
-rw-r--r-- | src/core/hle/kernel/sync_object.h | 8 |
4 files changed, 110 insertions, 4 deletions
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; }; |