diff options
32 files changed, 311 insertions, 452 deletions
| diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 242c2db0c..70547c8b2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -36,8 +36,6 @@ add_library(core STATIC      hle/kernel/client_session.h      hle/kernel/condition_variable.cpp      hle/kernel/condition_variable.h -    hle/kernel/domain.cpp -    hle/kernel/domain.h      hle/kernel/errors.h      hle/kernel/event.cpp      hle/kernel/event.h @@ -67,7 +65,6 @@ add_library(core STATIC      hle/kernel/svc.cpp      hle/kernel/svc.h      hle/kernel/svc_wrap.h -    hle/kernel/sync_object.h      hle/kernel/thread.cpp      hle/kernel/thread.h      hle/kernel/timer.cpp diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index ab479b49b..6066d8a18 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -11,7 +11,6 @@  #include "core/hle/ipc.h"  #include "core/hle/kernel/client_port.h"  #include "core/hle/kernel/client_session.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/kernel.h" @@ -31,11 +30,6 @@ public:      RequestHelperBase(Kernel::HLERequestContext& context)          : context(&context), cmdbuf(context.CommandBuffer()) {} -    void ValidateHeader() { -        // DEBUG_ASSERT_MSG(index == TotalSize(), "Operations do not match the header (cmd 0x%x)", -        //                 header.raw); -    } -      void Skip(unsigned size_in_words, bool set_to_null) {          if (set_to_null)              memset(cmdbuf + index, 0, size_in_words * sizeof(u32)); @@ -60,14 +54,30 @@ public:      }  }; -class RequestBuilder : public RequestHelperBase { +class ResponseBuilder : public RequestHelperBase {  public: -    RequestBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {} +    ResponseBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {} + +    u32 normal_params_size{}; +    u32 num_handles_to_copy{}; +    u32 num_objects_to_move{}; ///< Domain objects or move handles, context dependent +    std::ptrdiff_t datapayload_index{}; + +    /// Flags used for customizing the behavior of ResponseBuilder +    enum class Flags : u32 { +        None = 0, +        /// Uses move handles to move objects in the response, even when in a domain. This is +        /// required when PushMoveObjects is used. +        AlwaysMoveHandles = 1, +    }; + +    ResponseBuilder(Kernel::HLERequestContext& context, u32 normal_params_size, +                    u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0, +                    Flags flags = Flags::None) + +        : RequestHelperBase(context), normal_params_size(normal_params_size), +          num_handles_to_copy(num_handles_to_copy), num_objects_to_move(num_objects_to_move) { -    RequestBuilder(Kernel::HLERequestContext& context, unsigned normal_params_size, -                   u32 num_handles_to_copy = 0, u32 num_handles_to_move = 0, -                   u32 num_domain_objects = 0) -        : RequestHelperBase(context) {          memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);          context.ClearIncomingObjects(); @@ -77,12 +87,19 @@ public:          // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory          // padding.          u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; -        if (context.IsDomain()) { -            raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects; + +        u32 num_handles_to_move{}; +        u32 num_domain_objects{}; +        const bool always_move_handles{ +            (static_cast<u32>(flags) & static_cast<u32>(Flags::AlwaysMoveHandles)) != 0}; +        if (!context.Session()->IsDomain() || always_move_handles) { +            num_handles_to_move = num_objects_to_move;          } else { -            // If we're not in a domain, turn the domain object parameters into move handles. -            num_handles_to_move += num_domain_objects; -            num_domain_objects = 0; +            num_domain_objects = num_objects_to_move; +        } + +        if (context.Session()->IsDomain()) { +            raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;          }          header.data_size.Assign(raw_data_size); @@ -101,7 +118,7 @@ public:          AlignWithPadding(); -        if (context.IsDomain()) { +        if (context.Session()->IsDomain()) {              IPC::DomainMessageHeader domain_header{};              domain_header.num_objects = num_domain_objects;              PushRaw(domain_header); @@ -110,12 +127,13 @@ public:          IPC::DataPayloadHeader data_payload_header{};          data_payload_header.magic = Common::MakeMagic('S', 'F', 'C', 'O');          PushRaw(data_payload_header); + +        datapayload_index = index;      } -    template <class T, class... Args> -    void PushIpcInterface(Args&&... args) { -        auto iface = std::make_shared<T>(std::forward<Args>(args)...); -        if (context->IsDomain()) { +    template <class T> +    void PushIpcInterface(std::shared_ptr<T> iface) { +        if (context->Session()->IsDomain()) {              context->AddDomainObject(std::move(iface));          } else {              auto sessions = Kernel::ServerSession::CreateSessionPair(iface->GetServiceName()); @@ -126,8 +144,26 @@ public:          }      } +    template <class T, class... Args> +    void PushIpcInterface(Args&&... args) { +        PushIpcInterface<T>(std::make_shared<T>(std::forward<Args>(args)...)); +    } + +    void ValidateHeader() { +        const size_t num_domain_objects = context->NumDomainObjects(); +        const size_t num_move_objects = context->NumMoveObjects(); +        ASSERT_MSG(!num_domain_objects || !num_move_objects, +                   "cannot move normal handles and domain objects"); +        ASSERT_MSG((index - datapayload_index) == normal_params_size, +                   "normal_params_size value is incorrect"); +        ASSERT_MSG((num_domain_objects + num_move_objects) == num_objects_to_move, +                   "num_objects_to_move value is incorrect"); +        ASSERT_MSG(context->NumCopyObjects() == num_handles_to_copy, +                   "num_handles_to_copy value is incorrect"); +    } +      // Validate on destruction, as there shouldn't be any case where we don't want it -    ~RequestBuilder() { +    ~ResponseBuilder() {          ValidateHeader();      } @@ -155,52 +191,52 @@ public:  /// Push ///  template <> -inline void RequestBuilder::Push(u32 value) { +inline void ResponseBuilder::Push(u32 value) {      cmdbuf[index++] = value;  }  template <typename T> -void RequestBuilder::PushRaw(const T& value) { +void ResponseBuilder::PushRaw(const T& value) {      std::memcpy(cmdbuf + index, &value, sizeof(T));      index += (sizeof(T) + 3) / 4; // round up to word length  }  template <> -inline void RequestBuilder::Push(ResultCode value) { +inline void ResponseBuilder::Push(ResultCode value) {      // Result codes are actually 64-bit in the IPC buffer, but only the high part is discarded.      Push(value.raw);      Push<u32>(0);  }  template <> -inline void RequestBuilder::Push(u8 value) { +inline void ResponseBuilder::Push(u8 value) {      PushRaw(value);  }  template <> -inline void RequestBuilder::Push(u16 value) { +inline void ResponseBuilder::Push(u16 value) {      PushRaw(value);  }  template <> -inline void RequestBuilder::Push(u64 value) { +inline void ResponseBuilder::Push(u64 value) {      Push(static_cast<u32>(value));      Push(static_cast<u32>(value >> 32));  }  template <> -inline void RequestBuilder::Push(bool value) { +inline void ResponseBuilder::Push(bool value) {      Push(static_cast<u8>(value));  }  template <typename First, typename... Other> -void RequestBuilder::Push(const First& first_value, const Other&... other_values) { +void ResponseBuilder::Push(const First& first_value, const Other&... other_values) {      Push(first_value);      Push(other_values...);  }  template <typename... O> -inline void RequestBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) { +inline void ResponseBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) {      auto objects = {pointers...};      for (auto& object : objects) {          context->AddCopyObject(std::move(object)); @@ -208,7 +244,7 @@ inline void RequestBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) {  }  template <typename... O> -inline void RequestBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) { +inline void ResponseBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) {      auto objects = {pointers...};      for (auto& object : objects) {          context->AddMoveObject(std::move(object)); @@ -227,15 +263,10 @@ public:          Skip(CommandIdSize, false);      } -    RequestBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy, -                               u32 num_handles_to_move, u32 num_domain_objects, -                               bool validate_header = true) { -        if (validate_header) { -            ValidateHeader(); -        } - -        return {*context, normal_params_size, num_handles_to_copy, num_handles_to_move, -                num_domain_objects}; +    ResponseBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy, +                                u32 num_handles_to_move, +                                ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) { +        return {*context, normal_params_size, num_handles_to_copy, num_handles_to_move, flags};      }      template <typename T> diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index d6ab4f893..2258f95bc 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -7,7 +7,7 @@  #include <memory>  #include <string>  #include "common/common_types.h" -#include "core/hle/kernel/sync_object.h" +#include "core/hle/kernel/kernel.h"  #include "core/hle/result.h"  namespace Kernel { @@ -16,7 +16,7 @@ class ServerSession;  class Session;  class Thread; -class ClientSession final : public SyncObject { +class ClientSession final : public Object {  public:      friend class ServerSession; @@ -33,7 +33,7 @@ public:          return HANDLE_TYPE;      } -    ResultCode SendSyncRequest(SharedPtr<Thread> thread) override; +    ResultCode SendSyncRequest(SharedPtr<Thread> thread);      std::string name; ///< Name of client port (optional) diff --git a/src/core/hle/kernel/domain.cpp b/src/core/hle/kernel/domain.cpp deleted file mode 100644 index 5035e9c08..000000000 --- a/src/core/hle/kernel/domain.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/logging/log.h" -#include "core/hle/ipc_helpers.h" -#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}; -        switch (domain_message_header->command) { -        case IPC::DomainMessageHeader::CommandType::SendMessage: -            return request_handlers[object_id - 1]->HandleSyncRequest(context); - -        case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { -            LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id); - -            request_handlers[object_id - 1] = nullptr; - -            IPC::RequestBuilder rb{context, 2}; -            rb.Push(RESULT_SUCCESS); - -            return RESULT_SUCCESS; -        } -        } - -        LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value()); -        UNIMPLEMENTED(); -    } -    return request_handlers.front()->HandleSyncRequest(context); -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/domain.h b/src/core/hle/kernel/domain.h deleted file mode 100644 index 3fec3b0b2..000000000 --- a/src/core/hle/kernel/domain.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2018 yuzu emulator team -// 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/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 74d3d0514..3beb55753 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -5,12 +5,10 @@  #include <utility>  #include "common/assert.h"  #include "common/logging/log.h" -#include "core/hle/kernel/client_session.h"  #include "core/hle/kernel/errors.h"  #include "core/hle/kernel/handle_table.h"  #include "core/hle/kernel/kernel.h"  #include "core/hle/kernel/process.h" -#include "core/hle/kernel/session.h"  #include "core/hle/kernel/thread.h"  namespace Kernel { @@ -55,14 +53,6 @@ ResultVal<Handle> HandleTable::Duplicate(Handle handle) {      return Create(std::move(object));  } -void HandleTable::ConvertSessionToDomain(const Session& session, SharedPtr<Object> domain) { -    for (auto& object : objects) { -        if (DynamicObjectCast<ClientSession>(object) == session.client) { -            object = domain; -        } -    } -} -  ResultCode HandleTable::Close(Handle handle) {      if (!IsValid(handle))          return ERR_INVALID_HANDLE; diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index 935cc22b5..ba968c666 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -17,8 +17,6 @@ enum KernelHandle : Handle {      CurrentProcess = 0xFFFF8001,  }; -class Session; -  /**   * This class allows the creation of Handles, which are references to objects that can be tested   * for validity and looked up. Here they are used to pass references to kernel objects to/from the @@ -62,11 +60,6 @@ public:      ResultVal<Handle> Duplicate(Handle handle);      /** -     * Convert all handles of the specified Session to the specified Domain. -     */ -    void ConvertSessionToDomain(const Session& session, SharedPtr<Object> domain); - -    /**       * Closes a handle, removing it from the table and decreasing the object's ref-count.       * @return `RESULT_SUCCESS` or one of the following errors:       *           - `ERR_INVALID_HANDLE`: an invalid handle was passed in. diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index ecf32c18a..db104e8a2 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -7,7 +7,6 @@  #include "common/common_funcs.h"  #include "common/common_types.h"  #include "core/hle/ipc_helpers.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/kernel.h" @@ -26,10 +25,6 @@ void SessionRequestHandler::ClientDisconnected(SharedPtr<ServerSession> server_s      boost::range::remove_erase(connected_sessions, server_session);  } -HLERequestContext::HLERequestContext(SharedPtr<Kernel::Domain> domain) : domain(std::move(domain)) { -    cmd_buf[0] = 0; -} -  HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)      : server_session(std::move(server_session)) {      cmd_buf[0] = 0; @@ -87,7 +82,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {      // Padding to align to 16 bytes      rp.AlignWithPadding(); -    if (IsDomain() && (command_header->type == IPC::CommandType::Request || !incoming)) { +    if (Session()->IsDomain() && (command_header->type == IPC::CommandType::Request || !incoming)) {          // If this is an incoming message, only CommandType "Request" has a domain header          // All outgoing domain messages have the domain header          domain_message_header = @@ -200,12 +195,12 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P      // TODO(Subv): Translate the X/A/B/W buffers. -    if (IsDomain()) { +    if (Session()->IsDomain()) {          ASSERT(domain_message_header->num_objects == domain_objects.size());          // Write the domain objects to the command buffer, these go after the raw untranslated data.          // TODO(Subv): This completely ignores C buffers.          size_t domain_offset = size - domain_message_header->num_objects; -        auto& request_handlers = domain->request_handlers; +        auto& request_handlers = server_session->domain_request_handlers;          for (auto& object : domain_objects) {              request_handlers.emplace_back(object); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 80fa48d7f..da8335b35 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -86,7 +86,6 @@ protected:   */  class HLERequestContext {  public: -    HLERequestContext(SharedPtr<Kernel::Domain> domain);      HLERequestContext(SharedPtr<Kernel::ServerSession> session);      ~HLERequestContext(); @@ -96,17 +95,10 @@ public:      }      /** -     * Returns the domain through which this request was made. -     */ -    const SharedPtr<Kernel::Domain>& Domain() const { -        return domain; -    } - -    /**       * Returns the session through which this request was made. This can be used as a map key to       * access per-client data on services.       */ -    const SharedPtr<Kernel::ServerSession>& ServerSession() const { +    const SharedPtr<Kernel::ServerSession>& Session() const {          return server_session;      } @@ -151,10 +143,6 @@ public:          return domain_message_header;      } -    bool IsDomain() const { -        return domain != nullptr; -    } -      template <typename T>      SharedPtr<T> GetCopyObject(size_t index) {          ASSERT(index < copy_objects.size()); @@ -187,9 +175,20 @@ public:          domain_objects.clear();      } +    size_t NumMoveObjects() const { +        return move_objects.size(); +    } + +    size_t NumCopyObjects() const { +        return copy_objects.size(); +    } + +    size_t NumDomainObjects() const { +        return domain_objects.size(); +    } +  private:      std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; -    SharedPtr<Kernel::Domain> domain;      SharedPtr<Kernel::ServerSession> server_session;      // TODO(yuriks): Check common usage of this and optimize size accordingly      boost::container::small_vector<SharedPtr<Object>, 8> move_objects; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 4d9549e45..c77e58f3c 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -31,7 +31,6 @@ enum class HandleType : u32 {      ServerPort,      ClientSession,      ServerSession, -    Domain,  };  enum { @@ -84,27 +83,12 @@ 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/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 09d02a691..54481f7f1 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -4,6 +4,7 @@  #include <tuple> +#include "core/hle/ipc_helpers.h"  #include "core/hle/kernel/client_port.h"  #include "core/hle/kernel/client_session.h"  #include "core/hle/kernel/handle_table.h" @@ -61,6 +62,38 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {      // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or      // similar. +    Kernel::HLERequestContext context(this); +    u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); +    context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process, +                                              Kernel::g_handle_table); + +    // If the session has been converted to a domain, handle the doomain request +    if (IsDomain()) { +        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}; +            switch (domain_message_header->command) { +            case IPC::DomainMessageHeader::CommandType::SendMessage: +                return domain_request_handlers[object_id - 1]->HandleSyncRequest(context); + +            case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { +                LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id); + +                domain_request_handlers[object_id - 1] = nullptr; + +                IPC::ResponseBuilder rb{context, 2}; +                rb.Push(RESULT_SUCCESS); +                return RESULT_SUCCESS; +            } +            } + +            LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value()); +            ASSERT(false); +        } +        // If there is no domain header, the regular session handler is used +    } +      // If this ServerSession has an associated HLE handler, forward the request to it.      ResultCode result{RESULT_SUCCESS};      if (hle_handler != nullptr) { @@ -69,11 +102,6 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {          if (translate_result.IsError())              return translate_result; -        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); -          result = hle_handler->HandleSyncRequest(context);      } else {          // Add the thread to the list of threads that have issued a sync request with this @@ -84,6 +112,15 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {      // If this ServerSession does not have an HLE implementation, just wake up the threads waiting      // on it.      WakeupAllWaitingThreads(); + +    // Handle scenario when ConvertToDomain command was issued, as we must do the conversion at the +    // end of the command such that only commands following this one are handled as domains +    if (convert_to_domain) { +        ASSERT_MSG(domain_request_handlers.empty(), "already a domain"); +        domain_request_handlers = {hle_handler}; +        convert_to_domain = false; +    } +      return result;  } diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 6ff4ef8c1..144692106 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -79,7 +79,10 @@ public:      std::string name;                ///< The name of this session (optional)      std::shared_ptr<Session> parent; ///< The parent session, which links to the client endpoint.      std::shared_ptr<SessionRequestHandler> -        hle_handler; ///< This session's HLE request handler (optional) +        hle_handler; ///< This session's HLE request handler (applicable when not a domain) + +    /// This is the list of domain request handlers (after conversion to a domain) +    std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;      /// List of threads that are pending a response after a sync request. This list is processed in      /// a LIFO manner, thus, the last request will be dispatched first. @@ -91,6 +94,16 @@ public:      /// TODO(Subv): Find a better name for this.      SharedPtr<Thread> currently_handling; +    /// Returns true if the session has been converted to a domain, otherwise False +    bool IsDomain() const { +        return !domain_request_handlers.empty(); +    } + +    /// Converts the session to a domain at the end of the current command +    void ConvertToDomain() { +        convert_to_domain = true; +    } +  private:      ServerSession();      ~ServerSession() override; @@ -102,6 +115,9 @@ private:       * @return The created server session       */      static ResultVal<SharedPtr<ServerSession>> Create(std::string name = "Unknown"); + +    /// When set to True, converts the session to a domain at the end of the command +    bool convert_to_domain{};  };  /** diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 516309036..4c0276cf0 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -20,7 +20,6 @@  #include "core/hle/kernel/shared_memory.h"  #include "core/hle/kernel/svc.h"  #include "core/hle/kernel/svc_wrap.h" -#include "core/hle/kernel/sync_object.h"  #include "core/hle/kernel/thread.h"  #include "core/hle/lock.h"  #include "core/hle/result.h" @@ -87,7 +86,7 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address  /// Makes a blocking IPC call to an OS service.  static ResultCode SendSyncRequest(Handle handle) { -    SharedPtr<SyncObject> session = g_handle_table.Get<SyncObject>(handle); +    SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle);      if (!session) {          LOG_ERROR(Kernel_SVC, "called with invalid handle=0x%08X", handle);          return ERR_INVALID_HANDLE; diff --git a/src/core/hle/kernel/sync_object.h b/src/core/hle/kernel/sync_object.h deleted file mode 100644 index f2befa2ea..000000000 --- a/src/core/hle/kernel/sync_object.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include <boost/smart_ptr/intrusive_ptr.hpp> -#include "core/hle/kernel/kernel.h" -#include "core/hle/result.h" - -namespace Kernel { - -class Thread; - -/// Class that represents a Kernel object that svcSendSyncRequest can be called on -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. -     */ -    virtual ResultCode SendSyncRequest(SharedPtr<Thread> thread) = 0; -}; - -// Specialization of DynamicObjectCast for SyncObjects -template <> -inline SharedPtr<SyncObject> DynamicObjectCast<SyncObject>(SharedPtr<Object> object) { -    if (object != nullptr && object->IsSyncable()) { -        return boost::static_pointer_cast<SyncObject>(std::move(object)); -    } -    return nullptr; -} - -} // namespace Kernel diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index 7f0192fd3..67f05aad4 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp @@ -22,7 +22,7 @@ private:      void GetBase(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service, "(STUBBED) called");          ProfileBase profile_base{}; -        IPC::RequestBuilder rb{ctx, 16}; +        IPC::ResponseBuilder rb{ctx, 16};          rb.Push(RESULT_SUCCESS);          rb.PushRaw(profile_base);      } @@ -40,7 +40,7 @@ public:  private:      void CheckAvailability(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service, "(STUBBED) called"); -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push(true); // TODO: Check when this is supposed to return true and when not      } @@ -48,13 +48,13 @@ private:  void ACC_U0::GetUserExistence(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push(true); // TODO: Check when this is supposed to return true and when not  }  void ACC_U0::GetProfile(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IProfile>();      LOG_DEBUG(Service, "called"); @@ -62,12 +62,12 @@ void ACC_U0::GetProfile(Kernel::HLERequestContext& ctx) {  void ACC_U0::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2}; +    IPC::ResponseBuilder rb{ctx, 2};      rb.Push(RESULT_SUCCESS);  }  void ACC_U0::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IManagerForApplication>();      LOG_DEBUG(Service, "called"); diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index 7d16b45f3..15b7701e0 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -25,14 +25,14 @@ public:  private:      void GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service, "(STUBBED) called"); -        IPC::RequestBuilder rb{ctx, 4}; +        IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS);          rb.Push<u64>(0);      }      void AcquireForegroundRights(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service, "(STUBBED) called"); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      }  }; @@ -86,14 +86,14 @@ private:          };          auto flags = rp.PopRaw<FocusHandlingModeParams>(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called");      }      void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called"); @@ -104,7 +104,7 @@ private:          bool flag = rp.Pop<bool>(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag)); @@ -115,7 +115,7 @@ private:          bool flag = rp.Pop<bool>(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag)); @@ -128,21 +128,21 @@ private:          bool enabled = rp.Pop<bool>(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));      }      void LockExit(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called");      }      void UnlockExit(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called"); @@ -154,7 +154,7 @@ private:          u64 display_id = nvflinger->OpenDisplay("Default");          u64 layer_id = nvflinger->CreateLayer(display_id); -        IPC::RequestBuilder rb{ctx, 4}; +        IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS);          rb.Push(layer_id); @@ -193,7 +193,7 @@ private:      void GetEventHandle(Kernel::HLERequestContext& ctx) {          event->Signal(); -        IPC::RequestBuilder rb{ctx, 2, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 1};          rb.Push(RESULT_SUCCESS);          rb.PushCopyObjects(event); @@ -201,7 +201,7 @@ private:      }      void ReceiveMessage(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push<u32>(15); @@ -209,7 +209,7 @@ private:      }      void GetCurrentFocusState(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push(static_cast<u8>(FocusState::InFocus)); @@ -217,7 +217,7 @@ private:      }      void GetOperationMode(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push(static_cast<u8>(OperationMode::Handheld)); @@ -225,7 +225,7 @@ private:      }      void GetPerformanceMode(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld)); @@ -250,7 +250,7 @@ private:      std::vector<u8> buffer;      void GetSize(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 4}; +        IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS);          rb.Push(static_cast<u64>(buffer.size())); @@ -269,7 +269,7 @@ private:          Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size()); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS); @@ -291,7 +291,7 @@ private:      std::vector<u8> buffer;      void Open(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<AM::IStorageAccessor>(buffer); @@ -328,7 +328,7 @@ private:          std::vector<u8> buffer(data, data + sizeof(data)); -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<AM::IStorage>(buffer); @@ -343,34 +343,34 @@ private:          IPC::RequestParser rp{ctx};          u32 result = rp.Pop<u32>(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);      }      void GetDesiredLanguage(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 4}; +        IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS);          rb.Push<u64>(SystemLanguage::English);          LOG_WARNING(Service, "(STUBBED) called");      }      void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called");      }      void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called");      }      void NotifyRunning(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push<u8>(0); // Unknown, seems to be ignored by official processes @@ -402,56 +402,56 @@ public:  private:      void GetAudioController(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<IAudioController>();          LOG_DEBUG(Service, "called");      }      void GetDisplayController(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<IDisplayController>();          LOG_DEBUG(Service, "called");      }      void GetDebugFunctions(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<IDebugFunctions>();          LOG_DEBUG(Service, "called");      }      void GetWindowController(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<IWindowController>();          LOG_DEBUG(Service, "called");      }      void GetSelfController(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<ISelfController>(nvflinger);          LOG_DEBUG(Service, "called");      }      void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<ICommonStateGetter>();          LOG_DEBUG(Service, "called");      }      void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<ILibraryAppletCreator>();          LOG_DEBUG(Service, "called");      }      void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS);          rb.PushIpcInterface<IApplicationFunctions>();          LOG_DEBUG(Service, "called"); @@ -461,7 +461,7 @@ private:  };  void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IApplicationProxy>(nvflinger);      LOG_DEBUG(Service, "called"); diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index bf7e12288..c4b1723c5 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -30,7 +30,7 @@ private:          auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());          u32 config = rp.Pop<u32>(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode), config); @@ -41,7 +41,7 @@ private:          auto mode = static_cast<PerformanceMode>(rp.Pop<u32>()); -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push<u32>(0); // Performance configuration @@ -58,7 +58,7 @@ APM::APM() : ServiceFramework("apm") {  }  void APM::OpenSession(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<ISession>();  } diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index df04d636e..f56ba2ea1 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -23,7 +23,7 @@ constexpr u64 audio_ticks{static_cast<u64>(BASE_CLOCK_RATE / 500)};  class IAudioOut final : public ServiceFramework<IAudioOut> {  public: -    IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(Stopped) { +    IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) {          static const FunctionInfo functions[] = {              {0x0, nullptr, "GetAudioOutState"},              {0x1, &IAudioOut::StartAudioOut, "StartAudioOut"}, @@ -58,29 +58,29 @@ private:      void StartAudioOut(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service_Audio, "(STUBBED) called"); -        // start audio -        audio_out_state = Started; +        // Start audio +        audio_out_state = AudioState::Started; -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      }      void StopAudioOut(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service_Audio, "(STUBBED) called"); -        // stop audio -        audio_out_state = Stopped; +        // Stop audio +        audio_out_state = AudioState::Stopped;          queue_keys.clear(); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      }      void RegisterBufferEvent(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service_Audio, "(STUBBED) called"); -        IPC::RequestBuilder rb{ctx, 2, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 1};          rb.Push(RESULT_SUCCESS);          rb.PushCopyObjects(buffer_event);      } @@ -89,11 +89,10 @@ private:          LOG_WARNING(Service_Audio, "(STUBBED) called");          IPC::RequestParser rp{ctx}; -        u64 key = rp.Pop<u64>(); - +        const u64 key{rp.Pop<u64>()};          queue_keys.insert(queue_keys.begin(), key); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      } @@ -102,11 +101,10 @@ private:          const auto& buffer = ctx.BufferDescriptorB()[0]; -        // TODO(st4rk): this is how libtransistor currently implements the -        // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the APP and this address +        // TODO(st4rk): This is how libtransistor currently implements the +        // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address          // is used to know which buffer should be filled with data and send again to the service          // through AppendAudioOutBuffer. Check if this is the proper way to do it. -          u64 key{0};          if (queue_keys.size()) { @@ -116,7 +114,7 @@ private:          Memory::WriteBlock(buffer.Address(), &key, sizeof(u64)); -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          // TODO(st4rk): This might be the total of released buffers, needs to be verified on          // hardware @@ -124,8 +122,7 @@ private:      }      void UpdateAudioBuffersCallback() { - -        if (audio_out_state != Started) { +        if (audio_out_state != AudioState::Started) {              return;          } @@ -136,7 +133,7 @@ private:          buffer_event->Signal();      } -    enum AudioState : u32 { +    enum class AudioState : u32 {          Started,          Stopped,      }; @@ -148,10 +145,10 @@ private:      /// This is the evend handle used to check if the audio buffer was released      Kernel::SharedPtr<Kernel::Event> buffer_event; -    /// (st4rk): this is just a temporary workaround for the future implementation. Libtransistor +    /// (st4rk): This is just a temporary workaround for the future implementation. Libtransistor      /// uses the key as an address in the App, so we need to return when the      /// GetReleasedAudioOutBuffer_1 is called, otherwise we'll run in problems, because -    /// libtransistor uses the key returned as an pointer; +    /// libtransistor uses the key returned as an pointer.      std::vector<u64> queue_keys;      AudioState audio_out_state; @@ -166,14 +163,12 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {      Memory::WriteBlock(buffer.Address(), &audio_interface[0], audio_interface.size()); -    IPC::RequestBuilder rb = rp.MakeBuilder(3, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);      rb.Push(RESULT_SUCCESS); -    // TODO(st4rk): we're currently returning only one audio interface -    // (stringlist size) -    // however, it's highly possible to have more than one interface (despite that -    // libtransistor -    // requires only one). +    // TODO(st4rk): We're currently returning only one audio interface (stringlist size). However, +    // it's highly possible to have more than one interface (despite that libtransistor requires +    // only one).      rb.Push<u32>(1);  } @@ -184,20 +179,13 @@ void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) {          audio_out_interface = std::make_shared<IAudioOut>();      } -    auto sessions = Kernel::ServerSession::CreateSessionPair(audio_out_interface->GetServiceName()); -    auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); -    auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); -    audio_out_interface->ClientConnected(server); -    LOG_DEBUG(Service, "called, initialized IAudioOut -> session=%u", client->GetObjectId()); -    IPC::RequestBuilder rb{ctx, 6, 0, 1}; - +    IPC::ResponseBuilder rb{ctx, 6, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(sample_rate);      rb.Push<u32>(audio_channels);      rb.Push<u32>(static_cast<u32>(PcmFormat::Int16)); -    // this field is unknown -    rb.Push<u32>(0); -    rb.PushMoveObjects(std::move(client)); +    rb.Push<u32>(0); // This field is unknown +    rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface);  }  AudOutU::AudOutU() : ServiceFramework("audout:u") { diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index ef1915e5a..71b82393e 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -40,12 +40,12 @@ private:          // Error checking          ASSERT_MSG(length == descriptor.Size(), "unexpected size difference");          if (length < 0) { -            IPC::RequestBuilder rb{ctx, 2}; +            IPC::ResponseBuilder rb{ctx, 2};              rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidLength));              return;          }          if (offset < 0) { -            IPC::RequestBuilder rb{ctx, 2}; +            IPC::ResponseBuilder rb{ctx, 2};              rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidOffset));              return;          } @@ -54,7 +54,7 @@ private:          std::vector<u8> output(length);          ResultVal<size_t> res = backend->Read(offset, length, output.data());          if (res.Failed()) { -            IPC::RequestBuilder rb{ctx, 2}; +            IPC::ResponseBuilder rb{ctx, 2};              rb.Push(res.Code());              return;          } @@ -62,7 +62,7 @@ private:          // Write the data to memory          Memory::WriteBlock(descriptor.Address(), output.data(), descriptor.Size()); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      }  }; @@ -91,14 +91,14 @@ void FSP_SRV::TryLoadRomFS() {  void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service_FS, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2}; +    IPC::ResponseBuilder rb{ctx, 2};      rb.Push(RESULT_SUCCESS);  }  void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service_FS, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 4}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(5);  } @@ -110,7 +110,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {      if (!romfs) {          // TODO (bunnei): Find the right error code to use here          LOG_CRITICAL(Service_FS, "no file system interface available!"); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(ResultCode(-1));          return;      } @@ -119,12 +119,12 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {      auto storage = romfs->OpenFile({}, {});      if (storage.Failed()) {          LOG_CRITICAL(Service_FS, "no storage interface available!"); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(storage.Code());          return;      } -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap()));  } diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ae60cc7b4..326e0a4ab 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -46,7 +46,7 @@ public:  private:      void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { -        IPC::RequestBuilder rb{ctx, 2, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 1};          rb.Push(RESULT_SUCCESS);          rb.PushCopyObjects(shared_mem);          LOG_DEBUG(Service, "called"); @@ -169,19 +169,10 @@ private:              applet_resource = std::make_shared<IAppletResource>();          } -        // TODO(Subv): Verify if this should return the interface as a domain object when called -        // from within a domain. - -        auto sessions = Kernel::ServerSession::CreateSessionPair(applet_resource->GetServiceName()); -        auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); -        auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); -        applet_resource->ClientConnected(server); - -        LOG_DEBUG(Service, "called, initialized IAppletResource -> session=%u", -                  client->GetObjectId()); -        IPC::RequestBuilder rb{ctx, 2, 0, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 0, 1};          rb.Push(RESULT_SUCCESS); -        rb.PushMoveObjects(std::move(client)); +        rb.PushIpcInterface<IAppletResource>(applet_resource); +        LOG_DEBUG(Service, "called");      }  }; diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index b505cdcaf..2843e0e40 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -65,7 +65,7 @@ private:       */      void Log(Kernel::HLERequestContext& ctx) {          // This function only succeeds - Get that out of the way -        IPC::RequestBuilder rb{ctx, 1}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          // Read MessageHeader, despite not doing anything with it right now @@ -130,7 +130,7 @@ private:          }          output += message; -        LOG_DEBUG(Debug_Emulated, "%s", output.c_str()); +        LOG_INFO(Debug_Emulated, "%s", output.c_str());      }  }; @@ -146,21 +146,11 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {   *      0: ResultCode   */  void LM::Initialize(Kernel::HLERequestContext& ctx) { -    // TODO(Subv): Verify if this should return the interface as a domain object when called from -    // within a domain. - -    auto logger = std::make_shared<Logger>(); -    auto sessions = Kernel::ServerSession::CreateSessionPair(logger->GetServiceName()); -    auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); -    auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); -    logger->ClientConnected(server); - -    LOG_DEBUG(Service_SM, "called, initialized logger -> session=%u", client->GetObjectId()); -    IPC::RequestBuilder rb{ctx, 2, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); -    rb.PushMoveObjects(std::move(client)); +    rb.PushIpcInterface<Logger>(); -    LOG_INFO(Service_SM, "called"); +    LOG_DEBUG(Service, "called");  }  LM::LM() : ServiceFramework("lm") { diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index 0181d1b4f..85ecde6d2 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -18,7 +18,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {      std::string device_name = Memory::ReadCString(buffer.Address(), buffer.Size());      u32 fd = nvdrv->Open(device_name); -    IPC::RequestBuilder rb{ctx, 4}; +    IPC::ResponseBuilder rb{ctx, 4};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(fd);      rb.Push<u32>(0); @@ -43,7 +43,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {      Memory::WriteBlock(output_buffer.Address(), output.data(), output_buffer.Size()); -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push(nv_result);  } @@ -56,13 +56,13 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) {      auto result = nvdrv->Close(fd); -    IPC::RequestBuilder rb{ctx, 2}; +    IPC::ResponseBuilder rb{ctx, 2};      rb.Push(result);  }  void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(0);  } @@ -72,7 +72,7 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) {      pid = rp.Pop<u64>();      LOG_INFO(Service, "called, pid=0x%lx", pid); -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(0);  } diff --git a/src/core/hle/service/pctl/pctl_a.cpp b/src/core/hle/service/pctl/pctl_a.cpp index 7978aecb8..c808b764b 100644 --- a/src/core/hle/service/pctl/pctl_a.cpp +++ b/src/core/hle/service/pctl/pctl_a.cpp @@ -15,7 +15,7 @@ public:  };  void PCTL_A::GetService(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IParentalControlService>();      LOG_DEBUG(Service, "called"); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 1b8565351..294351b76 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -132,7 +132,7 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {  ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& context) {      switch (context.GetCommandType()) {      case IPC::CommandType::Close: { -        IPC::RequestBuilder rb{context, 1}; +        IPC::ResponseBuilder rb{context, 2};          rb.Push(RESULT_SUCCESS);          return ResultCode(ErrorModule::HIPC, ErrorDescription::RemoteProcessDead);      } diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 3715acd74..e0e157fe1 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -19,7 +19,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {      Memory::WriteBlock(output_buffer.Address(), lang_codes.data(), lang_codes.size()); -    IPC::RequestBuilder rb{ctx, 4}; +    IPC::ResponseBuilder rb{ctx, 4};      rb.Push(RESULT_SUCCESS);      rb.Push(static_cast<u64>(lang_codes.size())); diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 7b1c8ee37..a81ff9f49 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -4,30 +4,26 @@  #include "common/logging/log.h"  #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/domain.h"  #include "core/hle/service/sm/controller.h"  namespace Service {  namespace SM {  void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { -    auto domain = Kernel::Domain::CreateFromSession(*ctx.ServerSession()->parent).Unwrap(); +    ASSERT_MSG(!ctx.Session()->IsDomain(), "session is alread a domain"); +    ctx.Session()->ConvertToDomain(); -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS); -    rb.Push(static_cast<u32>(domain->request_handlers.size())); +    rb.Push<u32>(1); // Converted sessions start with 1 request handler -    LOG_DEBUG(Service, "called, domain=%d", domain->GetObjectId()); +    LOG_DEBUG(Service, "called, server_session=%d", ctx.Session()->GetObjectId());  }  void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};      rb.Push(RESULT_SUCCESS); -    // TODO(Subv): Check if this is correct -    if (ctx.IsDomain()) -        rb.PushMoveObjects(ctx.Domain()); -    else -        rb.PushMoveObjects(ctx.ServerSession()); +    rb.PushMoveObjects(ctx.Session());      LOG_DEBUG(Service, "called");  } @@ -39,7 +35,7 @@ void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) {  }  void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(0x500); diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index c4078f02f..73aa013e3 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -83,7 +83,7 @@ std::shared_ptr<ServiceManager> g_service_manager;   *      0: ResultCode   */  void SM::Initialize(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 1}; +    IPC::ResponseBuilder rb{ctx, 2};      rb.Push(RESULT_SUCCESS);      LOG_DEBUG(Service_SM, "called");  } @@ -99,7 +99,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {      auto client_port = service_manager->GetServicePort(name);      if (client_port.Failed()) { -        IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); +        IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);          rb.Push(client_port.Code());          LOG_ERROR(Service_SM, "called service=%s -> error 0x%08X", name.c_str(),                    client_port.Code().raw); @@ -112,7 +112,8 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {      if (session.Succeeded()) {          LOG_DEBUG(Service_SM, "called service=%s -> session=%u", name.c_str(),                    (*session)->GetObjectId()); -        IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 1, 0); +        IPC::ResponseBuilder rb = +            rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles);          rb.Push(session.Code());          rb.PushMoveObjects(std::move(session).Unwrap());      } diff --git a/src/core/hle/service/sockets/bsd_u.cpp b/src/core/hle/service/sockets/bsd_u.cpp index a819acc96..4fd960bd8 100644 --- a/src/core/hle/service/sockets/bsd_u.cpp +++ b/src/core/hle/service/sockets/bsd_u.cpp @@ -11,7 +11,7 @@ namespace Sockets {  void BSD_U::RegisterClient(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 3}; +    IPC::ResponseBuilder rb{ctx, 3};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(0); // bsd errno @@ -28,7 +28,7 @@ void BSD_U::Socket(Kernel::HLERequestContext& ctx) {      u32 fd = next_fd++; -    IPC::RequestBuilder rb{ctx, 4}; +    IPC::ResponseBuilder rb{ctx, 4};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(fd); @@ -38,7 +38,7 @@ void BSD_U::Socket(Kernel::HLERequestContext& ctx) {  void BSD_U::Connect(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 4}; +    IPC::ResponseBuilder rb{ctx, 4};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(0); // ret @@ -48,7 +48,7 @@ void BSD_U::Connect(Kernel::HLERequestContext& ctx) {  void BSD_U::SendTo(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 4}; +    IPC::ResponseBuilder rb{ctx, 4};      rb.Push(RESULT_SUCCESS);      rb.Push<u32>(0); // ret diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 448ef8544..96ccee50d 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -19,7 +19,7 @@ public:      ISystemClock() : ServiceFramework("ISystemClock") {          static const FunctionInfo functions[] = {              {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, -        }; +            {2, &ISystemClock::GetSystemClockContext, "GetSystemClockContext"}};          RegisterHandlers(functions);      } @@ -28,10 +28,18 @@ private:          const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(                                         std::chrono::system_clock::now().time_since_epoch())                                         .count()}; -        IPC::RequestBuilder rb{ctx, 4}; +        LOG_DEBUG(Service, "called"); +        IPC::ResponseBuilder rb{ctx, 4};          rb.Push(RESULT_SUCCESS);          rb.Push<u64>(time_since_epoch); -        LOG_DEBUG(Service, "called"); +    } + +    void GetSystemClockContext(Kernel::HLERequestContext& ctx) { +        LOG_WARNING(Service, "(STUBBED) called"); +        SystemClockContext system_clock_ontext{}; +        IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; +        rb.Push(RESULT_SUCCESS); +        rb.PushRaw(system_clock_ontext);      }  }; @@ -55,14 +63,14 @@ private:      void GetDeviceLocationName(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service, "(STUBBED) called");          LocationName location_name{}; -        IPC::RequestBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; +        IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2};          rb.Push(RESULT_SUCCESS);          rb.PushRaw(location_name);      }      void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) {          LOG_WARNING(Service, "(STUBBED) called"); -        IPC::RequestBuilder rb{ctx, 3}; +        IPC::ResponseBuilder rb{ctx, 3};          rb.Push(RESULT_SUCCESS);          rb.Push<u32>(0);      } @@ -75,7 +83,7 @@ private:          CalendarTime calendar_time{2018, 1, 1, 0, 0, 0};          CalendarAdditionalInfo additional_info{}; -        IPC::RequestBuilder rb{ctx, 10}; +        IPC::ResponseBuilder rb{ctx, 10};          rb.Push(RESULT_SUCCESS);          rb.PushRaw(calendar_time);          rb.PushRaw(additional_info); @@ -83,49 +91,28 @@ private:  };  void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { -    // TODO(Subv): Verify if this should return the interface as a domain object when called from -    // within a domain. -    auto system_clock = std::make_shared<ISystemClock>(); -    auto sessions = Kernel::ServerSession::CreateSessionPair(system_clock->GetServiceName()); -    auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); -    auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); -    system_clock->ClientConnected(server); -    LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u", client->GetObjectId()); -    IPC::RequestBuilder rb{ctx, 2, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); -    rb.PushMoveObjects(std::move(client)); +    rb.PushIpcInterface<ISystemClock>(); +    LOG_DEBUG(Service, "called");  }  void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { -    // TODO(Subv): Verify if this should return the interface as a domain object when called from -    // within a domain. -    auto system_clock = std::make_shared<ISystemClock>(); -    auto sessions = Kernel::ServerSession::CreateSessionPair(system_clock->GetServiceName()); -    auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); -    auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); -    system_clock->ClientConnected(server); -    LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u", client->GetObjectId()); -    IPC::RequestBuilder rb{ctx, 2, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); -    rb.PushMoveObjects(std::move(client)); +    rb.PushIpcInterface<ISystemClock>(); +    LOG_DEBUG(Service, "called");  }  void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { -    // TODO(Subv): Verify if this should return the interface as a domain object when called from -    // within a domain. -    auto steady_clock = std::make_shared<ISteadyClock>(); -    auto sessions = Kernel::ServerSession::CreateSessionPair(steady_clock->GetServiceName()); -    auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); -    auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); -    steady_clock->ClientConnected(server); -    LOG_DEBUG(Service, "called, initialized ISteadyClock -> session=%u", client->GetObjectId()); -    IPC::RequestBuilder rb{ctx, 2, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); -    rb.PushMoveObjects(std::move(client)); +    rb.PushIpcInterface<ISteadyClock>(); +    LOG_DEBUG(Service, "called");  }  void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<ITimeZoneService>();      LOG_DEBUG(Service, "called"); diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 399f474d6..cd936a50c 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -33,6 +33,13 @@ struct CalendarAdditionalInfo {  static_assert(sizeof(CalendarAdditionalInfo) == 0x18,                "CalendarAdditionalInfo structure has incorrect size"); +// TODO(bunnei) RE this structure +struct SystemClockContext { +    INSERT_PADDING_BYTES(0x20); +}; +static_assert(sizeof(SystemClockContext) == 0x20, +              "SystemClockContext structure has incorrect size"); +  class Module final {  public:      class Interface : public ServiceFramework<Interface> { diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 6576f81db..3b993f36c 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -486,7 +486,7 @@ private:          }          LOG_WARNING(Service, "(STUBBED) called"); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      } @@ -497,7 +497,7 @@ private:          u32 type = rp.Pop<u32>();          LOG_WARNING(Service, "(STUBBED) called id=%u, addval=%08X, type=%08X", id, addval, type); -        IPC::RequestBuilder rb{ctx, 2}; +        IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);      } @@ -511,7 +511,7 @@ private:          // TODO(Subv): Find out what this actually is.          LOG_WARNING(Service, "(STUBBED) called id=%u, unknown=%08X", id, unknown); -        IPC::RequestBuilder rb{ctx, 2, 1}; +        IPC::ResponseBuilder rb{ctx, 2, 1};          rb.Push(RESULT_SUCCESS);          rb.PushCopyObjects(buffer_queue->GetNativeHandle());      } @@ -537,7 +537,7 @@ private:          u64 layer_id = rp.Pop<u64>();          u64 z_value = rp.Pop<u64>(); -        IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); +        IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);          rb.Push(RESULT_SUCCESS);      }  }; @@ -562,7 +562,7 @@ private:          IPC::RequestParser rp{ctx};          u64 display = rp.Pop<u64>(); -        IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); +        IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);          rb.Push(RESULT_SUCCESS);      } @@ -576,7 +576,7 @@ private:          u64 layer_id = nv_flinger->CreateLayer(display); -        IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); +        IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);          rb.Push(RESULT_SUCCESS);          rb.Push(layer_id);      } @@ -587,7 +587,7 @@ private:          u32 stack = rp.Pop<u32>();          u64 layer_id = rp.Pop<u64>(); -        IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); +        IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);          rb.Push(RESULT_SUCCESS);      } @@ -597,7 +597,7 @@ private:  void IApplicationDisplayService::GetRelayService(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IHOSBinderDriver>(nv_flinger);  } @@ -605,7 +605,7 @@ void IApplicationDisplayService::GetRelayService(Kernel::HLERequestContext& ctx)  void IApplicationDisplayService::GetSystemDisplayService(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<ISystemDisplayService>();  } @@ -613,7 +613,7 @@ void IApplicationDisplayService::GetSystemDisplayService(Kernel::HLERequestConte  void IApplicationDisplayService::GetManagerDisplayService(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IManagerDisplayService>(nv_flinger);  } @@ -622,7 +622,7 @@ void IApplicationDisplayService::GetIndirectDisplayTransactionService(      Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IHOSBinderDriver>(nv_flinger);  } @@ -637,7 +637,7 @@ void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) {      ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet"); -    IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);      rb.Push(RESULT_SUCCESS);      rb.Push<u64>(nv_flinger->OpenDisplay(name));  } @@ -647,7 +647,7 @@ void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      u64 display_id = rp.Pop<u64>(); -    IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);      rb.Push(RESULT_SUCCESS);  } @@ -671,7 +671,7 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) {      auto data = native_window.Serialize();      Memory::WriteBlock(buffer.Address(), data.data(), data.size()); -    IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);      rb.Push(RESULT_SUCCESS);      rb.Push<u64>(data.size());  } @@ -694,7 +694,7 @@ void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx      auto data = native_window.Serialize();      Memory::WriteBlock(buffer.Address(), data.data(), data.size()); -    IPC::RequestBuilder rb = rp.MakeBuilder(6, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0);      rb.Push(RESULT_SUCCESS);      rb.Push(layer_id);      rb.Push<u64>(data.size()); @@ -706,7 +706,7 @@ void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ct      IPC::RequestParser rp{ctx};      u64 layer_id = rp.Pop<u64>(); -    IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);      rb.Push(RESULT_SUCCESS);  } @@ -716,7 +716,7 @@ void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext&      u32 scaling_mode = rp.Pop<u32>();      u64 unknown = rp.Pop<u64>(); -    IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);      rb.Push(RESULT_SUCCESS);  } @@ -727,7 +727,7 @@ void IApplicationDisplayService::GetDisplayVsyncEvent(Kernel::HLERequestContext&      auto vsync_event = nv_flinger->GetVsyncEvent(display_id); -    IPC::RequestBuilder rb = rp.MakeBuilder(2, 1, 0, 0); +    IPC::ResponseBuilder rb = rp.MakeBuilder(2, 1, 0);      rb.Push(RESULT_SUCCESS);      rb.PushCopyObjects(vsync_event);  } diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp index 20b24658e..bb440cadb 100644 --- a/src/core/hle/service/vi/vi_m.cpp +++ b/src/core/hle/service/vi/vi_m.cpp @@ -13,7 +13,8 @@ namespace VI {  void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) {      LOG_WARNING(Service, "(STUBBED) called"); -    IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; +    IPC::ResponseBuilder rb{ctx, 2, 0, 1}; +    rb.Push(RESULT_SUCCESS);      rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger);  } | 
