diff options
| author | 2019-11-30 18:56:35 -0500 | |
|---|---|---|
| committer | 2019-11-30 18:56:35 -0500 | |
| commit | 5c7253f8d3c010c0a0e5c91db497819829cb4a43 (patch) | |
| tree | c2aa6989d3f081c07c72c3ab4a698c73ecd8c429 /src/core/hle/service | |
| parent | Merge pull request #3184 from ReinUsesLisp/framebuffer-cache (diff) | |
| parent | kernel: Implement a more accurate IPC dispatch. (diff) | |
| download | yuzu-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.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/sm/controller.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 33 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 6 |
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 | ||
| 39 | void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { | 36 | void 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 | ||
| 39 | void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self) { | 39 | void 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 | ||
| 140 | void SM::RegisterService(Kernel::HLERequestContext& ctx) { | 147 | void 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 | ||
| 181 | SM::SM(std::shared_ptr<ServiceManager> service_manager) | 188 | SM::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 @@ | |||
| 18 | namespace Kernel { | 18 | namespace Kernel { |
| 19 | class ClientPort; | 19 | class ClientPort; |
| 20 | class ClientSession; | 20 | class ClientSession; |
| 21 | class KernelCore; | ||
| 21 | class ServerPort; | 22 | class ServerPort; |
| 22 | class SessionRequestHandler; | 23 | class SessionRequestHandler; |
| 23 | } // namespace Kernel | 24 | } // namespace Kernel |
| @@ -29,7 +30,7 @@ class Controller; | |||
| 29 | /// Interface to "sm:" service | 30 | /// Interface to "sm:" service |
| 30 | class SM final : public ServiceFramework<SM> { | 31 | class SM final : public ServiceFramework<SM> { |
| 31 | public: | 32 | public: |
| 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 | ||
| 35 | private: | 36 | private: |
| @@ -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 | ||
| 44 | class ServiceManager { | 46 | class ServiceManager { |
| 45 | public: | 47 | public: |
| 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(); |