diff options
| m--------- | externals/dynarmic | 0 | ||||
| -rw-r--r-- | src/core/arm/arm_interface.h | 5 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 198 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 105 |
5 files changed, 282 insertions, 34 deletions
diff --git a/externals/dynarmic b/externals/dynarmic | |||
| Subproject b759773b3b76c62200ecd4e097ec6ecfd825aac | Subproject 4f967387c07365b7ea35d2fa3e19b7df8872a09 | ||
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index fbdce4134..0c1d6ac39 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -33,16 +33,15 @@ public: | |||
| 33 | 33 | ||
| 34 | struct ThreadContext32 { | 34 | struct ThreadContext32 { |
| 35 | std::array<u32, 16> cpu_registers{}; | 35 | std::array<u32, 16> cpu_registers{}; |
| 36 | std::array<u32, 64> extension_registers{}; | ||
| 36 | u32 cpsr{}; | 37 | u32 cpsr{}; |
| 37 | std::array<u8, 4> padding{}; | ||
| 38 | std::array<u64, 32> fprs{}; | ||
| 39 | u32 fpscr{}; | 38 | u32 fpscr{}; |
| 40 | u32 fpexc{}; | 39 | u32 fpexc{}; |
| 41 | u32 tpidr{}; | 40 | u32 tpidr{}; |
| 42 | }; | 41 | }; |
| 43 | // Internally within the kernel, it expects the AArch32 version of the | 42 | // Internally within the kernel, it expects the AArch32 version of the |
| 44 | // thread context to be 344 bytes in size. | 43 | // thread context to be 344 bytes in size. |
| 45 | static_assert(sizeof(ThreadContext32) == 0x158); | 44 | static_assert(sizeof(ThreadContext32) == 0x150); |
| 46 | 45 | ||
| 47 | struct ThreadContext64 { | 46 | struct ThreadContext64 { |
| 48 | std::array<u64, 31> cpu_registers{}; | 47 | std::array<u64, 31> cpu_registers{}; |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 5df4fc079..cfda12098 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -222,13 +222,17 @@ void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) { | |||
| 222 | Dynarmic::A32::Context context; | 222 | Dynarmic::A32::Context context; |
| 223 | jit->SaveContext(context); | 223 | jit->SaveContext(context); |
| 224 | ctx.cpu_registers = context.Regs(); | 224 | ctx.cpu_registers = context.Regs(); |
| 225 | ctx.extension_registers = context.ExtRegs(); | ||
| 225 | ctx.cpsr = context.Cpsr(); | 226 | ctx.cpsr = context.Cpsr(); |
| 227 | ctx.fpscr = context.Fpscr(); | ||
| 226 | } | 228 | } |
| 227 | 229 | ||
| 228 | void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) { | 230 | void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) { |
| 229 | Dynarmic::A32::Context context; | 231 | Dynarmic::A32::Context context; |
| 230 | context.Regs() = ctx.cpu_registers; | 232 | context.Regs() = ctx.cpu_registers; |
| 233 | context.ExtRegs() = ctx.extension_registers; | ||
| 231 | context.SetCpsr(ctx.cpsr); | 234 | context.SetCpsr(ctx.cpsr); |
| 235 | context.SetFpscr(ctx.fpscr); | ||
| 232 | jit->LoadContext(context); | 236 | jit->LoadContext(context); |
| 233 | } | 237 | } |
| 234 | 238 | ||
| @@ -243,7 +247,9 @@ void ARM_Dynarmic_32::ClearInstructionCache() { | |||
| 243 | jit->ClearCache(); | 247 | jit->ClearCache(); |
| 244 | } | 248 | } |
| 245 | 249 | ||
| 246 | void ARM_Dynarmic_32::ClearExclusiveState() {} | 250 | void ARM_Dynarmic_32::ClearExclusiveState() { |
| 251 | jit->ClearExclusiveState(); | ||
| 252 | } | ||
| 247 | 253 | ||
| 248 | void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, | 254 | void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, |
| 249 | std::size_t new_address_space_size_in_bits) { | 255 | std::size_t new_address_space_size_in_bits) { |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 1d47a2779..5db19dcf3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -254,6 +254,11 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr | |||
| 254 | return page_table.Map(dst_addr, src_addr, size); | 254 | return page_table.Map(dst_addr, src_addr, size); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { | ||
| 258 | return MapMemory(system, static_cast<VAddr>(dst_addr), static_cast<VAddr>(src_addr), | ||
| 259 | static_cast<std::size_t>(size)); | ||
| 260 | } | ||
| 261 | |||
| 257 | /// Unmaps a region that was previously mapped with svcMapMemory | 262 | /// Unmaps a region that was previously mapped with svcMapMemory |
| 258 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 263 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 259 | std::lock_guard lock{HLE::g_hle_lock}; | 264 | std::lock_guard lock{HLE::g_hle_lock}; |
| @@ -270,6 +275,11 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | |||
| 270 | return page_table.Unmap(dst_addr, src_addr, size); | 275 | return page_table.Unmap(dst_addr, src_addr, size); |
| 271 | } | 276 | } |
| 272 | 277 | ||
| 278 | static ResultCode UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { | ||
| 279 | return UnmapMemory(system, static_cast<VAddr>(dst_addr), static_cast<VAddr>(src_addr), | ||
| 280 | static_cast<std::size_t>(size)); | ||
| 281 | } | ||
| 282 | |||
| 273 | /// Connect to an OS service given the port name, returns the handle to the port to out | 283 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 274 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | 284 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, |
| 275 | VAddr port_name_address) { | 285 | VAddr port_name_address) { |
| @@ -417,6 +427,15 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han | |||
| 417 | return ERR_INVALID_HANDLE; | 427 | return ERR_INVALID_HANDLE; |
| 418 | } | 428 | } |
| 419 | 429 | ||
| 430 | static ResultCode GetProcessId32(Core::System& system, u32* process_id_low, u32* process_id_high, | ||
| 431 | Handle handle) { | ||
| 432 | u64 process_id{}; | ||
| 433 | const auto result = GetProcessId(system, &process_id, handle); | ||
| 434 | *process_id_low = static_cast<u32>(process_id); | ||
| 435 | *process_id_high = static_cast<u32>(process_id >> 32); | ||
| 436 | return result; | ||
| 437 | } | ||
| 438 | |||
| 420 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 439 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 421 | static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address, | 440 | static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address, |
| 422 | u64 handle_count, s64 nano_seconds) { | 441 | u64 handle_count, s64 nano_seconds) { |
| @@ -484,6 +503,10 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand | |||
| 484 | return RESULT_SUCCESS; | 503 | return RESULT_SUCCESS; |
| 485 | } | 504 | } |
| 486 | 505 | ||
| 506 | static ResultCode CancelSynchronization32(Core::System& system, Handle thread_handle) { | ||
| 507 | return CancelSynchronization(system, thread_handle); | ||
| 508 | } | ||
| 509 | |||
| 487 | /// Attempts to locks a mutex, creating it if it does not already exist | 510 | /// Attempts to locks a mutex, creating it if it does not already exist |
| 488 | static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_handle, | 511 | static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_handle, |
| 489 | VAddr mutex_addr, Handle requesting_thread_handle) { | 512 | VAddr mutex_addr, Handle requesting_thread_handle) { |
| @@ -508,6 +531,12 @@ static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_hand | |||
| 508 | requesting_thread_handle); | 531 | requesting_thread_handle); |
| 509 | } | 532 | } |
| 510 | 533 | ||
| 534 | static ResultCode ArbitrateLock32(Core::System& system, Handle holding_thread_handle, | ||
| 535 | u32 mutex_addr, Handle requesting_thread_handle) { | ||
| 536 | return ArbitrateLock(system, holding_thread_handle, static_cast<VAddr>(mutex_addr), | ||
| 537 | requesting_thread_handle); | ||
| 538 | } | ||
| 539 | |||
| 511 | /// Unlock a mutex | 540 | /// Unlock a mutex |
| 512 | static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) { | 541 | static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) { |
| 513 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); | 542 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); |
| @@ -527,6 +556,10 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) { | |||
| 527 | return current_process->GetMutex().Release(mutex_addr); | 556 | return current_process->GetMutex().Release(mutex_addr); |
| 528 | } | 557 | } |
| 529 | 558 | ||
| 559 | static ResultCode ArbitrateUnlock32(Core::System& system, u32 mutex_addr) { | ||
| 560 | return ArbitrateUnlock(system, static_cast<VAddr>(mutex_addr)); | ||
| 561 | } | ||
| 562 | |||
| 530 | enum class BreakType : u32 { | 563 | enum class BreakType : u32 { |
| 531 | Panic = 0, | 564 | Panic = 0, |
| 532 | AssertionFailed = 1, | 565 | AssertionFailed = 1, |
| @@ -645,6 +678,10 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 645 | } | 678 | } |
| 646 | } | 679 | } |
| 647 | 680 | ||
| 681 | static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { | ||
| 682 | Break(system, reason, static_cast<u64>(info1), static_cast<u64>(info2)); | ||
| 683 | } | ||
| 684 | |||
| 648 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit | 685 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit |
| 649 | static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr address, u64 len) { | 686 | static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr address, u64 len) { |
| 650 | if (len == 0) { | 687 | if (len == 0) { |
| @@ -973,6 +1010,10 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) | |||
| 973 | return page_table.MapPhysicalMemory(addr, size); | 1010 | return page_table.MapPhysicalMemory(addr, size); |
| 974 | } | 1011 | } |
| 975 | 1012 | ||
| 1013 | static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { | ||
| 1014 | return MapPhysicalMemory(system, static_cast<VAddr>(addr), static_cast<std::size_t>(size)); | ||
| 1015 | } | ||
| 1016 | |||
| 976 | /// Unmaps memory previously mapped via MapPhysicalMemory | 1017 | /// Unmaps memory previously mapped via MapPhysicalMemory |
| 977 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 1018 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 978 | std::lock_guard lock{HLE::g_hle_lock}; | 1019 | std::lock_guard lock{HLE::g_hle_lock}; |
| @@ -1023,6 +1064,10 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size | |||
| 1023 | return page_table.UnmapPhysicalMemory(addr, size); | 1064 | return page_table.UnmapPhysicalMemory(addr, size); |
| 1024 | } | 1065 | } |
| 1025 | 1066 | ||
| 1067 | static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { | ||
| 1068 | return UnmapPhysicalMemory(system, static_cast<VAddr>(addr), static_cast<std::size_t>(size)); | ||
| 1069 | } | ||
| 1070 | |||
| 1026 | /// Sets the thread activity | 1071 | /// Sets the thread activity |
| 1027 | static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) { | 1072 | static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) { |
| 1028 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); | 1073 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); |
| @@ -1055,6 +1100,10 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act | |||
| 1055 | return thread->SetActivity(static_cast<ThreadActivity>(activity)); | 1100 | return thread->SetActivity(static_cast<ThreadActivity>(activity)); |
| 1056 | } | 1101 | } |
| 1057 | 1102 | ||
| 1103 | static ResultCode SetThreadActivity32(Core::System& system, Handle handle, u32 activity) { | ||
| 1104 | return SetThreadActivity(system, handle, activity); | ||
| 1105 | } | ||
| 1106 | |||
| 1058 | /// Gets the thread context | 1107 | /// Gets the thread context |
| 1059 | static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, Handle handle) { | 1108 | static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, Handle handle) { |
| 1060 | LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); | 1109 | LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); |
| @@ -1096,6 +1145,10 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | |||
| 1096 | return RESULT_SUCCESS; | 1145 | return RESULT_SUCCESS; |
| 1097 | } | 1146 | } |
| 1098 | 1147 | ||
| 1148 | static ResultCode GetThreadContext32(Core::System& system, u32 thread_context, Handle handle) { | ||
| 1149 | return GetThreadContext(system, static_cast<VAddr>(thread_context), handle); | ||
| 1150 | } | ||
| 1151 | |||
| 1099 | /// Gets the priority for the specified thread | 1152 | /// Gets the priority for the specified thread |
| 1100 | static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle handle) { | 1153 | static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle handle) { |
| 1101 | LOG_TRACE(Kernel_SVC, "called"); | 1154 | LOG_TRACE(Kernel_SVC, "called"); |
| @@ -1228,6 +1281,12 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1228 | return shared_memory->Map(*current_process, addr, size, permission_type); | 1281 | return shared_memory->Map(*current_process, addr, size, permission_type); |
| 1229 | } | 1282 | } |
| 1230 | 1283 | ||
| 1284 | static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, | ||
| 1285 | u32 size, u32 permissions) { | ||
| 1286 | return MapSharedMemory(system, shared_memory_handle, static_cast<VAddr>(addr), | ||
| 1287 | static_cast<std::size_t>(size), permissions); | ||
| 1288 | } | ||
| 1289 | |||
| 1231 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1290 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1232 | VAddr page_info_address, Handle process_handle, | 1291 | VAddr page_info_address, Handle process_handle, |
| 1233 | VAddr address) { | 1292 | VAddr address) { |
| @@ -1426,6 +1485,10 @@ static void ExitProcess(Core::System& system) { | |||
| 1426 | system.CurrentScheduler().GetCurrentThread()->Stop(); | 1485 | system.CurrentScheduler().GetCurrentThread()->Stop(); |
| 1427 | } | 1486 | } |
| 1428 | 1487 | ||
| 1488 | static void ExitProcess32(Core::System& system) { | ||
| 1489 | ExitProcess(system); | ||
| 1490 | } | ||
| 1491 | |||
| 1429 | /// Creates a new thread | 1492 | /// Creates a new thread |
| 1430 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, | 1493 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, |
| 1431 | VAddr stack_top, u32 priority, s32 processor_id) { | 1494 | VAddr stack_top, u32 priority, s32 processor_id) { |
| @@ -1489,6 +1552,12 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1489 | return RESULT_SUCCESS; | 1552 | return RESULT_SUCCESS; |
| 1490 | } | 1553 | } |
| 1491 | 1554 | ||
| 1555 | static ResultCode CreateThread32(Core::System& system, Handle* out_handle, u32 priority, | ||
| 1556 | u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { | ||
| 1557 | return CreateThread(system, out_handle, static_cast<VAddr>(entry_point), static_cast<u64>(arg), | ||
| 1558 | static_cast<VAddr>(stack_top), priority, processor_id); | ||
| 1559 | } | ||
| 1560 | |||
| 1492 | /// Starts the thread for the provided handle | 1561 | /// Starts the thread for the provided handle |
| 1493 | static ResultCode StartThread(Core::System& system, Handle thread_handle) { | 1562 | static ResultCode StartThread(Core::System& system, Handle thread_handle) { |
| 1494 | LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | 1563 | LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); |
| @@ -1506,6 +1575,10 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | |||
| 1506 | return thread->Start(); | 1575 | return thread->Start(); |
| 1507 | } | 1576 | } |
| 1508 | 1577 | ||
| 1578 | static ResultCode StartThread32(Core::System& system, Handle thread_handle) { | ||
| 1579 | return StartThread(system, thread_handle); | ||
| 1580 | } | ||
| 1581 | |||
| 1509 | /// Called when a thread exits | 1582 | /// Called when a thread exits |
| 1510 | static void ExitThread(Core::System& system) { | 1583 | static void ExitThread(Core::System& system) { |
| 1511 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | 1584 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); |
| @@ -1515,6 +1588,10 @@ static void ExitThread(Core::System& system) { | |||
| 1515 | current_thread->Stop(); | 1588 | current_thread->Stop(); |
| 1516 | } | 1589 | } |
| 1517 | 1590 | ||
| 1591 | static void ExitThread32(Core::System& system) { | ||
| 1592 | ExitThread(system); | ||
| 1593 | } | ||
| 1594 | |||
| 1518 | /// Sleep the current thread | 1595 | /// Sleep the current thread |
| 1519 | static void SleepThread(Core::System& system, s64 nanoseconds) { | 1596 | static void SleepThread(Core::System& system, s64 nanoseconds) { |
| 1520 | LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); | 1597 | LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); |
| @@ -1561,6 +1638,12 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
| 1561 | } | 1638 | } |
| 1562 | } | 1639 | } |
| 1563 | 1640 | ||
| 1641 | static void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high) { | ||
| 1642 | const s64 nanoseconds = static_cast<s64>(static_cast<u64>(nanoseconds_low) | | ||
| 1643 | (static_cast<u64>(nanoseconds_high) << 32)); | ||
| 1644 | SleepThread(system, nanoseconds); | ||
| 1645 | } | ||
| 1646 | |||
| 1564 | /// Wait process wide key atomic | 1647 | /// Wait process wide key atomic |
| 1565 | static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_addr, | 1648 | static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_addr, |
| 1566 | VAddr condition_variable_addr, Handle thread_handle, | 1649 | VAddr condition_variable_addr, Handle thread_handle, |
| @@ -1640,6 +1723,16 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | |||
| 1640 | return current_thread->GetSignalingResult(); | 1723 | return current_thread->GetSignalingResult(); |
| 1641 | } | 1724 | } |
| 1642 | 1725 | ||
| 1726 | static ResultCode WaitProcessWideKeyAtomic32(Core::System& system, u32 mutex_addr, | ||
| 1727 | u32 condition_variable_addr, Handle thread_handle, | ||
| 1728 | u32 nanoseconds_low, u32 nanoseconds_high) { | ||
| 1729 | const s64 nanoseconds = | ||
| 1730 | static_cast<s64>(nanoseconds_low | (static_cast<u64>(nanoseconds_high) << 32)); | ||
| 1731 | return WaitProcessWideKeyAtomic(system, static_cast<VAddr>(mutex_addr), | ||
| 1732 | static_cast<VAddr>(condition_variable_addr), thread_handle, | ||
| 1733 | nanoseconds); | ||
| 1734 | } | ||
| 1735 | |||
| 1643 | /// Signal process wide key | 1736 | /// Signal process wide key |
| 1644 | static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_addr, s32 target) { | 1737 | static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_addr, s32 target) { |
| 1645 | LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", | 1738 | LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", |
| @@ -1741,6 +1834,12 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type, | |||
| 1741 | return result; | 1834 | return result; |
| 1742 | } | 1835 | } |
| 1743 | 1836 | ||
| 1837 | static ResultCode WaitForAddress32(Core::System& system, u32 address, u32 type, s32 value, | ||
| 1838 | u32 timeout_low, u32 timeout_high) { | ||
| 1839 | s64 timeout = static_cast<s64>(timeout_low | (static_cast<u64>(timeout_high) << 32)); | ||
| 1840 | return WaitForAddress(system, static_cast<VAddr>(address), type, value, timeout); | ||
| 1841 | } | ||
| 1842 | |||
| 1744 | // Signals to an address (via Address Arbiter) | 1843 | // Signals to an address (via Address Arbiter) |
| 1745 | static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, s32 value, | 1844 | static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, s32 value, |
| 1746 | s32 num_to_wake) { | 1845 | s32 num_to_wake) { |
| @@ -1764,6 +1863,11 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, | |||
| 1764 | return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake); | 1863 | return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake); |
| 1765 | } | 1864 | } |
| 1766 | 1865 | ||
| 1866 | static ResultCode SignalToAddress32(Core::System& system, u32 address, u32 type, s32 value, | ||
| 1867 | s32 num_to_wake) { | ||
| 1868 | return SignalToAddress(system, static_cast<VAddr>(address), type, value, num_to_wake); | ||
| 1869 | } | ||
| 1870 | |||
| 1767 | static void KernelDebug([[maybe_unused]] Core::System& system, | 1871 | static void KernelDebug([[maybe_unused]] Core::System& system, |
| 1768 | [[maybe_unused]] u32 kernel_debug_type, [[maybe_unused]] u64 param1, | 1872 | [[maybe_unused]] u32 kernel_debug_type, [[maybe_unused]] u64 param1, |
| 1769 | [[maybe_unused]] u64 param2, [[maybe_unused]] u64 param3) { | 1873 | [[maybe_unused]] u64 param2, [[maybe_unused]] u64 param3) { |
| @@ -1791,6 +1895,12 @@ static u64 GetSystemTick(Core::System& system) { | |||
| 1791 | return result; | 1895 | return result; |
| 1792 | } | 1896 | } |
| 1793 | 1897 | ||
| 1898 | static void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) { | ||
| 1899 | u64 time = GetSystemTick(system); | ||
| 1900 | *time_low = static_cast<u32>(time); | ||
| 1901 | *time_high = static_cast<u32>(time >> 32); | ||
| 1902 | } | ||
| 1903 | |||
| 1794 | /// Close a handle | 1904 | /// Close a handle |
| 1795 | static ResultCode CloseHandle(Core::System& system, Handle handle) { | 1905 | static ResultCode CloseHandle(Core::System& system, Handle handle) { |
| 1796 | LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); | 1906 | LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); |
| @@ -1823,6 +1933,10 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { | |||
| 1823 | return ERR_INVALID_HANDLE; | 1933 | return ERR_INVALID_HANDLE; |
| 1824 | } | 1934 | } |
| 1825 | 1935 | ||
| 1936 | static ResultCode ResetSignal32(Core::System& system, Handle handle) { | ||
| 1937 | return ResetSignal(system, handle); | ||
| 1938 | } | ||
| 1939 | |||
| 1826 | /// Creates a TransferMemory object | 1940 | /// Creates a TransferMemory object |
| 1827 | static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, | 1941 | static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, |
| 1828 | u32 permissions) { | 1942 | u32 permissions) { |
| @@ -1897,6 +2011,15 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, | |||
| 1897 | return RESULT_SUCCESS; | 2011 | return RESULT_SUCCESS; |
| 1898 | } | 2012 | } |
| 1899 | 2013 | ||
| 2014 | static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle, u32* core, | ||
| 2015 | u32* mask_low, u32* mask_high) { | ||
| 2016 | u64 mask{}; | ||
| 2017 | const auto result = GetThreadCoreMask(system, thread_handle, core, &mask); | ||
| 2018 | *mask_high = static_cast<u32>(mask >> 32); | ||
| 2019 | *mask_low = static_cast<u32>(mask); | ||
| 2020 | return result; | ||
| 2021 | } | ||
| 2022 | |||
| 1900 | static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core, | 2023 | static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core, |
| 1901 | u64 affinity_mask) { | 2024 | u64 affinity_mask) { |
| 1902 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, core=0x{:X}, affinity_mask=0x{:016X}", | 2025 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, core=0x{:X}, affinity_mask=0x{:016X}", |
| @@ -1988,6 +2111,10 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle | |||
| 1988 | return RESULT_SUCCESS; | 2111 | return RESULT_SUCCESS; |
| 1989 | } | 2112 | } |
| 1990 | 2113 | ||
| 2114 | static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) { | ||
| 2115 | return CreateEvent(system, write_handle, read_handle); | ||
| 2116 | } | ||
| 2117 | |||
| 1991 | static ResultCode ClearEvent(Core::System& system, Handle handle) { | 2118 | static ResultCode ClearEvent(Core::System& system, Handle handle) { |
| 1992 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); | 2119 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); |
| 1993 | 2120 | ||
| @@ -2009,6 +2136,10 @@ static ResultCode ClearEvent(Core::System& system, Handle handle) { | |||
| 2009 | return ERR_INVALID_HANDLE; | 2136 | return ERR_INVALID_HANDLE; |
| 2010 | } | 2137 | } |
| 2011 | 2138 | ||
| 2139 | static ResultCode ClearEvent32(Core::System& system, Handle handle) { | ||
| 2140 | return ClearEvent(system, handle); | ||
| 2141 | } | ||
| 2142 | |||
| 2012 | static ResultCode SignalEvent(Core::System& system, Handle handle) { | 2143 | static ResultCode SignalEvent(Core::System& system, Handle handle) { |
| 2013 | LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); | 2144 | LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); |
| 2014 | 2145 | ||
| @@ -2024,6 +2155,10 @@ static ResultCode SignalEvent(Core::System& system, Handle handle) { | |||
| 2024 | return RESULT_SUCCESS; | 2155 | return RESULT_SUCCESS; |
| 2025 | } | 2156 | } |
| 2026 | 2157 | ||
| 2158 | static ResultCode SignalEvent32(Core::System& system, Handle handle) { | ||
| 2159 | return SignalEvent(system, handle); | ||
| 2160 | } | ||
| 2161 | |||
| 2027 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { | 2162 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { |
| 2028 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); | 2163 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); |
| 2029 | 2164 | ||
| @@ -2209,6 +2344,15 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2209 | return RESULT_SUCCESS; | 2344 | return RESULT_SUCCESS; |
| 2210 | } | 2345 | } |
| 2211 | 2346 | ||
| 2347 | static ResultCode FlushProcessDataCache32(Core::System& system, Handle handle, u32 address, | ||
| 2348 | u32 size) { | ||
| 2349 | // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a nope | ||
| 2350 | // as all emulation is done in the same cache level in host architecture, thus data cache | ||
| 2351 | // does not need flushing. | ||
| 2352 | LOG_DEBUG(Kernel_SVC, "called"); | ||
| 2353 | return RESULT_SUCCESS; | ||
| 2354 | } | ||
| 2355 | |||
| 2212 | namespace { | 2356 | namespace { |
| 2213 | struct FunctionDef { | 2357 | struct FunctionDef { |
| 2214 | using Func = void(Core::System&); | 2358 | using Func = void(Core::System&); |
| @@ -2224,56 +2368,56 @@ static const FunctionDef SVC_Table_32[] = { | |||
| 2224 | {0x01, SvcWrap32<SetHeapSize32>, "SetHeapSize32"}, | 2368 | {0x01, SvcWrap32<SetHeapSize32>, "SetHeapSize32"}, |
| 2225 | {0x02, nullptr, "Unknown"}, | 2369 | {0x02, nullptr, "Unknown"}, |
| 2226 | {0x03, SvcWrap32<SetMemoryAttribute32>, "SetMemoryAttribute32"}, | 2370 | {0x03, SvcWrap32<SetMemoryAttribute32>, "SetMemoryAttribute32"}, |
| 2227 | {0x04, nullptr, "MapMemory32"}, | 2371 | {0x04, SvcWrap32<MapMemory32>, "MapMemory32"}, |
| 2228 | {0x05, nullptr, "UnmapMemory32"}, | 2372 | {0x05, SvcWrap32<UnmapMemory32>, "UnmapMemory32"}, |
| 2229 | {0x06, SvcWrap32<QueryMemory32>, "QueryMemory32"}, | 2373 | {0x06, SvcWrap32<QueryMemory32>, "QueryMemory32"}, |
| 2230 | {0x07, nullptr, "ExitProcess32"}, | 2374 | {0x07, SvcWrap32<ExitProcess32>, "ExitProcess32"}, |
| 2231 | {0x08, nullptr, "CreateThread32"}, | 2375 | {0x08, SvcWrap32<CreateThread32>, "CreateThread32"}, |
| 2232 | {0x09, nullptr, "StartThread32"}, | 2376 | {0x09, SvcWrap32<StartThread32>, "StartThread32"}, |
| 2233 | {0x0a, nullptr, "ExitThread32"}, | 2377 | {0x0a, SvcWrap32<ExitThread32>, "ExitThread32"}, |
| 2234 | {0x0b, nullptr, "SleepThread32"}, | 2378 | {0x0b, SvcWrap32<SleepThread32>, "SleepThread32"}, |
| 2235 | {0x0c, SvcWrap32<GetThreadPriority32>, "GetThreadPriority32"}, | 2379 | {0x0c, SvcWrap32<GetThreadPriority32>, "GetThreadPriority32"}, |
| 2236 | {0x0d, SvcWrap32<SetThreadPriority32>, "SetThreadPriority32"}, | 2380 | {0x0d, SvcWrap32<SetThreadPriority32>, "SetThreadPriority32"}, |
| 2237 | {0x0e, nullptr, "GetThreadCoreMask32"}, | 2381 | {0x0e, SvcWrap32<GetThreadCoreMask32>, "GetThreadCoreMask32"}, |
| 2238 | {0x0f, SvcWrap32<SetThreadCoreMask32>, "SetThreadCoreMask32"}, | 2382 | {0x0f, SvcWrap32<SetThreadCoreMask32>, "SetThreadCoreMask32"}, |
| 2239 | {0x10, SvcWrap32<GetCurrentProcessorNumber32>, "GetCurrentProcessorNumber32"}, | 2383 | {0x10, SvcWrap32<GetCurrentProcessorNumber32>, "GetCurrentProcessorNumber32"}, |
| 2240 | {0x11, nullptr, "SignalEvent32"}, | 2384 | {0x11, SvcWrap32<SignalEvent32>, "SignalEvent32"}, |
| 2241 | {0x12, nullptr, "ClearEvent32"}, | 2385 | {0x12, SvcWrap32<ClearEvent32>, "ClearEvent32"}, |
| 2242 | {0x13, nullptr, "MapSharedMemory32"}, | 2386 | {0x13, SvcWrap32<MapSharedMemory32>, "MapSharedMemory32"}, |
| 2243 | {0x14, nullptr, "UnmapSharedMemory32"}, | 2387 | {0x14, nullptr, "UnmapSharedMemory32"}, |
| 2244 | {0x15, SvcWrap32<CreateTransferMemory32>, "CreateTransferMemory32"}, | 2388 | {0x15, SvcWrap32<CreateTransferMemory32>, "CreateTransferMemory32"}, |
| 2245 | {0x16, SvcWrap32<CloseHandle32>, "CloseHandle32"}, | 2389 | {0x16, SvcWrap32<CloseHandle32>, "CloseHandle32"}, |
| 2246 | {0x17, nullptr, "ResetSignal32"}, | 2390 | {0x17, SvcWrap32<ResetSignal32>, "ResetSignal32"}, |
| 2247 | {0x18, SvcWrap32<WaitSynchronization32>, "WaitSynchronization32"}, | 2391 | {0x18, SvcWrap32<WaitSynchronization32>, "WaitSynchronization32"}, |
| 2248 | {0x19, nullptr, "CancelSynchronization32"}, | 2392 | {0x19, SvcWrap32<CancelSynchronization32>, "CancelSynchronization32"}, |
| 2249 | {0x1a, nullptr, "ArbitrateLock32"}, | 2393 | {0x1a, SvcWrap32<ArbitrateLock32>, "ArbitrateLock32"}, |
| 2250 | {0x1b, nullptr, "ArbitrateUnlock32"}, | 2394 | {0x1b, SvcWrap32<ArbitrateUnlock32>, "ArbitrateUnlock32"}, |
| 2251 | {0x1c, nullptr, "WaitProcessWideKeyAtomic32"}, | 2395 | {0x1c, SvcWrap32<WaitProcessWideKeyAtomic32>, "WaitProcessWideKeyAtomic32"}, |
| 2252 | {0x1d, SvcWrap32<SignalProcessWideKey32>, "SignalProcessWideKey32"}, | 2396 | {0x1d, SvcWrap32<SignalProcessWideKey32>, "SignalProcessWideKey32"}, |
| 2253 | {0x1e, nullptr, "GetSystemTick32"}, | 2397 | {0x1e, SvcWrap32<GetSystemTick32>, "GetSystemTick32"}, |
| 2254 | {0x1f, SvcWrap32<ConnectToNamedPort32>, "ConnectToNamedPort32"}, | 2398 | {0x1f, SvcWrap32<ConnectToNamedPort32>, "ConnectToNamedPort32"}, |
| 2255 | {0x20, nullptr, "Unknown"}, | 2399 | {0x20, nullptr, "Unknown"}, |
| 2256 | {0x21, SvcWrap32<SendSyncRequest32>, "SendSyncRequest32"}, | 2400 | {0x21, SvcWrap32<SendSyncRequest32>, "SendSyncRequest32"}, |
| 2257 | {0x22, nullptr, "SendSyncRequestWithUserBuffer32"}, | 2401 | {0x22, nullptr, "SendSyncRequestWithUserBuffer32"}, |
| 2258 | {0x23, nullptr, "Unknown"}, | 2402 | {0x23, nullptr, "Unknown"}, |
| 2259 | {0x24, nullptr, "GetProcessId32"}, | 2403 | {0x24, SvcWrap32<GetProcessId32>, "GetProcessId32"}, |
| 2260 | {0x25, SvcWrap32<GetThreadId32>, "GetThreadId32"}, | 2404 | {0x25, SvcWrap32<GetThreadId32>, "GetThreadId32"}, |
| 2261 | {0x26, nullptr, "Break32"}, | 2405 | {0x26, SvcWrap32<Break32>, "Break32"}, |
| 2262 | {0x27, nullptr, "OutputDebugString32"}, | 2406 | {0x27, nullptr, "OutputDebugString32"}, |
| 2263 | {0x28, nullptr, "Unknown"}, | 2407 | {0x28, nullptr, "Unknown"}, |
| 2264 | {0x29, SvcWrap32<GetInfo32>, "GetInfo32"}, | 2408 | {0x29, SvcWrap32<GetInfo32>, "GetInfo32"}, |
| 2265 | {0x2a, nullptr, "Unknown"}, | 2409 | {0x2a, nullptr, "Unknown"}, |
| 2266 | {0x2b, nullptr, "Unknown"}, | 2410 | {0x2b, nullptr, "Unknown"}, |
| 2267 | {0x2c, nullptr, "MapPhysicalMemory32"}, | 2411 | {0x2c, SvcWrap32<MapPhysicalMemory32>, "MapPhysicalMemory32"}, |
| 2268 | {0x2d, nullptr, "UnmapPhysicalMemory32"}, | 2412 | {0x2d, SvcWrap32<UnmapPhysicalMemory32>, "UnmapPhysicalMemory32"}, |
| 2269 | {0x2e, nullptr, "Unknown"}, | 2413 | {0x2e, nullptr, "Unknown"}, |
| 2270 | {0x2f, nullptr, "Unknown"}, | 2414 | {0x2f, nullptr, "Unknown"}, |
| 2271 | {0x30, nullptr, "Unknown"}, | 2415 | {0x30, nullptr, "Unknown"}, |
| 2272 | {0x31, nullptr, "Unknown"}, | 2416 | {0x31, nullptr, "Unknown"}, |
| 2273 | {0x32, nullptr, "SetThreadActivity32"}, | 2417 | {0x32, SvcWrap32<SetThreadActivity32>, "SetThreadActivity32"}, |
| 2274 | {0x33, nullptr, "GetThreadContext32"}, | 2418 | {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"}, |
| 2275 | {0x34, nullptr, "WaitForAddress32"}, | 2419 | {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"}, |
| 2276 | {0x35, nullptr, "SignalToAddress32"}, | 2420 | {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"}, |
| 2277 | {0x36, nullptr, "Unknown"}, | 2421 | {0x36, nullptr, "Unknown"}, |
| 2278 | {0x37, nullptr, "Unknown"}, | 2422 | {0x37, nullptr, "Unknown"}, |
| 2279 | {0x38, nullptr, "Unknown"}, | 2423 | {0x38, nullptr, "Unknown"}, |
| @@ -2289,7 +2433,7 @@ static const FunctionDef SVC_Table_32[] = { | |||
| 2289 | {0x42, nullptr, "Unknown"}, | 2433 | {0x42, nullptr, "Unknown"}, |
| 2290 | {0x43, nullptr, "ReplyAndReceive32"}, | 2434 | {0x43, nullptr, "ReplyAndReceive32"}, |
| 2291 | {0x44, nullptr, "Unknown"}, | 2435 | {0x44, nullptr, "Unknown"}, |
| 2292 | {0x45, nullptr, "CreateEvent32"}, | 2436 | {0x45, SvcWrap32<CreateEvent32>, "CreateEvent32"}, |
| 2293 | {0x46, nullptr, "Unknown"}, | 2437 | {0x46, nullptr, "Unknown"}, |
| 2294 | {0x47, nullptr, "Unknown"}, | 2438 | {0x47, nullptr, "Unknown"}, |
| 2295 | {0x48, nullptr, "Unknown"}, | 2439 | {0x48, nullptr, "Unknown"}, |
| @@ -2315,7 +2459,7 @@ static const FunctionDef SVC_Table_32[] = { | |||
| 2315 | {0x5c, nullptr, "Unknown"}, | 2459 | {0x5c, nullptr, "Unknown"}, |
| 2316 | {0x5d, nullptr, "Unknown"}, | 2460 | {0x5d, nullptr, "Unknown"}, |
| 2317 | {0x5e, nullptr, "Unknown"}, | 2461 | {0x5e, nullptr, "Unknown"}, |
| 2318 | {0x5F, nullptr, "FlushProcessDataCache32"}, | 2462 | {0x5F, SvcWrap32<FlushProcessDataCache32>, "FlushProcessDataCache32"}, |
| 2319 | {0x60, nullptr, "Unknown"}, | 2463 | {0x60, nullptr, "Unknown"}, |
| 2320 | {0x61, nullptr, "Unknown"}, | 2464 | {0x61, nullptr, "Unknown"}, |
| 2321 | {0x62, nullptr, "Unknown"}, | 2465 | {0x62, nullptr, "Unknown"}, |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index ba90c354f..0b6dd9df0 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -350,17 +350,48 @@ void SvcWrap64(Core::System& system) { | |||
| 350 | func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)); | 350 | func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | // Used by QueryMemory32 | 353 | // Used by QueryMemory32, ArbitrateLock32 |
| 354 | template <ResultCode func(Core::System&, u32, u32, u32)> | 354 | template <ResultCode func(Core::System&, u32, u32, u32)> |
| 355 | void SvcWrap32(Core::System& system) { | 355 | void SvcWrap32(Core::System& system) { |
| 356 | FuncReturn32(system, | 356 | FuncReturn32(system, |
| 357 | func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw); | 357 | func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | // Used by Break32 | ||
| 361 | template <void func(Core::System&, u32, u32, u32)> | ||
| 362 | void SvcWrap32(Core::System& system) { | ||
| 363 | func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)); | ||
| 364 | } | ||
| 365 | |||
| 366 | // Used by ExitProcess32, ExitThread32 | ||
| 367 | template <void func(Core::System&)> | ||
| 368 | void SvcWrap32(Core::System& system) { | ||
| 369 | func(system); | ||
| 370 | } | ||
| 371 | |||
| 360 | // Used by GetCurrentProcessorNumber32 | 372 | // Used by GetCurrentProcessorNumber32 |
| 361 | template <u32 func(Core::System&)> | 373 | template <u32 func(Core::System&)> |
| 362 | void SvcWrap32(Core::System& system) { | 374 | void SvcWrap32(Core::System& system) { |
| 363 | FuncReturn(system, func(system)); | 375 | FuncReturn32(system, func(system)); |
| 376 | } | ||
| 377 | |||
| 378 | // Used by SleepThread32 | ||
| 379 | template <void func(Core::System&, u32, u32)> | ||
| 380 | void SvcWrap32(Core::System& system) { | ||
| 381 | func(system, Param32(system, 0), Param32(system, 1)); | ||
| 382 | } | ||
| 383 | |||
| 384 | // Used by CreateThread32 | ||
| 385 | template <ResultCode func(Core::System&, Handle*, u32, u32, u32, u32, s32)> | ||
| 386 | void SvcWrap32(Core::System& system) { | ||
| 387 | Handle param_1 = 0; | ||
| 388 | |||
| 389 | const u32 retval = func(system, ¶m_1, Param32(system, 0), Param32(system, 1), | ||
| 390 | Param32(system, 2), Param32(system, 3), Param32(system, 4)) | ||
| 391 | .raw; | ||
| 392 | |||
| 393 | system.CurrentArmInterface().SetReg(1, param_1); | ||
| 394 | FuncReturn(system, retval); | ||
| 364 | } | 395 | } |
| 365 | 396 | ||
| 366 | // Used by GetInfo32 | 397 | // Used by GetInfo32 |
| @@ -399,6 +430,43 @@ void SvcWrap32(Core::System& system) { | |||
| 399 | FuncReturn(system, retval); | 430 | FuncReturn(system, retval); |
| 400 | } | 431 | } |
| 401 | 432 | ||
| 433 | // Used by GetSystemTick32 | ||
| 434 | template <void func(Core::System&, u32*, u32*)> | ||
| 435 | void SvcWrap32(Core::System& system) { | ||
| 436 | u32 param_1 = 0; | ||
| 437 | u32 param_2 = 0; | ||
| 438 | |||
| 439 | func(system, ¶m_1, ¶m_2); | ||
| 440 | system.CurrentArmInterface().SetReg(0, param_1); | ||
| 441 | system.CurrentArmInterface().SetReg(1, param_2); | ||
| 442 | } | ||
| 443 | |||
| 444 | // Used by CreateEvent32 | ||
| 445 | template <ResultCode func(Core::System&, Handle*, Handle*)> | ||
| 446 | void SvcWrap32(Core::System& system) { | ||
| 447 | Handle param_1 = 0; | ||
| 448 | Handle param_2 = 0; | ||
| 449 | |||
| 450 | const u32 retval = func(system, ¶m_1, ¶m_2).raw; | ||
| 451 | system.CurrentArmInterface().SetReg(1, param_1); | ||
| 452 | system.CurrentArmInterface().SetReg(2, param_2); | ||
| 453 | FuncReturn(system, retval); | ||
| 454 | } | ||
| 455 | |||
| 456 | // Used by GetThreadId32 | ||
| 457 | template <ResultCode func(Core::System&, Handle, u32*, u32*, u32*)> | ||
| 458 | void SvcWrap32(Core::System& system) { | ||
| 459 | u32 param_1 = 0; | ||
| 460 | u32 param_2 = 0; | ||
| 461 | u32 param_3 = 0; | ||
| 462 | |||
| 463 | const u32 retval = func(system, Param32(system, 2), ¶m_1, ¶m_2, ¶m_3).raw; | ||
| 464 | system.CurrentArmInterface().SetReg(1, param_1); | ||
| 465 | system.CurrentArmInterface().SetReg(2, param_2); | ||
| 466 | system.CurrentArmInterface().SetReg(3, param_3); | ||
| 467 | FuncReturn(system, retval); | ||
| 468 | } | ||
| 469 | |||
| 402 | // Used by SignalProcessWideKey32 | 470 | // Used by SignalProcessWideKey32 |
| 403 | template <void func(Core::System&, u32, s32)> | 471 | template <void func(Core::System&, u32, s32)> |
| 404 | void SvcWrap32(Core::System& system) { | 472 | void SvcWrap32(Core::System& system) { |
| @@ -423,7 +491,38 @@ void SvcWrap32(Core::System& system) { | |||
| 423 | FuncReturn(system, retval); | 491 | FuncReturn(system, retval); |
| 424 | } | 492 | } |
| 425 | 493 | ||
| 426 | // Used by SendSyncRequest32 | 494 | // Used by WaitProcessWideKeyAtomic32 |
| 495 | template <ResultCode func(Core::System&, u32, u32, Handle, u32, u32)> | ||
| 496 | void SvcWrap32(Core::System& system) { | ||
| 497 | const u32 retval = | ||
| 498 | func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), | ||
| 499 | static_cast<Handle>(Param(system, 2)), static_cast<u32>(Param(system, 3)), | ||
| 500 | static_cast<u32>(Param(system, 4))) | ||
| 501 | .raw; | ||
| 502 | FuncReturn(system, retval); | ||
| 503 | } | ||
| 504 | |||
| 505 | // Used by WaitForAddress32 | ||
| 506 | template <ResultCode func(Core::System&, u32, u32, s32, u32, u32)> | ||
| 507 | void SvcWrap32(Core::System& system) { | ||
| 508 | const u32 retval = func(system, static_cast<u32>(Param(system, 0)), | ||
| 509 | static_cast<u32>(Param(system, 1)), static_cast<s32>(Param(system, 2)), | ||
| 510 | static_cast<u32>(Param(system, 3)), static_cast<u32>(Param(system, 4))) | ||
| 511 | .raw; | ||
| 512 | FuncReturn(system, retval); | ||
| 513 | } | ||
| 514 | |||
| 515 | // Used by SignalToAddress32 | ||
| 516 | template <ResultCode func(Core::System&, u32, u32, s32, s32)> | ||
| 517 | void SvcWrap32(Core::System& system) { | ||
| 518 | const u32 retval = | ||
| 519 | func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), | ||
| 520 | static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3))) | ||
| 521 | .raw; | ||
| 522 | FuncReturn(system, retval); | ||
| 523 | } | ||
| 524 | |||
| 525 | // Used by SendSyncRequest32, ArbitrateUnlock32 | ||
| 427 | template <ResultCode func(Core::System&, u32)> | 526 | template <ResultCode func(Core::System&, u32)> |
| 428 | void SvcWrap32(Core::System& system) { | 527 | void SvcWrap32(Core::System& system) { |
| 429 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); | 528 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); |