Merge pull request #3077 from Subv/hle_static_buffer
Kernel/IPC: Implement StaticBuffer translation for HLE services that use the HLERequestContext architecture.
This commit is contained in:
commit
555c8ba7c1
11 changed files with 182 additions and 45 deletions
|
@ -2,6 +2,7 @@
|
|||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <vector>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
|
@ -44,6 +45,16 @@ void HLERequestContext::ClearIncomingObjects() {
|
|||
request_handles.clear();
|
||||
}
|
||||
|
||||
const std::vector<u8>& HLERequestContext::GetStaticBuffer(u8 buffer_id) const {
|
||||
ASSERT_MSG(!static_buffers[buffer_id].empty(), "Empty static buffer!");
|
||||
return static_buffers[buffer_id];
|
||||
}
|
||||
|
||||
void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector<u8> data) {
|
||||
ASSERT(static_buffers[buffer_id].empty() && !data.empty());
|
||||
static_buffers[buffer_id] = std::move(data);
|
||||
}
|
||||
|
||||
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
||||
Process& src_process,
|
||||
HandleTable& src_table) {
|
||||
|
@ -84,6 +95,18 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
|||
cmd_buf[i++] = src_process.process_id;
|
||||
break;
|
||||
}
|
||||
case IPC::DescriptorType::StaticBuffer: {
|
||||
VAddr source_address = src_cmdbuf[i];
|
||||
IPC::StaticBufferDescInfo buffer_info{descriptor};
|
||||
|
||||
// Copy the input buffer into our own vector and store it.
|
||||
std::vector<u8> data(buffer_info.size);
|
||||
Memory::ReadBlock(src_process, source_address, data.data(), data.size());
|
||||
|
||||
AddStaticBuffer(buffer_info.buffer_id, std::move(data));
|
||||
cmd_buf[i++] = source_address;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unsupported handle translation: 0x%08X", descriptor);
|
||||
}
|
||||
|
@ -124,6 +147,25 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
|
|||
}
|
||||
break;
|
||||
}
|
||||
case IPC::DescriptorType::StaticBuffer: {
|
||||
IPC::StaticBufferDescInfo buffer_info{descriptor};
|
||||
|
||||
const auto& data = GetStaticBuffer(buffer_info.buffer_id);
|
||||
|
||||
// Grab the address that the target thread set up to receive the response static buffer
|
||||
// and write our data there. The static buffers area is located right after the command
|
||||
// buffer area.
|
||||
size_t static_buffer_offset = IPC::COMMAND_BUFFER_LENGTH + 2 * buffer_info.buffer_id;
|
||||
IPC::StaticBufferDescInfo target_descriptor{dst_cmdbuf[static_buffer_offset]};
|
||||
VAddr target_address = dst_cmdbuf[static_buffer_offset + 1];
|
||||
|
||||
ASSERT_MSG(target_descriptor.size >= data.size(), "Static buffer data is too big");
|
||||
|
||||
Memory::WriteBlock(dst_process, target_address, data.data(), data.size());
|
||||
|
||||
dst_cmdbuf[i++] = target_address;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unsupported handle translation: 0x%08X", descriptor);
|
||||
}
|
||||
|
|
|
@ -119,6 +119,18 @@ public:
|
|||
*/
|
||||
void ClearIncomingObjects();
|
||||
|
||||
/**
|
||||
* Retrieves the static buffer identified by the input buffer_id. The static buffer *must* have
|
||||
* been created in PopulateFromIncomingCommandBuffer by way of an input StaticBuffer descriptor.
|
||||
*/
|
||||
const std::vector<u8>& GetStaticBuffer(u8 buffer_id) const;
|
||||
|
||||
/**
|
||||
* Sets up a static buffer that will be copied to the target process when the request is
|
||||
* translated.
|
||||
*/
|
||||
void AddStaticBuffer(u8 buffer_id, std::vector<u8> data);
|
||||
|
||||
/// Populates this context with data from the requesting process/thread.
|
||||
ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process,
|
||||
HandleTable& src_table);
|
||||
|
@ -131,6 +143,8 @@ private:
|
|||
SharedPtr<ServerSession> session;
|
||||
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
||||
boost::container::small_vector<SharedPtr<Object>, 8> request_handles;
|
||||
// The static buffers will be created when the IPC request is translated.
|
||||
std::array<std::vector<u8>, IPC::MAX_STATIC_BUFFERS> static_buffers;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue