mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
hle: kernel: Implement named service ports using service interface factory.
- This allows us to create a new interface each time ConnectToNamedPort is called, removing the assumption that these are static.
This commit is contained in:
parent
44c763f9c6
commit
c6de9657be
4 changed files with 30 additions and 22 deletions
|
@ -44,6 +44,7 @@
|
||||||
#include "core/hle/kernel/time_manager.h"
|
#include "core/hle/kernel/time_manager.h"
|
||||||
#include "core/hle/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
||||||
|
@ -656,6 +657,7 @@ struct KernelCore::Impl {
|
||||||
|
|
||||||
/// Map of named ports managed by the kernel, which can be retrieved using
|
/// Map of named ports managed by the kernel, which can be retrieved using
|
||||||
/// the ConnectToPort SVC.
|
/// the ConnectToPort SVC.
|
||||||
|
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
|
||||||
NamedPortTable named_ports;
|
NamedPortTable named_ports;
|
||||||
|
|
||||||
std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
|
std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
|
||||||
|
@ -844,18 +846,17 @@ void KernelCore::PrepareReschedule(std::size_t id) {
|
||||||
// TODO: Reimplement, this
|
// TODO: Reimplement, this
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::AddNamedPort(std::string name, KClientPort* port) {
|
void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory) {
|
||||||
port->Open();
|
impl->service_interface_factory.emplace(std::move(name), factory);
|
||||||
impl->named_ports.emplace(std::move(name), port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) {
|
KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
|
||||||
return impl->named_ports.find(name);
|
auto search = impl->service_interface_factory.find(name);
|
||||||
|
if (search == impl->service_interface_factory.end()) {
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
return &search->second(impl->system.ServiceManager(), impl->system);
|
||||||
KernelCore::NamedPortTable::const_iterator KernelCore::FindNamedPort(
|
|
||||||
const std::string& name) const {
|
|
||||||
return impl->named_ports.find(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
|
bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
|
||||||
|
|
|
@ -27,6 +27,10 @@ class CoreTiming;
|
||||||
struct EventType;
|
struct EventType;
|
||||||
} // namespace Core::Timing
|
} // namespace Core::Timing
|
||||||
|
|
||||||
|
namespace Service::SM {
|
||||||
|
class ServiceManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class KClientPort;
|
class KClientPort;
|
||||||
|
@ -51,6 +55,9 @@ class ServiceThread;
|
||||||
class Synchronization;
|
class Synchronization;
|
||||||
class TimeManager;
|
class TimeManager;
|
||||||
|
|
||||||
|
using ServiceInterfaceFactory =
|
||||||
|
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
|
||||||
|
|
||||||
namespace Init {
|
namespace Init {
|
||||||
struct KSlabResourceCounts;
|
struct KSlabResourceCounts;
|
||||||
}
|
}
|
||||||
|
@ -172,14 +179,11 @@ public:
|
||||||
|
|
||||||
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
|
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
|
||||||
|
|
||||||
/// Adds a port to the named port table
|
/// Registers a named HLE service, passing a factory used to open a port to that service.
|
||||||
void AddNamedPort(std::string name, KClientPort* port);
|
void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory);
|
||||||
|
|
||||||
/// Finds a port within the named port table with the given name.
|
/// Opens a port to a service previously registered with RegisterNamedService.
|
||||||
NamedPortTable::iterator FindNamedPort(const std::string& name);
|
KClientPort* CreateNamedServicePort(std::string name);
|
||||||
|
|
||||||
/// Finds a port within the named port table with the given name.
|
|
||||||
NamedPortTable::const_iterator FindNamedPort(const std::string& name) const;
|
|
||||||
|
|
||||||
/// Determines whether or not the given port is a valid named port.
|
/// Determines whether or not the given port is a valid named port.
|
||||||
bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
|
bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
|
||||||
|
|
|
@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
|
||||||
port_installed = true;
|
port_installed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) {
|
Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) {
|
||||||
const auto guard = LockService();
|
const auto guard = LockService();
|
||||||
|
|
||||||
ASSERT(!port_installed);
|
ASSERT(!port_installed);
|
||||||
|
@ -119,9 +119,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) {
|
||||||
auto* port = Kernel::KPort::Create(kernel);
|
auto* port = Kernel::KPort::Create(kernel);
|
||||||
port->Initialize(max_sessions, false, service_name);
|
port->Initialize(max_sessions, false, service_name);
|
||||||
port->GetServerPort().SetHleHandler(shared_from_this());
|
port->GetServerPort().SetHleHandler(shared_from_this());
|
||||||
kernel.AddNamedPort(service_name, &port->GetClientPort());
|
|
||||||
|
|
||||||
port_installed = true;
|
port_installed = true;
|
||||||
|
|
||||||
|
return port->GetClientPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
|
void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
|
||||||
|
|
|
@ -64,10 +64,12 @@ public:
|
||||||
|
|
||||||
/// Creates a port pair and registers this service with the given ServiceManager.
|
/// Creates a port pair and registers this service with the given ServiceManager.
|
||||||
void InstallAsService(SM::ServiceManager& service_manager);
|
void InstallAsService(SM::ServiceManager& service_manager);
|
||||||
/// Creates a port pair and registers it on the kernel's global port registry.
|
|
||||||
void InstallAsNamedPort(Kernel::KernelCore& kernel);
|
/// Invokes a service request routine using the HIPC protocol.
|
||||||
/// Invokes a service request routine.
|
|
||||||
void InvokeRequest(Kernel::HLERequestContext& ctx);
|
void InvokeRequest(Kernel::HLERequestContext& ctx);
|
||||||
|
/// Creates a port pair and registers it on the kernel's global port registry.
|
||||||
|
Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel);
|
||||||
|
|
||||||
/// Handles a synchronization request for the service.
|
/// Handles a synchronization request for the service.
|
||||||
ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override;
|
ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue