summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar Liam2022-10-11 18:16:56 -0400
committerGravatar Liam2022-10-11 18:40:40 -0400
commit61a8696510b3bca120f1f0289a3829e3db14834e (patch)
tree34239a299b7cd842e46df21626f6b190e9b40d14 /src/core/hle/kernel/svc.cpp
parentAdd implementation of svcCreateSession (diff)
downloadyuzu-61a8696510b3bca120f1f0289a3829e3db14834e.tar.gz
yuzu-61a8696510b3bca120f1f0289a3829e3db14834e.tar.xz
yuzu-61a8696510b3bca120f1f0289a3829e3db14834e.zip
k_server_session: preliminary support for userspace server sessions
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp82
1 files changed, 68 insertions, 14 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 3a89511aa..510a9b3e3 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -323,7 +323,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
323 // Add the server session to the handle table. 323 // Add the server session to the handle table.
324 R_TRY(handle_table.Add(out_server, &session->GetServerSession())); 324 R_TRY(handle_table.Add(out_server, &session->GetServerSession()));
325 325
326 // Add the client session to the handle table. */ 326 // Add the client session to the handle table.
327 const auto result = handle_table.Add(out_client, &session->GetClientSession()); 327 const auto result = handle_table.Add(out_client, &session->GetClientSession());
328 328
329 if (!R_SUCCEEDED(result)) { 329 if (!R_SUCCEEDED(result)) {
@@ -383,7 +383,8 @@ static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_n
383 383
384 // Create a session. 384 // Create a session.
385 KClientSession* session{}; 385 KClientSession* session{};
386 R_TRY(port->CreateSession(std::addressof(session))); 386 R_TRY(port->CreateSession(std::addressof(session),
387 std::make_shared<SessionRequestManager>(kernel)));
387 port->Close(); 388 port->Close();
388 389
389 // Register the session in the table, close the extra reference. 390 // Register the session in the table, close the extra reference.
@@ -401,7 +402,7 @@ static Result ConnectToNamedPort32(Core::System& system, Handle* out_handle,
401 return ConnectToNamedPort(system, out_handle, port_name_address); 402 return ConnectToNamedPort(system, out_handle, port_name_address);
402} 403}
403 404
404/// Makes a blocking IPC call to an OS service. 405/// Makes a blocking IPC call to a service.
405static Result SendSyncRequest(Core::System& system, Handle handle) { 406static Result SendSyncRequest(Core::System& system, Handle handle) {
406 auto& kernel = system.Kernel(); 407 auto& kernel = system.Kernel();
407 408
@@ -415,22 +416,75 @@ static Result SendSyncRequest(Core::System& system, Handle handle) {
415 416
416 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 417 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
417 418
418 { 419 return session->SendSyncRequest();
419 KScopedSchedulerLock lock(kernel);
420
421 // This is a synchronous request, so we should wait for our request to complete.
422 GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
423 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
424 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
425 }
426
427 return GetCurrentThread(kernel).GetWaitResult();
428} 420}
429 421
430static Result SendSyncRequest32(Core::System& system, Handle handle) { 422static Result SendSyncRequest32(Core::System& system, Handle handle) {
431 return SendSyncRequest(system, handle); 423 return SendSyncRequest(system, handle);
432} 424}
433 425
426static Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles,
427 s32 num_handles, Handle reply_target, s64 timeout_ns) {
428 auto& kernel = system.Kernel();
429 auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable();
430
431 // Convert handle list to object table.
432 std::vector<KSynchronizationObject*> objs(num_handles);
433 R_UNLESS(
434 handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles),
435 ResultInvalidHandle);
436
437 // Ensure handles are closed when we're done.
438 SCOPE_EXIT({
439 for (auto i = 0; i < num_handles; ++i) {
440 objs[i]->Close();
441 }
442 });
443
444 // Reply to the target, if one is specified.
445 if (reply_target != InvalidHandle) {
446 KScopedAutoObject session = handle_table.GetObject<KServerSession>(reply_target);
447 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
448
449 // If we fail to reply, we want to set the output index to -1.
450 // ON_RESULT_FAILURE { *out_index = -1; };
451
452 // Send the reply.
453 // R_TRY(session->SendReply());
454
455 Result rc = session->SendReply();
456 if (!R_SUCCEEDED(rc)) {
457 *out_index = -1;
458 return rc;
459 }
460 }
461
462 // Wait for a message.
463 while (true) {
464 // Wait for an object.
465 s32 index;
466 Result result = KSynchronizationObject::Wait(kernel, &index, objs.data(),
467 static_cast<s32>(objs.size()), timeout_ns);
468 if (result == ResultTimedOut) {
469 return result;
470 }
471
472 // Receive the request.
473 if (R_SUCCEEDED(result)) {
474 KServerSession* session = objs[index]->DynamicCast<KServerSession*>();
475 if (session != nullptr) {
476 result = session->ReceiveRequest();
477 if (result == ResultNotFound) {
478 continue;
479 }
480 }
481 }
482
483 *out_index = index;
484 return result;
485 }
486}
487
434/// Get the ID for the specified thread. 488/// Get the ID for the specified thread.
435static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { 489static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
436 // Get the thread from its handle. 490 // Get the thread from its handle.
@@ -2951,7 +3005,7 @@ static const FunctionDef SVC_Table_64[] = {
2951 {0x40, SvcWrap64<CreateSession>, "CreateSession"}, 3005 {0x40, SvcWrap64<CreateSession>, "CreateSession"},
2952 {0x41, nullptr, "AcceptSession"}, 3006 {0x41, nullptr, "AcceptSession"},
2953 {0x42, nullptr, "ReplyAndReceiveLight"}, 3007 {0x42, nullptr, "ReplyAndReceiveLight"},
2954 {0x43, nullptr, "ReplyAndReceive"}, 3008 {0x43, SvcWrap64<ReplyAndReceive>, "ReplyAndReceive"},
2955 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, 3009 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"},
2956 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"}, 3010 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"},
2957 {0x46, nullptr, "MapIoRegion"}, 3011 {0x46, nullptr, "MapIoRegion"},