diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 348 |
1 files changed, 185 insertions, 163 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 66e0ce2d0..8655506b0 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -15,6 +15,7 @@ #include "common/scope_exit.h" #include "core/core.h" #include "core/core_timing.h" +#include "core/debugger/debugger.h" #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/k_code_memory.h" @@ -57,8 +58,8 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) { // Helper function that performs the common sanity checks for svcMapMemory // and svcUnmapMemory. This is doable, as both functions perform their sanitizing // in the same order. -ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr, - u64 size) { +Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr, + u64 size) { if (!Common::Is4KBAligned(dst_addr)) { LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); return ResultInvalidAddress; @@ -134,7 +135,7 @@ enum class ResourceLimitValueType { } // Anonymous namespace /// Set the process heap to a given Size. It can both extend and shrink the heap. -static ResultCode SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { +static Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size); // Validate size. @@ -147,9 +148,9 @@ static ResultCode SetHeapSize(Core::System& system, VAddr* out_address, u64 size return ResultSuccess; } -static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) { +static Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) { VAddr temp_heap_addr{}; - const ResultCode result{SetHeapSize(system, &temp_heap_addr, heap_size)}; + const Result result{SetHeapSize(system, &temp_heap_addr, heap_size)}; *heap_addr = static_cast<u32>(temp_heap_addr); return result; } @@ -165,8 +166,8 @@ constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) { } } -static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 size, - MemoryPermission perm) { +static Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, + MemoryPermission perm) { LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size, perm); @@ -187,8 +188,8 @@ static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 s return page_table.SetMemoryPermission(address, size, perm); } -static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, - u32 attr) { +static Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, + u32 attr) { LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, size, mask, attr); @@ -212,19 +213,19 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si return page_table.SetMemoryAttribute(address, size, mask, attr); } -static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, - u32 attr) { +static Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, + u32 attr) { return SetMemoryAttribute(system, address, size, mask, attr); } /// Maps a memory range into a different range. -static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { +static Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; - if (const ResultCode result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; + if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; result.IsError()) { return result; } @@ -232,18 +233,18 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr return page_table.MapMemory(dst_addr, src_addr, size); } -static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { +static Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { return MapMemory(system, dst_addr, src_addr, size); } /// Unmaps a region that was previously mapped with svcMapMemory -static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { +static Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, src_addr, size); auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; - if (const ResultCode result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; + if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; result.IsError()) { return result; } @@ -251,12 +252,12 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad return page_table.UnmapMemory(dst_addr, src_addr, size); } -static ResultCode UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { +static Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { return UnmapMemory(system, dst_addr, src_addr, size); } /// Connect to an OS service given the port name, returns the handle to the port to out -static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { +static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { auto& memory = system.Memory(); if (!memory.IsValidVirtualAddress(port_name_address)) { LOG_ERROR(Kernel_SVC, @@ -306,14 +307,14 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr po return ResultSuccess; } -static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, - u32 port_name_address) { +static Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, + u32 port_name_address) { return ConnectToNamedPort(system, out_handle, port_name_address); } /// Makes a blocking IPC call to an OS service. -static ResultCode SendSyncRequest(Core::System& system, Handle handle) { +static Result SendSyncRequest(Core::System& system, Handle handle) { auto& kernel = system.Kernel(); // Create the wait queue. @@ -326,7 +327,6 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); - auto thread = kernel.CurrentScheduler()->GetCurrentThread(); { KScopedSchedulerLock lock(kernel); @@ -336,15 +336,15 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming()); } - return thread->GetWaitResult(); + return GetCurrentThread(kernel).GetWaitResult(); } -static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { +static Result SendSyncRequest32(Core::System& system, Handle handle) { return SendSyncRequest(system, handle); } /// Get the ID for the specified thread. -static ResultCode GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { +static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { // Get the thread from its handle. KScopedAutoObject thread = system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); @@ -355,10 +355,10 @@ static ResultCode GetThreadId(Core::System& system, u64* out_thread_id, Handle t return ResultSuccess; } -static ResultCode GetThreadId32(Core::System& system, u32* out_thread_id_low, - u32* out_thread_id_high, Handle thread_handle) { +static Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high, + Handle thread_handle) { u64 out_thread_id{}; - const ResultCode result{GetThreadId(system, &out_thread_id, thread_handle)}; + const Result result{GetThreadId(system, &out_thread_id, thread_handle)}; *out_thread_id_low = static_cast<u32>(out_thread_id >> 32); *out_thread_id_high = static_cast<u32>(out_thread_id & std::numeric_limits<u32>::max()); @@ -367,7 +367,7 @@ static ResultCode GetThreadId32(Core::System& system, u32* out_thread_id_low, } /// Gets the ID of the specified process or a specified thread's owning process. -static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { +static Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); // Get the object from the handle table. @@ -398,8 +398,8 @@ static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle return ResultSuccess; } -static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low, - u32* out_process_id_high, Handle handle) { +static Result GetProcessId32(Core::System& system, u32* out_process_id_low, + u32* out_process_id_high, Handle handle) { u64 out_process_id{}; const auto result = GetProcessId(system, &out_process_id, handle); *out_process_id_low = static_cast<u32>(out_process_id); @@ -408,8 +408,8 @@ static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low, } /// Wait for the given handles to synchronize, timeout after the specified nanoseconds -static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, - s32 num_handles, s64 nano_seconds) { +static Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, + s32 num_handles, s64 nano_seconds) { LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}", handles_address, num_handles, nano_seconds); @@ -444,14 +444,14 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha nano_seconds); } -static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, - s32 num_handles, u32 timeout_high, s32* index) { +static Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, + s32 num_handles, u32 timeout_high, s32* index) { const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; return WaitSynchronization(system, index, handles_address, num_handles, nano_seconds); } /// Resumes a thread waiting on WaitSynchronization -static ResultCode CancelSynchronization(Core::System& system, Handle handle) { +static Result CancelSynchronization(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); // Get the thread from its handle. @@ -464,13 +464,12 @@ static ResultCode CancelSynchronization(Core::System& system, Handle handle) { return ResultSuccess; } -static ResultCode CancelSynchronization32(Core::System& system, Handle handle) { +static Result CancelSynchronization32(Core::System& system, Handle handle) { return CancelSynchronization(system, handle); } /// Attempts to locks a mutex -static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, - u32 tag) { +static Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag) { LOG_TRACE(Kernel_SVC, "called thread_handle=0x{:08X}, address=0x{:X}, tag=0x{:08X}", thread_handle, address, tag); @@ -488,13 +487,12 @@ static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAdd return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag); } -static ResultCode ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, - u32 tag) { +static Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag) { return ArbitrateLock(system, thread_handle, address, tag); } /// Unlock a mutex -static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) { +static Result ArbitrateUnlock(Core::System& system, VAddr address) { LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); // Validate the input address. @@ -512,7 +510,7 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) { return system.Kernel().CurrentProcess()->SignalToAddress(address); } -static ResultCode ArbitrateUnlock32(Core::System& system, u32 address) { +static Result ArbitrateUnlock32(Core::System& system, u32 address) { return ArbitrateUnlock(system, address); } @@ -623,10 +621,16 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { handle_debug_buffer(info1, info2); - auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); + auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); const auto thread_processor_id = current_thread->GetActiveCore(); system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); } + + if (system.DebuggerEnabled()) { + auto* thread = system.Kernel().GetCurrentEmuThread(); + system.GetDebugger().NotifyThreadStopped(thread); + thread->RequestSuspend(Kernel::SuspendType::Debug); + } } static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { @@ -649,8 +653,8 @@ static void OutputDebugString32(Core::System& system, u32 address, u32 len) { } /// Gets system/memory information for the current process -static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, - u64 info_sub_id) { +static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, + u64 info_sub_id) { LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, info_sub_id, handle); @@ -685,6 +689,9 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle // 6.0.0+ TotalPhysicalMemoryAvailableWithoutSystemResource = 21, TotalPhysicalMemoryUsedWithoutSystemResource = 22, + + // Homebrew only + MesosphereCurrentProcess = 65001, }; const auto info_id_type = static_cast<GetInfoType>(info_id); @@ -877,7 +884,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle const auto& core_timing = system.CoreTiming(); const auto& scheduler = *system.Kernel().CurrentScheduler(); - const auto* const current_thread = scheduler.GetCurrentThread(); + const auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); const bool same_thread = current_thread == thread.GetPointerUnsafe(); const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks(); @@ -907,18 +914,39 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle *result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime(); return ResultSuccess; } + case GetInfoType::MesosphereCurrentProcess: { + // Verify the input handle is invalid. + R_UNLESS(handle == InvalidHandle, ResultInvalidHandle); + + // Verify the sub-type is valid. + R_UNLESS(info_sub_id == 0, ResultInvalidCombination); + + // Get the handle table. + KProcess* current_process = system.Kernel().CurrentProcess(); + KHandleTable& handle_table = current_process->GetHandleTable(); + + // Get a new handle for the current process. + Handle tmp; + R_TRY(handle_table.Add(&tmp, current_process)); + + // Set the output. + *result = tmp; + + // We succeeded. + return ResultSuccess; + } default: LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); return ResultInvalidEnumValue; } } -static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, - u32 info_id, u32 handle, u32 sub_id_high) { +static Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, + u32 info_id, u32 handle, u32 sub_id_high) { const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)}; u64 res_value{}; - const ResultCode result{GetInfo(system, &res_value, info_id, handle, sub_id)}; + const Result result{GetInfo(system, &res_value, info_id, handle, sub_id)}; *result_high = static_cast<u32>(res_value >> 32); *result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max()); @@ -926,7 +954,7 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h } /// Maps memory at a desired address -static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { +static Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); if (!Common::Is4KBAligned(addr)) { @@ -974,12 +1002,12 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) return page_table.MapPhysicalMemory(addr, size); } -static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { +static Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { return MapPhysicalMemory(system, addr, size); } /// Unmaps memory previously mapped via MapPhysicalMemory -static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { +static Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); if (!Common::Is4KBAligned(addr)) { @@ -1027,13 +1055,13 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size return page_table.UnmapPhysicalMemory(addr, size); } -static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { +static Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { return UnmapPhysicalMemory(system, addr, size); } /// Sets the thread activity -static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, - ThreadActivity thread_activity) { +static Result SetThreadActivity(Core::System& system, Handle thread_handle, + ThreadActivity thread_activity) { LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", thread_handle, thread_activity); @@ -1058,13 +1086,13 @@ static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, return ResultSuccess; } -static ResultCode SetThreadActivity32(Core::System& system, Handle thread_handle, - Svc::ThreadActivity thread_activity) { +static Result SetThreadActivity32(Core::System& system, Handle thread_handle, + Svc::ThreadActivity thread_activity) { return SetThreadActivity(system, thread_handle, thread_activity); } /// Gets the thread context -static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle) { +static Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle) { LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, thread_handle); @@ -1096,7 +1124,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand if (thread->GetRawState() != ThreadState::Runnable) { bool current = false; for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { - if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) { + if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetSchedulerCurrentThread()) { current = true; break; } @@ -1121,12 +1149,12 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand return ResultSuccess; } -static ResultCode GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle) { +static Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle) { return GetThreadContext(system, out_context, thread_handle); } /// Gets the priority for the specified thread -static ResultCode GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) { +static Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) { LOG_TRACE(Kernel_SVC, "called"); // Get the thread from its handle. @@ -1139,12 +1167,12 @@ static ResultCode GetThreadPriority(Core::System& system, u32* out_priority, Han return ResultSuccess; } -static ResultCode GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle) { +static Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle) { return GetThreadPriority(system, out_priority, handle); } /// Sets the priority for the specified thread -static ResultCode SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { +static Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { // Get the current process. KProcess& process = *system.Kernel().CurrentProcess(); @@ -1162,7 +1190,7 @@ static ResultCode SetThreadPriority(Core::System& system, Handle thread_handle, return ResultSuccess; } -static ResultCode SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { +static Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { return SetThreadPriority(system, thread_handle, priority); } @@ -1222,8 +1250,8 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(Svc::MemoryPermission p } // Anonymous namespace -static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, - u64 size, Svc::MemoryPermission map_perm) { +static Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size, + Svc::MemoryPermission map_perm) { LOG_TRACE(Kernel_SVC, "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", shmem_handle, address, size, map_perm); @@ -1263,13 +1291,13 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAd return ResultSuccess; } -static ResultCode MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, - u32 size, Svc::MemoryPermission map_perm) { +static Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size, + Svc::MemoryPermission map_perm) { return MapSharedMemory(system, shmem_handle, address, size, map_perm); } -static ResultCode UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, - u64 size) { +static Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, + u64 size) { // Validate the address/size. R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); @@ -1296,13 +1324,13 @@ static ResultCode UnmapSharedMemory(Core::System& system, Handle shmem_handle, V return ResultSuccess; } -static ResultCode UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, - u32 size) { +static Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, + u32 size) { return UnmapSharedMemory(system, shmem_handle, address, size); } -static ResultCode SetProcessMemoryPermission(Core::System& system, Handle process_handle, - VAddr address, u64 size, Svc::MemoryPermission perm) { +static Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address, + u64 size, Svc::MemoryPermission perm) { LOG_TRACE(Kernel_SVC, "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", process_handle, address, size, perm); @@ -1331,8 +1359,8 @@ static ResultCode SetProcessMemoryPermission(Core::System& system, Handle proces return page_table.SetProcessMemoryPermission(address, size, perm); } -static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, - VAddr src_address, u64 size) { +static Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, + VAddr src_address, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", dst_address, process_handle, src_address, size); @@ -1361,7 +1389,7 @@ static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Hand ResultInvalidMemoryRegion); // Create a new page group. - KPageLinkedList pg; + KPageGroup pg; R_TRY(src_pt.MakeAndOpenPageGroup( std::addressof(pg), src_address, size / PageSize, KMemoryState::FlagCanMapProcess, KMemoryState::FlagCanMapProcess, KMemoryPermission::None, KMemoryPermission::None, @@ -1374,8 +1402,8 @@ static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Hand return ResultSuccess; } -static ResultCode UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, - VAddr src_address, u64 size) { +static Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, + VAddr src_address, u64 size) { LOG_TRACE(Kernel_SVC, "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", dst_address, process_handle, src_address, size); @@ -1409,7 +1437,7 @@ static ResultCode UnmapProcessMemory(Core::System& system, VAddr dst_address, Ha return ResultSuccess; } -static ResultCode CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) { +static Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) { LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size); // Get kernel instance. @@ -1444,12 +1472,12 @@ static ResultCode CreateCodeMemory(Core::System& system, Handle* out, VAddr addr return ResultSuccess; } -static ResultCode CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) { +static Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) { return CreateCodeMemory(system, out, address, size); } -static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, - VAddr address, size_t size, Svc::MemoryPermission perm) { +static Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, + VAddr address, size_t size, Svc::MemoryPermission perm) { LOG_TRACE(Kernel_SVC, "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, " @@ -1527,15 +1555,13 @@ static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_han return ResultSuccess; } -static ResultCode ControlCodeMemory32(Core::System& system, Handle code_memory_handle, - u32 operation, u64 address, u64 size, - Svc::MemoryPermission perm) { +static Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation, + u64 address, u64 size, Svc::MemoryPermission perm) { return ControlCodeMemory(system, code_memory_handle, operation, address, size, perm); } -static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, - VAddr page_info_address, Handle process_handle, - VAddr address) { +static Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, + VAddr page_info_address, Handle process_handle, VAddr address) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); @@ -1563,8 +1589,8 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add return ResultSuccess; } -static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address, - VAddr page_info_address, VAddr query_address) { +static Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, + VAddr query_address) { LOG_TRACE(Kernel_SVC, "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " "query_address=0x{:016X}", @@ -1574,13 +1600,13 @@ static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address, query_address); } -static ResultCode QueryMemory32(Core::System& system, u32 memory_info_address, - u32 page_info_address, u32 query_address) { +static Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address, + u32 query_address) { return QueryMemory(system, memory_info_address, page_info_address, query_address); } -static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, - u64 src_address, u64 size) { +static Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, + u64 src_address, u64 size) { LOG_DEBUG(Kernel_SVC, "called. process_handle=0x{:08X}, dst_address=0x{:016X}, " "src_address=0x{:016X}, size=0x{:016X}", @@ -1647,8 +1673,8 @@ static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_hand return page_table.MapCodeMemory(dst_address, src_address, size); } -static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle, - u64 dst_address, u64 src_address, u64 size) { +static Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, + u64 src_address, u64 size) { LOG_DEBUG(Kernel_SVC, "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " "size=0x{:016X}", @@ -1719,11 +1745,12 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha /// Exits the current process static void ExitProcess(Core::System& system) { auto* current_process = system.Kernel().CurrentProcess(); - UNIMPLEMENTED(); LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, "Process has already exited"); + + system.Exit(); } static void ExitProcess32(Core::System& system) { @@ -1739,8 +1766,8 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) { } // Anonymous namespace /// Creates a new thread -static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, - VAddr stack_bottom, u32 priority, s32 core_id) { +static Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, + VAddr stack_bottom, u32 priority, s32 core_id) { LOG_DEBUG(Kernel_SVC, "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, " "priority=0x{:08X}, core_id=0x{:08X}", @@ -1811,13 +1838,13 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e return ResultSuccess; } -static ResultCode CreateThread32(Core::System& system, Handle* out_handle, u32 priority, - u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { +static Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, + u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { return CreateThread(system, out_handle, entry_point, arg, stack_top, priority, processor_id); } /// Starts the thread for the provided handle -static ResultCode StartThread(Core::System& system, Handle thread_handle) { +static Result StartThread(Core::System& system, Handle thread_handle) { LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); // Get the thread from its handle. @@ -1835,7 +1862,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { return ResultSuccess; } -static ResultCode StartThread32(Core::System& system, Handle thread_handle) { +static Result StartThread32(Core::System& system, Handle thread_handle) { return StartThread(system, thread_handle); } @@ -1843,7 +1870,7 @@ static ResultCode StartThread32(Core::System& system, Handle thread_handle) { static void ExitThread(Core::System& system) { LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); - auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); + auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); system.GlobalSchedulerContext().RemoveThread(current_thread); current_thread->Exit(); system.Kernel().UnregisterInUseObject(current_thread); @@ -1876,7 +1903,7 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { KScheduler::YieldToAnyThread(kernel); } else { // Nintendo does nothing at all if an otherwise invalid value is passed. - UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); + ASSERT_MSG(false, "Unimplemented sleep yield type '{:016X}'!", nanoseconds); } } @@ -1886,8 +1913,8 @@ static void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanosec } /// Wait process wide key atomic -static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, - u32 tag, s64 timeout_ns) { +static Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag, + s64 timeout_ns) { LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address, cv_key, tag, timeout_ns); @@ -1922,8 +1949,8 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address, address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout); } -static ResultCode WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, - u32 timeout_ns_low, u32 timeout_ns_high) { +static Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, + u32 timeout_ns_low, u32 timeout_ns_high) { const auto timeout_ns = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); return WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns); } @@ -1968,8 +1995,8 @@ constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) { } // namespace // Wait for an address (via Address Arbiter) -static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::ArbitrationType arb_type, - s32 value, s64 timeout_ns) { +static Result WaitForAddress(Core::System& system, VAddr address, Svc::ArbitrationType arb_type, + s32 value, s64 timeout_ns) { LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}", address, arb_type, value, timeout_ns); @@ -2006,15 +2033,15 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::Arbit return system.Kernel().CurrentProcess()->WaitAddressArbiter(address, arb_type, value, timeout); } -static ResultCode WaitForAddress32(Core::System& system, u32 address, Svc::ArbitrationType arb_type, - s32 value, u32 timeout_ns_low, u32 timeout_ns_high) { +static Result WaitForAddress32(Core::System& system, u32 address, Svc::ArbitrationType arb_type, + s32 value, u32 timeout_ns_low, u32 timeout_ns_high) { const auto timeout = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); return WaitForAddress(system, address, arb_type, value, timeout); } // Signals to an address (via Address Arbiter) -static ResultCode SignalToAddress(Core::System& system, VAddr address, Svc::SignalType signal_type, - s32 value, s32 count) { +static Result SignalToAddress(Core::System& system, VAddr address, Svc::SignalType signal_type, + s32 value, s32 count) { LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}", address, signal_type, value, count); @@ -2055,8 +2082,8 @@ static void SynchronizePreemptionState(Core::System& system) { } } -static ResultCode SignalToAddress32(Core::System& system, u32 address, Svc::SignalType signal_type, - s32 value, s32 count) { +static Result SignalToAddress32(Core::System& system, u32 address, Svc::SignalType signal_type, + s32 value, s32 count) { return SignalToAddress(system, address, signal_type, value, count); } @@ -2094,7 +2121,7 @@ static void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) } /// Close a handle -static ResultCode CloseHandle(Core::System& system, Handle handle) { +static Result CloseHandle(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); // Remove the handle. @@ -2104,12 +2131,12 @@ static ResultCode CloseHandle(Core::System& system, Handle handle) { return ResultSuccess; } -static ResultCode CloseHandle32(Core::System& system, Handle handle) { +static Result CloseHandle32(Core::System& system, Handle handle) { return CloseHandle(system, handle); } /// Clears the signaled state of an event or process. -static ResultCode ResetSignal(Core::System& system, Handle handle) { +static Result ResetSignal(Core::System& system, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); // Get the current handle table. @@ -2136,7 +2163,7 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { return ResultInvalidHandle; } -static ResultCode ResetSignal32(Core::System& system, Handle handle) { +static Result ResetSignal32(Core::System& system, Handle handle) { return ResetSignal(system, handle); } @@ -2156,8 +2183,8 @@ constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { } // Anonymous namespace /// Creates a TransferMemory object -static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, - MemoryPermission map_perm) { +static Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, + MemoryPermission map_perm) { auto& kernel = system.Kernel(); // Validate the size. @@ -2203,13 +2230,13 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr return ResultSuccess; } -static ResultCode CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, - MemoryPermission map_perm) { +static Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, + MemoryPermission map_perm) { return CreateTransferMemory(system, out, address, size, map_perm); } -static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, - u64* out_affinity_mask) { +static Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, + u64* out_affinity_mask) { LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); // Get the thread from its handle. @@ -2223,8 +2250,8 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, return ResultSuccess; } -static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, - u32* out_affinity_mask_low, u32* out_affinity_mask_high) { +static Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, + u32* out_affinity_mask_low, u32* out_affinity_mask_high) { u64 out_affinity_mask{}; const auto result = GetThreadCoreMask(system, thread_handle, out_core_id, &out_affinity_mask); *out_affinity_mask_high = static_cast<u32>(out_affinity_mask >> 32); @@ -2232,8 +2259,8 @@ static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle return result; } -static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, - u64 affinity_mask) { +static Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, + u64 affinity_mask) { // Determine the core id/affinity mask. if (core_id == IdealCoreUseProcessValue) { core_id = system.Kernel().CurrentProcess()->GetIdealCoreId(); @@ -2264,13 +2291,13 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, return ResultSuccess; } -static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, - u32 affinity_mask_low, u32 affinity_mask_high) { +static Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, + u32 affinity_mask_low, u32 affinity_mask_high) { const auto affinity_mask = u64{affinity_mask_low} | (u64{affinity_mask_high} << 32); return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); } -static ResultCode SignalEvent(Core::System& system, Handle event_handle) { +static Result SignalEvent(Core::System& system, Handle event_handle) { LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); // Get the current handle table. @@ -2283,11 +2310,11 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) { return writable_event->Signal(); } -static ResultCode SignalEvent32(Core::System& system, Handle event_handle) { +static Result SignalEvent32(Core::System& system, Handle event_handle) { return SignalEvent(system, event_handle); } -static ResultCode ClearEvent(Core::System& system, Handle event_handle) { +static Result ClearEvent(Core::System& system, Handle event_handle) { LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); // Get the current handle table. @@ -2314,11 +2341,11 @@ static ResultCode ClearEvent(Core::System& system, Handle event_handle) { return ResultInvalidHandle; } -static ResultCode ClearEvent32(Core::System& system, Handle event_handle) { +static Result ClearEvent32(Core::System& system, Handle event_handle) { return ClearEvent(system, event_handle); } -static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { +static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { LOG_DEBUG(Kernel_SVC, "called"); // Get the kernel reference and handle table. @@ -2363,11 +2390,11 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o return ResultSuccess; } -static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { +static Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { return CreateEvent(system, out_write, out_read); } -static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { +static Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); // This function currently only allows retrieving a process' status. @@ -2393,7 +2420,7 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ return ResultSuccess; } -static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { +static Result CreateResourceLimit(Core::System& system, Handle* out_handle) { LOG_DEBUG(Kernel_SVC, "called"); // Create a new resource limit. @@ -2416,9 +2443,8 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) return ResultSuccess; } -static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, - Handle resource_limit_handle, - LimitableResource which) { +static Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, + Handle resource_limit_handle, LimitableResource which) { LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, which); @@ -2437,9 +2463,8 @@ static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limi return ResultSuccess; } -static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, - Handle resource_limit_handle, - LimitableResource which) { +static Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, + Handle resource_limit_handle, LimitableResource which) { LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, which); @@ -2458,8 +2483,8 @@ static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_cu return ResultSuccess; } -static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, - LimitableResource which, u64 limit_value) { +static Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, + LimitableResource which, u64 limit_value) { LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", resource_limit_handle, which, limit_value); @@ -2478,8 +2503,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour return ResultSuccess; } -static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, - VAddr out_process_ids, u32 out_process_ids_size) { +static Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids, + u32 out_process_ids_size) { LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", out_process_ids, out_process_ids_size); @@ -2515,8 +2540,8 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, return ResultSuccess; } -static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, - u32 out_thread_ids_size, Handle debug_handle) { +static Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, + u32 out_thread_ids_size, Handle debug_handle) { // TODO: Handle this case when debug events are supported. UNIMPLEMENTED_IF(debug_handle != InvalidHandle); @@ -2530,7 +2555,7 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd return ResultOutOfRange; } - const auto* const current_process = system.Kernel().CurrentProcess(); + auto* const current_process = system.Kernel().CurrentProcess(); const auto total_copy_size = out_thread_ids_size * sizeof(u64); if (out_thread_ids_size > 0 && @@ -2555,9 +2580,9 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd return ResultSuccess; } -static ResultCode FlushProcessDataCache32([[maybe_unused]] Core::System& system, - [[maybe_unused]] Handle handle, - [[maybe_unused]] u32 address, [[maybe_unused]] u32 size) { +static Result FlushProcessDataCache32([[maybe_unused]] Core::System& system, + [[maybe_unused]] Handle handle, [[maybe_unused]] u32 address, + [[maybe_unused]] u32 size) { // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a no-op, // as all emulation is done in the same cache level in host architecture, thus data cache // does not need flushing. @@ -2982,11 +3007,10 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) { } void Call(Core::System& system, u32 immediate) { - system.ExitDynarmicProfile(); auto& kernel = system.Kernel(); kernel.EnterSVCProfile(); - auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); + auto* thread = GetCurrentThreadPointer(kernel); thread->SetIsCallingSvc(); const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) @@ -3007,8 +3031,6 @@ void Call(Core::System& system, u32 immediate) { auto* host_context = thread->GetHostContext().get(); host_context->Rewind(); } - - system.EnterDynarmicProfile(); } } // namespace Kernel::Svc |