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.
This commit is contained in:
parent
465f486160
commit
2a1f59b301
|
@ -1598,6 +1598,34 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
|
||||||
return RESULT_SUCCESS;
|
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) {
|
static ResultCode ClearEvent(Handle handle) {
|
||||||
LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
|
LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
|
||||||
|
|
||||||
|
@ -1806,7 +1834,7 @@ static const FunctionDef SVC_Table[] = {
|
||||||
{0x42, nullptr, "ReplyAndReceiveLight"},
|
{0x42, nullptr, "ReplyAndReceiveLight"},
|
||||||
{0x43, nullptr, "ReplyAndReceive"},
|
{0x43, nullptr, "ReplyAndReceive"},
|
||||||
{0x44, nullptr, "ReplyAndReceiveWithUserBuffer"},
|
{0x44, nullptr, "ReplyAndReceiveWithUserBuffer"},
|
||||||
{0x45, nullptr, "CreateEvent"},
|
{0x45, SvcWrap<CreateEvent>, "CreateEvent"},
|
||||||
{0x46, nullptr, "Unknown"},
|
{0x46, nullptr, "Unknown"},
|
||||||
{0x47, nullptr, "Unknown"},
|
{0x47, nullptr, "Unknown"},
|
||||||
{0x48, nullptr, "MapPhysicalMemoryUnsafe"},
|
{0x48, nullptr, "MapPhysicalMemoryUnsafe"},
|
||||||
|
|
|
@ -59,6 +59,19 @@ void SvcWrap() {
|
||||||
FuncReturn(retval);
|
FuncReturn(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <ResultCode func(u32*, u32*)>
|
||||||
|
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 <ResultCode func(u32*, u64)>
|
template <ResultCode func(u32*, u64)>
|
||||||
void SvcWrap() {
|
void SvcWrap() {
|
||||||
u32 param_1 = 0;
|
u32 param_1 = 0;
|
||||||
|
|
Reference in New Issue