Просмотр исходного кода

hle_ipc: Add helper functions for reading and writing buffers.

bunnei 8 лет назад
Родитель
Сommit
1ce6fff064
3 измененных файлов с 55 добавлено и 0 удалено
  1. 4 0
      src/core/hle/ipc.h
  2. 39 0
      src/core/hle/kernel/hle_ipc.cpp
  3. 12 0
      src/core/hle/kernel/hle_ipc.h

+ 4 - 0
src/core/hle/ipc.h

@@ -91,6 +91,10 @@ struct BufferDescriptorX {
         address |= static_cast<VAddr>(address_bits_36_38) << 36;
         return address;
     }
+
+    u64 Size() const {
+        return static_cast<u64>(size);
+    }
 };
 static_assert(sizeof(BufferDescriptorX) == 8, "BufferDescriptorX size is incorrect");
 

+ 39 - 0
src/core/hle/kernel/hle_ipc.cpp

@@ -12,6 +12,7 @@
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/server_session.h"
+#include "core/memory.h"
 
 namespace Kernel {
 
@@ -210,4 +211,42 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
     return RESULT_SUCCESS;
 }
 
+std::vector<u8> HLERequestContext::ReadBuffer() const {
+    std::vector<u8> buffer;
+    const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[0].Size()};
+
+    if (is_buffer_a) {
+        buffer.resize(BufferDescriptorA()[0].Size());
+        Memory::ReadBlock(BufferDescriptorA()[0].Address(), buffer.data(), buffer.size());
+    } else {
+        buffer.resize(BufferDescriptorX()[0].Size());
+        Memory::ReadBlock(BufferDescriptorX()[0].Address(), buffer.data(), buffer.size());
+    }
+
+    return buffer;
+}
+
+size_t HLERequestContext::WriteBuffer(const void* buffer, const size_t size) const {
+    const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
+
+    if (is_buffer_b) {
+        const size_t size{std::min(BufferDescriptorB()[0].Size(), size)};
+        Memory::WriteBlock(BufferDescriptorB()[0].Address(), buffer, size);
+        return size;
+    } else {
+        const size_t size{std::min(BufferDescriptorC()[0].Size(), size)};
+        Memory::WriteBlock(BufferDescriptorC()[0].Address(), buffer, size);
+        return size;
+    }
+}
+
+size_t HLERequestContext::WriteBuffer(const std::vector<u8>& buffer) const {
+    return WriteBuffer(buffer.data(), buffer.size());
+}
+
+size_t HLERequestContext::GetWriteBufferSize() const {
+    const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
+    return is_buffer_b ? BufferDescriptorB()[0].Size() : BufferDescriptorC()[0].Size();
+}
+
 } // namespace Kernel

+ 12 - 0
src/core/hle/kernel/hle_ipc.h

@@ -143,6 +143,18 @@ public:
         return domain_message_header;
     }
 
+    /// Helper function to read a buffer using the appropriate buffer descriptor
+    std::vector<u8> ReadBuffer() const;
+
+    /// Helper function to write a buffer using the appropriate buffer descriptor
+    size_t WriteBuffer(const void* buffer, const size_t size) const;
+
+    /// Helper function to write a buffer using the appropriate buffer descriptor
+    size_t WriteBuffer(const std::vector<u8>& buffer) const;
+
+    /// Helper function to get the size of the output buffer
+    size_t GetWriteBufferSize() const;
+
     template <typename T>
     SharedPtr<T> GetCopyObject(size_t index) {
         ASSERT(index < copy_objects.size());