diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 205 |
1 files changed, 145 insertions, 60 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 3339777c1..812b32005 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -20,17 +20,18 @@ #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/event.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/process.h" +#include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/resource_limit.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_wrap.h" #include "core/hle/kernel/thread.h" +#include "core/hle/kernel/writable_event.h" #include "core/hle/lock.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -662,7 +663,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) TotalMemoryUsage = 6, TotalHeapUsage = 7, IsCurrentProcessBeingDebugged = 8, - ResourceHandleLimit = 9, + RegisterResourceLimit = 9, IdleTickCount = 10, RandomEntropy = 11, PerformanceCounter = 0xF0000002, @@ -682,37 +683,137 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) ThreadTickCount = 0xF0000002, }; - const auto* current_process = Core::CurrentProcess(); - const auto& vm_manager = current_process->VMManager(); + const auto info_id_type = static_cast<GetInfoType>(info_id); - switch (static_cast<GetInfoType>(info_id)) { + switch (info_id_type) { case GetInfoType::AllowedCpuIdBitmask: - *result = current_process->GetAllowedProcessorMask(); - break; case GetInfoType::AllowedThreadPrioBitmask: - *result = current_process->GetAllowedThreadPriorityMask(); - break; case GetInfoType::MapRegionBaseAddr: - *result = vm_manager.GetMapRegionBaseAddress(); - break; case GetInfoType::MapRegionSize: - *result = vm_manager.GetMapRegionSize(); - break; case GetInfoType::HeapRegionBaseAddr: - *result = vm_manager.GetHeapRegionBaseAddress(); - break; case GetInfoType::HeapRegionSize: - *result = vm_manager.GetHeapRegionSize(); - break; + case GetInfoType::ASLRRegionBaseAddr: + case GetInfoType::ASLRRegionSize: + case GetInfoType::NewMapRegionBaseAddr: + case GetInfoType::NewMapRegionSize: case GetInfoType::TotalMemoryUsage: - *result = vm_manager.GetTotalMemoryUsage(); - break; case GetInfoType::TotalHeapUsage: - *result = vm_manager.GetTotalHeapUsage(); - break; + case GetInfoType::IsVirtualAddressMemoryEnabled: + case GetInfoType::PersonalMmHeapUsage: + case GetInfoType::TitleId: + case GetInfoType::UserExceptionContextAddr: { + if (info_sub_id != 0) { + return ERR_INVALID_ENUM_VALUE; + } + + const auto& current_process_handle_table = Core::CurrentProcess()->GetHandleTable(); + const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle)); + if (!process) { + return ERR_INVALID_HANDLE; + } + + switch (info_id_type) { + case GetInfoType::AllowedCpuIdBitmask: + *result = process->GetAllowedProcessorMask(); + return RESULT_SUCCESS; + + case GetInfoType::AllowedThreadPrioBitmask: + *result = process->GetAllowedThreadPriorityMask(); + return RESULT_SUCCESS; + + case GetInfoType::MapRegionBaseAddr: + *result = process->VMManager().GetMapRegionBaseAddress(); + return RESULT_SUCCESS; + + case GetInfoType::MapRegionSize: + *result = process->VMManager().GetMapRegionSize(); + return RESULT_SUCCESS; + + case GetInfoType::HeapRegionBaseAddr: + *result = process->VMManager().GetHeapRegionBaseAddress(); + return RESULT_SUCCESS; + + case GetInfoType::HeapRegionSize: + *result = process->VMManager().GetHeapRegionSize(); + return RESULT_SUCCESS; + + case GetInfoType::ASLRRegionBaseAddr: + *result = process->VMManager().GetASLRRegionBaseAddress(); + return RESULT_SUCCESS; + + case GetInfoType::ASLRRegionSize: + *result = process->VMManager().GetASLRRegionSize(); + return RESULT_SUCCESS; + + case GetInfoType::NewMapRegionBaseAddr: + *result = process->VMManager().GetNewMapRegionBaseAddress(); + return RESULT_SUCCESS; + + case GetInfoType::NewMapRegionSize: + *result = process->VMManager().GetNewMapRegionSize(); + return RESULT_SUCCESS; + + case GetInfoType::TotalMemoryUsage: + *result = process->VMManager().GetTotalMemoryUsage(); + return RESULT_SUCCESS; + + case GetInfoType::TotalHeapUsage: + *result = process->VMManager().GetTotalHeapUsage(); + return RESULT_SUCCESS; + + case GetInfoType::IsVirtualAddressMemoryEnabled: + *result = process->IsVirtualMemoryEnabled(); + return RESULT_SUCCESS; + + case GetInfoType::TitleId: + *result = process->GetTitleID(); + return RESULT_SUCCESS; + + case GetInfoType::UserExceptionContextAddr: + LOG_WARNING(Kernel_SVC, + "(STUBBED) Attempted to query user exception context address, returned 0"); + *result = 0; + return RESULT_SUCCESS; + + default: + break; + } + + LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id); + return ERR_INVALID_ENUM_VALUE; + } + case GetInfoType::IsCurrentProcessBeingDebugged: *result = 0; - break; + return RESULT_SUCCESS; + + case GetInfoType::RegisterResourceLimit: { + if (handle != 0) { + return ERR_INVALID_HANDLE; + } + + if (info_sub_id != 0) { + return ERR_INVALID_COMBINATION; + } + + Process* const current_process = Core::CurrentProcess(); + HandleTable& handle_table = current_process->GetHandleTable(); + const auto resource_limit = current_process->GetResourceLimit(); + if (!resource_limit) { + *result = KernelHandle::InvalidHandle; + // Yes, the kernel considers this a successful operation. + return RESULT_SUCCESS; + } + + const auto table_result = handle_table.Create(resource_limit); + if (table_result.Failed()) { + return table_result.Code(); + } + + *result = *table_result; + return RESULT_SUCCESS; + } + case GetInfoType::RandomEntropy: if (handle != 0) { LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}", @@ -726,37 +827,15 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) return ERR_INVALID_COMBINATION; } - *result = current_process->GetRandomEntropy(info_sub_id); + *result = Core::CurrentProcess()->GetRandomEntropy(info_sub_id); return RESULT_SUCCESS; - break; - case GetInfoType::ASLRRegionBaseAddr: - *result = vm_manager.GetASLRRegionBaseAddress(); - break; - case GetInfoType::ASLRRegionSize: - *result = vm_manager.GetASLRRegionSize(); - break; - case GetInfoType::NewMapRegionBaseAddr: - *result = vm_manager.GetNewMapRegionBaseAddress(); - break; - case GetInfoType::NewMapRegionSize: - *result = vm_manager.GetNewMapRegionSize(); - break; - case GetInfoType::IsVirtualAddressMemoryEnabled: - *result = current_process->IsVirtualMemoryEnabled(); - break; - case GetInfoType::TitleId: - *result = current_process->GetTitleID(); - break; + case GetInfoType::PrivilegedProcessId: LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query privileged process id bounds, returned 0"); *result = 0; - break; - case GetInfoType::UserExceptionContextAddr: - LOG_WARNING(Kernel_SVC, - "(STUBBED) Attempted to query user exception context address, returned 0"); - *result = 0; - break; + return RESULT_SUCCESS; + case GetInfoType::ThreadTickCount: { constexpr u64 num_cpus = 4; if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { @@ -766,7 +845,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) } const auto thread = - current_process->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); + Core::CurrentProcess()->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); if (!thread) { LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", static_cast<Handle>(handle)); @@ -789,14 +868,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) } *result = out_ticks; - break; + return RESULT_SUCCESS; } + default: LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id); return ERR_INVALID_ENUM_VALUE; } - - return RESULT_SUCCESS; } /// Sets the thread activity @@ -1042,7 +1120,7 @@ static void ExitProcess() { static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, u32 priority, s32 processor_id) { LOG_TRACE(Kernel_SVC, - "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " + "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", entry_point, arg, stack_top, priority, processor_id, *out_handle); @@ -1361,7 +1439,7 @@ static ResultCode ResetSignal(Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); - auto event = handle_table.Get<Event>(handle); + auto event = handle_table.Get<ReadableEvent>(handle); ASSERT(event != nullptr); @@ -1524,14 +1602,21 @@ static ResultCode ClearEvent(Handle handle) { LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); - SharedPtr<Event> evt = handle_table.Get<Event>(handle); - if (evt == nullptr) { - LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); - return ERR_INVALID_HANDLE; + + auto writable_event = handle_table.Get<WritableEvent>(handle); + if (writable_event) { + writable_event->Clear(); + return RESULT_SUCCESS; } - evt->Clear(); - return RESULT_SUCCESS; + auto readable_event = handle_table.Get<ReadableEvent>(handle); + if (readable_event) { + readable_event->Clear(); + return RESULT_SUCCESS; + } + + LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); + return ERR_INVALID_HANDLE; } static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { |