summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Liam2024-01-25 21:26:44 -0500
committerGravatar Liam2024-01-25 22:18:42 -0500
commita774ff935c3b34298db17465e6053a703ed7d782 (patch)
tree98fd82a2dc3544e4d927ea9c95c5cdaf85dc52e2 /src
parentcmif_types: improve ergonomics of types (diff)
downloadyuzu-a774ff935c3b34298db17465e6053a703ed7d782.tar.gz
yuzu-a774ff935c3b34298db17465e6053a703ed7d782.tar.xz
yuzu-a774ff935c3b34298db17465e6053a703ed7d782.zip
cmif_serialization: support non-domain sessions on domain servers
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/cmif_serialization.h65
1 files changed, 32 insertions, 33 deletions
diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h
index 84b736155..9eb10e816 100644
--- a/src/core/hle/service/cmif_serialization.h
+++ b/src/core/hle/service/cmif_serialization.h
@@ -97,20 +97,20 @@ constexpr RequestLayout GetDomainReplyOutLayout() {
97 }; 97 };
98} 98}
99 99
100template <bool Domain, typename MethodArguments> 100template <typename MethodArguments>
101constexpr RequestLayout GetReplyInLayout() { 101constexpr RequestLayout GetReplyInLayout(bool is_domain) {
102 return Domain ? GetDomainReplyInLayout<MethodArguments>() : GetNonDomainReplyInLayout<MethodArguments>(); 102 return is_domain ? GetDomainReplyInLayout<MethodArguments>() : GetNonDomainReplyInLayout<MethodArguments>();
103} 103}
104 104
105template <bool Domain, typename MethodArguments> 105template <typename MethodArguments>
106constexpr RequestLayout GetReplyOutLayout() { 106constexpr RequestLayout GetReplyOutLayout(bool is_domain) {
107 return Domain ? GetDomainReplyOutLayout<MethodArguments>() : GetNonDomainReplyOutLayout<MethodArguments>(); 107 return is_domain ? GetDomainReplyOutLayout<MethodArguments>() : GetNonDomainReplyOutLayout<MethodArguments>();
108} 108}
109 109
110using OutTemporaryBuffers = std::array<Common::ScratchBuffer<u8>, 3>; 110using OutTemporaryBuffers = std::array<Common::ScratchBuffer<u8>, 3>;
111 111
112template <bool Domain, typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t HandleIndex = 0, size_t InBufferIndex = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0> 112template <typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t HandleIndex = 0, size_t InBufferIndex = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0>
113void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) { 113void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) {
114 if constexpr (ArgIndex >= std::tuple_size_v<CallArguments>) { 114 if constexpr (ArgIndex >= std::tuple_size_v<CallArguments>) {
115 return; 115 return;
116 } else { 116 } else {
@@ -134,25 +134,25 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
134 std::memcpy(&std::get<ArgIndex>(args), raw_data + ArgOffset, ArgSize); 134 std::memcpy(&std::get<ArgIndex>(args), raw_data + ArgOffset, ArgSize);
135 } 135 }
136 136
137 return ReadInArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, false, ArgIndex + 1>(args, raw_data, ctx, temp); 137 return ReadInArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, false, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
138 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InInterface) { 138 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InInterface) {
139 constexpr size_t ArgAlign = alignof(u32); 139 constexpr size_t ArgAlign = alignof(u32);
140 constexpr size_t ArgSize = sizeof(u32); 140 constexpr size_t ArgSize = sizeof(u32);
141 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); 141 constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
142 constexpr size_t ArgEnd = ArgOffset + ArgSize; 142 constexpr size_t ArgEnd = ArgOffset + ArgSize;
143 143
144 static_assert(Domain); 144 ASSERT(is_domain);
145 ASSERT(ctx.GetDomainMessageHeader().input_object_count > 0); 145 ASSERT(ctx.GetDomainMessageHeader().input_object_count > 0);
146 146
147 u32 value{}; 147 u32 value{};
148 std::memcpy(&value, raw_data + ArgOffset, ArgSize); 148 std::memcpy(&value, raw_data + ArgOffset, ArgSize);
149 std::get<ArgIndex>(args) = ctx.GetDomainHandler<ArgType::Type>(value - 1); 149 std::get<ArgIndex>(args) = ctx.GetDomainHandler<ArgType::Type>(value - 1);
150 150
151 return ReadInArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp); 151 return ReadInArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, true, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
152 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InCopyHandle) { 152 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InCopyHandle) {
153 std::get<ArgIndex>(args) = ctx.GetObjectFromHandle<typename ArgType::Type>(ctx.GetCopyHandle(HandleIndex)).GetPointerUnsafe(); 153 std::get<ArgIndex>(args) = ctx.GetObjectFromHandle<typename ArgType::Type>(ctx.GetCopyHandle(HandleIndex)).GetPointerUnsafe();
154 154
155 return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 155 return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
156 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) { 156 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) {
157 constexpr size_t BufferSize = sizeof(ArgType); 157 constexpr size_t BufferSize = sizeof(ArgType);
158 158
@@ -172,7 +172,7 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
172 172
173 std::memcpy(&std::get<ArgIndex>(args), buffer.data(), std::min(BufferSize, buffer.size())); 173 std::memcpy(&std::get<ArgIndex>(args), buffer.data(), std::min(BufferSize, buffer.size()));
174 174
175 return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 175 return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
176 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InBuffer) { 176 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InBuffer) {
177 using ElementType = typename ArgType::Type; 177 using ElementType = typename ArgType::Type;
178 178
@@ -193,14 +193,14 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
193 193
194 std::get<ArgIndex>(args) = std::span(ptr, size); 194 std::get<ArgIndex>(args) = std::span(ptr, size);
195 195
196 return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 196 return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
197 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) { 197 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
198 constexpr size_t BufferSize = sizeof(ArgType); 198 constexpr size_t BufferSize = sizeof(ArgType);
199 199
200 // Clear the existing data. 200 // Clear the existing data.
201 std::memset(&std::get<ArgIndex>(args), 0, BufferSize); 201 std::memset(&std::get<ArgIndex>(args), 0, BufferSize);
202 202
203 return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 203 return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
204 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) { 204 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) {
205 using ElementType = typename ArgType::Type; 205 using ElementType = typename ArgType::Type;
206 206
@@ -217,15 +217,15 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext&
217 217
218 std::get<ArgIndex>(args) = std::span(ptr, size); 218 std::get<ArgIndex>(args) = std::span(ptr, size);
219 219
220 return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 220 return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
221 } else { 221 } else {
222 return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 222 return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
223 } 223 }
224 } 224 }
225} 225}
226 226
227template <bool Domain, typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0> 227template <typename MethodArguments, typename CallArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t OutBufferIndex = 0, bool RawDataFinished = false, size_t ArgIndex = 0>
228void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) { 228void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequestContext& ctx, OutTemporaryBuffers& temp) {
229 if constexpr (ArgIndex >= std::tuple_size_v<CallArguments>) { 229 if constexpr (ArgIndex >= std::tuple_size_v<CallArguments>) {
230 return; 230 return;
231 } else { 231 } else {
@@ -243,23 +243,23 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
243 243
244 std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args), ArgSize); 244 std::memcpy(raw_data + ArgOffset, &std::get<ArgIndex>(args), ArgSize);
245 245
246 return WriteOutArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, OutBufferIndex, false, ArgIndex + 1>(args, raw_data, ctx, temp); 246 return WriteOutArgument<MethodArguments, CallArguments, ArgAlign, ArgEnd, OutBufferIndex, false, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
247 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutInterface) { 247 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutInterface) {
248 if constexpr (Domain) { 248 if (is_domain) {
249 ctx.AddDomainObject(std::get<ArgIndex>(args)); 249 ctx.AddDomainObject(std::get<ArgIndex>(args));
250 } else { 250 } else {
251 ctx.AddMoveInterface(std::get<ArgIndex>(args)); 251 ctx.AddMoveInterface(std::get<ArgIndex>(args));
252 } 252 }
253 253
254 return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp); 254 return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
255 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) { 255 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) {
256 ctx.AddCopyObject(std::get<ArgIndex>(args)); 256 ctx.AddCopyObject(std::get<ArgIndex>(args));
257 257
258 return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 258 return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
259 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) { 259 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) {
260 ctx.AddMoveObject(std::get<ArgIndex>(args)); 260 ctx.AddMoveObject(std::get<ArgIndex>(args));
261 261
262 return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 262 return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
263 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) { 263 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
264 constexpr size_t BufferSize = sizeof(ArgType); 264 constexpr size_t BufferSize = sizeof(ArgType);
265 265
@@ -272,7 +272,7 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
272 ctx.WriteBufferC(&std::get<ArgIndex>(args), BufferSize, OutBufferIndex); 272 ctx.WriteBufferC(&std::get<ArgIndex>(args), BufferSize, OutBufferIndex);
273 } 273 }
274 274
275 return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 275 return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
276 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) { 276 } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutBuffer) {
277 auto& buffer = temp[OutBufferIndex]; 277 auto& buffer = temp[OutBufferIndex];
278 const size_t size = buffer.size(); 278 const size_t size = buffer.size();
@@ -287,9 +287,9 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
287 } 287 }
288 } 288 }
289 289
290 return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>( args, raw_data, ctx, temp); 290 return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex + 1, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
291 } else { 291 } else {
292 return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); 292 return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
293 } 293 }
294 } 294 }
295} 295}
@@ -297,11 +297,10 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx,
297template <bool Domain, typename T, typename... A> 297template <bool Domain, typename T, typename... A>
298void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) { 298void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
299 // Verify domain state. 299 // Verify domain state.
300 if constexpr (Domain) { 300 if constexpr (!Domain) {
301 ASSERT_MSG(ctx.GetManager()->IsDomain(), "Domain reply used on non-domain session");
302 } else {
303 ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Non-domain reply used on domain session"); 301 ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Non-domain reply used on domain session");
304 } 302 }
303 const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false;
305 304
306 using MethodArguments = std::tuple<std::remove_reference_t<A>...>; 305 using MethodArguments = std::tuple<std::remove_reference_t<A>...>;
307 306
@@ -310,7 +309,7 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
310 309
311 // Read inputs. 310 // Read inputs.
312 const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2; 311 const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2;
313 ReadInArgument<Domain, MethodArguments>(call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + offset_plus_command_id), ctx, buffers); 312 ReadInArgument<MethodArguments>(is_domain, call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + offset_plus_command_id), ctx, buffers);
314 313
315 // Call. 314 // Call.
316 const auto Callable = [&]<typename... CallArgs>(CallArgs&... args) { 315 const auto Callable = [&]<typename... CallArgs>(CallArgs&... args) {
@@ -319,12 +318,12 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) {
319 const Result res = std::apply(Callable, call_arguments); 318 const Result res = std::apply(Callable, call_arguments);
320 319
321 // Write result. 320 // Write result.
322 constexpr RequestLayout layout = GetReplyOutLayout<Domain, MethodArguments>(); 321 const RequestLayout layout = GetReplyOutLayout<MethodArguments>(is_domain);
323 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}; 322 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};
324 rb.Push(res); 323 rb.Push(res);
325 324
326 // Write out arguments. 325 // Write out arguments.
327 WriteOutArgument<Domain, MethodArguments>(call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + rb.GetCurrentOffset()), ctx, buffers); 326 WriteOutArgument<MethodArguments>(is_domain, call_arguments, reinterpret_cast<u8*>(ctx.CommandBuffer() + rb.GetCurrentOffset()), ctx, buffers);
328} 327}
329// clang-format on 328// clang-format on
330 329