summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2021-05-10 16:08:06 -0700
committerGravatar bunnei2021-05-10 20:34:38 -0700
commit21671d05a362f98cd24dcc520a3da163e349fe07 (patch)
tree904d17169565cb12c4dd7ac8c640d136803ae686
parenthle: service: Implement IPC::CommandType::Close. (diff)
downloadyuzu-21671d05a362f98cd24dcc520a3da163e349fe07.tar.gz
yuzu-21671d05a362f98cd24dcc520a3da163e349fe07.tar.xz
yuzu-21671d05a362f98cd24dcc520a3da163e349fe07.zip
hle: service: Add support for dispatching TIPC requests.
-rw-r--r--src/core/hle/service/service.cpp29
-rw-r--r--src/core/hle/service/service.h24
2 files changed, 52 insertions, 1 deletions
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index e36c35a86..2c9b2ce6d 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -133,6 +133,16 @@ void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* function
133 } 133 }
134} 134}
135 135
136void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions,
137 std::size_t n) {
138 handlers_tipc.reserve(handlers_tipc.size() + n);
139 for (std::size_t i = 0; i < n; ++i) {
140 // Usually this array is sorted by id already, so hint to insert at the end
141 handlers_tipc.emplace_hint(handlers_tipc.cend(), functions[i].expected_header,
142 functions[i]);
143 }
144}
145
136void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, 146void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx,
137 const FunctionInfoBase* info) { 147 const FunctionInfoBase* info) {
138 auto cmd_buf = ctx.CommandBuffer(); 148 auto cmd_buf = ctx.CommandBuffer();
@@ -167,6 +177,20 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
167 handler_invoker(this, info->handler_callback, ctx); 177 handler_invoker(this, info->handler_callback, ctx);
168} 178}
169 179
180void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) {
181 boost::container::flat_map<u32, FunctionInfoBase>::iterator itr;
182
183 itr = handlers_tipc.find(ctx.GetCommand());
184
185 const FunctionInfoBase* info = itr == handlers_tipc.end() ? nullptr : &itr->second;
186 if (info == nullptr || info->handler_callback == nullptr) {
187 return ReportUnimplementedFunction(ctx, info);
188 }
189
190 LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer()));
191 handler_invoker(this, info->handler_callback, ctx);
192}
193
170ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, 194ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
171 Kernel::HLERequestContext& ctx) { 195 Kernel::HLERequestContext& ctx) {
172 const auto guard = LockService(); 196 const auto guard = LockService();
@@ -190,6 +214,11 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& sessi
190 break; 214 break;
191 } 215 }
192 default: 216 default:
217 if (ctx.IsTipc()) {
218 InvokeRequestTipc(ctx);
219 break;
220 }
221
193 UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); 222 UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType());
194 } 223 }
195 224
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 51e22a791..3dfb0740a 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -21,7 +21,9 @@ class System;
21 21
22namespace Kernel { 22namespace Kernel {
23class HLERequestContext; 23class HLERequestContext;
24} 24class KClientPort;
25class KServerSession;
26} // namespace Kernel
25 27
26namespace Service { 28namespace Service {
27 29
@@ -67,6 +69,10 @@ public:
67 69
68 /// Invokes a service request routine using the HIPC protocol. 70 /// Invokes a service request routine using the HIPC protocol.
69 void InvokeRequest(Kernel::HLERequestContext& ctx); 71 void InvokeRequest(Kernel::HLERequestContext& ctx);
72
73 /// Invokes a service request routine using the HIPC protocol.
74 void InvokeRequestTipc(Kernel::HLERequestContext& ctx);
75
70 /// Creates a port pair and registers it on the kernel's global port registry. 76 /// Creates a port pair and registers it on the kernel's global port registry.
71 Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel); 77 Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel);
72 78
@@ -105,6 +111,7 @@ private:
105 ~ServiceFrameworkBase() override; 111 ~ServiceFrameworkBase() override;
106 112
107 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); 113 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n);
114 void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n);
108 void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info); 115 void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info);
109 116
110 /// Identifier string used to connect to the service. 117 /// Identifier string used to connect to the service.
@@ -119,6 +126,7 @@ private:
119 /// Function used to safely up-cast pointers to the derived class before invoking a handler. 126 /// Function used to safely up-cast pointers to the derived class before invoking a handler.
120 InvokerFn* handler_invoker; 127 InvokerFn* handler_invoker;
121 boost::container::flat_map<u32, FunctionInfoBase> handlers; 128 boost::container::flat_map<u32, FunctionInfoBase> handlers;
129 boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc;
122 130
123 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. 131 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
124 Common::SpinLock lock_service; 132 Common::SpinLock lock_service;
@@ -186,6 +194,20 @@ protected:
186 RegisterHandlersBase(functions, n); 194 RegisterHandlersBase(functions, n);
187 } 195 }
188 196
197 /// Registers handlers in the service.
198 template <std::size_t N>
199 void RegisterHandlersTipc(const FunctionInfo (&functions)[N]) {
200 RegisterHandlersTipc(functions, N);
201 }
202
203 /**
204 * Registers handlers in the service. Usually prefer using the other RegisterHandlers
205 * overload in order to avoid needing to specify the array size.
206 */
207 void RegisterHandlersTipc(const FunctionInfo* functions, std::size_t n) {
208 RegisterHandlersBaseTipc(functions, n);
209 }
210
189private: 211private:
190 /** 212 /**
191 * This function is used to allow invocation of pointers to handlers stored in the base class 213 * This function is used to allow invocation of pointers to handlers stored in the base class