summaryrefslogtreecommitdiff
path: root/src/core/hle/service
diff options
context:
space:
mode:
authorGravatar bunnei2019-11-30 18:56:35 -0500
committerGravatar GitHub2019-11-30 18:56:35 -0500
commit5c7253f8d3c010c0a0e5c91db497819829cb4a43 (patch)
treec2aa6989d3f081c07c72c3ab4a698c73ecd8c429 /src/core/hle/service
parentMerge pull request #3184 from ReinUsesLisp/framebuffer-cache (diff)
parentkernel: Implement a more accurate IPC dispatch. (diff)
downloadyuzu-5c7253f8d3c010c0a0e5c91db497819829cb4a43.tar.gz
yuzu-5c7253f8d3c010c0a0e5c91db497819829cb4a43.tar.xz
yuzu-5c7253f8d3c010c0a0e5c91db497819829cb4a43.zip
Merge pull request #3177 from bunnei/new-ipc-req
kernel: Implement a more accurate IPC dispatch.
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/nfp/nfp.cpp2
-rw-r--r--src/core/hle/service/service.cpp4
-rw-r--r--src/core/hle/service/sm/controller.cpp5
-rw-r--r--src/core/hle/service/sm/sm.cpp33
-rw-r--r--src/core/hle/service/sm/sm.h6
5 files changed, 28 insertions, 22 deletions
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index ec0367978..4b79eb81d 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -189,7 +189,7 @@ private:
189 LOG_DEBUG(Service_NFP, "called"); 189 LOG_DEBUG(Service_NFP, "called");
190 190
191 auto nfc_event = nfp_interface.GetNFCEvent(); 191 auto nfc_event = nfp_interface.GetNFCEvent();
192 if (!nfc_event->ShouldWait(Kernel::GetCurrentThread()) && !has_attached_handle) { 192 if (!nfc_event->ShouldWait(&ctx.GetThread()) && !has_attached_handle) {
193 device_state = DeviceState::TagFound; 193 device_state = DeviceState::TagFound;
194 nfc_event->Clear(); 194 nfc_event->Clear();
195 } 195 }
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 5698f429f..fa5347af9 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -186,7 +186,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
186 UNIMPLEMENTED_MSG("command_type={}", static_cast<int>(context.GetCommandType())); 186 UNIMPLEMENTED_MSG("command_type={}", static_cast<int>(context.GetCommandType()));
187 } 187 }
188 188
189 context.WriteToOutgoingCommandBuffer(*Kernel::GetCurrentThread()); 189 context.WriteToOutgoingCommandBuffer(context.GetThread());
190 190
191 return RESULT_SUCCESS; 191 return RESULT_SUCCESS;
192} 192}
@@ -201,7 +201,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
201 auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system); 201 auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system);
202 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); 202 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
203 203
204 SM::ServiceManager::InstallInterfaces(sm); 204 SM::ServiceManager::InstallInterfaces(sm, system.Kernel());
205 205
206 Account::InstallInterfaces(system); 206 Account::InstallInterfaces(system);
207 AM::InstallInterfaces(*sm, nv_flinger, system); 207 AM::InstallInterfaces(*sm, nv_flinger, system);
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp
index af2fadcef..c45b285f8 100644
--- a/src/core/hle/service/sm/controller.cpp
+++ b/src/core/hle/service/sm/controller.cpp
@@ -30,10 +30,7 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
30 30
31 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 31 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
32 rb.Push(RESULT_SUCCESS); 32 rb.Push(RESULT_SUCCESS);
33 std::shared_ptr<Kernel::ClientSession> session{ctx.Session()->GetParent()->client}; 33 rb.PushMoveObjects(ctx.Session()->GetParent()->Client());
34 rb.PushMoveObjects(session);
35
36 LOG_DEBUG(Service, "session={}", session->GetObjectId());
37} 34}
38 35
39void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { 36void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index a0a7206bb..88909504d 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -36,10 +36,11 @@ static ResultCode ValidateServiceName(const std::string& name) {
36 return RESULT_SUCCESS; 36 return RESULT_SUCCESS;
37} 37}
38 38
39void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self) { 39void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self,
40 Kernel::KernelCore& kernel) {
40 ASSERT(self->sm_interface.expired()); 41 ASSERT(self->sm_interface.expired());
41 42
42 auto sm = std::make_shared<SM>(self); 43 auto sm = std::make_shared<SM>(self, kernel);
43 sm->InstallAsNamedPort(); 44 sm->InstallAsNamedPort();
44 self->sm_interface = sm; 45 self->sm_interface = sm;
45 self->controller_interface = std::make_unique<Controller>(); 46 self->controller_interface = std::make_unique<Controller>();
@@ -114,8 +115,6 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
114 115
115 std::string name(name_buf.begin(), end); 116 std::string name(name_buf.begin(), end);
116 117
117 // TODO(yuriks): Permission checks go here
118
119 auto client_port = service_manager->GetServicePort(name); 118 auto client_port = service_manager->GetServicePort(name);
120 if (client_port.Failed()) { 119 if (client_port.Failed()) {
121 IPC::ResponseBuilder rb{ctx, 2}; 120 IPC::ResponseBuilder rb{ctx, 2};
@@ -127,14 +126,22 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
127 return; 126 return;
128 } 127 }
129 128
130 auto session = client_port.Unwrap()->Connect(); 129 auto [client, server] = Kernel::Session::Create(kernel, name);
131 ASSERT(session.Succeeded()); 130
132 if (session.Succeeded()) { 131 const auto& server_port = client_port.Unwrap()->GetServerPort();
133 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); 132 if (server_port->GetHLEHandler()) {
134 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 133 server_port->GetHLEHandler()->ClientConnected(server);
135 rb.Push(session.Code()); 134 } else {
136 rb.PushMoveObjects(std::move(session).Unwrap()); 135 server_port->AppendPendingSession(server);
137 } 136 }
137
138 // Wake the threads waiting on the ServerPort
139 server_port->WakeupAllWaitingThreads();
140
141 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId());
142 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
143 rb.Push(RESULT_SUCCESS);
144 rb.PushMoveObjects(std::move(client));
138} 145}
139 146
140void SM::RegisterService(Kernel::HLERequestContext& ctx) { 147void SM::RegisterService(Kernel::HLERequestContext& ctx) {
@@ -178,8 +185,8 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) {
178 rb.Push(service_manager->UnregisterService(name)); 185 rb.Push(service_manager->UnregisterService(name));
179} 186}
180 187
181SM::SM(std::shared_ptr<ServiceManager> service_manager) 188SM::SM(std::shared_ptr<ServiceManager> service_manager, Kernel::KernelCore& kernel)
182 : ServiceFramework("sm:", 4), service_manager(std::move(service_manager)) { 189 : ServiceFramework{"sm:", 4}, service_manager{std::move(service_manager)}, kernel{kernel} {
183 static const FunctionInfo functions[] = { 190 static const FunctionInfo functions[] = {
184 {0x00000000, &SM::Initialize, "Initialize"}, 191 {0x00000000, &SM::Initialize, "Initialize"},
185 {0x00000001, &SM::GetService, "GetService"}, 192 {0x00000001, &SM::GetService, "GetService"},
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 3de22268b..b06d2f103 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -18,6 +18,7 @@
18namespace Kernel { 18namespace Kernel {
19class ClientPort; 19class ClientPort;
20class ClientSession; 20class ClientSession;
21class KernelCore;
21class ServerPort; 22class ServerPort;
22class SessionRequestHandler; 23class SessionRequestHandler;
23} // namespace Kernel 24} // namespace Kernel
@@ -29,7 +30,7 @@ class Controller;
29/// Interface to "sm:" service 30/// Interface to "sm:" service
30class SM final : public ServiceFramework<SM> { 31class SM final : public ServiceFramework<SM> {
31public: 32public:
32 explicit SM(std::shared_ptr<ServiceManager> service_manager); 33 explicit SM(std::shared_ptr<ServiceManager> service_manager, Kernel::KernelCore& kernel);
33 ~SM() override; 34 ~SM() override;
34 35
35private: 36private:
@@ -39,11 +40,12 @@ private:
39 void UnregisterService(Kernel::HLERequestContext& ctx); 40 void UnregisterService(Kernel::HLERequestContext& ctx);
40 41
41 std::shared_ptr<ServiceManager> service_manager; 42 std::shared_ptr<ServiceManager> service_manager;
43 Kernel::KernelCore& kernel;
42}; 44};
43 45
44class ServiceManager { 46class ServiceManager {
45public: 47public:
46 static void InstallInterfaces(std::shared_ptr<ServiceManager> self); 48 static void InstallInterfaces(std::shared_ptr<ServiceManager> self, Kernel::KernelCore& kernel);
47 49
48 ServiceManager(); 50 ServiceManager();
49 ~ServiceManager(); 51 ~ServiceManager();