summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/ipc.h4
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp44
-rw-r--r--src/core/hle/kernel/hle_ipc.h15
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp3
-rw-r--r--src/core/hle/service/am/am.cpp6
-rw-r--r--src/core/hle/service/audio/audout_u.cpp8
-rw-r--r--src/core/hle/service/audio/audren_u.cpp4
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp4
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp27
-rw-r--r--src/core/hle/service/set/set.cpp4
-rw-r--r--src/core/hle/service/vi/vi.cpp91
11 files changed, 102 insertions, 108 deletions
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h
index 0dcaede67..a6602e12c 100644
--- a/src/core/hle/ipc.h
+++ b/src/core/hle/ipc.h
@@ -91,6 +91,10 @@ struct BufferDescriptorX {
91 address |= static_cast<VAddr>(address_bits_36_38) << 36; 91 address |= static_cast<VAddr>(address_bits_36_38) << 36;
92 return address; 92 return address;
93 } 93 }
94
95 u64 Size() const {
96 return static_cast<u64>(size);
97 }
94}; 98};
95static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect"); 99static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect");
96 100
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index db104e8a2..6d16f71a7 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -12,6 +12,7 @@
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
14#include "core/hle/kernel/server_session.h" 14#include "core/hle/kernel/server_session.h"
15#include "core/memory.h"
15 16
16namespace Kernel { 17namespace Kernel {
17 18
@@ -210,4 +211,47 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
210 return RESULT_SUCCESS; 211 return RESULT_SUCCESS;
211} 212}
212 213
214std::vector<u8> HLERequestContext::ReadBuffer() const {
215 std::vector<u8> buffer;
216 const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[0].Size()};
217
218 if (is_buffer_a) {
219 buffer.resize(BufferDescriptorA()[0].Size());
220 Memory::ReadBlock(BufferDescriptorA()[0].Address(), buffer.data(), buffer.size());
221 } else {
222 buffer.resize(BufferDescriptorX()[0].Size());
223 Memory::ReadBlock(BufferDescriptorX()[0].Address(), buffer.data(), buffer.size());
224 }
225
226 return buffer;
227}
228
229size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const {
230 const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
231
232 ASSERT_MSG(size <= GetWriteBufferSize(), "Size %d is too big", size);
233
234 if (is_buffer_b) {
235 Memory::WriteBlock(BufferDescriptorB()[0].Address(), buffer, size);
236 } else {
237 Memory::WriteBlock(BufferDescriptorC()[0].Address(), buffer, size);
238 }
239
240 return size;
241}
242
243size_t HLERequestContext::WriteBuffer(const std::vector<u8>& buffer) const {
244 return WriteBuffer(buffer.data(), buffer.size());
245}
246
247size_t HLERequestContext::GetReadBufferSize() const {
248 const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[0].Size()};
249 return is_buffer_a ? BufferDescriptorA()[0].Size() : BufferDescriptorX()[0].Size();
250}
251
252size_t HLERequestContext::GetWriteBufferSize() const {
253 const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
254 return is_buffer_b ? BufferDescriptorB()[0].Size() : BufferDescriptorC()[0].Size();
255}
256
213} // namespace Kernel 257} // namespace Kernel
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index da8335b35..81e3489c8 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -143,6 +143,21 @@ public:
143 return domain_message_header; 143 return domain_message_header;
144 } 144 }
145 145
146 /// Helper function to read a buffer using the appropriate buffer descriptor
147 std::vector<u8> ReadBuffer() const;
148
149 /// Helper function to write a buffer using the appropriate buffer descriptor
150 size_t WriteBuffer(const void* buffer, size_t size) const;
151
152 /// Helper function to write a buffer using the appropriate buffer descriptor
153 size_t WriteBuffer(const std::vector<u8>& buffer) const;
154
155 /// Helper function to get the size of the input buffer
156 size_t GetReadBufferSize() const;
157
158 /// Helper function to get the size of the output buffer
159 size_t GetWriteBufferSize() const;
160
146 template <typename T> 161 template <typename T>
147 SharedPtr<T> GetCopyObject(size_t index) { 162 SharedPtr<T> GetCopyObject(size_t index) {
148 ASSERT(index < copy_objects.size()); 163 ASSERT(index < copy_objects.size());
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
index ee7d07aa7..7955f726b 100644
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ b/src/core/hle/service/acc/acc_u0.cpp
@@ -66,8 +66,7 @@ void ACC_U0::GetUserExistence(Kernel::HLERequestContext& ctx) {
66 66
67void ACC_U0::ListAllUsers(Kernel::HLERequestContext& ctx) { 67void ACC_U0::ListAllUsers(Kernel::HLERequestContext& ctx) {
68 constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; 68 constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
69 const auto& output_buffer = ctx.BufferDescriptorC()[0]; 69 ctx.WriteBuffer(user_ids.data(), user_ids.size());
70 Memory::WriteBlock(output_buffer.Address(), user_ids.data(), user_ids.size());
71 IPC::ResponseBuilder rb{ctx, 2}; 70 IPC::ResponseBuilder rb{ctx, 2};
72 rb.Push(RESULT_SUCCESS); 71 rb.Push(RESULT_SUCCESS);
73 LOG_DEBUG(Service_ACC, "called"); 72 LOG_DEBUG(Service_ACC, "called");
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 07cea8717..402105ea0 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -306,11 +306,11 @@ private:
306 306
307 u64 offset = rp.Pop<u64>(); 307 u64 offset = rp.Pop<u64>();
308 308
309 const auto& output_buffer = ctx.BufferDescriptorC()[0]; 309 const size_t size{ctx.GetWriteBufferSize()};
310 310
311 ASSERT(offset + output_buffer.Size() <= buffer.size()); 311 ASSERT(offset + size <= buffer.size());
312 312
313 Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size()); 313 ctx.WriteBuffer(buffer.data() + offset, size);
314 314
315 IPC::ResponseBuilder rb{ctx, 2}; 315 IPC::ResponseBuilder rb{ctx, 2};
316 316
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index f56ba2ea1..780a4e6e5 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -99,8 +99,6 @@ private:
99 void GetReleasedAudioOutBuffer_1(Kernel::HLERequestContext& ctx) { 99 void GetReleasedAudioOutBuffer_1(Kernel::HLERequestContext& ctx) {
100 LOG_WARNING(Service_Audio, "(STUBBED) called"); 100 LOG_WARNING(Service_Audio, "(STUBBED) called");
101 101
102 const auto& buffer = ctx.BufferDescriptorB()[0];
103
104 // TODO(st4rk): This is how libtransistor currently implements the 102 // TODO(st4rk): This is how libtransistor currently implements the
105 // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address 103 // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address
106 // is used to know which buffer should be filled with data and send again to the service 104 // is used to know which buffer should be filled with data and send again to the service
@@ -112,7 +110,7 @@ private:
112 queue_keys.pop_back(); 110 queue_keys.pop_back();
113 } 111 }
114 112
115 Memory::WriteBlock(buffer.Address(), &key, sizeof(u64)); 113 ctx.WriteBuffer(&key, sizeof(u64));
116 114
117 IPC::ResponseBuilder rb{ctx, 3}; 115 IPC::ResponseBuilder rb{ctx, 3};
118 rb.Push(RESULT_SUCCESS); 116 rb.Push(RESULT_SUCCESS);
@@ -158,10 +156,8 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
158 LOG_WARNING(Service_Audio, "(STUBBED) called"); 156 LOG_WARNING(Service_Audio, "(STUBBED) called");
159 IPC::RequestParser rp{ctx}; 157 IPC::RequestParser rp{ctx};
160 158
161 auto& buffer = ctx.BufferDescriptorB()[0];
162 const std::string audio_interface = "AudioInterface"; 159 const std::string audio_interface = "AudioInterface";
163 160 ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size());
164 Memory::WriteBlock(buffer.Address(), &audio_interface[0], audio_interface.size());
165 161
166 IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); 162 IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
167 163
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index c8d8ba748..20306c6cf 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -69,9 +69,7 @@ private:
69 response_data.state_entries[i].state = 5; 69 response_data.state_entries[i].state = 5;
70 } 70 }
71 71
72 auto& buffer = ctx.BufferDescriptorB()[0]; 72 ctx.WriteBuffer(&response_data, response_data.total_size);
73
74 Memory::WriteBlock(buffer.Address(), &response_data, response_data.total_size);
75 73
76 IPC::ResponseBuilder rb{ctx, 2}; 74 IPC::ResponseBuilder rb{ctx, 2};
77 75
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 34d4fd035..87a07e457 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -33,12 +33,10 @@ private:
33 IPC::RequestParser rp{ctx}; 33 IPC::RequestParser rp{ctx};
34 const s64 offset = rp.Pop<s64>(); 34 const s64 offset = rp.Pop<s64>();
35 const s64 length = rp.Pop<s64>(); 35 const s64 length = rp.Pop<s64>();
36 const auto& descriptor = ctx.BufferDescriptorB()[0];
37 36
38 LOG_DEBUG(Service_FS, "called, offset=0x%llx, length=0x%llx", offset, length); 37 LOG_DEBUG(Service_FS, "called, offset=0x%llx, length=0x%llx", offset, length);
39 38
40 // Error checking 39 // Error checking
41 ASSERT_MSG(length == descriptor.Size(), "unexpected size difference");
42 if (length < 0) { 40 if (length < 0) {
43 IPC::ResponseBuilder rb{ctx, 2}; 41 IPC::ResponseBuilder rb{ctx, 2};
44 rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidLength)); 42 rb.Push(ResultCode(ErrorModule::FS, ErrorDescription::InvalidLength));
@@ -60,7 +58,7 @@ private:
60 } 58 }
61 59
62 // Write the data to memory 60 // Write the data to memory
63 Memory::WriteBlock(descriptor.Address(), output.data(), descriptor.Size()); 61 ctx.WriteBuffer(output);
64 62
65 IPC::ResponseBuilder rb{ctx, 2}; 63 IPC::ResponseBuilder rb{ctx, 2};
66 rb.Push(RESULT_SUCCESS); 64 rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 1a5efaeaf..c70370f1f 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -15,9 +15,8 @@ namespace Nvidia {
15void NVDRV::Open(Kernel::HLERequestContext& ctx) { 15void NVDRV::Open(Kernel::HLERequestContext& ctx) {
16 LOG_DEBUG(Service_NVDRV, "called"); 16 LOG_DEBUG(Service_NVDRV, "called");
17 17
18 auto buffer = ctx.BufferDescriptorA()[0]; 18 const auto& buffer = ctx.ReadBuffer();
19 19 std::string device_name(buffer.begin(), buffer.end());
20 std::string device_name = Memory::ReadCString(buffer.Address(), buffer.Size());
21 20
22 u32 fd = nvdrv->Open(device_name); 21 u32 fd = nvdrv->Open(device_name);
23 IPC::ResponseBuilder rb{ctx, 4}; 22 IPC::ResponseBuilder rb{ctx, 4};
@@ -33,25 +32,13 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
33 u32 fd = rp.Pop<u32>(); 32 u32 fd = rp.Pop<u32>();
34 u32 command = rp.Pop<u32>(); 33 u32 command = rp.Pop<u32>();
35 34
35 std::vector<u8> output(ctx.GetWriteBufferSize());
36
36 IPC::ResponseBuilder rb{ctx, 3}; 37 IPC::ResponseBuilder rb{ctx, 3};
37 rb.Push(RESULT_SUCCESS); 38 rb.Push(RESULT_SUCCESS);
38 if (ctx.BufferDescriptorA()[0].Size() != 0) { 39 rb.Push(nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output));
39 auto input_buffer = ctx.BufferDescriptorA()[0]; 40
40 auto output_buffer = ctx.BufferDescriptorB()[0]; 41 ctx.WriteBuffer(output);
41 std::vector<u8> input(input_buffer.Size());
42 std::vector<u8> output(output_buffer.Size());
43 Memory::ReadBlock(input_buffer.Address(), input.data(), input_buffer.Size());
44 rb.Push(nvdrv->Ioctl(fd, command, input, output));
45 Memory::WriteBlock(output_buffer.Address(), output.data(), output_buffer.Size());
46 } else {
47 auto input_buffer = ctx.BufferDescriptorX()[0];
48 auto output_buffer = ctx.BufferDescriptorC()[0];
49 std::vector<u8> input(input_buffer.size);
50 std::vector<u8> output(output_buffer.size);
51 Memory::ReadBlock(input_buffer.Address(), input.data(), input_buffer.size);
52 rb.Push(nvdrv->Ioctl(fd, command, input, output));
53 Memory::WriteBlock(output_buffer.Address(), output.data(), output_buffer.size);
54 }
55} 42}
56 43
57void NVDRV::Close(Kernel::HLERequestContext& ctx) { 44void NVDRV::Close(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index 1062ba8b3..3001ee411 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -17,9 +17,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
17 u32 id = rp.Pop<u32>(); 17 u32 id = rp.Pop<u32>();
18 constexpr std::array<u8, 13> lang_codes{}; 18 constexpr std::array<u8, 13> lang_codes{};
19 19
20 const auto& output_buffer = ctx.BufferDescriptorC()[0]; 20 ctx.WriteBuffer(lang_codes.data(), lang_codes.size());
21
22 Memory::WriteBlock(output_buffer.Address(), lang_codes.data(), lang_codes.size());
23 21
24 IPC::ResponseBuilder rb{ctx, 2}; 22 IPC::ResponseBuilder rb{ctx, 2};
25 23
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 8b4ed30d2..ff5005f71 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -429,7 +429,7 @@ public:
429 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, 429 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
430 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, 430 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
431 {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, 431 {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"},
432 {3, &IHOSBinderDriver::TransactParcelAuto, "TransactParcelAuto"}, 432 {3, &IHOSBinderDriver::TransactParcel, "TransactParcelAuto"},
433 }; 433 };
434 RegisterHandlers(functions); 434 RegisterHandlers(functions);
435 } 435 }
@@ -453,95 +453,61 @@ private:
453 SetPreallocatedBuffer = 14 453 SetPreallocatedBuffer = 14
454 }; 454 };
455 455
456 void TransactParcel(u32 id, TransactionId transaction, const std::vector<u8>& input_data, 456 void TransactParcel(Kernel::HLERequestContext& ctx) {
457 VAddr output_addr, u64 output_size) { 457 IPC::RequestParser rp{ctx};
458 u32 id = rp.Pop<u32>();
459 auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
460 u32 flags = rp.Pop<u32>();
458 auto buffer_queue = nv_flinger->GetBufferQueue(id); 461 auto buffer_queue = nv_flinger->GetBufferQueue(id);
459 462
463 LOG_DEBUG(Service_VI, "called, transaction=%x", transaction);
464
460 if (transaction == TransactionId::Connect) { 465 if (transaction == TransactionId::Connect) {
461 IGBPConnectRequestParcel request{input_data}; 466 IGBPConnectRequestParcel request{ctx.ReadBuffer()};
462 IGBPConnectResponseParcel response{1280, 720}; 467 IGBPConnectResponseParcel response{1280, 720};
463 std::vector<u8> response_buffer = response.Serialize(); 468 ctx.WriteBuffer(response.Serialize());
464 Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size());
465 } else if (transaction == TransactionId::SetPreallocatedBuffer) { 469 } else if (transaction == TransactionId::SetPreallocatedBuffer) {
466 IGBPSetPreallocatedBufferRequestParcel request{input_data}; 470 IGBPSetPreallocatedBufferRequestParcel request{ctx.ReadBuffer()};
467 471
468 buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer); 472 buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer);
469 473
470 IGBPSetPreallocatedBufferResponseParcel response{}; 474 IGBPSetPreallocatedBufferResponseParcel response{};
471 std::vector<u8> response_buffer = response.Serialize(); 475 ctx.WriteBuffer(response.Serialize());
472 Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size());
473 } else if (transaction == TransactionId::DequeueBuffer) { 476 } else if (transaction == TransactionId::DequeueBuffer) {
474 IGBPDequeueBufferRequestParcel request{input_data}; 477 IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
475 478
476 u32 slot = buffer_queue->DequeueBuffer(request.data.pixel_format, request.data.width, 479 u32 slot = buffer_queue->DequeueBuffer(request.data.pixel_format, request.data.width,
477 request.data.height); 480 request.data.height);
478 481
479 IGBPDequeueBufferResponseParcel response{slot}; 482 IGBPDequeueBufferResponseParcel response{slot};
480 std::vector<u8> response_buffer = response.Serialize(); 483 ctx.WriteBuffer(response.Serialize());
481 Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size());
482 } else if (transaction == TransactionId::RequestBuffer) { 484 } else if (transaction == TransactionId::RequestBuffer) {
483 IGBPRequestBufferRequestParcel request{input_data}; 485 IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};
484 486
485 auto& buffer = buffer_queue->RequestBuffer(request.slot); 487 auto& buffer = buffer_queue->RequestBuffer(request.slot);
486 488
487 IGBPRequestBufferResponseParcel response{buffer}; 489 IGBPRequestBufferResponseParcel response{buffer};
488 std::vector<u8> response_buffer = response.Serialize(); 490 ctx.WriteBuffer(response.Serialize());
489 Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size());
490 } else if (transaction == TransactionId::QueueBuffer) { 491 } else if (transaction == TransactionId::QueueBuffer) {
491 IGBPQueueBufferRequestParcel request{input_data}; 492 IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()};
492 493
493 buffer_queue->QueueBuffer(request.data.slot, request.data.transform); 494 buffer_queue->QueueBuffer(request.data.slot, request.data.transform);
494 495
495 IGBPQueueBufferResponseParcel response{1280, 720}; 496 IGBPQueueBufferResponseParcel response{1280, 720};
496 std::vector<u8> response_buffer = response.Serialize(); 497 ctx.WriteBuffer(response.Serialize());
497 Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size());
498 } else if (transaction == TransactionId::Query) { 498 } else if (transaction == TransactionId::Query) {
499 IGBPQueryRequestParcel request{input_data}; 499 IGBPQueryRequestParcel request{ctx.ReadBuffer()};
500 500
501 u32 value = 501 u32 value =
502 buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); 502 buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type));
503 503
504 IGBPQueryResponseParcel response{value}; 504 IGBPQueryResponseParcel response{value};
505 std::vector<u8> response_buffer = response.Serialize(); 505 ctx.WriteBuffer(response.Serialize());
506 Memory::WriteBlock(output_addr, response_buffer.data(), response_buffer.size());
507 } else if (transaction == TransactionId::CancelBuffer) { 506 } else if (transaction == TransactionId::CancelBuffer) {
508 LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); 507 LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer");
509 } else { 508 } else {
510 ASSERT_MSG(false, "Unimplemented"); 509 ASSERT_MSG(false, "Unimplemented");
511 } 510 }
512 }
513
514 void TransactParcel(Kernel::HLERequestContext& ctx) {
515 IPC::RequestParser rp{ctx};
516 u32 id = rp.Pop<u32>();
517 auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
518 u32 flags = rp.Pop<u32>();
519 LOG_DEBUG(Service_VI, "called, transaction=%x", transaction);
520
521 auto& input_buffer = ctx.BufferDescriptorA()[0];
522 auto& output_buffer = ctx.BufferDescriptorB()[0];
523 std::vector<u8> input_data(input_buffer.Size());
524 Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.Size());
525
526 TransactParcel(id, transaction, input_data, output_buffer.Address(), output_buffer.Size());
527
528 IPC::ResponseBuilder rb{ctx, 2};
529 rb.Push(RESULT_SUCCESS);
530 }
531
532 void TransactParcelAuto(Kernel::HLERequestContext& ctx) {
533 IPC::RequestParser rp{ctx};
534 u32 id = rp.Pop<u32>();
535 auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
536 u32 flags = rp.Pop<u32>();
537 LOG_DEBUG(Service_VI, "called, transaction=%x", transaction);
538
539 auto& input_buffer = ctx.BufferDescriptorX()[0];
540 auto& output_buffer = ctx.BufferDescriptorC()[0];
541 std::vector<u8> input_data(input_buffer.size);
542 Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.size);
543
544 TransactParcel(id, transaction, input_data, output_buffer.Address(), output_buffer.Size());
545 511
546 IPC::ResponseBuilder rb{ctx, 2}; 512 IPC::ResponseBuilder rb{ctx, 2};
547 rb.Push(RESULT_SUCCESS); 513 rb.Push(RESULT_SUCCESS);
@@ -719,18 +685,13 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) {
719 u64 layer_id = rp.Pop<u64>(); 685 u64 layer_id = rp.Pop<u64>();
720 u64 aruid = rp.Pop<u64>(); 686 u64 aruid = rp.Pop<u64>();
721 687
722 auto& buffer = ctx.BufferDescriptorB()[0];
723
724 u64 display_id = nv_flinger->OpenDisplay(display_name); 688 u64 display_id = nv_flinger->OpenDisplay(display_name);
725 u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); 689 u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id);
726 690
727 NativeWindow native_window{buffer_queue_id}; 691 NativeWindow native_window{buffer_queue_id};
728 auto data = native_window.Serialize();
729 Memory::WriteBlock(buffer.Address(), data.data(), data.size());
730
731 IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); 692 IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);
732 rb.Push(RESULT_SUCCESS); 693 rb.Push(RESULT_SUCCESS);
733 rb.Push<u64>(data.size()); 694 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
734} 695}
735 696
736void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { 697void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) {
@@ -741,21 +702,16 @@ void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx
741 rp.Pop<u32>(); // padding 702 rp.Pop<u32>(); // padding
742 u64 display_id = rp.Pop<u64>(); 703 u64 display_id = rp.Pop<u64>();
743 704
744 auto& buffer = ctx.BufferDescriptorB()[0];
745
746 // TODO(Subv): What's the difference between a Stray and a Managed layer? 705 // TODO(Subv): What's the difference between a Stray and a Managed layer?
747 706
748 u64 layer_id = nv_flinger->CreateLayer(display_id); 707 u64 layer_id = nv_flinger->CreateLayer(display_id);
749 u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); 708 u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id);
750 709
751 NativeWindow native_window{buffer_queue_id}; 710 NativeWindow native_window{buffer_queue_id};
752 auto data = native_window.Serialize();
753 Memory::WriteBlock(buffer.Address(), data.data(), data.size());
754
755 IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0); 711 IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0);
756 rb.Push(RESULT_SUCCESS); 712 rb.Push(RESULT_SUCCESS);
757 rb.Push(layer_id); 713 rb.Push(layer_id);
758 rb.Push<u64>(data.size()); 714 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
759} 715}
760 716
761void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) { 717void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) {
@@ -781,8 +737,7 @@ void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext&
781void IApplicationDisplayService::ListDisplays(Kernel::HLERequestContext& ctx) { 737void IApplicationDisplayService::ListDisplays(Kernel::HLERequestContext& ctx) {
782 IPC::RequestParser rp{ctx}; 738 IPC::RequestParser rp{ctx};
783 DisplayInfo display_info; 739 DisplayInfo display_info;
784 auto& buffer = ctx.BufferDescriptorB()[0]; 740 ctx.WriteBuffer(&display_info, sizeof(DisplayInfo));
785 Memory::WriteBlock(buffer.Address(), &display_info, sizeof(DisplayInfo));
786 IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); 741 IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);
787 rb.Push(RESULT_SUCCESS); 742 rb.Push(RESULT_SUCCESS);
788 rb.Push<u64>(1); 743 rb.Push<u64>(1);