diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 61733c7ee..19b6753a4 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -158,7 +158,7 @@ public: ARM_Dynarmic& parent; Core::Timing& timing; - Kernel::SVC svc_context; + Kernel::SVCContext svc_context; }; ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode) diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 2eeae6ba6..4854eb23e 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -3864,7 +3864,7 @@ SWI_INST : { cpu->NumInstrsToExecute = num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs; num_instrs = 0; - Kernel::SVC{Core::System::GetInstance()}.CallSVC(inst_cream->num & 0xFFFF); + Kernel::SVCContext{Core::System::GetInstance()}.CallSVC(inst_cream->num & 0xFFFF); // The kernel would call ERET to get here, which clears exclusive memory state. cpu->UnsetExclusiveMemoryAddress(); } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 650054583..53728a66d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -29,6 +29,7 @@ #include "core/hle/kernel/session.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/svc.h" +#include "core/hle/kernel/svc_wrapper.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" #include "core/hle/kernel/vm_manager.h" @@ -56,6 +57,133 @@ enum ControlMemoryOperation { MEMOP_LINEAR = 0x10000, }; +struct MemoryInfo { + u32 base_address; + u32 size; + u32 permission; + u32 state; +}; + +struct PageInfo { + u32 flags; +}; + +/// Values accepted by svcGetSystemInfo's type parameter. +enum class SystemInfoType { + /** + * Reports total used memory for all regions or a specific one, according to the extra + * parameter. See `SystemInfoMemUsageRegion`. + */ + REGION_MEMORY_USAGE = 0, + /** + * Returns the memory usage for certain allocations done internally by the kernel. + */ + KERNEL_ALLOCATED_PAGES = 2, + /** + * "This returns the total number of processes which were launched directly by the kernel. + * For the ARM11 NATIVE_FIRM kernel, this is 5, for processes sm, fs, pm, loader, and pxi." + */ + KERNEL_SPAWNED_PIDS = 26, +}; + +/** + * Accepted by svcGetSystemInfo param with REGION_MEMORY_USAGE type. Selects a region to query + * memory usage of. + */ +enum class SystemInfoMemUsageRegion { + ALL = 0, + APPLICATION = 1, + SYSTEM = 2, + BASE = 3, +}; + +class SVC : public SVCWrapper { +public: + SVC(Core::System& system); + void CallSVC(u32 immediate); + +private: + Core::System& system; + Kernel::KernelSystem& kernel; + + friend class SVCWrapper; + + // ARM interfaces + + u32 GetReg(std::size_t n); + void SetReg(std::size_t n, u32 value); + + // SVC interfaces + + ResultCode ControlMemory(u32* out_addr, u32 addr0, u32 addr1, u32 size, u32 operation, + u32 permissions); + void ExitProcess(); + ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions); + ResultCode UnmapMemoryBlock(Handle handle, u32 addr); + ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address); + ResultCode SendSyncRequest(Handle handle); + ResultCode CloseHandle(Handle handle); + ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds); + ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count, + bool wait_all, s64 nano_seconds); + ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count, + Handle reply_target); + ResultCode CreateAddressArbiter(Handle* out_handle); + ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds); + void Break(u8 break_reason); + void OutputDebugString(VAddr address, s32 len); + ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle); + ResultCode GetResourceLimitCurrentValues(VAddr values, Handle resource_limit_handle, + VAddr names, u32 name_count); + ResultCode GetResourceLimitLimitValues(VAddr values, Handle resource_limit_handle, VAddr names, + u32 name_count); + ResultCode CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr stack_top, + u32 priority, s32 processor_id); + void ExitThread(); + ResultCode GetThreadPriority(u32* priority, Handle handle); + ResultCode SetThreadPriority(Handle handle, u32 priority); + ResultCode CreateMutex(Handle* out_handle, u32 initial_locked); + ResultCode ReleaseMutex(Handle handle); + ResultCode GetProcessId(u32* process_id, Handle process_handle); + ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle); + ResultCode GetThreadId(u32* thread_id, Handle handle); + ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count); + ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); + ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, + Handle process_handle, u32 addr); + ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32 addr); + ResultCode CreateEvent(Handle* out_handle, u32 reset_type); + ResultCode DuplicateHandle(Handle* out, Handle handle); + ResultCode SignalEvent(Handle handle); + ResultCode ClearEvent(Handle handle); + ResultCode CreateTimer(Handle* out_handle, u32 reset_type); + ResultCode ClearTimer(Handle handle); + ResultCode SetTimer(Handle handle, s64 initial, s64 interval); + ResultCode CancelTimer(Handle handle); + void SleepThread(s64 nanoseconds); + s64 GetSystemTick(); + ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, + u32 other_permission); + ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr name_address, + u32 max_sessions); + ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle); + ResultCode CreateSession(Handle* server_session, Handle* client_session); + ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle); + ResultCode GetSystemInfo(s64* out, u32 type, s32 param); + ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type); + + struct FunctionDef { + using Func = void (SVC::*)(); + + u32 id; + Func func; + const char* name; + }; + + static const FunctionDef SVC_Table[]; + static const FunctionDef* GetSVCInfo(u32 func_num); +}; + /// Map application or GSP heap memory ResultCode SVC::ControlMemory(u32* out_addr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions) { @@ -1446,4 +1574,11 @@ void SVC::SetReg(std::size_t n, u32 value) { system.CPU().SetReg(static_cast(n), value); } +SVCContext::SVCContext(Core::System& system) : impl(std::make_unique(system)) {} +SVCContext::~SVCContext() = default; + +void SVCContext::CallSVC(u32 immediate) { + impl->CallSVC(immediate); +} + } // namespace Kernel diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index 3d9bd3803..efddff9e8 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h @@ -4,12 +4,8 @@ #pragma once +#include #include "common/common_types.h" -#include "core/hle/kernel/handle_table.h" -#include "core/hle/kernel/svc_wrapper.h" -#include "core/hle/result.h" - -class ARM_Interface; namespace Core { class System; @@ -17,133 +13,16 @@ class System; namespace Kernel { -class KernelSystem; +class SVC; -struct MemoryInfo { - u32 base_address; - u32 size; - u32 permission; - u32 state; -}; - -struct PageInfo { - u32 flags; -}; - -/// Values accepted by svcGetSystemInfo's type parameter. -enum class SystemInfoType { - /** - * Reports total used memory for all regions or a specific one, according to the extra - * parameter. See `SystemInfoMemUsageRegion`. - */ - REGION_MEMORY_USAGE = 0, - /** - * Returns the memory usage for certain allocations done internally by the kernel. - */ - KERNEL_ALLOCATED_PAGES = 2, - /** - * "This returns the total number of processes which were launched directly by the kernel. - * For the ARM11 NATIVE_FIRM kernel, this is 5, for processes sm, fs, pm, loader, and pxi." - */ - KERNEL_SPAWNED_PIDS = 26, -}; - -/** - * Accepted by svcGetSystemInfo param with REGION_MEMORY_USAGE type. Selects a region to query - * memory usage of. - */ -enum class SystemInfoMemUsageRegion { - ALL = 0, - APPLICATION = 1, - SYSTEM = 2, - BASE = 3, -}; - -class SVC : public SVCWrapper { +class SVCContext { public: - SVC(Core::System& system); + SVCContext(Core::System& system); + ~SVCContext(); void CallSVC(u32 immediate); private: - Core::System& system; - Kernel::KernelSystem& kernel; - - friend class SVCWrapper; - - // ARM interfaces - - u32 GetReg(std::size_t n); - void SetReg(std::size_t n, u32 value); - - // SVC interfaces - - ResultCode ControlMemory(u32* out_addr, u32 addr0, u32 addr1, u32 size, u32 operation, - u32 permissions); - void ExitProcess(); - ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions); - ResultCode UnmapMemoryBlock(Handle handle, u32 addr); - ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address); - ResultCode SendSyncRequest(Handle handle); - ResultCode CloseHandle(Handle handle); - ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds); - ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count, - bool wait_all, s64 nano_seconds); - ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count, - Handle reply_target); - ResultCode CreateAddressArbiter(Handle* out_handle); - ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds); - void Break(u8 break_reason); - void OutputDebugString(VAddr address, s32 len); - ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle); - ResultCode GetResourceLimitCurrentValues(VAddr values, Handle resource_limit_handle, - VAddr names, u32 name_count); - ResultCode GetResourceLimitLimitValues(VAddr values, Handle resource_limit_handle, VAddr names, - u32 name_count); - ResultCode CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr stack_top, - u32 priority, s32 processor_id); - void ExitThread(); - ResultCode GetThreadPriority(u32* priority, Handle handle); - ResultCode SetThreadPriority(Handle handle, u32 priority); - ResultCode CreateMutex(Handle* out_handle, u32 initial_locked); - ResultCode ReleaseMutex(Handle handle); - ResultCode GetProcessId(u32* process_id, Handle process_handle); - ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle); - ResultCode GetThreadId(u32* thread_id, Handle handle); - ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count); - ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count); - ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, - Handle process_handle, u32 addr); - ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32 addr); - ResultCode CreateEvent(Handle* out_handle, u32 reset_type); - ResultCode DuplicateHandle(Handle* out, Handle handle); - ResultCode SignalEvent(Handle handle); - ResultCode ClearEvent(Handle handle); - ResultCode CreateTimer(Handle* out_handle, u32 reset_type); - ResultCode ClearTimer(Handle handle); - ResultCode SetTimer(Handle handle, s64 initial, s64 interval); - ResultCode CancelTimer(Handle handle); - void SleepThread(s64 nanoseconds); - s64 GetSystemTick(); - ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, - u32 other_permission); - ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr name_address, - u32 max_sessions); - ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle); - ResultCode CreateSession(Handle* server_session, Handle* client_session); - ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle); - ResultCode GetSystemInfo(s64* out, u32 type, s32 param); - ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type); - - struct FunctionDef { - using Func = void (SVC::*)(); - - u32 id; - Func func; - const char* name; - }; - - static const FunctionDef SVC_Table[]; - static const FunctionDef* GetSVCInfo(u32 func_num); + std::unique_ptr impl; }; } // namespace Kernel