summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/function_wrappers.h5
-rw-r--r--src/core/hle/kernel/errors.h5
-rw-r--r--src/core/hle/kernel/server_port.cpp12
-rw-r--r--src/core/hle/kernel/server_port.h11
-rw-r--r--src/core/hle/svc.cpp26
5 files changed, 52 insertions, 7 deletions
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index b19b64509..410bb87ea 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -226,9 +226,8 @@ void Wrap() {
226 u32 retval = func(&param_1, &param_2, 226 u32 retval = func(&param_1, &param_2,
227 reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3)) 227 reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3))
228 .raw; 228 .raw;
229 // The first out parameter is moved into R2 and the second is moved into R1. 229 Core::CPU().SetReg(1, param_1);
230 Core::CPU().SetReg(1, param_2); 230 Core::CPU().SetReg(2, param_2);
231 Core::CPU().SetReg(2, param_1);
232 FuncReturn(retval); 231 FuncReturn(retval);
233} 232}
234 233
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h
index b3b60e7df..64aa61460 100644
--- a/src/core/hle/kernel/errors.h
+++ b/src/core/hle/kernel/errors.h
@@ -13,6 +13,7 @@ enum {
13 OutOfHandles = 19, 13 OutOfHandles = 19,
14 SessionClosedByRemote = 26, 14 SessionClosedByRemote = 26,
15 PortNameTooLong = 30, 15 PortNameTooLong = 30,
16 NoPendingSessions = 35,
16 WrongPermission = 46, 17 WrongPermission = 46,
17 InvalidBufferDescriptor = 48, 18 InvalidBufferDescriptor = 48,
18 MaxConnectionsReached = 52, 19 MaxConnectionsReached = 52,
@@ -94,5 +95,9 @@ constexpr ResultCode ERR_OUT_OF_RANGE_KERNEL(ErrorDescription::OutOfRange, Error
94 ErrorLevel::Permanent); // 0xD8E007FD 95 ErrorLevel::Permanent); // 0xD8E007FD
95constexpr ResultCode RESULT_TIMEOUT(ErrorDescription::Timeout, ErrorModule::OS, 96constexpr ResultCode RESULT_TIMEOUT(ErrorDescription::Timeout, ErrorModule::OS,
96 ErrorSummary::StatusChanged, ErrorLevel::Info); 97 ErrorSummary::StatusChanged, ErrorLevel::Info);
98/// Returned when Accept() is called on a port with no sessions to be accepted.
99constexpr ResultCode ERR_NO_PENDING_SESSIONS(ErrCodes::NoPendingSessions, ErrorModule::OS,
100 ErrorSummary::WouldBlock,
101 ErrorLevel::Permanent); // 0xD8401823
97 102
98} // namespace Kernel 103} // namespace Kernel
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
index 4d20c39a1..49a9cdfa3 100644
--- a/src/core/hle/kernel/server_port.cpp
+++ b/src/core/hle/kernel/server_port.cpp
@@ -5,8 +5,10 @@
5#include <tuple> 5#include <tuple>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/hle/kernel/client_port.h" 7#include "core/hle/kernel/client_port.h"
8#include "core/hle/kernel/errors.h"
8#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
9#include "core/hle/kernel/server_port.h" 10#include "core/hle/kernel/server_port.h"
11#include "core/hle/kernel/server_session.h"
10#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
11 13
12namespace Kernel { 14namespace Kernel {
@@ -14,6 +16,16 @@ namespace Kernel {
14ServerPort::ServerPort() {} 16ServerPort::ServerPort() {}
15ServerPort::~ServerPort() {} 17ServerPort::~ServerPort() {}
16 18
19ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
20 if (pending_sessions.empty()) {
21 return ERR_NO_PENDING_SESSIONS;
22 }
23
24 auto session = std::move(pending_sessions.back());
25 pending_sessions.pop_back();
26 return MakeResult(std::move(session));
27}
28
17bool ServerPort::ShouldWait(Thread* thread) const { 29bool ServerPort::ShouldWait(Thread* thread) const {
18 // If there are no pending sessions, we wait until a new one is added. 30 // If there are no pending sessions, we wait until a new one is added.
19 return pending_sessions.size() == 0; 31 return pending_sessions.size() == 0;
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index f1419cd46..6fe7c7f2f 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -14,6 +14,7 @@
14namespace Kernel { 14namespace Kernel {
15 15
16class ClientPort; 16class ClientPort;
17class ServerSession;
17class SessionRequestHandler; 18class SessionRequestHandler;
18 19
19class ServerPort final : public WaitObject { 20class ServerPort final : public WaitObject {
@@ -41,6 +42,12 @@ public:
41 } 42 }
42 43
43 /** 44 /**
45 * Accepts a pending incoming connection on this port. If there are no pending sessions, will
46 * return ERR_NO_PENDING_SESSIONS.
47 */
48 ResultVal<SharedPtr<ServerSession>> Accept();
49
50 /**
44 * Sets the HLE handler template for the port. ServerSessions crated by connecting to this port 51 * Sets the HLE handler template for the port. ServerSessions crated by connecting to this port
45 * will inherit a reference to this handler. 52 * will inherit a reference to this handler.
46 */ 53 */
@@ -50,8 +57,8 @@ public:
50 57
51 std::string name; ///< Name of port (optional) 58 std::string name; ///< Name of port (optional)
52 59
53 std::vector<SharedPtr<WaitObject>> 60 /// ServerSessions waiting to be accepted by the port
54 pending_sessions; ///< ServerSessions waiting to be accepted by the port 61 std::vector<SharedPtr<ServerSession>> pending_sessions;
55 62
56 /// This session's HLE request handler template (optional) 63 /// This session's HLE request handler template (optional)
57 /// ServerSessions created from this port inherit a reference to this handler. 64 /// ServerSessions created from this port inherit a reference to this handler.
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index f459b1314..c05401143 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -947,6 +947,17 @@ static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client
947 return RESULT_SUCCESS; 947 return RESULT_SUCCESS;
948} 948}
949 949
950static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle) {
951 using Kernel::ClientPort;
952 SharedPtr<ClientPort> client_port = Kernel::g_handle_table.Get<ClientPort>(client_port_handle);
953 if (client_port == nullptr)
954 return ERR_INVALID_HANDLE;
955
956 CASCADE_RESULT(auto session, client_port->Connect());
957 CASCADE_RESULT(*out_client_session, Kernel::g_handle_table.Create(std::move(session)));
958 return RESULT_SUCCESS;
959}
960
950static ResultCode CreateSession(Handle* server_session, Handle* client_session) { 961static ResultCode CreateSession(Handle* server_session, Handle* client_session) {
951 auto sessions = Kernel::ServerSession::CreateSessionPair(); 962 auto sessions = Kernel::ServerSession::CreateSessionPair();
952 963
@@ -960,6 +971,17 @@ static ResultCode CreateSession(Handle* server_session, Handle* client_session)
960 return RESULT_SUCCESS; 971 return RESULT_SUCCESS;
961} 972}
962 973
974static ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle) {
975 using Kernel::ServerPort;
976 SharedPtr<ServerPort> server_port = Kernel::g_handle_table.Get<ServerPort>(server_port_handle);
977 if (server_port == nullptr)
978 return ERR_INVALID_HANDLE;
979
980 CASCADE_RESULT(auto session, server_port->Accept());
981 CASCADE_RESULT(*out_server_session, Kernel::g_handle_table.Create(std::move(session)));
982 return RESULT_SUCCESS;
983}
984
963static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) { 985static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
964 using Kernel::MemoryRegion; 986 using Kernel::MemoryRegion;
965 987
@@ -1134,9 +1156,9 @@ static const FunctionDef SVC_Table[] = {
1134 {0x45, nullptr, "Unknown"}, 1156 {0x45, nullptr, "Unknown"},
1135 {0x46, nullptr, "Unknown"}, 1157 {0x46, nullptr, "Unknown"},
1136 {0x47, HLE::Wrap<CreatePort>, "CreatePort"}, 1158 {0x47, HLE::Wrap<CreatePort>, "CreatePort"},
1137 {0x48, nullptr, "CreateSessionToPort"}, 1159 {0x48, HLE::Wrap<CreateSessionToPort>, "CreateSessionToPort"},
1138 {0x49, HLE::Wrap<CreateSession>, "CreateSession"}, 1160 {0x49, HLE::Wrap<CreateSession>, "CreateSession"},
1139 {0x4A, nullptr, "AcceptSession"}, 1161 {0x4A, HLE::Wrap<AcceptSession>, "AcceptSession"},
1140 {0x4B, nullptr, "ReplyAndReceive1"}, 1162 {0x4B, nullptr, "ReplyAndReceive1"},
1141 {0x4C, nullptr, "ReplyAndReceive2"}, 1163 {0x4C, nullptr, "ReplyAndReceive2"},
1142 {0x4D, nullptr, "ReplyAndReceive3"}, 1164 {0x4D, nullptr, "ReplyAndReceive3"},