diff options
| author | 2017-06-08 23:52:30 -0700 | |
|---|---|---|
| committer | 2017-06-11 13:07:33 -0700 | |
| commit | 20e5abb30807d4e0e34c79c049252f0872e47ca7 (patch) | |
| tree | 54284838ca89629576a046807b6965fe11507880 /src | |
| parent | Remove unused import in break_points.cpp (#2763) (diff) | |
| download | yuzu-20e5abb30807d4e0e34c79c049252f0872e47ca7.tar.gz yuzu-20e5abb30807d4e0e34c79c049252f0872e47ca7.tar.xz yuzu-20e5abb30807d4e0e34c79c049252f0872e47ca7.zip | |
ServiceFramework: Use separate copy of command buffer
Copy the IPC command buffer to/from the request context before/after the
handler is invoked. This is part of a move away from using global data
for handling IPC requests.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/ipc.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 26 |
3 files changed, 29 insertions, 9 deletions
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index 303ca090d..f7f96125a 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h | |||
| @@ -44,6 +44,9 @@ inline u32* GetStaticBuffers(const int offset = 0) { | |||
| 44 | 44 | ||
| 45 | namespace IPC { | 45 | namespace IPC { |
| 46 | 46 | ||
| 47 | /// Size of the command buffer area, in 32-bit words. | ||
| 48 | constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); | ||
| 49 | |||
| 47 | // These errors are commonly returned by invalid IPC translations, so alias them here for | 50 | // These errors are commonly returned by invalid IPC translations, so alias them here for |
| 48 | // convenience. | 51 | // convenience. |
| 49 | // TODO(yuriks): These will probably go away once translation is implemented inside the kernel. | 52 | // TODO(yuriks): These will probably go away once translation is implemented inside the kernel. |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index c30184eab..aa0046001 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -4,8 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 8 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/hle/ipc.h" | ||
| 9 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 10 | #include "core/hle/kernel/server_session.h" | 13 | #include "core/hle/kernel/server_session.h" |
| 11 | 14 | ||
| @@ -65,8 +68,8 @@ public: | |||
| 65 | ~HLERequestContext(); | 68 | ~HLERequestContext(); |
| 66 | 69 | ||
| 67 | /// Returns a pointer to the IPC command buffer for this request. | 70 | /// Returns a pointer to the IPC command buffer for this request. |
| 68 | u32* CommandBuffer() const { | 71 | u32* CommandBuffer() { |
| 69 | return cmd_buf; | 72 | return cmd_buf.data(); |
| 70 | } | 73 | } |
| 71 | 74 | ||
| 72 | /** | 75 | /** |
| @@ -80,7 +83,7 @@ public: | |||
| 80 | private: | 83 | private: |
| 81 | friend class Service::ServiceFrameworkBase; | 84 | friend class Service::ServiceFrameworkBase; |
| 82 | 85 | ||
| 83 | u32* cmd_buf = nullptr; | 86 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |
| 84 | SharedPtr<ServerSession> session; | 87 | SharedPtr<ServerSession> session; |
| 85 | }; | 88 | }; |
| 86 | 89 | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index d34968428..35582b0ff 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -2,9 +2,12 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <fmt/format.h> | 6 | #include <fmt/format.h> |
| 7 | #include "common/assert.h" | ||
| 6 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 7 | #include "common/string_util.h" | 9 | #include "common/string_util.h" |
| 10 | #include "core/hle/ipc.h" | ||
| 8 | #include "core/hle/kernel/client_port.h" | 11 | #include "core/hle/kernel/client_port.h" |
| 9 | #include "core/hle/kernel/server_port.h" | 12 | #include "core/hle/kernel/server_port.h" |
| 10 | #include "core/hle/kernel/server_session.h" | 13 | #include "core/hle/kernel/server_session.h" |
| @@ -160,12 +163,6 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(u32* cmd_buf, const Funct | |||
| 160 | void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_session) { | 163 | void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_session) { |
| 161 | u32* cmd_buf = Kernel::GetCommandBuffer(); | 164 | u32* cmd_buf = Kernel::GetCommandBuffer(); |
| 162 | 165 | ||
| 163 | // TODO(yuriks): The kernel should be the one handling this as part of translation after | ||
| 164 | // everything else is migrated | ||
| 165 | Kernel::HLERequestContext context; | ||
| 166 | context.cmd_buf = cmd_buf; | ||
| 167 | context.session = std::move(server_session); | ||
| 168 | |||
| 169 | u32 header_code = cmd_buf[0]; | 166 | u32 header_code = cmd_buf[0]; |
| 170 | auto itr = handlers.find(header_code); | 167 | auto itr = handlers.find(header_code); |
| 171 | const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; | 168 | const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; |
| @@ -173,9 +170,26 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses | |||
| 173 | return ReportUnimplementedFunction(cmd_buf, info); | 170 | return ReportUnimplementedFunction(cmd_buf, info); |
| 174 | } | 171 | } |
| 175 | 172 | ||
| 173 | // TODO(yuriks): The kernel should be the one handling this as part of translation after | ||
| 174 | // everything else is migrated | ||
| 175 | IPC::Header request_header{cmd_buf[0]}; | ||
| 176 | size_t request_size = | ||
| 177 | 1 + request_header.normal_params_size + request_header.translate_params_size; | ||
| 178 | ASSERT(request_size <= IPC::COMMAND_BUFFER_LENGTH); // TODO(yuriks): Return error | ||
| 179 | |||
| 180 | Kernel::HLERequestContext context; | ||
| 181 | std::copy_n(cmd_buf, request_size, context.cmd_buf.begin()); | ||
| 182 | context.session = std::move(server_session); | ||
| 183 | |||
| 176 | LOG_TRACE(Service, "%s", | 184 | LOG_TRACE(Service, "%s", |
| 177 | MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf).c_str()); | 185 | MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf).c_str()); |
| 178 | handler_invoker(this, info->handler_callback, context); | 186 | handler_invoker(this, info->handler_callback, context); |
| 187 | |||
| 188 | IPC::Header response_header{context.cmd_buf[0]}; | ||
| 189 | size_t response_size = | ||
| 190 | 1 + response_header.normal_params_size + response_header.translate_params_size; | ||
| 191 | ASSERT(response_size <= IPC::COMMAND_BUFFER_LENGTH); | ||
| 192 | std::copy_n(context.cmd_buf.begin(), response_size, cmd_buf); | ||
| 179 | } | 193 | } |
| 180 | 194 | ||
| 181 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 195 | //////////////////////////////////////////////////////////////////////////////////////////////////// |