From 8779b31fe60c728ace89a9b5128b68feffa9c7d7 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 30 Jan 2015 16:07:04 -0200 Subject: Make Port/Service registration and querying more HW-accurate --- src/core/hle/service/service.cpp | 130 +++++++++++++++++---------------------- src/core/hle/service/service.h | 30 ++------- src/core/hle/service/srv.cpp | 6 +- 3 files changed, 64 insertions(+), 102 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 355196fd..e0979ea5 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -54,96 +54,76 @@ namespace Service { -Manager* g_manager = nullptr; ///< Service manager +std::unordered_map> g_kernel_named_ports; +std::unordered_map> g_srv_services; //////////////////////////////////////////////////////////////////////////////////////////////////// -// Service Manager class - -void Manager::AddService(Interface* service) { - // TOOD(yuriks): Fix error reporting - m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); - m_services.push_back(service); -} - -void Manager::DeleteService(const std::string& port_name) { - Interface* service = FetchFromPortName(port_name); - m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); - m_port_map.erase(port_name); -} +// Module interface -Interface* Manager::FetchFromHandle(Handle handle) { - // TODO(yuriks): This function is very suspicious and should probably be exterminated. - return Kernel::g_handle_table.Get(handle).get(); +static void AddNamedPort(Interface* interface) { + g_kernel_named_ports.emplace(interface->GetPortName(), interface); } -Interface* Manager::FetchFromPortName(const std::string& port_name) { - auto itr = m_port_map.find(port_name); - if (itr == m_port_map.end()) { - return nullptr; - } - return FetchFromHandle(itr->second); +static void AddService(Interface* interface) { + g_srv_services.emplace(interface->GetPortName(), interface); } - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Module interface - /// Initialize ServiceManager void Init() { - g_manager = new Manager; - - g_manager->AddService(new SRV::Interface); - g_manager->AddService(new AC_U::Interface); - g_manager->AddService(new ACT_U::Interface); - g_manager->AddService(new AM_APP::Interface); - g_manager->AddService(new AM_NET::Interface); - g_manager->AddService(new AM_SYS::Interface); - g_manager->AddService(new APT_A::Interface); - g_manager->AddService(new APT_S::Interface); - g_manager->AddService(new APT_U::Interface); - g_manager->AddService(new BOSS_P::Interface); - g_manager->AddService(new BOSS_U::Interface); - g_manager->AddService(new CAM_U::Interface); - g_manager->AddService(new CECD_S::Interface); - g_manager->AddService(new CECD_U::Interface); - g_manager->AddService(new CFG_I::Interface); - g_manager->AddService(new CFG_S::Interface); - g_manager->AddService(new CFG_U::Interface); - g_manager->AddService(new CSND_SND::Interface); - g_manager->AddService(new DSP_DSP::Interface); - g_manager->AddService(new ERR_F::Interface); - g_manager->AddService(new FRD_A::Interface); - g_manager->AddService(new FRD_U::Interface); - g_manager->AddService(new FS::FSUserInterface); - g_manager->AddService(new GSP_GPU::Interface); - g_manager->AddService(new GSP_LCD::Interface); - g_manager->AddService(new HID_User::Interface); - g_manager->AddService(new HID_SPVR::Interface); - g_manager->AddService(new HTTP_C::Interface); - g_manager->AddService(new IR_RST::Interface); - g_manager->AddService(new IR_U::Interface); - g_manager->AddService(new LDR_RO::Interface); - g_manager->AddService(new MIC_U::Interface); - g_manager->AddService(new NDM_U::Interface); - g_manager->AddService(new NEWS_S::Interface); - g_manager->AddService(new NEWS_U::Interface); - g_manager->AddService(new NIM_AOC::Interface); - g_manager->AddService(new NS_S::Interface); - g_manager->AddService(new NWM_UDS::Interface); - g_manager->AddService(new PM_APP::Interface); - g_manager->AddService(new PTM_PLAY::Interface); - g_manager->AddService(new PTM_U::Interface); - g_manager->AddService(new PTM_SYSM::Interface); - g_manager->AddService(new SOC_U::Interface); - g_manager->AddService(new SSL_C::Interface); - g_manager->AddService(new Y2R_U::Interface); + AddNamedPort(new SRV::Interface); + + AddService(new AC_U::Interface); + AddService(new ACT_U::Interface); + AddService(new AM_APP::Interface); + AddService(new AM_NET::Interface); + AddService(new AM_SYS::Interface); + AddService(new APT_A::Interface); + AddService(new APT_S::Interface); + AddService(new APT_U::Interface); + AddService(new BOSS_P::Interface); + AddService(new BOSS_U::Interface); + AddService(new CAM_U::Interface); + AddService(new CECD_S::Interface); + AddService(new CECD_U::Interface); + AddService(new CFG_I::Interface); + AddService(new CFG_S::Interface); + AddService(new CFG_U::Interface); + AddService(new CSND_SND::Interface); + AddService(new DSP_DSP::Interface); + AddService(new ERR_F::Interface); + AddService(new FRD_A::Interface); + AddService(new FRD_U::Interface); + AddService(new FS::FSUserInterface); + AddService(new GSP_GPU::Interface); + AddService(new GSP_LCD::Interface); + AddService(new HID_User::Interface); + AddService(new HID_SPVR::Interface); + AddService(new HTTP_C::Interface); + AddService(new IR_RST::Interface); + AddService(new IR_U::Interface); + AddService(new LDR_RO::Interface); + AddService(new MIC_U::Interface); + AddService(new NDM_U::Interface); + AddService(new NEWS_S::Interface); + AddService(new NEWS_U::Interface); + AddService(new NIM_AOC::Interface); + AddService(new NS_S::Interface); + AddService(new NWM_UDS::Interface); + AddService(new PM_APP::Interface); + AddService(new PTM_PLAY::Interface); + AddService(new PTM_U::Interface); + AddService(new PTM_SYSM::Interface); + AddService(new SOC_U::Interface); + AddService(new SSL_C::Interface); + AddService(new Y2R_U::Interface); LOG_DEBUG(Service, "initialized OK"); } /// Shutdown ServiceManager void Shutdown() { - delete g_manager; + g_srv_services.clear(); + g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index e75d5008..533d3565 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -5,9 +5,10 @@ #pragma once #include -#include #include #include +#include +#include #include "common/common.h" #include "common/string_util.h" @@ -121,34 +122,15 @@ private: }; -/// Simple class to manage accessing services from ports and UID handles -class Manager { -public: - /// Add a service to the manager - void AddService(Interface* service); - - /// Removes a service from the manager - void DeleteService(const std::string& port_name); - - /// Get a Service Interface from its Handle - Interface* FetchFromHandle(Handle handle); - - /// Get a Service Interface from its port - Interface* FetchFromPortName(const std::string& port_name); - -private: - std::vector m_services; - std::map m_port_map; -}; - /// Initialize ServiceManager void Init(); /// Shutdown ServiceManager void Shutdown(); - -extern Manager* g_manager; ///< Service manager - +/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. +extern std::unordered_map> g_kernel_named_ports; +/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. +extern std::unordered_map> g_srv_services; } // namespace diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index aa0aac3b..c50aebf1 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -35,10 +35,10 @@ static void GetServiceHandle(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); - Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); + auto it = Service::g_srv_services.find(port_name); - if (nullptr != service) { - cmd_buff[3] = service->GetHandle(); + if (it != Service::g_srv_services.end()) { + cmd_buff[3] = Kernel::g_handle_table.Create(it->second).MoveFrom(); LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); } else { LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); -- cgit v1.2.3