From 3db51801b422315c29a83fc89116d732c1dc1079 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 4 Dec 2018 15:11:18 -0500 Subject: [PATCH 1/3] kernel/svc: Implement svcCreateEvent() svcCreateEvent operates by creating both a readable and writable event and then attempts to add both to the current process' handle table. If adding either of the events to the handle table fails, then the relevant error from the handle table is returned. If adding the readable event after the writable event to the table fails, then the writable event is removed from the handle table and the relevant error from the handle table is returned. Note that since we do not currently test resource limits, we don't check the resource limit table yet. --- src/core/hle/kernel/svc.cpp | 30 +++++++++++++++++++++++++++++- src/core/hle/kernel/svc_wrap.h | 13 +++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 812b320057..a0e3dc4706 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1598,6 +1598,34 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss return RESULT_SUCCESS; } +static ResultCode CreateEvent(Handle* write_handle, Handle* read_handle) { + LOG_DEBUG(Kernel_SVC, "called"); + + auto& kernel = Core::System::GetInstance().Kernel(); + const auto [readable_event, writable_event] = + WritableEvent::CreateEventPair(kernel, ResetType::Sticky, "CreateEvent"); + + HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); + + const auto write_create_result = handle_table.Create(writable_event); + if (write_create_result.Failed()) { + return write_create_result.Code(); + } + *write_handle = *write_create_result; + + const auto read_create_result = handle_table.Create(readable_event); + if (read_create_result.Failed()) { + handle_table.Close(*write_create_result); + return read_create_result.Code(); + } + *read_handle = *read_create_result; + + LOG_DEBUG(Kernel_SVC, + "successful. Writable event handle=0x{:08X}, Readable event handle=0x{:08X}", + *write_create_result, *read_create_result); + return RESULT_SUCCESS; +} + static ResultCode ClearEvent(Handle handle) { LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); @@ -1806,7 +1834,7 @@ static const FunctionDef SVC_Table[] = { {0x42, nullptr, "ReplyAndReceiveLight"}, {0x43, nullptr, "ReplyAndReceive"}, {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, - {0x45, nullptr, "CreateEvent"}, + {0x45, SvcWrap, "CreateEvent"}, {0x46, nullptr, "Unknown"}, {0x47, nullptr, "Unknown"}, {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index fa11166249..24aef46c93 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -59,6 +59,19 @@ void SvcWrap() { FuncReturn(retval); } +template +void SvcWrap() { + u32 param_1 = 0; + u32 param_2 = 0; + const u32 retval = func(¶m_1, ¶m_2).raw; + + auto& arm_interface = Core::CurrentArmInterface(); + arm_interface.SetReg(1, param_1); + arm_interface.SetReg(2, param_2); + + FuncReturn(retval); +} + template void SvcWrap() { u32 param_1 = 0; From 98342ed10999cfca45f1e54a7c25e977887f018f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 4 Dec 2018 15:39:49 -0500 Subject: [PATCH 2/3] kernel/svc: Implement svcSignalEvent() This function simply does a handle table lookup for a writable event instance identified by the given handle value. If a writable event cannot be found for the given handle, then an invalid handle error is returned. If a writable event is found, then it simply signals the event, as one would expect. --- src/core/hle/kernel/svc.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a0e3dc4706..830594d72b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1647,6 +1647,21 @@ static ResultCode ClearEvent(Handle handle) { return ERR_INVALID_HANDLE; } +static ResultCode SignalEvent(Handle handle) { + LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); + + HandleTable& handle_table = Core::CurrentProcess()->GetHandleTable(); + auto writable_event = handle_table.Get(handle); + + if (!writable_event) { + LOG_ERROR(Kernel_SVC, "Non-existent writable event handle used (0x{:08X})", handle); + return ERR_INVALID_HANDLE; + } + + writable_event->Signal(); + return RESULT_SUCCESS; +} + static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); @@ -1782,7 +1797,7 @@ static const FunctionDef SVC_Table[] = { {0x0E, SvcWrap, "GetThreadCoreMask"}, {0x0F, SvcWrap, "SetThreadCoreMask"}, {0x10, SvcWrap, "GetCurrentProcessorNumber"}, - {0x11, nullptr, "SignalEvent"}, + {0x11, SvcWrap, "SignalEvent"}, {0x12, SvcWrap, "ClearEvent"}, {0x13, SvcWrap, "MapSharedMemory"}, {0x14, SvcWrap, "UnmapSharedMemory"}, From 42256624f92b397437e5f10215fa86078deab593 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 4 Dec 2018 15:48:20 -0500 Subject: [PATCH 3/3] kernel/svc: Remove unused header inclusion --- src/core/hle/kernel/svc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 830594d72b..e6c77f9db8 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -35,7 +35,6 @@ #include "core/hle/lock.h" #include "core/hle/result.h" #include "core/hle/service/service.h" -#include "core/settings.h" namespace Kernel { namespace {