summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc
diff options
context:
space:
mode:
authorGravatar Liam2023-12-06 19:54:52 -0500
committerGravatar Liam2023-12-07 09:13:43 -0500
commit9268f265a1207f0cddb97a908a1cc349f9b6410b (patch)
tree5da6aea714523b3504b78362c5d8abd53689d72f /src/core/hle/kernel/svc
parentMerge pull request #12236 from liamwhite/cpu-refactor (diff)
downloadyuzu-9268f265a1207f0cddb97a908a1cc349f9b6410b.tar.gz
yuzu-9268f265a1207f0cddb97a908a1cc349f9b6410b.tar.xz
yuzu-9268f265a1207f0cddb97a908a1cc349f9b6410b.zip
kernel: implement light IPC
Diffstat (limited to 'src/core/hle/kernel/svc')
-rw-r--r--src/core/hle/kernel/svc/svc_light_ipc.cpp29
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp71
-rw-r--r--src/core/hle/kernel/svc/svc_session.cpp40
3 files changed, 124 insertions, 16 deletions
diff --git a/src/core/hle/kernel/svc/svc_light_ipc.cpp b/src/core/hle/kernel/svc/svc_light_ipc.cpp
index d757d5af2..4772cbda1 100644
--- a/src/core/hle/kernel/svc/svc_light_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_light_ipc.cpp
@@ -1,21 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/arm/arm_interface.h"
5#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/kernel/k_light_client_session.h"
6#include "core/hle/kernel/k_light_server_session.h"
7#include "core/hle/kernel/k_process.h"
8#include "core/hle/kernel/k_thread.h"
6#include "core/hle/kernel/svc.h" 9#include "core/hle/kernel/svc.h"
7#include "core/hle/kernel/svc_results.h" 10#include "core/hle/kernel/svc_results.h"
8 11
9namespace Kernel::Svc { 12namespace Kernel::Svc {
10 13
11Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) { 14Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) {
12 UNIMPLEMENTED(); 15 // Get the light client session from its handle.
13 R_THROW(ResultNotImplemented); 16 KScopedAutoObject session = GetCurrentProcess(system.Kernel())
17 .GetHandleTable()
18 .GetObject<KLightClientSession>(session_handle);
19 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
20
21 // Send the request.
22 R_TRY(session->SendSyncRequest(args));
23
24 R_SUCCEED();
14} 25}
15 26
16Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) { 27Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) {
17 UNIMPLEMENTED(); 28 // Get the light server session from its handle.
18 R_THROW(ResultNotImplemented); 29 KScopedAutoObject session = GetCurrentProcess(system.Kernel())
30 .GetHandleTable()
31 .GetObject<KLightServerSession>(session_handle);
32 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
33
34 // Handle the request.
35 R_TRY(session->ReplyAndReceive(args));
36
37 R_SUCCEED();
19} 38}
20 39
21Result SendSyncRequestLight64(Core::System& system, Handle session_handle, u32* args) { 40Result SendSyncRequestLight64(Core::System& system, Handle session_handle, u32* args) {
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index abba757c7..737749f7d 100644
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -5,6 +5,7 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/k_client_port.h" 6#include "core/hle/kernel/k_client_port.h"
7#include "core/hle/kernel/k_client_session.h" 7#include "core/hle/kernel/k_client_session.h"
8#include "core/hle/kernel/k_light_client_session.h"
8#include "core/hle/kernel/k_object_name.h" 9#include "core/hle/kernel/k_object_name.h"
9#include "core/hle/kernel/k_port.h" 10#include "core/hle/kernel/k_port.h"
10#include "core/hle/kernel/k_process.h" 11#include "core/hle/kernel/k_process.h"
@@ -51,13 +52,73 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) {
51 52
52Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, 53Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
53 int32_t max_sessions, bool is_light, uint64_t name) { 54 int32_t max_sessions, bool is_light, uint64_t name) {
54 UNIMPLEMENTED(); 55 auto& kernel = system.Kernel();
55 R_THROW(ResultNotImplemented); 56
57 // Ensure max sessions is valid.
58 R_UNLESS(max_sessions > 0, ResultOutOfRange);
59
60 // Get the current handle table.
61 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
62
63 // Create a new port.
64 KPort* port = KPort::Create(kernel);
65 R_UNLESS(port != nullptr, ResultOutOfResource);
66
67 // Initialize the port.
68 port->Initialize(max_sessions, is_light, name);
69
70 // Ensure that we clean up the port (and its only references are handle table) on function end.
71 SCOPE_EXIT({
72 port->GetServerPort().Close();
73 port->GetClientPort().Close();
74 });
75
76 // Register the port.
77 KPort::Register(kernel, port);
78
79 // Add the client to the handle table.
80 R_TRY(handle_table.Add(out_client, std::addressof(port->GetClientPort())));
81
82 // Ensure that we maintain a clean handle state on exit.
83 ON_RESULT_FAILURE {
84 handle_table.Remove(*out_client);
85 };
86
87 // Add the server to the handle table.
88 R_RETURN(handle_table.Add(out_server, std::addressof(port->GetServerPort())));
56} 89}
57 90
58Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) { 91Result ConnectToPort(Core::System& system, Handle* out, Handle port) {
59 UNIMPLEMENTED(); 92 // Get the current handle table.
60 R_THROW(ResultNotImplemented); 93 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
94
95 // Get the client port.
96 KScopedAutoObject client_port = handle_table.GetObject<KClientPort>(port);
97 R_UNLESS(client_port.IsNotNull(), ResultInvalidHandle);
98
99 // Reserve a handle for the port.
100 // NOTE: Nintendo really does write directly to the output handle here.
101 R_TRY(handle_table.Reserve(out));
102 ON_RESULT_FAILURE {
103 handle_table.Unreserve(*out);
104 };
105
106 // Create the session.
107 KAutoObject* session;
108 if (client_port->IsLight()) {
109 R_TRY(client_port->CreateLightSession(
110 reinterpret_cast<KLightClientSession**>(std::addressof(session))));
111 } else {
112 R_TRY(client_port->CreateSession(
113 reinterpret_cast<KClientSession**>(std::addressof(session))));
114 }
115
116 // Register the session.
117 handle_table.Register(*out, session);
118 session->Close();
119
120 // We succeeded.
121 R_SUCCEED();
61} 122}
62 123
63Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, 124Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
diff --git a/src/core/hle/kernel/svc/svc_session.cpp b/src/core/hle/kernel/svc/svc_session.cpp
index 01b8a52ad..2f5905f32 100644
--- a/src/core/hle/kernel/svc/svc_session.cpp
+++ b/src/core/hle/kernel/svc/svc_session.cpp
@@ -3,8 +3,10 @@
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/k_light_session.h"
6#include "core/hle/kernel/k_process.h" 7#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/k_scoped_resource_reservation.h" 8#include "core/hle/kernel/k_scoped_resource_reservation.h"
9#include "core/hle/kernel/k_server_port.h"
8#include "core/hle/kernel/k_session.h" 10#include "core/hle/kernel/k_session.h"
9#include "core/hle/kernel/svc.h" 11#include "core/hle/kernel/svc.h"
10 12
@@ -20,7 +22,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
20 T* session; 22 T* session;
21 23
22 // Reserve a new session from the process resource limit. 24 // Reserve a new session from the process resource limit.
23 // FIXME: LimitableResource_SessionCountMax 25 // TODO: Dynamic resource limits
24 KScopedResourceReservation session_reservation(std::addressof(process), 26 KScopedResourceReservation session_reservation(std::addressof(process),
25 LimitableResource::SessionCountMax); 27 LimitableResource::SessionCountMax);
26 if (session_reservation.Succeeded()) { 28 if (session_reservation.Succeeded()) {
@@ -92,16 +94,42 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
92Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, bool is_light, 94Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, bool is_light,
93 u64 name) { 95 u64 name) {
94 if (is_light) { 96 if (is_light) {
95 // return CreateSession<KLightSession>(system, out_server, out_client, name); 97 R_RETURN(CreateSession<KLightSession>(system, out_server, out_client, name));
96 R_THROW(ResultNotImplemented);
97 } else { 98 } else {
98 R_RETURN(CreateSession<KSession>(system, out_server, out_client, name)); 99 R_RETURN(CreateSession<KSession>(system, out_server, out_client, name));
99 } 100 }
100} 101}
101 102
102Result AcceptSession(Core::System& system, Handle* out_handle, Handle port_handle) { 103Result AcceptSession(Core::System& system, Handle* out, Handle port_handle) {
103 UNIMPLEMENTED(); 104 // Get the current handle table.
104 R_THROW(ResultNotImplemented); 105 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
106
107 // Get the server port.
108 KScopedAutoObject port = handle_table.GetObject<KServerPort>(port_handle);
109 R_UNLESS(port.IsNotNull(), ResultInvalidHandle);
110
111 // Reserve an entry for the new session.
112 R_TRY(handle_table.Reserve(out));
113 ON_RESULT_FAILURE {
114 handle_table.Unreserve(*out);
115 };
116
117 // Accept the session.
118 KAutoObject* session;
119 if (port->IsLight()) {
120 session = port->AcceptLightSession();
121 } else {
122 session = port->AcceptSession();
123 }
124
125 // Ensure we accepted successfully.
126 R_UNLESS(session != nullptr, ResultNotFound);
127
128 // Register the session.
129 handle_table.Register(*out, session);
130 session->Close();
131
132 R_SUCCEED();
105} 133}
106 134
107Result CreateSession64(Core::System& system, Handle* out_server_session_handle, 135Result CreateSession64(Core::System& system, Handle* out_server_session_handle,