summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-01-30 16:07:04 -0200
committerGravatar Yuri Kunde Schlesner2015-02-02 15:36:59 -0200
commit8779b31fe60c728ace89a9b5128b68feffa9c7d7 (patch)
treeb83440cbe4187f1fe120a5a247919a1ecbb1c65d /src
parentFilesys: Move creation of Handles for File/Directory to service handlers (diff)
downloadyuzu-8779b31fe60c728ace89a9b5128b68feffa9c7d7.tar.gz
yuzu-8779b31fe60c728ace89a9b5128b68feffa9c7d7.tar.xz
yuzu-8779b31fe60c728ace89a9b5128b68feffa9c7d7.zip
Make Port/Service registration and querying more HW-accurate
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/service.cpp130
-rw-r--r--src/core/hle/service/service.h30
-rw-r--r--src/core/hle/service/srv.cpp6
-rw-r--r--src/core/hle/svc.cpp20
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 @@
54 54
55namespace Service { 55namespace Service {
56 56
57Manager* g_manager = nullptr; ///< Service manager 57std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
58std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
58 59
59//////////////////////////////////////////////////////////////////////////////////////////////////// 60////////////////////////////////////////////////////////////////////////////////////////////////////
60// Service Manager class 61// Module interface
61
62void Manager::AddService(Interface* service) {
63 // TOOD(yuriks): Fix error reporting
64 m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE);
65 m_services.push_back(service);
66}
67
68void Manager::DeleteService(const std::string& port_name) {
69 Interface* service = FetchFromPortName(port_name);
70 m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end());
71 m_port_map.erase(port_name);
72}
73 62
74Interface* Manager::FetchFromHandle(Handle handle) { 63static void AddNamedPort(Interface* interface) {
75 // TODO(yuriks): This function is very suspicious and should probably be exterminated. 64 g_kernel_named_ports.emplace(interface->GetPortName(), interface);
76 return Kernel::g_handle_table.Get<Interface>(handle).get();
77} 65}
78 66
79Interface* Manager::FetchFromPortName(const std::string& port_name) { 67static void AddService(Interface* interface) {
80 auto itr = m_port_map.find(port_name); 68 g_srv_services.emplace(interface->GetPortName(), interface);
81 if (itr == m_port_map.end()) {
82 return nullptr;
83 }
84 return FetchFromHandle(itr->second);
85} 69}
86 70
87
88////////////////////////////////////////////////////////////////////////////////////////////////////
89// Module interface
90
91/// Initialize ServiceManager 71/// Initialize ServiceManager
92void Init() { 72void Init() {
93 g_manager = new Manager; 73 AddNamedPort(new SRV::Interface);
94 74
95 g_manager->AddService(new SRV::Interface); 75 AddService(new AC_U::Interface);
96 g_manager->AddService(new AC_U::Interface); 76 AddService(new ACT_U::Interface);
97 g_manager->AddService(new ACT_U::Interface); 77 AddService(new AM_APP::Interface);
98 g_manager->AddService(new AM_APP::Interface); 78 AddService(new AM_NET::Interface);
99 g_manager->AddService(new AM_NET::Interface); 79 AddService(new AM_SYS::Interface);
100 g_manager->AddService(new AM_SYS::Interface); 80 AddService(new APT_A::Interface);
101 g_manager->AddService(new APT_A::Interface); 81 AddService(new APT_S::Interface);
102 g_manager->AddService(new APT_S::Interface); 82 AddService(new APT_U::Interface);
103 g_manager->AddService(new APT_U::Interface); 83 AddService(new BOSS_P::Interface);
104 g_manager->AddService(new BOSS_P::Interface); 84 AddService(new BOSS_U::Interface);
105 g_manager->AddService(new BOSS_U::Interface); 85 AddService(new CAM_U::Interface);
106 g_manager->AddService(new CAM_U::Interface); 86 AddService(new CECD_S::Interface);
107 g_manager->AddService(new CECD_S::Interface); 87 AddService(new CECD_U::Interface);
108 g_manager->AddService(new CECD_U::Interface); 88 AddService(new CFG_I::Interface);
109 g_manager->AddService(new CFG_I::Interface); 89 AddService(new CFG_S::Interface);
110 g_manager->AddService(new CFG_S::Interface); 90 AddService(new CFG_U::Interface);
111 g_manager->AddService(new CFG_U::Interface); 91 AddService(new CSND_SND::Interface);
112 g_manager->AddService(new CSND_SND::Interface); 92 AddService(new DSP_DSP::Interface);
113 g_manager->AddService(new DSP_DSP::Interface); 93 AddService(new ERR_F::Interface);
114 g_manager->AddService(new ERR_F::Interface); 94 AddService(new FRD_A::Interface);
115 g_manager->AddService(new FRD_A::Interface); 95 AddService(new FRD_U::Interface);
116 g_manager->AddService(new FRD_U::Interface); 96 AddService(new FS::FSUserInterface);
117 g_manager->AddService(new FS::FSUserInterface); 97 AddService(new GSP_GPU::Interface);
118 g_manager->AddService(new GSP_GPU::Interface); 98 AddService(new GSP_LCD::Interface);
119 g_manager->AddService(new GSP_LCD::Interface); 99 AddService(new HID_User::Interface);
120 g_manager->AddService(new HID_User::Interface); 100 AddService(new HID_SPVR::Interface);
121 g_manager->AddService(new HID_SPVR::Interface); 101 AddService(new HTTP_C::Interface);
122 g_manager->AddService(new HTTP_C::Interface); 102 AddService(new IR_RST::Interface);
123 g_manager->AddService(new IR_RST::Interface); 103 AddService(new IR_U::Interface);
124 g_manager->AddService(new IR_U::Interface); 104 AddService(new LDR_RO::Interface);
125 g_manager->AddService(new LDR_RO::Interface); 105 AddService(new MIC_U::Interface);
126 g_manager->AddService(new MIC_U::Interface); 106 AddService(new NDM_U::Interface);
127 g_manager->AddService(new NDM_U::Interface); 107 AddService(new NEWS_S::Interface);
128 g_manager->AddService(new NEWS_S::Interface); 108 AddService(new NEWS_U::Interface);
129 g_manager->AddService(new NEWS_U::Interface); 109 AddService(new NIM_AOC::Interface);
130 g_manager->AddService(new NIM_AOC::Interface); 110 AddService(new NS_S::Interface);
131 g_manager->AddService(new NS_S::Interface); 111 AddService(new NWM_UDS::Interface);
132 g_manager->AddService(new NWM_UDS::Interface); 112 AddService(new PM_APP::Interface);
133 g_manager->AddService(new PM_APP::Interface); 113 AddService(new PTM_PLAY::Interface);
134 g_manager->AddService(new PTM_PLAY::Interface); 114 AddService(new PTM_U::Interface);
135 g_manager->AddService(new PTM_U::Interface); 115 AddService(new PTM_SYSM::Interface);
136 g_manager->AddService(new PTM_SYSM::Interface); 116 AddService(new SOC_U::Interface);
137 g_manager->AddService(new SOC_U::Interface); 117 AddService(new SSL_C::Interface);
138 g_manager->AddService(new SSL_C::Interface); 118 AddService(new Y2R_U::Interface);
139 g_manager->AddService(new Y2R_U::Interface);
140 119
141 LOG_DEBUG(Service, "initialized OK"); 120 LOG_DEBUG(Service, "initialized OK");
142} 121}
143 122
144/// Shutdown ServiceManager 123/// Shutdown ServiceManager
145void Shutdown() { 124void Shutdown() {
146 delete g_manager; 125 g_srv_services.clear();
126 g_kernel_named_ports.clear();
147 LOG_DEBUG(Service, "shutdown OK"); 127 LOG_DEBUG(Service, "shutdown OK");
148} 128}
149 129
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 @@
5#pragma once 5#pragma once
6 6
7#include <algorithm> 7#include <algorithm>
8#include <vector>
9#include <map> 8#include <map>
10#include <string> 9#include <string>
10#include <unordered_map>
11#include <vector>
11 12
12#include "common/common.h" 13#include "common/common.h"
13#include "common/string_util.h" 14#include "common/string_util.h"
@@ -121,34 +122,15 @@ private:
121 122
122}; 123};
123 124
124/// Simple class to manage accessing services from ports and UID handles
125class Manager {
126public:
127 /// Add a service to the manager
128 void AddService(Interface* service);
129
130 /// Removes a service from the manager
131 void DeleteService(const std::string& port_name);
132
133 /// Get a Service Interface from its Handle
134 Interface* FetchFromHandle(Handle handle);
135
136 /// Get a Service Interface from its port
137 Interface* FetchFromPortName(const std::string& port_name);
138
139private:
140 std::vector<Interface*> m_services;
141 std::map<std::string, u32> m_port_map;
142};
143
144/// Initialize ServiceManager 125/// Initialize ServiceManager
145void Init(); 126void Init();
146 127
147/// Shutdown ServiceManager 128/// Shutdown ServiceManager
148void Shutdown(); 129void Shutdown();
149 130
150 131/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC.
151extern Manager* g_manager; ///< Service manager 132extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
152 133/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle.
134extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
153 135
154} // namespace 136} // 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) {
35 u32* cmd_buff = Kernel::GetCommandBuffer(); 35 u32* cmd_buff = Kernel::GetCommandBuffer();
36 36
37 std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); 37 std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
38 Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); 38 auto it = Service::g_srv_services.find(port_name);
39 39
40 if (nullptr != service) { 40 if (it != Service::g_srv_services.end()) {
41 cmd_buff[3] = service->GetHandle(); 41 cmd_buff[3] = Kernel::g_handle_table.Create(it->second).MoveFrom();
42 LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); 42 LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]);
43 } else { 43 } else {
44 LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); 44 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;
30 30
31namespace SVC { 31namespace SVC {
32 32
33const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel,
34 ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA
35const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS,
36 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E
37
33/// An invalid result code that is meant to be overwritten when a thread resumes from waiting 38/// An invalid result code that is meant to be overwritten when a thread resumes from waiting
34const ResultCode RESULT_INVALID(0xDEADC0DE); 39const ResultCode RESULT_INVALID(0xDEADC0DE);
35 40
@@ -94,14 +99,21 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
94} 99}
95 100
96/// Connect to an OS service given the port name, returns the handle to the port to out 101/// Connect to an OS service given the port name, returns the handle to the port to out
97static ResultCode ConnectToPort(Handle* out, const char* port_name) { 102static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) {
98 Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); 103 if (port_name == nullptr)
104 return ERR_NOT_FOUND;
105 if (std::strlen(port_name) > 11)
106 return ERR_PORT_NAME_TOO_LONG;
99 107
100 LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); 108 LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name);
101 _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!");
102 109
103 *out = service->GetHandle(); 110 auto it = Service::g_kernel_named_ports.find(port_name);
111 if (it == Service::g_kernel_named_ports.end()) {
112 LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name);
113 return ERR_NOT_FOUND;
114 }
104 115
116 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(it->second));
105 return RESULT_SUCCESS; 117 return RESULT_SUCCESS;
106} 118}
107 119