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:      struct ThreadContext32 {          std::array<u32, 16> cpu_registers{}; +        std::array<u32, 64> extension_registers{};          u32 cpsr{}; -        std::array<u8, 4> padding{}; -        std::array<u64, 32> fprs{};          u32 fpscr{};          u32 fpexc{};          u32 tpidr{};      };      // Internally within the kernel, it expects the AArch32 version of the      // thread context to be 344 bytes in size. -    static_assert(sizeof(ThreadContext32) == 0x158); +    static_assert(sizeof(ThreadContext32) == 0x150);      struct ThreadContext64 {          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) {      Dynarmic::A32::Context context;      jit->SaveContext(context);      ctx.cpu_registers = context.Regs(); +    ctx.extension_registers = context.ExtRegs();      ctx.cpsr = context.Cpsr(); +    ctx.fpscr = context.Fpscr();  }  void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) {      Dynarmic::A32::Context context;      context.Regs() = ctx.cpu_registers; +    context.ExtRegs() = ctx.extension_registers;      context.SetCpsr(ctx.cpsr); +    context.SetFpscr(ctx.fpscr);      jit->LoadContext(context);  } @@ -243,7 +247,9 @@ void ARM_Dynarmic_32::ClearInstructionCache() {      jit->ClearCache();  } -void ARM_Dynarmic_32::ClearExclusiveState() {} +void ARM_Dynarmic_32::ClearExclusiveState() { +    jit->ClearExclusiveState(); +}  void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table,                                         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      return page_table.Map(dst_addr, src_addr, size);  } +static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { +    return MapMemory(system, static_cast<VAddr>(dst_addr), static_cast<VAddr>(src_addr), +                     static_cast<std::size_t>(size)); +} +  /// Unmaps a region that was previously mapped with svcMapMemory  static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {      std::lock_guard lock{HLE::g_hle_lock}; @@ -270,6 +275,11 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad      return page_table.Unmap(dst_addr, src_addr, size);  } +static ResultCode UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { +    return UnmapMemory(system, static_cast<VAddr>(dst_addr), static_cast<VAddr>(src_addr), +                       static_cast<std::size_t>(size)); +} +  /// Connect to an OS service given the port name, returns the handle to the port to out  static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,                                       VAddr port_name_address) { @@ -417,6 +427,15 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han      return ERR_INVALID_HANDLE;  } +static ResultCode GetProcessId32(Core::System& system, u32* process_id_low, u32* process_id_high, +                                 Handle handle) { +    u64 process_id{}; +    const auto result = GetProcessId(system, &process_id, handle); +    *process_id_low = static_cast<u32>(process_id); +    *process_id_high = static_cast<u32>(process_id >> 32); +    return result; +} +  /// Wait for the given handles to synchronize, timeout after the specified nanoseconds  static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address,                                        u64 handle_count, s64 nano_seconds) { @@ -484,6 +503,10 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand      return RESULT_SUCCESS;  } +static ResultCode CancelSynchronization32(Core::System& system, Handle thread_handle) { +    return CancelSynchronization(system, thread_handle); +} +  /// Attempts to locks a mutex, creating it if it does not already exist  static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_handle,                                  VAddr mutex_addr, Handle requesting_thread_handle) { @@ -508,6 +531,12 @@ static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_hand                                                    requesting_thread_handle);  } +static ResultCode ArbitrateLock32(Core::System& system, Handle holding_thread_handle, +                                  u32 mutex_addr, Handle requesting_thread_handle) { +    return ArbitrateLock(system, holding_thread_handle, static_cast<VAddr>(mutex_addr), +                         requesting_thread_handle); +} +  /// Unlock a mutex  static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {      LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); @@ -527,6 +556,10 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {      return current_process->GetMutex().Release(mutex_addr);  } +static ResultCode ArbitrateUnlock32(Core::System& system, u32 mutex_addr) { +    return ArbitrateUnlock(system, static_cast<VAddr>(mutex_addr)); +} +  enum class BreakType : u32 {      Panic = 0,      AssertionFailed = 1, @@ -645,6 +678,10 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {      }  } +static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { +    Break(system, reason, static_cast<u64>(info1), static_cast<u64>(info2)); +} +  /// Used to output a message on a debug hardware unit - does nothing on a retail unit  static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr address, u64 len) {      if (len == 0) { @@ -973,6 +1010,10 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size)      return page_table.MapPhysicalMemory(addr, size);  } +static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { +    return MapPhysicalMemory(system, static_cast<VAddr>(addr), static_cast<std::size_t>(size)); +} +  /// Unmaps memory previously mapped via MapPhysicalMemory  static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {      std::lock_guard lock{HLE::g_hle_lock}; @@ -1023,6 +1064,10 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size      return page_table.UnmapPhysicalMemory(addr, size);  } +static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { +    return UnmapPhysicalMemory(system, static_cast<VAddr>(addr), static_cast<std::size_t>(size)); +} +  /// Sets the thread activity  static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) {      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      return thread->SetActivity(static_cast<ThreadActivity>(activity));  } +static ResultCode SetThreadActivity32(Core::System& system, Handle handle, u32 activity) { +    return SetThreadActivity(system, handle, activity); +} +  /// Gets the thread context  static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, Handle handle) {      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      return RESULT_SUCCESS;  } +static ResultCode GetThreadContext32(Core::System& system, u32 thread_context, Handle handle) { +    return GetThreadContext(system, static_cast<VAddr>(thread_context), handle); +} +  /// Gets the priority for the specified thread  static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle handle) {      LOG_TRACE(Kernel_SVC, "called"); @@ -1228,6 +1281,12 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han      return shared_memory->Map(*current_process, addr, size, permission_type);  } +static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, +                                    u32 size, u32 permissions) { +    return MapSharedMemory(system, shared_memory_handle, static_cast<VAddr>(addr), +                           static_cast<std::size_t>(size), permissions); +} +  static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,                                       VAddr page_info_address, Handle process_handle,                                       VAddr address) { @@ -1426,6 +1485,10 @@ static void ExitProcess(Core::System& system) {      system.CurrentScheduler().GetCurrentThread()->Stop();  } +static void ExitProcess32(Core::System& system) { +    ExitProcess(system); +} +  /// Creates a new thread  static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,                                 VAddr stack_top, u32 priority, s32 processor_id) { @@ -1489,6 +1552,12 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e      return RESULT_SUCCESS;  } +static ResultCode CreateThread32(Core::System& system, Handle* out_handle, u32 priority, +                                 u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { +    return CreateThread(system, out_handle, static_cast<VAddr>(entry_point), static_cast<u64>(arg), +                        static_cast<VAddr>(stack_top), priority, processor_id); +} +  /// Starts the thread for the provided handle  static ResultCode StartThread(Core::System& system, Handle thread_handle) {      LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); @@ -1506,6 +1575,10 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {      return thread->Start();  } +static ResultCode StartThread32(Core::System& system, Handle thread_handle) { +    return StartThread(system, thread_handle); +} +  /// Called when a thread exits  static void ExitThread(Core::System& system) {      LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); @@ -1515,6 +1588,10 @@ static void ExitThread(Core::System& system) {      current_thread->Stop();  } +static void ExitThread32(Core::System& system) { +    ExitThread(system); +} +  /// Sleep the current thread  static void SleepThread(Core::System& system, s64 nanoseconds) {      LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); @@ -1561,6 +1638,12 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {      }  } +static void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high) { +    const s64 nanoseconds = static_cast<s64>(static_cast<u64>(nanoseconds_low) | +                                             (static_cast<u64>(nanoseconds_high) << 32)); +    SleepThread(system, nanoseconds); +} +  /// Wait process wide key atomic  static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_addr,                                             VAddr condition_variable_addr, Handle thread_handle, @@ -1640,6 +1723,16 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add      return current_thread->GetSignalingResult();  } +static ResultCode WaitProcessWideKeyAtomic32(Core::System& system, u32 mutex_addr, +                                             u32 condition_variable_addr, Handle thread_handle, +                                             u32 nanoseconds_low, u32 nanoseconds_high) { +    const s64 nanoseconds = +        static_cast<s64>(nanoseconds_low | (static_cast<u64>(nanoseconds_high) << 32)); +    return WaitProcessWideKeyAtomic(system, static_cast<VAddr>(mutex_addr), +                                    static_cast<VAddr>(condition_variable_addr), thread_handle, +                                    nanoseconds); +} +  /// Signal process wide key  static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_addr, s32 target) {      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,      return result;  } +static ResultCode WaitForAddress32(Core::System& system, u32 address, u32 type, s32 value, +                                   u32 timeout_low, u32 timeout_high) { +    s64 timeout = static_cast<s64>(timeout_low | (static_cast<u64>(timeout_high) << 32)); +    return WaitForAddress(system, static_cast<VAddr>(address), type, value, timeout); +} +  // Signals to an address (via Address Arbiter)  static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, s32 value,                                    s32 num_to_wake) { @@ -1764,6 +1863,11 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type,      return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);  } +static ResultCode SignalToAddress32(Core::System& system, u32 address, u32 type, s32 value, +                                    s32 num_to_wake) { +    return SignalToAddress(system, static_cast<VAddr>(address), type, value, num_to_wake); +} +  static void KernelDebug([[maybe_unused]] Core::System& system,                          [[maybe_unused]] u32 kernel_debug_type, [[maybe_unused]] u64 param1,                          [[maybe_unused]] u64 param2, [[maybe_unused]] u64 param3) { @@ -1791,6 +1895,12 @@ static u64 GetSystemTick(Core::System& system) {      return result;  } +static void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) { +    u64 time = GetSystemTick(system); +    *time_low = static_cast<u32>(time); +    *time_high = static_cast<u32>(time >> 32); +} +  /// Close a handle  static ResultCode CloseHandle(Core::System& system, Handle handle) {      LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); @@ -1823,6 +1933,10 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) {      return ERR_INVALID_HANDLE;  } +static ResultCode ResetSignal32(Core::System& system, Handle handle) { +    return ResetSignal(system, handle); +} +  /// Creates a TransferMemory object  static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size,                                         u32 permissions) { @@ -1897,6 +2011,15 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,      return RESULT_SUCCESS;  } +static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle, u32* core, +                                      u32* mask_low, u32* mask_high) { +    u64 mask{}; +    const auto result = GetThreadCoreMask(system, thread_handle, core, &mask); +    *mask_high = static_cast<u32>(mask >> 32); +    *mask_low = static_cast<u32>(mask); +    return result; +} +  static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core,                                      u64 affinity_mask) {      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      return RESULT_SUCCESS;  } +static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) { +    return CreateEvent(system, write_handle, read_handle); +} +  static ResultCode ClearEvent(Core::System& system, Handle handle) {      LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); @@ -2009,6 +2136,10 @@ static ResultCode ClearEvent(Core::System& system, Handle handle) {      return ERR_INVALID_HANDLE;  } +static ResultCode ClearEvent32(Core::System& system, Handle handle) { +    return ClearEvent(system, handle); +} +  static ResultCode SignalEvent(Core::System& system, Handle handle) {      LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); @@ -2024,6 +2155,10 @@ static ResultCode SignalEvent(Core::System& system, Handle handle) {      return RESULT_SUCCESS;  } +static ResultCode SignalEvent32(Core::System& system, Handle handle) { +    return SignalEvent(system, handle); +} +  static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {      LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); @@ -2209,6 +2344,15 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd      return RESULT_SUCCESS;  } +static ResultCode FlushProcessDataCache32(Core::System& system, Handle handle, u32 address, +                                          u32 size) { +    // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a nope +    // as all emulation is done in the same cache level in host architecture, thus data cache +    // does not need flushing. +    LOG_DEBUG(Kernel_SVC, "called"); +    return RESULT_SUCCESS; +} +  namespace {  struct FunctionDef {      using Func = void(Core::System&); @@ -2224,56 +2368,56 @@ static const FunctionDef SVC_Table_32[] = {      {0x01, SvcWrap32<SetHeapSize32>, "SetHeapSize32"},      {0x02, nullptr, "Unknown"},      {0x03, SvcWrap32<SetMemoryAttribute32>, "SetMemoryAttribute32"}, -    {0x04, nullptr, "MapMemory32"}, -    {0x05, nullptr, "UnmapMemory32"}, +    {0x04, SvcWrap32<MapMemory32>, "MapMemory32"}, +    {0x05, SvcWrap32<UnmapMemory32>, "UnmapMemory32"},      {0x06, SvcWrap32<QueryMemory32>, "QueryMemory32"}, -    {0x07, nullptr, "ExitProcess32"}, -    {0x08, nullptr, "CreateThread32"}, -    {0x09, nullptr, "StartThread32"}, -    {0x0a, nullptr, "ExitThread32"}, -    {0x0b, nullptr, "SleepThread32"}, +    {0x07, SvcWrap32<ExitProcess32>, "ExitProcess32"}, +    {0x08, SvcWrap32<CreateThread32>, "CreateThread32"}, +    {0x09, SvcWrap32<StartThread32>, "StartThread32"}, +    {0x0a, SvcWrap32<ExitThread32>, "ExitThread32"}, +    {0x0b, SvcWrap32<SleepThread32>, "SleepThread32"},      {0x0c, SvcWrap32<GetThreadPriority32>, "GetThreadPriority32"},      {0x0d, SvcWrap32<SetThreadPriority32>, "SetThreadPriority32"}, -    {0x0e, nullptr, "GetThreadCoreMask32"}, +    {0x0e, SvcWrap32<GetThreadCoreMask32>, "GetThreadCoreMask32"},      {0x0f, SvcWrap32<SetThreadCoreMask32>, "SetThreadCoreMask32"},      {0x10, SvcWrap32<GetCurrentProcessorNumber32>, "GetCurrentProcessorNumber32"}, -    {0x11, nullptr, "SignalEvent32"}, -    {0x12, nullptr, "ClearEvent32"}, -    {0x13, nullptr, "MapSharedMemory32"}, +    {0x11, SvcWrap32<SignalEvent32>, "SignalEvent32"}, +    {0x12, SvcWrap32<ClearEvent32>, "ClearEvent32"}, +    {0x13, SvcWrap32<MapSharedMemory32>, "MapSharedMemory32"},      {0x14, nullptr, "UnmapSharedMemory32"},      {0x15, SvcWrap32<CreateTransferMemory32>, "CreateTransferMemory32"},      {0x16, SvcWrap32<CloseHandle32>, "CloseHandle32"}, -    {0x17, nullptr, "ResetSignal32"}, +    {0x17, SvcWrap32<ResetSignal32>, "ResetSignal32"},      {0x18, SvcWrap32<WaitSynchronization32>, "WaitSynchronization32"}, -    {0x19, nullptr, "CancelSynchronization32"}, -    {0x1a, nullptr, "ArbitrateLock32"}, -    {0x1b, nullptr, "ArbitrateUnlock32"}, -    {0x1c, nullptr, "WaitProcessWideKeyAtomic32"}, +    {0x19, SvcWrap32<CancelSynchronization32>, "CancelSynchronization32"}, +    {0x1a, SvcWrap32<ArbitrateLock32>, "ArbitrateLock32"}, +    {0x1b, SvcWrap32<ArbitrateUnlock32>, "ArbitrateUnlock32"}, +    {0x1c, SvcWrap32<WaitProcessWideKeyAtomic32>, "WaitProcessWideKeyAtomic32"},      {0x1d, SvcWrap32<SignalProcessWideKey32>, "SignalProcessWideKey32"}, -    {0x1e, nullptr, "GetSystemTick32"}, +    {0x1e, SvcWrap32<GetSystemTick32>, "GetSystemTick32"},      {0x1f, SvcWrap32<ConnectToNamedPort32>, "ConnectToNamedPort32"},      {0x20, nullptr, "Unknown"},      {0x21, SvcWrap32<SendSyncRequest32>, "SendSyncRequest32"},      {0x22, nullptr, "SendSyncRequestWithUserBuffer32"},      {0x23, nullptr, "Unknown"}, -    {0x24, nullptr, "GetProcessId32"}, +    {0x24, SvcWrap32<GetProcessId32>, "GetProcessId32"},      {0x25, SvcWrap32<GetThreadId32>, "GetThreadId32"}, -    {0x26, nullptr, "Break32"}, +    {0x26, SvcWrap32<Break32>, "Break32"},      {0x27, nullptr, "OutputDebugString32"},      {0x28, nullptr, "Unknown"},      {0x29, SvcWrap32<GetInfo32>, "GetInfo32"},      {0x2a, nullptr, "Unknown"},      {0x2b, nullptr, "Unknown"}, -    {0x2c, nullptr, "MapPhysicalMemory32"}, -    {0x2d, nullptr, "UnmapPhysicalMemory32"}, +    {0x2c, SvcWrap32<MapPhysicalMemory32>, "MapPhysicalMemory32"}, +    {0x2d, SvcWrap32<UnmapPhysicalMemory32>, "UnmapPhysicalMemory32"},      {0x2e, nullptr, "Unknown"},      {0x2f, nullptr, "Unknown"},      {0x30, nullptr, "Unknown"},      {0x31, nullptr, "Unknown"}, -    {0x32, nullptr, "SetThreadActivity32"}, -    {0x33, nullptr, "GetThreadContext32"}, -    {0x34, nullptr, "WaitForAddress32"}, -    {0x35, nullptr, "SignalToAddress32"}, +    {0x32, SvcWrap32<SetThreadActivity32>, "SetThreadActivity32"}, +    {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"}, +    {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"}, +    {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"},      {0x36, nullptr, "Unknown"},      {0x37, nullptr, "Unknown"},      {0x38, nullptr, "Unknown"}, @@ -2289,7 +2433,7 @@ static const FunctionDef SVC_Table_32[] = {      {0x42, nullptr, "Unknown"},      {0x43, nullptr, "ReplyAndReceive32"},      {0x44, nullptr, "Unknown"}, -    {0x45, nullptr, "CreateEvent32"}, +    {0x45, SvcWrap32<CreateEvent32>, "CreateEvent32"},      {0x46, nullptr, "Unknown"},      {0x47, nullptr, "Unknown"},      {0x48, nullptr, "Unknown"}, @@ -2315,7 +2459,7 @@ static const FunctionDef SVC_Table_32[] = {      {0x5c, nullptr, "Unknown"},      {0x5d, nullptr, "Unknown"},      {0x5e, nullptr, "Unknown"}, -    {0x5F, nullptr, "FlushProcessDataCache32"}, +    {0x5F, SvcWrap32<FlushProcessDataCache32>, "FlushProcessDataCache32"},      {0x60, nullptr, "Unknown"},      {0x61, nullptr, "Unknown"},      {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) {      func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2));  } -// Used by QueryMemory32 +// Used by QueryMemory32, ArbitrateLock32  template <ResultCode func(Core::System&, u32, u32, u32)>  void SvcWrap32(Core::System& system) {      FuncReturn32(system,                   func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw);  } +// Used by Break32 +template <void func(Core::System&, u32, u32, u32)> +void SvcWrap32(Core::System& system) { +    func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)); +} + +// Used by ExitProcess32, ExitThread32 +template <void func(Core::System&)> +void SvcWrap32(Core::System& system) { +    func(system); +} +  // Used by GetCurrentProcessorNumber32  template <u32 func(Core::System&)>  void SvcWrap32(Core::System& system) { -    FuncReturn(system, func(system)); +    FuncReturn32(system, func(system)); +} + +// Used by SleepThread32 +template <void func(Core::System&, u32, u32)> +void SvcWrap32(Core::System& system) { +    func(system, Param32(system, 0), Param32(system, 1)); +} + +// Used by CreateThread32 +template <ResultCode func(Core::System&, Handle*, u32, u32, u32, u32, s32)> +void SvcWrap32(Core::System& system) { +    Handle param_1 = 0; + +    const u32 retval = func(system, ¶m_1, Param32(system, 0), Param32(system, 1), +                            Param32(system, 2), Param32(system, 3), Param32(system, 4)) +                           .raw; + +    system.CurrentArmInterface().SetReg(1, param_1); +    FuncReturn(system, retval);  }  // Used by GetInfo32 @@ -399,6 +430,43 @@ void SvcWrap32(Core::System& system) {      FuncReturn(system, retval);  } +// Used by GetSystemTick32 +template <void func(Core::System&, u32*, u32*)> +void SvcWrap32(Core::System& system) { +    u32 param_1 = 0; +    u32 param_2 = 0; + +    func(system, ¶m_1, ¶m_2); +    system.CurrentArmInterface().SetReg(0, param_1); +    system.CurrentArmInterface().SetReg(1, param_2); +} + +// Used by CreateEvent32 +template <ResultCode func(Core::System&, Handle*, Handle*)> +void SvcWrap32(Core::System& system) { +    Handle param_1 = 0; +    Handle param_2 = 0; + +    const u32 retval = func(system, ¶m_1, ¶m_2).raw; +    system.CurrentArmInterface().SetReg(1, param_1); +    system.CurrentArmInterface().SetReg(2, param_2); +    FuncReturn(system, retval); +} + +// Used by GetThreadId32 +template <ResultCode func(Core::System&, Handle, u32*, u32*, u32*)> +void SvcWrap32(Core::System& system) { +    u32 param_1 = 0; +    u32 param_2 = 0; +    u32 param_3 = 0; + +    const u32 retval = func(system, Param32(system, 2), ¶m_1, ¶m_2, ¶m_3).raw; +    system.CurrentArmInterface().SetReg(1, param_1); +    system.CurrentArmInterface().SetReg(2, param_2); +    system.CurrentArmInterface().SetReg(3, param_3); +    FuncReturn(system, retval); +} +  // Used by SignalProcessWideKey32  template <void func(Core::System&, u32, s32)>  void SvcWrap32(Core::System& system) { @@ -423,7 +491,38 @@ void SvcWrap32(Core::System& system) {      FuncReturn(system, retval);  } -// Used by SendSyncRequest32 +// Used by WaitProcessWideKeyAtomic32 +template <ResultCode func(Core::System&, u32, u32, Handle, u32, u32)> +void SvcWrap32(Core::System& system) { +    const u32 retval = +        func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), +             static_cast<Handle>(Param(system, 2)), static_cast<u32>(Param(system, 3)), +             static_cast<u32>(Param(system, 4))) +            .raw; +    FuncReturn(system, retval); +} + +// Used by WaitForAddress32 +template <ResultCode func(Core::System&, u32, u32, s32, u32, u32)> +void SvcWrap32(Core::System& system) { +    const u32 retval = func(system, static_cast<u32>(Param(system, 0)), +                            static_cast<u32>(Param(system, 1)), static_cast<s32>(Param(system, 2)), +                            static_cast<u32>(Param(system, 3)), static_cast<u32>(Param(system, 4))) +                           .raw; +    FuncReturn(system, retval); +} + +// Used by SignalToAddress32 +template <ResultCode func(Core::System&, u32, u32, s32, s32)> +void SvcWrap32(Core::System& system) { +    const u32 retval = +        func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), +             static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3))) +            .raw; +    FuncReturn(system, retval); +} + +// Used by SendSyncRequest32, ArbitrateUnlock32  template <ResultCode func(Core::System&, u32)>  void SvcWrap32(Core::System& system) {      FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); | 
