mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +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
					
				@ -44,6 +44,9 @@ inline u32* GetStaticBuffers(const int offset = 0) {
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
// convenience.
 | 
			
		||||
// TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,11 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/ipc.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/server_session.h"
 | 
			
		||||
 | 
			
		||||
@ -65,8 +68,8 @@ public:
 | 
			
		||||
    ~HLERequestContext();
 | 
			
		||||
 | 
			
		||||
    /// Returns a pointer to the IPC command buffer for this request.
 | 
			
		||||
    u32* CommandBuffer() const {
 | 
			
		||||
        return cmd_buf;
 | 
			
		||||
    u32* CommandBuffer() {
 | 
			
		||||
        return cmd_buf.data();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -80,7 +83,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    friend class Service::ServiceFrameworkBase;
 | 
			
		||||
 | 
			
		||||
    u32* cmd_buf = nullptr;
 | 
			
		||||
    std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
 | 
			
		||||
    SharedPtr<ServerSession> session;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,12 @@
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <fmt/format.h>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
#include "core/hle/ipc.h"
 | 
			
		||||
#include "core/hle/kernel/client_port.h"
 | 
			
		||||
#include "core/hle/kernel/server_port.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) {
 | 
			
		||||
    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];
 | 
			
		||||
    auto itr = handlers.find(header_code);
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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",
 | 
			
		||||
              MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf).c_str());
 | 
			
		||||
    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…
	
		Reference in New Issue
	
	Block a user