mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									9a8a90b52b
								
							
						
					
					
						commit
						20e5abb308
					
				
					 3 changed files with 29 additions and 9 deletions
				
			
		|  | @ -44,6 +44,9 @@ inline u32* GetStaticBuffers(const int offset = 0) { | ||||||
| 
 | 
 | ||||||
| namespace IPC { | namespace IPC { | ||||||
| 
 | 
 | ||||||
|  | /// Size of the command buffer area, in 32-bit words.
 | ||||||
|  | constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); | ||||||
|  | 
 | ||||||
| // These errors are commonly returned by invalid IPC translations, so alias them here for
 | // These errors are commonly returned by invalid IPC translations, so alias them here for
 | ||||||
| // convenience.
 | // convenience.
 | ||||||
| // TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
 | // TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
 | ||||||
|  |  | ||||||
|  | @ -4,8 +4,11 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <array> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "core/hle/ipc.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
| #include "core/hle/kernel/server_session.h" | #include "core/hle/kernel/server_session.h" | ||||||
| 
 | 
 | ||||||
|  | @ -65,8 +68,8 @@ public: | ||||||
|     ~HLERequestContext(); |     ~HLERequestContext(); | ||||||
| 
 | 
 | ||||||
|     /// Returns a pointer to the IPC command buffer for this request.
 |     /// Returns a pointer to the IPC command buffer for this request.
 | ||||||
|     u32* CommandBuffer() const { |     u32* CommandBuffer() { | ||||||
|         return cmd_buf; |         return cmd_buf.data(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|  | @ -80,7 +83,7 @@ public: | ||||||
| private: | private: | ||||||
|     friend class Service::ServiceFrameworkBase; |     friend class Service::ServiceFrameworkBase; | ||||||
| 
 | 
 | ||||||
|     u32* cmd_buf = nullptr; |     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | ||||||
|     SharedPtr<ServerSession> session; |     SharedPtr<ServerSession> session; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,9 +2,12 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
|  | #include <algorithm> | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
|  | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
|  | #include "core/hle/ipc.h" | ||||||
| #include "core/hle/kernel/client_port.h" | #include "core/hle/kernel/client_port.h" | ||||||
| #include "core/hle/kernel/server_port.h" | #include "core/hle/kernel/server_port.h" | ||||||
| #include "core/hle/kernel/server_session.h" | #include "core/hle/kernel/server_session.h" | ||||||
|  | @ -160,12 +163,6 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(u32* cmd_buf, const Funct | ||||||
| void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_session) { | void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_session) { | ||||||
|     u32* cmd_buf = Kernel::GetCommandBuffer(); |     u32* cmd_buf = Kernel::GetCommandBuffer(); | ||||||
| 
 | 
 | ||||||
|     // TODO(yuriks): The kernel should be the one handling this as part of translation after
 |  | ||||||
|     // everything else is migrated
 |  | ||||||
|     Kernel::HLERequestContext context; |  | ||||||
|     context.cmd_buf = cmd_buf; |  | ||||||
|     context.session = std::move(server_session); |  | ||||||
| 
 |  | ||||||
|     u32 header_code = cmd_buf[0]; |     u32 header_code = cmd_buf[0]; | ||||||
|     auto itr = handlers.find(header_code); |     auto itr = handlers.find(header_code); | ||||||
|     const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; |     const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; | ||||||
|  | @ -173,9 +170,26 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr<ServerSession> server_ses | ||||||
|         return ReportUnimplementedFunction(cmd_buf, info); |         return ReportUnimplementedFunction(cmd_buf, info); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // TODO(yuriks): The kernel should be the one handling this as part of translation after
 | ||||||
|  |     // everything else is migrated
 | ||||||
|  |     IPC::Header request_header{cmd_buf[0]}; | ||||||
|  |     size_t request_size = | ||||||
|  |         1 + request_header.normal_params_size + request_header.translate_params_size; | ||||||
|  |     ASSERT(request_size <= IPC::COMMAND_BUFFER_LENGTH); // TODO(yuriks): Return error
 | ||||||
|  | 
 | ||||||
|  |     Kernel::HLERequestContext context; | ||||||
|  |     std::copy_n(cmd_buf, request_size, context.cmd_buf.begin()); | ||||||
|  |     context.session = std::move(server_session); | ||||||
|  | 
 | ||||||
|     LOG_TRACE(Service, "%s", |     LOG_TRACE(Service, "%s", | ||||||
|               MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf).c_str()); |               MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf).c_str()); | ||||||
|     handler_invoker(this, info->handler_callback, context); |     handler_invoker(this, info->handler_callback, context); | ||||||
|  | 
 | ||||||
|  |     IPC::Header response_header{context.cmd_buf[0]}; | ||||||
|  |     size_t response_size = | ||||||
|  |         1 + response_header.normal_params_size + response_header.translate_params_size; | ||||||
|  |     ASSERT(response_size <= IPC::COMMAND_BUFFER_LENGTH); | ||||||
|  |     std::copy_n(context.cmd_buf.begin(), response_size, cmd_buf); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue