diff options
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/physical_core.cpp | 19 | ||||
-rw-r--r-- | src/core/hle/kernel/physical_core.h | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/process.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 21 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.h | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 329 | ||||
-rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 158 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.cpp | 31 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.h | 22 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/set/set.cpp | 10 | ||||
-rw-r--r-- | src/core/hle/service/set/set.h | 1 | ||||
-rw-r--r-- | src/core/hle/service/time/time_zone_content_manager.cpp | 2 |
14 files changed, 466 insertions, 147 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 9232f4d7e..e47f1deed 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -186,6 +186,10 @@ struct KernelCore::Impl { return; } + for (auto& core : cores) { + core.SetIs64Bit(process->Is64BitProcess()); + } + system.Memory().SetCurrentPageTable(*process); } diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index 9303dd273..aa2787467 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp @@ -5,7 +5,8 @@ #include "common/logging/log.h" #include "core/arm/arm_interface.h" #ifdef ARCHITECTURE_x86_64 -#include "core/arm/dynarmic/arm_dynarmic.h" +#include "core/arm/dynarmic/arm_dynarmic_32.h" +#include "core/arm/dynarmic/arm_dynarmic_64.h" #endif #include "core/arm/exclusive_monitor.h" #include "core/arm/unicorn/arm_unicorn.h" @@ -20,13 +21,17 @@ PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Core::ExclusiveMonitor& exclusive_monitor) : core_index{id} { #ifdef ARCHITECTURE_x86_64 - arm_interface = std::make_unique<Core::ARM_Dynarmic>(system, exclusive_monitor, core_index); + arm_interface_32 = + std::make_unique<Core::ARM_Dynarmic_32>(system, exclusive_monitor, core_index); + arm_interface_64 = + std::make_unique<Core::ARM_Dynarmic_64>(system, exclusive_monitor, core_index); + #else arm_interface = std::make_shared<Core::ARM_Unicorn>(system); LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif - scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface, core_index); + scheduler = std::make_unique<Kernel::Scheduler>(system, core_index); } PhysicalCore::~PhysicalCore() = default; @@ -48,4 +53,12 @@ void PhysicalCore::Shutdown() { scheduler->Shutdown(); } +void PhysicalCore::SetIs64Bit(bool is_64_bit) { + if (is_64_bit) { + arm_interface = arm_interface_64.get(); + } else { + arm_interface = arm_interface_32.get(); + } +} + } // namespace Kernel diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index 4c32c0f1b..3269166be 100644 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -68,10 +68,14 @@ public: return *scheduler; } + void SetIs64Bit(bool is_64_bit); + private: std::size_t core_index; - std::unique_ptr<Core::ARM_Interface> arm_interface; + std::unique_ptr<Core::ARM_Interface> arm_interface_32; + std::unique_ptr<Core::ARM_Interface> arm_interface_64; std::unique_ptr<Kernel::Scheduler> scheduler; + Core::ARM_Interface* arm_interface{}; }; } // namespace Kernel diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 2fcb7326c..edc414d69 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -42,7 +42,8 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) { // Register 1 must be a handle to the main thread const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); - thread->GetContext().cpu_registers[1] = thread_handle; + thread->GetContext32().cpu_registers[1] = thread_handle; + thread->GetContext64().cpu_registers[1] = thread_handle; // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires thread->ResumeFromWait(); diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index c65f82fb7..1140c72a3 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -383,8 +383,8 @@ void GlobalScheduler::Unlock() { // TODO(Blinkhawk): Setup the interrupts and change context on current core. } -Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id) - : system(system), cpu_core(cpu_core), core_id(core_id) {} +Scheduler::Scheduler(Core::System& system, std::size_t core_id) + : system{system}, core_id{core_id} {} Scheduler::~Scheduler() = default; @@ -422,9 +422,10 @@ void Scheduler::UnloadThread() { // Save context for previous thread if (previous_thread) { - cpu_core.SaveContext(previous_thread->GetContext()); + system.ArmInterface(core_id).SaveContext(previous_thread->GetContext32()); + system.ArmInterface(core_id).SaveContext(previous_thread->GetContext64()); // Save the TPIDR_EL0 system register in case it was modified. - previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); + previous_thread->SetTPIDR_EL0(system.ArmInterface(core_id).GetTPIDR_EL0()); if (previous_thread->GetStatus() == ThreadStatus::Running) { // This is only the case when a reschedule is triggered without the current thread @@ -451,9 +452,10 @@ void Scheduler::SwitchContext() { // Save context for previous thread if (previous_thread) { - cpu_core.SaveContext(previous_thread->GetContext()); + system.ArmInterface(core_id).SaveContext(previous_thread->GetContext32()); + system.ArmInterface(core_id).SaveContext(previous_thread->GetContext64()); // Save the TPIDR_EL0 system register in case it was modified. - previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); + previous_thread->SetTPIDR_EL0(system.ArmInterface(core_id).GetTPIDR_EL0()); if (previous_thread->GetStatus() == ThreadStatus::Running) { // This is only the case when a reschedule is triggered without the current thread @@ -481,9 +483,10 @@ void Scheduler::SwitchContext() { system.Kernel().MakeCurrentProcess(thread_owner_process); } - cpu_core.LoadContext(new_thread->GetContext()); - cpu_core.SetTlsAddress(new_thread->GetTLSAddress()); - cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); + system.ArmInterface(core_id).LoadContext(new_thread->GetContext32()); + system.ArmInterface(core_id).LoadContext(new_thread->GetContext64()); + system.ArmInterface(core_id).SetTlsAddress(new_thread->GetTLSAddress()); + system.ArmInterface(core_id).SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); } else { current_thread = nullptr; // Note: We do not reset the current process and current page table when idling because diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 1c93a838c..07df33f9c 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -181,7 +181,7 @@ private: class Scheduler final { public: - explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id); + explicit Scheduler(Core::System& system, std::size_t core_id); ~Scheduler(); /// Returns whether there are any threads that are ready to run. @@ -235,7 +235,6 @@ private: std::shared_ptr<Thread> selected_thread = nullptr; Core::System& system; - Core::ARM_Interface& cpu_core; u64 last_context_switch_time = 0; u64 idle_selection_count = 0; const std::size_t core_id; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index fd91779a3..4ffc113c2 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -187,6 +187,13 @@ static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_s return RESULT_SUCCESS; } +static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) { + VAddr temp_heap_addr{}; + const ResultCode result{SetHeapSize(system, &temp_heap_addr, heap_size)}; + *heap_addr = static_cast<u32>(temp_heap_addr); + return result; +} + static ResultCode SetMemoryPermission(Core::System& system, VAddr addr, u64 size, u32 prot) { LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); @@ -371,6 +378,12 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, return RESULT_SUCCESS; } +static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, + u32 port_name_address) { + + return ConnectToNamedPort(system, out_handle, port_name_address); +} + /// Makes a blocking IPC call to an OS service. static ResultCode SendSyncRequest(Core::System& system, Handle handle) { const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); @@ -390,6 +403,10 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { return session->SendSyncRequest(SharedFrom(thread), system.Memory()); } +static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { + return SendSyncRequest(system, handle); +} + /// Get the ID for the specified thread. static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); @@ -405,6 +422,17 @@ static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle threa return RESULT_SUCCESS; } +static ResultCode GetThreadId32(Core::System& system, u32* thread_id_low, u32* thread_id_high, + Handle thread_handle) { + u64 thread_id{}; + const ResultCode result{GetThreadId(system, &thread_id, thread_handle)}; + + *thread_id_low = static_cast<u32>(thread_id >> 32); + *thread_id_high = static_cast<u32>(thread_id & std::numeric_limits<u32>::max()); + + return result; +} + /// Gets the ID of the specified process or a specified thread's owning process. static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); @@ -479,6 +507,12 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr return result; } +static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, + s32 handle_count, u32 timeout_high, Handle* index) { + const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; + return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds); +} + /// Resumes a thread waiting on WaitSynchronization static ResultCode CancelSynchronization(Core::System& system, Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); @@ -917,6 +951,18 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha } } +static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, + u32 info_id, u32 handle, u32 sub_id_high) { + const u64 sub_id{static_cast<u64>(sub_id_low | (static_cast<u64>(sub_id_high) << 32))}; + u64 res_value{}; + + const ResultCode result{GetInfo(system, &res_value, info_id, handle, sub_id)}; + *result_high = static_cast<u32>(res_value >> 32); + *result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max()); + + return result; +} + /// Maps memory at a desired address static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); @@ -1058,7 +1104,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H return ERR_BUSY; } - Core::ARM_Interface::ThreadContext ctx = thread->GetContext(); + Core::ARM_Interface::ThreadContext64 ctx = thread->GetContext64(); // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. ctx.pstate &= 0xFF0FFE20; @@ -1088,6 +1134,10 @@ static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle return RESULT_SUCCESS; } +static ResultCode GetThreadPriority32(Core::System& system, u32* priority, Handle handle) { + return GetThreadPriority(system, priority, handle); +} + /// Sets the priority for the specified thread static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 priority) { LOG_TRACE(Kernel_SVC, "called"); @@ -1259,6 +1309,11 @@ static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address, query_address); } +static ResultCode QueryMemory32(Core::System& system, u32 memory_info_address, + u32 page_info_address, u32 query_address) { + return QueryMemory(system, memory_info_address, page_info_address, query_address); +} + static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, u64 src_address, u64 size) { LOG_DEBUG(Kernel_SVC, @@ -1675,6 +1730,10 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_ } } +static void SignalProcessWideKey32(Core::System& system, u32 condition_variable_addr, s32 target) { + SignalProcessWideKey(system, condition_variable_addr, target); +} + // Wait for an address (via Address Arbiter) static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type, s32 value, s64 timeout) { @@ -1760,6 +1819,10 @@ static ResultCode CloseHandle(Core::System& system, Handle handle) { return handle_table.Close(handle); } +static ResultCode CloseHandle32(Core::System& system, Handle handle) { + return CloseHandle(system, handle); +} + /// Clears the signaled state of an event or process. static ResultCode ResetSignal(Core::System& system, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); @@ -2317,69 +2380,196 @@ struct FunctionDef { }; } // namespace -static const FunctionDef SVC_Table[] = { +static const FunctionDef SVC_Table_32[] = { {0x00, nullptr, "Unknown"}, - {0x01, SvcWrap<SetHeapSize>, "SetHeapSize"}, - {0x02, SvcWrap<SetMemoryPermission>, "SetMemoryPermission"}, - {0x03, SvcWrap<SetMemoryAttribute>, "SetMemoryAttribute"}, - {0x04, SvcWrap<MapMemory>, "MapMemory"}, - {0x05, SvcWrap<UnmapMemory>, "UnmapMemory"}, - {0x06, SvcWrap<QueryMemory>, "QueryMemory"}, - {0x07, SvcWrap<ExitProcess>, "ExitProcess"}, - {0x08, SvcWrap<CreateThread>, "CreateThread"}, - {0x09, SvcWrap<StartThread>, "StartThread"}, - {0x0A, SvcWrap<ExitThread>, "ExitThread"}, - {0x0B, SvcWrap<SleepThread>, "SleepThread"}, - {0x0C, SvcWrap<GetThreadPriority>, "GetThreadPriority"}, - {0x0D, SvcWrap<SetThreadPriority>, "SetThreadPriority"}, - {0x0E, SvcWrap<GetThreadCoreMask>, "GetThreadCoreMask"}, - {0x0F, SvcWrap<SetThreadCoreMask>, "SetThreadCoreMask"}, - {0x10, SvcWrap<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"}, - {0x11, SvcWrap<SignalEvent>, "SignalEvent"}, - {0x12, SvcWrap<ClearEvent>, "ClearEvent"}, - {0x13, SvcWrap<MapSharedMemory>, "MapSharedMemory"}, - {0x14, SvcWrap<UnmapSharedMemory>, "UnmapSharedMemory"}, - {0x15, SvcWrap<CreateTransferMemory>, "CreateTransferMemory"}, - {0x16, SvcWrap<CloseHandle>, "CloseHandle"}, - {0x17, SvcWrap<ResetSignal>, "ResetSignal"}, - {0x18, SvcWrap<WaitSynchronization>, "WaitSynchronization"}, - {0x19, SvcWrap<CancelSynchronization>, "CancelSynchronization"}, - {0x1A, SvcWrap<ArbitrateLock>, "ArbitrateLock"}, - {0x1B, SvcWrap<ArbitrateUnlock>, "ArbitrateUnlock"}, - {0x1C, SvcWrap<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"}, - {0x1D, SvcWrap<SignalProcessWideKey>, "SignalProcessWideKey"}, - {0x1E, SvcWrap<GetSystemTick>, "GetSystemTick"}, - {0x1F, SvcWrap<ConnectToNamedPort>, "ConnectToNamedPort"}, + {0x01, SvcWrap32<SetHeapSize32>, "SetHeapSize32"}, + {0x02, nullptr, "Unknown"}, + {0x03, nullptr, "SetMemoryAttribute32"}, + {0x04, nullptr, "MapMemory32"}, + {0x05, nullptr, "UnmapMemory32"}, + {0x06, SvcWrap32<QueryMemory32>, "QueryMemory32"}, + {0x07, nullptr, "ExitProcess32"}, + {0x08, nullptr, "CreateThread32"}, + {0x09, nullptr, "StartThread32"}, + {0x0a, nullptr, "ExitThread32"}, + {0x0b, nullptr, "SleepThread32"}, + {0x0c, SvcWrap32<GetThreadPriority32>, "GetThreadPriority32"}, + {0x0d, nullptr, "SetThreadPriority32"}, + {0x0e, nullptr, "GetThreadCoreMask32"}, + {0x0f, nullptr, "SetThreadCoreMask32"}, + {0x10, nullptr, "GetCurrentProcessorNumber32"}, + {0x11, nullptr, "SignalEvent32"}, + {0x12, nullptr, "ClearEvent32"}, + {0x13, nullptr, "MapSharedMemory32"}, + {0x14, nullptr, "UnmapSharedMemory32"}, + {0x15, nullptr, "CreateTransferMemory32"}, + {0x16, SvcWrap32<CloseHandle32>, "CloseHandle32"}, + {0x17, nullptr, "ResetSignal32"}, + {0x18, SvcWrap32<WaitSynchronization32>, "WaitSynchronization32"}, + {0x19, nullptr, "CancelSynchronization32"}, + {0x1a, nullptr, "ArbitrateLock32"}, + {0x1b, nullptr, "ArbitrateUnlock32"}, + {0x1c, nullptr, "WaitProcessWideKeyAtomic32"}, + {0x1d, SvcWrap32<SignalProcessWideKey32>, "SignalProcessWideKey32"}, + {0x1e, nullptr, "GetSystemTick32"}, + {0x1f, SvcWrap32<ConnectToNamedPort32>, "ConnectToNamedPort32"}, + {0x20, nullptr, "Unknown"}, + {0x21, SvcWrap32<SendSyncRequest32>, "SendSyncRequest32"}, + {0x22, nullptr, "SendSyncRequestWithUserBuffer32"}, + {0x23, nullptr, "Unknown"}, + {0x24, nullptr, "GetProcessId32"}, + {0x25, SvcWrap32<GetThreadId32>, "GetThreadId32"}, + {0x26, nullptr, "Break32"}, + {0x27, nullptr, "OutputDebugString32"}, + {0x28, nullptr, "Unknown"}, + {0x29, SvcWrap32<GetInfo32>, "GetInfo32"}, + {0x2a, nullptr, "Unknown"}, + {0x2b, nullptr, "Unknown"}, + {0x2c, nullptr, "MapPhysicalMemory32"}, + {0x2d, nullptr, "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"}, + {0x36, nullptr, "Unknown"}, + {0x37, nullptr, "Unknown"}, + {0x38, nullptr, "Unknown"}, + {0x39, nullptr, "Unknown"}, + {0x3a, nullptr, "Unknown"}, + {0x3b, nullptr, "Unknown"}, + {0x3c, nullptr, "Unknown"}, + {0x3d, nullptr, "Unknown"}, + {0x3e, nullptr, "Unknown"}, + {0x3f, nullptr, "Unknown"}, + {0x40, nullptr, "CreateSession32"}, + {0x41, nullptr, "AcceptSession32"}, + {0x42, nullptr, "Unknown"}, + {0x43, nullptr, "ReplyAndReceive32"}, + {0x44, nullptr, "Unknown"}, + {0x45, nullptr, "CreateEvent32"}, + {0x46, nullptr, "Unknown"}, + {0x47, nullptr, "Unknown"}, + {0x48, nullptr, "Unknown"}, + {0x49, nullptr, "Unknown"}, + {0x4a, nullptr, "Unknown"}, + {0x4b, nullptr, "Unknown"}, + {0x4c, nullptr, "Unknown"}, + {0x4d, nullptr, "Unknown"}, + {0x4e, nullptr, "Unknown"}, + {0x4f, nullptr, "Unknown"}, + {0x50, nullptr, "Unknown"}, + {0x51, nullptr, "Unknown"}, + {0x52, nullptr, "Unknown"}, + {0x53, nullptr, "Unknown"}, + {0x54, nullptr, "Unknown"}, + {0x55, nullptr, "Unknown"}, + {0x56, nullptr, "Unknown"}, + {0x57, nullptr, "Unknown"}, + {0x58, nullptr, "Unknown"}, + {0x59, nullptr, "Unknown"}, + {0x5a, nullptr, "Unknown"}, + {0x5b, nullptr, "Unknown"}, + {0x5c, nullptr, "Unknown"}, + {0x5d, nullptr, "Unknown"}, + {0x5e, nullptr, "Unknown"}, + {0x5F, nullptr, "FlushProcessDataCache32"}, + {0x60, nullptr, "Unknown"}, + {0x61, nullptr, "Unknown"}, + {0x62, nullptr, "Unknown"}, + {0x63, nullptr, "Unknown"}, + {0x64, nullptr, "Unknown"}, + {0x65, nullptr, "GetProcessList32"}, + {0x66, nullptr, "Unknown"}, + {0x67, nullptr, "Unknown"}, + {0x68, nullptr, "Unknown"}, + {0x69, nullptr, "Unknown"}, + {0x6A, nullptr, "Unknown"}, + {0x6B, nullptr, "Unknown"}, + {0x6C, nullptr, "Unknown"}, + {0x6D, nullptr, "Unknown"}, + {0x6E, nullptr, "Unknown"}, + {0x6f, nullptr, "GetSystemInfo32"}, + {0x70, nullptr, "CreatePort32"}, + {0x71, nullptr, "ManageNamedPort32"}, + {0x72, nullptr, "ConnectToPort32"}, + {0x73, nullptr, "SetProcessMemoryPermission32"}, + {0x74, nullptr, "Unknown"}, + {0x75, nullptr, "Unknown"}, + {0x76, nullptr, "Unknown"}, + {0x77, nullptr, "MapProcessCodeMemory32"}, + {0x78, nullptr, "UnmapProcessCodeMemory32"}, + {0x79, nullptr, "Unknown"}, + {0x7A, nullptr, "Unknown"}, + {0x7B, nullptr, "TerminateProcess32"}, +}; + +static const FunctionDef SVC_Table_64[] = { + {0x00, nullptr, "Unknown"}, + {0x01, SvcWrap64<SetHeapSize>, "SetHeapSize"}, + {0x02, SvcWrap64<SetMemoryPermission>, "SetMemoryPermission"}, + {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, + {0x04, SvcWrap64<MapMemory>, "MapMemory"}, + {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, + {0x06, SvcWrap64<QueryMemory>, "QueryMemory"}, + {0x07, SvcWrap64<ExitProcess>, "ExitProcess"}, + {0x08, SvcWrap64<CreateThread>, "CreateThread"}, + {0x09, SvcWrap64<StartThread>, "StartThread"}, + {0x0A, SvcWrap64<ExitThread>, "ExitThread"}, + {0x0B, SvcWrap64<SleepThread>, "SleepThread"}, + {0x0C, SvcWrap64<GetThreadPriority>, "GetThreadPriority"}, + {0x0D, SvcWrap64<SetThreadPriority>, "SetThreadPriority"}, + {0x0E, SvcWrap64<GetThreadCoreMask>, "GetThreadCoreMask"}, + {0x0F, SvcWrap64<SetThreadCoreMask>, "SetThreadCoreMask"}, + {0x10, SvcWrap64<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"}, + {0x11, SvcWrap64<SignalEvent>, "SignalEvent"}, + {0x12, SvcWrap64<ClearEvent>, "ClearEvent"}, + {0x13, SvcWrap64<MapSharedMemory>, "MapSharedMemory"}, + {0x14, SvcWrap64<UnmapSharedMemory>, "UnmapSharedMemory"}, + {0x15, SvcWrap64<CreateTransferMemory>, "CreateTransferMemory"}, + {0x16, SvcWrap64<CloseHandle>, "CloseHandle"}, + {0x17, SvcWrap64<ResetSignal>, "ResetSignal"}, + {0x18, SvcWrap64<WaitSynchronization>, "WaitSynchronization"}, + {0x19, SvcWrap64<CancelSynchronization>, "CancelSynchronization"}, + {0x1A, SvcWrap64<ArbitrateLock>, "ArbitrateLock"}, + {0x1B, SvcWrap64<ArbitrateUnlock>, "ArbitrateUnlock"}, + {0x1C, SvcWrap64<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"}, + {0x1D, SvcWrap64<SignalProcessWideKey>, "SignalProcessWideKey"}, + {0x1E, SvcWrap64<GetSystemTick>, "GetSystemTick"}, + {0x1F, SvcWrap64<ConnectToNamedPort>, "ConnectToNamedPort"}, {0x20, nullptr, "SendSyncRequestLight"}, - {0x21, SvcWrap<SendSyncRequest>, "SendSyncRequest"}, + {0x21, SvcWrap64<SendSyncRequest>, "SendSyncRequest"}, {0x22, nullptr, "SendSyncRequestWithUserBuffer"}, {0x23, nullptr, "SendAsyncRequestWithUserBuffer"}, - {0x24, SvcWrap<GetProcessId>, "GetProcessId"}, - {0x25, SvcWrap<GetThreadId>, "GetThreadId"}, - {0x26, SvcWrap<Break>, "Break"}, - {0x27, SvcWrap<OutputDebugString>, "OutputDebugString"}, + {0x24, SvcWrap64<GetProcessId>, "GetProcessId"}, + {0x25, SvcWrap64<GetThreadId>, "GetThreadId"}, + {0x26, SvcWrap64<Break>, "Break"}, + {0x27, SvcWrap64<OutputDebugString>, "OutputDebugString"}, {0x28, nullptr, "ReturnFromException"}, - {0x29, SvcWrap<GetInfo>, "GetInfo"}, + {0x29, SvcWrap64<GetInfo>, "GetInfo"}, {0x2A, nullptr, "FlushEntireDataCache"}, {0x2B, nullptr, "FlushDataCache"}, - {0x2C, SvcWrap<MapPhysicalMemory>, "MapPhysicalMemory"}, - {0x2D, SvcWrap<UnmapPhysicalMemory>, "UnmapPhysicalMemory"}, + {0x2C, SvcWrap64<MapPhysicalMemory>, "MapPhysicalMemory"}, + {0x2D, SvcWrap64<UnmapPhysicalMemory>, "UnmapPhysicalMemory"}, {0x2E, nullptr, "GetFutureThreadInfo"}, {0x2F, nullptr, "GetLastThreadInfo"}, - {0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, - {0x31, SvcWrap<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"}, - {0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"}, - {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"}, - {0x34, SvcWrap<WaitForAddress>, "WaitForAddress"}, - {0x35, SvcWrap<SignalToAddress>, "SignalToAddress"}, + {0x30, SvcWrap64<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, + {0x31, SvcWrap64<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"}, + {0x32, SvcWrap64<SetThreadActivity>, "SetThreadActivity"}, + {0x33, SvcWrap64<GetThreadContext>, "GetThreadContext"}, + {0x34, SvcWrap64<WaitForAddress>, "WaitForAddress"}, + {0x35, SvcWrap64<SignalToAddress>, "SignalToAddress"}, {0x36, nullptr, "SynchronizePreemptionState"}, {0x37, nullptr, "Unknown"}, {0x38, nullptr, "Unknown"}, {0x39, nullptr, "Unknown"}, {0x3A, nullptr, "Unknown"}, {0x3B, nullptr, "Unknown"}, - {0x3C, SvcWrap<KernelDebug>, "KernelDebug"}, - {0x3D, SvcWrap<ChangeKernelTraceState>, "ChangeKernelTraceState"}, + {0x3C, SvcWrap64<KernelDebug>, "KernelDebug"}, + {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, {0x3E, nullptr, "Unknown"}, {0x3F, nullptr, "Unknown"}, {0x40, nullptr, "CreateSession"}, @@ -2387,7 +2577,7 @@ static const FunctionDef SVC_Table[] = { {0x42, nullptr, "ReplyAndReceiveLight"}, {0x43, nullptr, "ReplyAndReceive"}, {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, - {0x45, SvcWrap<CreateEvent>, "CreateEvent"}, + {0x45, SvcWrap64<CreateEvent>, "CreateEvent"}, {0x46, nullptr, "Unknown"}, {0x47, nullptr, "Unknown"}, {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, @@ -2398,9 +2588,9 @@ static const FunctionDef SVC_Table[] = { {0x4D, nullptr, "SleepSystem"}, {0x4E, nullptr, "ReadWriteRegister"}, {0x4F, nullptr, "SetProcessActivity"}, - {0x50, SvcWrap<CreateSharedMemory>, "CreateSharedMemory"}, - {0x51, SvcWrap<MapTransferMemory>, "MapTransferMemory"}, - {0x52, SvcWrap<UnmapTransferMemory>, "UnmapTransferMemory"}, + {0x50, SvcWrap64<CreateSharedMemory>, "CreateSharedMemory"}, + {0x51, SvcWrap64<MapTransferMemory>, "MapTransferMemory"}, + {0x52, SvcWrap64<UnmapTransferMemory>, "UnmapTransferMemory"}, {0x53, nullptr, "CreateInterruptEvent"}, {0x54, nullptr, "QueryPhysicalAddress"}, {0x55, nullptr, "QueryIoMapping"}, @@ -2419,8 +2609,8 @@ static const FunctionDef SVC_Table[] = { {0x62, nullptr, "TerminateDebugProcess"}, {0x63, nullptr, "GetDebugEvent"}, {0x64, nullptr, "ContinueDebugEvent"}, - {0x65, SvcWrap<GetProcessList>, "GetProcessList"}, - {0x66, SvcWrap<GetThreadList>, "GetThreadList"}, + {0x65, SvcWrap64<GetProcessList>, "GetProcessList"}, + {0x66, SvcWrap64<GetThreadList>, "GetThreadList"}, {0x67, nullptr, "GetDebugThreadContext"}, {0x68, nullptr, "SetDebugThreadContext"}, {0x69, nullptr, "QueryDebugProcessMemory"}, @@ -2436,24 +2626,32 @@ static const FunctionDef SVC_Table[] = { {0x73, nullptr, "SetProcessMemoryPermission"}, {0x74, nullptr, "MapProcessMemory"}, {0x75, nullptr, "UnmapProcessMemory"}, - {0x76, SvcWrap<QueryProcessMemory>, "QueryProcessMemory"}, - {0x77, SvcWrap<MapProcessCodeMemory>, "MapProcessCodeMemory"}, - {0x78, SvcWrap<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, + {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, + {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"}, + {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, {0x79, nullptr, "CreateProcess"}, {0x7A, nullptr, "StartProcess"}, {0x7B, nullptr, "TerminateProcess"}, - {0x7C, SvcWrap<GetProcessInfo>, "GetProcessInfo"}, - {0x7D, SvcWrap<CreateResourceLimit>, "CreateResourceLimit"}, - {0x7E, SvcWrap<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"}, + {0x7C, SvcWrap64<GetProcessInfo>, "GetProcessInfo"}, + {0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"}, + {0x7E, SvcWrap64<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"}, {0x7F, nullptr, "CallSecureMonitor"}, }; -static const FunctionDef* GetSVCInfo(u32 func_num) { - if (func_num >= std::size(SVC_Table)) { +static const FunctionDef* GetSVCInfo32(u32 func_num) { + if (func_num >= std::size(SVC_Table_32)) { + LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); + return nullptr; + } + return &SVC_Table_32[func_num]; +} + +static const FunctionDef* GetSVCInfo64(u32 func_num) { + if (func_num >= std::size(SVC_Table_64)) { LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); return nullptr; } - return &SVC_Table[func_num]; + return &SVC_Table_64[func_num]; } MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); @@ -2464,7 +2662,8 @@ void CallSVC(Core::System& system, u32 immediate) { // Lock the global kernel mutex when we enter the kernel HLE. std::lock_guard lock{HLE::g_hle_lock}; - const FunctionDef* info = GetSVCInfo(immediate); + const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) + : GetSVCInfo32(immediate); if (info) { if (info->func) { info->func(system); diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 29a2cfa9d..7d735e3fa 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -15,6 +15,10 @@ static inline u64 Param(const Core::System& system, int n) { return system.CurrentArmInterface().GetReg(n); } +static inline u32 Param32(const Core::System& system, int n) { + return static_cast<u32>(system.CurrentArmInterface().GetReg(n)); +} + /** * HLE a function return from the current ARM userland process * @param system System context @@ -24,40 +28,44 @@ static inline void FuncReturn(Core::System& system, u64 result) { system.CurrentArmInterface().SetReg(0, result); } +static inline void FuncReturn32(Core::System& system, u32 result) { + system.CurrentArmInterface().SetReg(0, (u64)result); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type ResultCode template <ResultCode func(Core::System&, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0)).raw); } template <ResultCode func(Core::System&, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1)).raw); } template <ResultCode func(Core::System&, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); } template <ResultCode func(Core::System&, u32, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn( system, func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw); } template <ResultCode func(Core::System&, u32, u64, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2), Param(system, 3)) .raw); } template <ResultCode func(Core::System&, u32*)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param = 0; const u32 retval = func(system, ¶m).raw; system.CurrentArmInterface().SetReg(1, param); @@ -65,7 +73,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32*, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; system.CurrentArmInterface().SetReg(1, param_1); @@ -73,7 +81,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32*, u32*)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; u32 param_2 = 0; const u32 retval = func(system, ¶m_1, ¶m_2).raw; @@ -86,7 +94,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32*, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; system.CurrentArmInterface().SetReg(1, param_1); @@ -94,7 +102,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32*, u64, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2))).raw; @@ -104,7 +112,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u64*, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; @@ -113,12 +121,12 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u64, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw); } template <ResultCode func(Core::System&, u64*, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; @@ -127,7 +135,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u64*, u32, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1)), static_cast<u32>(Param(system, 2))) @@ -138,19 +146,19 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); } template <ResultCode func(Core::System&, u32, u32, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), Param(system, 2)) .raw); } template <ResultCode func(Core::System&, u32, u32*, u64*)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; u64 param_2 = 0; const ResultCode retval = func(system, static_cast<u32>(Param(system, 2)), ¶m_1, ¶m_2); @@ -161,54 +169,54 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u64, u64, u32, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) .raw); } template <ResultCode func(Core::System&, u64, u64, u32, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2)), Param(system, 3)) .raw); } template <ResultCode func(Core::System&, u32, u64, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), static_cast<u32>(Param(system, 2))) .raw); } template <ResultCode func(Core::System&, u64, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw); } template <ResultCode func(Core::System&, u64, u64, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn( system, func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw); } template <ResultCode func(Core::System&, u32, u64, u64, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2), static_cast<u32>(Param(system, 3))) .raw); } template <ResultCode func(Core::System&, u32, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn( system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw); } template <ResultCode func(Core::System&, u32*, u64, u64, s64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) @@ -219,14 +227,14 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u64, u64, u32, s64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) .raw); } template <ResultCode func(Core::System&, u64*, u64, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u64 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), Param(system, 3)).raw; @@ -236,7 +244,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32*, u64, u64, u64, u32, s32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), Param(system, 3), static_cast<u32>(Param(system, 4)), static_cast<s32>(Param(system, 5))) @@ -247,7 +255,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u32*, u64, u64, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), static_cast<u32>(Param(system, 3))) @@ -258,7 +266,7 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, Handle*, u64, u32, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) @@ -269,14 +277,14 @@ void SvcWrap(Core::System& system) { } template <ResultCode func(Core::System&, u64, u32, s32, s64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)), static_cast<s32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) .raw); } template <ResultCode func(Core::System&, u64, u32, s32, s32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)), static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3))) .raw); @@ -286,7 +294,7 @@ void SvcWrap(Core::System& system) { // Function wrappers that return type u32 template <u32 func(Core::System&)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system)); } @@ -294,7 +302,7 @@ void SvcWrap(Core::System& system) { // Function wrappers that return type u64 template <u64 func(Core::System&)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { FuncReturn(system, func(system)); } @@ -302,44 +310,110 @@ void SvcWrap(Core::System& system) { /// Function wrappers that return type void template <void func(Core::System&)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system); } template <void func(Core::System&, u32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, static_cast<u32>(Param(system, 0))); } template <void func(Core::System&, u32, u64, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2), Param(system, 3)); } template <void func(Core::System&, s64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, static_cast<s64>(Param(system, 0))); } template <void func(Core::System&, u64, s32)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, Param(system, 0), static_cast<s32>(Param(system, 1))); } template <void func(Core::System&, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, Param(system, 0), Param(system, 1)); } template <void func(Core::System&, u64, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, Param(system, 0), Param(system, 1), Param(system, 2)); } template <void func(Core::System&, u32, u64, u64)> -void SvcWrap(Core::System& system) { +void SvcWrap64(Core::System& system) { func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)); } +// Used by QueryMemory32 +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 GetInfo32 +template <ResultCode func(Core::System&, u32*, u32*, u32, u32, u32, u32)> +void SvcWrap32(Core::System& system) { + u32 param_1 = 0; + u32 param_2 = 0; + + const u32 retval = func(system, ¶m_1, ¶m_2, Param32(system, 0), Param32(system, 1), + Param32(system, 2), Param32(system, 3)) + .raw; + + system.CurrentArmInterface().SetReg(1, param_1); + system.CurrentArmInterface().SetReg(2, param_2); + FuncReturn(system, retval); +} + +// Used by GetThreadPriority32, ConnectToNamedPort32 +template <ResultCode func(Core::System&, u32*, u32)> +void SvcWrap32(Core::System& system) { + u32 param_1 = 0; + const u32 retval = func(system, ¶m_1, Param32(system, 1)).raw; + system.CurrentArmInterface().SetReg(1, param_1); + FuncReturn(system, retval); +} + +// Used by GetThreadId32 +template <ResultCode func(Core::System&, u32*, u32*, u32)> +void SvcWrap32(Core::System& system) { + u32 param_1 = 0; + u32 param_2 = 0; + + const u32 retval = func(system, ¶m_1, ¶m_2, Param32(system, 1)).raw; + system.CurrentArmInterface().SetReg(1, param_1); + system.CurrentArmInterface().SetReg(2, param_2); + FuncReturn(system, retval); +} + +// Used by SignalProcessWideKey32 +template <void func(Core::System&, u32, s32)> +void SvcWrap32(Core::System& system) { + func(system, static_cast<u32>(Param(system, 0)), static_cast<s32>(Param(system, 1))); +} + +// Used by SendSyncRequest32 +template <ResultCode func(Core::System&, u32)> +void SvcWrap32(Core::System& system) { + FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); +} + +// Used by WaitSynchronization32 +template <ResultCode func(Core::System&, u32, u32, s32, u32, Handle*)> +void SvcWrap32(Core::System& system) { + u32 param_1 = 0; + const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2), + Param32(system, 3), ¶m_1) + .raw; + system.CurrentArmInterface().SetReg(1, param_1); + FuncReturn(system, retval); +} + } // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index bf850e0b2..83e956036 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -133,15 +133,16 @@ void Thread::CancelWait() { ResumeFromWait(); } -/** - * Resets a thread context, making it ready to be scheduled and run by the CPU - * @param context Thread context to reset - * @param stack_top Address of the top of the stack - * @param entry_point Address of entry point for execution - * @param arg User argument for thread - */ -static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top, - VAddr entry_point, u64 arg) { +static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top, + u32 entry_point, u32 arg) { + context = {}; + context.cpu_registers[0] = arg; + context.cpu_registers[15] = entry_point; + context.cpu_registers[13] = stack_top; +} + +static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, VAddr stack_top, + VAddr entry_point, u64 arg) { context = {}; context.cpu_registers[0] = arg; context.pc = entry_point; @@ -198,9 +199,9 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::strin thread->owner_process->RegisterThread(thread.get()); - // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used - // to initialize the context - ResetThreadContext(thread->context, stack_top, entry_point, arg); + ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top), + static_cast<u32>(entry_point), static_cast<u32>(arg)); + ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); return MakeResult<std::shared_ptr<Thread>>(std::move(thread)); } @@ -213,11 +214,13 @@ void Thread::SetPriority(u32 priority) { } void Thread::SetWaitSynchronizationResult(ResultCode result) { - context.cpu_registers[0] = result.raw; + context_32.cpu_registers[0] = result.raw; + context_64.cpu_registers[0] = result.raw; } void Thread::SetWaitSynchronizationOutput(s32 output) { - context.cpu_registers[1] = output; + context_32.cpu_registers[1] = output; + context_64.cpu_registers[1] = output; } s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 129e7858a..23fdef8a4 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -102,7 +102,8 @@ public: using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>; - using ThreadContext = Core::ARM_Interface::ThreadContext; + using ThreadContext32 = Core::ARM_Interface::ThreadContext32; + using ThreadContext64 = Core::ARM_Interface::ThreadContext64; using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>; @@ -273,12 +274,20 @@ public: return status == ThreadStatus::WaitSynch; } - ThreadContext& GetContext() { - return context; + ThreadContext32& GetContext32() { + return context_32; } - const ThreadContext& GetContext() const { - return context; + const ThreadContext32& GetContext32() const { + return context_32; + } + + ThreadContext64& GetContext64() { + return context_64; + } + + const ThreadContext64& GetContext64() const { + return context_64; } ThreadStatus GetStatus() const { @@ -466,7 +475,8 @@ private: void AdjustSchedulingOnPriority(u32 old_priority); void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core); - Core::ARM_Interface::ThreadContext context{}; + ThreadContext32 context_32{}; + ThreadContext64 context_64{}; u64 thread_id = 0; diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 134152210..437bc5dee 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -191,8 +191,6 @@ void NVFlinger::Compose() { // Search for a queued buffer and acquire it auto buffer = buffer_queue.AcquireBuffer(); - MicroProfileFlip(); - if (!buffer) { continue; } @@ -206,6 +204,8 @@ void NVFlinger::Compose() { gpu.WaitFence(fence.id, fence.value); } + MicroProfileFlip(); + // Now send the buffer to the GPU for drawing. // TODO(Subv): Support more than just disp0. The display device selection is probably based // on which display we're drawing (Default, Internal, External, etc) diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 5bcc0b588..9e12c76fc 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -111,6 +111,14 @@ void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { rb.PushEnum(available_language_codes[Settings::values.language_index]); } +void SET::GetRegionCode(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(Settings::values.region_index); +} + SET::SET() : ServiceFramework("set") { // clang-format off static const FunctionInfo functions[] = { @@ -118,7 +126,7 @@ SET::SET() : ServiceFramework("set") { {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, {2, &SET::MakeLanguageCode, "MakeLanguageCode"}, {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, - {4, nullptr, "GetRegionCode"}, + {4, &SET::GetRegionCode, "GetRegionCode"}, {5, &SET::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, {7, nullptr, "GetKeyCodeMap"}, diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index b154e08aa..6084b345d 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h @@ -43,6 +43,7 @@ private: void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx); void GetQuestFlag(Kernel::HLERequestContext& ctx); + void GetRegionCode(Kernel::HLERequestContext& ctx); }; } // namespace Service::Set diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp index 57b1a2bca..78d4acd95 100644 --- a/src/core/hle/service/time/time_zone_content_manager.cpp +++ b/src/core/hle/service/time/time_zone_content_manager.cpp @@ -53,7 +53,7 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) { return {}; } - std::vector<char> raw_data(binary_list->GetSize()); + std::vector<char> raw_data(binary_list->GetSize() + 1); binary_list->ReadBytes<char>(raw_data.data(), binary_list->GetSize()); std::stringstream data_stream{raw_data.data()}; |