summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/ipc.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.h9
-rw-r--r--src/core/hle/service/service.cpp26
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) {
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.
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 @@
#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;
};
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 @@
// 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);
}
////////////////////////////////////////////////////////////////////////////////////////////////////