From 59575d5cae573b57eb9e1e611e2c25ceb935ec0a Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 18 Jan 2018 16:54:34 -0300 Subject: Stub PopLaunchParameter and implement Buffer C Descriptors reading on hle_ipc (#96) * Stub PopLaunchParameter and implement Buffer C Descriptors reading * Address PR feedback * Ensure we push a u64 not a size_t * Fix formatting --- src/core/hle/kernel/hle_ipc.cpp | 34 +++++++++++++++++++++++++++------- src/core/hle/kernel/hle_ipc.h | 6 ++++++ 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index ac62a0d5a..73bb6a8be 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -81,13 +81,8 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { for (unsigned i = 0; i < command_header->num_buf_w_descriptors; ++i) { buffer_w_desciptors.push_back(rp.PopRaw()); } - if (command_header->buf_c_descriptor_flags != - IPC::CommandHeader::BufferDescriptorCFlag::Disabled) { - if (command_header->buf_c_descriptor_flags != - IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) { - UNIMPLEMENTED(); - } - } + + buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size; // Padding to align to 16 bytes rp.AlignWithPadding(); @@ -117,6 +112,31 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O')); } + rp.SetCurrentOffset(buffer_c_offset); + + // For Inline buffers, the response data is written directly to buffer_c_offset + // and in this case we don't have any BufferDescriptorC on the request. + if (command_header->buf_c_descriptor_flags > + IPC::CommandHeader::BufferDescriptorCFlag::InlineDescriptor) { + if (command_header->buf_c_descriptor_flags == + IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) { + buffer_c_desciptors.push_back(rp.PopRaw()); + } else { + unsigned num_buf_c_descriptors = + static_cast(command_header->buf_c_descriptor_flags.Value()) - 2; + + // This is used to detect possible underflows, in case something is broken + // with the two ifs above and the flags value is == 0 || == 1. + ASSERT(num_buf_c_descriptors < 14); + + for (unsigned i = 0; i < num_buf_c_descriptors; ++i) { + buffer_c_desciptors.push_back(rp.PopRaw()); + } + } + } + + rp.SetCurrentOffset(data_payload_offset); + command = rp.Pop(); rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 6dceb766d..80fa48d7f 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -143,6 +143,10 @@ public: return buffer_b_desciptors; } + const std::vector& BufferDescriptorC() const { + return buffer_c_desciptors; + } + const std::unique_ptr& GetDomainMessageHeader() const { return domain_message_header; } @@ -200,8 +204,10 @@ private: std::vector buffer_a_desciptors; std::vector buffer_b_desciptors; std::vector buffer_w_desciptors; + std::vector buffer_c_desciptors; unsigned data_payload_offset{}; + unsigned buffer_c_offset{}; u32_le command{}; }; -- cgit v1.2.3