summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/ipc.h4
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp39
-rw-r--r--src/core/hle/kernel/hle_ipc.h12
3 files changed, 55 insertions, 0 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 {
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");
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index db104e8a2..a5a3d4fe4 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/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
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index da8335b35..0cc270909 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/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());