From a774ff935c3b34298db17465e6053a703ed7d782 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 25 Jan 2024 21:26:44 -0500 Subject: [PATCH] cmif_serialization: support non-domain sessions on domain servers --- src/core/hle/service/cmif_serialization.h | 65 +++++++++++------------ 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h index 84b736155b..9eb10e8168 100644 --- a/src/core/hle/service/cmif_serialization.h +++ b/src/core/hle/service/cmif_serialization.h @@ -97,20 +97,20 @@ constexpr RequestLayout GetDomainReplyOutLayout() { }; } -template -constexpr RequestLayout GetReplyInLayout() { - return Domain ? GetDomainReplyInLayout() : GetNonDomainReplyInLayout(); +template +constexpr RequestLayout GetReplyInLayout(bool is_domain) { + return is_domain ? GetDomainReplyInLayout() : GetNonDomainReplyInLayout(); } -template -constexpr RequestLayout GetReplyOutLayout() { - return Domain ? GetDomainReplyOutLayout() : GetNonDomainReplyOutLayout(); +template +constexpr RequestLayout GetReplyOutLayout(bool is_domain) { + return is_domain ? GetDomainReplyOutLayout() : GetNonDomainReplyOutLayout(); } using OutTemporaryBuffers = std::array, 3>; -template -void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) { +template +void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) { if constexpr (ArgIndex >= std::tuple_size_v) { return; } else { @@ -134,25 +134,25 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& std::memcpy(&std::get(args), raw_data + ArgOffset, ArgSize); } - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::InInterface) { constexpr size_t ArgAlign = alignof(u32); constexpr size_t ArgSize = sizeof(u32); constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); constexpr size_t ArgEnd = ArgOffset + ArgSize; - static_assert(Domain); + ASSERT(is_domain); ASSERT(ctx.GetDomainMessageHeader().input_object_count > 0); u32 value{}; std::memcpy(&value, raw_data + ArgOffset, ArgSize); std::get(args) = ctx.GetDomainHandler(value - 1); - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::InCopyHandle) { std::get(args) = ctx.GetObjectFromHandle(ctx.GetCopyHandle(HandleIndex)).GetPointerUnsafe(); - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::InLargeData) { constexpr size_t BufferSize = sizeof(ArgType); @@ -172,7 +172,7 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& std::memcpy(&std::get(args), buffer.data(), std::min(BufferSize, buffer.size())); - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::InBuffer) { using ElementType = typename ArgType::Type; @@ -193,14 +193,14 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& std::get(args) = std::span(ptr, size); - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutLargeData) { constexpr size_t BufferSize = sizeof(ArgType); // Clear the existing data. std::memset(&std::get(args), 0, BufferSize); - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutBuffer) { using ElementType = typename ArgType::Type; @@ -217,15 +217,15 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& std::get(args) = std::span(ptr, size); - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else { - return ReadInArgument(args, raw_data, ctx, temp); + return ReadInArgument(is_domain, args, raw_data, ctx, temp); } } } -template -void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) { +template +void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) { if constexpr (ArgIndex >= std::tuple_size_v) { return; } else { @@ -243,23 +243,23 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, std::memcpy(raw_data + ArgOffset, &std::get(args), ArgSize); - return WriteOutArgument(args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutInterface) { - if constexpr (Domain) { + if (is_domain) { ctx.AddDomainObject(std::get(args)); } else { ctx.AddMoveInterface(std::get(args)); } - return WriteOutArgument(args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutCopyHandle) { ctx.AddCopyObject(std::get(args)); - return WriteOutArgument(args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutMoveHandle) { ctx.AddMoveObject(std::get(args)); - return WriteOutArgument(args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutLargeData) { constexpr size_t BufferSize = sizeof(ArgType); @@ -272,7 +272,7 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, ctx.WriteBufferC(&std::get(args), BufferSize, OutBufferIndex); } - return WriteOutArgument(args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutBuffer) { auto& buffer = temp[OutBufferIndex]; const size_t size = buffer.size(); @@ -287,9 +287,9 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, } } - return WriteOutArgument( args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else { - return WriteOutArgument(args, raw_data, ctx, temp); + return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } } } @@ -297,11 +297,10 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, template void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) { // Verify domain state. - if constexpr (Domain) { - ASSERT_MSG(ctx.GetManager()->IsDomain(), "Domain reply used on non-domain session"); - } else { + if constexpr (!Domain) { ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Non-domain reply used on domain session"); } + const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false; using MethodArguments = std::tuple...>; @@ -310,7 +309,7 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) { // Read inputs. const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2; - ReadInArgument(call_arguments, reinterpret_cast(ctx.CommandBuffer() + offset_plus_command_id), ctx, buffers); + ReadInArgument(is_domain, call_arguments, reinterpret_cast(ctx.CommandBuffer() + offset_plus_command_id), ctx, buffers); // Call. const auto Callable = [&](CallArgs&... args) { @@ -319,12 +318,12 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) { const Result res = std::apply(Callable, call_arguments); // Write result. - constexpr RequestLayout layout = GetReplyOutLayout(); + const RequestLayout layout = GetReplyOutLayout(is_domain); IPC::ResponseBuilder rb{ctx, 2 + Common::DivCeil(layout.cmif_raw_data_size, sizeof(u32)), layout.copy_handle_count, layout.move_handle_count + layout.domain_interface_count}; rb.Push(res); // Write out arguments. - WriteOutArgument(call_arguments, reinterpret_cast(ctx.CommandBuffer() + rb.GetCurrentOffset()), ctx, buffers); + WriteOutArgument(is_domain, call_arguments, reinterpret_cast(ctx.CommandBuffer() + rb.GetCurrentOffset()), ctx, buffers); } // clang-format on