From e17c0019c5cf9faaa8f23e3904342c8c4faf0980 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 28 Dec 2017 23:30:21 -0500 Subject: kernel: Add basic support for Domain object. --- src/core/hle/kernel/domain.cpp | 44 ++++++++++++++++++++++++++++++++++++++ src/core/hle/kernel/domain.h | 45 +++++++++++++++++++++++++++++++++++++++ src/core/hle/kernel/kernel.h | 17 +++++++++++++++ src/core/hle/kernel/sync_object.h | 8 +++---- 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 src/core/hle/kernel/domain.cpp create mode 100644 src/core/hle/kernel/domain.h (limited to 'src/core/hle') 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> Domain::Create(std::string name) { + SharedPtr domain(new Domain); + domain->name = std::move(name); + return MakeResult(std::move(domain)); +} + +ResultVal> 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) { + 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 +#include +#include +#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> CreateFromSession(const Session& server); + + ResultCode SendSyncRequest(SharedPtr thread) override; + + /// The name of this domain (optional) + std::string name; + + std::vector> request_handlers; + +private: + Domain() = default; + ~Domain() override = default; + + static ResultVal> 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) = 0; }; -- cgit v1.2.3