diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/service.cpp | 130 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 30 | ||||
| -rw-r--r-- | src/core/hle/service/srv.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 20 | 
4 files changed, 80 insertions, 106 deletions
| diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 355196fd3..e0979ea5d 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<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; +std::unordered_map<std::string, Kernel::SharedPtr<Interface>> 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<Interface>(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 e75d5008b..533d3565b 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -5,9 +5,10 @@  #pragma once  #include <algorithm> -#include <vector>  #include <map>  #include <string> +#include <unordered_map> +#include <vector>  #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<Interface*>     m_services; -    std::map<std::string, u32>  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<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; +/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. +extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;  } // namespace diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index aa0aac3bb..c50aebf15 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()); diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 88813c2ce..d253f4fe5 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -30,6 +30,11 @@ using Kernel::ERR_INVALID_HANDLE;  namespace SVC { +const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, +        ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA +const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, +        ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E +  /// An invalid result code that is meant to be overwritten when a thread resumes from waiting  const ResultCode RESULT_INVALID(0xDEADC0DE); @@ -94,14 +99,21 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o  }  /// Connect to an OS service given the port name, returns the handle to the port to out -static ResultCode ConnectToPort(Handle* out, const char* port_name) { -    Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); +static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { +    if (port_name == nullptr) +        return ERR_NOT_FOUND; +    if (std::strlen(port_name) > 11) +        return ERR_PORT_NAME_TOO_LONG;      LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); -    _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!"); -    *out = service->GetHandle(); +    auto it = Service::g_kernel_named_ports.find(port_name); +    if (it == Service::g_kernel_named_ports.end()) { +        LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name); +        return ERR_NOT_FOUND; +    } +    CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(it->second));      return RESULT_SUCCESS;  } | 
