summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/kernel.cpp4
-rw-r--r--src/core/hle/kernel/physical_core.cpp19
-rw-r--r--src/core/hle/kernel/physical_core.h6
-rw-r--r--src/core/hle/kernel/process.cpp3
-rw-r--r--src/core/hle/kernel/scheduler.cpp21
-rw-r--r--src/core/hle/kernel/scheduler.h3
-rw-r--r--src/core/hle/kernel/svc.cpp329
-rw-r--r--src/core/hle/kernel/svc_wrap.h158
-rw-r--r--src/core/hle/kernel/thread.cpp31
-rw-r--r--src/core/hle/kernel/thread.h22
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp4
-rw-r--r--src/core/hle/service/set/set.cpp10
-rw-r--r--src/core/hle/service/set/set.h1
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.cpp2
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, &param).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, &param_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, &param_1, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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)), &param_1, &param_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, &param_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, &param_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, &param_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, &param_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, &param_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, &param_1, &param_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, &param_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, &param_1, &param_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), &param_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()};