code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

// This file is automatically generated using svc_generator.py.

#pragma once

namespace Core {
class System;
}

#include <span>

#include "common/common_types.h"
#include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h"

namespace Kernel::Svc {

// clang-format off
Result SetHeapSize(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
Result MapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
void ExitProcess(Core::System& system);
Result CreateThread(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread(Core::System& system, Handle thread_handle);
void ExitThread(Core::System& system);
void SleepThread(Core::System& system, int64_t ns);
Result GetThreadPriority(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber(Core::System& system);
Result SignalEvent(Core::System& system, Handle event_handle);
Result ClearEvent(Core::System& system, Handle event_handle);
Result MapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
Result CreateTransferMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result CloseHandle(Core::System& system, Handle handle);
Result ResetSignal(Core::System& system, Handle handle);
Result WaitSynchronization(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization(Core::System& system, Handle handle);
Result ArbitrateLock(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
Result ArbitrateUnlock(Core::System& system, uint64_t address);
Result WaitProcessWideKeyAtomic(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey(Core::System& system, uint64_t cv_key, int32_t count);
int64_t GetSystemTick(Core::System& system);
Result ConnectToNamedPort(Core::System& system, Handle* out_handle, uint64_t name);
Result SendSyncRequest(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result GetProcessId(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
Result OutputDebugString(Core::System& system, uint64_t debug_str, uint64_t len);
void ReturnFromException(Core::System& system, Result result);
Result GetInfo(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache(Core::System& system);
Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size);
Result MapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext3(Core::System& system, uint64_t out_context, Handle thread_handle);
Result WaitForAddress(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState(Core::System& system);
Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
Result AcceptSession(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result CreateEvent(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
Result UnmapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
Result SetUnsafeLimit(Core::System& system, uint64_t limit);
Result CreateCodeMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem(Core::System& system);
Result ReadWriteRegister(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
Result CreateInterruptEvent(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
Result CreateDeviceAddressSpace(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess(Core::System& system, Handle debug_handle);
Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle);
Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
Result GetProcessList(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
Result GetThreadList(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result UnmapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess(Core::System& system, Handle process_handle);
Result GetProcessInfo(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);

Result SetHeapSize64From32(Core::System& system, uint64_t* out_address, uint32_t size);
Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, MemoryPermission perm);
Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, uint32_t mask, uint32_t attr);
Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, uint32_t address);
void ExitProcess64From32(Core::System& system);
Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg, uint32_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread64From32(Core::System& system, Handle thread_handle);
void ExitThread64From32(Core::System& system);
void SleepThread64From32(Core::System& system, int64_t ns);
Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber64From32(Core::System& system);
Result SignalEvent64From32(Core::System& system, Handle event_handle);
Result ClearEvent64From32(Core::System& system, Handle event_handle);
Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size);
Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
Result CloseHandle64From32(Core::System& system, Handle handle);
Result ResetSignal64From32(Core::System& system, Handle handle);
Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization64From32(Core::System& system, Handle handle);
Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address, uint32_t tag);
Result ArbitrateUnlock64From32(Core::System& system, uint32_t address);
Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count);
int64_t GetSystemTick64From32(Core::System& system);
Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name);
Result SendSyncRequest64From32(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size);
Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len);
void ReturnFromException64From32(Core::System& system, Result result);
Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache64From32(Core::System& system);
Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size);
Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle);
Result WaitForAddress64From32(Core::System& system, uint32_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress64From32(Core::System& system, uint32_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState64From32(Core::System& system);
Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint32_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint32_t name);
Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index, uint32_t message_buffer, uint32_t message_buffer_size, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result CreateEvent64From32(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size, MemoryPermission perm);
Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size);
Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit);
Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size);
Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem64From32(Core::System& system);
Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity64From32(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size);
Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, uint32_t address);
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint32_t size);
Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address);
Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle);
Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle);
Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags, uint32_t thread_ids, int32_t num_thread_ids);
Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes, uint32_t out_process_ids, int32_t max_out_count);
Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads, uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id, uint32_t context, uint32_t context_flags);
Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint32_t address);
Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle, uint32_t address, uint32_t size);
Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer, uint32_t address, uint32_t size);
Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort64From32(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint32_t name);
Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name, int32_t max_sessions);
Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters, uint32_t caps, int32_t num_caps);
Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess64From32(Core::System& system, Handle process_handle);
Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);

Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
void ExitProcess64(Core::System& system);
Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread64(Core::System& system, Handle thread_handle);
void ExitThread64(Core::System& system);
void SleepThread64(Core::System& system, int64_t ns);
Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber64(Core::System& system);
Result SignalEvent64(Core::System& system, Handle event_handle);
Result ClearEvent64(Core::System& system, Handle event_handle);
Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result CloseHandle64(Core::System& system, Handle handle);
Result ResetSignal64(Core::System& system, Handle handle);
Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization64(Core::System& system, Handle handle);
Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
Result ArbitrateUnlock64(Core::System& system, uint64_t address);
Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count);
int64_t GetSystemTick64(Core::System& system);
Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name);
Result SendSyncRequest64(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len);
void ReturnFromException64(Core::System& system, Result result);
Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache64(Core::System& system);
Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size);
Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle);
Result WaitForAddress64(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress64(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState64(Core::System& system);
Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession64(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
Result SetUnsafeLimit64(Core::System& system, uint64_t limit);
Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem64(Core::System& system);
Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity64(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess64(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess64(Core::System& system, Handle debug_handle);
Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle);
Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess64(Core::System& system, Handle process_handle);
Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit64(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);

enum class SvcId : u32 {
    SetHeapSize = 0x1,
    SetMemoryPermission = 0x2,
    SetMemoryAttribute = 0x3,
    MapMemory = 0x4,
    UnmapMemory = 0x5,
    QueryMemory = 0x6,
    ExitProcess = 0x7,
    CreateThread = 0x8,
    StartThread = 0x9,
    ExitThread = 0xa,
    SleepThread = 0xb,
    GetThreadPriority = 0xc,
    SetThreadPriority = 0xd,
    GetThreadCoreMask = 0xe,
    SetThreadCoreMask = 0xf,
    GetCurrentProcessorNumber = 0x10,
    SignalEvent = 0x11,
    ClearEvent = 0x12,
    MapSharedMemory = 0x13,
    UnmapSharedMemory = 0x14,
    CreateTransferMemory = 0x15,
    CloseHandle = 0x16,
    ResetSignal = 0x17,
    WaitSynchronization = 0x18,
    CancelSynchronization = 0x19,
    ArbitrateLock = 0x1a,
    ArbitrateUnlock = 0x1b,
    WaitProcessWideKeyAtomic = 0x1c,
    SignalProcessWideKey = 0x1d,
    GetSystemTick = 0x1e,
    ConnectToNamedPort = 0x1f,
    SendSyncRequestLight = 0x20,
    SendSyncRequest = 0x21,
    SendSyncRequestWithUserBuffer = 0x22,
    SendAsyncRequestWithUserBuffer = 0x23,
    GetProcessId = 0x24,
    GetThreadId = 0x25,
    Break = 0x26,
    OutputDebugString = 0x27,
    ReturnFromException = 0x28,
    GetInfo = 0x29,
    FlushEntireDataCache = 0x2a,
    FlushDataCache = 0x2b,
    MapPhysicalMemory = 0x2c,
    UnmapPhysicalMemory = 0x2d,
    GetDebugFutureThreadInfo = 0x2e,
    GetLastThreadInfo = 0x2f,
    GetResourceLimitLimitValue = 0x30,
    GetResourceLimitCurrentValue = 0x31,
    SetThreadActivity = 0x32,
    GetThreadContext3 = 0x33,
    WaitForAddress = 0x34,
    SignalToAddress = 0x35,
    SynchronizePreemptionState = 0x36,
    GetResourceLimitPeakValue = 0x37,
    CreateIoPool = 0x39,
    CreateIoRegion = 0x3a,
    KernelDebug = 0x3c,
    ChangeKernelTraceState = 0x3d,
    CreateSession = 0x40,
    AcceptSession = 0x41,
    ReplyAndReceiveLight = 0x42,
    ReplyAndReceive = 0x43,
    ReplyAndReceiveWithUserBuffer = 0x44,
    CreateEvent = 0x45,
    MapIoRegion = 0x46,
    UnmapIoRegion = 0x47,
    MapPhysicalMemoryUnsafe = 0x48,
    UnmapPhysicalMemoryUnsafe = 0x49,
    SetUnsafeLimit = 0x4a,
    CreateCodeMemory = 0x4b,
    ControlCodeMemory = 0x4c,
    SleepSystem = 0x4d,
    ReadWriteRegister = 0x4e,
    SetProcessActivity = 0x4f,
    CreateSharedMemory = 0x50,
    MapTransferMemory = 0x51,
    UnmapTransferMemory = 0x52,
    CreateInterruptEvent = 0x53,
    QueryPhysicalAddress = 0x54,
    QueryIoMapping = 0x55,
    CreateDeviceAddressSpace = 0x56,
    AttachDeviceAddressSpace = 0x57,
    DetachDeviceAddressSpace = 0x58,
    MapDeviceAddressSpaceByForce = 0x59,
    MapDeviceAddressSpaceAligned = 0x5a,
    UnmapDeviceAddressSpace = 0x5c,
    InvalidateProcessDataCache = 0x5d,
    StoreProcessDataCache = 0x5e,
    FlushProcessDataCache = 0x5f,
    DebugActiveProcess = 0x60,
    BreakDebugProcess = 0x61,
    TerminateDebugProcess = 0x62,
    GetDebugEvent = 0x63,
    ContinueDebugEvent = 0x64,
    GetProcessList = 0x65,
    GetThreadList = 0x66,
    GetDebugThreadContext = 0x67,
    SetDebugThreadContext = 0x68,
    QueryDebugProcessMemory = 0x69,
    ReadDebugProcessMemory = 0x6a,
    WriteDebugProcessMemory = 0x6b,
    SetHardwareBreakPoint = 0x6c,
    GetDebugThreadParam = 0x6d,
    GetSystemInfo = 0x6f,
    CreatePort = 0x70,
    ManageNamedPort = 0x71,
    ConnectToPort = 0x72,
    SetProcessMemoryPermission = 0x73,
    MapProcessMemory = 0x74,
    UnmapProcessMemory = 0x75,
    QueryProcessMemory = 0x76,
    MapProcessCodeMemory = 0x77,
    UnmapProcessCodeMemory = 0x78,
    CreateProcess = 0x79,
    StartProcess = 0x7a,
    TerminateProcess = 0x7b,
    GetProcessInfo = 0x7c,
    CreateResourceLimit = 0x7d,
    SetResourceLimitLimitValue = 0x7e,
    CallSecureMonitor = 0x7f,
    MapInsecureMemory = 0x90,
    UnmapInsecureMemory = 0x91,
};
// clang-format on

// Custom ABI.
Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args);

Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args);
Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args);
Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args);

void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args);
void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args);
void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args);

// Defined in svc_light_ipc.cpp.
void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system, std::span<uint64_t, 8> args);
void SvcWrap_ReplyAndReceiveLight64(Core::System& system, std::span<uint64_t, 8> args);

void SvcWrap_SendSyncRequestLight64From32(Core::System& system, std::span<uint64_t, 8> args);
void SvcWrap_SendSyncRequestLight64(Core::System& system, std::span<uint64_t, 8> args);

// Defined in svc_secure_monitor_call.cpp.
void SvcWrap_CallSecureMonitor64From32(Core::System& system, std::span<uint64_t, 8> args);
void SvcWrap_CallSecureMonitor64(Core::System& system, std::span<uint64_t, 8> args);

// Perform a supervisor call by index.
void Call(Core::System& system, u32 imm);

} // namespace Kernel::Svc

repo_name: litucks/torzu

license: mit


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/core.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"

namespace Kernel::Svc {

/// Sets the thread activity
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);

    // Validate the activity.
    static constexpr auto IsValidThreadActivity = [](ThreadActivity activity) {
        return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused;
    };
    R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue);

    // Get the thread from its handle.
    KScopedAutoObject thread =
        GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
    R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);

    // Check that the activity is being set on a non-current thread for the current process.
    R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()),
             ResultInvalidHandle);
    R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy);

    // Set the activity.
    R_TRY(thread->SetActivity(thread_activity));

    return ResultSuccess;
}

Result SetProcessActivity(Core::System& system, Handle process_handle,
                          ProcessActivity process_activity) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result SetThreadActivity64(Core::System& system, Handle thread_handle,
                           ThreadActivity thread_activity) {
    return SetThreadActivity(system, thread_handle, thread_activity);
}

Result SetProcessActivity64(Core::System& system, Handle process_handle,
                            ProcessActivity process_activity) {
    return SetProcessActivity(system, process_handle, process_activity);
}

Result SetThreadActivity64From32(Core::System& system, Handle thread_handle,
                                 ThreadActivity thread_activity) {
    return SetThreadActivity(system, thread_handle, thread_activity);
}

Result SetProcessActivity64From32(Core::System& system, Handle process_handle,
                                  ProcessActivity process_activity) {
    return SetProcessActivity(system, process_handle, process_activity);
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/core.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/svc_types.h"

namespace Kernel::Svc {
namespace {

constexpr bool IsValidSignalType(Svc::SignalType type) {
    switch (type) {
    case Svc::SignalType::Signal:
    case Svc::SignalType::SignalAndIncrementIfEqual:
    case Svc::SignalType::SignalAndModifyByWaitingCountIfEqual:
        return true;
    default:
        return false;
    }
}

constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) {
    switch (type) {
    case Svc::ArbitrationType::WaitIfLessThan:
    case Svc::ArbitrationType::DecrementAndWaitIfLessThan:
    case Svc::ArbitrationType::WaitIfEqual:
        return true;
    default:
        return false;
    }
}

} // namespace

// Wait for an address (via Address Arbiter)
Result WaitForAddress(Core::System& system, u64 address, 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);

    // Validate input.
    R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory);
    R_UNLESS(Common::IsAligned(address, sizeof(s32)), ResultInvalidAddress);
    R_UNLESS(IsValidArbitrationType(arb_type), ResultInvalidEnumValue);

    // Convert timeout from nanoseconds to ticks.
    s64 timeout{};
    if (timeout_ns > 0) {
        const s64 offset_tick(timeout_ns);
        if (offset_tick > 0) {
            timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2;
            if (timeout <= 0) {
                timeout = std::numeric_limits<s64>::max();
            }
        } else {
            timeout = std::numeric_limits<s64>::max();
        }
    } else {
        timeout = timeout_ns;
    }

    R_RETURN(
        GetCurrentProcess(system.Kernel()).WaitAddressArbiter(address, arb_type, value, timeout));
}

// Signals to an address (via Address Arbiter)
Result SignalToAddress(Core::System& system, u64 address, 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);

    // Validate input.
    R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory);
    R_UNLESS(Common::IsAligned(address, sizeof(s32)), ResultInvalidAddress);
    R_UNLESS(IsValidSignalType(signal_type), ResultInvalidEnumValue);

    R_RETURN(GetCurrentProcess(system.Kernel())
                 .SignalAddressArbiter(address, signal_type, value, count));
}

Result WaitForAddress64(Core::System& system, u64 address, ArbitrationType arb_type, s32 value,
                        s64 timeout_ns) {
    R_RETURN(WaitForAddress(system, address, arb_type, value, timeout_ns));
}

Result SignalToAddress64(Core::System& system, u64 address, SignalType signal_type, s32 value,
                         s32 count) {
    R_RETURN(SignalToAddress(system, address, signal_type, value, count));
}

Result WaitForAddress64From32(Core::System& system, u32 address, ArbitrationType arb_type,
                              s32 value, s64 timeout_ns) {
    R_RETURN(WaitForAddress(system, address, arb_type, value, timeout_ns));
}

Result SignalToAddress64From32(Core::System& system, u32 address, SignalType signal_type, s32 value,
                               s32 count) {
    R_RETURN(SignalToAddress(system, address, signal_type, value, count));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"

namespace Kernel::Svc {

Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
                            uint64_t address) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size,
                      uint64_t physical_address, uint64_t size) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
                              uint64_t address) {
    R_RETURN(QueryPhysicalAddress(system, out_info, address));
}

Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size,
                        uint64_t physical_address, uint64_t size) {
    R_RETURN(QueryIoMapping(system, out_address, out_size, physical_address, size));
}

Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info,
                                    uint32_t address) {
    lp64::PhysicalMemoryInfo info{};
    R_TRY(QueryPhysicalAddress(system, std::addressof(info), address));

    *out_info = {
        .physical_address = info.physical_address,
        .virtual_address = static_cast<u32>(info.virtual_address),
        .size = static_cast<u32>(info.size),
    };
    R_SUCCEED();
}

Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size,
                              uint64_t physical_address, uint32_t size) {
    R_RETURN(QueryIoMapping(system, reinterpret_cast<uint64_t*>(out_address),
                            reinterpret_cast<uint64_t*>(out_size), physical_address, size));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/core.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/svc_types.h"

namespace Kernel::Svc {

void FlushEntireDataCache(Core::System& system) {
    UNIMPLEMENTED();
}

Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
                                  uint64_t size) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
                             uint64_t size) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 address, u64 size) {
    // Validate address/size.
    R_UNLESS(size > 0, ResultInvalidSize);
    R_UNLESS(address == static_cast<uint64_t>(address), ResultInvalidCurrentMemory);
    R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);

    // Get the process from its handle.
    KScopedAutoObject process =
        GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
    R_UNLESS(process.IsNotNull(), ResultInvalidHandle);

    // Verify the region is within range.
    auto& page_table = process->GetPageTable();
    R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);

    // Perform the operation.
    R_RETURN(GetCurrentMemory(system.Kernel()).FlushDataCache(address, size));
}

void FlushEntireDataCache64(Core::System& system) {
    FlushEntireDataCache(system);
}

Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size) {
    R_RETURN(FlushDataCache(system, address, size));
}

Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
                                    uint64_t size) {
    R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
}

Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
                               uint64_t size) {
    R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
}

Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
                               uint64_t size) {
    R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
}

void FlushEntireDataCache64From32(Core::System& system) {
    return FlushEntireDataCache(system);
}

Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size) {
    R_RETURN(FlushDataCache(system, address, size));
}

Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle,
                                          uint64_t address, uint64_t size) {
    R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
}

Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
                                     uint64_t size) {
    R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
}

Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
                                     uint64_t size) {
    R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"

namespace Kernel::Svc {
namespace {

constexpr bool IsValidMapCodeMemoryPermission(MemoryPermission perm) {
    return perm == MemoryPermission::ReadWrite;
}

constexpr bool IsValidMapToOwnerCodeMemoryPermission(MemoryPermission perm) {
    return perm == MemoryPermission::Read || perm == MemoryPermission::ReadExecute;
}

constexpr bool IsValidUnmapCodeMemoryPermission(MemoryPermission perm) {
    return perm == MemoryPermission::None;
}

constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm) {
    return perm == MemoryPermission::None;
}

} // namespace

Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) {
    LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);

    // Get kernel instance.
    auto& kernel = system.Kernel();

    // Validate address / size.
    R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
    R_UNLESS(size > 0, ResultInvalidSize);
    R_UNLESS((address < address + size), ResultInvalidCurrentMemory);

    // Create the code memory.

    KCodeMemory* code_mem = KCodeMemory::Create(kernel);
    R_UNLESS(code_mem != nullptr, ResultOutOfResource);
    SCOPE_EXIT {
        code_mem->Close();
    };

    // Verify that the region is in range.
    R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size),
             ResultInvalidCurrentMemory);

    // Initialize the code memory.
    R_TRY(code_mem->Initialize(system.DeviceMemory(), address, size));

    // Register the code memory.
    KCodeMemory::Register(kernel, code_mem);

    // Add the code memory to the handle table.
    R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, code_mem));

    R_SUCCEED();
}

Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
                         CodeMemoryOperation operation, u64 address, uint64_t size,
                         MemoryPermission perm) {

    LOG_TRACE(Kernel_SVC,
              "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, "
              "permission=0x{:X}",
              code_memory_handle, operation, address, size, perm);

    // Validate the address / size.
    R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
    R_UNLESS(size > 0, ResultInvalidSize);
    R_UNLESS((address < address + size), ResultInvalidCurrentMemory);

    // Get the code memory from its handle.
    KScopedAutoObject code_mem = GetCurrentProcess(system.Kernel())
                                     .GetHandleTable()
                                     .GetObject<KCodeMemory>(code_memory_handle);
    R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle);

    // NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process.
    // This enables homebrew usage of these SVCs for JIT.

    // Perform the operation.
    switch (operation) {
    case CodeMemoryOperation::Map: {
        // Check that the region is in range.
        R_UNLESS(GetCurrentProcess(system.Kernel())
                     .GetPageTable()
                     .CanContain(address, size, KMemoryState::CodeOut),
                 ResultInvalidMemoryRegion);

        // Check the memory permission.
        R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);

        // Map the memory.
        R_TRY(code_mem->Map(address, size));
    } break;
    case CodeMemoryOperation::Unmap: {
        // Check that the region is in range.
        R_UNLESS(GetCurrentProcess(system.Kernel())
                     .GetPageTable()
                     .CanContain(address, size, KMemoryState::CodeOut),
                 ResultInvalidMemoryRegion);

        // Check the memory permission.
        R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);

        // Unmap the memory.
        R_TRY(code_mem->Unmap(address, size));
    } break;
    case CodeMemoryOperation::MapToOwner: {
        // Check that the region is in range.
        R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size,
                                                                 KMemoryState::GeneratedCode),
                 ResultInvalidMemoryRegion);

        // Check the memory permission.
        R_UNLESS(IsValidMapToOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);

        // Map the memory to its owner.
        R_TRY(code_mem->MapToOwner(address, size, perm));
    } break;
    case CodeMemoryOperation::UnmapFromOwner: {
        // Check that the region is in range.
        R_UNLESS(code_mem->GetOwner()->GetPageTable().CanContain(address, size,
                                                                 KMemoryState::GeneratedCode),
                 ResultInvalidMemoryRegion);

        // Check the memory permission.
        R_UNLESS(IsValidUnmapFromOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);

        // Unmap the memory from its owner.
        R_TRY(code_mem->UnmapFromOwner(address, size));
    } break;
    default:
        R_THROW(ResultInvalidEnumValue);
    }

    R_SUCCEED();
}

Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address,
                          uint64_t size) {
    R_RETURN(CreateCodeMemory(system, out_handle, address, size));
}

Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle,
                           CodeMemoryOperation operation, uint64_t address, uint64_t size,
                           MemoryPermission perm) {
    R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
}

Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address,
                                uint32_t size) {
    R_RETURN(CreateCodeMemory(system, out_handle, address, size));
}

Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle,
                                 CodeMemoryOperation operation, uint64_t address, uint64_t size,
                                 MemoryPermission perm) {
    R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/core.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"

namespace Kernel::Svc {

/// Wait process wide key atomic
Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 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);

    // Validate input.
    R_UNLESS(!IsKernelAddress(address), ResultInvalidCurrentMemory);
    R_UNLESS(Common::IsAligned(address, sizeof(s32)), ResultInvalidAddress);

    // Convert timeout from nanoseconds to ticks.
    s64 timeout{};
    if (timeout_ns > 0) {
        const s64 offset_tick(timeout_ns);
        if (offset_tick > 0) {
            timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2;
            if (timeout <= 0) {
                timeout = std::numeric_limits<s64>::max();
            }
        } else {
            timeout = std::numeric_limits<s64>::max();
        }
    } else {
        timeout = timeout_ns;
    }

    // Wait on the condition variable.
    R_RETURN(
        GetCurrentProcess(system.Kernel())
            .WaitConditionVariable(address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout));
}

/// Signal process wide key
void SignalProcessWideKey(Core::System& system, u64 cv_key, s32 count) {
    LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);

    // Signal the condition variable.
    return GetCurrentProcess(system.Kernel())
        .SignalConditionVariable(Common::AlignDown(cv_key, sizeof(u32)), count);
}

Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key,
                                  uint32_t tag, int64_t timeout_ns) {
    R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
}

void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count) {
    SignalProcessWideKey(system, cv_key, count);
}

Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key,
                                        uint32_t tag, int64_t timeout_ns) {
    R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
}

void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count) {
    SignalProcessWideKey(system, cv_key, count);
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"

namespace Kernel::Svc {

Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result BreakDebugProcess(Core::System& system, Handle debug_handle) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result TerminateDebugProcess(Core::System& system, Handle debug_handle) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags,
                          uint64_t user_thread_ids, int32_t num_thread_ids) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle,
                             uint64_t thread_id, uint32_t context_flags) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id,
                             uint64_t user_context, uint32_t context_flags) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info,
                               PageInfo* out_page_info, Handle process_handle, uint64_t address) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle,
                              uint64_t address, uint64_t size) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer,
                               uint64_t address, uint64_t size) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name,
                             uint64_t flags, uint64_t value) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32,
                           Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
    UNIMPLEMENTED();
    R_THROW(ResultNotImplemented);
}

Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id) {
    R_RETURN(DebugActiveProcess(system, out_handle, process_id));
}

Result BreakDebugProcess64(Core::System& system, Handle debug_handle) {
    R_RETURN(BreakDebugProcess(system, debug_handle));
}

Result TerminateDebugProcess64(Core::System& system, Handle debug_handle) {
    R_RETURN(TerminateDebugProcess(system, debug_handle));
}

Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle) {
    R_RETURN(GetDebugEvent(system, out_info, debug_handle));
}

Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags,
                            uint64_t thread_ids, int32_t num_thread_ids) {
    R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
}

Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle,
                               uint64_t thread_id, uint32_t context_flags) {
    R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
}

Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id,
                               uint64_t context, uint32_t context_flags) {
    R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
}

Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info,
                                 PageInfo* out_page_info, Handle debug_handle, uint64_t address) {
    R_RETURN(
        QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
}

Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle,
                                uint64_t address, uint64_t size) {
    R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
}

Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer,
                                 uint64_t address, uint64_t size) {
    R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
}

Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name,
                               uint64_t flags, uint64_t value) {
    R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
}

Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32,
                             Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
    R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
}

Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id) {
    R_RETURN(DebugActiveProcess(system, out_handle, process_id));
}

Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle) {
    R_RETURN(BreakDebugProcess(system, debug_handle));
}

Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle) {
    R_RETURN(TerminateDebugProcess(system, debug_handle));
}

Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle) {
    R_RETURN(GetDebugEvent(system, out_info, debug_handle));
}

Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags,
                                  uint32_t thread_ids, int32_t num_thread_ids) {
    R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
}

Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context,
                                     Handle debug_handle, uint64_t thread_id,
                                     uint32_t context_flags) {
    R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
}

Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id,
                                     uint32_t context, uint32_t context_flags) {
    R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
}

Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info,
                                       PageInfo* out_page_info, Handle debug_handle,
                                       uint32_t address) {
    R_RETURN(
        QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
}

Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle,
                                      uint32_t address, uint32_t size) {
    R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
}

Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer,
                                       uint32_t address, uint32_t size) {
    R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
}

Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name,
                                     uint64_t flags, uint64_t value) {
    R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
}

Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32,
                                   Handle debug_handle, uint64_t thread_id,
                                   DebugThreadParam param) {
    R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/core.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"

namespace Kernel::Svc {

/// Used to output a message on a debug hardware unit - does nothing on a retail unit
Result OutputDebugString(Core::System& system, u64 address, u64 len) {
    R_SUCCEED_IF(len == 0);

    std::string str(len, '\0');
    GetCurrentMemory(system.Kernel()).ReadBlock(address, str.data(), str.size());
    LOG_INFO(Debug_Emulated, "{}", str);

    R_SUCCEED();
}

Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len) {
    R_RETURN(OutputDebugString(system, debug_str, len));
}

Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len) {
    R_RETURN(OutputDebugString(system, debug_str, len));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "common/alignment.h"
#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/k_device_address_space.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/svc.h"

namespace Kernel::Svc {

constexpr inline u64 DeviceAddressSpaceAlignMask = (1ULL << 22) - 1;

constexpr bool IsProcessAndDeviceAligned(uint64_t process_address, uint64_t device_address) {
    return (process_address & DeviceAddressSpaceAlignMask) ==
           (device_address & DeviceAddressSpaceAlignMask);
}

Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_address,
                                uint64_t das_size) {
    // Validate input.
    R_UNLESS(Common::IsAligned(das_address, PageSize), ResultInvalidMemoryRegion);
    R_UNLESS(Common::IsAligned(das_size, PageSize), ResultInvalidMemoryRegion);
    R_UNLESS(das_size > 0, ResultInvalidMemoryRegion);
    R_UNLESS((das_address < das_address + das_size), ResultInvalidMemoryRegion);

    // Create the device address space.
    KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel());
    R_UNLESS(das != nullptr, ResultOutOfResource);
    SCOPE_EXIT {
        das->Close();
    };

    // Initialize the device address space.
    R_TRY(das->Initialize(das_address, das_size));

    // Register the device address space.
    KDeviceAddressSpace::Register(system.Kernel(), das);

    // Add to the handle table.
    R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, das));

    R_SUCCEED();
}

Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
    // Get the device address space.
    KScopedAutoObject das = GetCurrentProcess(system.Kernel())
                                .GetHandleTable()
                                .GetObject<KDeviceAddressSpace>(das_handle);
    R_UNLESS(das.IsNotNull(), ResultInvalidHandle);

    // Attach.
    R_RETURN(das->Attach(device_name));
}

Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
    // Get the device address space.
    KScopedAutoObject das = GetCurrentProcess(system.Kernel())
                                .GetHandleTable()
                                .GetObject<KDeviceAddressSpace>(das_handle);
    R_UNLESS(das.IsNotNull(), ResultInvalidHandle);

    // Detach.
    R_RETURN(das->Detach(device_name));
}

constexpr bool IsValidDeviceMemoryPermission(MemoryPermission device_perm) {
    switch (device_perm) {
    case MemoryPermission::Read:
    case MemoryPermission::Write:
    case MemoryPermission::ReadWrite:
        return true;
    default:
        return false;
    }
}

Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle,
                                    uint64_t process_address, uint64_t size,
                                    uint64_t device_address, u32 option) {
    // Decode the option.
    const MapDeviceAddressSpaceOption option_pack{option};
    const auto device_perm = option_pack.permission;
    const auto reserved = option_pack.reserved;

    // Validate input.
    R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
    R_UNLESS(size > 0, ResultInvalidSize);
    R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
    R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
    R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
             ResultInvalidCurrentMemory);
    R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
    R_UNLESS(reserved == 0, ResultInvalidEnumValue);

    // Get the device address space.
    KScopedAutoObject das = GetCurrentProcess(system.Kernel())
                                .GetHandleTable()
                                .GetObject<KDeviceAddressSpace>(das_handle);
    R_UNLESS(das.IsNotNull(), ResultInvalidHandle);

    // Get the process.
    KScopedAutoObject process =
        GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
    R_UNLESS(process.IsNotNull(), ResultInvalidHandle);

    // Validate that the process address is within range.
    auto& page_table = process->GetPageTable();
    R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);

    // Map.
    R_RETURN(
        das->MapByForce(std::addressof(page_table), process_address, size, device_address, option));
}

Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle,
                                    uint64_t process_address, uint64_t size,
                                    uint64_t device_address, u32 option) {
    // Decode the option.
    const MapDeviceAddressSpaceOption option_pack{option};
    const auto device_perm = option_pack.permission;
    const auto reserved = option_pack.reserved;

    // Validate input.
    R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
    R_UNLESS(IsProcessAndDeviceAligned(process_address, device_address), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
    R_UNLESS(size > 0, ResultInvalidSize);
    R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
    R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
    R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
             ResultInvalidCurrentMemory);
    R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
    R_UNLESS(reserved == 0, ResultInvalidEnumValue);

    // Get the device address space.
    KScopedAutoObject das = GetCurrentProcess(system.Kernel())
                                .GetHandleTable()
                                .GetObject<KDeviceAddressSpace>(das_handle);
    R_UNLESS(das.IsNotNull(), ResultInvalidHandle);

    // Get the process.
    KScopedAutoObject process =
        GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
    R_UNLESS(process.IsNotNull(), ResultInvalidHandle);

    // Validate that the process address is within range.
    auto& page_table = process->GetPageTable();
    R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);

    // Map.
    R_RETURN(
        das->MapAligned(std::addressof(page_table), process_address, size, device_address, option));
}

Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle,
                               uint64_t process_address, uint64_t size, uint64_t device_address) {
    // Validate input.
    R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
    R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
    R_UNLESS(size > 0, ResultInvalidSize);
    R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
    R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
    R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
             ResultInvalidCurrentMemory);

    // Get the device address space.
    KScopedAutoObject das = GetCurrentProcess(system.Kernel())
                                .GetHandleTable()
                                .GetObject<KDeviceAddressSpace>(das_handle);
    R_UNLESS(das.IsNotNull(), ResultInvalidHandle);

    // Get the process.
    KScopedAutoObject process =
        GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
    R_UNLESS(process.IsNotNull(), ResultInvalidHandle);

    // Validate that the process address is within range.
    auto& page_table = process->GetPageTable();
    R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);

    R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address));
}

Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address,
                                  uint64_t das_size) {
    R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size));
}

Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) {
    R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle));
}

Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) {
    R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle));
}

Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle,
                                      Handle process_handle, uint64_t process_address,
                                      uint64_t size, uint64_t device_address, u32 option) {
    R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size,
                                          device_address, option));
}

Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle,
                                      Handle process_handle, uint64_t process_address,
                                      uint64_t size, uint64_t device_address, u32 option) {
    R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size,
                                          device_address, option));
}

Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle,
                                 uint64_t process_address, uint64_t size, uint64_t device_address) {
    R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size,
                                     device_address));
}

Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle,
                                        uint64_t das_address, uint64_t das_size) {
    R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size));
}

Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name,
                                        Handle das_handle) {
    R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle));
}

Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name,
                                        Handle das_handle) {
    R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle));
}

Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle,
                                            Handle process_handle, uint64_t process_address,
                                            uint32_t size, uint64_t device_address, u32 option) {
    R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size,
                                          device_address, option));
}

Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle,
                                            Handle process_handle, uint64_t process_address,
                                            uint32_t size, uint64_t device_address, u32 option) {
    R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size,
                                          device_address, option));
}

Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle,
                                       Handle process_handle, uint64_t process_address,
                                       uint32_t size, uint64_t device_address) {
    R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size,
                                     device_address));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"

namespace Kernel::Svc {

Result SignalEvent(Core::System& system, Handle event_handle) {
    LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);

    // Get the current handle table.
    const KHandleTable& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();

    // Get the event.
    KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
    R_UNLESS(event.IsNotNull(), ResultInvalidHandle);

    R_RETURN(event->Signal());
}

Result ClearEvent(Core::System& system, Handle event_handle) {
    LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);

    // Get the current handle table.
    const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();

    // Try to clear the writable event.
    {
        KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
        if (event.IsNotNull()) {
            R_RETURN(event->Clear());
        }
    }

    // Try to clear the readable event.
    {
        KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
        if (readable_event.IsNotNull()) {
            R_RETURN(readable_event->Clear());
        }
    }

    R_THROW(ResultInvalidHandle);
}

Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
    LOG_DEBUG(Kernel_SVC, "called");

    // Get the kernel reference and handle table.
    auto& kernel = system.Kernel();
    auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();

    // Reserve a new event from the process resource limit
    KScopedResourceReservation event_reservation(GetCurrentProcessPointer(kernel),
                                                 LimitableResource::EventCountMax);
    R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);

    // Create a new event.
    KEvent* event = KEvent::Create(kernel);
    R_UNLESS(event != nullptr, ResultOutOfResource);

    // Initialize the event.
    event->Initialize(GetCurrentProcessPointer(kernel));

    // Commit the thread reservation.
    event_reservation.Commit();

    // Ensure that we clean up the event (and its only references are handle table) on function end.
    SCOPE_EXIT {
        event->GetReadableEvent().Close();
        event->Close();
    };

    // Register the event.
    KEvent::Register(kernel, event);

    // Add the event to the handle table.
    R_TRY(handle_table.Add(out_write, event));

    // Ensure that we maintain a clean handle state on exit.
    ON_RESULT_FAILURE {
        handle_table.Remove(*out_write);
    };

    // Add the readable event to the handle table.
    R_RETURN(handle_table.Add(out_read, std::addressof(event->GetReadableEvent())));
}

Result SignalEvent64(Core::System& system, Handle event_handle) {
    R_RETURN(SignalEvent(system, event_handle));
}

Result ClearEvent64(Core::System& system, Handle event_handle) {
    R_RETURN(ClearEvent(system, event_handle));
}

Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle) {
    R_RETURN(CreateEvent(system, out_write_handle, out_read_handle));
}

Result SignalEvent64From32(Core::System& system, Handle event_handle) {
    R_RETURN(SignalEvent(system, event_handle));
}

Result ClearEvent64From32(Core::System& system, Handle event_handle) {
    R_RETURN(ClearEvent(system, event_handle));
}

Result CreateEvent64From32(Core::System& system, Handle* out_write_handle,
                           Handle* out_read_handle) {
    R_RETURN(CreateEvent(system, out_write_handle, out_read_handle));
}

} // namespace Kernel::Svc


code:
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "core/core.h"
#include "core/debugger/debugger.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_types.h"
#include "core/memory.h"
#include "core/reporter.h"

namespace Kernel::Svc {

/// Break program execution
void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
    BreakReason break_reason =
        reason & static_cast<BreakReason>(~BreakReason::NotificationOnlyFlag);
    bool notification_only = True(reason & BreakReason::NotificationOnlyFlag);

    bool has_dumped_buffer{};
    std::vector<u8> debug_buffer;

    const auto handle_debug_buffer = [&](u64 addr, u64 sz) {
        if (sz == 0 || addr == 0 || has_dumped_buffer) {
            return;
        }

        auto& memory = GetCurrentMemory(system.Kernel());

        // This typically is an error code so we're going to assume this is the case
        if (sz == sizeof(u32)) {
            LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", memory.Read32(addr));
        } else {
            // We don't know what's in here so we'll hexdump it
            debug_buffer.resize(sz);
            memory.ReadBlock(addr, debug_buffer.data(), sz);
            std::string hexdump;
            for (std::size_t i = 0; i < debug_buffer.size(); i++) {
                hexdump += fmt::format("{:02X} ", debug_buffer[i]);
                if (i != 0 && i % 16 == 0) {
                    hexdump += '\n';
                }
            }
            LOG_CRITICAL(Debug_Emulated, "debug_buffer=\n{}", hexdump);
        }
        has_dumped_buffer = true;
    };
    switch (break_reason) {
    case BreakReason::Panic:
        LOG_CRITICAL(Debug_Emulated, "Userspace PANIC! info1=0x{:016X}, info2=0x{:016X}", info1,
                     info2);
        handle_debug_buffer(info1, info2);
        break;
    case BreakReason::Assert:
        LOG_CRITICAL(Debug_Emulated, "Userspace Assertion failed! info1=0x{:016X}, info2=0x{:016X}",
                     info1, info2);
        handle_debug_buffer(info1, info2);
        break;
    case BreakReason::User:
        LOG_WARNING(Debug_Emulated, "Userspace Break! 0x{:016X} with size 0x{:016X}", info1, info2);
        handle_debug_buffer(info1, info2);
        break;
    case BreakReason::PreLoadDll:
        LOG_INFO(Debug_Emulated,
                 "Userspace Attempting to load an NRO at 0x{:016X} with size 0x{:016X}", info1,
                 info2);
        break;
    case BreakReason::PostLoadDll:
        LOG_INFO(Debug_Emulated, "Userspace Loaded an NRO at 0x{:016X} with size 0x{:016X}", info1,
                 info2);
        break;
    case BreakReason::PreUnloadDll:
        LOG_INFO(Debug_Emulated,
                 "Userspace Attempting to unload an NRO at 0x{:016X} with size 0x{:016X}", info1,
                 info2);
        break;
    case BreakReason::PostUnloadDll:
        LOG_INFO(Debug_Emulated, "Userspace Unloaded an NRO at 0x{:016X} with size 0x{:016X}",
                 info1, info2);
        break;
    case BreakReason::CppException:
        LOG_CRITICAL(Debug_Emulated, "Signalling debugger. Uncaught C++ exception encountered.");
        break;
    default:
        LOG_WARNING(
            Debug_Emulated,
            "Signalling debugger, Unknown break reason {:#X}, info1=0x{:016X}, info2=0x{:016X}",
            reason, info1, info2);
        handle_debug_buffer(info1, info2);
        break;
    }

    system.GetReporter().SaveSvcBreakReport(
        static_cast<u32>(reason), notification_only, info1, info2,
        has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);

    if (!notification_only) {
        LOG_CRITICAL(
            Debug_Emulated,
            "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
            reason, info1, info2);

        handle_debug_buffer(info1, info2);

        system.CurrentPhysicalCore().LogBacktrace();
    }

    const bool is_hbl = GetCurrentProcess(system.Kernel()).IsHbl();
    const bool should_break = is_hbl || !notification_only;

    if (system.DebuggerEnabled() && should_break) {
        auto* thread = system.Kernel().GetCurrentEmuThread();
        system.GetDebugger().NotifyThreadStopped(thread);
        thread->RequestSuspend(Kernel::SuspendType::Debug);
    }
}

void ReturnFromException(Core::System& system, Result result) {
    UNIMPLEMENTED();
}

void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size) {
    Break(system, break_reason, arg, size);
}

void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size) {
    Break(system, break_reason, arg, size);
}

void ReturnFromException64(Core::System& system, Result result) {
    ReturnFromException(system, result);
}

void ReturnFromException64From32(Core::System& system, Result result) {
    ReturnFromException(system, result);
}

} // namespace Kernel::Svc