diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/ipc.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 44 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 15 | ||||
| -rw-r--r-- | src/core/hle/service/acc/acc_u0.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/interface.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/service/set/set.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 91 |
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 | }; |
| 95 | static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect"); | 99 | static_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 | ||
| 16 | namespace Kernel { | 17 | namespace 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 | ||
| 214 | std::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 | |||
| 229 | size_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 | |||
| 243 | size_t HLERequestContext::WriteBuffer(const std::vector<u8>& buffer) const { | ||
| 244 | return WriteBuffer(buffer.data(), buffer.size()); | ||
| 245 | } | ||
| 246 | |||
| 247 | size_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 | |||
| 252 | size_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 | ||
| 67 | void ACC_U0::ListAllUsers(Kernel::HLERequestContext& ctx) { | 67 | void 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 { | |||
| 15 | void NVDRV::Open(Kernel::HLERequestContext& ctx) { | 15 | void 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 | ||
| 57 | void NVDRV::Close(Kernel::HLERequestContext& ctx) { | 44 | void 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 | ||
| 736 | void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { | 697 | void 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 | ||
| 761 | void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) { | 717 | void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) { |
| @@ -781,8 +737,7 @@ void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext& | |||
| 781 | void IApplicationDisplayService::ListDisplays(Kernel::HLERequestContext& ctx) { | 737 | void 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); |