hle: service: Add support for dispatching TIPC requests.
This commit is contained in:
parent
da25a59866
commit
21671d05a3
|
@ -133,6 +133,16 @@ void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions,
|
||||||
|
std::size_t n) {
|
||||||
|
handlers_tipc.reserve(handlers_tipc.size() + n);
|
||||||
|
for (std::size_t i = 0; i < n; ++i) {
|
||||||
|
// Usually this array is sorted by id already, so hint to insert at the end
|
||||||
|
handlers_tipc.emplace_hint(handlers_tipc.cend(), functions[i].expected_header,
|
||||||
|
functions[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx,
|
void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx,
|
||||||
const FunctionInfoBase* info) {
|
const FunctionInfoBase* info) {
|
||||||
auto cmd_buf = ctx.CommandBuffer();
|
auto cmd_buf = ctx.CommandBuffer();
|
||||||
|
@ -167,6 +177,20 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
|
||||||
handler_invoker(this, info->handler_callback, ctx);
|
handler_invoker(this, info->handler_callback, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) {
|
||||||
|
boost::container::flat_map<u32, FunctionInfoBase>::iterator itr;
|
||||||
|
|
||||||
|
itr = handlers_tipc.find(ctx.GetCommand());
|
||||||
|
|
||||||
|
const FunctionInfoBase* info = itr == handlers_tipc.end() ? nullptr : &itr->second;
|
||||||
|
if (info == nullptr || info->handler_callback == nullptr) {
|
||||||
|
return ReportUnimplementedFunction(ctx, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer()));
|
||||||
|
handler_invoker(this, info->handler_callback, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
|
ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
|
||||||
Kernel::HLERequestContext& ctx) {
|
Kernel::HLERequestContext& ctx) {
|
||||||
const auto guard = LockService();
|
const auto guard = LockService();
|
||||||
|
@ -190,6 +214,11 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& sessi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
if (ctx.IsTipc()) {
|
||||||
|
InvokeRequestTipc(ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType());
|
UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,9 @@ class System;
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
}
|
class KClientPort;
|
||||||
|
class KServerSession;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
|
|
||||||
|
@ -67,6 +69,10 @@ public:
|
||||||
|
|
||||||
/// Invokes a service request routine using the HIPC protocol.
|
/// Invokes a service request routine using the HIPC protocol.
|
||||||
void InvokeRequest(Kernel::HLERequestContext& ctx);
|
void InvokeRequest(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
/// Invokes a service request routine using the HIPC protocol.
|
||||||
|
void InvokeRequestTipc(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
/// Creates a port pair and registers it on the kernel's global port registry.
|
/// Creates a port pair and registers it on the kernel's global port registry.
|
||||||
Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel);
|
Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel);
|
||||||
|
|
||||||
|
@ -105,6 +111,7 @@ private:
|
||||||
~ServiceFrameworkBase() override;
|
~ServiceFrameworkBase() override;
|
||||||
|
|
||||||
void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n);
|
void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n);
|
||||||
|
void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n);
|
||||||
void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info);
|
void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info);
|
||||||
|
|
||||||
/// Identifier string used to connect to the service.
|
/// Identifier string used to connect to the service.
|
||||||
|
@ -119,6 +126,7 @@ private:
|
||||||
/// Function used to safely up-cast pointers to the derived class before invoking a handler.
|
/// Function used to safely up-cast pointers to the derived class before invoking a handler.
|
||||||
InvokerFn* handler_invoker;
|
InvokerFn* handler_invoker;
|
||||||
boost::container::flat_map<u32, FunctionInfoBase> handlers;
|
boost::container::flat_map<u32, FunctionInfoBase> handlers;
|
||||||
|
boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc;
|
||||||
|
|
||||||
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
|
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
|
||||||
Common::SpinLock lock_service;
|
Common::SpinLock lock_service;
|
||||||
|
@ -186,6 +194,20 @@ protected:
|
||||||
RegisterHandlersBase(functions, n);
|
RegisterHandlersBase(functions, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registers handlers in the service.
|
||||||
|
template <std::size_t N>
|
||||||
|
void RegisterHandlersTipc(const FunctionInfo (&functions)[N]) {
|
||||||
|
RegisterHandlersTipc(functions, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers handlers in the service. Usually prefer using the other RegisterHandlers
|
||||||
|
* overload in order to avoid needing to specify the array size.
|
||||||
|
*/
|
||||||
|
void RegisterHandlersTipc(const FunctionInfo* functions, std::size_t n) {
|
||||||
|
RegisterHandlersBaseTipc(functions, n);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* This function is used to allow invocation of pointers to handlers stored in the base class
|
* This function is used to allow invocation of pointers to handlers stored in the base class
|
||||||
|
|
Loading…
Reference in New Issue