summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/renderer/adsp/audio_renderer.cpp2
-rw-r--r--src/audio_core/renderer/command/command_buffer.cpp4
-rw-r--r--src/audio_core/renderer/command/command_generator.cpp2
-rw-r--r--src/audio_core/renderer/command/effect/aux_.cpp130
-rw-r--r--src/audio_core/renderer/command/effect/biquad_filter.cpp38
-rw-r--r--src/audio_core/renderer/command/effect/i3dl2_reverb.cpp8
-rw-r--r--src/audio_core/renderer/command/effect/reverb.cpp8
-rw-r--r--src/audio_core/renderer/command/resample/upsample.cpp12
-rw-r--r--src/audio_core/renderer/system.cpp2
-rw-r--r--src/audio_core/renderer/system_manager.cpp2
-rw-r--r--src/audio_core/renderer/voice/voice_state.h8
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp20
-rw-r--r--src/audio_core/sink/sink_stream.cpp8
-rw-r--r--src/common/settings.cpp4
-rw-r--r--src/common/settings.h1
-rw-r--r--src/core/CMakeLists.txt19
-rw-r--r--src/core/arm/arm_interface.cpp6
-rw-r--r--src/core/arm/arm_interface.h1
-rw-r--r--src/core/core.cpp42
-rw-r--r--src/core/core.h18
-rw-r--r--src/core/core_timing.cpp2
-rw-r--r--src/core/debugger/gdbstub.cpp28
-rw-r--r--src/core/debugger/gdbstub_arch.cpp14
-rw-r--r--src/core/debugger/gdbstub_arch.h6
-rw-r--r--src/core/file_sys/ips_layer.cpp8
-rw-r--r--src/core/file_sys/registered_cache.cpp2
-rw-r--r--src/core/file_sys/savedata_factory.cpp2
-rw-r--r--src/core/hid/emulated_console.cpp3
-rw-r--r--src/core/hid/emulated_controller.cpp22
-rw-r--r--src/core/hid/emulated_controller.h5
-rw-r--r--src/core/hid/emulated_devices.cpp3
-rw-r--r--src/core/hid/hid_types.h7
-rw-r--r--src/core/hid/motion_input.cpp12
-rw-r--r--src/core/hid/motion_input.h15
-rw-r--r--src/core/hle/ipc_helpers.h2
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp2
-rw-r--r--src/core/hle/kernel/k_client_port.cpp3
-rw-r--r--src/core/hle/kernel/k_code_memory.cpp8
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp8
-rw-r--r--src/core/hle/kernel/k_handle_table.h3
-rw-r--r--src/core/hle/kernel/k_interrupt_manager.cpp2
-rw-r--r--src/core/hle/kernel/k_object_name.cpp102
-rw-r--r--src/core/hle/kernel/k_object_name.h86
-rw-r--r--src/core/hle/kernel/k_process.cpp2
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp14
-rw-r--r--src/core/hle/kernel/k_session.cpp3
-rw-r--r--src/core/hle/kernel/k_thread.cpp8
-rw-r--r--src/core/hle/kernel/k_thread.h2
-rw-r--r--src/core/hle/kernel/k_transfer_memory.cpp2
-rw-r--r--src/core/hle/kernel/kernel.cpp68
-rw-r--r--src/core/hle/kernel/kernel.h38
-rw-r--r--src/core/hle/kernel/svc.cpp4844
-rw-r--r--src/core/hle/kernel/svc.h664
-rw-r--r--src/core/hle/kernel/svc/svc_activity.cpp30
-rw-r--r--src/core/hle/kernel/svc/svc_address_arbiter.cpp29
-rw-r--r--src/core/hle/kernel/svc/svc_address_translation.cpp46
-rw-r--r--src/core/hle/kernel/svc/svc_cache.cpp71
-rw-r--r--src/core/hle/kernel/svc/svc_code_memory.cpp57
-rw-r--r--src/core/hle/kernel/svc/svc_condition_variable.cpp30
-rw-r--r--src/core/hle/kernel/svc/svc_debug.cpp190
-rw-r--r--src/core/hle/kernel/svc/svc_debug_string.cpp16
-rw-r--r--src/core/hle/kernel/svc/svc_device_address_space.cpp254
-rw-r--r--src/core/hle/kernel/svc/svc_event.cpp43
-rw-r--r--src/core/hle/kernel/svc/svc_exception.cpp32
-rw-r--r--src/core/hle/kernel/svc/svc_info.cpp53
-rw-r--r--src/core/hle/kernel/svc/svc_insecure_memory.cpp35
-rw-r--r--src/core/hle/kernel/svc/svc_interrupt_event.cpp21
-rw-r--r--src/core/hle/kernel/svc/svc_io_pool.cpp67
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp103
-rw-r--r--src/core/hle/kernel/svc/svc_kernel_debug.cpp26
-rw-r--r--src/core/hle/kernel/svc/svc_light_ipc.cpp69
-rw-r--r--src/core/hle/kernel/svc/svc_lock.cpp25
-rw-r--r--src/core/hle/kernel/svc/svc_memory.cpp56
-rw-r--r--src/core/hle/kernel/svc/svc_physical_memory.cpp80
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp105
-rw-r--r--src/core/hle/kernel/svc/svc_power_management.cpp17
-rw-r--r--src/core/hle/kernel/svc/svc_process.cpp126
-rw-r--r--src/core/hle/kernel/svc/svc_process_memory.cpp60
-rw-r--r--src/core/hle/kernel/svc/svc_processor.cpp10
-rw-r--r--src/core/hle/kernel/svc/svc_query_memory.cpp56
-rw-r--r--src/core/hle/kernel/svc/svc_register.cpp23
-rw-r--r--src/core/hle/kernel/svc/svc_resource_limit.cpp80
-rw-r--r--src/core/hle/kernel/svc/svc_secure_monitor_call.cpp49
-rw-r--r--src/core/hle/kernel/svc/svc_session.cpp31
-rw-r--r--src/core/hle/kernel/svc/svc_shared_memory.cpp45
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp70
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp193
-rw-r--r--src/core/hle/kernel/svc/svc_thread_profiler.cpp56
-rw-r--r--src/core/hle/kernel/svc/svc_tick.cpp14
-rw-r--r--src/core/hle/kernel/svc/svc_transfer_memory.cpp48
-rw-r--r--src/core/hle/kernel/svc_generator.py716
-rw-r--r--src/core/hle/kernel/svc_results.h1
-rw-r--r--src/core/hle/kernel/svc_types.h11
-rw-r--r--src/core/hle/kernel/svc_version.h4
-rw-r--r--src/core/hle/kernel/svc_wrap.h733
-rw-r--r--src/core/hle/service/acc/acc.cpp4
-rw-r--r--src/core/hle/service/am/am.cpp26
-rw-r--r--src/core/hle/service/am/applets/applet_error.cpp2
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.cpp2
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.cpp2
-rw-r--r--src/core/hle/service/am/tcap.cpp22
-rw-r--r--src/core/hle/service/am/tcap.h20
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp6
-rw-r--r--src/core/hle/service/apm/apm.cpp2
-rw-r--r--src/core/hle/service/apm/apm_controller.cpp2
-rw-r--r--src/core/hle/service/audio/auddbg.cpp21
-rw-r--r--src/core/hle/service/audio/auddbg.h20
-rw-r--r--src/core/hle/service/audio/audin_a.cpp23
-rw-r--r--src/core/hle/service/audio/audin_a.h20
-rw-r--r--src/core/hle/service/audio/audio.cpp14
-rw-r--r--src/core/hle/service/audio/audout_a.cpp25
-rw-r--r--src/core/hle/service/audio/audout_a.h20
-rw-r--r--src/core/hle/service/audio/audren_a.cpp27
-rw-r--r--src/core/hle/service/audio/audren_a.h20
-rw-r--r--src/core/hle/service/audio/audren_u.cpp2
-rw-r--r--src/core/hle/service/audio/codecctl.cpp29
-rw-r--r--src/core/hle/service/audio/codecctl.h20
-rw-r--r--src/core/hle/service/bcat/bcat_module.cpp10
-rw-r--r--src/core/hle/service/fatal/fatal.cpp2
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp4
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp5
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp7
-rw-r--r--src/core/hle/service/hid/controllers/npad.h14
-rw-r--r--src/core/hle/service/hid/hid.cpp28
-rw-r--r--src/core/hle/service/hid/hidbus.cpp4
-rw-r--r--src/core/hle/service/hid/irs.cpp8
-rw-r--r--src/core/hle/service/jit/jit.cpp4
-rw-r--r--src/core/hle/service/ldr/ldr.cpp13
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp2
-rw-r--r--src/core/hle/service/nvdrv/core/syncpoint_manager.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp4
-rw-r--r--src/core/hle/service/pctl/pctl_module.cpp2
-rw-r--r--src/core/hle/service/pcv/pcv.cpp28
-rw-r--r--src/core/hle/service/prepo/prepo.cpp4
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/sockets/ethc.cpp42
-rw-r--r--src/core/hle/service/sockets/ethc.h26
-rw-r--r--src/core/hle/service/sockets/sockets.cpp4
-rw-r--r--src/core/hle/service/time/time_zone_manager.cpp2
-rw-r--r--src/core/hle/service/wlan/wlan.cpp186
-rw-r--r--src/core/hle/service/wlan/wlan.h18
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/memory.cpp10
-rw-r--r--src/core/memory/cheat_engine.cpp6
-rw-r--r--src/core/reporter.cpp10
-rw-r--r--src/core/telemetry_session.cpp2
-rw-r--r--src/input_common/drivers/joycon.cpp51
-rw-r--r--src/input_common/drivers/joycon.h1
-rw-r--r--src/input_common/drivers/mouse.cpp67
-rw-r--r--src/input_common/drivers/mouse.h38
-rw-r--r--src/input_common/drivers/sdl_driver.cpp22
-rw-r--r--src/input_common/helpers/joycon_driver.cpp3
-rw-r--r--src/input_common/input_mapping.cpp4
-rw-r--r--src/shader_recompiler/backend/glsl/glsl_emit_context.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp2
-rw-r--r--src/shader_recompiler/host_translate_info.h1
-rw-r--r--src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp13
-rw-r--r--src/shader_recompiler/ir_opt/passes.h2
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h13
-rw-r--r--src/video_core/engines/maxwell_3d.cpp6
-rw-r--r--src/video_core/gpu.cpp2
-rw-r--r--src/video_core/gpu_thread.cpp6
-rw-r--r--src/video_core/gpu_thread.h8
-rw-r--r--src/video_core/host1x/codecs/codec.cpp2
-rw-r--r--src/video_core/host1x/vic.cpp14
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt2
-rw-r--r--src/video_core/host_shaders/convert_msaa_to_non_msaa.comp30
-rw-r--r--src/video_core/host_shaders/convert_non_msaa_to_msaa.comp29
-rw-r--r--src/video_core/memory_manager.h2
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h9
-rw-r--r--src/video_core/renderer_opengl/util_shaders.cpp33
-rw-r--r--src/video_core/renderer_opengl/util_shaders.h5
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp26
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_smaa.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h9
-rw-r--r--src/video_core/renderer_vulkan/vk_turbo_mode.cpp4
-rw-r--r--src/video_core/texture_cache/formatter.cpp3
-rw-r--r--src/video_core/texture_cache/texture_cache.h14
-rw-r--r--src/video_core/texture_cache/util.cpp5
-rw-r--r--src/video_core/textures/decoders.cpp2
-rw-r--r--src/yuzu/bootmanager.cpp32
-rw-r--r--src/yuzu/bootmanager.h2
-rw-r--r--src/yuzu/configuration/config.cpp3
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp2
-rw-r--r--src/yuzu/configuration/configure_input_advanced.ui22
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp2
-rw-r--r--src/yuzu/configuration/configure_ringcon.cpp2
-rw-r--r--src/yuzu/game_list.cpp1
-rw-r--r--src/yuzu/game_list.h1
-rw-r--r--src/yuzu/main.cpp28
-rw-r--r--src/yuzu_cmd/config.cpp1
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp8
-rw-r--r--src/yuzu_cmd/yuzu.cpp2
201 files changed, 8690 insertions, 2779 deletions
diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/renderer/adsp/audio_renderer.cpp
index d982ef630..78c15629b 100644
--- a/src/audio_core/renderer/adsp/audio_renderer.cpp
+++ b/src/audio_core/renderer/adsp/audio_renderer.cpp
@@ -132,7 +132,7 @@ void AudioRenderer::CreateSinkStreams() {
132} 132}
133 133
134void AudioRenderer::ThreadFunc() { 134void AudioRenderer::ThreadFunc() {
135 constexpr char name[]{"AudioRenderer"}; 135 static constexpr char name[]{"AudioRenderer"};
136 MicroProfileOnThreadCreate(name); 136 MicroProfileOnThreadCreate(name);
137 Common::SetCurrentThreadName(name); 137 Common::SetCurrentThreadName(name);
138 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); 138 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp
index 8c6fe97e7..0bd418306 100644
--- a/src/audio_core/renderer/command/command_buffer.cpp
+++ b/src/audio_core/renderer/command/command_buffer.cpp
@@ -251,8 +251,8 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
251 251
252 const auto& parameter{ 252 const auto& parameter{
253 *reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())}; 253 *reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
254 const auto state{ 254 const auto state{reinterpret_cast<VoiceState::BiquadFilterState*>(
255 reinterpret_cast<VoiceState::BiquadFilterState*>(effect_info.GetStateBuffer())}; 255 effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))};
256 256
257 cmd.input = buffer_offset + parameter.inputs[channel]; 257 cmd.input = buffer_offset + parameter.inputs[channel];
258 cmd.output = buffer_offset + parameter.outputs[channel]; 258 cmd.output = buffer_offset + parameter.outputs[channel];
diff --git a/src/audio_core/renderer/command/command_generator.cpp b/src/audio_core/renderer/command/command_generator.cpp
index 2ea50d128..fba84c7bd 100644
--- a/src/audio_core/renderer/command/command_generator.cpp
+++ b/src/audio_core/renderer/command/command_generator.cpp
@@ -46,7 +46,7 @@ void CommandGenerator::GenerateDataSourceCommand(VoiceInfo& voice_info,
46 while (destination != nullptr) { 46 while (destination != nullptr) {
47 if (destination->IsConfigured()) { 47 if (destination->IsConfigured()) {
48 auto mix_id{destination->GetMixId()}; 48 auto mix_id{destination->GetMixId()};
49 if (mix_id < mix_context.GetCount()) { 49 if (mix_id < mix_context.GetCount() && mix_id != UnusedSplitterId) {
50 auto mix_info{mix_context.GetInfo(mix_id)}; 50 auto mix_info{mix_context.GetInfo(mix_id)};
51 command_buffer.GenerateDepopPrepareCommand( 51 command_buffer.GenerateDepopPrepareCommand(
52 voice_info.node_id, voice_state, render_context.depop_buffer, 52 voice_info.node_id, voice_state, render_context.depop_buffer,
diff --git a/src/audio_core/renderer/command/effect/aux_.cpp b/src/audio_core/renderer/command/effect/aux_.cpp
index e76db893f..c5650effa 100644
--- a/src/audio_core/renderer/command/effect/aux_.cpp
+++ b/src/audio_core/renderer/command/effect/aux_.cpp
@@ -4,6 +4,7 @@
4#include "audio_core/renderer/adsp/command_list_processor.h" 4#include "audio_core/renderer/adsp/command_list_processor.h"
5#include "audio_core/renderer/command/effect/aux_.h" 5#include "audio_core/renderer/command/effect/aux_.h"
6#include "audio_core/renderer/effect/aux_.h" 6#include "audio_core/renderer/effect/aux_.h"
7#include "core/core.h"
7#include "core/memory.h" 8#include "core/memory.h"
8 9
9namespace AudioCore::AudioRenderer { 10namespace AudioCore::AudioRenderer {
@@ -19,10 +20,24 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
19 return; 20 return;
20 } 21 }
21 22
22 auto info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(aux_info))}; 23 AuxInfo::AuxInfoDsp info{};
23 info->read_offset = 0; 24 auto info_ptr{&info};
24 info->write_offset = 0; 25 bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <=
25 info->total_sample_count = 0; 26 (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))};
27
28 if (host_safe) [[likely]] {
29 info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info);
30 } else {
31 memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
32 }
33
34 info_ptr->read_offset = 0;
35 info_ptr->write_offset = 0;
36 info_ptr->total_sample_count = 0;
37
38 if (!host_safe) [[unlikely]] {
39 memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
40 }
26} 41}
27 42
28/** 43/**
@@ -40,11 +55,10 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
40 * @param update_count - If non-zero, send_info_ will be updated. 55 * @param update_count - If non-zero, send_info_ will be updated.
41 * @return Number of samples written. 56 * @return Number of samples written.
42 */ 57 */
43static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_info_, 58static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
44 [[maybe_unused]] u32 sample_count, const CpuAddr send_buffer, 59 [[maybe_unused]] u32 sample_count, CpuAddr send_buffer, u32 count_max,
45 const u32 count_max, std::span<const s32> input, 60 std::span<const s32> input, u32 write_count_, u32 write_offset,
46 const u32 write_count_, const u32 write_offset, 61 u32 update_count) {
47 const u32 update_count) {
48 if (write_count_ > count_max) { 62 if (write_count_ > count_max) {
49 LOG_ERROR(Service_Audio, 63 LOG_ERROR(Service_Audio,
50 "write_count must be smaller than count_max! write_count {}, count_max {}", 64 "write_count must be smaller than count_max! write_count {}, count_max {}",
@@ -52,6 +66,11 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
52 return 0; 66 return 0;
53 } 67 }
54 68
69 if (send_info_ == 0) {
70 LOG_ERROR(Service_Audio, "send_info_ is 0!");
71 return 0;
72 }
73
55 if (input.empty()) { 74 if (input.empty()) {
56 LOG_ERROR(Service_Audio, "input buffer is empty!"); 75 LOG_ERROR(Service_Audio, "input buffer is empty!");
57 return 0; 76 return 0;
@@ -67,33 +86,47 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
67 } 86 }
68 87
69 AuxInfo::AuxInfoDsp send_info{}; 88 AuxInfo::AuxInfoDsp send_info{};
70 memory.ReadBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp)); 89 auto send_ptr = &send_info;
90 bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <=
91 (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
71 92
72 u32 target_write_offset{send_info.write_offset + write_offset}; 93 if (host_safe) [[likely]] {
73 if (target_write_offset > count_max || write_count_ == 0) { 94 send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_);
95 } else {
96 memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
97 }
98
99 u32 target_write_offset{send_ptr->write_offset + write_offset};
100 if (target_write_offset > count_max) {
74 return 0; 101 return 0;
75 } 102 }
76 103
77 u32 write_count{write_count_}; 104 u32 write_count{write_count_};
78 u32 write_pos{0}; 105 u32 read_pos{0};
79 while (write_count > 0) { 106 while (write_count > 0) {
80 u32 to_write{std::min(count_max - target_write_offset, write_count)}; 107 u32 to_write{std::min(count_max - target_write_offset, write_count)};
81 108 const auto write_addr = send_buffer + target_write_offset * sizeof(s32);
82 if (to_write > 0) { 109 bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <=
110 (Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))};
111 if (write_safe) [[likely]] {
112 auto ptr = memory.GetPointer(write_addr);
113 std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32));
114 } else {
83 memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32), 115 memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32),
84 &input[write_pos], to_write * sizeof(s32)); 116 &input[read_pos], to_write * sizeof(s32));
85 } 117 }
86
87 target_write_offset = (target_write_offset + to_write) % count_max; 118 target_write_offset = (target_write_offset + to_write) % count_max;
88 write_count -= to_write; 119 write_count -= to_write;
89 write_pos += to_write; 120 read_pos += to_write;
90 } 121 }
91 122
92 if (update_count) { 123 if (update_count) {
93 send_info.write_offset = (send_info.write_offset + update_count) % count_max; 124 send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max;
94 } 125 }
95 126
96 memory.WriteBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp)); 127 if (!host_safe) [[unlikely]] {
128 memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
129 }
97 130
98 return write_count_; 131 return write_count_;
99} 132}
@@ -102,7 +135,7 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
102 * Read the given memory at return_buffer into the output mix buffer, and update return_info_ if 135 * Read the given memory at return_buffer into the output mix buffer, and update return_info_ if
103 * update_count is set, to notify the game that an update happened. 136 * update_count is set, to notify the game that an update happened.
104 * 137 *
105 * @param memory - Core memory for writing. 138 * @param memory - Core memory for reading.
106 * @param return_info_ - Meta information for where to read the mix buffer. 139 * @param return_info_ - Meta information for where to read the mix buffer.
107 * @param return_buffer - Memory address to read the samples from. 140 * @param return_buffer - Memory address to read the samples from.
108 * @param count_max - Maximum number of samples in the receiving buffer. 141 * @param count_max - Maximum number of samples in the receiving buffer.
@@ -112,16 +145,21 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
112 * @param update_count - If non-zero, send_info_ will be updated. 145 * @param update_count - If non-zero, send_info_ will be updated.
113 * @return Number of samples read. 146 * @return Number of samples read.
114 */ 147 */
115static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_info_, 148static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
116 const CpuAddr return_buffer, const u32 count_max, std::span<s32> output, 149 CpuAddr return_buffer, u32 count_max, std::span<s32> output,
117 const u32 count_, const u32 read_offset, const u32 update_count) { 150 u32 read_count_, u32 read_offset, u32 update_count) {
118 if (count_max == 0) { 151 if (count_max == 0) {
119 return 0; 152 return 0;
120 } 153 }
121 154
122 if (count_ > count_max) { 155 if (read_count_ > count_max) {
123 LOG_ERROR(Service_Audio, "count must be smaller than count_max! count {}, count_max {}", 156 LOG_ERROR(Service_Audio, "count must be smaller than count_max! count {}, count_max {}",
124 count_, count_max); 157 read_count_, count_max);
158 return 0;
159 }
160
161 if (return_info_ == 0) {
162 LOG_ERROR(Service_Audio, "return_info_ is 0!");
125 return 0; 163 return 0;
126 } 164 }
127 165
@@ -136,35 +174,49 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_i
136 } 174 }
137 175
138 AuxInfo::AuxInfoDsp return_info{}; 176 AuxInfo::AuxInfoDsp return_info{};
139 memory.ReadBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp)); 177 auto return_ptr = &return_info;
178 bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <=
179 (Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
180
181 if (host_safe) [[likely]] {
182 return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_);
183 } else {
184 memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
185 }
140 186
141 u32 target_read_offset{return_info.read_offset + read_offset}; 187 u32 target_read_offset{return_ptr->read_offset + read_offset};
142 if (target_read_offset > count_max) { 188 if (target_read_offset > count_max) {
143 return 0; 189 return 0;
144 } 190 }
145 191
146 u32 read_count{count_}; 192 u32 read_count{read_count_};
147 u32 read_pos{0}; 193 u32 write_pos{0};
148 while (read_count > 0) { 194 while (read_count > 0) {
149 u32 to_read{std::min(count_max - target_read_offset, read_count)}; 195 u32 to_read{std::min(count_max - target_read_offset, read_count)};
150 196 const auto read_addr = return_buffer + target_read_offset * sizeof(s32);
151 if (to_read > 0) { 197 bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <=
198 (Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))};
199 if (read_safe) [[likely]] {
200 auto ptr = memory.GetPointer(read_addr);
201 std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32));
202 } else {
152 memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32), 203 memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32),
153 &output[read_pos], to_read * sizeof(s32)); 204 &output[write_pos], to_read * sizeof(s32));
154 } 205 }
155
156 target_read_offset = (target_read_offset + to_read) % count_max; 206 target_read_offset = (target_read_offset + to_read) % count_max;
157 read_count -= to_read; 207 read_count -= to_read;
158 read_pos += to_read; 208 write_pos += to_read;
159 } 209 }
160 210
161 if (update_count) { 211 if (update_count) {
162 return_info.read_offset = (return_info.read_offset + update_count) % count_max; 212 return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max;
163 } 213 }
164 214
165 memory.WriteBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp)); 215 if (!host_safe) [[unlikely]] {
216 memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
217 }
166 218
167 return count_; 219 return read_count_;
168} 220}
169 221
170void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor, 222void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
@@ -189,7 +241,7 @@ void AuxCommand::Process(const ADSP::CommandListProcessor& processor) {
189 update_count)}; 241 update_count)};
190 242
191 if (read != processor.sample_count) { 243 if (read != processor.sample_count) {
192 std::memset(&output_buffer[read], 0, processor.sample_count - read); 244 std::memset(&output_buffer[read], 0, (processor.sample_count - read) * sizeof(s32));
193 } 245 }
194 } else { 246 } else {
195 ResetAuxBufferDsp(*processor.memory, send_buffer_info); 247 ResetAuxBufferDsp(*processor.memory, send_buffer_info);
diff --git a/src/audio_core/renderer/command/effect/biquad_filter.cpp b/src/audio_core/renderer/command/effect/biquad_filter.cpp
index edb30ce72..dea6423dc 100644
--- a/src/audio_core/renderer/command/effect/biquad_filter.cpp
+++ b/src/audio_core/renderer/command/effect/biquad_filter.cpp
@@ -4,6 +4,7 @@
4#include "audio_core/renderer/adsp/command_list_processor.h" 4#include "audio_core/renderer/adsp/command_list_processor.h"
5#include "audio_core/renderer/command/effect/biquad_filter.h" 5#include "audio_core/renderer/command/effect/biquad_filter.h"
6#include "audio_core/renderer/voice/voice_state.h" 6#include "audio_core/renderer/voice/voice_state.h"
7#include "common/bit_cast.h"
7 8
8namespace AudioCore::AudioRenderer { 9namespace AudioCore::AudioRenderer {
9/** 10/**
@@ -19,21 +20,21 @@ namespace AudioCore::AudioRenderer {
19void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input, 20void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
20 std::array<s16, 3>& b_, std::array<s16, 2>& a_, 21 std::array<s16, 3>& b_, std::array<s16, 2>& a_,
21 VoiceState::BiquadFilterState& state, const u32 sample_count) { 22 VoiceState::BiquadFilterState& state, const u32 sample_count) {
22 constexpr s64 min{std::numeric_limits<s32>::min()}; 23 constexpr f64 min{std::numeric_limits<s32>::min()};
23 constexpr s64 max{std::numeric_limits<s32>::max()}; 24 constexpr f64 max{std::numeric_limits<s32>::max()};
24 std::array<f64, 3> b{Common::FixedPoint<50, 14>::from_base(b_[0]).to_double(), 25 std::array<f64, 3> b{Common::FixedPoint<50, 14>::from_base(b_[0]).to_double(),
25 Common::FixedPoint<50, 14>::from_base(b_[1]).to_double(), 26 Common::FixedPoint<50, 14>::from_base(b_[1]).to_double(),
26 Common::FixedPoint<50, 14>::from_base(b_[2]).to_double()}; 27 Common::FixedPoint<50, 14>::from_base(b_[2]).to_double()};
27 std::array<f64, 2> a{Common::FixedPoint<50, 14>::from_base(a_[0]).to_double(), 28 std::array<f64, 2> a{Common::FixedPoint<50, 14>::from_base(a_[0]).to_double(),
28 Common::FixedPoint<50, 14>::from_base(a_[1]).to_double()}; 29 Common::FixedPoint<50, 14>::from_base(a_[1]).to_double()};
29 std::array<f64, 4> s{state.s0.to_double(), state.s1.to_double(), state.s2.to_double(), 30 std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1),
30 state.s3.to_double()}; 31 Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)};
31 32
32 for (u32 i = 0; i < sample_count; i++) { 33 for (u32 i = 0; i < sample_count; i++) {
33 f64 in_sample{static_cast<f64>(input[i])}; 34 f64 in_sample{static_cast<f64>(input[i])};
34 auto sample{in_sample * b[0] + s[0] * b[1] + s[1] * b[2] + s[2] * a[0] + s[3] * a[1]}; 35 auto sample{in_sample * b[0] + s[0] * b[1] + s[1] * b[2] + s[2] * a[0] + s[3] * a[1]};
35 36
36 output[i] = static_cast<s32>(std::clamp(static_cast<s64>(sample), min, max)); 37 output[i] = static_cast<s32>(std::clamp(sample, min, max));
37 38
38 s[1] = s[0]; 39 s[1] = s[0];
39 s[0] = in_sample; 40 s[0] = in_sample;
@@ -41,10 +42,10 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
41 s[2] = sample; 42 s[2] = sample;
42 } 43 }
43 44
44 state.s0 = s[0]; 45 state.s0 = Common::BitCast<s64>(s[0]);
45 state.s1 = s[1]; 46 state.s1 = Common::BitCast<s64>(s[1]);
46 state.s2 = s[2]; 47 state.s2 = Common::BitCast<s64>(s[2]);
47 state.s3 = s[3]; 48 state.s3 = Common::BitCast<s64>(s[3]);
48} 49}
49 50
50/** 51/**
@@ -58,29 +59,20 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
58 * @param sample_count - Number of samples to process. 59 * @param sample_count - Number of samples to process.
59 */ 60 */
60static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> input, 61static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> input,
61 std::array<s16, 3>& b_, std::array<s16, 2>& a_, 62 std::array<s16, 3>& b, std::array<s16, 2>& a,
62 VoiceState::BiquadFilterState& state, const u32 sample_count) { 63 VoiceState::BiquadFilterState& state, const u32 sample_count) {
63 constexpr s64 min{std::numeric_limits<s32>::min()}; 64 constexpr s64 min{std::numeric_limits<s32>::min()};
64 constexpr s64 max{std::numeric_limits<s32>::max()}; 65 constexpr s64 max{std::numeric_limits<s32>::max()};
65 std::array<Common::FixedPoint<50, 14>, 3> b{
66 Common::FixedPoint<50, 14>::from_base(b_[0]),
67 Common::FixedPoint<50, 14>::from_base(b_[1]),
68 Common::FixedPoint<50, 14>::from_base(b_[2]),
69 };
70 std::array<Common::FixedPoint<50, 14>, 3> a{
71 Common::FixedPoint<50, 14>::from_base(a_[0]),
72 Common::FixedPoint<50, 14>::from_base(a_[1]),
73 };
74 66
75 for (u32 i = 0; i < sample_count; i++) { 67 for (u32 i = 0; i < sample_count; i++) {
76 s64 in_sample{input[i]}; 68 const s64 in_sample{input[i]};
77 auto sample{in_sample * b[0] + state.s0}; 69 const s64 sample{in_sample * b[0] + state.s0};
78 const auto out_sample{std::clamp(sample.to_long(), min, max)}; 70 const s64 out_sample{std::clamp<s64>((sample + (1 << 13)) >> 14, min, max)};
79 71
80 output[i] = static_cast<s32>(out_sample); 72 output[i] = static_cast<s32>(out_sample);
81 73
82 state.s0 = state.s1 + b[1] * in_sample + a[0] * out_sample; 74 state.s0 = state.s1 + b[1] * in_sample + a[0] * out_sample;
83 state.s1 = 0 + b[2] * in_sample + a[1] * out_sample; 75 state.s1 = b[2] * in_sample + a[1] * out_sample;
84 } 76 }
85} 77}
86 78
diff --git a/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp b/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
index 2187d8a65..27d8b9844 100644
--- a/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
+++ b/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
@@ -244,16 +244,16 @@ template <size_t NumChannels>
244static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state, 244static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state,
245 std::span<std::span<const s32>> inputs, 245 std::span<std::span<const s32>> inputs,
246 std::span<std::span<s32>> outputs, const u32 sample_count) { 246 std::span<std::span<s32>> outputs, const u32 sample_count) {
247 constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{ 247 static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249 }; 249 };
250 constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{ 250 static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
251 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 251 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
252 }; 252 };
253 constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{ 253 static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
254 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3, 254 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3,
255 }; 255 };
256 constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{ 256 static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
257 2, 0, 0, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 0, 0, 0, 0, 5, 5, 5, 257 2, 0, 0, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 0, 0, 0, 0, 5, 5, 5,
258 }; 258 };
259 259
diff --git a/src/audio_core/renderer/command/effect/reverb.cpp b/src/audio_core/renderer/command/effect/reverb.cpp
index 427489214..6fe844ff0 100644
--- a/src/audio_core/renderer/command/effect/reverb.cpp
+++ b/src/audio_core/renderer/command/effect/reverb.cpp
@@ -252,16 +252,16 @@ template <size_t NumChannels>
252static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state, 252static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
253 std::vector<std::span<const s32>>& inputs, 253 std::vector<std::span<const s32>>& inputs,
254 std::vector<std::span<s32>>& outputs, const u32 sample_count) { 254 std::vector<std::span<s32>>& outputs, const u32 sample_count) {
255 constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{ 255 static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 }; 257 };
258 constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{ 258 static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
259 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 259 0, 0, 1, 1, 0, 1, 0, 0, 1, 1,
260 }; 260 };
261 constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{ 261 static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
262 0, 0, 1, 1, 0, 1, 2, 2, 3, 3, 262 0, 0, 1, 1, 0, 1, 2, 2, 3, 3,
263 }; 263 };
264 constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{ 264 static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
265 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 265 0, 0, 1, 1, 2, 2, 4, 4, 5, 5,
266 }; 266 };
267 267
diff --git a/src/audio_core/renderer/command/resample/upsample.cpp b/src/audio_core/renderer/command/resample/upsample.cpp
index 5f7db12ca..86ddee1a4 100644
--- a/src/audio_core/renderer/command/resample/upsample.cpp
+++ b/src/audio_core/renderer/command/resample/upsample.cpp
@@ -19,24 +19,24 @@ namespace AudioCore::AudioRenderer {
19static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input, 19static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
20 const u32 target_sample_count, const u32 source_sample_count, 20 const u32 target_sample_count, const u32 source_sample_count,
21 UpsamplerState* state) { 21 UpsamplerState* state) {
22 constexpr u32 WindowSize = 10; 22 static constexpr u32 WindowSize = 10;
23 constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{ 23 static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
24 0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f, 24 0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f,
25 -0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f, 25 -0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f,
26 }; 26 };
27 constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{ 27 static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
28 0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f, 28 0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f,
29 -0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f, 29 -0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f,
30 }; 30 };
31 constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{ 31 static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
32 0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f, 32 0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f,
33 -0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f, 33 -0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f,
34 }; 34 };
35 constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{ 35 static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
36 0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f, 36 0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f,
37 -0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f, 37 -0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f,
38 }; 38 };
39 constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{ 39 static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
40 0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f, 40 0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f,
41 -0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f, 41 -0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f,
42 }; 42 };
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 4fac30c7c..31cbee282 100644
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -127,7 +127,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
127 render_device = params.rendering_device; 127 render_device = params.rendering_device;
128 execution_mode = params.execution_mode; 128 execution_mode = params.execution_mode;
129 129
130 core.Memory().ZeroBlock(*core.Kernel().CurrentProcess(), transfer_memory->GetSourceAddress(), 130 core.Memory().ZeroBlock(*core.ApplicationProcess(), transfer_memory->GetSourceAddress(),
131 transfer_memory_size); 131 transfer_memory_size);
132 132
133 // Note: We're not actually using the transfer memory because it's a pain to code for. 133 // Note: We're not actually using the transfer memory because it's a pain to code for.
diff --git a/src/audio_core/renderer/system_manager.cpp b/src/audio_core/renderer/system_manager.cpp
index f66b2b890..ce631f810 100644
--- a/src/audio_core/renderer/system_manager.cpp
+++ b/src/audio_core/renderer/system_manager.cpp
@@ -94,7 +94,7 @@ bool SystemManager::Remove(System& system_) {
94} 94}
95 95
96void SystemManager::ThreadFunc() { 96void SystemManager::ThreadFunc() {
97 constexpr char name[]{"AudioRenderSystemManager"}; 97 static constexpr char name[]{"AudioRenderSystemManager"};
98 MicroProfileOnThreadCreate(name); 98 MicroProfileOnThreadCreate(name);
99 Common::SetCurrentThreadName(name); 99 Common::SetCurrentThreadName(name);
100 Common::SetCurrentThreadPriority(Common::ThreadPriority::High); 100 Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
diff --git a/src/audio_core/renderer/voice/voice_state.h b/src/audio_core/renderer/voice/voice_state.h
index d5497e2fb..ce947233f 100644
--- a/src/audio_core/renderer/voice/voice_state.h
+++ b/src/audio_core/renderer/voice/voice_state.h
@@ -19,10 +19,10 @@ struct VoiceState {
19 * State of the voice's biquad filter. 19 * State of the voice's biquad filter.
20 */ 20 */
21 struct BiquadFilterState { 21 struct BiquadFilterState {
22 Common::FixedPoint<50, 14> s0; 22 s64 s0;
23 Common::FixedPoint<50, 14> s1; 23 s64 s1;
24 Common::FixedPoint<50, 14> s2; 24 s64 s2;
25 Common::FixedPoint<50, 14> s3; 25 s64 s3;
26 }; 26 };
27 27
28 /** 28 /**
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index 32c1b1cb3..9133f5388 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
302 std::vector<std::string> device_list; 302 std::vector<std::string> device_list;
303 cubeb* ctx; 303 cubeb* ctx;
304 304
305#ifdef _WIN32
306 auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
307#endif
308
305 if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) { 309 if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
306 LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); 310 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
307 return {}; 311 return {};
308 } 312 }
309 313
314#ifdef _WIN32
315 if (SUCCEEDED(com_init_result)) {
316 CoUninitialize();
317 }
318#endif
319
310 auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT}; 320 auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT};
311 cubeb_device_collection collection; 321 cubeb_device_collection collection;
312 if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) { 322 if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) {
@@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
329u32 GetCubebLatency() { 339u32 GetCubebLatency() {
330 cubeb* ctx; 340 cubeb* ctx;
331 341
342#ifdef _WIN32
343 auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
344#endif
345
332 if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) { 346 if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
333 LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); 347 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
334 // Return a large latency so we choose SDL instead. 348 // Return a large latency so we choose SDL instead.
335 return 10000u; 349 return 10000u;
336 } 350 }
337 351
352#ifdef _WIN32
353 if (SUCCEEDED(com_init_result)) {
354 CoUninitialize();
355 }
356#endif
357
338 cubeb_stream_params params{}; 358 cubeb_stream_params params{};
339 params.rate = TargetSampleRate; 359 params.rate = TargetSampleRate;
340 params.channels = 2; 360 params.channels = 2;
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index 06c2a876e..39a21b0f0 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -35,7 +35,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
35 35
36 if (system_channels == 6 && device_channels == 2) { 36 if (system_channels == 6 && device_channels == 2) {
37 // We're given 6 channels, but our device only outputs 2, so downmix. 37 // We're given 6 channels, but our device only outputs 2, so downmix.
38 constexpr std::array<f32, 4> down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f}; 38 static constexpr std::array<f32, 4> down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f};
39 39
40 for (u32 read_index = 0, write_index = 0; read_index < samples.size(); 40 for (u32 read_index = 0, write_index = 0; read_index < samples.size();
41 read_index += system_channels, write_index += device_channels) { 41 read_index += system_channels, write_index += device_channels) {
@@ -202,7 +202,7 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
202 // If we're paused or going to shut down, we don't want to consume buffers as coretiming is 202 // If we're paused or going to shut down, we don't want to consume buffers as coretiming is
203 // paused and we'll desync, so just play silence. 203 // paused and we'll desync, so just play silence.
204 if (system.IsPaused() || system.IsShuttingDown()) { 204 if (system.IsPaused() || system.IsShuttingDown()) {
205 constexpr std::array<s16, 6> silence{}; 205 static constexpr std::array<s16, 6> silence{};
206 for (size_t i = frames_written; i < num_frames; i++) { 206 for (size_t i = frames_written; i < num_frames; i++) {
207 std::memcpy(&output_buffer[i * frame_size], &silence[0], frame_size_bytes); 207 std::memcpy(&output_buffer[i * frame_size], &silence[0], frame_size_bytes);
208 } 208 }
@@ -270,7 +270,7 @@ void SinkStream::Stall() {
270 if (stalled_lock) { 270 if (stalled_lock) {
271 return; 271 return;
272 } 272 }
273 stalled_lock = system.StallProcesses(); 273 stalled_lock = system.StallApplication();
274} 274}
275 275
276void SinkStream::Unstall() { 276void SinkStream::Unstall() {
@@ -278,7 +278,7 @@ void SinkStream::Unstall() {
278 if (!stalled_lock) { 278 if (!stalled_lock) {
279 return; 279 return;
280 } 280 }
281 system.UnstallProcesses(); 281 system.UnstallApplication();
282 stalled_lock.unlock(); 282 stalled_lock.unlock();
283} 283}
284 284
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index b1a2aa8b2..49b41c158 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -199,7 +199,11 @@ void RestoreGlobalState(bool is_powered_on) {
199 values.renderer_backend.SetGlobal(true); 199 values.renderer_backend.SetGlobal(true);
200 values.renderer_force_max_clock.SetGlobal(true); 200 values.renderer_force_max_clock.SetGlobal(true);
201 values.vulkan_device.SetGlobal(true); 201 values.vulkan_device.SetGlobal(true);
202 values.fullscreen_mode.SetGlobal(true);
202 values.aspect_ratio.SetGlobal(true); 203 values.aspect_ratio.SetGlobal(true);
204 values.resolution_setup.SetGlobal(true);
205 values.scaling_filter.SetGlobal(true);
206 values.anti_aliasing.SetGlobal(true);
203 values.max_anisotropy.SetGlobal(true); 207 values.max_anisotropy.SetGlobal(true);
204 values.use_speed_limit.SetGlobal(true); 208 values.use_speed_limit.SetGlobal(true);
205 values.speed_limit.SetGlobal(true); 209 values.speed_limit.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index 64db66f37..6d27dd5ee 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -488,6 +488,7 @@ struct Values {
488 Setting<bool> enable_raw_input{false, "enable_raw_input"}; 488 Setting<bool> enable_raw_input{false, "enable_raw_input"};
489 Setting<bool> controller_navigation{true, "controller_navigation"}; 489 Setting<bool> controller_navigation{true, "controller_navigation"};
490 Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"}; 490 Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
491 Setting<bool> enable_procon_driver{false, "enable_procon_driver"};
491 492
492 SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"}; 493 SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
493 SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; 494 SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f16072e6c..ff5502d87 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -225,6 +225,8 @@ add_library(core STATIC
225 hle/kernel/k_memory_manager.h 225 hle/kernel/k_memory_manager.h
226 hle/kernel/k_memory_region.h 226 hle/kernel/k_memory_region.h
227 hle/kernel/k_memory_region_type.h 227 hle/kernel/k_memory_region_type.h
228 hle/kernel/k_object_name.cpp
229 hle/kernel/k_object_name.h
228 hle/kernel/k_page_bitmap.h 230 hle/kernel/k_page_bitmap.h
229 hle/kernel/k_page_buffer.cpp 231 hle/kernel/k_page_buffer.cpp
230 hle/kernel/k_page_buffer.h 232 hle/kernel/k_page_buffer.h
@@ -310,6 +312,7 @@ add_library(core STATIC
310 hle/kernel/svc/svc_event.cpp 312 hle/kernel/svc/svc_event.cpp
311 hle/kernel/svc/svc_exception.cpp 313 hle/kernel/svc/svc_exception.cpp
312 hle/kernel/svc/svc_info.cpp 314 hle/kernel/svc/svc_info.cpp
315 hle/kernel/svc/svc_insecure_memory.cpp
313 hle/kernel/svc/svc_interrupt_event.cpp 316 hle/kernel/svc/svc_interrupt_event.cpp
314 hle/kernel/svc/svc_io_pool.cpp 317 hle/kernel/svc/svc_io_pool.cpp
315 hle/kernel/svc/svc_ipc.cpp 318 hle/kernel/svc/svc_ipc.cpp
@@ -383,8 +386,6 @@ add_library(core STATIC
383 hle/service/am/omm.h 386 hle/service/am/omm.h
384 hle/service/am/spsm.cpp 387 hle/service/am/spsm.cpp
385 hle/service/am/spsm.h 388 hle/service/am/spsm.h
386 hle/service/am/tcap.cpp
387 hle/service/am/tcap.h
388 hle/service/aoc/aoc_u.cpp 389 hle/service/aoc/aoc_u.cpp
389 hle/service/aoc/aoc_u.h 390 hle/service/aoc/aoc_u.h
390 hle/service/apm/apm.cpp 391 hle/service/apm/apm.cpp
@@ -395,28 +396,18 @@ add_library(core STATIC
395 hle/service/apm/apm_interface.h 396 hle/service/apm/apm_interface.h
396 hle/service/audio/audctl.cpp 397 hle/service/audio/audctl.cpp
397 hle/service/audio/audctl.h 398 hle/service/audio/audctl.h
398 hle/service/audio/auddbg.cpp
399 hle/service/audio/auddbg.h
400 hle/service/audio/audin_a.cpp
401 hle/service/audio/audin_a.h
402 hle/service/audio/audin_u.cpp 399 hle/service/audio/audin_u.cpp
403 hle/service/audio/audin_u.h 400 hle/service/audio/audin_u.h
404 hle/service/audio/audio.cpp 401 hle/service/audio/audio.cpp
405 hle/service/audio/audio.h 402 hle/service/audio/audio.h
406 hle/service/audio/audout_a.cpp
407 hle/service/audio/audout_a.h
408 hle/service/audio/audout_u.cpp 403 hle/service/audio/audout_u.cpp
409 hle/service/audio/audout_u.h 404 hle/service/audio/audout_u.h
410 hle/service/audio/audrec_a.cpp 405 hle/service/audio/audrec_a.cpp
411 hle/service/audio/audrec_a.h 406 hle/service/audio/audrec_a.h
412 hle/service/audio/audrec_u.cpp 407 hle/service/audio/audrec_u.cpp
413 hle/service/audio/audrec_u.h 408 hle/service/audio/audrec_u.h
414 hle/service/audio/audren_a.cpp
415 hle/service/audio/audren_a.h
416 hle/service/audio/audren_u.cpp 409 hle/service/audio/audren_u.cpp
417 hle/service/audio/audren_u.h 410 hle/service/audio/audren_u.h
418 hle/service/audio/codecctl.cpp
419 hle/service/audio/codecctl.h
420 hle/service/audio/errors.h 411 hle/service/audio/errors.h
421 hle/service/audio/hwopus.cpp 412 hle/service/audio/hwopus.cpp
422 hle/service/audio/hwopus.h 413 hle/service/audio/hwopus.h
@@ -711,8 +702,6 @@ add_library(core STATIC
711 hle/service/sm/sm_controller.h 702 hle/service/sm/sm_controller.h
712 hle/service/sockets/bsd.cpp 703 hle/service/sockets/bsd.cpp
713 hle/service/sockets/bsd.h 704 hle/service/sockets/bsd.h
714 hle/service/sockets/ethc.cpp
715 hle/service/sockets/ethc.h
716 hle/service/sockets/nsd.cpp 705 hle/service/sockets/nsd.cpp
717 hle/service/sockets/nsd.h 706 hle/service/sockets/nsd.h
718 hle/service/sockets/sfdnsres.cpp 707 hle/service/sockets/sfdnsres.cpp
@@ -779,8 +768,6 @@ add_library(core STATIC
779 hle/service/vi/vi_s.h 768 hle/service/vi/vi_s.h
780 hle/service/vi/vi_u.cpp 769 hle/service/vi/vi_u.cpp
781 hle/service/vi/vi_u.h 770 hle/service/vi/vi_u.h
782 hle/service/wlan/wlan.cpp
783 hle/service/wlan/wlan.h
784 internal_network/network.cpp 771 internal_network/network.cpp
785 internal_network/network.h 772 internal_network/network.h
786 internal_network/network_interface.cpp 773 internal_network/network_interface.cpp
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 8aa7b9641..4a331d4c1 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -43,9 +43,9 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
43 43
44 std::map<std::string, Symbols::Symbols> symbols; 44 std::map<std::string, Symbols::Symbols> symbols;
45 for (const auto& module : modules) { 45 for (const auto& module : modules) {
46 symbols.insert_or_assign(module.second, 46 symbols.insert_or_assign(
47 Symbols::GetSymbols(module.first, system.Memory(), 47 module.second, Symbols::GetSymbols(module.first, system.Memory(),
48 system.CurrentProcess()->Is64BitProcess())); 48 system.ApplicationProcess()->Is64BitProcess()));
49 } 49 }
50 50
51 for (auto& entry : out) { 51 for (auto& entry : out) {
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 7d62d030e..c40771c97 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -5,6 +5,7 @@
5 5
6#include <array> 6#include <array>
7#include <span> 7#include <span>
8#include <string>
8#include <vector> 9#include <vector>
9 10
10#include <dynarmic/interface/halt_reason.h> 11#include <dynarmic/interface/halt_reason.h>
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 47292cd78..fb9b25d12 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -186,7 +186,7 @@ struct System::Impl {
186 void Run() { 186 void Run() {
187 std::unique_lock<std::mutex> lk(suspend_guard); 187 std::unique_lock<std::mutex> lk(suspend_guard);
188 188
189 kernel.Suspend(false); 189 kernel.SuspendApplication(false);
190 core_timing.SyncPause(false); 190 core_timing.SyncPause(false);
191 is_paused.store(false, std::memory_order_relaxed); 191 is_paused.store(false, std::memory_order_relaxed);
192 } 192 }
@@ -195,7 +195,7 @@ struct System::Impl {
195 std::unique_lock<std::mutex> lk(suspend_guard); 195 std::unique_lock<std::mutex> lk(suspend_guard);
196 196
197 core_timing.SyncPause(true); 197 core_timing.SyncPause(true);
198 kernel.Suspend(true); 198 kernel.SuspendApplication(true);
199 is_paused.store(true, std::memory_order_relaxed); 199 is_paused.store(true, std::memory_order_relaxed);
200 } 200 }
201 201
@@ -203,17 +203,17 @@ struct System::Impl {
203 return is_paused.load(std::memory_order_relaxed); 203 return is_paused.load(std::memory_order_relaxed);
204 } 204 }
205 205
206 std::unique_lock<std::mutex> StallProcesses() { 206 std::unique_lock<std::mutex> StallApplication() {
207 std::unique_lock<std::mutex> lk(suspend_guard); 207 std::unique_lock<std::mutex> lk(suspend_guard);
208 kernel.Suspend(true); 208 kernel.SuspendApplication(true);
209 core_timing.SyncPause(true); 209 core_timing.SyncPause(true);
210 return lk; 210 return lk;
211 } 211 }
212 212
213 void UnstallProcesses() { 213 void UnstallApplication() {
214 if (!IsPaused()) { 214 if (!IsPaused()) {
215 core_timing.SyncPause(false); 215 core_timing.SyncPause(false);
216 kernel.Suspend(false); 216 kernel.SuspendApplication(false);
217 } 217 }
218 } 218 }
219 219
@@ -221,7 +221,7 @@ struct System::Impl {
221 debugger = std::make_unique<Debugger>(system, port); 221 debugger = std::make_unique<Debugger>(system, port);
222 } 222 }
223 223
224 SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) { 224 SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
225 LOG_DEBUG(Core, "initialized OK"); 225 LOG_DEBUG(Core, "initialized OK");
226 226
227 // Setting changes may require a full system reinitialization (e.g., disabling multicore). 227 // Setting changes may require a full system reinitialization (e.g., disabling multicore).
@@ -273,7 +273,7 @@ struct System::Impl {
273 return SystemResultStatus::ErrorGetLoader; 273 return SystemResultStatus::ErrorGetLoader;
274 } 274 }
275 275
276 SystemResultStatus init_result{SetupForMainProcess(system, emu_window)}; 276 SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
277 if (init_result != SystemResultStatus::Success) { 277 if (init_result != SystemResultStatus::Success) {
278 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", 278 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
279 static_cast<int>(init_result)); 279 static_cast<int>(init_result));
@@ -302,7 +302,7 @@ struct System::Impl {
302 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); 302 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
303 } 303 }
304 AddGlueRegistrationForProcess(*app_loader, *main_process); 304 AddGlueRegistrationForProcess(*app_loader, *main_process);
305 kernel.MakeCurrentProcess(main_process); 305 kernel.MakeApplicationProcess(main_process);
306 kernel.InitializeCores(); 306 kernel.InitializeCores();
307 307
308 // Initialize cheat engine 308 // Initialize cheat engine
@@ -585,12 +585,12 @@ void System::DetachDebugger() {
585 } 585 }
586} 586}
587 587
588std::unique_lock<std::mutex> System::StallProcesses() { 588std::unique_lock<std::mutex> System::StallApplication() {
589 return impl->StallProcesses(); 589 return impl->StallApplication();
590} 590}
591 591
592void System::UnstallProcesses() { 592void System::UnstallApplication() {
593 impl->UnstallProcesses(); 593 impl->UnstallApplication();
594} 594}
595 595
596void System::InitializeDebugger() { 596void System::InitializeDebugger() {
@@ -648,8 +648,8 @@ const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const {
648 return impl->kernel.GlobalSchedulerContext(); 648 return impl->kernel.GlobalSchedulerContext();
649} 649}
650 650
651Kernel::KProcess* System::CurrentProcess() { 651Kernel::KProcess* System::ApplicationProcess() {
652 return impl->kernel.CurrentProcess(); 652 return impl->kernel.ApplicationProcess();
653} 653}
654 654
655Core::DeviceMemory& System::DeviceMemory() { 655Core::DeviceMemory& System::DeviceMemory() {
@@ -660,8 +660,8 @@ const Core::DeviceMemory& System::DeviceMemory() const {
660 return *impl->device_memory; 660 return *impl->device_memory;
661} 661}
662 662
663const Kernel::KProcess* System::CurrentProcess() const { 663const Kernel::KProcess* System::ApplicationProcess() const {
664 return impl->kernel.CurrentProcess(); 664 return impl->kernel.ApplicationProcess();
665} 665}
666 666
667ARM_Interface& System::ArmInterface(std::size_t core_index) { 667ARM_Interface& System::ArmInterface(std::size_t core_index) {
@@ -760,8 +760,8 @@ const Core::SpeedLimiter& System::SpeedLimiter() const {
760 return impl->speed_limiter; 760 return impl->speed_limiter;
761} 761}
762 762
763u64 System::GetCurrentProcessProgramID() const { 763u64 System::GetApplicationProcessProgramID() const {
764 return impl->kernel.CurrentProcess()->GetProgramID(); 764 return impl->kernel.ApplicationProcess()->GetProgramID();
765} 765}
766 766
767Loader::ResultStatus System::GetGameName(std::string& out) const { 767Loader::ResultStatus System::GetGameName(std::string& out) const {
@@ -880,11 +880,11 @@ bool System::GetExitLock() const {
880 return impl->exit_lock; 880 return impl->exit_lock;
881} 881}
882 882
883void System::SetCurrentProcessBuildID(const CurrentBuildProcessID& id) { 883void System::SetApplicationProcessBuildID(const CurrentBuildProcessID& id) {
884 impl->build_id = id; 884 impl->build_id = id;
885} 885}
886 886
887const System::CurrentBuildProcessID& System::GetCurrentProcessBuildID() const { 887const System::CurrentBuildProcessID& System::GetApplicationProcessBuildID() const {
888 return impl->build_id; 888 return impl->build_id;
889} 889}
890 890
diff --git a/src/core/core.h b/src/core/core.h
index fb5cda2f5..0042ac170 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -184,8 +184,8 @@ public:
184 /// Forcibly detach the debugger if it is running. 184 /// Forcibly detach the debugger if it is running.
185 void DetachDebugger(); 185 void DetachDebugger();
186 186
187 std::unique_lock<std::mutex> StallProcesses(); 187 std::unique_lock<std::mutex> StallApplication();
188 void UnstallProcesses(); 188 void UnstallApplication();
189 189
190 /** 190 /**
191 * Initialize the debugger. 191 * Initialize the debugger.
@@ -295,11 +295,11 @@ public:
295 /// Gets the manager for the guest device memory 295 /// Gets the manager for the guest device memory
296 [[nodiscard]] const Core::DeviceMemory& DeviceMemory() const; 296 [[nodiscard]] const Core::DeviceMemory& DeviceMemory() const;
297 297
298 /// Provides a pointer to the current process 298 /// Provides a pointer to the application process
299 [[nodiscard]] Kernel::KProcess* CurrentProcess(); 299 [[nodiscard]] Kernel::KProcess* ApplicationProcess();
300 300
301 /// Provides a constant pointer to the current process. 301 /// Provides a constant pointer to the application process.
302 [[nodiscard]] const Kernel::KProcess* CurrentProcess() const; 302 [[nodiscard]] const Kernel::KProcess* ApplicationProcess() const;
303 303
304 /// Provides a reference to the core timing instance. 304 /// Provides a reference to the core timing instance.
305 [[nodiscard]] Timing::CoreTiming& CoreTiming(); 305 [[nodiscard]] Timing::CoreTiming& CoreTiming();
@@ -331,7 +331,7 @@ public:
331 /// Provides a constant reference to the speed limiter 331 /// Provides a constant reference to the speed limiter
332 [[nodiscard]] const Core::SpeedLimiter& SpeedLimiter() const; 332 [[nodiscard]] const Core::SpeedLimiter& SpeedLimiter() const;
333 333
334 [[nodiscard]] u64 GetCurrentProcessProgramID() const; 334 [[nodiscard]] u64 GetApplicationProcessProgramID() const;
335 335
336 /// Gets the name of the current game 336 /// Gets the name of the current game
337 [[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const; 337 [[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
@@ -396,8 +396,8 @@ public:
396 void SetExitLock(bool locked); 396 void SetExitLock(bool locked);
397 [[nodiscard]] bool GetExitLock() const; 397 [[nodiscard]] bool GetExitLock() const;
398 398
399 void SetCurrentProcessBuildID(const CurrentBuildProcessID& id); 399 void SetApplicationProcessBuildID(const CurrentBuildProcessID& id);
400 [[nodiscard]] const CurrentBuildProcessID& GetCurrentProcessBuildID() const; 400 [[nodiscard]] const CurrentBuildProcessID& GetApplicationProcessBuildID() const;
401 401
402 /// Register a host thread as an emulated CPU Core. 402 /// Register a host thread as an emulated CPU Core.
403 void RegisterCoreThread(std::size_t id); 403 void RegisterCoreThread(std::size_t id);
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 6bac6722f..3a63b52e3 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -45,7 +45,7 @@ CoreTiming::~CoreTiming() {
45} 45}
46 46
47void CoreTiming::ThreadEntry(CoreTiming& instance) { 47void CoreTiming::ThreadEntry(CoreTiming& instance) {
48 constexpr char name[] = "HostTiming"; 48 static constexpr char name[] = "HostTiming";
49 MicroProfileOnThreadCreate(name); 49 MicroProfileOnThreadCreate(name);
50 Common::SetCurrentThreadName(name); 50 Common::SetCurrentThreadName(name);
51 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); 51 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 9c02b7b31..945ec528e 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -96,7 +96,7 @@ static std::string EscapeXML(std::string_view data) {
96 96
97GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_) 97GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_)
98 : DebuggerFrontend(backend_), system{system_} { 98 : DebuggerFrontend(backend_), system{system_} {
99 if (system.CurrentProcess()->Is64BitProcess()) { 99 if (system.ApplicationProcess()->Is64BitProcess()) {
100 arch = std::make_unique<GDBStubA64>(); 100 arch = std::make_unique<GDBStubA64>();
101 } else { 101 } else {
102 arch = std::make_unique<GDBStubA32>(); 102 arch = std::make_unique<GDBStubA32>();
@@ -340,15 +340,15 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) {
340 success = true; 340 success = true;
341 break; 341 break;
342 case BreakpointType::WriteWatch: 342 case BreakpointType::WriteWatch:
343 success = system.CurrentProcess()->InsertWatchpoint(system, addr, size, 343 success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
344 Kernel::DebugWatchpointType::Write); 344 Kernel::DebugWatchpointType::Write);
345 break; 345 break;
346 case BreakpointType::ReadWatch: 346 case BreakpointType::ReadWatch:
347 success = system.CurrentProcess()->InsertWatchpoint(system, addr, size, 347 success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
348 Kernel::DebugWatchpointType::Read); 348 Kernel::DebugWatchpointType::Read);
349 break; 349 break;
350 case BreakpointType::AccessWatch: 350 case BreakpointType::AccessWatch:
351 success = system.CurrentProcess()->InsertWatchpoint( 351 success = system.ApplicationProcess()->InsertWatchpoint(
352 system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); 352 system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
353 break; 353 break;
354 case BreakpointType::Hardware: 354 case BreakpointType::Hardware:
@@ -391,15 +391,15 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
391 break; 391 break;
392 } 392 }
393 case BreakpointType::WriteWatch: 393 case BreakpointType::WriteWatch:
394 success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size, 394 success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
395 Kernel::DebugWatchpointType::Write); 395 Kernel::DebugWatchpointType::Write);
396 break; 396 break;
397 case BreakpointType::ReadWatch: 397 case BreakpointType::ReadWatch:
398 success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size, 398 success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
399 Kernel::DebugWatchpointType::Read); 399 Kernel::DebugWatchpointType::Read);
400 break; 400 break;
401 case BreakpointType::AccessWatch: 401 case BreakpointType::AccessWatch:
402 success = system.CurrentProcess()->RemoveWatchpoint( 402 success = system.ApplicationProcess()->RemoveWatchpoint(
403 system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); 403 system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
404 break; 404 break;
405 case BreakpointType::Hardware: 405 case BreakpointType::Hardware:
@@ -482,7 +482,7 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory&
482 482
483static std::optional<std::string> GetThreadName(Core::System& system, 483static std::optional<std::string> GetThreadName(Core::System& system,
484 const Kernel::KThread* thread) { 484 const Kernel::KThread* thread) {
485 if (system.CurrentProcess()->Is64BitProcess()) { 485 if (system.ApplicationProcess()->Is64BitProcess()) {
486 return GetNameFromThreadType64(system.Memory(), thread); 486 return GetNameFromThreadType64(system.Memory(), thread);
487 } else { 487 } else {
488 return GetNameFromThreadType32(system.Memory(), thread); 488 return GetNameFromThreadType32(system.Memory(), thread);
@@ -555,7 +555,7 @@ void GDBStub::HandleQuery(std::string_view command) {
555 SendReply(fmt::format("TextSeg={:x}", main->first)); 555 SendReply(fmt::format("TextSeg={:x}", main->first));
556 } else { 556 } else {
557 SendReply(fmt::format("TextSeg={:x}", 557 SendReply(fmt::format("TextSeg={:x}",
558 system.CurrentProcess()->PageTable().GetCodeRegionStart())); 558 system.ApplicationProcess()->PageTable().GetCodeRegionStart()));
559 } 559 }
560 } else if (command.starts_with("Xfer:libraries:read::")) { 560 } else if (command.starts_with("Xfer:libraries:read::")) {
561 Loader::AppLoader::Modules modules; 561 Loader::AppLoader::Modules modules;
@@ -729,7 +729,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
729 std::string_view command_str{reinterpret_cast<const char*>(&command[0]), command.size()}; 729 std::string_view command_str{reinterpret_cast<const char*>(&command[0]), command.size()};
730 std::string reply; 730 std::string reply;
731 731
732 auto* process = system.CurrentProcess(); 732 auto* process = system.ApplicationProcess();
733 auto& page_table = process->PageTable(); 733 auto& page_table = process->PageTable();
734 734
735 const char* commands = "Commands:\n" 735 const char* commands = "Commands:\n"
diff --git a/src/core/debugger/gdbstub_arch.cpp b/src/core/debugger/gdbstub_arch.cpp
index 4bef09bd7..831c48513 100644
--- a/src/core/debugger/gdbstub_arch.cpp
+++ b/src/core/debugger/gdbstub_arch.cpp
@@ -41,9 +41,8 @@ static void PutSIMDRegister(std::array<u32, 64>& simd_regs, size_t offset, const
41 41
42// For sample XML files see the GDB source /gdb/features 42// For sample XML files see the GDB source /gdb/features
43// This XML defines what the registers are for this specific ARM device 43// This XML defines what the registers are for this specific ARM device
44std::string GDBStubA64::GetTargetXML() const { 44std::string_view GDBStubA64::GetTargetXML() const {
45 constexpr const char* target_xml = 45 return R"(<?xml version="1.0"?>
46 R"(<?xml version="1.0"?>
47<!DOCTYPE target SYSTEM "gdb-target.dtd"> 46<!DOCTYPE target SYSTEM "gdb-target.dtd">
48<target version="1.0"> 47<target version="1.0">
49 <architecture>aarch64</architecture> 48 <architecture>aarch64</architecture>
@@ -178,8 +177,6 @@ std::string GDBStubA64::GetTargetXML() const {
178 <reg name="fpcr" bitsize="32"/> 177 <reg name="fpcr" bitsize="32"/>
179 </feature> 178 </feature>
180</target>)"; 179</target>)";
181
182 return target_xml;
183} 180}
184 181
185std::string GDBStubA64::RegRead(const Kernel::KThread* thread, size_t id) const { 182std::string GDBStubA64::RegRead(const Kernel::KThread* thread, size_t id) const {
@@ -270,9 +267,8 @@ u32 GDBStubA64::BreakpointInstruction() const {
270 return 0xd4200000; 267 return 0xd4200000;
271} 268}
272 269
273std::string GDBStubA32::GetTargetXML() const { 270std::string_view GDBStubA32::GetTargetXML() const {
274 constexpr const char* target_xml = 271 return R"(<?xml version="1.0"?>
275 R"(<?xml version="1.0"?>
276<!DOCTYPE target SYSTEM "gdb-target.dtd"> 272<!DOCTYPE target SYSTEM "gdb-target.dtd">
277<target version="1.0"> 273<target version="1.0">
278 <architecture>arm</architecture> 274 <architecture>arm</architecture>
@@ -378,8 +374,6 @@ std::string GDBStubA32::GetTargetXML() const {
378 <reg name="fpscr" bitsize="32" type="int" group="float" regnum="80"/> 374 <reg name="fpscr" bitsize="32" type="int" group="float" regnum="80"/>
379 </feature> 375 </feature>
380</target>)"; 376</target>)";
381
382 return target_xml;
383} 377}
384 378
385std::string GDBStubA32::RegRead(const Kernel::KThread* thread, size_t id) const { 379std::string GDBStubA32::RegRead(const Kernel::KThread* thread, size_t id) const {
diff --git a/src/core/debugger/gdbstub_arch.h b/src/core/debugger/gdbstub_arch.h
index 2540d6456..34530c788 100644
--- a/src/core/debugger/gdbstub_arch.h
+++ b/src/core/debugger/gdbstub_arch.h
@@ -16,7 +16,7 @@ namespace Core {
16class GDBStubArch { 16class GDBStubArch {
17public: 17public:
18 virtual ~GDBStubArch() = default; 18 virtual ~GDBStubArch() = default;
19 virtual std::string GetTargetXML() const = 0; 19 virtual std::string_view GetTargetXML() const = 0;
20 virtual std::string RegRead(const Kernel::KThread* thread, size_t id) const = 0; 20 virtual std::string RegRead(const Kernel::KThread* thread, size_t id) const = 0;
21 virtual void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const = 0; 21 virtual void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const = 0;
22 virtual std::string ReadRegisters(const Kernel::KThread* thread) const = 0; 22 virtual std::string ReadRegisters(const Kernel::KThread* thread) const = 0;
@@ -27,7 +27,7 @@ public:
27 27
28class GDBStubA64 final : public GDBStubArch { 28class GDBStubA64 final : public GDBStubArch {
29public: 29public:
30 std::string GetTargetXML() const override; 30 std::string_view GetTargetXML() const override;
31 std::string RegRead(const Kernel::KThread* thread, size_t id) const override; 31 std::string RegRead(const Kernel::KThread* thread, size_t id) const override;
32 void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override; 32 void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override;
33 std::string ReadRegisters(const Kernel::KThread* thread) const override; 33 std::string ReadRegisters(const Kernel::KThread* thread) const override;
@@ -47,7 +47,7 @@ private:
47 47
48class GDBStubA32 final : public GDBStubArch { 48class GDBStubA32 final : public GDBStubArch {
49public: 49public:
50 std::string GetTargetXML() const override; 50 std::string_view GetTargetXML() const override;
51 std::string RegRead(const Kernel::KThread* thread, size_t id) const override; 51 std::string RegRead(const Kernel::KThread* thread, size_t id) const override;
52 void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override; 52 void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override;
53 std::string ReadRegisters(const Kernel::KThread* thread) const override; 53 std::string ReadRegisters(const Kernel::KThread* thread) const override;
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index 5aab428bb..efdf18cee 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -41,12 +41,12 @@ static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
41 return IPSFileType::Error; 41 return IPSFileType::Error;
42 } 42 }
43 43
44 constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}}; 44 static constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
45 if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) { 45 if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) {
46 return IPSFileType::IPS; 46 return IPSFileType::IPS;
47 } 47 }
48 48
49 constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}}; 49 static constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
50 if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) { 50 if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) {
51 return IPSFileType::IPS32; 51 return IPSFileType::IPS32;
52 } 52 }
@@ -55,12 +55,12 @@ static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
55} 55}
56 56
57static bool IsEOF(IPSFileType type, const std::vector<u8>& data) { 57static bool IsEOF(IPSFileType type, const std::vector<u8>& data) {
58 constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}}; 58 static constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
59 if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) { 59 if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) {
60 return true; 60 return true;
61 } 61 }
62 62
63 constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}}; 63 static constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
64 return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin()); 64 return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin());
65} 65}
66 66
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 878d832c2..a6960170c 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -71,7 +71,7 @@ static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bo
71} 71}
72 72
73static std::string GetCNMTName(TitleType type, u64 title_id) { 73static std::string GetCNMTName(TitleType type, u64 title_id) {
74 constexpr std::array<const char*, 9> TITLE_TYPE_NAMES{ 74 static constexpr std::array<const char*, 9> TITLE_TYPE_NAMES{
75 "SystemProgram", 75 "SystemProgram",
76 "SystemData", 76 "SystemData",
77 "SystemUpdate", 77 "SystemUpdate",
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index 1567da231..769065b6f 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -172,7 +172,7 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
172 // be interpreted as the title id of the current process. 172 // be interpreted as the title id of the current process.
173 if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { 173 if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
174 if (title_id == 0) { 174 if (title_id == 0) {
175 title_id = system.GetCurrentProcessProgramID(); 175 title_id = system.GetApplicationProcessProgramID();
176 } 176 }
177 } 177 }
178 178
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index 1c91bbe40..17d663379 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -23,7 +23,8 @@ void EmulatedConsole::SetTouchParams() {
23 23
24 // We can't use mouse as touch if native mouse is enabled 24 // We can't use mouse as touch if native mouse is enabled
25 if (!Settings::values.mouse_enabled) { 25 if (!Settings::values.mouse_enabled) {
26 touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"}; 26 touch_params[index++] =
27 Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
27 } 28 }
28 29
29 touch_params[index++] = 30 touch_params[index++] =
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 631aa6ad2..6d5a3dead 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -957,7 +957,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
957 raw_status.gyro.y.value, 957 raw_status.gyro.y.value,
958 raw_status.gyro.z.value, 958 raw_status.gyro.z.value,
959 }); 959 });
960 emulated.SetGyroThreshold(raw_status.gyro.x.properties.threshold); 960 emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold);
961 emulated.UpdateRotation(raw_status.delta_timestamp); 961 emulated.UpdateRotation(raw_status.delta_timestamp);
962 emulated.UpdateOrientation(raw_status.delta_timestamp); 962 emulated.UpdateOrientation(raw_status.delta_timestamp);
963 force_update_motion = raw_status.force_update; 963 force_update_motion = raw_status.force_update;
@@ -1284,6 +1284,26 @@ void EmulatedController::SetLedPattern() {
1284 } 1284 }
1285} 1285}
1286 1286
1287void EmulatedController::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode) {
1288 for (auto& motion : controller.motion_values) {
1289 switch (mode) {
1290 case GyroscopeZeroDriftMode::Loose:
1291 motion_sensitivity = motion.emulated.IsAtRestLoose;
1292 motion.emulated.SetGyroThreshold(motion.emulated.ThresholdLoose);
1293 break;
1294 case GyroscopeZeroDriftMode::Tight:
1295 motion_sensitivity = motion.emulated.IsAtRestThight;
1296 motion.emulated.SetGyroThreshold(motion.emulated.ThresholdThight);
1297 break;
1298 case GyroscopeZeroDriftMode::Standard:
1299 default:
1300 motion_sensitivity = motion.emulated.IsAtRestStandard;
1301 motion.emulated.SetGyroThreshold(motion.emulated.ThresholdStandard);
1302 break;
1303 }
1304 }
1305}
1306
1287void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) { 1307void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) {
1288 supported_style_tag = supported_styles; 1308 supported_style_tag = supported_styles;
1289 if (!is_connected) { 1309 if (!is_connected) {
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index b02bf35c4..a9da465a2 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -398,6 +398,9 @@ public:
398 /// Asks the output device to change the player led pattern 398 /// Asks the output device to change the player led pattern
399 void SetLedPattern(); 399 void SetLedPattern();
400 400
401 /// Changes sensitivity of the motion sensor
402 void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode);
403
401 /** 404 /**
402 * Adds a callback to the list of events 405 * Adds a callback to the list of events
403 * @param update_callback A ConsoleUpdateCallback that will be triggered 406 * @param update_callback A ConsoleUpdateCallback that will be triggered
@@ -523,7 +526,7 @@ private:
523 bool is_connected{false}; 526 bool is_connected{false};
524 bool is_configuring{false}; 527 bool is_configuring{false};
525 bool system_buttons_enabled{true}; 528 bool system_buttons_enabled{true};
526 f32 motion_sensitivity{0.01f}; 529 f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
527 bool force_update_motion{false}; 530 bool force_update_motion{false};
528 u32 turbo_button_state{0}; 531 u32 turbo_button_state{0};
529 532
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index 836f32c0f..578a6ff61 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -34,9 +34,12 @@ void EmulatedDevices::ReloadInput() {
34 // First two axis are reserved for mouse position 34 // First two axis are reserved for mouse position
35 key_index = 2; 35 key_index = 2;
36 for (auto& mouse_device : mouse_analog_devices) { 36 for (auto& mouse_device : mouse_analog_devices) {
37 // Mouse axis are only mapped on port 1, pad 0
37 Common::ParamPackage mouse_params; 38 Common::ParamPackage mouse_params;
38 mouse_params.Set("engine", "mouse"); 39 mouse_params.Set("engine", "mouse");
39 mouse_params.Set("axis", static_cast<int>(key_index)); 40 mouse_params.Set("axis", static_cast<int>(key_index));
41 mouse_params.Set("port", 1);
42 mouse_params.Set("pad", 0);
40 mouse_device = Common::Input::CreateInputDevice(mouse_params); 43 mouse_device = Common::Input::CreateInputDevice(mouse_params);
41 key_index++; 44 key_index++;
42 } 45 }
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index e3b1cfbc6..6b35f448c 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -282,6 +282,13 @@ enum class VibrationGcErmCommand : u64 {
282 StopHard = 2, 282 StopHard = 2,
283}; 283};
284 284
285// This is nn::hid::GyroscopeZeroDriftMode
286enum class GyroscopeZeroDriftMode : u32 {
287 Loose = 0,
288 Standard = 1,
289 Tight = 2,
290};
291
285// This is nn::hid::NpadStyleTag 292// This is nn::hid::NpadStyleTag
286struct NpadStyleTag { 293struct NpadStyleTag {
287 union { 294 union {
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp
index b1f658e62..eef6edf4b 100644
--- a/src/core/hid/motion_input.cpp
+++ b/src/core/hid/motion_input.cpp
@@ -9,7 +9,7 @@ namespace Core::HID {
9MotionInput::MotionInput() { 9MotionInput::MotionInput() {
10 // Initialize PID constants with default values 10 // Initialize PID constants with default values
11 SetPID(0.3f, 0.005f, 0.0f); 11 SetPID(0.3f, 0.005f, 0.0f);
12 SetGyroThreshold(0.007f); 12 SetGyroThreshold(ThresholdStandard);
13} 13}
14 14
15void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) { 15void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
@@ -26,11 +26,11 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
26 gyro = gyroscope - gyro_bias; 26 gyro = gyroscope - gyro_bias;
27 27
28 // Auto adjust drift to minimize drift 28 // Auto adjust drift to minimize drift
29 if (!IsMoving(0.1f)) { 29 if (!IsMoving(IsAtRestRelaxed)) {
30 gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); 30 gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
31 } 31 }
32 32
33 if (gyro.Length() < gyro_threshold) { 33 if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
34 gyro = {}; 34 gyro = {};
35 } else { 35 } else {
36 only_accelerometer = false; 36 only_accelerometer = false;
@@ -49,6 +49,10 @@ void MotionInput::SetGyroThreshold(f32 threshold) {
49 gyro_threshold = threshold; 49 gyro_threshold = threshold;
50} 50}
51 51
52void MotionInput::SetUserGyroThreshold(f32 threshold) {
53 user_gyro_threshold = threshold / ThresholdStandard;
54}
55
52void MotionInput::EnableReset(bool reset) { 56void MotionInput::EnableReset(bool reset) {
53 reset_enabled = reset; 57 reset_enabled = reset;
54} 58}
@@ -208,7 +212,7 @@ void MotionInput::ResetOrientation() {
208 if (!reset_enabled || only_accelerometer) { 212 if (!reset_enabled || only_accelerometer) {
209 return; 213 return;
210 } 214 }
211 if (!IsMoving(0.5f) && accel.z <= -0.9f) { 215 if (!IsMoving(IsAtRestRelaxed) && accel.z <= -0.9f) {
212 ++reset_counter; 216 ++reset_counter;
213 if (reset_counter > 900) { 217 if (reset_counter > 900) {
214 quat.w = 0; 218 quat.w = 0;
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h
index f5fd90db5..9180bb9aa 100644
--- a/src/core/hid/motion_input.h
+++ b/src/core/hid/motion_input.h
@@ -11,6 +11,15 @@ namespace Core::HID {
11 11
12class MotionInput { 12class MotionInput {
13public: 13public:
14 static constexpr float ThresholdLoose = 0.01f;
15 static constexpr float ThresholdStandard = 0.007f;
16 static constexpr float ThresholdThight = 0.002f;
17
18 static constexpr float IsAtRestRelaxed = 0.05f;
19 static constexpr float IsAtRestLoose = 0.02f;
20 static constexpr float IsAtRestStandard = 0.01f;
21 static constexpr float IsAtRestThight = 0.005f;
22
14 explicit MotionInput(); 23 explicit MotionInput();
15 24
16 MotionInput(const MotionInput&) = default; 25 MotionInput(const MotionInput&) = default;
@@ -26,6 +35,9 @@ public:
26 void SetGyroBias(const Common::Vec3f& bias); 35 void SetGyroBias(const Common::Vec3f& bias);
27 void SetGyroThreshold(f32 threshold); 36 void SetGyroThreshold(f32 threshold);
28 37
38 /// Applies a modifier on top of the normal gyro threshold
39 void SetUserGyroThreshold(f32 threshold);
40
29 void EnableReset(bool reset); 41 void EnableReset(bool reset);
30 void ResetRotations(); 42 void ResetRotations();
31 43
@@ -74,6 +86,9 @@ private:
74 // Minimum gyro amplitude to detect if the device is moving 86 // Minimum gyro amplitude to detect if the device is moving
75 f32 gyro_threshold = 0.0f; 87 f32 gyro_threshold = 0.0f;
76 88
89 // Multiplies gyro_threshold by this value
90 f32 user_gyro_threshold = 0.0f;
91
77 // Number of invalid sequential data 92 // Number of invalid sequential data
78 u32 reset_counter = 0; 93 u32 reset_counter = 0;
79 94
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index a86bec252..38d6cfaff 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -148,7 +148,7 @@ public:
148 if (context->GetManager()->IsDomain()) { 148 if (context->GetManager()->IsDomain()) {
149 context->AddDomainObject(std::move(iface)); 149 context->AddDomainObject(std::move(iface));
150 } else { 150 } else {
151 kernel.CurrentProcess()->GetResourceLimit()->Reserve( 151 kernel.ApplicationProcess()->GetResourceLimit()->Reserve(
152 Kernel::LimitableResource::SessionCountMax, 1); 152 Kernel::LimitableResource::SessionCountMax, 1);
153 153
154 auto* session = Kernel::KSession::Create(kernel); 154 auto* session = Kernel::KSession::Create(kernel);
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 571acf4b2..abdb5639f 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -16,6 +16,7 @@
16#include "core/hle/kernel/k_event_info.h" 16#include "core/hle/kernel/k_event_info.h"
17#include "core/hle/kernel/k_memory_layout.h" 17#include "core/hle/kernel/k_memory_layout.h"
18#include "core/hle/kernel/k_memory_manager.h" 18#include "core/hle/kernel/k_memory_manager.h"
19#include "core/hle/kernel/k_object_name.h"
19#include "core/hle/kernel/k_page_buffer.h" 20#include "core/hle/kernel/k_page_buffer.h"
20#include "core/hle/kernel/k_port.h" 21#include "core/hle/kernel/k_port.h"
21#include "core/hle/kernel/k_process.h" 22#include "core/hle/kernel/k_process.h"
@@ -49,6 +50,7 @@ namespace Kernel::Init {
49 HANDLER(KThreadLocalPage, \ 50 HANDLER(KThreadLocalPage, \
50 (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \ 51 (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
51 ##__VA_ARGS__) \ 52 ##__VA_ARGS__) \
53 HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ##__VA_ARGS__) \
52 HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \ 54 HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
53 HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \ 55 HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
54 HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \ 56 HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp
index 2ec623a58..c72a91a76 100644
--- a/src/core/hle/kernel/k_client_port.cpp
+++ b/src/core/hle/kernel/k_client_port.cpp
@@ -60,7 +60,8 @@ bool KClientPort::IsSignaled() const {
60 60
61Result KClientPort::CreateSession(KClientSession** out) { 61Result KClientPort::CreateSession(KClientSession** out) {
62 // Reserve a new session from the resource limit. 62 // Reserve a new session from the resource limit.
63 KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(), 63 //! FIXME: we are reserving this from the wrong resource limit!
64 KScopedResourceReservation session_reservation(kernel.ApplicationProcess()->GetResourceLimit(),
64 LimitableResource::SessionCountMax); 65 LimitableResource::SessionCountMax);
65 R_UNLESS(session_reservation.Succeeded(), ResultLimitReached); 66 R_UNLESS(session_reservation.Succeeded(), ResultLimitReached);
66 67
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp
index 884eba001..6c44a9e99 100644
--- a/src/core/hle/kernel/k_code_memory.cpp
+++ b/src/core/hle/kernel/k_code_memory.cpp
@@ -21,7 +21,7 @@ KCodeMemory::KCodeMemory(KernelCore& kernel_)
21 21
22Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) { 22Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) {
23 // Set members. 23 // Set members.
24 m_owner = kernel.CurrentProcess(); 24 m_owner = GetCurrentProcessPointer(kernel);
25 25
26 // Get the owner page table. 26 // Get the owner page table.
27 auto& page_table = m_owner->PageTable(); 27 auto& page_table = m_owner->PageTable();
@@ -74,7 +74,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
74 R_UNLESS(!m_is_mapped, ResultInvalidState); 74 R_UNLESS(!m_is_mapped, ResultInvalidState);
75 75
76 // Map the memory. 76 // Map the memory.
77 R_TRY(kernel.CurrentProcess()->PageTable().MapPageGroup( 77 R_TRY(GetCurrentProcess(kernel).PageTable().MapPageGroup(
78 address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite)); 78 address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
79 79
80 // Mark ourselves as mapped. 80 // Mark ourselves as mapped.
@@ -91,8 +91,8 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) {
91 KScopedLightLock lk(m_lock); 91 KScopedLightLock lk(m_lock);
92 92
93 // Unmap the memory. 93 // Unmap the memory.
94 R_TRY(kernel.CurrentProcess()->PageTable().UnmapPageGroup(address, *m_page_group, 94 R_TRY(GetCurrentProcess(kernel).PageTable().UnmapPageGroup(address, *m_page_group,
95 KMemoryState::CodeOut)); 95 KMemoryState::CodeOut));
96 96
97 // Mark ourselves as unmapped. 97 // Mark ourselves as unmapped.
98 m_is_mapped = false; 98 m_is_mapped = false;
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 0c6b20db3..3f0be1c3f 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -164,8 +164,8 @@ Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value)
164 R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask)); 164 R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask));
165 165
166 // Get the lock owner thread. 166 // Get the lock owner thread.
167 owner_thread = kernel.CurrentProcess() 167 owner_thread = GetCurrentProcess(kernel)
168 ->GetHandleTable() 168 .GetHandleTable()
169 .GetObjectWithoutPseudoHandle<KThread>(handle) 169 .GetObjectWithoutPseudoHandle<KThread>(handle)
170 .ReleasePointerUnsafe(); 170 .ReleasePointerUnsafe();
171 R_UNLESS(owner_thread != nullptr, ResultInvalidHandle); 171 R_UNLESS(owner_thread != nullptr, ResultInvalidHandle);
@@ -213,8 +213,8 @@ void KConditionVariable::SignalImpl(KThread* thread) {
213 thread->EndWait(ResultSuccess); 213 thread->EndWait(ResultSuccess);
214 } else { 214 } else {
215 // Get the previous owner. 215 // Get the previous owner.
216 KThread* owner_thread = kernel.CurrentProcess() 216 KThread* owner_thread = GetCurrentProcess(kernel)
217 ->GetHandleTable() 217 .GetHandleTable()
218 .GetObjectWithoutPseudoHandle<KThread>( 218 .GetObjectWithoutPseudoHandle<KThread>(
219 static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask)) 219 static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
220 .ReleasePointerUnsafe(); 220 .ReleasePointerUnsafe();
diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h
index 37a24e7d9..d7660630c 100644
--- a/src/core/hle/kernel/k_handle_table.h
+++ b/src/core/hle/kernel/k_handle_table.h
@@ -90,7 +90,8 @@ public:
90 // Handle pseudo-handles. 90 // Handle pseudo-handles.
91 if constexpr (std::derived_from<KProcess, T>) { 91 if constexpr (std::derived_from<KProcess, T>) {
92 if (handle == Svc::PseudoHandle::CurrentProcess) { 92 if (handle == Svc::PseudoHandle::CurrentProcess) {
93 auto* const cur_process = m_kernel.CurrentProcess(); 93 //! FIXME: this is the wrong process!
94 auto* const cur_process = m_kernel.ApplicationProcess();
94 ASSERT(cur_process != nullptr); 95 ASSERT(cur_process != nullptr);
95 return cur_process; 96 return cur_process;
96 } 97 }
diff --git a/src/core/hle/kernel/k_interrupt_manager.cpp b/src/core/hle/kernel/k_interrupt_manager.cpp
index 4a6b60d26..fe6a20168 100644
--- a/src/core/hle/kernel/k_interrupt_manager.cpp
+++ b/src/core/hle/kernel/k_interrupt_manager.cpp
@@ -16,7 +16,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) {
16 16
17 auto& current_thread = GetCurrentThread(kernel); 17 auto& current_thread = GetCurrentThread(kernel);
18 18
19 if (auto* process = kernel.CurrentProcess(); process) { 19 if (auto* process = GetCurrentProcessPointer(kernel); process) {
20 // If the user disable count is set, we may need to pin the current thread. 20 // If the user disable count is set, we may need to pin the current thread.
21 if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) { 21 if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) {
22 KScopedSchedulerLock sl{kernel}; 22 KScopedSchedulerLock sl{kernel};
diff --git a/src/core/hle/kernel/k_object_name.cpp b/src/core/hle/kernel/k_object_name.cpp
new file mode 100644
index 000000000..df3a1c4c5
--- /dev/null
+++ b/src/core/hle/kernel/k_object_name.cpp
@@ -0,0 +1,102 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/kernel/k_object_name.h"
5
6namespace Kernel {
7
8KObjectNameGlobalData::KObjectNameGlobalData(KernelCore& kernel) : m_object_list_lock{kernel} {}
9KObjectNameGlobalData::~KObjectNameGlobalData() = default;
10
11void KObjectName::Initialize(KAutoObject* obj, const char* name) {
12 // Set member variables.
13 m_object = obj;
14 std::strncpy(m_name.data(), name, sizeof(m_name) - 1);
15 m_name[sizeof(m_name) - 1] = '\x00';
16
17 // Open a reference to the object we hold.
18 m_object->Open();
19}
20
21bool KObjectName::MatchesName(const char* name) const {
22 return std::strncmp(m_name.data(), name, sizeof(m_name)) == 0;
23}
24
25Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name) {
26 // Create a new object name.
27 KObjectName* new_name = KObjectName::Allocate(kernel);
28 R_UNLESS(new_name != nullptr, ResultOutOfResource);
29
30 // Initialize the new name.
31 new_name->Initialize(obj, name);
32
33 // Check if there's an existing name.
34 {
35 // Get the global data.
36 KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
37
38 // Ensure we have exclusive access to the global list.
39 KScopedLightLock lk{gd.GetObjectListLock()};
40
41 // If the object doesn't exist, put it into the list.
42 KScopedAutoObject existing_object = FindImpl(kernel, name);
43 if (existing_object.IsNull()) {
44 gd.GetObjectList().push_back(*new_name);
45 R_SUCCEED();
46 }
47 }
48
49 // The object already exists, which is an error condition. Perform cleanup.
50 obj->Close();
51 KObjectName::Free(kernel, new_name);
52 R_THROW(ResultInvalidState);
53}
54
55Result KObjectName::Delete(KernelCore& kernel, KAutoObject* obj, const char* compare_name) {
56 // Get the global data.
57 KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
58
59 // Ensure we have exclusive access to the global list.
60 KScopedLightLock lk{gd.GetObjectListLock()};
61
62 // Find a matching entry in the list, and delete it.
63 for (auto& name : gd.GetObjectList()) {
64 if (name.MatchesName(compare_name) && obj == name.GetObject()) {
65 // We found a match, clean up its resources.
66 obj->Close();
67 gd.GetObjectList().erase(gd.GetObjectList().iterator_to(name));
68 KObjectName::Free(kernel, std::addressof(name));
69 R_SUCCEED();
70 }
71 }
72
73 // We didn't find the object in the list.
74 R_THROW(ResultNotFound);
75}
76
77KScopedAutoObject<KAutoObject> KObjectName::Find(KernelCore& kernel, const char* name) {
78 // Get the global data.
79 KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
80
81 // Ensure we have exclusive access to the global list.
82 KScopedLightLock lk{gd.GetObjectListLock()};
83
84 return FindImpl(kernel, name);
85}
86
87KScopedAutoObject<KAutoObject> KObjectName::FindImpl(KernelCore& kernel, const char* compare_name) {
88 // Get the global data.
89 KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
90
91 // Try to find a matching object in the global list.
92 for (const auto& name : gd.GetObjectList()) {
93 if (name.MatchesName(compare_name)) {
94 return name.GetObject();
95 }
96 }
97
98 // There's no matching entry in the list.
99 return nullptr;
100}
101
102} // namespace Kernel
diff --git a/src/core/hle/kernel/k_object_name.h b/src/core/hle/kernel/k_object_name.h
new file mode 100644
index 000000000..b7f943134
--- /dev/null
+++ b/src/core/hle/kernel/k_object_name.h
@@ -0,0 +1,86 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7#include <memory>
8#include <boost/intrusive/list.hpp>
9
10#include "core/hle/kernel/k_light_lock.h"
11#include "core/hle/kernel/slab_helpers.h"
12#include "core/hle/kernel/svc_results.h"
13
14namespace Kernel {
15
16class KObjectNameGlobalData;
17
18class KObjectName : public KSlabAllocated<KObjectName>, public boost::intrusive::list_base_hook<> {
19public:
20 explicit KObjectName(KernelCore&) {}
21 virtual ~KObjectName() = default;
22
23 static constexpr size_t NameLengthMax = 12;
24 using List = boost::intrusive::list<KObjectName>;
25
26 static Result NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name);
27 static Result Delete(KernelCore& kernel, KAutoObject* obj, const char* name);
28
29 static KScopedAutoObject<KAutoObject> Find(KernelCore& kernel, const char* name);
30
31 template <typename Derived>
32 static Result Delete(KernelCore& kernel, const char* name) {
33 // Find the object.
34 KScopedAutoObject obj = Find(kernel, name);
35 R_UNLESS(obj.IsNotNull(), ResultNotFound);
36
37 // Cast the object to the desired type.
38 Derived* derived = obj->DynamicCast<Derived*>();
39 R_UNLESS(derived != nullptr, ResultNotFound);
40
41 // Check that the object is closed.
42 R_UNLESS(derived->IsServerClosed(), ResultInvalidState);
43
44 return Delete(kernel, obj.GetPointerUnsafe(), name);
45 }
46
47 template <typename Derived>
48 requires(std::derived_from<Derived, KAutoObject>)
49 static KScopedAutoObject<Derived> Find(KernelCore& kernel, const char* name) {
50 return Find(kernel, name);
51 }
52
53private:
54 static KScopedAutoObject<KAutoObject> FindImpl(KernelCore& kernel, const char* name);
55
56 void Initialize(KAutoObject* obj, const char* name);
57
58 bool MatchesName(const char* name) const;
59 KAutoObject* GetObject() const {
60 return m_object;
61 }
62
63private:
64 std::array<char, NameLengthMax> m_name{};
65 KAutoObject* m_object{};
66};
67
68class KObjectNameGlobalData {
69public:
70 explicit KObjectNameGlobalData(KernelCore& kernel);
71 ~KObjectNameGlobalData();
72
73 KLightLock& GetObjectListLock() {
74 return m_object_list_lock;
75 }
76
77 KObjectName::List& GetObjectList() {
78 return m_object_list;
79 }
80
81private:
82 KLightLock m_object_list_lock;
83 KObjectName::List m_object_list;
84};
85
86} // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index e201bb0cd..0e4283a0c 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -370,7 +370,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
370 // Initialize proces address space 370 // Initialize proces address space
371 if (const Result result{page_table.InitializeForProcess( 371 if (const Result result{page_table.InitializeForProcess(
372 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, 372 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
373 0x8000000, code_size, &kernel.GetSystemSystemResource(), resource_limit)}; 373 0x8000000, code_size, &kernel.GetAppSystemResource(), resource_limit)};
374 result.IsError()) { 374 result.IsError()) {
375 R_RETURN(result); 375 R_RETURN(result);
376 } 376 }
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index d6676904b..d6c214237 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -328,7 +328,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
328} 328}
329 329
330void KScheduler::SwitchThread(KThread* next_thread) { 330void KScheduler::SwitchThread(KThread* next_thread) {
331 KProcess* const cur_process = kernel.CurrentProcess(); 331 KProcess* const cur_process = GetCurrentProcessPointer(kernel);
332 KThread* const cur_thread = GetCurrentThreadPointer(kernel); 332 KThread* const cur_thread = GetCurrentThreadPointer(kernel);
333 333
334 // We never want to schedule a null thread, so use the idle thread if we don't have a next. 334 // We never want to schedule a null thread, so use the idle thread if we don't have a next.
@@ -689,11 +689,11 @@ void KScheduler::RotateScheduledQueue(KernelCore& kernel, s32 core_id, s32 prior
689void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) { 689void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
690 // Validate preconditions. 690 // Validate preconditions.
691 ASSERT(CanSchedule(kernel)); 691 ASSERT(CanSchedule(kernel));
692 ASSERT(kernel.CurrentProcess() != nullptr); 692 ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
693 693
694 // Get the current thread and process. 694 // Get the current thread and process.
695 KThread& cur_thread = GetCurrentThread(kernel); 695 KThread& cur_thread = GetCurrentThread(kernel);
696 KProcess& cur_process = *kernel.CurrentProcess(); 696 KProcess& cur_process = GetCurrentProcess(kernel);
697 697
698 // If the thread's yield count matches, there's nothing for us to do. 698 // If the thread's yield count matches, there's nothing for us to do.
699 if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { 699 if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@@ -728,11 +728,11 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
728void KScheduler::YieldWithCoreMigration(KernelCore& kernel) { 728void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
729 // Validate preconditions. 729 // Validate preconditions.
730 ASSERT(CanSchedule(kernel)); 730 ASSERT(CanSchedule(kernel));
731 ASSERT(kernel.CurrentProcess() != nullptr); 731 ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
732 732
733 // Get the current thread and process. 733 // Get the current thread and process.
734 KThread& cur_thread = GetCurrentThread(kernel); 734 KThread& cur_thread = GetCurrentThread(kernel);
735 KProcess& cur_process = *kernel.CurrentProcess(); 735 KProcess& cur_process = GetCurrentProcess(kernel);
736 736
737 // If the thread's yield count matches, there's nothing for us to do. 737 // If the thread's yield count matches, there's nothing for us to do.
738 if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { 738 if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@@ -816,11 +816,11 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
816void KScheduler::YieldToAnyThread(KernelCore& kernel) { 816void KScheduler::YieldToAnyThread(KernelCore& kernel) {
817 // Validate preconditions. 817 // Validate preconditions.
818 ASSERT(CanSchedule(kernel)); 818 ASSERT(CanSchedule(kernel));
819 ASSERT(kernel.CurrentProcess() != nullptr); 819 ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
820 820
821 // Get the current thread and process. 821 // Get the current thread and process.
822 KThread& cur_thread = GetCurrentThread(kernel); 822 KThread& cur_thread = GetCurrentThread(kernel);
823 KProcess& cur_process = *kernel.CurrentProcess(); 823 KProcess& cur_process = GetCurrentProcess(kernel);
824 824
825 // If the thread's yield count matches, there's nothing for us to do. 825 // If the thread's yield count matches, there's nothing for us to do.
826 if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { 826 if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp
index b6f6fe9d9..7e677c028 100644
--- a/src/core/hle/kernel/k_session.cpp
+++ b/src/core/hle/kernel/k_session.cpp
@@ -33,7 +33,8 @@ void KSession::Initialize(KClientPort* port_, const std::string& name_) {
33 name = name_; 33 name = name_;
34 34
35 // Set our owner process. 35 // Set our owner process.
36 process = kernel.CurrentProcess(); 36 //! FIXME: this is the wrong process!
37 process = kernel.ApplicationProcess();
37 process->Open(); 38 process->Open();
38 39
39 // Set our port. 40 // Set our port.
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 84ff3c64b..2d3da9d66 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -1266,6 +1266,14 @@ KThread& GetCurrentThread(KernelCore& kernel) {
1266 return *GetCurrentThreadPointer(kernel); 1266 return *GetCurrentThreadPointer(kernel);
1267} 1267}
1268 1268
1269KProcess* GetCurrentProcessPointer(KernelCore& kernel) {
1270 return GetCurrentThread(kernel).GetOwnerProcess();
1271}
1272
1273KProcess& GetCurrentProcess(KernelCore& kernel) {
1274 return *GetCurrentProcessPointer(kernel);
1275}
1276
1269s32 GetCurrentCoreId(KernelCore& kernel) { 1277s32 GetCurrentCoreId(KernelCore& kernel) {
1270 return GetCurrentThread(kernel).GetCurrentCore(); 1278 return GetCurrentThread(kernel).GetCurrentCore();
1271} 1279}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 8b8dc51be..ca82ce3b6 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -110,6 +110,8 @@ enum class StepState : u32 {
110void SetCurrentThread(KernelCore& kernel, KThread* thread); 110void SetCurrentThread(KernelCore& kernel, KThread* thread);
111[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); 111[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel);
112[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); 112[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
113[[nodiscard]] KProcess* GetCurrentProcessPointer(KernelCore& kernel);
114[[nodiscard]] KProcess& GetCurrentProcess(KernelCore& kernel);
113[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); 115[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
114 116
115class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, 117class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>,
diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp
index 9f34c2d46..faa5c73b5 100644
--- a/src/core/hle/kernel/k_transfer_memory.cpp
+++ b/src/core/hle/kernel/k_transfer_memory.cpp
@@ -16,7 +16,7 @@ KTransferMemory::~KTransferMemory() = default;
16Result KTransferMemory::Initialize(VAddr address_, std::size_t size_, 16Result KTransferMemory::Initialize(VAddr address_, std::size_t size_,
17 Svc::MemoryPermission owner_perm_) { 17 Svc::MemoryPermission owner_perm_) {
18 // Set members. 18 // Set members.
19 owner = kernel.CurrentProcess(); 19 owner = GetCurrentProcessPointer(kernel);
20 20
21 // TODO(bunnei): Lock for transfer memory 21 // TODO(bunnei): Lock for transfer memory
22 22
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index ece20a643..2ff253183 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -29,6 +29,7 @@
29#include "core/hle/kernel/k_hardware_timer.h" 29#include "core/hle/kernel/k_hardware_timer.h"
30#include "core/hle/kernel/k_memory_layout.h" 30#include "core/hle/kernel/k_memory_layout.h"
31#include "core/hle/kernel/k_memory_manager.h" 31#include "core/hle/kernel/k_memory_manager.h"
32#include "core/hle/kernel/k_object_name.h"
32#include "core/hle/kernel/k_page_buffer.h" 33#include "core/hle/kernel/k_page_buffer.h"
33#include "core/hle/kernel/k_process.h" 34#include "core/hle/kernel/k_process.h"
34#include "core/hle/kernel/k_resource_limit.h" 35#include "core/hle/kernel/k_resource_limit.h"
@@ -84,6 +85,7 @@ struct KernelCore::Impl {
84 InitializeShutdownThreads(); 85 InitializeShutdownThreads();
85 InitializePhysicalCores(); 86 InitializePhysicalCores();
86 InitializePreemption(kernel); 87 InitializePreemption(kernel);
88 InitializeGlobalData(kernel);
87 89
88 // Initialize the Dynamic Slab Heaps. 90 // Initialize the Dynamic Slab Heaps.
89 { 91 {
@@ -102,13 +104,13 @@ struct KernelCore::Impl {
102 104
103 void InitializeCores() { 105 void InitializeCores() {
104 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { 106 for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
105 cores[core_id]->Initialize((*current_process).Is64BitProcess()); 107 cores[core_id]->Initialize((*application_process).Is64BitProcess());
106 system.Memory().SetCurrentPageTable(*current_process, core_id); 108 system.Memory().SetCurrentPageTable(*application_process, core_id);
107 } 109 }
108 } 110 }
109 111
110 void CloseCurrentProcess() { 112 void CloseApplicationProcess() {
111 KProcess* old_process = current_process.exchange(nullptr); 113 KProcess* old_process = application_process.exchange(nullptr);
112 if (old_process == nullptr) { 114 if (old_process == nullptr) {
113 return; 115 return;
114 } 116 }
@@ -182,7 +184,7 @@ struct KernelCore::Impl {
182 } 184 }
183 } 185 }
184 186
185 CloseCurrentProcess(); 187 CloseApplicationProcess();
186 188
187 // Track kernel objects that were not freed on shutdown 189 // Track kernel objects that were not freed on shutdown
188 { 190 {
@@ -194,6 +196,8 @@ struct KernelCore::Impl {
194 } 196 }
195 } 197 }
196 198
199 object_name_global_data.reset();
200
197 // Ensure that the object list container is finalized and properly shutdown. 201 // Ensure that the object list container is finalized and properly shutdown.
198 global_object_list_container->Finalize(); 202 global_object_list_container->Finalize();
199 global_object_list_container.reset(); 203 global_object_list_container.reset();
@@ -363,8 +367,12 @@ struct KernelCore::Impl {
363 } 367 }
364 } 368 }
365 369
366 void MakeCurrentProcess(KProcess* process) { 370 void InitializeGlobalData(KernelCore& kernel) {
367 current_process = process; 371 object_name_global_data = std::make_unique<KObjectNameGlobalData>(kernel);
372 }
373
374 void MakeApplicationProcess(KProcess* process) {
375 application_process = process;
368 } 376 }
369 377
370 static inline thread_local u8 host_thread_id = UINT8_MAX; 378 static inline thread_local u8 host_thread_id = UINT8_MAX;
@@ -812,7 +820,7 @@ struct KernelCore::Impl {
812 820
813 // Lists all processes that exist in the current session. 821 // Lists all processes that exist in the current session.
814 std::vector<KProcess*> process_list; 822 std::vector<KProcess*> process_list;
815 std::atomic<KProcess*> current_process{}; 823 std::atomic<KProcess*> application_process{};
816 std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; 824 std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
817 std::unique_ptr<Kernel::KHardwareTimer> hardware_timer; 825 std::unique_ptr<Kernel::KHardwareTimer> hardware_timer;
818 826
@@ -829,6 +837,8 @@ struct KernelCore::Impl {
829 837
830 std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container; 838 std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container;
831 839
840 std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
841
832 /// Map of named ports managed by the kernel, which can be retrieved using 842 /// Map of named ports managed by the kernel, which can be retrieved using
833 /// the ConnectToPort SVC. 843 /// the ConnectToPort SVC.
834 std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; 844 std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
@@ -932,20 +942,20 @@ void KernelCore::AppendNewProcess(KProcess* process) {
932 impl->process_list.push_back(process); 942 impl->process_list.push_back(process);
933} 943}
934 944
935void KernelCore::MakeCurrentProcess(KProcess* process) { 945void KernelCore::MakeApplicationProcess(KProcess* process) {
936 impl->MakeCurrentProcess(process); 946 impl->MakeApplicationProcess(process);
937} 947}
938 948
939KProcess* KernelCore::CurrentProcess() { 949KProcess* KernelCore::ApplicationProcess() {
940 return impl->current_process; 950 return impl->application_process;
941} 951}
942 952
943const KProcess* KernelCore::CurrentProcess() const { 953const KProcess* KernelCore::ApplicationProcess() const {
944 return impl->current_process; 954 return impl->application_process;
945} 955}
946 956
947void KernelCore::CloseCurrentProcess() { 957void KernelCore::CloseApplicationProcess() {
948 impl->CloseCurrentProcess(); 958 impl->CloseApplicationProcess();
949} 959}
950 960
951const std::vector<KProcess*>& KernelCore::GetProcessList() const { 961const std::vector<KProcess*>& KernelCore::GetProcessList() const {
@@ -1129,6 +1139,10 @@ void KernelCore::SetCurrentEmuThread(KThread* thread) {
1129 impl->SetCurrentEmuThread(thread); 1139 impl->SetCurrentEmuThread(thread);
1130} 1140}
1131 1141
1142KObjectNameGlobalData& KernelCore::ObjectNameGlobalData() {
1143 return *impl->object_name_global_data;
1144}
1145
1132KMemoryManager& KernelCore::MemoryManager() { 1146KMemoryManager& KernelCore::MemoryManager() {
1133 return *impl->memory_manager; 1147 return *impl->memory_manager;
1134} 1148}
@@ -1137,6 +1151,14 @@ const KMemoryManager& KernelCore::MemoryManager() const {
1137 return *impl->memory_manager; 1151 return *impl->memory_manager;
1138} 1152}
1139 1153
1154KSystemResource& KernelCore::GetAppSystemResource() {
1155 return *impl->app_system_resource;
1156}
1157
1158const KSystemResource& KernelCore::GetAppSystemResource() const {
1159 return *impl->app_system_resource;
1160}
1161
1140KSystemResource& KernelCore::GetSystemSystemResource() { 1162KSystemResource& KernelCore::GetSystemSystemResource() {
1141 return *impl->sys_system_resource; 1163 return *impl->sys_system_resource;
1142} 1164}
@@ -1185,12 +1207,12 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const {
1185 return *impl->hidbus_shared_mem; 1207 return *impl->hidbus_shared_mem;
1186} 1208}
1187 1209
1188void KernelCore::Suspend(bool suspended) { 1210void KernelCore::SuspendApplication(bool suspended) {
1189 const bool should_suspend{exception_exited || suspended}; 1211 const bool should_suspend{exception_exited || suspended};
1190 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; 1212 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
1191 1213
1192 //! This refers to the application process, not the current process. 1214 // Get the application process.
1193 KScopedAutoObject<KProcess> process = CurrentProcess(); 1215 KScopedAutoObject<KProcess> process = ApplicationProcess();
1194 if (process.IsNull()) { 1216 if (process.IsNull()) {
1195 return; 1217 return;
1196 } 1218 }
@@ -1201,8 +1223,8 @@ void KernelCore::Suspend(bool suspended) {
1201 // Wait for process execution to stop. 1223 // Wait for process execution to stop.
1202 bool must_wait{should_suspend}; 1224 bool must_wait{should_suspend};
1203 1225
1204 // KernelCore::Suspend must be called from locked context, or we 1226 // KernelCore::SuspendApplication must be called from locked context,
1205 // could race another call to SetActivity, interfering with waiting. 1227 // or we could race another call to SetActivity, interfering with waiting.
1206 while (must_wait) { 1228 while (must_wait) {
1207 KScopedSchedulerLock sl{*this}; 1229 KScopedSchedulerLock sl{*this};
1208 1230
@@ -1236,9 +1258,9 @@ bool KernelCore::IsShuttingDown() const {
1236 return impl->IsShuttingDown(); 1258 return impl->IsShuttingDown();
1237} 1259}
1238 1260
1239void KernelCore::ExceptionalExit() { 1261void KernelCore::ExceptionalExitApplication() {
1240 exception_exited = true; 1262 exception_exited = true;
1241 Suspend(true); 1263 SuspendApplication(true);
1242} 1264}
1243 1265
1244void KernelCore::EnterSVCProfile() { 1266void KernelCore::EnterSVCProfile() {
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 5f52e1e95..6e0668f7f 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -44,6 +44,8 @@ class KHardwareTimer;
44class KLinkedListNode; 44class KLinkedListNode;
45class KMemoryLayout; 45class KMemoryLayout;
46class KMemoryManager; 46class KMemoryManager;
47class KObjectName;
48class KObjectNameGlobalData;
47class KPageBuffer; 49class KPageBuffer;
48class KPageBufferSlabHeap; 50class KPageBufferSlabHeap;
49class KPort; 51class KPort;
@@ -131,17 +133,17 @@ public:
131 /// Adds the given shared pointer to an internal list of active processes. 133 /// Adds the given shared pointer to an internal list of active processes.
132 void AppendNewProcess(KProcess* process); 134 void AppendNewProcess(KProcess* process);
133 135
134 /// Makes the given process the new current process. 136 /// Makes the given process the new application process.
135 void MakeCurrentProcess(KProcess* process); 137 void MakeApplicationProcess(KProcess* process);
136 138
137 /// Retrieves a pointer to the current process. 139 /// Retrieves a pointer to the application process.
138 KProcess* CurrentProcess(); 140 KProcess* ApplicationProcess();
139 141
140 /// Retrieves a const pointer to the current process. 142 /// Retrieves a const pointer to the application process.
141 const KProcess* CurrentProcess() const; 143 const KProcess* ApplicationProcess() const;
142 144
143 /// Closes the current process. 145 /// Closes the application process.
144 void CloseCurrentProcess(); 146 void CloseApplicationProcess();
145 147
146 /// Retrieves the list of processes. 148 /// Retrieves the list of processes.
147 const std::vector<KProcess*>& GetProcessList() const; 149 const std::vector<KProcess*>& GetProcessList() const;
@@ -240,12 +242,21 @@ public:
240 /// Register the current thread as a non CPU core thread. 242 /// Register the current thread as a non CPU core thread.
241 void RegisterHostThread(KThread* existing_thread = nullptr); 243 void RegisterHostThread(KThread* existing_thread = nullptr);
242 244
245 /// Gets global data for KObjectName.
246 KObjectNameGlobalData& ObjectNameGlobalData();
247
243 /// Gets the virtual memory manager for the kernel. 248 /// Gets the virtual memory manager for the kernel.
244 KMemoryManager& MemoryManager(); 249 KMemoryManager& MemoryManager();
245 250
246 /// Gets the virtual memory manager for the kernel. 251 /// Gets the virtual memory manager for the kernel.
247 const KMemoryManager& MemoryManager() const; 252 const KMemoryManager& MemoryManager() const;
248 253
254 /// Gets the application resource manager.
255 KSystemResource& GetAppSystemResource();
256
257 /// Gets the application resource manager.
258 const KSystemResource& GetAppSystemResource() const;
259
249 /// Gets the system resource manager. 260 /// Gets the system resource manager.
250 KSystemResource& GetSystemSystemResource(); 261 KSystemResource& GetSystemSystemResource();
251 262
@@ -282,11 +293,11 @@ public:
282 /// Gets the shared memory object for HIDBus services. 293 /// Gets the shared memory object for HIDBus services.
283 const Kernel::KSharedMemory& GetHidBusSharedMem() const; 294 const Kernel::KSharedMemory& GetHidBusSharedMem() const;
284 295
285 /// Suspend/unsuspend all processes. 296 /// Suspend/unsuspend application process.
286 void Suspend(bool suspend); 297 void SuspendApplication(bool suspend);
287 298
288 /// Exceptional exit all processes. 299 /// Exceptional exit application process.
289 void ExceptionalExit(); 300 void ExceptionalExitApplication();
290 301
291 /// Notify emulated CPU cores to shut down. 302 /// Notify emulated CPU cores to shut down.
292 void ShutdownCores(); 303 void ShutdownCores();
@@ -366,6 +377,8 @@ public:
366 return slab_heap_container->page_buffer; 377 return slab_heap_container->page_buffer;
367 } else if constexpr (std::is_same_v<T, KThreadLocalPage>) { 378 } else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
368 return slab_heap_container->thread_local_page; 379 return slab_heap_container->thread_local_page;
380 } else if constexpr (std::is_same_v<T, KObjectName>) {
381 return slab_heap_container->object_name;
369 } else if constexpr (std::is_same_v<T, KSessionRequest>) { 382 } else if constexpr (std::is_same_v<T, KSessionRequest>) {
370 return slab_heap_container->session_request; 383 return slab_heap_container->session_request;
371 } else if constexpr (std::is_same_v<T, KSecureSystemResource>) { 384 } else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
@@ -437,6 +450,7 @@ private:
437 KSlabHeap<KDeviceAddressSpace> device_address_space; 450 KSlabHeap<KDeviceAddressSpace> device_address_space;
438 KSlabHeap<KPageBuffer> page_buffer; 451 KSlabHeap<KPageBuffer> page_buffer;
439 KSlabHeap<KThreadLocalPage> thread_local_page; 452 KSlabHeap<KThreadLocalPage> thread_local_page;
453 KSlabHeap<KObjectName> object_name;
440 KSlabHeap<KSessionRequest> session_request; 454 KSlabHeap<KSessionRequest> session_request;
441 KSlabHeap<KSecureSystemResource> secure_system_resource; 455 KSlabHeap<KSecureSystemResource> secure_system_resource;
442 KSlabHeap<KEventInfo> event_info; 456 KSlabHeap<KEventInfo> event_info;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4cb6f40a0..1072da8cc 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1,449 +1,4435 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/common_types.h" 4// This file is automatically generated using svc_generator.py.
5
6#include <type_traits>
7
8#include "core/arm/arm_interface.h"
9#include "core/core.h"
5#include "core/hle/kernel/k_process.h" 10#include "core/hle/kernel/k_process.h"
6#include "core/hle/kernel/k_thread.h"
7#include "core/hle/kernel/svc.h" 11#include "core/hle/kernel/svc.h"
8#include "core/hle/kernel/svc_wrap.h"
9#include "core/hle/result.h"
10 12
11namespace Kernel::Svc { 13namespace Kernel::Svc {
12namespace { 14
13 15static uint32_t GetReg32(Core::System& system, int n) {
14struct FunctionDef { 16 return static_cast<uint32_t>(system.CurrentArmInterface().GetReg(n));
15 using Func = void(Core::System&); 17}
16 18
17 u32 id; 19static void SetReg32(Core::System& system, int n, uint32_t result) {
18 Func* func; 20 system.CurrentArmInterface().SetReg(n, static_cast<uint64_t>(result));
19 const char* name; 21}
20}; 22
21 23static uint64_t GetReg64(Core::System& system, int n) {
22} // namespace 24 return system.CurrentArmInterface().GetReg(n);
23 25}
24static const FunctionDef SVC_Table_32[] = { 26
25 {0x00, nullptr, "Unknown0"}, 27static void SetReg64(Core::System& system, int n, uint64_t result) {
26 {0x01, SvcWrap32<SetHeapSize32>, "SetHeapSize32"}, 28 system.CurrentArmInterface().SetReg(n, result);
27 {0x02, nullptr, "SetMemoryPermission32"}, 29}
28 {0x03, SvcWrap32<SetMemoryAttribute32>, "SetMemoryAttribute32"}, 30
29 {0x04, SvcWrap32<MapMemory32>, "MapMemory32"}, 31// Like bit_cast, but handles the case when the source and dest
30 {0x05, SvcWrap32<UnmapMemory32>, "UnmapMemory32"}, 32// are differently-sized.
31 {0x06, SvcWrap32<QueryMemory32>, "QueryMemory32"}, 33template <typename To, typename From>
32 {0x07, SvcWrap32<ExitProcess32>, "ExitProcess32"}, 34 requires(std::is_trivial_v<To> && std::is_trivially_copyable_v<From>)
33 {0x08, SvcWrap32<CreateThread32>, "CreateThread32"}, 35static To Convert(const From& from) {
34 {0x09, SvcWrap32<StartThread32>, "StartThread32"}, 36 To to{};
35 {0x0a, SvcWrap32<ExitThread32>, "ExitThread32"}, 37
36 {0x0b, SvcWrap32<SleepThread32>, "SleepThread32"}, 38 if constexpr (sizeof(To) >= sizeof(From)) {
37 {0x0c, SvcWrap32<GetThreadPriority32>, "GetThreadPriority32"}, 39 std::memcpy(&to, &from, sizeof(From));
38 {0x0d, SvcWrap32<SetThreadPriority32>, "SetThreadPriority32"}, 40 } else {
39 {0x0e, SvcWrap32<GetThreadCoreMask32>, "GetThreadCoreMask32"}, 41 std::memcpy(&to, &from, sizeof(To));
40 {0x0f, SvcWrap32<SetThreadCoreMask32>, "SetThreadCoreMask32"}, 42 }
41 {0x10, SvcWrap32<GetCurrentProcessorNumber32>, "GetCurrentProcessorNumber32"}, 43
42 {0x11, SvcWrap32<SignalEvent32>, "SignalEvent32"}, 44 return to;
43 {0x12, SvcWrap32<ClearEvent32>, "ClearEvent32"}, 45}
44 {0x13, SvcWrap32<MapSharedMemory32>, "MapSharedMemory32"}, 46
45 {0x14, SvcWrap32<UnmapSharedMemory32>, "UnmapSharedMemory32"}, 47// clang-format off
46 {0x15, SvcWrap32<CreateTransferMemory32>, "CreateTransferMemory32"}, 48static_assert(sizeof(ArbitrationType) == 4);
47 {0x16, SvcWrap32<CloseHandle32>, "CloseHandle32"}, 49static_assert(sizeof(BreakReason) == 4);
48 {0x17, SvcWrap32<ResetSignal32>, "ResetSignal32"}, 50static_assert(sizeof(CodeMemoryOperation) == 4);
49 {0x18, SvcWrap32<WaitSynchronization32>, "WaitSynchronization32"}, 51static_assert(sizeof(DebugThreadParam) == 4);
50 {0x19, SvcWrap32<CancelSynchronization32>, "CancelSynchronization32"}, 52static_assert(sizeof(DeviceName) == 4);
51 {0x1a, SvcWrap32<ArbitrateLock32>, "ArbitrateLock32"}, 53static_assert(sizeof(HardwareBreakPointRegisterName) == 4);
52 {0x1b, SvcWrap32<ArbitrateUnlock32>, "ArbitrateUnlock32"}, 54static_assert(sizeof(Handle) == 4);
53 {0x1c, SvcWrap32<WaitProcessWideKeyAtomic32>, "WaitProcessWideKeyAtomic32"}, 55static_assert(sizeof(InfoType) == 4);
54 {0x1d, SvcWrap32<SignalProcessWideKey32>, "SignalProcessWideKey32"}, 56static_assert(sizeof(InterruptType) == 4);
55 {0x1e, SvcWrap32<GetSystemTick32>, "GetSystemTick32"}, 57static_assert(sizeof(IoPoolType) == 4);
56 {0x1f, SvcWrap32<ConnectToNamedPort32>, "ConnectToNamedPort32"}, 58static_assert(sizeof(KernelDebugType) == 4);
57 {0x20, nullptr, "SendSyncRequestLight32"}, 59static_assert(sizeof(KernelTraceState) == 4);
58 {0x21, SvcWrap32<SendSyncRequest32>, "SendSyncRequest32"}, 60static_assert(sizeof(LimitableResource) == 4);
59 {0x22, nullptr, "SendSyncRequestWithUserBuffer32"}, 61static_assert(sizeof(MemoryMapping) == 4);
60 {0x23, nullptr, "SendAsyncRequestWithUserBuffer32"}, 62static_assert(sizeof(MemoryPermission) == 4);
61 {0x24, SvcWrap32<GetProcessId32>, "GetProcessId32"}, 63static_assert(sizeof(PageInfo) == 4);
62 {0x25, SvcWrap32<GetThreadId32>, "GetThreadId32"}, 64static_assert(sizeof(ProcessActivity) == 4);
63 {0x26, SvcWrap32<Break32>, "Break32"}, 65static_assert(sizeof(ProcessInfoType) == 4);
64 {0x27, SvcWrap32<OutputDebugString32>, "OutputDebugString32"}, 66static_assert(sizeof(Result) == 4);
65 {0x28, nullptr, "ReturnFromException32"}, 67static_assert(sizeof(SignalType) == 4);
66 {0x29, SvcWrap32<GetInfo32>, "GetInfo32"}, 68static_assert(sizeof(SystemInfoType) == 4);
67 {0x2a, nullptr, "FlushEntireDataCache32"}, 69static_assert(sizeof(ThreadActivity) == 4);
68 {0x2b, nullptr, "FlushDataCache32"}, 70static_assert(sizeof(ilp32::LastThreadContext) == 16);
69 {0x2c, SvcWrap32<MapPhysicalMemory32>, "MapPhysicalMemory32"}, 71static_assert(sizeof(ilp32::PhysicalMemoryInfo) == 16);
70 {0x2d, SvcWrap32<UnmapPhysicalMemory32>, "UnmapPhysicalMemory32"}, 72static_assert(sizeof(ilp32::SecureMonitorArguments) == 32);
71 {0x2e, nullptr, "GetDebugFutureThreadInfo32"}, 73static_assert(sizeof(lp64::LastThreadContext) == 32);
72 {0x2f, nullptr, "GetLastThreadInfo32"}, 74static_assert(sizeof(lp64::PhysicalMemoryInfo) == 24);
73 {0x30, nullptr, "GetResourceLimitLimitValue32"}, 75static_assert(sizeof(lp64::SecureMonitorArguments) == 64);
74 {0x31, nullptr, "GetResourceLimitCurrentValue32"}, 76static_assert(sizeof(bool) == 1);
75 {0x32, SvcWrap32<SetThreadActivity32>, "SetThreadActivity32"}, 77static_assert(sizeof(int32_t) == 4);
76 {0x33, SvcWrap32<GetThreadContext32>, "GetThreadContext32"}, 78static_assert(sizeof(int64_t) == 8);
77 {0x34, SvcWrap32<WaitForAddress32>, "WaitForAddress32"}, 79static_assert(sizeof(uint32_t) == 4);
78 {0x35, SvcWrap32<SignalToAddress32>, "SignalToAddress32"}, 80static_assert(sizeof(uint64_t) == 8);
79 {0x36, SvcWrap32<SynchronizePreemptionState>, "SynchronizePreemptionState32"}, 81
80 {0x37, nullptr, "GetResourceLimitPeakValue32"}, 82static void SvcWrap_SetHeapSize64From32(Core::System& system) {
81 {0x38, nullptr, "Unknown38"}, 83 Result ret{};
82 {0x39, nullptr, "CreateIoPool32"}, 84
83 {0x3a, nullptr, "CreateIoRegion32"}, 85 uintptr_t out_address{};
84 {0x3b, nullptr, "Unknown3b"}, 86 uint32_t size{};
85 {0x3c, nullptr, "KernelDebug32"}, 87
86 {0x3d, nullptr, "ChangeKernelTraceState32"}, 88 size = Convert<uint32_t>(GetReg32(system, 1));
87 {0x3e, nullptr, "Unknown3e"}, 89
88 {0x3f, nullptr, "Unknown3f"}, 90 ret = SetHeapSize64From32(system, &out_address, size);
89 {0x40, nullptr, "CreateSession32"}, 91
90 {0x41, nullptr, "AcceptSession32"}, 92 SetReg32(system, 0, Convert<uint32_t>(ret));
91 {0x42, nullptr, "ReplyAndReceiveLight32"}, 93 SetReg32(system, 1, Convert<uint32_t>(out_address));
92 {0x43, nullptr, "ReplyAndReceive32"}, 94}
93 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer32"}, 95
94 {0x45, SvcWrap32<CreateEvent32>, "CreateEvent32"}, 96static void SvcWrap_SetMemoryPermission64From32(Core::System& system) {
95 {0x46, nullptr, "MapIoRegion32"}, 97 Result ret{};
96 {0x47, nullptr, "UnmapIoRegion32"}, 98
97 {0x48, nullptr, "MapPhysicalMemoryUnsafe32"}, 99 uint32_t address{};
98 {0x49, nullptr, "UnmapPhysicalMemoryUnsafe32"}, 100 uint32_t size{};
99 {0x4a, nullptr, "SetUnsafeLimit32"}, 101 MemoryPermission perm{};
100 {0x4b, SvcWrap32<CreateCodeMemory32>, "CreateCodeMemory32"}, 102
101 {0x4c, SvcWrap32<ControlCodeMemory32>, "ControlCodeMemory32"}, 103 address = Convert<uint32_t>(GetReg32(system, 0));
102 {0x4d, nullptr, "SleepSystem32"}, 104 size = Convert<uint32_t>(GetReg32(system, 1));
103 {0x4e, nullptr, "ReadWriteRegister32"}, 105 perm = Convert<MemoryPermission>(GetReg32(system, 2));
104 {0x4f, nullptr, "SetProcessActivity32"}, 106
105 {0x50, nullptr, "CreateSharedMemory32"}, 107 ret = SetMemoryPermission64From32(system, address, size, perm);
106 {0x51, nullptr, "MapTransferMemory32"}, 108
107 {0x52, nullptr, "UnmapTransferMemory32"}, 109 SetReg32(system, 0, Convert<uint32_t>(ret));
108 {0x53, nullptr, "CreateInterruptEvent32"}, 110}
109 {0x54, nullptr, "QueryPhysicalAddress32"}, 111
110 {0x55, nullptr, "QueryIoMapping32"}, 112static void SvcWrap_SetMemoryAttribute64From32(Core::System& system) {
111 {0x56, nullptr, "CreateDeviceAddressSpace32"}, 113 Result ret{};
112 {0x57, nullptr, "AttachDeviceAddressSpace32"}, 114
113 {0x58, nullptr, "DetachDeviceAddressSpace32"}, 115 uint32_t address{};
114 {0x59, nullptr, "MapDeviceAddressSpaceByForce32"}, 116 uint32_t size{};
115 {0x5a, nullptr, "MapDeviceAddressSpaceAligned32"}, 117 uint32_t mask{};
116 {0x5b, nullptr, "MapDeviceAddressSpace32"}, 118 uint32_t attr{};
117 {0x5c, nullptr, "UnmapDeviceAddressSpace32"}, 119
118 {0x5d, nullptr, "InvalidateProcessDataCache32"}, 120 address = Convert<uint32_t>(GetReg32(system, 0));
119 {0x5e, nullptr, "StoreProcessDataCache32"}, 121 size = Convert<uint32_t>(GetReg32(system, 1));
120 {0x5F, SvcWrap32<FlushProcessDataCache32>, "FlushProcessDataCache32"}, 122 mask = Convert<uint32_t>(GetReg32(system, 2));
121 {0x60, nullptr, "StoreProcessDataCache32"}, 123 attr = Convert<uint32_t>(GetReg32(system, 3));
122 {0x61, nullptr, "BreakDebugProcess32"}, 124
123 {0x62, nullptr, "TerminateDebugProcess32"}, 125 ret = SetMemoryAttribute64From32(system, address, size, mask, attr);
124 {0x63, nullptr, "GetDebugEvent32"}, 126
125 {0x64, nullptr, "ContinueDebugEvent32"}, 127 SetReg32(system, 0, Convert<uint32_t>(ret));
126 {0x65, nullptr, "GetProcessList32"}, 128}
127 {0x66, nullptr, "GetThreadList"}, 129
128 {0x67, nullptr, "GetDebugThreadContext32"}, 130static void SvcWrap_MapMemory64From32(Core::System& system) {
129 {0x68, nullptr, "SetDebugThreadContext32"}, 131 Result ret{};
130 {0x69, nullptr, "QueryDebugProcessMemory32"}, 132
131 {0x6A, nullptr, "ReadDebugProcessMemory32"}, 133 uint32_t dst_address{};
132 {0x6B, nullptr, "WriteDebugProcessMemory32"}, 134 uint32_t src_address{};
133 {0x6C, nullptr, "SetHardwareBreakPoint32"}, 135 uint32_t size{};
134 {0x6D, nullptr, "GetDebugThreadParam32"}, 136
135 {0x6E, nullptr, "Unknown6E"}, 137 dst_address = Convert<uint32_t>(GetReg32(system, 0));
136 {0x6f, nullptr, "GetSystemInfo32"}, 138 src_address = Convert<uint32_t>(GetReg32(system, 1));
137 {0x70, nullptr, "CreatePort32"}, 139 size = Convert<uint32_t>(GetReg32(system, 2));
138 {0x71, nullptr, "ManageNamedPort32"}, 140
139 {0x72, nullptr, "ConnectToPort32"}, 141 ret = MapMemory64From32(system, dst_address, src_address, size);
140 {0x73, nullptr, "SetProcessMemoryPermission32"}, 142
141 {0x74, nullptr, "MapProcessMemory32"}, 143 SetReg32(system, 0, Convert<uint32_t>(ret));
142 {0x75, nullptr, "UnmapProcessMemory32"}, 144}
143 {0x76, nullptr, "QueryProcessMemory32"}, 145
144 {0x77, nullptr, "MapProcessCodeMemory32"}, 146static void SvcWrap_UnmapMemory64From32(Core::System& system) {
145 {0x78, nullptr, "UnmapProcessCodeMemory32"}, 147 Result ret{};
146 {0x79, nullptr, "CreateProcess32"}, 148
147 {0x7A, nullptr, "StartProcess32"}, 149 uint32_t dst_address{};
148 {0x7B, nullptr, "TerminateProcess32"}, 150 uint32_t src_address{};
149 {0x7C, nullptr, "GetProcessInfo32"}, 151 uint32_t size{};
150 {0x7D, nullptr, "CreateResourceLimit32"}, 152
151 {0x7E, nullptr, "SetResourceLimitLimitValue32"}, 153 dst_address = Convert<uint32_t>(GetReg32(system, 0));
152 {0x7F, nullptr, "CallSecureMonitor32"}, 154 src_address = Convert<uint32_t>(GetReg32(system, 1));
153 {0x80, nullptr, "Unknown"}, 155 size = Convert<uint32_t>(GetReg32(system, 2));
154 {0x81, nullptr, "Unknown"}, 156
155 {0x82, nullptr, "Unknown"}, 157 ret = UnmapMemory64From32(system, dst_address, src_address, size);
156 {0x83, nullptr, "Unknown"}, 158
157 {0x84, nullptr, "Unknown"}, 159 SetReg32(system, 0, Convert<uint32_t>(ret));
158 {0x85, nullptr, "Unknown"}, 160}
159 {0x86, nullptr, "Unknown"}, 161
160 {0x87, nullptr, "Unknown"}, 162static void SvcWrap_QueryMemory64From32(Core::System& system) {
161 {0x88, nullptr, "Unknown"}, 163 Result ret{};
162 {0x89, nullptr, "Unknown"}, 164
163 {0x8A, nullptr, "Unknown"}, 165 PageInfo out_page_info{};
164 {0x8B, nullptr, "Unknown"}, 166 uint32_t out_memory_info{};
165 {0x8C, nullptr, "Unknown"}, 167 uint32_t address{};
166 {0x8D, nullptr, "Unknown"}, 168
167 {0x8E, nullptr, "Unknown"}, 169 out_memory_info = Convert<uint32_t>(GetReg32(system, 0));
168 {0x8F, nullptr, "Unknown"}, 170 address = Convert<uint32_t>(GetReg32(system, 2));
169 {0x90, nullptr, "Unknown"}, 171
170 {0x91, nullptr, "Unknown"}, 172 ret = QueryMemory64From32(system, out_memory_info, &out_page_info, address);
171 {0x92, nullptr, "Unknown"}, 173
172 {0x93, nullptr, "Unknown"}, 174 SetReg32(system, 0, Convert<uint32_t>(ret));
173 {0x94, nullptr, "Unknown"}, 175 SetReg32(system, 1, Convert<uint32_t>(out_page_info));
174 {0x95, nullptr, "Unknown"}, 176}
175 {0x96, nullptr, "Unknown"}, 177
176 {0x97, nullptr, "Unknown"}, 178static void SvcWrap_ExitProcess64From32(Core::System& system) {
177 {0x98, nullptr, "Unknown"}, 179 ExitProcess64From32(system);
178 {0x99, nullptr, "Unknown"}, 180}
179 {0x9A, nullptr, "Unknown"}, 181
180 {0x9B, nullptr, "Unknown"}, 182static void SvcWrap_CreateThread64From32(Core::System& system) {
181 {0x9C, nullptr, "Unknown"}, 183 Result ret{};
182 {0x9D, nullptr, "Unknown"}, 184
183 {0x9E, nullptr, "Unknown"}, 185 Handle out_handle{};
184 {0x9F, nullptr, "Unknown"}, 186 uint32_t func{};
185 {0xA0, nullptr, "Unknown"}, 187 uint32_t arg{};
186 {0xA1, nullptr, "Unknown"}, 188 uint32_t stack_bottom{};
187 {0xA2, nullptr, "Unknown"}, 189 int32_t priority{};
188 {0xA3, nullptr, "Unknown"}, 190 int32_t core_id{};
189 {0xA4, nullptr, "Unknown"}, 191
190 {0xA5, nullptr, "Unknown"}, 192 func = Convert<uint32_t>(GetReg32(system, 1));
191 {0xA6, nullptr, "Unknown"}, 193 arg = Convert<uint32_t>(GetReg32(system, 2));
192 {0xA7, nullptr, "Unknown"}, 194 stack_bottom = Convert<uint32_t>(GetReg32(system, 3));
193 {0xA8, nullptr, "Unknown"}, 195 priority = Convert<int32_t>(GetReg32(system, 0));
194 {0xA9, nullptr, "Unknown"}, 196 core_id = Convert<int32_t>(GetReg32(system, 4));
195 {0xAA, nullptr, "Unknown"}, 197
196 {0xAB, nullptr, "Unknown"}, 198 ret = CreateThread64From32(system, &out_handle, func, arg, stack_bottom, priority, core_id);
197 {0xAC, nullptr, "Unknown"}, 199
198 {0xAD, nullptr, "Unknown"}, 200 SetReg32(system, 0, Convert<uint32_t>(ret));
199 {0xAE, nullptr, "Unknown"}, 201 SetReg32(system, 1, Convert<uint32_t>(out_handle));
200 {0xAF, nullptr, "Unknown"}, 202}
201 {0xB0, nullptr, "Unknown"}, 203
202 {0xB1, nullptr, "Unknown"}, 204static void SvcWrap_StartThread64From32(Core::System& system) {
203 {0xB2, nullptr, "Unknown"}, 205 Result ret{};
204 {0xB3, nullptr, "Unknown"}, 206
205 {0xB4, nullptr, "Unknown"}, 207 Handle thread_handle{};
206 {0xB5, nullptr, "Unknown"}, 208
207 {0xB6, nullptr, "Unknown"}, 209 thread_handle = Convert<Handle>(GetReg32(system, 0));
208 {0xB7, nullptr, "Unknown"}, 210
209 {0xB8, nullptr, "Unknown"}, 211 ret = StartThread64From32(system, thread_handle);
210 {0xB9, nullptr, "Unknown"}, 212
211 {0xBA, nullptr, "Unknown"}, 213 SetReg32(system, 0, Convert<uint32_t>(ret));
212 {0xBB, nullptr, "Unknown"}, 214}
213 {0xBC, nullptr, "Unknown"}, 215
214 {0xBD, nullptr, "Unknown"}, 216static void SvcWrap_ExitThread64From32(Core::System& system) {
215 {0xBE, nullptr, "Unknown"}, 217 ExitThread64From32(system);
216 {0xBF, nullptr, "Unknown"}, 218}
217}; 219
218 220static void SvcWrap_SleepThread64From32(Core::System& system) {
219static const FunctionDef SVC_Table_64[] = { 221 int64_t ns{};
220 {0x00, nullptr, "Unknown0"}, 222
221 {0x01, SvcWrap64<SetHeapSize>, "SetHeapSize"}, 223 std::array<uint32_t, 2> ns_gather{};
222 {0x02, SvcWrap64<SetMemoryPermission>, "SetMemoryPermission"}, 224 ns_gather[0] = GetReg32(system, 0);
223 {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, 225 ns_gather[1] = GetReg32(system, 1);
224 {0x04, SvcWrap64<MapMemory>, "MapMemory"}, 226 ns = Convert<int64_t>(ns_gather);
225 {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, 227
226 {0x06, SvcWrap64<QueryMemory>, "QueryMemory"}, 228 SleepThread64From32(system, ns);
227 {0x07, SvcWrap64<ExitProcess>, "ExitProcess"}, 229}
228 {0x08, SvcWrap64<CreateThread>, "CreateThread"}, 230
229 {0x09, SvcWrap64<StartThread>, "StartThread"}, 231static void SvcWrap_GetThreadPriority64From32(Core::System& system) {
230 {0x0A, SvcWrap64<ExitThread>, "ExitThread"}, 232 Result ret{};
231 {0x0B, SvcWrap64<SleepThread>, "SleepThread"}, 233
232 {0x0C, SvcWrap64<GetThreadPriority>, "GetThreadPriority"}, 234 int32_t out_priority{};
233 {0x0D, SvcWrap64<SetThreadPriority>, "SetThreadPriority"}, 235 Handle thread_handle{};
234 {0x0E, SvcWrap64<GetThreadCoreMask>, "GetThreadCoreMask"}, 236
235 {0x0F, SvcWrap64<SetThreadCoreMask>, "SetThreadCoreMask"}, 237 thread_handle = Convert<Handle>(GetReg32(system, 1));
236 {0x10, SvcWrap64<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"}, 238
237 {0x11, SvcWrap64<SignalEvent>, "SignalEvent"}, 239 ret = GetThreadPriority64From32(system, &out_priority, thread_handle);
238 {0x12, SvcWrap64<ClearEvent>, "ClearEvent"}, 240
239 {0x13, SvcWrap64<MapSharedMemory>, "MapSharedMemory"}, 241 SetReg32(system, 0, Convert<uint32_t>(ret));
240 {0x14, SvcWrap64<UnmapSharedMemory>, "UnmapSharedMemory"}, 242 SetReg32(system, 1, Convert<uint32_t>(out_priority));
241 {0x15, SvcWrap64<CreateTransferMemory>, "CreateTransferMemory"}, 243}
242 {0x16, SvcWrap64<CloseHandle>, "CloseHandle"}, 244
243 {0x17, SvcWrap64<ResetSignal>, "ResetSignal"}, 245static void SvcWrap_SetThreadPriority64From32(Core::System& system) {
244 {0x18, SvcWrap64<WaitSynchronization>, "WaitSynchronization"}, 246 Result ret{};
245 {0x19, SvcWrap64<CancelSynchronization>, "CancelSynchronization"}, 247
246 {0x1A, SvcWrap64<ArbitrateLock>, "ArbitrateLock"}, 248 Handle thread_handle{};
247 {0x1B, SvcWrap64<ArbitrateUnlock>, "ArbitrateUnlock"}, 249 int32_t priority{};
248 {0x1C, SvcWrap64<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"}, 250
249 {0x1D, SvcWrap64<SignalProcessWideKey>, "SignalProcessWideKey"}, 251 thread_handle = Convert<Handle>(GetReg32(system, 0));
250 {0x1E, SvcWrap64<GetSystemTick>, "GetSystemTick"}, 252 priority = Convert<int32_t>(GetReg32(system, 1));
251 {0x1F, SvcWrap64<ConnectToNamedPort>, "ConnectToNamedPort"}, 253
252 {0x20, nullptr, "SendSyncRequestLight"}, 254 ret = SetThreadPriority64From32(system, thread_handle, priority);
253 {0x21, SvcWrap64<SendSyncRequest>, "SendSyncRequest"}, 255
254 {0x22, nullptr, "SendSyncRequestWithUserBuffer"}, 256 SetReg32(system, 0, Convert<uint32_t>(ret));
255 {0x23, nullptr, "SendAsyncRequestWithUserBuffer"}, 257}
256 {0x24, SvcWrap64<GetProcessId>, "GetProcessId"}, 258
257 {0x25, SvcWrap64<GetThreadId>, "GetThreadId"}, 259static void SvcWrap_GetThreadCoreMask64From32(Core::System& system) {
258 {0x26, SvcWrap64<Break>, "Break"}, 260 Result ret{};
259 {0x27, SvcWrap64<OutputDebugString>, "OutputDebugString"}, 261
260 {0x28, nullptr, "ReturnFromException"}, 262 int32_t out_core_id{};
261 {0x29, SvcWrap64<GetInfo>, "GetInfo"}, 263 uint64_t out_affinity_mask{};
262 {0x2A, nullptr, "FlushEntireDataCache"}, 264 Handle thread_handle{};
263 {0x2B, nullptr, "FlushDataCache"}, 265
264 {0x2C, SvcWrap64<MapPhysicalMemory>, "MapPhysicalMemory"}, 266 thread_handle = Convert<Handle>(GetReg32(system, 2));
265 {0x2D, SvcWrap64<UnmapPhysicalMemory>, "UnmapPhysicalMemory"}, 267
266 {0x2E, nullptr, "GetFutureThreadInfo"}, 268 ret = GetThreadCoreMask64From32(system, &out_core_id, &out_affinity_mask, thread_handle);
267 {0x2F, nullptr, "GetLastThreadInfo"}, 269
268 {0x30, SvcWrap64<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, 270 SetReg32(system, 0, Convert<uint32_t>(ret));
269 {0x31, SvcWrap64<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"}, 271 SetReg32(system, 1, Convert<uint32_t>(out_core_id));
270 {0x32, SvcWrap64<SetThreadActivity>, "SetThreadActivity"}, 272 auto out_affinity_mask_scatter = Convert<std::array<uint32_t, 2>>(out_affinity_mask);
271 {0x33, SvcWrap64<GetThreadContext>, "GetThreadContext"}, 273 SetReg32(system, 2, out_affinity_mask_scatter[0]);
272 {0x34, SvcWrap64<WaitForAddress>, "WaitForAddress"}, 274 SetReg32(system, 3, out_affinity_mask_scatter[1]);
273 {0x35, SvcWrap64<SignalToAddress>, "SignalToAddress"}, 275}
274 {0x36, SvcWrap64<SynchronizePreemptionState>, "SynchronizePreemptionState"}, 276
275 {0x37, nullptr, "GetResourceLimitPeakValue"}, 277static void SvcWrap_SetThreadCoreMask64From32(Core::System& system) {
276 {0x38, nullptr, "Unknown38"}, 278 Result ret{};
277 {0x39, nullptr, "CreateIoPool"}, 279
278 {0x3A, nullptr, "CreateIoRegion"}, 280 Handle thread_handle{};
279 {0x3B, nullptr, "Unknown3B"}, 281 int32_t core_id{};
280 {0x3C, SvcWrap64<KernelDebug>, "KernelDebug"}, 282 uint64_t affinity_mask{};
281 {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, 283
282 {0x3E, nullptr, "Unknown3e"}, 284 thread_handle = Convert<Handle>(GetReg32(system, 0));
283 {0x3F, nullptr, "Unknown3f"}, 285 core_id = Convert<int32_t>(GetReg32(system, 1));
284 {0x40, SvcWrap64<CreateSession>, "CreateSession"}, 286 std::array<uint32_t, 2> affinity_mask_gather{};
285 {0x41, nullptr, "AcceptSession"}, 287 affinity_mask_gather[0] = GetReg32(system, 2);
286 {0x42, nullptr, "ReplyAndReceiveLight"}, 288 affinity_mask_gather[1] = GetReg32(system, 3);
287 {0x43, SvcWrap64<ReplyAndReceive>, "ReplyAndReceive"}, 289 affinity_mask = Convert<uint64_t>(affinity_mask_gather);
288 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, 290
289 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"}, 291 ret = SetThreadCoreMask64From32(system, thread_handle, core_id, affinity_mask);
290 {0x46, nullptr, "MapIoRegion"}, 292
291 {0x47, nullptr, "UnmapIoRegion"}, 293 SetReg32(system, 0, Convert<uint32_t>(ret));
292 {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, 294}
293 {0x49, nullptr, "UnmapPhysicalMemoryUnsafe"}, 295
294 {0x4A, nullptr, "SetUnsafeLimit"}, 296static void SvcWrap_GetCurrentProcessorNumber64From32(Core::System& system) {
295 {0x4B, SvcWrap64<CreateCodeMemory>, "CreateCodeMemory"}, 297 int32_t ret{};
296 {0x4C, SvcWrap64<ControlCodeMemory>, "ControlCodeMemory"}, 298
297 {0x4D, nullptr, "SleepSystem"}, 299 ret = GetCurrentProcessorNumber64From32(system);
298 {0x4E, nullptr, "ReadWriteRegister"}, 300
299 {0x4F, nullptr, "SetProcessActivity"}, 301 SetReg32(system, 0, Convert<uint32_t>(ret));
300 {0x50, nullptr, "CreateSharedMemory"}, 302}
301 {0x51, nullptr, "MapTransferMemory"}, 303
302 {0x52, nullptr, "UnmapTransferMemory"}, 304static void SvcWrap_SignalEvent64From32(Core::System& system) {
303 {0x53, nullptr, "CreateInterruptEvent"}, 305 Result ret{};
304 {0x54, nullptr, "QueryPhysicalAddress"}, 306
305 {0x55, nullptr, "QueryIoMapping"}, 307 Handle event_handle{};
306 {0x56, nullptr, "CreateDeviceAddressSpace"}, 308
307 {0x57, nullptr, "AttachDeviceAddressSpace"}, 309 event_handle = Convert<Handle>(GetReg32(system, 0));
308 {0x58, nullptr, "DetachDeviceAddressSpace"}, 310
309 {0x59, nullptr, "MapDeviceAddressSpaceByForce"}, 311 ret = SignalEvent64From32(system, event_handle);
310 {0x5A, nullptr, "MapDeviceAddressSpaceAligned"}, 312
311 {0x5B, nullptr, "MapDeviceAddressSpace"}, 313 SetReg32(system, 0, Convert<uint32_t>(ret));
312 {0x5C, nullptr, "UnmapDeviceAddressSpace"}, 314}
313 {0x5D, nullptr, "InvalidateProcessDataCache"}, 315
314 {0x5E, nullptr, "StoreProcessDataCache"}, 316static void SvcWrap_ClearEvent64From32(Core::System& system) {
315 {0x5F, nullptr, "FlushProcessDataCache"}, 317 Result ret{};
316 {0x60, nullptr, "DebugActiveProcess"}, 318
317 {0x61, nullptr, "BreakDebugProcess"}, 319 Handle event_handle{};
318 {0x62, nullptr, "TerminateDebugProcess"}, 320
319 {0x63, nullptr, "GetDebugEvent"}, 321 event_handle = Convert<Handle>(GetReg32(system, 0));
320 {0x64, nullptr, "ContinueDebugEvent"}, 322
321 {0x65, SvcWrap64<GetProcessList>, "GetProcessList"}, 323 ret = ClearEvent64From32(system, event_handle);
322 {0x66, SvcWrap64<GetThreadList>, "GetThreadList"}, 324
323 {0x67, nullptr, "GetDebugThreadContext"}, 325 SetReg32(system, 0, Convert<uint32_t>(ret));
324 {0x68, nullptr, "SetDebugThreadContext"}, 326}
325 {0x69, nullptr, "QueryDebugProcessMemory"}, 327
326 {0x6A, nullptr, "ReadDebugProcessMemory"}, 328static void SvcWrap_MapSharedMemory64From32(Core::System& system) {
327 {0x6B, nullptr, "WriteDebugProcessMemory"}, 329 Result ret{};
328 {0x6C, nullptr, "SetHardwareBreakPoint"}, 330
329 {0x6D, nullptr, "GetDebugThreadParam"}, 331 Handle shmem_handle{};
330 {0x6E, nullptr, "Unknown6E"}, 332 uint32_t address{};
331 {0x6F, nullptr, "GetSystemInfo"}, 333 uint32_t size{};
332 {0x70, nullptr, "CreatePort"}, 334 MemoryPermission map_perm{};
333 {0x71, nullptr, "ManageNamedPort"}, 335
334 {0x72, nullptr, "ConnectToPort"}, 336 shmem_handle = Convert<Handle>(GetReg32(system, 0));
335 {0x73, SvcWrap64<SetProcessMemoryPermission>, "SetProcessMemoryPermission"}, 337 address = Convert<uint32_t>(GetReg32(system, 1));
336 {0x74, SvcWrap64<MapProcessMemory>, "MapProcessMemory"}, 338 size = Convert<uint32_t>(GetReg32(system, 2));
337 {0x75, SvcWrap64<UnmapProcessMemory>, "UnmapProcessMemory"}, 339 map_perm = Convert<MemoryPermission>(GetReg32(system, 3));
338 {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, 340
339 {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"}, 341 ret = MapSharedMemory64From32(system, shmem_handle, address, size, map_perm);
340 {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, 342
341 {0x79, nullptr, "CreateProcess"}, 343 SetReg32(system, 0, Convert<uint32_t>(ret));
342 {0x7A, nullptr, "StartProcess"}, 344}
343 {0x7B, nullptr, "TerminateProcess"}, 345
344 {0x7C, SvcWrap64<GetProcessInfo>, "GetProcessInfo"}, 346static void SvcWrap_UnmapSharedMemory64From32(Core::System& system) {
345 {0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"}, 347 Result ret{};
346 {0x7E, SvcWrap64<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"}, 348
347 {0x7F, nullptr, "CallSecureMonitor"}, 349 Handle shmem_handle{};
348 {0x80, nullptr, "Unknown"}, 350 uint32_t address{};
349 {0x81, nullptr, "Unknown"}, 351 uint32_t size{};
350 {0x82, nullptr, "Unknown"}, 352
351 {0x83, nullptr, "Unknown"}, 353 shmem_handle = Convert<Handle>(GetReg32(system, 0));
352 {0x84, nullptr, "Unknown"}, 354 address = Convert<uint32_t>(GetReg32(system, 1));
353 {0x85, nullptr, "Unknown"}, 355 size = Convert<uint32_t>(GetReg32(system, 2));
354 {0x86, nullptr, "Unknown"}, 356
355 {0x87, nullptr, "Unknown"}, 357 ret = UnmapSharedMemory64From32(system, shmem_handle, address, size);
356 {0x88, nullptr, "Unknown"}, 358
357 {0x89, nullptr, "Unknown"}, 359 SetReg32(system, 0, Convert<uint32_t>(ret));
358 {0x8A, nullptr, "Unknown"}, 360}
359 {0x8B, nullptr, "Unknown"}, 361
360 {0x8C, nullptr, "Unknown"}, 362static void SvcWrap_CreateTransferMemory64From32(Core::System& system) {
361 {0x8D, nullptr, "Unknown"}, 363 Result ret{};
362 {0x8E, nullptr, "Unknown"}, 364
363 {0x8F, nullptr, "Unknown"}, 365 Handle out_handle{};
364 {0x90, nullptr, "Unknown"}, 366 uint32_t address{};
365 {0x91, nullptr, "Unknown"}, 367 uint32_t size{};
366 {0x92, nullptr, "Unknown"}, 368 MemoryPermission map_perm{};
367 {0x93, nullptr, "Unknown"}, 369
368 {0x94, nullptr, "Unknown"}, 370 address = Convert<uint32_t>(GetReg32(system, 1));
369 {0x95, nullptr, "Unknown"}, 371 size = Convert<uint32_t>(GetReg32(system, 2));
370 {0x96, nullptr, "Unknown"}, 372 map_perm = Convert<MemoryPermission>(GetReg32(system, 3));
371 {0x97, nullptr, "Unknown"}, 373
372 {0x98, nullptr, "Unknown"}, 374 ret = CreateTransferMemory64From32(system, &out_handle, address, size, map_perm);
373 {0x99, nullptr, "Unknown"}, 375
374 {0x9A, nullptr, "Unknown"}, 376 SetReg32(system, 0, Convert<uint32_t>(ret));
375 {0x9B, nullptr, "Unknown"}, 377 SetReg32(system, 1, Convert<uint32_t>(out_handle));
376 {0x9C, nullptr, "Unknown"}, 378}
377 {0x9D, nullptr, "Unknown"}, 379
378 {0x9E, nullptr, "Unknown"}, 380static void SvcWrap_CloseHandle64From32(Core::System& system) {
379 {0x9F, nullptr, "Unknown"}, 381 Result ret{};
380 {0xA0, nullptr, "Unknown"}, 382
381 {0xA1, nullptr, "Unknown"}, 383 Handle handle{};
382 {0xA2, nullptr, "Unknown"}, 384
383 {0xA3, nullptr, "Unknown"}, 385 handle = Convert<Handle>(GetReg32(system, 0));
384 {0xA4, nullptr, "Unknown"}, 386
385 {0xA5, nullptr, "Unknown"}, 387 ret = CloseHandle64From32(system, handle);
386 {0xA6, nullptr, "Unknown"}, 388
387 {0xA7, nullptr, "Unknown"}, 389 SetReg32(system, 0, Convert<uint32_t>(ret));
388 {0xA8, nullptr, "Unknown"}, 390}
389 {0xA9, nullptr, "Unknown"}, 391
390 {0xAA, nullptr, "Unknown"}, 392static void SvcWrap_ResetSignal64From32(Core::System& system) {
391 {0xAB, nullptr, "Unknown"}, 393 Result ret{};
392 {0xAC, nullptr, "Unknown"}, 394
393 {0xAD, nullptr, "Unknown"}, 395 Handle handle{};
394 {0xAE, nullptr, "Unknown"}, 396
395 {0xAF, nullptr, "Unknown"}, 397 handle = Convert<Handle>(GetReg32(system, 0));
396 {0xB0, nullptr, "Unknown"}, 398
397 {0xB1, nullptr, "Unknown"}, 399 ret = ResetSignal64From32(system, handle);
398 {0xB2, nullptr, "Unknown"}, 400
399 {0xB3, nullptr, "Unknown"}, 401 SetReg32(system, 0, Convert<uint32_t>(ret));
400 {0xB4, nullptr, "Unknown"}, 402}
401 {0xB5, nullptr, "Unknown"}, 403
402 {0xB6, nullptr, "Unknown"}, 404static void SvcWrap_WaitSynchronization64From32(Core::System& system) {
403 {0xB7, nullptr, "Unknown"}, 405 Result ret{};
404 {0xB8, nullptr, "Unknown"}, 406
405 {0xB9, nullptr, "Unknown"}, 407 int32_t out_index{};
406 {0xBA, nullptr, "Unknown"}, 408 uint32_t handles{};
407 {0xBB, nullptr, "Unknown"}, 409 int32_t num_handles{};
408 {0xBC, nullptr, "Unknown"}, 410 int64_t timeout_ns{};
409 {0xBD, nullptr, "Unknown"}, 411
410 {0xBE, nullptr, "Unknown"}, 412 handles = Convert<uint32_t>(GetReg32(system, 1));
411 {0xBF, nullptr, "Unknown"}, 413 num_handles = Convert<int32_t>(GetReg32(system, 2));
412}; 414 std::array<uint32_t, 2> timeout_ns_gather{};
413 415 timeout_ns_gather[0] = GetReg32(system, 0);
414static const FunctionDef* GetSVCInfo32(u32 func_num) { 416 timeout_ns_gather[1] = GetReg32(system, 3);
415 if (func_num >= std::size(SVC_Table_32)) { 417 timeout_ns = Convert<int64_t>(timeout_ns_gather);
416 LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); 418
417 return nullptr; 419 ret = WaitSynchronization64From32(system, &out_index, handles, num_handles, timeout_ns);
420
421 SetReg32(system, 0, Convert<uint32_t>(ret));
422 SetReg32(system, 1, Convert<uint32_t>(out_index));
423}
424
425static void SvcWrap_CancelSynchronization64From32(Core::System& system) {
426 Result ret{};
427
428 Handle handle{};
429
430 handle = Convert<Handle>(GetReg32(system, 0));
431
432 ret = CancelSynchronization64From32(system, handle);
433
434 SetReg32(system, 0, Convert<uint32_t>(ret));
435}
436
437static void SvcWrap_ArbitrateLock64From32(Core::System& system) {
438 Result ret{};
439
440 Handle thread_handle{};
441 uint32_t address{};
442 uint32_t tag{};
443
444 thread_handle = Convert<Handle>(GetReg32(system, 0));
445 address = Convert<uint32_t>(GetReg32(system, 1));
446 tag = Convert<uint32_t>(GetReg32(system, 2));
447
448 ret = ArbitrateLock64From32(system, thread_handle, address, tag);
449
450 SetReg32(system, 0, Convert<uint32_t>(ret));
451}
452
453static void SvcWrap_ArbitrateUnlock64From32(Core::System& system) {
454 Result ret{};
455
456 uint32_t address{};
457
458 address = Convert<uint32_t>(GetReg32(system, 0));
459
460 ret = ArbitrateUnlock64From32(system, address);
461
462 SetReg32(system, 0, Convert<uint32_t>(ret));
463}
464
465static void SvcWrap_WaitProcessWideKeyAtomic64From32(Core::System& system) {
466 Result ret{};
467
468 uint32_t address{};
469 uint32_t cv_key{};
470 uint32_t tag{};
471 int64_t timeout_ns{};
472
473 address = Convert<uint32_t>(GetReg32(system, 0));
474 cv_key = Convert<uint32_t>(GetReg32(system, 1));
475 tag = Convert<uint32_t>(GetReg32(system, 2));
476 std::array<uint32_t, 2> timeout_ns_gather{};
477 timeout_ns_gather[0] = GetReg32(system, 3);
478 timeout_ns_gather[1] = GetReg32(system, 4);
479 timeout_ns = Convert<int64_t>(timeout_ns_gather);
480
481 ret = WaitProcessWideKeyAtomic64From32(system, address, cv_key, tag, timeout_ns);
482
483 SetReg32(system, 0, Convert<uint32_t>(ret));
484}
485
486static void SvcWrap_SignalProcessWideKey64From32(Core::System& system) {
487 uint32_t cv_key{};
488 int32_t count{};
489
490 cv_key = Convert<uint32_t>(GetReg32(system, 0));
491 count = Convert<int32_t>(GetReg32(system, 1));
492
493 SignalProcessWideKey64From32(system, cv_key, count);
494}
495
496static void SvcWrap_GetSystemTick64From32(Core::System& system) {
497 int64_t ret{};
498
499 ret = GetSystemTick64From32(system);
500
501 auto ret_scatter = Convert<std::array<uint32_t, 2>>(ret);
502 SetReg32(system, 0, ret_scatter[0]);
503 SetReg32(system, 1, ret_scatter[1]);
504}
505
506static void SvcWrap_ConnectToNamedPort64From32(Core::System& system) {
507 Result ret{};
508
509 Handle out_handle{};
510 uint32_t name{};
511
512 name = Convert<uint32_t>(GetReg32(system, 1));
513
514 ret = ConnectToNamedPort64From32(system, &out_handle, name);
515
516 SetReg32(system, 0, Convert<uint32_t>(ret));
517 SetReg32(system, 1, Convert<uint32_t>(out_handle));
518}
519
520static void SvcWrap_SendSyncRequest64From32(Core::System& system) {
521 Result ret{};
522
523 Handle session_handle{};
524
525 session_handle = Convert<Handle>(GetReg32(system, 0));
526
527 ret = SendSyncRequest64From32(system, session_handle);
528
529 SetReg32(system, 0, Convert<uint32_t>(ret));
530}
531
532static void SvcWrap_SendSyncRequestWithUserBuffer64From32(Core::System& system) {
533 Result ret{};
534
535 uint32_t message_buffer{};
536 uint32_t message_buffer_size{};
537 Handle session_handle{};
538
539 message_buffer = Convert<uint32_t>(GetReg32(system, 0));
540 message_buffer_size = Convert<uint32_t>(GetReg32(system, 1));
541 session_handle = Convert<Handle>(GetReg32(system, 2));
542
543 ret = SendSyncRequestWithUserBuffer64From32(system, message_buffer, message_buffer_size, session_handle);
544
545 SetReg32(system, 0, Convert<uint32_t>(ret));
546}
547
548static void SvcWrap_SendAsyncRequestWithUserBuffer64From32(Core::System& system) {
549 Result ret{};
550
551 Handle out_event_handle{};
552 uint32_t message_buffer{};
553 uint32_t message_buffer_size{};
554 Handle session_handle{};
555
556 message_buffer = Convert<uint32_t>(GetReg32(system, 1));
557 message_buffer_size = Convert<uint32_t>(GetReg32(system, 2));
558 session_handle = Convert<Handle>(GetReg32(system, 3));
559
560 ret = SendAsyncRequestWithUserBuffer64From32(system, &out_event_handle, message_buffer, message_buffer_size, session_handle);
561
562 SetReg32(system, 0, Convert<uint32_t>(ret));
563 SetReg32(system, 1, Convert<uint32_t>(out_event_handle));
564}
565
566static void SvcWrap_GetProcessId64From32(Core::System& system) {
567 Result ret{};
568
569 uint64_t out_process_id{};
570 Handle process_handle{};
571
572 process_handle = Convert<Handle>(GetReg32(system, 1));
573
574 ret = GetProcessId64From32(system, &out_process_id, process_handle);
575
576 SetReg32(system, 0, Convert<uint32_t>(ret));
577 auto out_process_id_scatter = Convert<std::array<uint32_t, 2>>(out_process_id);
578 SetReg32(system, 1, out_process_id_scatter[0]);
579 SetReg32(system, 2, out_process_id_scatter[1]);
580}
581
582static void SvcWrap_GetThreadId64From32(Core::System& system) {
583 Result ret{};
584
585 uint64_t out_thread_id{};
586 Handle thread_handle{};
587
588 thread_handle = Convert<Handle>(GetReg32(system, 1));
589
590 ret = GetThreadId64From32(system, &out_thread_id, thread_handle);
591
592 SetReg32(system, 0, Convert<uint32_t>(ret));
593 auto out_thread_id_scatter = Convert<std::array<uint32_t, 2>>(out_thread_id);
594 SetReg32(system, 1, out_thread_id_scatter[0]);
595 SetReg32(system, 2, out_thread_id_scatter[1]);
596}
597
598static void SvcWrap_Break64From32(Core::System& system) {
599 BreakReason break_reason{};
600 uint32_t arg{};
601 uint32_t size{};
602
603 break_reason = Convert<BreakReason>(GetReg32(system, 0));
604 arg = Convert<uint32_t>(GetReg32(system, 1));
605 size = Convert<uint32_t>(GetReg32(system, 2));
606
607 Break64From32(system, break_reason, arg, size);
608}
609
610static void SvcWrap_OutputDebugString64From32(Core::System& system) {
611 Result ret{};
612
613 uint32_t debug_str{};
614 uint32_t len{};
615
616 debug_str = Convert<uint32_t>(GetReg32(system, 0));
617 len = Convert<uint32_t>(GetReg32(system, 1));
618
619 ret = OutputDebugString64From32(system, debug_str, len);
620
621 SetReg32(system, 0, Convert<uint32_t>(ret));
622}
623
624static void SvcWrap_ReturnFromException64From32(Core::System& system) {
625 Result result{};
626
627 result = Convert<Result>(GetReg32(system, 0));
628
629 ReturnFromException64From32(system, result);
630}
631
632static void SvcWrap_GetInfo64From32(Core::System& system) {
633 Result ret{};
634
635 uint64_t out{};
636 InfoType info_type{};
637 Handle handle{};
638 uint64_t info_subtype{};
639
640 info_type = Convert<InfoType>(GetReg32(system, 1));
641 handle = Convert<Handle>(GetReg32(system, 2));
642 std::array<uint32_t, 2> info_subtype_gather{};
643 info_subtype_gather[0] = GetReg32(system, 0);
644 info_subtype_gather[1] = GetReg32(system, 3);
645 info_subtype = Convert<uint64_t>(info_subtype_gather);
646
647 ret = GetInfo64From32(system, &out, info_type, handle, info_subtype);
648
649 SetReg32(system, 0, Convert<uint32_t>(ret));
650 auto out_scatter = Convert<std::array<uint32_t, 2>>(out);
651 SetReg32(system, 1, out_scatter[0]);
652 SetReg32(system, 2, out_scatter[1]);
653}
654
655static void SvcWrap_FlushEntireDataCache64From32(Core::System& system) {
656 FlushEntireDataCache64From32(system);
657}
658
659static void SvcWrap_FlushDataCache64From32(Core::System& system) {
660 Result ret{};
661
662 uint32_t address{};
663 uint32_t size{};
664
665 address = Convert<uint32_t>(GetReg32(system, 0));
666 size = Convert<uint32_t>(GetReg32(system, 1));
667
668 ret = FlushDataCache64From32(system, address, size);
669
670 SetReg32(system, 0, Convert<uint32_t>(ret));
671}
672
673static void SvcWrap_MapPhysicalMemory64From32(Core::System& system) {
674 Result ret{};
675
676 uint32_t address{};
677 uint32_t size{};
678
679 address = Convert<uint32_t>(GetReg32(system, 0));
680 size = Convert<uint32_t>(GetReg32(system, 1));
681
682 ret = MapPhysicalMemory64From32(system, address, size);
683
684 SetReg32(system, 0, Convert<uint32_t>(ret));
685}
686
687static void SvcWrap_UnmapPhysicalMemory64From32(Core::System& system) {
688 Result ret{};
689
690 uint32_t address{};
691 uint32_t size{};
692
693 address = Convert<uint32_t>(GetReg32(system, 0));
694 size = Convert<uint32_t>(GetReg32(system, 1));
695
696 ret = UnmapPhysicalMemory64From32(system, address, size);
697
698 SetReg32(system, 0, Convert<uint32_t>(ret));
699}
700
701static void SvcWrap_GetDebugFutureThreadInfo64From32(Core::System& system) {
702 Result ret{};
703
704 ilp32::LastThreadContext out_context{};
705 uint64_t out_thread_id{};
706 Handle debug_handle{};
707 int64_t ns{};
708
709 debug_handle = Convert<Handle>(GetReg32(system, 2));
710 std::array<uint32_t, 2> ns_gather{};
711 ns_gather[0] = GetReg32(system, 0);
712 ns_gather[1] = GetReg32(system, 1);
713 ns = Convert<int64_t>(ns_gather);
714
715 ret = GetDebugFutureThreadInfo64From32(system, &out_context, &out_thread_id, debug_handle, ns);
716
717 SetReg32(system, 0, Convert<uint32_t>(ret));
718 auto out_context_scatter = Convert<std::array<uint32_t, 4>>(out_context);
719 SetReg32(system, 1, out_context_scatter[0]);
720 SetReg32(system, 2, out_context_scatter[1]);
721 SetReg32(system, 3, out_context_scatter[2]);
722 SetReg32(system, 4, out_context_scatter[3]);
723 auto out_thread_id_scatter = Convert<std::array<uint32_t, 2>>(out_thread_id);
724 SetReg32(system, 5, out_thread_id_scatter[0]);
725 SetReg32(system, 6, out_thread_id_scatter[1]);
726}
727
728static void SvcWrap_GetLastThreadInfo64From32(Core::System& system) {
729 Result ret{};
730
731 ilp32::LastThreadContext out_context{};
732 uintptr_t out_tls_address{};
733 uint32_t out_flags{};
734
735 ret = GetLastThreadInfo64From32(system, &out_context, &out_tls_address, &out_flags);
736
737 SetReg32(system, 0, Convert<uint32_t>(ret));
738 auto out_context_scatter = Convert<std::array<uint32_t, 4>>(out_context);
739 SetReg32(system, 1, out_context_scatter[0]);
740 SetReg32(system, 2, out_context_scatter[1]);
741 SetReg32(system, 3, out_context_scatter[2]);
742 SetReg32(system, 4, out_context_scatter[3]);
743 SetReg32(system, 5, Convert<uint32_t>(out_tls_address));
744 SetReg32(system, 6, Convert<uint32_t>(out_flags));
745}
746
747static void SvcWrap_GetResourceLimitLimitValue64From32(Core::System& system) {
748 Result ret{};
749
750 int64_t out_limit_value{};
751 Handle resource_limit_handle{};
752 LimitableResource which{};
753
754 resource_limit_handle = Convert<Handle>(GetReg32(system, 1));
755 which = Convert<LimitableResource>(GetReg32(system, 2));
756
757 ret = GetResourceLimitLimitValue64From32(system, &out_limit_value, resource_limit_handle, which);
758
759 SetReg32(system, 0, Convert<uint32_t>(ret));
760 auto out_limit_value_scatter = Convert<std::array<uint32_t, 2>>(out_limit_value);
761 SetReg32(system, 1, out_limit_value_scatter[0]);
762 SetReg32(system, 2, out_limit_value_scatter[1]);
763}
764
765static void SvcWrap_GetResourceLimitCurrentValue64From32(Core::System& system) {
766 Result ret{};
767
768 int64_t out_current_value{};
769 Handle resource_limit_handle{};
770 LimitableResource which{};
771
772 resource_limit_handle = Convert<Handle>(GetReg32(system, 1));
773 which = Convert<LimitableResource>(GetReg32(system, 2));
774
775 ret = GetResourceLimitCurrentValue64From32(system, &out_current_value, resource_limit_handle, which);
776
777 SetReg32(system, 0, Convert<uint32_t>(ret));
778 auto out_current_value_scatter = Convert<std::array<uint32_t, 2>>(out_current_value);
779 SetReg32(system, 1, out_current_value_scatter[0]);
780 SetReg32(system, 2, out_current_value_scatter[1]);
781}
782
783static void SvcWrap_SetThreadActivity64From32(Core::System& system) {
784 Result ret{};
785
786 Handle thread_handle{};
787 ThreadActivity thread_activity{};
788
789 thread_handle = Convert<Handle>(GetReg32(system, 0));
790 thread_activity = Convert<ThreadActivity>(GetReg32(system, 1));
791
792 ret = SetThreadActivity64From32(system, thread_handle, thread_activity);
793
794 SetReg32(system, 0, Convert<uint32_t>(ret));
795}
796
797static void SvcWrap_GetThreadContext364From32(Core::System& system) {
798 Result ret{};
799
800 uint32_t out_context{};
801 Handle thread_handle{};
802
803 out_context = Convert<uint32_t>(GetReg32(system, 0));
804 thread_handle = Convert<Handle>(GetReg32(system, 1));
805
806 ret = GetThreadContext364From32(system, out_context, thread_handle);
807
808 SetReg32(system, 0, Convert<uint32_t>(ret));
809}
810
811static void SvcWrap_WaitForAddress64From32(Core::System& system) {
812 Result ret{};
813
814 uint32_t address{};
815 ArbitrationType arb_type{};
816 int32_t value{};
817 int64_t timeout_ns{};
818
819 address = Convert<uint32_t>(GetReg32(system, 0));
820 arb_type = Convert<ArbitrationType>(GetReg32(system, 1));
821 value = Convert<int32_t>(GetReg32(system, 2));
822 std::array<uint32_t, 2> timeout_ns_gather{};
823 timeout_ns_gather[0] = GetReg32(system, 3);
824 timeout_ns_gather[1] = GetReg32(system, 4);
825 timeout_ns = Convert<int64_t>(timeout_ns_gather);
826
827 ret = WaitForAddress64From32(system, address, arb_type, value, timeout_ns);
828
829 SetReg32(system, 0, Convert<uint32_t>(ret));
830}
831
832static void SvcWrap_SignalToAddress64From32(Core::System& system) {
833 Result ret{};
834
835 uint32_t address{};
836 SignalType signal_type{};
837 int32_t value{};
838 int32_t count{};
839
840 address = Convert<uint32_t>(GetReg32(system, 0));
841 signal_type = Convert<SignalType>(GetReg32(system, 1));
842 value = Convert<int32_t>(GetReg32(system, 2));
843 count = Convert<int32_t>(GetReg32(system, 3));
844
845 ret = SignalToAddress64From32(system, address, signal_type, value, count);
846
847 SetReg32(system, 0, Convert<uint32_t>(ret));
848}
849
850static void SvcWrap_SynchronizePreemptionState64From32(Core::System& system) {
851 SynchronizePreemptionState64From32(system);
852}
853
854static void SvcWrap_GetResourceLimitPeakValue64From32(Core::System& system) {
855 Result ret{};
856
857 int64_t out_peak_value{};
858 Handle resource_limit_handle{};
859 LimitableResource which{};
860
861 resource_limit_handle = Convert<Handle>(GetReg32(system, 1));
862 which = Convert<LimitableResource>(GetReg32(system, 2));
863
864 ret = GetResourceLimitPeakValue64From32(system, &out_peak_value, resource_limit_handle, which);
865
866 SetReg32(system, 0, Convert<uint32_t>(ret));
867 auto out_peak_value_scatter = Convert<std::array<uint32_t, 2>>(out_peak_value);
868 SetReg32(system, 1, out_peak_value_scatter[0]);
869 SetReg32(system, 2, out_peak_value_scatter[1]);
870}
871
872static void SvcWrap_CreateIoPool64From32(Core::System& system) {
873 Result ret{};
874
875 Handle out_handle{};
876 IoPoolType which{};
877
878 which = Convert<IoPoolType>(GetReg32(system, 1));
879
880 ret = CreateIoPool64From32(system, &out_handle, which);
881
882 SetReg32(system, 0, Convert<uint32_t>(ret));
883 SetReg32(system, 1, Convert<uint32_t>(out_handle));
884}
885
886static void SvcWrap_CreateIoRegion64From32(Core::System& system) {
887 Result ret{};
888
889 Handle out_handle{};
890 Handle io_pool{};
891 uint64_t physical_address{};
892 uint32_t size{};
893 MemoryMapping mapping{};
894 MemoryPermission perm{};
895
896 io_pool = Convert<Handle>(GetReg32(system, 1));
897 std::array<uint32_t, 2> physical_address_gather{};
898 physical_address_gather[0] = GetReg32(system, 2);
899 physical_address_gather[1] = GetReg32(system, 3);
900 physical_address = Convert<uint64_t>(physical_address_gather);
901 size = Convert<uint32_t>(GetReg32(system, 0));
902 mapping = Convert<MemoryMapping>(GetReg32(system, 4));
903 perm = Convert<MemoryPermission>(GetReg32(system, 5));
904
905 ret = CreateIoRegion64From32(system, &out_handle, io_pool, physical_address, size, mapping, perm);
906
907 SetReg32(system, 0, Convert<uint32_t>(ret));
908 SetReg32(system, 1, Convert<uint32_t>(out_handle));
909}
910
911static void SvcWrap_KernelDebug64From32(Core::System& system) {
912 KernelDebugType kern_debug_type{};
913 uint64_t arg0{};
914 uint64_t arg1{};
915 uint64_t arg2{};
916
917 kern_debug_type = Convert<KernelDebugType>(GetReg32(system, 0));
918 std::array<uint32_t, 2> arg0_gather{};
919 arg0_gather[0] = GetReg32(system, 2);
920 arg0_gather[1] = GetReg32(system, 3);
921 arg0 = Convert<uint64_t>(arg0_gather);
922 std::array<uint32_t, 2> arg1_gather{};
923 arg1_gather[0] = GetReg32(system, 1);
924 arg1_gather[1] = GetReg32(system, 4);
925 arg1 = Convert<uint64_t>(arg1_gather);
926 std::array<uint32_t, 2> arg2_gather{};
927 arg2_gather[0] = GetReg32(system, 5);
928 arg2_gather[1] = GetReg32(system, 6);
929 arg2 = Convert<uint64_t>(arg2_gather);
930
931 KernelDebug64From32(system, kern_debug_type, arg0, arg1, arg2);
932}
933
934static void SvcWrap_ChangeKernelTraceState64From32(Core::System& system) {
935 KernelTraceState kern_trace_state{};
936
937 kern_trace_state = Convert<KernelTraceState>(GetReg32(system, 0));
938
939 ChangeKernelTraceState64From32(system, kern_trace_state);
940}
941
942static void SvcWrap_CreateSession64From32(Core::System& system) {
943 Result ret{};
944
945 Handle out_server_session_handle{};
946 Handle out_client_session_handle{};
947 bool is_light{};
948 uint32_t name{};
949
950 is_light = Convert<bool>(GetReg32(system, 2));
951 name = Convert<uint32_t>(GetReg32(system, 3));
952
953 ret = CreateSession64From32(system, &out_server_session_handle, &out_client_session_handle, is_light, name);
954
955 SetReg32(system, 0, Convert<uint32_t>(ret));
956 SetReg32(system, 1, Convert<uint32_t>(out_server_session_handle));
957 SetReg32(system, 2, Convert<uint32_t>(out_client_session_handle));
958}
959
960static void SvcWrap_AcceptSession64From32(Core::System& system) {
961 Result ret{};
962
963 Handle out_handle{};
964 Handle port{};
965
966 port = Convert<Handle>(GetReg32(system, 1));
967
968 ret = AcceptSession64From32(system, &out_handle, port);
969
970 SetReg32(system, 0, Convert<uint32_t>(ret));
971 SetReg32(system, 1, Convert<uint32_t>(out_handle));
972}
973
974static void SvcWrap_ReplyAndReceive64From32(Core::System& system) {
975 Result ret{};
976
977 int32_t out_index{};
978 uint32_t handles{};
979 int32_t num_handles{};
980 Handle reply_target{};
981 int64_t timeout_ns{};
982
983 handles = Convert<uint32_t>(GetReg32(system, 1));
984 num_handles = Convert<int32_t>(GetReg32(system, 2));
985 reply_target = Convert<Handle>(GetReg32(system, 3));
986 std::array<uint32_t, 2> timeout_ns_gather{};
987 timeout_ns_gather[0] = GetReg32(system, 0);
988 timeout_ns_gather[1] = GetReg32(system, 4);
989 timeout_ns = Convert<int64_t>(timeout_ns_gather);
990
991 ret = ReplyAndReceive64From32(system, &out_index, handles, num_handles, reply_target, timeout_ns);
992
993 SetReg32(system, 0, Convert<uint32_t>(ret));
994 SetReg32(system, 1, Convert<uint32_t>(out_index));
995}
996
997static void SvcWrap_ReplyAndReceiveWithUserBuffer64From32(Core::System& system) {
998 Result ret{};
999
1000 int32_t out_index{};
1001 uint32_t message_buffer{};
1002 uint32_t message_buffer_size{};
1003 uint32_t handles{};
1004 int32_t num_handles{};
1005 Handle reply_target{};
1006 int64_t timeout_ns{};
1007
1008 message_buffer = Convert<uint32_t>(GetReg32(system, 1));
1009 message_buffer_size = Convert<uint32_t>(GetReg32(system, 2));
1010 handles = Convert<uint32_t>(GetReg32(system, 3));
1011 num_handles = Convert<int32_t>(GetReg32(system, 0));
1012 reply_target = Convert<Handle>(GetReg32(system, 4));
1013 std::array<uint32_t, 2> timeout_ns_gather{};
1014 timeout_ns_gather[0] = GetReg32(system, 5);
1015 timeout_ns_gather[1] = GetReg32(system, 6);
1016 timeout_ns = Convert<int64_t>(timeout_ns_gather);
1017
1018 ret = ReplyAndReceiveWithUserBuffer64From32(system, &out_index, message_buffer, message_buffer_size, handles, num_handles, reply_target, timeout_ns);
1019
1020 SetReg32(system, 0, Convert<uint32_t>(ret));
1021 SetReg32(system, 1, Convert<uint32_t>(out_index));
1022}
1023
1024static void SvcWrap_CreateEvent64From32(Core::System& system) {
1025 Result ret{};
1026
1027 Handle out_write_handle{};
1028 Handle out_read_handle{};
1029
1030 ret = CreateEvent64From32(system, &out_write_handle, &out_read_handle);
1031
1032 SetReg32(system, 0, Convert<uint32_t>(ret));
1033 SetReg32(system, 1, Convert<uint32_t>(out_write_handle));
1034 SetReg32(system, 2, Convert<uint32_t>(out_read_handle));
1035}
1036
1037static void SvcWrap_MapIoRegion64From32(Core::System& system) {
1038 Result ret{};
1039
1040 Handle io_region{};
1041 uint32_t address{};
1042 uint32_t size{};
1043 MemoryPermission perm{};
1044
1045 io_region = Convert<Handle>(GetReg32(system, 0));
1046 address = Convert<uint32_t>(GetReg32(system, 1));
1047 size = Convert<uint32_t>(GetReg32(system, 2));
1048 perm = Convert<MemoryPermission>(GetReg32(system, 3));
1049
1050 ret = MapIoRegion64From32(system, io_region, address, size, perm);
1051
1052 SetReg32(system, 0, Convert<uint32_t>(ret));
1053}
1054
1055static void SvcWrap_UnmapIoRegion64From32(Core::System& system) {
1056 Result ret{};
1057
1058 Handle io_region{};
1059 uint32_t address{};
1060 uint32_t size{};
1061
1062 io_region = Convert<Handle>(GetReg32(system, 0));
1063 address = Convert<uint32_t>(GetReg32(system, 1));
1064 size = Convert<uint32_t>(GetReg32(system, 2));
1065
1066 ret = UnmapIoRegion64From32(system, io_region, address, size);
1067
1068 SetReg32(system, 0, Convert<uint32_t>(ret));
1069}
1070
1071static void SvcWrap_MapPhysicalMemoryUnsafe64From32(Core::System& system) {
1072 Result ret{};
1073
1074 uint32_t address{};
1075 uint32_t size{};
1076
1077 address = Convert<uint32_t>(GetReg32(system, 0));
1078 size = Convert<uint32_t>(GetReg32(system, 1));
1079
1080 ret = MapPhysicalMemoryUnsafe64From32(system, address, size);
1081
1082 SetReg32(system, 0, Convert<uint32_t>(ret));
1083}
1084
1085static void SvcWrap_UnmapPhysicalMemoryUnsafe64From32(Core::System& system) {
1086 Result ret{};
1087
1088 uint32_t address{};
1089 uint32_t size{};
1090
1091 address = Convert<uint32_t>(GetReg32(system, 0));
1092 size = Convert<uint32_t>(GetReg32(system, 1));
1093
1094 ret = UnmapPhysicalMemoryUnsafe64From32(system, address, size);
1095
1096 SetReg32(system, 0, Convert<uint32_t>(ret));
1097}
1098
1099static void SvcWrap_SetUnsafeLimit64From32(Core::System& system) {
1100 Result ret{};
1101
1102 uint32_t limit{};
1103
1104 limit = Convert<uint32_t>(GetReg32(system, 0));
1105
1106 ret = SetUnsafeLimit64From32(system, limit);
1107
1108 SetReg32(system, 0, Convert<uint32_t>(ret));
1109}
1110
1111static void SvcWrap_CreateCodeMemory64From32(Core::System& system) {
1112 Result ret{};
1113
1114 Handle out_handle{};
1115 uint32_t address{};
1116 uint32_t size{};
1117
1118 address = Convert<uint32_t>(GetReg32(system, 1));
1119 size = Convert<uint32_t>(GetReg32(system, 2));
1120
1121 ret = CreateCodeMemory64From32(system, &out_handle, address, size);
1122
1123 SetReg32(system, 0, Convert<uint32_t>(ret));
1124 SetReg32(system, 1, Convert<uint32_t>(out_handle));
1125}
1126
1127static void SvcWrap_ControlCodeMemory64From32(Core::System& system) {
1128 Result ret{};
1129
1130 Handle code_memory_handle{};
1131 CodeMemoryOperation operation{};
1132 uint64_t address{};
1133 uint64_t size{};
1134 MemoryPermission perm{};
1135
1136 code_memory_handle = Convert<Handle>(GetReg32(system, 0));
1137 operation = Convert<CodeMemoryOperation>(GetReg32(system, 1));
1138 std::array<uint32_t, 2> address_gather{};
1139 address_gather[0] = GetReg32(system, 2);
1140 address_gather[1] = GetReg32(system, 3);
1141 address = Convert<uint64_t>(address_gather);
1142 std::array<uint32_t, 2> size_gather{};
1143 size_gather[0] = GetReg32(system, 4);
1144 size_gather[1] = GetReg32(system, 5);
1145 size = Convert<uint64_t>(size_gather);
1146 perm = Convert<MemoryPermission>(GetReg32(system, 6));
1147
1148 ret = ControlCodeMemory64From32(system, code_memory_handle, operation, address, size, perm);
1149
1150 SetReg32(system, 0, Convert<uint32_t>(ret));
1151}
1152
1153static void SvcWrap_SleepSystem64From32(Core::System& system) {
1154 SleepSystem64From32(system);
1155}
1156
1157static void SvcWrap_ReadWriteRegister64From32(Core::System& system) {
1158 Result ret{};
1159
1160 uint32_t out_value{};
1161 uint64_t address{};
1162 uint32_t mask{};
1163 uint32_t value{};
1164
1165 std::array<uint32_t, 2> address_gather{};
1166 address_gather[0] = GetReg32(system, 2);
1167 address_gather[1] = GetReg32(system, 3);
1168 address = Convert<uint64_t>(address_gather);
1169 mask = Convert<uint32_t>(GetReg32(system, 0));
1170 value = Convert<uint32_t>(GetReg32(system, 1));
1171
1172 ret = ReadWriteRegister64From32(system, &out_value, address, mask, value);
1173
1174 SetReg32(system, 0, Convert<uint32_t>(ret));
1175 SetReg32(system, 1, Convert<uint32_t>(out_value));
1176}
1177
1178static void SvcWrap_SetProcessActivity64From32(Core::System& system) {
1179 Result ret{};
1180
1181 Handle process_handle{};
1182 ProcessActivity process_activity{};
1183
1184 process_handle = Convert<Handle>(GetReg32(system, 0));
1185 process_activity = Convert<ProcessActivity>(GetReg32(system, 1));
1186
1187 ret = SetProcessActivity64From32(system, process_handle, process_activity);
1188
1189 SetReg32(system, 0, Convert<uint32_t>(ret));
1190}
1191
1192static void SvcWrap_CreateSharedMemory64From32(Core::System& system) {
1193 Result ret{};
1194
1195 Handle out_handle{};
1196 uint32_t size{};
1197 MemoryPermission owner_perm{};
1198 MemoryPermission remote_perm{};
1199
1200 size = Convert<uint32_t>(GetReg32(system, 1));
1201 owner_perm = Convert<MemoryPermission>(GetReg32(system, 2));
1202 remote_perm = Convert<MemoryPermission>(GetReg32(system, 3));
1203
1204 ret = CreateSharedMemory64From32(system, &out_handle, size, owner_perm, remote_perm);
1205
1206 SetReg32(system, 0, Convert<uint32_t>(ret));
1207 SetReg32(system, 1, Convert<uint32_t>(out_handle));
1208}
1209
1210static void SvcWrap_MapTransferMemory64From32(Core::System& system) {
1211 Result ret{};
1212
1213 Handle trmem_handle{};
1214 uint32_t address{};
1215 uint32_t size{};
1216 MemoryPermission owner_perm{};
1217
1218 trmem_handle = Convert<Handle>(GetReg32(system, 0));
1219 address = Convert<uint32_t>(GetReg32(system, 1));
1220 size = Convert<uint32_t>(GetReg32(system, 2));
1221 owner_perm = Convert<MemoryPermission>(GetReg32(system, 3));
1222
1223 ret = MapTransferMemory64From32(system, trmem_handle, address, size, owner_perm);
1224
1225 SetReg32(system, 0, Convert<uint32_t>(ret));
1226}
1227
1228static void SvcWrap_UnmapTransferMemory64From32(Core::System& system) {
1229 Result ret{};
1230
1231 Handle trmem_handle{};
1232 uint32_t address{};
1233 uint32_t size{};
1234
1235 trmem_handle = Convert<Handle>(GetReg32(system, 0));
1236 address = Convert<uint32_t>(GetReg32(system, 1));
1237 size = Convert<uint32_t>(GetReg32(system, 2));
1238
1239 ret = UnmapTransferMemory64From32(system, trmem_handle, address, size);
1240
1241 SetReg32(system, 0, Convert<uint32_t>(ret));
1242}
1243
1244static void SvcWrap_CreateInterruptEvent64From32(Core::System& system) {
1245 Result ret{};
1246
1247 Handle out_read_handle{};
1248 int32_t interrupt_id{};
1249 InterruptType interrupt_type{};
1250
1251 interrupt_id = Convert<int32_t>(GetReg32(system, 1));
1252 interrupt_type = Convert<InterruptType>(GetReg32(system, 2));
1253
1254 ret = CreateInterruptEvent64From32(system, &out_read_handle, interrupt_id, interrupt_type);
1255
1256 SetReg32(system, 0, Convert<uint32_t>(ret));
1257 SetReg32(system, 1, Convert<uint32_t>(out_read_handle));
1258}
1259
1260static void SvcWrap_QueryPhysicalAddress64From32(Core::System& system) {
1261 Result ret{};
1262
1263 ilp32::PhysicalMemoryInfo out_info{};
1264 uint32_t address{};
1265
1266 address = Convert<uint32_t>(GetReg32(system, 1));
1267
1268 ret = QueryPhysicalAddress64From32(system, &out_info, address);
1269
1270 SetReg32(system, 0, Convert<uint32_t>(ret));
1271 auto out_info_scatter = Convert<std::array<uint32_t, 4>>(out_info);
1272 SetReg32(system, 1, out_info_scatter[0]);
1273 SetReg32(system, 2, out_info_scatter[1]);
1274 SetReg32(system, 3, out_info_scatter[2]);
1275 SetReg32(system, 4, out_info_scatter[3]);
1276}
1277
1278static void SvcWrap_QueryIoMapping64From32(Core::System& system) {
1279 Result ret{};
1280
1281 uintptr_t out_address{};
1282 uintptr_t out_size{};
1283 uint64_t physical_address{};
1284 uint32_t size{};
1285
1286 std::array<uint32_t, 2> physical_address_gather{};
1287 physical_address_gather[0] = GetReg32(system, 2);
1288 physical_address_gather[1] = GetReg32(system, 3);
1289 physical_address = Convert<uint64_t>(physical_address_gather);
1290 size = Convert<uint32_t>(GetReg32(system, 0));
1291
1292 ret = QueryIoMapping64From32(system, &out_address, &out_size, physical_address, size);
1293
1294 SetReg32(system, 0, Convert<uint32_t>(ret));
1295 SetReg32(system, 1, Convert<uint32_t>(out_address));
1296 SetReg32(system, 2, Convert<uint32_t>(out_size));
1297}
1298
1299static void SvcWrap_CreateDeviceAddressSpace64From32(Core::System& system) {
1300 Result ret{};
1301
1302 Handle out_handle{};
1303 uint64_t das_address{};
1304 uint64_t das_size{};
1305
1306 std::array<uint32_t, 2> das_address_gather{};
1307 das_address_gather[0] = GetReg32(system, 2);
1308 das_address_gather[1] = GetReg32(system, 3);
1309 das_address = Convert<uint64_t>(das_address_gather);
1310 std::array<uint32_t, 2> das_size_gather{};
1311 das_size_gather[0] = GetReg32(system, 0);
1312 das_size_gather[1] = GetReg32(system, 1);
1313 das_size = Convert<uint64_t>(das_size_gather);
1314
1315 ret = CreateDeviceAddressSpace64From32(system, &out_handle, das_address, das_size);
1316
1317 SetReg32(system, 0, Convert<uint32_t>(ret));
1318 SetReg32(system, 1, Convert<uint32_t>(out_handle));
1319}
1320
1321static void SvcWrap_AttachDeviceAddressSpace64From32(Core::System& system) {
1322 Result ret{};
1323
1324 DeviceName device_name{};
1325 Handle das_handle{};
1326
1327 device_name = Convert<DeviceName>(GetReg32(system, 0));
1328 das_handle = Convert<Handle>(GetReg32(system, 1));
1329
1330 ret = AttachDeviceAddressSpace64From32(system, device_name, das_handle);
1331
1332 SetReg32(system, 0, Convert<uint32_t>(ret));
1333}
1334
1335static void SvcWrap_DetachDeviceAddressSpace64From32(Core::System& system) {
1336 Result ret{};
1337
1338 DeviceName device_name{};
1339 Handle das_handle{};
1340
1341 device_name = Convert<DeviceName>(GetReg32(system, 0));
1342 das_handle = Convert<Handle>(GetReg32(system, 1));
1343
1344 ret = DetachDeviceAddressSpace64From32(system, device_name, das_handle);
1345
1346 SetReg32(system, 0, Convert<uint32_t>(ret));
1347}
1348
1349static void SvcWrap_MapDeviceAddressSpaceByForce64From32(Core::System& system) {
1350 Result ret{};
1351
1352 Handle das_handle{};
1353 Handle process_handle{};
1354 uint64_t process_address{};
1355 uint32_t size{};
1356 uint64_t device_address{};
1357 uint32_t option{};
1358
1359 das_handle = Convert<Handle>(GetReg32(system, 0));
1360 process_handle = Convert<Handle>(GetReg32(system, 1));
1361 std::array<uint32_t, 2> process_address_gather{};
1362 process_address_gather[0] = GetReg32(system, 2);
1363 process_address_gather[1] = GetReg32(system, 3);
1364 process_address = Convert<uint64_t>(process_address_gather);
1365 size = Convert<uint32_t>(GetReg32(system, 4));
1366 std::array<uint32_t, 2> device_address_gather{};
1367 device_address_gather[0] = GetReg32(system, 5);
1368 device_address_gather[1] = GetReg32(system, 6);
1369 device_address = Convert<uint64_t>(device_address_gather);
1370 option = Convert<uint32_t>(GetReg32(system, 7));
1371
1372 ret = MapDeviceAddressSpaceByForce64From32(system, das_handle, process_handle, process_address, size, device_address, option);
1373
1374 SetReg32(system, 0, Convert<uint32_t>(ret));
1375}
1376
1377static void SvcWrap_MapDeviceAddressSpaceAligned64From32(Core::System& system) {
1378 Result ret{};
1379
1380 Handle das_handle{};
1381 Handle process_handle{};
1382 uint64_t process_address{};
1383 uint32_t size{};
1384 uint64_t device_address{};
1385 uint32_t option{};
1386
1387 das_handle = Convert<Handle>(GetReg32(system, 0));
1388 process_handle = Convert<Handle>(GetReg32(system, 1));
1389 std::array<uint32_t, 2> process_address_gather{};
1390 process_address_gather[0] = GetReg32(system, 2);
1391 process_address_gather[1] = GetReg32(system, 3);
1392 process_address = Convert<uint64_t>(process_address_gather);
1393 size = Convert<uint32_t>(GetReg32(system, 4));
1394 std::array<uint32_t, 2> device_address_gather{};
1395 device_address_gather[0] = GetReg32(system, 5);
1396 device_address_gather[1] = GetReg32(system, 6);
1397 device_address = Convert<uint64_t>(device_address_gather);
1398 option = Convert<uint32_t>(GetReg32(system, 7));
1399
1400 ret = MapDeviceAddressSpaceAligned64From32(system, das_handle, process_handle, process_address, size, device_address, option);
1401
1402 SetReg32(system, 0, Convert<uint32_t>(ret));
1403}
1404
1405static void SvcWrap_UnmapDeviceAddressSpace64From32(Core::System& system) {
1406 Result ret{};
1407
1408 Handle das_handle{};
1409 Handle process_handle{};
1410 uint64_t process_address{};
1411 uint32_t size{};
1412 uint64_t device_address{};
1413
1414 das_handle = Convert<Handle>(GetReg32(system, 0));
1415 process_handle = Convert<Handle>(GetReg32(system, 1));
1416 std::array<uint32_t, 2> process_address_gather{};
1417 process_address_gather[0] = GetReg32(system, 2);
1418 process_address_gather[1] = GetReg32(system, 3);
1419 process_address = Convert<uint64_t>(process_address_gather);
1420 size = Convert<uint32_t>(GetReg32(system, 4));
1421 std::array<uint32_t, 2> device_address_gather{};
1422 device_address_gather[0] = GetReg32(system, 5);
1423 device_address_gather[1] = GetReg32(system, 6);
1424 device_address = Convert<uint64_t>(device_address_gather);
1425
1426 ret = UnmapDeviceAddressSpace64From32(system, das_handle, process_handle, process_address, size, device_address);
1427
1428 SetReg32(system, 0, Convert<uint32_t>(ret));
1429}
1430
1431static void SvcWrap_InvalidateProcessDataCache64From32(Core::System& system) {
1432 Result ret{};
1433
1434 Handle process_handle{};
1435 uint64_t address{};
1436 uint64_t size{};
1437
1438 process_handle = Convert<Handle>(GetReg32(system, 0));
1439 std::array<uint32_t, 2> address_gather{};
1440 address_gather[0] = GetReg32(system, 2);
1441 address_gather[1] = GetReg32(system, 3);
1442 address = Convert<uint64_t>(address_gather);
1443 std::array<uint32_t, 2> size_gather{};
1444 size_gather[0] = GetReg32(system, 1);
1445 size_gather[1] = GetReg32(system, 4);
1446 size = Convert<uint64_t>(size_gather);
1447
1448 ret = InvalidateProcessDataCache64From32(system, process_handle, address, size);
1449
1450 SetReg32(system, 0, Convert<uint32_t>(ret));
1451}
1452
1453static void SvcWrap_StoreProcessDataCache64From32(Core::System& system) {
1454 Result ret{};
1455
1456 Handle process_handle{};
1457 uint64_t address{};
1458 uint64_t size{};
1459
1460 process_handle = Convert<Handle>(GetReg32(system, 0));
1461 std::array<uint32_t, 2> address_gather{};
1462 address_gather[0] = GetReg32(system, 2);
1463 address_gather[1] = GetReg32(system, 3);
1464 address = Convert<uint64_t>(address_gather);
1465 std::array<uint32_t, 2> size_gather{};
1466 size_gather[0] = GetReg32(system, 1);
1467 size_gather[1] = GetReg32(system, 4);
1468 size = Convert<uint64_t>(size_gather);
1469
1470 ret = StoreProcessDataCache64From32(system, process_handle, address, size);
1471
1472 SetReg32(system, 0, Convert<uint32_t>(ret));
1473}
1474
1475static void SvcWrap_FlushProcessDataCache64From32(Core::System& system) {
1476 Result ret{};
1477
1478 Handle process_handle{};
1479 uint64_t address{};
1480 uint64_t size{};
1481
1482 process_handle = Convert<Handle>(GetReg32(system, 0));
1483 std::array<uint32_t, 2> address_gather{};
1484 address_gather[0] = GetReg32(system, 2);
1485 address_gather[1] = GetReg32(system, 3);
1486 address = Convert<uint64_t>(address_gather);
1487 std::array<uint32_t, 2> size_gather{};
1488 size_gather[0] = GetReg32(system, 1);
1489 size_gather[1] = GetReg32(system, 4);
1490 size = Convert<uint64_t>(size_gather);
1491
1492 ret = FlushProcessDataCache64From32(system, process_handle, address, size);
1493
1494 SetReg32(system, 0, Convert<uint32_t>(ret));
1495}
1496
1497static void SvcWrap_DebugActiveProcess64From32(Core::System& system) {
1498 Result ret{};
1499
1500 Handle out_handle{};
1501 uint64_t process_id{};
1502
1503 std::array<uint32_t, 2> process_id_gather{};
1504 process_id_gather[0] = GetReg32(system, 2);
1505 process_id_gather[1] = GetReg32(system, 3);
1506 process_id = Convert<uint64_t>(process_id_gather);
1507
1508 ret = DebugActiveProcess64From32(system, &out_handle, process_id);
1509
1510 SetReg32(system, 0, Convert<uint32_t>(ret));
1511 SetReg32(system, 1, Convert<uint32_t>(out_handle));
1512}
1513
1514static void SvcWrap_BreakDebugProcess64From32(Core::System& system) {
1515 Result ret{};
1516
1517 Handle debug_handle{};
1518
1519 debug_handle = Convert<Handle>(GetReg32(system, 0));
1520
1521 ret = BreakDebugProcess64From32(system, debug_handle);
1522
1523 SetReg32(system, 0, Convert<uint32_t>(ret));
1524}
1525
1526static void SvcWrap_TerminateDebugProcess64From32(Core::System& system) {
1527 Result ret{};
1528
1529 Handle debug_handle{};
1530
1531 debug_handle = Convert<Handle>(GetReg32(system, 0));
1532
1533 ret = TerminateDebugProcess64From32(system, debug_handle);
1534
1535 SetReg32(system, 0, Convert<uint32_t>(ret));
1536}
1537
1538static void SvcWrap_GetDebugEvent64From32(Core::System& system) {
1539 Result ret{};
1540
1541 uint32_t out_info{};
1542 Handle debug_handle{};
1543
1544 out_info = Convert<uint32_t>(GetReg32(system, 0));
1545 debug_handle = Convert<Handle>(GetReg32(system, 1));
1546
1547 ret = GetDebugEvent64From32(system, out_info, debug_handle);
1548
1549 SetReg32(system, 0, Convert<uint32_t>(ret));
1550}
1551
1552static void SvcWrap_ContinueDebugEvent64From32(Core::System& system) {
1553 Result ret{};
1554
1555 Handle debug_handle{};
1556 uint32_t flags{};
1557 uint32_t thread_ids{};
1558 int32_t num_thread_ids{};
1559
1560 debug_handle = Convert<Handle>(GetReg32(system, 0));
1561 flags = Convert<uint32_t>(GetReg32(system, 1));
1562 thread_ids = Convert<uint32_t>(GetReg32(system, 2));
1563 num_thread_ids = Convert<int32_t>(GetReg32(system, 3));
1564
1565 ret = ContinueDebugEvent64From32(system, debug_handle, flags, thread_ids, num_thread_ids);
1566
1567 SetReg32(system, 0, Convert<uint32_t>(ret));
1568}
1569
1570static void SvcWrap_GetProcessList64From32(Core::System& system) {
1571 Result ret{};
1572
1573 int32_t out_num_processes{};
1574 uint32_t out_process_ids{};
1575 int32_t max_out_count{};
1576
1577 out_process_ids = Convert<uint32_t>(GetReg32(system, 1));
1578 max_out_count = Convert<int32_t>(GetReg32(system, 2));
1579
1580 ret = GetProcessList64From32(system, &out_num_processes, out_process_ids, max_out_count);
1581
1582 SetReg32(system, 0, Convert<uint32_t>(ret));
1583 SetReg32(system, 1, Convert<uint32_t>(out_num_processes));
1584}
1585
1586static void SvcWrap_GetThreadList64From32(Core::System& system) {
1587 Result ret{};
1588
1589 int32_t out_num_threads{};
1590 uint32_t out_thread_ids{};
1591 int32_t max_out_count{};
1592 Handle debug_handle{};
1593
1594 out_thread_ids = Convert<uint32_t>(GetReg32(system, 1));
1595 max_out_count = Convert<int32_t>(GetReg32(system, 2));
1596 debug_handle = Convert<Handle>(GetReg32(system, 3));
1597
1598 ret = GetThreadList64From32(system, &out_num_threads, out_thread_ids, max_out_count, debug_handle);
1599
1600 SetReg32(system, 0, Convert<uint32_t>(ret));
1601 SetReg32(system, 1, Convert<uint32_t>(out_num_threads));
1602}
1603
1604static void SvcWrap_GetDebugThreadContext64From32(Core::System& system) {
1605 Result ret{};
1606
1607 uint32_t out_context{};
1608 Handle debug_handle{};
1609 uint64_t thread_id{};
1610 uint32_t context_flags{};
1611
1612 out_context = Convert<uint32_t>(GetReg32(system, 0));
1613 debug_handle = Convert<Handle>(GetReg32(system, 1));
1614 std::array<uint32_t, 2> thread_id_gather{};
1615 thread_id_gather[0] = GetReg32(system, 2);
1616 thread_id_gather[1] = GetReg32(system, 3);
1617 thread_id = Convert<uint64_t>(thread_id_gather);
1618 context_flags = Convert<uint32_t>(GetReg32(system, 4));
1619
1620 ret = GetDebugThreadContext64From32(system, out_context, debug_handle, thread_id, context_flags);
1621
1622 SetReg32(system, 0, Convert<uint32_t>(ret));
1623}
1624
1625static void SvcWrap_SetDebugThreadContext64From32(Core::System& system) {
1626 Result ret{};
1627
1628 Handle debug_handle{};
1629 uint64_t thread_id{};
1630 uint32_t context{};
1631 uint32_t context_flags{};
1632
1633 debug_handle = Convert<Handle>(GetReg32(system, 0));
1634 std::array<uint32_t, 2> thread_id_gather{};
1635 thread_id_gather[0] = GetReg32(system, 2);
1636 thread_id_gather[1] = GetReg32(system, 3);
1637 thread_id = Convert<uint64_t>(thread_id_gather);
1638 context = Convert<uint32_t>(GetReg32(system, 1));
1639 context_flags = Convert<uint32_t>(GetReg32(system, 4));
1640
1641 ret = SetDebugThreadContext64From32(system, debug_handle, thread_id, context, context_flags);
1642
1643 SetReg32(system, 0, Convert<uint32_t>(ret));
1644}
1645
1646static void SvcWrap_QueryDebugProcessMemory64From32(Core::System& system) {
1647 Result ret{};
1648
1649 PageInfo out_page_info{};
1650 uint32_t out_memory_info{};
1651 Handle process_handle{};
1652 uint32_t address{};
1653
1654 out_memory_info = Convert<uint32_t>(GetReg32(system, 0));
1655 process_handle = Convert<Handle>(GetReg32(system, 2));
1656 address = Convert<uint32_t>(GetReg32(system, 3));
1657
1658 ret = QueryDebugProcessMemory64From32(system, out_memory_info, &out_page_info, process_handle, address);
1659
1660 SetReg32(system, 0, Convert<uint32_t>(ret));
1661 SetReg32(system, 1, Convert<uint32_t>(out_page_info));
1662}
1663
1664static void SvcWrap_ReadDebugProcessMemory64From32(Core::System& system) {
1665 Result ret{};
1666
1667 uint32_t buffer{};
1668 Handle debug_handle{};
1669 uint32_t address{};
1670 uint32_t size{};
1671
1672 buffer = Convert<uint32_t>(GetReg32(system, 0));
1673 debug_handle = Convert<Handle>(GetReg32(system, 1));
1674 address = Convert<uint32_t>(GetReg32(system, 2));
1675 size = Convert<uint32_t>(GetReg32(system, 3));
1676
1677 ret = ReadDebugProcessMemory64From32(system, buffer, debug_handle, address, size);
1678
1679 SetReg32(system, 0, Convert<uint32_t>(ret));
1680}
1681
1682static void SvcWrap_WriteDebugProcessMemory64From32(Core::System& system) {
1683 Result ret{};
1684
1685 Handle debug_handle{};
1686 uint32_t buffer{};
1687 uint32_t address{};
1688 uint32_t size{};
1689
1690 debug_handle = Convert<Handle>(GetReg32(system, 0));
1691 buffer = Convert<uint32_t>(GetReg32(system, 1));
1692 address = Convert<uint32_t>(GetReg32(system, 2));
1693 size = Convert<uint32_t>(GetReg32(system, 3));
1694
1695 ret = WriteDebugProcessMemory64From32(system, debug_handle, buffer, address, size);
1696
1697 SetReg32(system, 0, Convert<uint32_t>(ret));
1698}
1699
1700static void SvcWrap_SetHardwareBreakPoint64From32(Core::System& system) {
1701 Result ret{};
1702
1703 HardwareBreakPointRegisterName name{};
1704 uint64_t flags{};
1705 uint64_t value{};
1706
1707 name = Convert<HardwareBreakPointRegisterName>(GetReg32(system, 0));
1708 std::array<uint32_t, 2> flags_gather{};
1709 flags_gather[0] = GetReg32(system, 2);
1710 flags_gather[1] = GetReg32(system, 3);
1711 flags = Convert<uint64_t>(flags_gather);
1712 std::array<uint32_t, 2> value_gather{};
1713 value_gather[0] = GetReg32(system, 1);
1714 value_gather[1] = GetReg32(system, 4);
1715 value = Convert<uint64_t>(value_gather);
1716
1717 ret = SetHardwareBreakPoint64From32(system, name, flags, value);
1718
1719 SetReg32(system, 0, Convert<uint32_t>(ret));
1720}
1721
1722static void SvcWrap_GetDebugThreadParam64From32(Core::System& system) {
1723 Result ret{};
1724
1725 uint64_t out_64{};
1726 uint32_t out_32{};
1727 Handle debug_handle{};
1728 uint64_t thread_id{};
1729 DebugThreadParam param{};
1730
1731 debug_handle = Convert<Handle>(GetReg32(system, 2));
1732 std::array<uint32_t, 2> thread_id_gather{};
1733 thread_id_gather[0] = GetReg32(system, 0);
1734 thread_id_gather[1] = GetReg32(system, 1);
1735 thread_id = Convert<uint64_t>(thread_id_gather);
1736 param = Convert<DebugThreadParam>(GetReg32(system, 3));
1737
1738 ret = GetDebugThreadParam64From32(system, &out_64, &out_32, debug_handle, thread_id, param);
1739
1740 SetReg32(system, 0, Convert<uint32_t>(ret));
1741 auto out_64_scatter = Convert<std::array<uint32_t, 2>>(out_64);
1742 SetReg32(system, 1, out_64_scatter[0]);
1743 SetReg32(system, 2, out_64_scatter[1]);
1744 SetReg32(system, 3, Convert<uint32_t>(out_32));
1745}
1746
1747static void SvcWrap_GetSystemInfo64From32(Core::System& system) {
1748 Result ret{};
1749
1750 uint64_t out{};
1751 SystemInfoType info_type{};
1752 Handle handle{};
1753 uint64_t info_subtype{};
1754
1755 info_type = Convert<SystemInfoType>(GetReg32(system, 1));
1756 handle = Convert<Handle>(GetReg32(system, 2));
1757 std::array<uint32_t, 2> info_subtype_gather{};
1758 info_subtype_gather[0] = GetReg32(system, 0);
1759 info_subtype_gather[1] = GetReg32(system, 3);
1760 info_subtype = Convert<uint64_t>(info_subtype_gather);
1761
1762 ret = GetSystemInfo64From32(system, &out, info_type, handle, info_subtype);
1763
1764 SetReg32(system, 0, Convert<uint32_t>(ret));
1765 auto out_scatter = Convert<std::array<uint32_t, 2>>(out);
1766 SetReg32(system, 1, out_scatter[0]);
1767 SetReg32(system, 2, out_scatter[1]);
1768}
1769
1770static void SvcWrap_CreatePort64From32(Core::System& system) {
1771 Result ret{};
1772
1773 Handle out_server_handle{};
1774 Handle out_client_handle{};
1775 int32_t max_sessions{};
1776 bool is_light{};
1777 uint32_t name{};
1778
1779 max_sessions = Convert<int32_t>(GetReg32(system, 2));
1780 is_light = Convert<bool>(GetReg32(system, 3));
1781 name = Convert<uint32_t>(GetReg32(system, 0));
1782
1783 ret = CreatePort64From32(system, &out_server_handle, &out_client_handle, max_sessions, is_light, name);
1784
1785 SetReg32(system, 0, Convert<uint32_t>(ret));
1786 SetReg32(system, 1, Convert<uint32_t>(out_server_handle));
1787 SetReg32(system, 2, Convert<uint32_t>(out_client_handle));
1788}
1789
1790static void SvcWrap_ManageNamedPort64From32(Core::System& system) {
1791 Result ret{};
1792
1793 Handle out_server_handle{};
1794 uint32_t name{};
1795 int32_t max_sessions{};
1796
1797 name = Convert<uint32_t>(GetReg32(system, 1));
1798 max_sessions = Convert<int32_t>(GetReg32(system, 2));
1799
1800 ret = ManageNamedPort64From32(system, &out_server_handle, name, max_sessions);
1801
1802 SetReg32(system, 0, Convert<uint32_t>(ret));
1803 SetReg32(system, 1, Convert<uint32_t>(out_server_handle));
1804}
1805
1806static void SvcWrap_ConnectToPort64From32(Core::System& system) {
1807 Result ret{};
1808
1809 Handle out_handle{};
1810 Handle port{};
1811
1812 port = Convert<Handle>(GetReg32(system, 1));
1813
1814 ret = ConnectToPort64From32(system, &out_handle, port);
1815
1816 SetReg32(system, 0, Convert<uint32_t>(ret));
1817 SetReg32(system, 1, Convert<uint32_t>(out_handle));
1818}
1819
1820static void SvcWrap_SetProcessMemoryPermission64From32(Core::System& system) {
1821 Result ret{};
1822
1823 Handle process_handle{};
1824 uint64_t address{};
1825 uint64_t size{};
1826 MemoryPermission perm{};
1827
1828 process_handle = Convert<Handle>(GetReg32(system, 0));
1829 std::array<uint32_t, 2> address_gather{};
1830 address_gather[0] = GetReg32(system, 2);
1831 address_gather[1] = GetReg32(system, 3);
1832 address = Convert<uint64_t>(address_gather);
1833 std::array<uint32_t, 2> size_gather{};
1834 size_gather[0] = GetReg32(system, 1);
1835 size_gather[1] = GetReg32(system, 4);
1836 size = Convert<uint64_t>(size_gather);
1837 perm = Convert<MemoryPermission>(GetReg32(system, 5));
1838
1839 ret = SetProcessMemoryPermission64From32(system, process_handle, address, size, perm);
1840
1841 SetReg32(system, 0, Convert<uint32_t>(ret));
1842}
1843
1844static void SvcWrap_MapProcessMemory64From32(Core::System& system) {
1845 Result ret{};
1846
1847 uint32_t dst_address{};
1848 Handle process_handle{};
1849 uint64_t src_address{};
1850 uint32_t size{};
1851
1852 dst_address = Convert<uint32_t>(GetReg32(system, 0));
1853 process_handle = Convert<Handle>(GetReg32(system, 1));
1854 std::array<uint32_t, 2> src_address_gather{};
1855 src_address_gather[0] = GetReg32(system, 2);
1856 src_address_gather[1] = GetReg32(system, 3);
1857 src_address = Convert<uint64_t>(src_address_gather);
1858 size = Convert<uint32_t>(GetReg32(system, 4));
1859
1860 ret = MapProcessMemory64From32(system, dst_address, process_handle, src_address, size);
1861
1862 SetReg32(system, 0, Convert<uint32_t>(ret));
1863}
1864
1865static void SvcWrap_UnmapProcessMemory64From32(Core::System& system) {
1866 Result ret{};
1867
1868 uint32_t dst_address{};
1869 Handle process_handle{};
1870 uint64_t src_address{};
1871 uint32_t size{};
1872
1873 dst_address = Convert<uint32_t>(GetReg32(system, 0));
1874 process_handle = Convert<Handle>(GetReg32(system, 1));
1875 std::array<uint32_t, 2> src_address_gather{};
1876 src_address_gather[0] = GetReg32(system, 2);
1877 src_address_gather[1] = GetReg32(system, 3);
1878 src_address = Convert<uint64_t>(src_address_gather);
1879 size = Convert<uint32_t>(GetReg32(system, 4));
1880
1881 ret = UnmapProcessMemory64From32(system, dst_address, process_handle, src_address, size);
1882
1883 SetReg32(system, 0, Convert<uint32_t>(ret));
1884}
1885
1886static void SvcWrap_QueryProcessMemory64From32(Core::System& system) {
1887 Result ret{};
1888
1889 PageInfo out_page_info{};
1890 uint32_t out_memory_info{};
1891 Handle process_handle{};
1892 uint64_t address{};
1893
1894 out_memory_info = Convert<uint32_t>(GetReg32(system, 0));
1895 process_handle = Convert<Handle>(GetReg32(system, 2));
1896 std::array<uint32_t, 2> address_gather{};
1897 address_gather[0] = GetReg32(system, 1);
1898 address_gather[1] = GetReg32(system, 3);
1899 address = Convert<uint64_t>(address_gather);
1900
1901 ret = QueryProcessMemory64From32(system, out_memory_info, &out_page_info, process_handle, address);
1902
1903 SetReg32(system, 0, Convert<uint32_t>(ret));
1904 SetReg32(system, 1, Convert<uint32_t>(out_page_info));
1905}
1906
1907static void SvcWrap_MapProcessCodeMemory64From32(Core::System& system) {
1908 Result ret{};
1909
1910 Handle process_handle{};
1911 uint64_t dst_address{};
1912 uint64_t src_address{};
1913 uint64_t size{};
1914
1915 process_handle = Convert<Handle>(GetReg32(system, 0));
1916 std::array<uint32_t, 2> dst_address_gather{};
1917 dst_address_gather[0] = GetReg32(system, 2);
1918 dst_address_gather[1] = GetReg32(system, 3);
1919 dst_address = Convert<uint64_t>(dst_address_gather);
1920 std::array<uint32_t, 2> src_address_gather{};
1921 src_address_gather[0] = GetReg32(system, 1);
1922 src_address_gather[1] = GetReg32(system, 4);
1923 src_address = Convert<uint64_t>(src_address_gather);
1924 std::array<uint32_t, 2> size_gather{};
1925 size_gather[0] = GetReg32(system, 5);
1926 size_gather[1] = GetReg32(system, 6);
1927 size = Convert<uint64_t>(size_gather);
1928
1929 ret = MapProcessCodeMemory64From32(system, process_handle, dst_address, src_address, size);
1930
1931 SetReg32(system, 0, Convert<uint32_t>(ret));
1932}
1933
1934static void SvcWrap_UnmapProcessCodeMemory64From32(Core::System& system) {
1935 Result ret{};
1936
1937 Handle process_handle{};
1938 uint64_t dst_address{};
1939 uint64_t src_address{};
1940 uint64_t size{};
1941
1942 process_handle = Convert<Handle>(GetReg32(system, 0));
1943 std::array<uint32_t, 2> dst_address_gather{};
1944 dst_address_gather[0] = GetReg32(system, 2);
1945 dst_address_gather[1] = GetReg32(system, 3);
1946 dst_address = Convert<uint64_t>(dst_address_gather);
1947 std::array<uint32_t, 2> src_address_gather{};
1948 src_address_gather[0] = GetReg32(system, 1);
1949 src_address_gather[1] = GetReg32(system, 4);
1950 src_address = Convert<uint64_t>(src_address_gather);
1951 std::array<uint32_t, 2> size_gather{};
1952 size_gather[0] = GetReg32(system, 5);
1953 size_gather[1] = GetReg32(system, 6);
1954 size = Convert<uint64_t>(size_gather);
1955
1956 ret = UnmapProcessCodeMemory64From32(system, process_handle, dst_address, src_address, size);
1957
1958 SetReg32(system, 0, Convert<uint32_t>(ret));
1959}
1960
1961static void SvcWrap_CreateProcess64From32(Core::System& system) {
1962 Result ret{};
1963
1964 Handle out_handle{};
1965 uint32_t parameters{};
1966 uint32_t caps{};
1967 int32_t num_caps{};
1968
1969 parameters = Convert<uint32_t>(GetReg32(system, 1));
1970 caps = Convert<uint32_t>(GetReg32(system, 2));
1971 num_caps = Convert<int32_t>(GetReg32(system, 3));
1972
1973 ret = CreateProcess64From32(system, &out_handle, parameters, caps, num_caps);
1974
1975 SetReg32(system, 0, Convert<uint32_t>(ret));
1976 SetReg32(system, 1, Convert<uint32_t>(out_handle));
1977}
1978
1979static void SvcWrap_StartProcess64From32(Core::System& system) {
1980 Result ret{};
1981
1982 Handle process_handle{};
1983 int32_t priority{};
1984 int32_t core_id{};
1985 uint64_t main_thread_stack_size{};
1986
1987 process_handle = Convert<Handle>(GetReg32(system, 0));
1988 priority = Convert<int32_t>(GetReg32(system, 1));
1989 core_id = Convert<int32_t>(GetReg32(system, 2));
1990 std::array<uint32_t, 2> main_thread_stack_size_gather{};
1991 main_thread_stack_size_gather[0] = GetReg32(system, 3);
1992 main_thread_stack_size_gather[1] = GetReg32(system, 4);
1993 main_thread_stack_size = Convert<uint64_t>(main_thread_stack_size_gather);
1994
1995 ret = StartProcess64From32(system, process_handle, priority, core_id, main_thread_stack_size);
1996
1997 SetReg32(system, 0, Convert<uint32_t>(ret));
1998}
1999
2000static void SvcWrap_TerminateProcess64From32(Core::System& system) {
2001 Result ret{};
2002
2003 Handle process_handle{};
2004
2005 process_handle = Convert<Handle>(GetReg32(system, 0));
2006
2007 ret = TerminateProcess64From32(system, process_handle);
2008
2009 SetReg32(system, 0, Convert<uint32_t>(ret));
2010}
2011
2012static void SvcWrap_GetProcessInfo64From32(Core::System& system) {
2013 Result ret{};
2014
2015 int64_t out_info{};
2016 Handle process_handle{};
2017 ProcessInfoType info_type{};
2018
2019 process_handle = Convert<Handle>(GetReg32(system, 1));
2020 info_type = Convert<ProcessInfoType>(GetReg32(system, 2));
2021
2022 ret = GetProcessInfo64From32(system, &out_info, process_handle, info_type);
2023
2024 SetReg32(system, 0, Convert<uint32_t>(ret));
2025 auto out_info_scatter = Convert<std::array<uint32_t, 2>>(out_info);
2026 SetReg32(system, 1, out_info_scatter[0]);
2027 SetReg32(system, 2, out_info_scatter[1]);
2028}
2029
2030static void SvcWrap_CreateResourceLimit64From32(Core::System& system) {
2031 Result ret{};
2032
2033 Handle out_handle{};
2034
2035 ret = CreateResourceLimit64From32(system, &out_handle);
2036
2037 SetReg32(system, 0, Convert<uint32_t>(ret));
2038 SetReg32(system, 1, Convert<uint32_t>(out_handle));
2039}
2040
2041static void SvcWrap_SetResourceLimitLimitValue64From32(Core::System& system) {
2042 Result ret{};
2043
2044 Handle resource_limit_handle{};
2045 LimitableResource which{};
2046 int64_t limit_value{};
2047
2048 resource_limit_handle = Convert<Handle>(GetReg32(system, 0));
2049 which = Convert<LimitableResource>(GetReg32(system, 1));
2050 std::array<uint32_t, 2> limit_value_gather{};
2051 limit_value_gather[0] = GetReg32(system, 2);
2052 limit_value_gather[1] = GetReg32(system, 3);
2053 limit_value = Convert<int64_t>(limit_value_gather);
2054
2055 ret = SetResourceLimitLimitValue64From32(system, resource_limit_handle, which, limit_value);
2056
2057 SetReg32(system, 0, Convert<uint32_t>(ret));
2058}
2059
2060static void SvcWrap_MapInsecureMemory64From32(Core::System& system) {
2061 Result ret{};
2062
2063 uint32_t address{};
2064 uint32_t size{};
2065
2066 address = Convert<uint32_t>(GetReg32(system, 0));
2067 size = Convert<uint32_t>(GetReg32(system, 1));
2068
2069 ret = MapInsecureMemory64From32(system, address, size);
2070
2071 SetReg32(system, 0, Convert<uint32_t>(ret));
2072}
2073
2074static void SvcWrap_UnmapInsecureMemory64From32(Core::System& system) {
2075 Result ret{};
2076
2077 uint32_t address{};
2078 uint32_t size{};
2079
2080 address = Convert<uint32_t>(GetReg32(system, 0));
2081 size = Convert<uint32_t>(GetReg32(system, 1));
2082
2083 ret = UnmapInsecureMemory64From32(system, address, size);
2084
2085 SetReg32(system, 0, Convert<uint32_t>(ret));
2086}
2087
2088static void SvcWrap_SetHeapSize64(Core::System& system) {
2089 Result ret{};
2090
2091 uintptr_t out_address{};
2092 uint64_t size{};
2093
2094 size = Convert<uint64_t>(GetReg64(system, 1));
2095
2096 ret = SetHeapSize64(system, &out_address, size);
2097
2098 SetReg64(system, 0, Convert<uint64_t>(ret));
2099 SetReg64(system, 1, Convert<uint64_t>(out_address));
2100}
2101
2102static void SvcWrap_SetMemoryPermission64(Core::System& system) {
2103 Result ret{};
2104
2105 uint64_t address{};
2106 uint64_t size{};
2107 MemoryPermission perm{};
2108
2109 address = Convert<uint64_t>(GetReg64(system, 0));
2110 size = Convert<uint64_t>(GetReg64(system, 1));
2111 perm = Convert<MemoryPermission>(GetReg64(system, 2));
2112
2113 ret = SetMemoryPermission64(system, address, size, perm);
2114
2115 SetReg64(system, 0, Convert<uint64_t>(ret));
2116}
2117
2118static void SvcWrap_SetMemoryAttribute64(Core::System& system) {
2119 Result ret{};
2120
2121 uint64_t address{};
2122 uint64_t size{};
2123 uint32_t mask{};
2124 uint32_t attr{};
2125
2126 address = Convert<uint64_t>(GetReg64(system, 0));
2127 size = Convert<uint64_t>(GetReg64(system, 1));
2128 mask = Convert<uint32_t>(GetReg64(system, 2));
2129 attr = Convert<uint32_t>(GetReg64(system, 3));
2130
2131 ret = SetMemoryAttribute64(system, address, size, mask, attr);
2132
2133 SetReg64(system, 0, Convert<uint64_t>(ret));
2134}
2135
2136static void SvcWrap_MapMemory64(Core::System& system) {
2137 Result ret{};
2138
2139 uint64_t dst_address{};
2140 uint64_t src_address{};
2141 uint64_t size{};
2142
2143 dst_address = Convert<uint64_t>(GetReg64(system, 0));
2144 src_address = Convert<uint64_t>(GetReg64(system, 1));
2145 size = Convert<uint64_t>(GetReg64(system, 2));
2146
2147 ret = MapMemory64(system, dst_address, src_address, size);
2148
2149 SetReg64(system, 0, Convert<uint64_t>(ret));
2150}
2151
2152static void SvcWrap_UnmapMemory64(Core::System& system) {
2153 Result ret{};
2154
2155 uint64_t dst_address{};
2156 uint64_t src_address{};
2157 uint64_t size{};
2158
2159 dst_address = Convert<uint64_t>(GetReg64(system, 0));
2160 src_address = Convert<uint64_t>(GetReg64(system, 1));
2161 size = Convert<uint64_t>(GetReg64(system, 2));
2162
2163 ret = UnmapMemory64(system, dst_address, src_address, size);
2164
2165 SetReg64(system, 0, Convert<uint64_t>(ret));
2166}
2167
2168static void SvcWrap_QueryMemory64(Core::System& system) {
2169 Result ret{};
2170
2171 PageInfo out_page_info{};
2172 uint64_t out_memory_info{};
2173 uint64_t address{};
2174
2175 out_memory_info = Convert<uint64_t>(GetReg64(system, 0));
2176 address = Convert<uint64_t>(GetReg64(system, 2));
2177
2178 ret = QueryMemory64(system, out_memory_info, &out_page_info, address);
2179
2180 SetReg64(system, 0, Convert<uint64_t>(ret));
2181 SetReg64(system, 1, Convert<uint64_t>(out_page_info));
2182}
2183
2184static void SvcWrap_ExitProcess64(Core::System& system) {
2185 ExitProcess64(system);
2186}
2187
2188static void SvcWrap_CreateThread64(Core::System& system) {
2189 Result ret{};
2190
2191 Handle out_handle{};
2192 uint64_t func{};
2193 uint64_t arg{};
2194 uint64_t stack_bottom{};
2195 int32_t priority{};
2196 int32_t core_id{};
2197
2198 func = Convert<uint64_t>(GetReg64(system, 1));
2199 arg = Convert<uint64_t>(GetReg64(system, 2));
2200 stack_bottom = Convert<uint64_t>(GetReg64(system, 3));
2201 priority = Convert<int32_t>(GetReg64(system, 4));
2202 core_id = Convert<int32_t>(GetReg64(system, 5));
2203
2204 ret = CreateThread64(system, &out_handle, func, arg, stack_bottom, priority, core_id);
2205
2206 SetReg64(system, 0, Convert<uint64_t>(ret));
2207 SetReg64(system, 1, Convert<uint64_t>(out_handle));
2208}
2209
2210static void SvcWrap_StartThread64(Core::System& system) {
2211 Result ret{};
2212
2213 Handle thread_handle{};
2214
2215 thread_handle = Convert<Handle>(GetReg64(system, 0));
2216
2217 ret = StartThread64(system, thread_handle);
2218
2219 SetReg64(system, 0, Convert<uint64_t>(ret));
2220}
2221
2222static void SvcWrap_ExitThread64(Core::System& system) {
2223 ExitThread64(system);
2224}
2225
2226static void SvcWrap_SleepThread64(Core::System& system) {
2227 int64_t ns{};
2228
2229 ns = Convert<int64_t>(GetReg64(system, 0));
2230
2231 SleepThread64(system, ns);
2232}
2233
2234static void SvcWrap_GetThreadPriority64(Core::System& system) {
2235 Result ret{};
2236
2237 int32_t out_priority{};
2238 Handle thread_handle{};
2239
2240 thread_handle = Convert<Handle>(GetReg64(system, 1));
2241
2242 ret = GetThreadPriority64(system, &out_priority, thread_handle);
2243
2244 SetReg64(system, 0, Convert<uint64_t>(ret));
2245 SetReg64(system, 1, Convert<uint64_t>(out_priority));
2246}
2247
2248static void SvcWrap_SetThreadPriority64(Core::System& system) {
2249 Result ret{};
2250
2251 Handle thread_handle{};
2252 int32_t priority{};
2253
2254 thread_handle = Convert<Handle>(GetReg64(system, 0));
2255 priority = Convert<int32_t>(GetReg64(system, 1));
2256
2257 ret = SetThreadPriority64(system, thread_handle, priority);
2258
2259 SetReg64(system, 0, Convert<uint64_t>(ret));
2260}
2261
2262static void SvcWrap_GetThreadCoreMask64(Core::System& system) {
2263 Result ret{};
2264
2265 int32_t out_core_id{};
2266 uint64_t out_affinity_mask{};
2267 Handle thread_handle{};
2268
2269 thread_handle = Convert<Handle>(GetReg64(system, 2));
2270
2271 ret = GetThreadCoreMask64(system, &out_core_id, &out_affinity_mask, thread_handle);
2272
2273 SetReg64(system, 0, Convert<uint64_t>(ret));
2274 SetReg64(system, 1, Convert<uint64_t>(out_core_id));
2275 SetReg64(system, 2, Convert<uint64_t>(out_affinity_mask));
2276}
2277
2278static void SvcWrap_SetThreadCoreMask64(Core::System& system) {
2279 Result ret{};
2280
2281 Handle thread_handle{};
2282 int32_t core_id{};
2283 uint64_t affinity_mask{};
2284
2285 thread_handle = Convert<Handle>(GetReg64(system, 0));
2286 core_id = Convert<int32_t>(GetReg64(system, 1));
2287 affinity_mask = Convert<uint64_t>(GetReg64(system, 2));
2288
2289 ret = SetThreadCoreMask64(system, thread_handle, core_id, affinity_mask);
2290
2291 SetReg64(system, 0, Convert<uint64_t>(ret));
2292}
2293
2294static void SvcWrap_GetCurrentProcessorNumber64(Core::System& system) {
2295 int32_t ret{};
2296
2297 ret = GetCurrentProcessorNumber64(system);
2298
2299 SetReg64(system, 0, Convert<uint64_t>(ret));
2300}
2301
2302static void SvcWrap_SignalEvent64(Core::System& system) {
2303 Result ret{};
2304
2305 Handle event_handle{};
2306
2307 event_handle = Convert<Handle>(GetReg64(system, 0));
2308
2309 ret = SignalEvent64(system, event_handle);
2310
2311 SetReg64(system, 0, Convert<uint64_t>(ret));
2312}
2313
2314static void SvcWrap_ClearEvent64(Core::System& system) {
2315 Result ret{};
2316
2317 Handle event_handle{};
2318
2319 event_handle = Convert<Handle>(GetReg64(system, 0));
2320
2321 ret = ClearEvent64(system, event_handle);
2322
2323 SetReg64(system, 0, Convert<uint64_t>(ret));
2324}
2325
2326static void SvcWrap_MapSharedMemory64(Core::System& system) {
2327 Result ret{};
2328
2329 Handle shmem_handle{};
2330 uint64_t address{};
2331 uint64_t size{};
2332 MemoryPermission map_perm{};
2333
2334 shmem_handle = Convert<Handle>(GetReg64(system, 0));
2335 address = Convert<uint64_t>(GetReg64(system, 1));
2336 size = Convert<uint64_t>(GetReg64(system, 2));
2337 map_perm = Convert<MemoryPermission>(GetReg64(system, 3));
2338
2339 ret = MapSharedMemory64(system, shmem_handle, address, size, map_perm);
2340
2341 SetReg64(system, 0, Convert<uint64_t>(ret));
2342}
2343
2344static void SvcWrap_UnmapSharedMemory64(Core::System& system) {
2345 Result ret{};
2346
2347 Handle shmem_handle{};
2348 uint64_t address{};
2349 uint64_t size{};
2350
2351 shmem_handle = Convert<Handle>(GetReg64(system, 0));
2352 address = Convert<uint64_t>(GetReg64(system, 1));
2353 size = Convert<uint64_t>(GetReg64(system, 2));
2354
2355 ret = UnmapSharedMemory64(system, shmem_handle, address, size);
2356
2357 SetReg64(system, 0, Convert<uint64_t>(ret));
2358}
2359
2360static void SvcWrap_CreateTransferMemory64(Core::System& system) {
2361 Result ret{};
2362
2363 Handle out_handle{};
2364 uint64_t address{};
2365 uint64_t size{};
2366 MemoryPermission map_perm{};
2367
2368 address = Convert<uint64_t>(GetReg64(system, 1));
2369 size = Convert<uint64_t>(GetReg64(system, 2));
2370 map_perm = Convert<MemoryPermission>(GetReg64(system, 3));
2371
2372 ret = CreateTransferMemory64(system, &out_handle, address, size, map_perm);
2373
2374 SetReg64(system, 0, Convert<uint64_t>(ret));
2375 SetReg64(system, 1, Convert<uint64_t>(out_handle));
2376}
2377
2378static void SvcWrap_CloseHandle64(Core::System& system) {
2379 Result ret{};
2380
2381 Handle handle{};
2382
2383 handle = Convert<Handle>(GetReg64(system, 0));
2384
2385 ret = CloseHandle64(system, handle);
2386
2387 SetReg64(system, 0, Convert<uint64_t>(ret));
2388}
2389
2390static void SvcWrap_ResetSignal64(Core::System& system) {
2391 Result ret{};
2392
2393 Handle handle{};
2394
2395 handle = Convert<Handle>(GetReg64(system, 0));
2396
2397 ret = ResetSignal64(system, handle);
2398
2399 SetReg64(system, 0, Convert<uint64_t>(ret));
2400}
2401
2402static void SvcWrap_WaitSynchronization64(Core::System& system) {
2403 Result ret{};
2404
2405 int32_t out_index{};
2406 uint64_t handles{};
2407 int32_t num_handles{};
2408 int64_t timeout_ns{};
2409
2410 handles = Convert<uint64_t>(GetReg64(system, 1));
2411 num_handles = Convert<int32_t>(GetReg64(system, 2));
2412 timeout_ns = Convert<int64_t>(GetReg64(system, 3));
2413
2414 ret = WaitSynchronization64(system, &out_index, handles, num_handles, timeout_ns);
2415
2416 SetReg64(system, 0, Convert<uint64_t>(ret));
2417 SetReg64(system, 1, Convert<uint64_t>(out_index));
2418}
2419
2420static void SvcWrap_CancelSynchronization64(Core::System& system) {
2421 Result ret{};
2422
2423 Handle handle{};
2424
2425 handle = Convert<Handle>(GetReg64(system, 0));
2426
2427 ret = CancelSynchronization64(system, handle);
2428
2429 SetReg64(system, 0, Convert<uint64_t>(ret));
2430}
2431
2432static void SvcWrap_ArbitrateLock64(Core::System& system) {
2433 Result ret{};
2434
2435 Handle thread_handle{};
2436 uint64_t address{};
2437 uint32_t tag{};
2438
2439 thread_handle = Convert<Handle>(GetReg64(system, 0));
2440 address = Convert<uint64_t>(GetReg64(system, 1));
2441 tag = Convert<uint32_t>(GetReg64(system, 2));
2442
2443 ret = ArbitrateLock64(system, thread_handle, address, tag);
2444
2445 SetReg64(system, 0, Convert<uint64_t>(ret));
2446}
2447
2448static void SvcWrap_ArbitrateUnlock64(Core::System& system) {
2449 Result ret{};
2450
2451 uint64_t address{};
2452
2453 address = Convert<uint64_t>(GetReg64(system, 0));
2454
2455 ret = ArbitrateUnlock64(system, address);
2456
2457 SetReg64(system, 0, Convert<uint64_t>(ret));
2458}
2459
2460static void SvcWrap_WaitProcessWideKeyAtomic64(Core::System& system) {
2461 Result ret{};
2462
2463 uint64_t address{};
2464 uint64_t cv_key{};
2465 uint32_t tag{};
2466 int64_t timeout_ns{};
2467
2468 address = Convert<uint64_t>(GetReg64(system, 0));
2469 cv_key = Convert<uint64_t>(GetReg64(system, 1));
2470 tag = Convert<uint32_t>(GetReg64(system, 2));
2471 timeout_ns = Convert<int64_t>(GetReg64(system, 3));
2472
2473 ret = WaitProcessWideKeyAtomic64(system, address, cv_key, tag, timeout_ns);
2474
2475 SetReg64(system, 0, Convert<uint64_t>(ret));
2476}
2477
2478static void SvcWrap_SignalProcessWideKey64(Core::System& system) {
2479 uint64_t cv_key{};
2480 int32_t count{};
2481
2482 cv_key = Convert<uint64_t>(GetReg64(system, 0));
2483 count = Convert<int32_t>(GetReg64(system, 1));
2484
2485 SignalProcessWideKey64(system, cv_key, count);
2486}
2487
2488static void SvcWrap_GetSystemTick64(Core::System& system) {
2489 int64_t ret{};
2490
2491 ret = GetSystemTick64(system);
2492
2493 SetReg64(system, 0, Convert<uint64_t>(ret));
2494}
2495
2496static void SvcWrap_ConnectToNamedPort64(Core::System& system) {
2497 Result ret{};
2498
2499 Handle out_handle{};
2500 uint64_t name{};
2501
2502 name = Convert<uint64_t>(GetReg64(system, 1));
2503
2504 ret = ConnectToNamedPort64(system, &out_handle, name);
2505
2506 SetReg64(system, 0, Convert<uint64_t>(ret));
2507 SetReg64(system, 1, Convert<uint64_t>(out_handle));
2508}
2509
2510static void SvcWrap_SendSyncRequest64(Core::System& system) {
2511 Result ret{};
2512
2513 Handle session_handle{};
2514
2515 session_handle = Convert<Handle>(GetReg64(system, 0));
2516
2517 ret = SendSyncRequest64(system, session_handle);
2518
2519 SetReg64(system, 0, Convert<uint64_t>(ret));
2520}
2521
2522static void SvcWrap_SendSyncRequestWithUserBuffer64(Core::System& system) {
2523 Result ret{};
2524
2525 uint64_t message_buffer{};
2526 uint64_t message_buffer_size{};
2527 Handle session_handle{};
2528
2529 message_buffer = Convert<uint64_t>(GetReg64(system, 0));
2530 message_buffer_size = Convert<uint64_t>(GetReg64(system, 1));
2531 session_handle = Convert<Handle>(GetReg64(system, 2));
2532
2533 ret = SendSyncRequestWithUserBuffer64(system, message_buffer, message_buffer_size, session_handle);
2534
2535 SetReg64(system, 0, Convert<uint64_t>(ret));
2536}
2537
2538static void SvcWrap_SendAsyncRequestWithUserBuffer64(Core::System& system) {
2539 Result ret{};
2540
2541 Handle out_event_handle{};
2542 uint64_t message_buffer{};
2543 uint64_t message_buffer_size{};
2544 Handle session_handle{};
2545
2546 message_buffer = Convert<uint64_t>(GetReg64(system, 1));
2547 message_buffer_size = Convert<uint64_t>(GetReg64(system, 2));
2548 session_handle = Convert<Handle>(GetReg64(system, 3));
2549
2550 ret = SendAsyncRequestWithUserBuffer64(system, &out_event_handle, message_buffer, message_buffer_size, session_handle);
2551
2552 SetReg64(system, 0, Convert<uint64_t>(ret));
2553 SetReg64(system, 1, Convert<uint64_t>(out_event_handle));
2554}
2555
2556static void SvcWrap_GetProcessId64(Core::System& system) {
2557 Result ret{};
2558
2559 uint64_t out_process_id{};
2560 Handle process_handle{};
2561
2562 process_handle = Convert<Handle>(GetReg64(system, 1));
2563
2564 ret = GetProcessId64(system, &out_process_id, process_handle);
2565
2566 SetReg64(system, 0, Convert<uint64_t>(ret));
2567 SetReg64(system, 1, Convert<uint64_t>(out_process_id));
2568}
2569
2570static void SvcWrap_GetThreadId64(Core::System& system) {
2571 Result ret{};
2572
2573 uint64_t out_thread_id{};
2574 Handle thread_handle{};
2575
2576 thread_handle = Convert<Handle>(GetReg64(system, 1));
2577
2578 ret = GetThreadId64(system, &out_thread_id, thread_handle);
2579
2580 SetReg64(system, 0, Convert<uint64_t>(ret));
2581 SetReg64(system, 1, Convert<uint64_t>(out_thread_id));
2582}
2583
2584static void SvcWrap_Break64(Core::System& system) {
2585 BreakReason break_reason{};
2586 uint64_t arg{};
2587 uint64_t size{};
2588
2589 break_reason = Convert<BreakReason>(GetReg64(system, 0));
2590 arg = Convert<uint64_t>(GetReg64(system, 1));
2591 size = Convert<uint64_t>(GetReg64(system, 2));
2592
2593 Break64(system, break_reason, arg, size);
2594}
2595
2596static void SvcWrap_OutputDebugString64(Core::System& system) {
2597 Result ret{};
2598
2599 uint64_t debug_str{};
2600 uint64_t len{};
2601
2602 debug_str = Convert<uint64_t>(GetReg64(system, 0));
2603 len = Convert<uint64_t>(GetReg64(system, 1));
2604
2605 ret = OutputDebugString64(system, debug_str, len);
2606
2607 SetReg64(system, 0, Convert<uint64_t>(ret));
2608}
2609
2610static void SvcWrap_ReturnFromException64(Core::System& system) {
2611 Result result{};
2612
2613 result = Convert<Result>(GetReg64(system, 0));
2614
2615 ReturnFromException64(system, result);
2616}
2617
2618static void SvcWrap_GetInfo64(Core::System& system) {
2619 Result ret{};
2620
2621 uint64_t out{};
2622 InfoType info_type{};
2623 Handle handle{};
2624 uint64_t info_subtype{};
2625
2626 info_type = Convert<InfoType>(GetReg64(system, 1));
2627 handle = Convert<Handle>(GetReg64(system, 2));
2628 info_subtype = Convert<uint64_t>(GetReg64(system, 3));
2629
2630 ret = GetInfo64(system, &out, info_type, handle, info_subtype);
2631
2632 SetReg64(system, 0, Convert<uint64_t>(ret));
2633 SetReg64(system, 1, Convert<uint64_t>(out));
2634}
2635
2636static void SvcWrap_FlushEntireDataCache64(Core::System& system) {
2637 FlushEntireDataCache64(system);
2638}
2639
2640static void SvcWrap_FlushDataCache64(Core::System& system) {
2641 Result ret{};
2642
2643 uint64_t address{};
2644 uint64_t size{};
2645
2646 address = Convert<uint64_t>(GetReg64(system, 0));
2647 size = Convert<uint64_t>(GetReg64(system, 1));
2648
2649 ret = FlushDataCache64(system, address, size);
2650
2651 SetReg64(system, 0, Convert<uint64_t>(ret));
2652}
2653
2654static void SvcWrap_MapPhysicalMemory64(Core::System& system) {
2655 Result ret{};
2656
2657 uint64_t address{};
2658 uint64_t size{};
2659
2660 address = Convert<uint64_t>(GetReg64(system, 0));
2661 size = Convert<uint64_t>(GetReg64(system, 1));
2662
2663 ret = MapPhysicalMemory64(system, address, size);
2664
2665 SetReg64(system, 0, Convert<uint64_t>(ret));
2666}
2667
2668static void SvcWrap_UnmapPhysicalMemory64(Core::System& system) {
2669 Result ret{};
2670
2671 uint64_t address{};
2672 uint64_t size{};
2673
2674 address = Convert<uint64_t>(GetReg64(system, 0));
2675 size = Convert<uint64_t>(GetReg64(system, 1));
2676
2677 ret = UnmapPhysicalMemory64(system, address, size);
2678
2679 SetReg64(system, 0, Convert<uint64_t>(ret));
2680}
2681
2682static void SvcWrap_GetDebugFutureThreadInfo64(Core::System& system) {
2683 Result ret{};
2684
2685 lp64::LastThreadContext out_context{};
2686 uint64_t out_thread_id{};
2687 Handle debug_handle{};
2688 int64_t ns{};
2689
2690 debug_handle = Convert<Handle>(GetReg64(system, 2));
2691 ns = Convert<int64_t>(GetReg64(system, 3));
2692
2693 ret = GetDebugFutureThreadInfo64(system, &out_context, &out_thread_id, debug_handle, ns);
2694
2695 SetReg64(system, 0, Convert<uint64_t>(ret));
2696 auto out_context_scatter = Convert<std::array<uint64_t, 4>>(out_context);
2697 SetReg64(system, 1, out_context_scatter[0]);
2698 SetReg64(system, 2, out_context_scatter[1]);
2699 SetReg64(system, 3, out_context_scatter[2]);
2700 SetReg64(system, 4, out_context_scatter[3]);
2701 SetReg64(system, 5, Convert<uint64_t>(out_thread_id));
2702}
2703
2704static void SvcWrap_GetLastThreadInfo64(Core::System& system) {
2705 Result ret{};
2706
2707 lp64::LastThreadContext out_context{};
2708 uintptr_t out_tls_address{};
2709 uint32_t out_flags{};
2710
2711 ret = GetLastThreadInfo64(system, &out_context, &out_tls_address, &out_flags);
2712
2713 SetReg64(system, 0, Convert<uint64_t>(ret));
2714 auto out_context_scatter = Convert<std::array<uint64_t, 4>>(out_context);
2715 SetReg64(system, 1, out_context_scatter[0]);
2716 SetReg64(system, 2, out_context_scatter[1]);
2717 SetReg64(system, 3, out_context_scatter[2]);
2718 SetReg64(system, 4, out_context_scatter[3]);
2719 SetReg64(system, 5, Convert<uint64_t>(out_tls_address));
2720 SetReg64(system, 6, Convert<uint64_t>(out_flags));
2721}
2722
2723static void SvcWrap_GetResourceLimitLimitValue64(Core::System& system) {
2724 Result ret{};
2725
2726 int64_t out_limit_value{};
2727 Handle resource_limit_handle{};
2728 LimitableResource which{};
2729
2730 resource_limit_handle = Convert<Handle>(GetReg64(system, 1));
2731 which = Convert<LimitableResource>(GetReg64(system, 2));
2732
2733 ret = GetResourceLimitLimitValue64(system, &out_limit_value, resource_limit_handle, which);
2734
2735 SetReg64(system, 0, Convert<uint64_t>(ret));
2736 SetReg64(system, 1, Convert<uint64_t>(out_limit_value));
2737}
2738
2739static void SvcWrap_GetResourceLimitCurrentValue64(Core::System& system) {
2740 Result ret{};
2741
2742 int64_t out_current_value{};
2743 Handle resource_limit_handle{};
2744 LimitableResource which{};
2745
2746 resource_limit_handle = Convert<Handle>(GetReg64(system, 1));
2747 which = Convert<LimitableResource>(GetReg64(system, 2));
2748
2749 ret = GetResourceLimitCurrentValue64(system, &out_current_value, resource_limit_handle, which);
2750
2751 SetReg64(system, 0, Convert<uint64_t>(ret));
2752 SetReg64(system, 1, Convert<uint64_t>(out_current_value));
2753}
2754
2755static void SvcWrap_SetThreadActivity64(Core::System& system) {
2756 Result ret{};
2757
2758 Handle thread_handle{};
2759 ThreadActivity thread_activity{};
2760
2761 thread_handle = Convert<Handle>(GetReg64(system, 0));
2762 thread_activity = Convert<ThreadActivity>(GetReg64(system, 1));
2763
2764 ret = SetThreadActivity64(system, thread_handle, thread_activity);
2765
2766 SetReg64(system, 0, Convert<uint64_t>(ret));
2767}
2768
2769static void SvcWrap_GetThreadContext364(Core::System& system) {
2770 Result ret{};
2771
2772 uint64_t out_context{};
2773 Handle thread_handle{};
2774
2775 out_context = Convert<uint64_t>(GetReg64(system, 0));
2776 thread_handle = Convert<Handle>(GetReg64(system, 1));
2777
2778 ret = GetThreadContext364(system, out_context, thread_handle);
2779
2780 SetReg64(system, 0, Convert<uint64_t>(ret));
2781}
2782
2783static void SvcWrap_WaitForAddress64(Core::System& system) {
2784 Result ret{};
2785
2786 uint64_t address{};
2787 ArbitrationType arb_type{};
2788 int32_t value{};
2789 int64_t timeout_ns{};
2790
2791 address = Convert<uint64_t>(GetReg64(system, 0));
2792 arb_type = Convert<ArbitrationType>(GetReg64(system, 1));
2793 value = Convert<int32_t>(GetReg64(system, 2));
2794 timeout_ns = Convert<int64_t>(GetReg64(system, 3));
2795
2796 ret = WaitForAddress64(system, address, arb_type, value, timeout_ns);
2797
2798 SetReg64(system, 0, Convert<uint64_t>(ret));
2799}
2800
2801static void SvcWrap_SignalToAddress64(Core::System& system) {
2802 Result ret{};
2803
2804 uint64_t address{};
2805 SignalType signal_type{};
2806 int32_t value{};
2807 int32_t count{};
2808
2809 address = Convert<uint64_t>(GetReg64(system, 0));
2810 signal_type = Convert<SignalType>(GetReg64(system, 1));
2811 value = Convert<int32_t>(GetReg64(system, 2));
2812 count = Convert<int32_t>(GetReg64(system, 3));
2813
2814 ret = SignalToAddress64(system, address, signal_type, value, count);
2815
2816 SetReg64(system, 0, Convert<uint64_t>(ret));
2817}
2818
2819static void SvcWrap_SynchronizePreemptionState64(Core::System& system) {
2820 SynchronizePreemptionState64(system);
2821}
2822
2823static void SvcWrap_GetResourceLimitPeakValue64(Core::System& system) {
2824 Result ret{};
2825
2826 int64_t out_peak_value{};
2827 Handle resource_limit_handle{};
2828 LimitableResource which{};
2829
2830 resource_limit_handle = Convert<Handle>(GetReg64(system, 1));
2831 which = Convert<LimitableResource>(GetReg64(system, 2));
2832
2833 ret = GetResourceLimitPeakValue64(system, &out_peak_value, resource_limit_handle, which);
2834
2835 SetReg64(system, 0, Convert<uint64_t>(ret));
2836 SetReg64(system, 1, Convert<uint64_t>(out_peak_value));
2837}
2838
2839static void SvcWrap_CreateIoPool64(Core::System& system) {
2840 Result ret{};
2841
2842 Handle out_handle{};
2843 IoPoolType which{};
2844
2845 which = Convert<IoPoolType>(GetReg64(system, 1));
2846
2847 ret = CreateIoPool64(system, &out_handle, which);
2848
2849 SetReg64(system, 0, Convert<uint64_t>(ret));
2850 SetReg64(system, 1, Convert<uint64_t>(out_handle));
2851}
2852
2853static void SvcWrap_CreateIoRegion64(Core::System& system) {
2854 Result ret{};
2855
2856 Handle out_handle{};
2857 Handle io_pool{};
2858 uint64_t physical_address{};
2859 uint64_t size{};
2860 MemoryMapping mapping{};
2861 MemoryPermission perm{};
2862
2863 io_pool = Convert<Handle>(GetReg64(system, 1));
2864 physical_address = Convert<uint64_t>(GetReg64(system, 2));
2865 size = Convert<uint64_t>(GetReg64(system, 3));
2866 mapping = Convert<MemoryMapping>(GetReg64(system, 4));
2867 perm = Convert<MemoryPermission>(GetReg64(system, 5));
2868
2869 ret = CreateIoRegion64(system, &out_handle, io_pool, physical_address, size, mapping, perm);
2870
2871 SetReg64(system, 0, Convert<uint64_t>(ret));
2872 SetReg64(system, 1, Convert<uint64_t>(out_handle));
2873}
2874
2875static void SvcWrap_KernelDebug64(Core::System& system) {
2876 KernelDebugType kern_debug_type{};
2877 uint64_t arg0{};
2878 uint64_t arg1{};
2879 uint64_t arg2{};
2880
2881 kern_debug_type = Convert<KernelDebugType>(GetReg64(system, 0));
2882 arg0 = Convert<uint64_t>(GetReg64(system, 1));
2883 arg1 = Convert<uint64_t>(GetReg64(system, 2));
2884 arg2 = Convert<uint64_t>(GetReg64(system, 3));
2885
2886 KernelDebug64(system, kern_debug_type, arg0, arg1, arg2);
2887}
2888
2889static void SvcWrap_ChangeKernelTraceState64(Core::System& system) {
2890 KernelTraceState kern_trace_state{};
2891
2892 kern_trace_state = Convert<KernelTraceState>(GetReg64(system, 0));
2893
2894 ChangeKernelTraceState64(system, kern_trace_state);
2895}
2896
2897static void SvcWrap_CreateSession64(Core::System& system) {
2898 Result ret{};
2899
2900 Handle out_server_session_handle{};
2901 Handle out_client_session_handle{};
2902 bool is_light{};
2903 uint64_t name{};
2904
2905 is_light = Convert<bool>(GetReg64(system, 2));
2906 name = Convert<uint64_t>(GetReg64(system, 3));
2907
2908 ret = CreateSession64(system, &out_server_session_handle, &out_client_session_handle, is_light, name);
2909
2910 SetReg64(system, 0, Convert<uint64_t>(ret));
2911 SetReg64(system, 1, Convert<uint64_t>(out_server_session_handle));
2912 SetReg64(system, 2, Convert<uint64_t>(out_client_session_handle));
2913}
2914
2915static void SvcWrap_AcceptSession64(Core::System& system) {
2916 Result ret{};
2917
2918 Handle out_handle{};
2919 Handle port{};
2920
2921 port = Convert<Handle>(GetReg64(system, 1));
2922
2923 ret = AcceptSession64(system, &out_handle, port);
2924
2925 SetReg64(system, 0, Convert<uint64_t>(ret));
2926 SetReg64(system, 1, Convert<uint64_t>(out_handle));
2927}
2928
2929static void SvcWrap_ReplyAndReceive64(Core::System& system) {
2930 Result ret{};
2931
2932 int32_t out_index{};
2933 uint64_t handles{};
2934 int32_t num_handles{};
2935 Handle reply_target{};
2936 int64_t timeout_ns{};
2937
2938 handles = Convert<uint64_t>(GetReg64(system, 1));
2939 num_handles = Convert<int32_t>(GetReg64(system, 2));
2940 reply_target = Convert<Handle>(GetReg64(system, 3));
2941 timeout_ns = Convert<int64_t>(GetReg64(system, 4));
2942
2943 ret = ReplyAndReceive64(system, &out_index, handles, num_handles, reply_target, timeout_ns);
2944
2945 SetReg64(system, 0, Convert<uint64_t>(ret));
2946 SetReg64(system, 1, Convert<uint64_t>(out_index));
2947}
2948
2949static void SvcWrap_ReplyAndReceiveWithUserBuffer64(Core::System& system) {
2950 Result ret{};
2951
2952 int32_t out_index{};
2953 uint64_t message_buffer{};
2954 uint64_t message_buffer_size{};
2955 uint64_t handles{};
2956 int32_t num_handles{};
2957 Handle reply_target{};
2958 int64_t timeout_ns{};
2959
2960 message_buffer = Convert<uint64_t>(GetReg64(system, 1));
2961 message_buffer_size = Convert<uint64_t>(GetReg64(system, 2));
2962 handles = Convert<uint64_t>(GetReg64(system, 3));
2963 num_handles = Convert<int32_t>(GetReg64(system, 4));
2964 reply_target = Convert<Handle>(GetReg64(system, 5));
2965 timeout_ns = Convert<int64_t>(GetReg64(system, 6));
2966
2967 ret = ReplyAndReceiveWithUserBuffer64(system, &out_index, message_buffer, message_buffer_size, handles, num_handles, reply_target, timeout_ns);
2968
2969 SetReg64(system, 0, Convert<uint64_t>(ret));
2970 SetReg64(system, 1, Convert<uint64_t>(out_index));
2971}
2972
2973static void SvcWrap_CreateEvent64(Core::System& system) {
2974 Result ret{};
2975
2976 Handle out_write_handle{};
2977 Handle out_read_handle{};
2978
2979 ret = CreateEvent64(system, &out_write_handle, &out_read_handle);
2980
2981 SetReg64(system, 0, Convert<uint64_t>(ret));
2982 SetReg64(system, 1, Convert<uint64_t>(out_write_handle));
2983 SetReg64(system, 2, Convert<uint64_t>(out_read_handle));
2984}
2985
2986static void SvcWrap_MapIoRegion64(Core::System& system) {
2987 Result ret{};
2988
2989 Handle io_region{};
2990 uint64_t address{};
2991 uint64_t size{};
2992 MemoryPermission perm{};
2993
2994 io_region = Convert<Handle>(GetReg64(system, 0));
2995 address = Convert<uint64_t>(GetReg64(system, 1));
2996 size = Convert<uint64_t>(GetReg64(system, 2));
2997 perm = Convert<MemoryPermission>(GetReg64(system, 3));
2998
2999 ret = MapIoRegion64(system, io_region, address, size, perm);
3000
3001 SetReg64(system, 0, Convert<uint64_t>(ret));
3002}
3003
3004static void SvcWrap_UnmapIoRegion64(Core::System& system) {
3005 Result ret{};
3006
3007 Handle io_region{};
3008 uint64_t address{};
3009 uint64_t size{};
3010
3011 io_region = Convert<Handle>(GetReg64(system, 0));
3012 address = Convert<uint64_t>(GetReg64(system, 1));
3013 size = Convert<uint64_t>(GetReg64(system, 2));
3014
3015 ret = UnmapIoRegion64(system, io_region, address, size);
3016
3017 SetReg64(system, 0, Convert<uint64_t>(ret));
3018}
3019
3020static void SvcWrap_MapPhysicalMemoryUnsafe64(Core::System& system) {
3021 Result ret{};
3022
3023 uint64_t address{};
3024 uint64_t size{};
3025
3026 address = Convert<uint64_t>(GetReg64(system, 0));
3027 size = Convert<uint64_t>(GetReg64(system, 1));
3028
3029 ret = MapPhysicalMemoryUnsafe64(system, address, size);
3030
3031 SetReg64(system, 0, Convert<uint64_t>(ret));
3032}
3033
3034static void SvcWrap_UnmapPhysicalMemoryUnsafe64(Core::System& system) {
3035 Result ret{};
3036
3037 uint64_t address{};
3038 uint64_t size{};
3039
3040 address = Convert<uint64_t>(GetReg64(system, 0));
3041 size = Convert<uint64_t>(GetReg64(system, 1));
3042
3043 ret = UnmapPhysicalMemoryUnsafe64(system, address, size);
3044
3045 SetReg64(system, 0, Convert<uint64_t>(ret));
3046}
3047
3048static void SvcWrap_SetUnsafeLimit64(Core::System& system) {
3049 Result ret{};
3050
3051 uint64_t limit{};
3052
3053 limit = Convert<uint64_t>(GetReg64(system, 0));
3054
3055 ret = SetUnsafeLimit64(system, limit);
3056
3057 SetReg64(system, 0, Convert<uint64_t>(ret));
3058}
3059
3060static void SvcWrap_CreateCodeMemory64(Core::System& system) {
3061 Result ret{};
3062
3063 Handle out_handle{};
3064 uint64_t address{};
3065 uint64_t size{};
3066
3067 address = Convert<uint64_t>(GetReg64(system, 1));
3068 size = Convert<uint64_t>(GetReg64(system, 2));
3069
3070 ret = CreateCodeMemory64(system, &out_handle, address, size);
3071
3072 SetReg64(system, 0, Convert<uint64_t>(ret));
3073 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3074}
3075
3076static void SvcWrap_ControlCodeMemory64(Core::System& system) {
3077 Result ret{};
3078
3079 Handle code_memory_handle{};
3080 CodeMemoryOperation operation{};
3081 uint64_t address{};
3082 uint64_t size{};
3083 MemoryPermission perm{};
3084
3085 code_memory_handle = Convert<Handle>(GetReg64(system, 0));
3086 operation = Convert<CodeMemoryOperation>(GetReg64(system, 1));
3087 address = Convert<uint64_t>(GetReg64(system, 2));
3088 size = Convert<uint64_t>(GetReg64(system, 3));
3089 perm = Convert<MemoryPermission>(GetReg64(system, 4));
3090
3091 ret = ControlCodeMemory64(system, code_memory_handle, operation, address, size, perm);
3092
3093 SetReg64(system, 0, Convert<uint64_t>(ret));
3094}
3095
3096static void SvcWrap_SleepSystem64(Core::System& system) {
3097 SleepSystem64(system);
3098}
3099
3100static void SvcWrap_ReadWriteRegister64(Core::System& system) {
3101 Result ret{};
3102
3103 uint32_t out_value{};
3104 uint64_t address{};
3105 uint32_t mask{};
3106 uint32_t value{};
3107
3108 address = Convert<uint64_t>(GetReg64(system, 1));
3109 mask = Convert<uint32_t>(GetReg64(system, 2));
3110 value = Convert<uint32_t>(GetReg64(system, 3));
3111
3112 ret = ReadWriteRegister64(system, &out_value, address, mask, value);
3113
3114 SetReg64(system, 0, Convert<uint64_t>(ret));
3115 SetReg64(system, 1, Convert<uint64_t>(out_value));
3116}
3117
3118static void SvcWrap_SetProcessActivity64(Core::System& system) {
3119 Result ret{};
3120
3121 Handle process_handle{};
3122 ProcessActivity process_activity{};
3123
3124 process_handle = Convert<Handle>(GetReg64(system, 0));
3125 process_activity = Convert<ProcessActivity>(GetReg64(system, 1));
3126
3127 ret = SetProcessActivity64(system, process_handle, process_activity);
3128
3129 SetReg64(system, 0, Convert<uint64_t>(ret));
3130}
3131
3132static void SvcWrap_CreateSharedMemory64(Core::System& system) {
3133 Result ret{};
3134
3135 Handle out_handle{};
3136 uint64_t size{};
3137 MemoryPermission owner_perm{};
3138 MemoryPermission remote_perm{};
3139
3140 size = Convert<uint64_t>(GetReg64(system, 1));
3141 owner_perm = Convert<MemoryPermission>(GetReg64(system, 2));
3142 remote_perm = Convert<MemoryPermission>(GetReg64(system, 3));
3143
3144 ret = CreateSharedMemory64(system, &out_handle, size, owner_perm, remote_perm);
3145
3146 SetReg64(system, 0, Convert<uint64_t>(ret));
3147 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3148}
3149
3150static void SvcWrap_MapTransferMemory64(Core::System& system) {
3151 Result ret{};
3152
3153 Handle trmem_handle{};
3154 uint64_t address{};
3155 uint64_t size{};
3156 MemoryPermission owner_perm{};
3157
3158 trmem_handle = Convert<Handle>(GetReg64(system, 0));
3159 address = Convert<uint64_t>(GetReg64(system, 1));
3160 size = Convert<uint64_t>(GetReg64(system, 2));
3161 owner_perm = Convert<MemoryPermission>(GetReg64(system, 3));
3162
3163 ret = MapTransferMemory64(system, trmem_handle, address, size, owner_perm);
3164
3165 SetReg64(system, 0, Convert<uint64_t>(ret));
3166}
3167
3168static void SvcWrap_UnmapTransferMemory64(Core::System& system) {
3169 Result ret{};
3170
3171 Handle trmem_handle{};
3172 uint64_t address{};
3173 uint64_t size{};
3174
3175 trmem_handle = Convert<Handle>(GetReg64(system, 0));
3176 address = Convert<uint64_t>(GetReg64(system, 1));
3177 size = Convert<uint64_t>(GetReg64(system, 2));
3178
3179 ret = UnmapTransferMemory64(system, trmem_handle, address, size);
3180
3181 SetReg64(system, 0, Convert<uint64_t>(ret));
3182}
3183
3184static void SvcWrap_CreateInterruptEvent64(Core::System& system) {
3185 Result ret{};
3186
3187 Handle out_read_handle{};
3188 int32_t interrupt_id{};
3189 InterruptType interrupt_type{};
3190
3191 interrupt_id = Convert<int32_t>(GetReg64(system, 1));
3192 interrupt_type = Convert<InterruptType>(GetReg64(system, 2));
3193
3194 ret = CreateInterruptEvent64(system, &out_read_handle, interrupt_id, interrupt_type);
3195
3196 SetReg64(system, 0, Convert<uint64_t>(ret));
3197 SetReg64(system, 1, Convert<uint64_t>(out_read_handle));
3198}
3199
3200static void SvcWrap_QueryPhysicalAddress64(Core::System& system) {
3201 Result ret{};
3202
3203 lp64::PhysicalMemoryInfo out_info{};
3204 uint64_t address{};
3205
3206 address = Convert<uint64_t>(GetReg64(system, 1));
3207
3208 ret = QueryPhysicalAddress64(system, &out_info, address);
3209
3210 SetReg64(system, 0, Convert<uint64_t>(ret));
3211 auto out_info_scatter = Convert<std::array<uint64_t, 3>>(out_info);
3212 SetReg64(system, 1, out_info_scatter[0]);
3213 SetReg64(system, 2, out_info_scatter[1]);
3214 SetReg64(system, 3, out_info_scatter[2]);
3215}
3216
3217static void SvcWrap_QueryIoMapping64(Core::System& system) {
3218 Result ret{};
3219
3220 uintptr_t out_address{};
3221 uintptr_t out_size{};
3222 uint64_t physical_address{};
3223 uint64_t size{};
3224
3225 physical_address = Convert<uint64_t>(GetReg64(system, 2));
3226 size = Convert<uint64_t>(GetReg64(system, 3));
3227
3228 ret = QueryIoMapping64(system, &out_address, &out_size, physical_address, size);
3229
3230 SetReg64(system, 0, Convert<uint64_t>(ret));
3231 SetReg64(system, 1, Convert<uint64_t>(out_address));
3232 SetReg64(system, 2, Convert<uint64_t>(out_size));
3233}
3234
3235static void SvcWrap_CreateDeviceAddressSpace64(Core::System& system) {
3236 Result ret{};
3237
3238 Handle out_handle{};
3239 uint64_t das_address{};
3240 uint64_t das_size{};
3241
3242 das_address = Convert<uint64_t>(GetReg64(system, 1));
3243 das_size = Convert<uint64_t>(GetReg64(system, 2));
3244
3245 ret = CreateDeviceAddressSpace64(system, &out_handle, das_address, das_size);
3246
3247 SetReg64(system, 0, Convert<uint64_t>(ret));
3248 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3249}
3250
3251static void SvcWrap_AttachDeviceAddressSpace64(Core::System& system) {
3252 Result ret{};
3253
3254 DeviceName device_name{};
3255 Handle das_handle{};
3256
3257 device_name = Convert<DeviceName>(GetReg64(system, 0));
3258 das_handle = Convert<Handle>(GetReg64(system, 1));
3259
3260 ret = AttachDeviceAddressSpace64(system, device_name, das_handle);
3261
3262 SetReg64(system, 0, Convert<uint64_t>(ret));
3263}
3264
3265static void SvcWrap_DetachDeviceAddressSpace64(Core::System& system) {
3266 Result ret{};
3267
3268 DeviceName device_name{};
3269 Handle das_handle{};
3270
3271 device_name = Convert<DeviceName>(GetReg64(system, 0));
3272 das_handle = Convert<Handle>(GetReg64(system, 1));
3273
3274 ret = DetachDeviceAddressSpace64(system, device_name, das_handle);
3275
3276 SetReg64(system, 0, Convert<uint64_t>(ret));
3277}
3278
3279static void SvcWrap_MapDeviceAddressSpaceByForce64(Core::System& system) {
3280 Result ret{};
3281
3282 Handle das_handle{};
3283 Handle process_handle{};
3284 uint64_t process_address{};
3285 uint64_t size{};
3286 uint64_t device_address{};
3287 uint32_t option{};
3288
3289 das_handle = Convert<Handle>(GetReg64(system, 0));
3290 process_handle = Convert<Handle>(GetReg64(system, 1));
3291 process_address = Convert<uint64_t>(GetReg64(system, 2));
3292 size = Convert<uint64_t>(GetReg64(system, 3));
3293 device_address = Convert<uint64_t>(GetReg64(system, 4));
3294 option = Convert<uint32_t>(GetReg64(system, 5));
3295
3296 ret = MapDeviceAddressSpaceByForce64(system, das_handle, process_handle, process_address, size, device_address, option);
3297
3298 SetReg64(system, 0, Convert<uint64_t>(ret));
3299}
3300
3301static void SvcWrap_MapDeviceAddressSpaceAligned64(Core::System& system) {
3302 Result ret{};
3303
3304 Handle das_handle{};
3305 Handle process_handle{};
3306 uint64_t process_address{};
3307 uint64_t size{};
3308 uint64_t device_address{};
3309 uint32_t option{};
3310
3311 das_handle = Convert<Handle>(GetReg64(system, 0));
3312 process_handle = Convert<Handle>(GetReg64(system, 1));
3313 process_address = Convert<uint64_t>(GetReg64(system, 2));
3314 size = Convert<uint64_t>(GetReg64(system, 3));
3315 device_address = Convert<uint64_t>(GetReg64(system, 4));
3316 option = Convert<uint32_t>(GetReg64(system, 5));
3317
3318 ret = MapDeviceAddressSpaceAligned64(system, das_handle, process_handle, process_address, size, device_address, option);
3319
3320 SetReg64(system, 0, Convert<uint64_t>(ret));
3321}
3322
3323static void SvcWrap_UnmapDeviceAddressSpace64(Core::System& system) {
3324 Result ret{};
3325
3326 Handle das_handle{};
3327 Handle process_handle{};
3328 uint64_t process_address{};
3329 uint64_t size{};
3330 uint64_t device_address{};
3331
3332 das_handle = Convert<Handle>(GetReg64(system, 0));
3333 process_handle = Convert<Handle>(GetReg64(system, 1));
3334 process_address = Convert<uint64_t>(GetReg64(system, 2));
3335 size = Convert<uint64_t>(GetReg64(system, 3));
3336 device_address = Convert<uint64_t>(GetReg64(system, 4));
3337
3338 ret = UnmapDeviceAddressSpace64(system, das_handle, process_handle, process_address, size, device_address);
3339
3340 SetReg64(system, 0, Convert<uint64_t>(ret));
3341}
3342
3343static void SvcWrap_InvalidateProcessDataCache64(Core::System& system) {
3344 Result ret{};
3345
3346 Handle process_handle{};
3347 uint64_t address{};
3348 uint64_t size{};
3349
3350 process_handle = Convert<Handle>(GetReg64(system, 0));
3351 address = Convert<uint64_t>(GetReg64(system, 1));
3352 size = Convert<uint64_t>(GetReg64(system, 2));
3353
3354 ret = InvalidateProcessDataCache64(system, process_handle, address, size);
3355
3356 SetReg64(system, 0, Convert<uint64_t>(ret));
3357}
3358
3359static void SvcWrap_StoreProcessDataCache64(Core::System& system) {
3360 Result ret{};
3361
3362 Handle process_handle{};
3363 uint64_t address{};
3364 uint64_t size{};
3365
3366 process_handle = Convert<Handle>(GetReg64(system, 0));
3367 address = Convert<uint64_t>(GetReg64(system, 1));
3368 size = Convert<uint64_t>(GetReg64(system, 2));
3369
3370 ret = StoreProcessDataCache64(system, process_handle, address, size);
3371
3372 SetReg64(system, 0, Convert<uint64_t>(ret));
3373}
3374
3375static void SvcWrap_FlushProcessDataCache64(Core::System& system) {
3376 Result ret{};
3377
3378 Handle process_handle{};
3379 uint64_t address{};
3380 uint64_t size{};
3381
3382 process_handle = Convert<Handle>(GetReg64(system, 0));
3383 address = Convert<uint64_t>(GetReg64(system, 1));
3384 size = Convert<uint64_t>(GetReg64(system, 2));
3385
3386 ret = FlushProcessDataCache64(system, process_handle, address, size);
3387
3388 SetReg64(system, 0, Convert<uint64_t>(ret));
3389}
3390
3391static void SvcWrap_DebugActiveProcess64(Core::System& system) {
3392 Result ret{};
3393
3394 Handle out_handle{};
3395 uint64_t process_id{};
3396
3397 process_id = Convert<uint64_t>(GetReg64(system, 1));
3398
3399 ret = DebugActiveProcess64(system, &out_handle, process_id);
3400
3401 SetReg64(system, 0, Convert<uint64_t>(ret));
3402 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3403}
3404
3405static void SvcWrap_BreakDebugProcess64(Core::System& system) {
3406 Result ret{};
3407
3408 Handle debug_handle{};
3409
3410 debug_handle = Convert<Handle>(GetReg64(system, 0));
3411
3412 ret = BreakDebugProcess64(system, debug_handle);
3413
3414 SetReg64(system, 0, Convert<uint64_t>(ret));
3415}
3416
3417static void SvcWrap_TerminateDebugProcess64(Core::System& system) {
3418 Result ret{};
3419
3420 Handle debug_handle{};
3421
3422 debug_handle = Convert<Handle>(GetReg64(system, 0));
3423
3424 ret = TerminateDebugProcess64(system, debug_handle);
3425
3426 SetReg64(system, 0, Convert<uint64_t>(ret));
3427}
3428
3429static void SvcWrap_GetDebugEvent64(Core::System& system) {
3430 Result ret{};
3431
3432 uint64_t out_info{};
3433 Handle debug_handle{};
3434
3435 out_info = Convert<uint64_t>(GetReg64(system, 0));
3436 debug_handle = Convert<Handle>(GetReg64(system, 1));
3437
3438 ret = GetDebugEvent64(system, out_info, debug_handle);
3439
3440 SetReg64(system, 0, Convert<uint64_t>(ret));
3441}
3442
3443static void SvcWrap_ContinueDebugEvent64(Core::System& system) {
3444 Result ret{};
3445
3446 Handle debug_handle{};
3447 uint32_t flags{};
3448 uint64_t thread_ids{};
3449 int32_t num_thread_ids{};
3450
3451 debug_handle = Convert<Handle>(GetReg64(system, 0));
3452 flags = Convert<uint32_t>(GetReg64(system, 1));
3453 thread_ids = Convert<uint64_t>(GetReg64(system, 2));
3454 num_thread_ids = Convert<int32_t>(GetReg64(system, 3));
3455
3456 ret = ContinueDebugEvent64(system, debug_handle, flags, thread_ids, num_thread_ids);
3457
3458 SetReg64(system, 0, Convert<uint64_t>(ret));
3459}
3460
3461static void SvcWrap_GetProcessList64(Core::System& system) {
3462 Result ret{};
3463
3464 int32_t out_num_processes{};
3465 uint64_t out_process_ids{};
3466 int32_t max_out_count{};
3467
3468 out_process_ids = Convert<uint64_t>(GetReg64(system, 1));
3469 max_out_count = Convert<int32_t>(GetReg64(system, 2));
3470
3471 ret = GetProcessList64(system, &out_num_processes, out_process_ids, max_out_count);
3472
3473 SetReg64(system, 0, Convert<uint64_t>(ret));
3474 SetReg64(system, 1, Convert<uint64_t>(out_num_processes));
3475}
3476
3477static void SvcWrap_GetThreadList64(Core::System& system) {
3478 Result ret{};
3479
3480 int32_t out_num_threads{};
3481 uint64_t out_thread_ids{};
3482 int32_t max_out_count{};
3483 Handle debug_handle{};
3484
3485 out_thread_ids = Convert<uint64_t>(GetReg64(system, 1));
3486 max_out_count = Convert<int32_t>(GetReg64(system, 2));
3487 debug_handle = Convert<Handle>(GetReg64(system, 3));
3488
3489 ret = GetThreadList64(system, &out_num_threads, out_thread_ids, max_out_count, debug_handle);
3490
3491 SetReg64(system, 0, Convert<uint64_t>(ret));
3492 SetReg64(system, 1, Convert<uint64_t>(out_num_threads));
3493}
3494
3495static void SvcWrap_GetDebugThreadContext64(Core::System& system) {
3496 Result ret{};
3497
3498 uint64_t out_context{};
3499 Handle debug_handle{};
3500 uint64_t thread_id{};
3501 uint32_t context_flags{};
3502
3503 out_context = Convert<uint64_t>(GetReg64(system, 0));
3504 debug_handle = Convert<Handle>(GetReg64(system, 1));
3505 thread_id = Convert<uint64_t>(GetReg64(system, 2));
3506 context_flags = Convert<uint32_t>(GetReg64(system, 3));
3507
3508 ret = GetDebugThreadContext64(system, out_context, debug_handle, thread_id, context_flags);
3509
3510 SetReg64(system, 0, Convert<uint64_t>(ret));
3511}
3512
3513static void SvcWrap_SetDebugThreadContext64(Core::System& system) {
3514 Result ret{};
3515
3516 Handle debug_handle{};
3517 uint64_t thread_id{};
3518 uint64_t context{};
3519 uint32_t context_flags{};
3520
3521 debug_handle = Convert<Handle>(GetReg64(system, 0));
3522 thread_id = Convert<uint64_t>(GetReg64(system, 1));
3523 context = Convert<uint64_t>(GetReg64(system, 2));
3524 context_flags = Convert<uint32_t>(GetReg64(system, 3));
3525
3526 ret = SetDebugThreadContext64(system, debug_handle, thread_id, context, context_flags);
3527
3528 SetReg64(system, 0, Convert<uint64_t>(ret));
3529}
3530
3531static void SvcWrap_QueryDebugProcessMemory64(Core::System& system) {
3532 Result ret{};
3533
3534 PageInfo out_page_info{};
3535 uint64_t out_memory_info{};
3536 Handle process_handle{};
3537 uint64_t address{};
3538
3539 out_memory_info = Convert<uint64_t>(GetReg64(system, 0));
3540 process_handle = Convert<Handle>(GetReg64(system, 2));
3541 address = Convert<uint64_t>(GetReg64(system, 3));
3542
3543 ret = QueryDebugProcessMemory64(system, out_memory_info, &out_page_info, process_handle, address);
3544
3545 SetReg64(system, 0, Convert<uint64_t>(ret));
3546 SetReg64(system, 1, Convert<uint64_t>(out_page_info));
3547}
3548
3549static void SvcWrap_ReadDebugProcessMemory64(Core::System& system) {
3550 Result ret{};
3551
3552 uint64_t buffer{};
3553 Handle debug_handle{};
3554 uint64_t address{};
3555 uint64_t size{};
3556
3557 buffer = Convert<uint64_t>(GetReg64(system, 0));
3558 debug_handle = Convert<Handle>(GetReg64(system, 1));
3559 address = Convert<uint64_t>(GetReg64(system, 2));
3560 size = Convert<uint64_t>(GetReg64(system, 3));
3561
3562 ret = ReadDebugProcessMemory64(system, buffer, debug_handle, address, size);
3563
3564 SetReg64(system, 0, Convert<uint64_t>(ret));
3565}
3566
3567static void SvcWrap_WriteDebugProcessMemory64(Core::System& system) {
3568 Result ret{};
3569
3570 Handle debug_handle{};
3571 uint64_t buffer{};
3572 uint64_t address{};
3573 uint64_t size{};
3574
3575 debug_handle = Convert<Handle>(GetReg64(system, 0));
3576 buffer = Convert<uint64_t>(GetReg64(system, 1));
3577 address = Convert<uint64_t>(GetReg64(system, 2));
3578 size = Convert<uint64_t>(GetReg64(system, 3));
3579
3580 ret = WriteDebugProcessMemory64(system, debug_handle, buffer, address, size);
3581
3582 SetReg64(system, 0, Convert<uint64_t>(ret));
3583}
3584
3585static void SvcWrap_SetHardwareBreakPoint64(Core::System& system) {
3586 Result ret{};
3587
3588 HardwareBreakPointRegisterName name{};
3589 uint64_t flags{};
3590 uint64_t value{};
3591
3592 name = Convert<HardwareBreakPointRegisterName>(GetReg64(system, 0));
3593 flags = Convert<uint64_t>(GetReg64(system, 1));
3594 value = Convert<uint64_t>(GetReg64(system, 2));
3595
3596 ret = SetHardwareBreakPoint64(system, name, flags, value);
3597
3598 SetReg64(system, 0, Convert<uint64_t>(ret));
3599}
3600
3601static void SvcWrap_GetDebugThreadParam64(Core::System& system) {
3602 Result ret{};
3603
3604 uint64_t out_64{};
3605 uint32_t out_32{};
3606 Handle debug_handle{};
3607 uint64_t thread_id{};
3608 DebugThreadParam param{};
3609
3610 debug_handle = Convert<Handle>(GetReg64(system, 2));
3611 thread_id = Convert<uint64_t>(GetReg64(system, 3));
3612 param = Convert<DebugThreadParam>(GetReg64(system, 4));
3613
3614 ret = GetDebugThreadParam64(system, &out_64, &out_32, debug_handle, thread_id, param);
3615
3616 SetReg64(system, 0, Convert<uint64_t>(ret));
3617 SetReg64(system, 1, Convert<uint64_t>(out_64));
3618 SetReg64(system, 2, Convert<uint64_t>(out_32));
3619}
3620
3621static void SvcWrap_GetSystemInfo64(Core::System& system) {
3622 Result ret{};
3623
3624 uint64_t out{};
3625 SystemInfoType info_type{};
3626 Handle handle{};
3627 uint64_t info_subtype{};
3628
3629 info_type = Convert<SystemInfoType>(GetReg64(system, 1));
3630 handle = Convert<Handle>(GetReg64(system, 2));
3631 info_subtype = Convert<uint64_t>(GetReg64(system, 3));
3632
3633 ret = GetSystemInfo64(system, &out, info_type, handle, info_subtype);
3634
3635 SetReg64(system, 0, Convert<uint64_t>(ret));
3636 SetReg64(system, 1, Convert<uint64_t>(out));
3637}
3638
3639static void SvcWrap_CreatePort64(Core::System& system) {
3640 Result ret{};
3641
3642 Handle out_server_handle{};
3643 Handle out_client_handle{};
3644 int32_t max_sessions{};
3645 bool is_light{};
3646 uint64_t name{};
3647
3648 max_sessions = Convert<int32_t>(GetReg64(system, 2));
3649 is_light = Convert<bool>(GetReg64(system, 3));
3650 name = Convert<uint64_t>(GetReg64(system, 4));
3651
3652 ret = CreatePort64(system, &out_server_handle, &out_client_handle, max_sessions, is_light, name);
3653
3654 SetReg64(system, 0, Convert<uint64_t>(ret));
3655 SetReg64(system, 1, Convert<uint64_t>(out_server_handle));
3656 SetReg64(system, 2, Convert<uint64_t>(out_client_handle));
3657}
3658
3659static void SvcWrap_ManageNamedPort64(Core::System& system) {
3660 Result ret{};
3661
3662 Handle out_server_handle{};
3663 uint64_t name{};
3664 int32_t max_sessions{};
3665
3666 name = Convert<uint64_t>(GetReg64(system, 1));
3667 max_sessions = Convert<int32_t>(GetReg64(system, 2));
3668
3669 ret = ManageNamedPort64(system, &out_server_handle, name, max_sessions);
3670
3671 SetReg64(system, 0, Convert<uint64_t>(ret));
3672 SetReg64(system, 1, Convert<uint64_t>(out_server_handle));
3673}
3674
3675static void SvcWrap_ConnectToPort64(Core::System& system) {
3676 Result ret{};
3677
3678 Handle out_handle{};
3679 Handle port{};
3680
3681 port = Convert<Handle>(GetReg64(system, 1));
3682
3683 ret = ConnectToPort64(system, &out_handle, port);
3684
3685 SetReg64(system, 0, Convert<uint64_t>(ret));
3686 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3687}
3688
3689static void SvcWrap_SetProcessMemoryPermission64(Core::System& system) {
3690 Result ret{};
3691
3692 Handle process_handle{};
3693 uint64_t address{};
3694 uint64_t size{};
3695 MemoryPermission perm{};
3696
3697 process_handle = Convert<Handle>(GetReg64(system, 0));
3698 address = Convert<uint64_t>(GetReg64(system, 1));
3699 size = Convert<uint64_t>(GetReg64(system, 2));
3700 perm = Convert<MemoryPermission>(GetReg64(system, 3));
3701
3702 ret = SetProcessMemoryPermission64(system, process_handle, address, size, perm);
3703
3704 SetReg64(system, 0, Convert<uint64_t>(ret));
3705}
3706
3707static void SvcWrap_MapProcessMemory64(Core::System& system) {
3708 Result ret{};
3709
3710 uint64_t dst_address{};
3711 Handle process_handle{};
3712 uint64_t src_address{};
3713 uint64_t size{};
3714
3715 dst_address = Convert<uint64_t>(GetReg64(system, 0));
3716 process_handle = Convert<Handle>(GetReg64(system, 1));
3717 src_address = Convert<uint64_t>(GetReg64(system, 2));
3718 size = Convert<uint64_t>(GetReg64(system, 3));
3719
3720 ret = MapProcessMemory64(system, dst_address, process_handle, src_address, size);
3721
3722 SetReg64(system, 0, Convert<uint64_t>(ret));
3723}
3724
3725static void SvcWrap_UnmapProcessMemory64(Core::System& system) {
3726 Result ret{};
3727
3728 uint64_t dst_address{};
3729 Handle process_handle{};
3730 uint64_t src_address{};
3731 uint64_t size{};
3732
3733 dst_address = Convert<uint64_t>(GetReg64(system, 0));
3734 process_handle = Convert<Handle>(GetReg64(system, 1));
3735 src_address = Convert<uint64_t>(GetReg64(system, 2));
3736 size = Convert<uint64_t>(GetReg64(system, 3));
3737
3738 ret = UnmapProcessMemory64(system, dst_address, process_handle, src_address, size);
3739
3740 SetReg64(system, 0, Convert<uint64_t>(ret));
3741}
3742
3743static void SvcWrap_QueryProcessMemory64(Core::System& system) {
3744 Result ret{};
3745
3746 PageInfo out_page_info{};
3747 uint64_t out_memory_info{};
3748 Handle process_handle{};
3749 uint64_t address{};
3750
3751 out_memory_info = Convert<uint64_t>(GetReg64(system, 0));
3752 process_handle = Convert<Handle>(GetReg64(system, 2));
3753 address = Convert<uint64_t>(GetReg64(system, 3));
3754
3755 ret = QueryProcessMemory64(system, out_memory_info, &out_page_info, process_handle, address);
3756
3757 SetReg64(system, 0, Convert<uint64_t>(ret));
3758 SetReg64(system, 1, Convert<uint64_t>(out_page_info));
3759}
3760
3761static void SvcWrap_MapProcessCodeMemory64(Core::System& system) {
3762 Result ret{};
3763
3764 Handle process_handle{};
3765 uint64_t dst_address{};
3766 uint64_t src_address{};
3767 uint64_t size{};
3768
3769 process_handle = Convert<Handle>(GetReg64(system, 0));
3770 dst_address = Convert<uint64_t>(GetReg64(system, 1));
3771 src_address = Convert<uint64_t>(GetReg64(system, 2));
3772 size = Convert<uint64_t>(GetReg64(system, 3));
3773
3774 ret = MapProcessCodeMemory64(system, process_handle, dst_address, src_address, size);
3775
3776 SetReg64(system, 0, Convert<uint64_t>(ret));
3777}
3778
3779static void SvcWrap_UnmapProcessCodeMemory64(Core::System& system) {
3780 Result ret{};
3781
3782 Handle process_handle{};
3783 uint64_t dst_address{};
3784 uint64_t src_address{};
3785 uint64_t size{};
3786
3787 process_handle = Convert<Handle>(GetReg64(system, 0));
3788 dst_address = Convert<uint64_t>(GetReg64(system, 1));
3789 src_address = Convert<uint64_t>(GetReg64(system, 2));
3790 size = Convert<uint64_t>(GetReg64(system, 3));
3791
3792 ret = UnmapProcessCodeMemory64(system, process_handle, dst_address, src_address, size);
3793
3794 SetReg64(system, 0, Convert<uint64_t>(ret));
3795}
3796
3797static void SvcWrap_CreateProcess64(Core::System& system) {
3798 Result ret{};
3799
3800 Handle out_handle{};
3801 uint64_t parameters{};
3802 uint64_t caps{};
3803 int32_t num_caps{};
3804
3805 parameters = Convert<uint64_t>(GetReg64(system, 1));
3806 caps = Convert<uint64_t>(GetReg64(system, 2));
3807 num_caps = Convert<int32_t>(GetReg64(system, 3));
3808
3809 ret = CreateProcess64(system, &out_handle, parameters, caps, num_caps);
3810
3811 SetReg64(system, 0, Convert<uint64_t>(ret));
3812 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3813}
3814
3815static void SvcWrap_StartProcess64(Core::System& system) {
3816 Result ret{};
3817
3818 Handle process_handle{};
3819 int32_t priority{};
3820 int32_t core_id{};
3821 uint64_t main_thread_stack_size{};
3822
3823 process_handle = Convert<Handle>(GetReg64(system, 0));
3824 priority = Convert<int32_t>(GetReg64(system, 1));
3825 core_id = Convert<int32_t>(GetReg64(system, 2));
3826 main_thread_stack_size = Convert<uint64_t>(GetReg64(system, 3));
3827
3828 ret = StartProcess64(system, process_handle, priority, core_id, main_thread_stack_size);
3829
3830 SetReg64(system, 0, Convert<uint64_t>(ret));
3831}
3832
3833static void SvcWrap_TerminateProcess64(Core::System& system) {
3834 Result ret{};
3835
3836 Handle process_handle{};
3837
3838 process_handle = Convert<Handle>(GetReg64(system, 0));
3839
3840 ret = TerminateProcess64(system, process_handle);
3841
3842 SetReg64(system, 0, Convert<uint64_t>(ret));
3843}
3844
3845static void SvcWrap_GetProcessInfo64(Core::System& system) {
3846 Result ret{};
3847
3848 int64_t out_info{};
3849 Handle process_handle{};
3850 ProcessInfoType info_type{};
3851
3852 process_handle = Convert<Handle>(GetReg64(system, 1));
3853 info_type = Convert<ProcessInfoType>(GetReg64(system, 2));
3854
3855 ret = GetProcessInfo64(system, &out_info, process_handle, info_type);
3856
3857 SetReg64(system, 0, Convert<uint64_t>(ret));
3858 SetReg64(system, 1, Convert<uint64_t>(out_info));
3859}
3860
3861static void SvcWrap_CreateResourceLimit64(Core::System& system) {
3862 Result ret{};
3863
3864 Handle out_handle{};
3865
3866 ret = CreateResourceLimit64(system, &out_handle);
3867
3868 SetReg64(system, 0, Convert<uint64_t>(ret));
3869 SetReg64(system, 1, Convert<uint64_t>(out_handle));
3870}
3871
3872static void SvcWrap_SetResourceLimitLimitValue64(Core::System& system) {
3873 Result ret{};
3874
3875 Handle resource_limit_handle{};
3876 LimitableResource which{};
3877 int64_t limit_value{};
3878
3879 resource_limit_handle = Convert<Handle>(GetReg64(system, 0));
3880 which = Convert<LimitableResource>(GetReg64(system, 1));
3881 limit_value = Convert<int64_t>(GetReg64(system, 2));
3882
3883 ret = SetResourceLimitLimitValue64(system, resource_limit_handle, which, limit_value);
3884
3885 SetReg64(system, 0, Convert<uint64_t>(ret));
3886}
3887
3888static void SvcWrap_MapInsecureMemory64(Core::System& system) {
3889 Result ret{};
3890
3891 uint64_t address{};
3892 uint64_t size{};
3893
3894 address = Convert<uint64_t>(GetReg64(system, 0));
3895 size = Convert<uint64_t>(GetReg64(system, 1));
3896
3897 ret = MapInsecureMemory64(system, address, size);
3898
3899 SetReg64(system, 0, Convert<uint64_t>(ret));
3900}
3901
3902static void SvcWrap_UnmapInsecureMemory64(Core::System& system) {
3903 Result ret{};
3904
3905 uint64_t address{};
3906 uint64_t size{};
3907
3908 address = Convert<uint64_t>(GetReg64(system, 0));
3909 size = Convert<uint64_t>(GetReg64(system, 1));
3910
3911 ret = UnmapInsecureMemory64(system, address, size);
3912
3913 SetReg64(system, 0, Convert<uint64_t>(ret));
3914}
3915
3916static void Call32(Core::System& system, u32 imm) {
3917 switch (static_cast<SvcId>(imm)) {
3918 case SvcId::SetHeapSize:
3919 return SvcWrap_SetHeapSize64From32(system);
3920 case SvcId::SetMemoryPermission:
3921 return SvcWrap_SetMemoryPermission64From32(system);
3922 case SvcId::SetMemoryAttribute:
3923 return SvcWrap_SetMemoryAttribute64From32(system);
3924 case SvcId::MapMemory:
3925 return SvcWrap_MapMemory64From32(system);
3926 case SvcId::UnmapMemory:
3927 return SvcWrap_UnmapMemory64From32(system);
3928 case SvcId::QueryMemory:
3929 return SvcWrap_QueryMemory64From32(system);
3930 case SvcId::ExitProcess:
3931 return SvcWrap_ExitProcess64From32(system);
3932 case SvcId::CreateThread:
3933 return SvcWrap_CreateThread64From32(system);
3934 case SvcId::StartThread:
3935 return SvcWrap_StartThread64From32(system);
3936 case SvcId::ExitThread:
3937 return SvcWrap_ExitThread64From32(system);
3938 case SvcId::SleepThread:
3939 return SvcWrap_SleepThread64From32(system);
3940 case SvcId::GetThreadPriority:
3941 return SvcWrap_GetThreadPriority64From32(system);
3942 case SvcId::SetThreadPriority:
3943 return SvcWrap_SetThreadPriority64From32(system);
3944 case SvcId::GetThreadCoreMask:
3945 return SvcWrap_GetThreadCoreMask64From32(system);
3946 case SvcId::SetThreadCoreMask:
3947 return SvcWrap_SetThreadCoreMask64From32(system);
3948 case SvcId::GetCurrentProcessorNumber:
3949 return SvcWrap_GetCurrentProcessorNumber64From32(system);
3950 case SvcId::SignalEvent:
3951 return SvcWrap_SignalEvent64From32(system);
3952 case SvcId::ClearEvent:
3953 return SvcWrap_ClearEvent64From32(system);
3954 case SvcId::MapSharedMemory:
3955 return SvcWrap_MapSharedMemory64From32(system);
3956 case SvcId::UnmapSharedMemory:
3957 return SvcWrap_UnmapSharedMemory64From32(system);
3958 case SvcId::CreateTransferMemory:
3959 return SvcWrap_CreateTransferMemory64From32(system);
3960 case SvcId::CloseHandle:
3961 return SvcWrap_CloseHandle64From32(system);
3962 case SvcId::ResetSignal:
3963 return SvcWrap_ResetSignal64From32(system);
3964 case SvcId::WaitSynchronization:
3965 return SvcWrap_WaitSynchronization64From32(system);
3966 case SvcId::CancelSynchronization:
3967 return SvcWrap_CancelSynchronization64From32(system);
3968 case SvcId::ArbitrateLock:
3969 return SvcWrap_ArbitrateLock64From32(system);
3970 case SvcId::ArbitrateUnlock:
3971 return SvcWrap_ArbitrateUnlock64From32(system);
3972 case SvcId::WaitProcessWideKeyAtomic:
3973 return SvcWrap_WaitProcessWideKeyAtomic64From32(system);
3974 case SvcId::SignalProcessWideKey:
3975 return SvcWrap_SignalProcessWideKey64From32(system);
3976 case SvcId::GetSystemTick:
3977 return SvcWrap_GetSystemTick64From32(system);
3978 case SvcId::ConnectToNamedPort:
3979 return SvcWrap_ConnectToNamedPort64From32(system);
3980 case SvcId::SendSyncRequestLight:
3981 return SvcWrap_SendSyncRequestLight64From32(system);
3982 case SvcId::SendSyncRequest:
3983 return SvcWrap_SendSyncRequest64From32(system);
3984 case SvcId::SendSyncRequestWithUserBuffer:
3985 return SvcWrap_SendSyncRequestWithUserBuffer64From32(system);
3986 case SvcId::SendAsyncRequestWithUserBuffer:
3987 return SvcWrap_SendAsyncRequestWithUserBuffer64From32(system);
3988 case SvcId::GetProcessId:
3989 return SvcWrap_GetProcessId64From32(system);
3990 case SvcId::GetThreadId:
3991 return SvcWrap_GetThreadId64From32(system);
3992 case SvcId::Break:
3993 return SvcWrap_Break64From32(system);
3994 case SvcId::OutputDebugString:
3995 return SvcWrap_OutputDebugString64From32(system);
3996 case SvcId::ReturnFromException:
3997 return SvcWrap_ReturnFromException64From32(system);
3998 case SvcId::GetInfo:
3999 return SvcWrap_GetInfo64From32(system);
4000 case SvcId::FlushEntireDataCache:
4001 return SvcWrap_FlushEntireDataCache64From32(system);
4002 case SvcId::FlushDataCache:
4003 return SvcWrap_FlushDataCache64From32(system);
4004 case SvcId::MapPhysicalMemory:
4005 return SvcWrap_MapPhysicalMemory64From32(system);
4006 case SvcId::UnmapPhysicalMemory:
4007 return SvcWrap_UnmapPhysicalMemory64From32(system);
4008 case SvcId::GetDebugFutureThreadInfo:
4009 return SvcWrap_GetDebugFutureThreadInfo64From32(system);
4010 case SvcId::GetLastThreadInfo:
4011 return SvcWrap_GetLastThreadInfo64From32(system);
4012 case SvcId::GetResourceLimitLimitValue:
4013 return SvcWrap_GetResourceLimitLimitValue64From32(system);
4014 case SvcId::GetResourceLimitCurrentValue:
4015 return SvcWrap_GetResourceLimitCurrentValue64From32(system);
4016 case SvcId::SetThreadActivity:
4017 return SvcWrap_SetThreadActivity64From32(system);
4018 case SvcId::GetThreadContext3:
4019 return SvcWrap_GetThreadContext364From32(system);
4020 case SvcId::WaitForAddress:
4021 return SvcWrap_WaitForAddress64From32(system);
4022 case SvcId::SignalToAddress:
4023 return SvcWrap_SignalToAddress64From32(system);
4024 case SvcId::SynchronizePreemptionState:
4025 return SvcWrap_SynchronizePreemptionState64From32(system);
4026 case SvcId::GetResourceLimitPeakValue:
4027 return SvcWrap_GetResourceLimitPeakValue64From32(system);
4028 case SvcId::CreateIoPool:
4029 return SvcWrap_CreateIoPool64From32(system);
4030 case SvcId::CreateIoRegion:
4031 return SvcWrap_CreateIoRegion64From32(system);
4032 case SvcId::KernelDebug:
4033 return SvcWrap_KernelDebug64From32(system);
4034 case SvcId::ChangeKernelTraceState:
4035 return SvcWrap_ChangeKernelTraceState64From32(system);
4036 case SvcId::CreateSession:
4037 return SvcWrap_CreateSession64From32(system);
4038 case SvcId::AcceptSession:
4039 return SvcWrap_AcceptSession64From32(system);
4040 case SvcId::ReplyAndReceiveLight:
4041 return SvcWrap_ReplyAndReceiveLight64From32(system);
4042 case SvcId::ReplyAndReceive:
4043 return SvcWrap_ReplyAndReceive64From32(system);
4044 case SvcId::ReplyAndReceiveWithUserBuffer:
4045 return SvcWrap_ReplyAndReceiveWithUserBuffer64From32(system);
4046 case SvcId::CreateEvent:
4047 return SvcWrap_CreateEvent64From32(system);
4048 case SvcId::MapIoRegion:
4049 return SvcWrap_MapIoRegion64From32(system);
4050 case SvcId::UnmapIoRegion:
4051 return SvcWrap_UnmapIoRegion64From32(system);
4052 case SvcId::MapPhysicalMemoryUnsafe:
4053 return SvcWrap_MapPhysicalMemoryUnsafe64From32(system);
4054 case SvcId::UnmapPhysicalMemoryUnsafe:
4055 return SvcWrap_UnmapPhysicalMemoryUnsafe64From32(system);
4056 case SvcId::SetUnsafeLimit:
4057 return SvcWrap_SetUnsafeLimit64From32(system);
4058 case SvcId::CreateCodeMemory:
4059 return SvcWrap_CreateCodeMemory64From32(system);
4060 case SvcId::ControlCodeMemory:
4061 return SvcWrap_ControlCodeMemory64From32(system);
4062 case SvcId::SleepSystem:
4063 return SvcWrap_SleepSystem64From32(system);
4064 case SvcId::ReadWriteRegister:
4065 return SvcWrap_ReadWriteRegister64From32(system);
4066 case SvcId::SetProcessActivity:
4067 return SvcWrap_SetProcessActivity64From32(system);
4068 case SvcId::CreateSharedMemory:
4069 return SvcWrap_CreateSharedMemory64From32(system);
4070 case SvcId::MapTransferMemory:
4071 return SvcWrap_MapTransferMemory64From32(system);
4072 case SvcId::UnmapTransferMemory:
4073 return SvcWrap_UnmapTransferMemory64From32(system);
4074 case SvcId::CreateInterruptEvent:
4075 return SvcWrap_CreateInterruptEvent64From32(system);
4076 case SvcId::QueryPhysicalAddress:
4077 return SvcWrap_QueryPhysicalAddress64From32(system);
4078 case SvcId::QueryIoMapping:
4079 return SvcWrap_QueryIoMapping64From32(system);
4080 case SvcId::CreateDeviceAddressSpace:
4081 return SvcWrap_CreateDeviceAddressSpace64From32(system);
4082 case SvcId::AttachDeviceAddressSpace:
4083 return SvcWrap_AttachDeviceAddressSpace64From32(system);
4084 case SvcId::DetachDeviceAddressSpace:
4085 return SvcWrap_DetachDeviceAddressSpace64From32(system);
4086 case SvcId::MapDeviceAddressSpaceByForce:
4087 return SvcWrap_MapDeviceAddressSpaceByForce64From32(system);
4088 case SvcId::MapDeviceAddressSpaceAligned:
4089 return SvcWrap_MapDeviceAddressSpaceAligned64From32(system);
4090 case SvcId::UnmapDeviceAddressSpace:
4091 return SvcWrap_UnmapDeviceAddressSpace64From32(system);
4092 case SvcId::InvalidateProcessDataCache:
4093 return SvcWrap_InvalidateProcessDataCache64From32(system);
4094 case SvcId::StoreProcessDataCache:
4095 return SvcWrap_StoreProcessDataCache64From32(system);
4096 case SvcId::FlushProcessDataCache:
4097 return SvcWrap_FlushProcessDataCache64From32(system);
4098 case SvcId::DebugActiveProcess:
4099 return SvcWrap_DebugActiveProcess64From32(system);
4100 case SvcId::BreakDebugProcess:
4101 return SvcWrap_BreakDebugProcess64From32(system);
4102 case SvcId::TerminateDebugProcess:
4103 return SvcWrap_TerminateDebugProcess64From32(system);
4104 case SvcId::GetDebugEvent:
4105 return SvcWrap_GetDebugEvent64From32(system);
4106 case SvcId::ContinueDebugEvent:
4107 return SvcWrap_ContinueDebugEvent64From32(system);
4108 case SvcId::GetProcessList:
4109 return SvcWrap_GetProcessList64From32(system);
4110 case SvcId::GetThreadList:
4111 return SvcWrap_GetThreadList64From32(system);
4112 case SvcId::GetDebugThreadContext:
4113 return SvcWrap_GetDebugThreadContext64From32(system);
4114 case SvcId::SetDebugThreadContext:
4115 return SvcWrap_SetDebugThreadContext64From32(system);
4116 case SvcId::QueryDebugProcessMemory:
4117 return SvcWrap_QueryDebugProcessMemory64From32(system);
4118 case SvcId::ReadDebugProcessMemory:
4119 return SvcWrap_ReadDebugProcessMemory64From32(system);
4120 case SvcId::WriteDebugProcessMemory:
4121 return SvcWrap_WriteDebugProcessMemory64From32(system);
4122 case SvcId::SetHardwareBreakPoint:
4123 return SvcWrap_SetHardwareBreakPoint64From32(system);
4124 case SvcId::GetDebugThreadParam:
4125 return SvcWrap_GetDebugThreadParam64From32(system);
4126 case SvcId::GetSystemInfo:
4127 return SvcWrap_GetSystemInfo64From32(system);
4128 case SvcId::CreatePort:
4129 return SvcWrap_CreatePort64From32(system);
4130 case SvcId::ManageNamedPort:
4131 return SvcWrap_ManageNamedPort64From32(system);
4132 case SvcId::ConnectToPort:
4133 return SvcWrap_ConnectToPort64From32(system);
4134 case SvcId::SetProcessMemoryPermission:
4135 return SvcWrap_SetProcessMemoryPermission64From32(system);
4136 case SvcId::MapProcessMemory:
4137 return SvcWrap_MapProcessMemory64From32(system);
4138 case SvcId::UnmapProcessMemory:
4139 return SvcWrap_UnmapProcessMemory64From32(system);
4140 case SvcId::QueryProcessMemory:
4141 return SvcWrap_QueryProcessMemory64From32(system);
4142 case SvcId::MapProcessCodeMemory:
4143 return SvcWrap_MapProcessCodeMemory64From32(system);
4144 case SvcId::UnmapProcessCodeMemory:
4145 return SvcWrap_UnmapProcessCodeMemory64From32(system);
4146 case SvcId::CreateProcess:
4147 return SvcWrap_CreateProcess64From32(system);
4148 case SvcId::StartProcess:
4149 return SvcWrap_StartProcess64From32(system);
4150 case SvcId::TerminateProcess:
4151 return SvcWrap_TerminateProcess64From32(system);
4152 case SvcId::GetProcessInfo:
4153 return SvcWrap_GetProcessInfo64From32(system);
4154 case SvcId::CreateResourceLimit:
4155 return SvcWrap_CreateResourceLimit64From32(system);
4156 case SvcId::SetResourceLimitLimitValue:
4157 return SvcWrap_SetResourceLimitLimitValue64From32(system);
4158 case SvcId::CallSecureMonitor:
4159 return SvcWrap_CallSecureMonitor64From32(system);
4160 case SvcId::MapInsecureMemory:
4161 return SvcWrap_MapInsecureMemory64From32(system);
4162 case SvcId::UnmapInsecureMemory:
4163 return SvcWrap_UnmapInsecureMemory64From32(system);
4164 default:
4165 LOG_CRITICAL(Kernel_SVC, "Unknown SVC {:x}!", imm);
4166 break;
418 } 4167 }
419 return &SVC_Table_32[func_num];
420} 4168}
421 4169
422static const FunctionDef* GetSVCInfo64(u32 func_num) { 4170static void Call64(Core::System& system, u32 imm) {
423 if (func_num >= std::size(SVC_Table_64)) { 4171 switch (static_cast<SvcId>(imm)) {
424 LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); 4172 case SvcId::SetHeapSize:
425 return nullptr; 4173 return SvcWrap_SetHeapSize64(system);
4174 case SvcId::SetMemoryPermission:
4175 return SvcWrap_SetMemoryPermission64(system);
4176 case SvcId::SetMemoryAttribute:
4177 return SvcWrap_SetMemoryAttribute64(system);
4178 case SvcId::MapMemory:
4179 return SvcWrap_MapMemory64(system);
4180 case SvcId::UnmapMemory:
4181 return SvcWrap_UnmapMemory64(system);
4182 case SvcId::QueryMemory:
4183 return SvcWrap_QueryMemory64(system);
4184 case SvcId::ExitProcess:
4185 return SvcWrap_ExitProcess64(system);
4186 case SvcId::CreateThread:
4187 return SvcWrap_CreateThread64(system);
4188 case SvcId::StartThread:
4189 return SvcWrap_StartThread64(system);
4190 case SvcId::ExitThread:
4191 return SvcWrap_ExitThread64(system);
4192 case SvcId::SleepThread:
4193 return SvcWrap_SleepThread64(system);
4194 case SvcId::GetThreadPriority:
4195 return SvcWrap_GetThreadPriority64(system);
4196 case SvcId::SetThreadPriority:
4197 return SvcWrap_SetThreadPriority64(system);
4198 case SvcId::GetThreadCoreMask:
4199 return SvcWrap_GetThreadCoreMask64(system);
4200 case SvcId::SetThreadCoreMask:
4201 return SvcWrap_SetThreadCoreMask64(system);
4202 case SvcId::GetCurrentProcessorNumber:
4203 return SvcWrap_GetCurrentProcessorNumber64(system);
4204 case SvcId::SignalEvent:
4205 return SvcWrap_SignalEvent64(system);
4206 case SvcId::ClearEvent:
4207 return SvcWrap_ClearEvent64(system);
4208 case SvcId::MapSharedMemory:
4209 return SvcWrap_MapSharedMemory64(system);
4210 case SvcId::UnmapSharedMemory:
4211 return SvcWrap_UnmapSharedMemory64(system);
4212 case SvcId::CreateTransferMemory:
4213 return SvcWrap_CreateTransferMemory64(system);
4214 case SvcId::CloseHandle:
4215 return SvcWrap_CloseHandle64(system);
4216 case SvcId::ResetSignal:
4217 return SvcWrap_ResetSignal64(system);
4218 case SvcId::WaitSynchronization:
4219 return SvcWrap_WaitSynchronization64(system);
4220 case SvcId::CancelSynchronization:
4221 return SvcWrap_CancelSynchronization64(system);
4222 case SvcId::ArbitrateLock:
4223 return SvcWrap_ArbitrateLock64(system);
4224 case SvcId::ArbitrateUnlock:
4225 return SvcWrap_ArbitrateUnlock64(system);
4226 case SvcId::WaitProcessWideKeyAtomic:
4227 return SvcWrap_WaitProcessWideKeyAtomic64(system);
4228 case SvcId::SignalProcessWideKey:
4229 return SvcWrap_SignalProcessWideKey64(system);
4230 case SvcId::GetSystemTick:
4231 return SvcWrap_GetSystemTick64(system);
4232 case SvcId::ConnectToNamedPort:
4233 return SvcWrap_ConnectToNamedPort64(system);
4234 case SvcId::SendSyncRequestLight:
4235 return SvcWrap_SendSyncRequestLight64(system);
4236 case SvcId::SendSyncRequest:
4237 return SvcWrap_SendSyncRequest64(system);
4238 case SvcId::SendSyncRequestWithUserBuffer:
4239 return SvcWrap_SendSyncRequestWithUserBuffer64(system);
4240 case SvcId::SendAsyncRequestWithUserBuffer:
4241 return SvcWrap_SendAsyncRequestWithUserBuffer64(system);
4242 case SvcId::GetProcessId:
4243 return SvcWrap_GetProcessId64(system);
4244 case SvcId::GetThreadId:
4245 return SvcWrap_GetThreadId64(system);
4246 case SvcId::Break:
4247 return SvcWrap_Break64(system);
4248 case SvcId::OutputDebugString:
4249 return SvcWrap_OutputDebugString64(system);
4250 case SvcId::ReturnFromException:
4251 return SvcWrap_ReturnFromException64(system);
4252 case SvcId::GetInfo:
4253 return SvcWrap_GetInfo64(system);
4254 case SvcId::FlushEntireDataCache:
4255 return SvcWrap_FlushEntireDataCache64(system);
4256 case SvcId::FlushDataCache:
4257 return SvcWrap_FlushDataCache64(system);
4258 case SvcId::MapPhysicalMemory:
4259 return SvcWrap_MapPhysicalMemory64(system);
4260 case SvcId::UnmapPhysicalMemory:
4261 return SvcWrap_UnmapPhysicalMemory64(system);
4262 case SvcId::GetDebugFutureThreadInfo:
4263 return SvcWrap_GetDebugFutureThreadInfo64(system);
4264 case SvcId::GetLastThreadInfo:
4265 return SvcWrap_GetLastThreadInfo64(system);
4266 case SvcId::GetResourceLimitLimitValue:
4267 return SvcWrap_GetResourceLimitLimitValue64(system);
4268 case SvcId::GetResourceLimitCurrentValue:
4269 return SvcWrap_GetResourceLimitCurrentValue64(system);
4270 case SvcId::SetThreadActivity:
4271 return SvcWrap_SetThreadActivity64(system);
4272 case SvcId::GetThreadContext3:
4273 return SvcWrap_GetThreadContext364(system);
4274 case SvcId::WaitForAddress:
4275 return SvcWrap_WaitForAddress64(system);
4276 case SvcId::SignalToAddress:
4277 return SvcWrap_SignalToAddress64(system);
4278 case SvcId::SynchronizePreemptionState:
4279 return SvcWrap_SynchronizePreemptionState64(system);
4280 case SvcId::GetResourceLimitPeakValue:
4281 return SvcWrap_GetResourceLimitPeakValue64(system);
4282 case SvcId::CreateIoPool:
4283 return SvcWrap_CreateIoPool64(system);
4284 case SvcId::CreateIoRegion:
4285 return SvcWrap_CreateIoRegion64(system);
4286 case SvcId::KernelDebug:
4287 return SvcWrap_KernelDebug64(system);
4288 case SvcId::ChangeKernelTraceState:
4289 return SvcWrap_ChangeKernelTraceState64(system);
4290 case SvcId::CreateSession:
4291 return SvcWrap_CreateSession64(system);
4292 case SvcId::AcceptSession:
4293 return SvcWrap_AcceptSession64(system);
4294 case SvcId::ReplyAndReceiveLight:
4295 return SvcWrap_ReplyAndReceiveLight64(system);
4296 case SvcId::ReplyAndReceive:
4297 return SvcWrap_ReplyAndReceive64(system);
4298 case SvcId::ReplyAndReceiveWithUserBuffer:
4299 return SvcWrap_ReplyAndReceiveWithUserBuffer64(system);
4300 case SvcId::CreateEvent:
4301 return SvcWrap_CreateEvent64(system);
4302 case SvcId::MapIoRegion:
4303 return SvcWrap_MapIoRegion64(system);
4304 case SvcId::UnmapIoRegion:
4305 return SvcWrap_UnmapIoRegion64(system);
4306 case SvcId::MapPhysicalMemoryUnsafe:
4307 return SvcWrap_MapPhysicalMemoryUnsafe64(system);
4308 case SvcId::UnmapPhysicalMemoryUnsafe:
4309 return SvcWrap_UnmapPhysicalMemoryUnsafe64(system);
4310 case SvcId::SetUnsafeLimit:
4311 return SvcWrap_SetUnsafeLimit64(system);
4312 case SvcId::CreateCodeMemory:
4313 return SvcWrap_CreateCodeMemory64(system);
4314 case SvcId::ControlCodeMemory:
4315 return SvcWrap_ControlCodeMemory64(system);
4316 case SvcId::SleepSystem:
4317 return SvcWrap_SleepSystem64(system);
4318 case SvcId::ReadWriteRegister:
4319 return SvcWrap_ReadWriteRegister64(system);
4320 case SvcId::SetProcessActivity:
4321 return SvcWrap_SetProcessActivity64(system);
4322 case SvcId::CreateSharedMemory:
4323 return SvcWrap_CreateSharedMemory64(system);
4324 case SvcId::MapTransferMemory:
4325 return SvcWrap_MapTransferMemory64(system);
4326 case SvcId::UnmapTransferMemory:
4327 return SvcWrap_UnmapTransferMemory64(system);
4328 case SvcId::CreateInterruptEvent:
4329 return SvcWrap_CreateInterruptEvent64(system);
4330 case SvcId::QueryPhysicalAddress:
4331 return SvcWrap_QueryPhysicalAddress64(system);
4332 case SvcId::QueryIoMapping:
4333 return SvcWrap_QueryIoMapping64(system);
4334 case SvcId::CreateDeviceAddressSpace:
4335 return SvcWrap_CreateDeviceAddressSpace64(system);
4336 case SvcId::AttachDeviceAddressSpace:
4337 return SvcWrap_AttachDeviceAddressSpace64(system);
4338 case SvcId::DetachDeviceAddressSpace:
4339 return SvcWrap_DetachDeviceAddressSpace64(system);
4340 case SvcId::MapDeviceAddressSpaceByForce:
4341 return SvcWrap_MapDeviceAddressSpaceByForce64(system);
4342 case SvcId::MapDeviceAddressSpaceAligned:
4343 return SvcWrap_MapDeviceAddressSpaceAligned64(system);
4344 case SvcId::UnmapDeviceAddressSpace:
4345 return SvcWrap_UnmapDeviceAddressSpace64(system);
4346 case SvcId::InvalidateProcessDataCache:
4347 return SvcWrap_InvalidateProcessDataCache64(system);
4348 case SvcId::StoreProcessDataCache:
4349 return SvcWrap_StoreProcessDataCache64(system);
4350 case SvcId::FlushProcessDataCache:
4351 return SvcWrap_FlushProcessDataCache64(system);
4352 case SvcId::DebugActiveProcess:
4353 return SvcWrap_DebugActiveProcess64(system);
4354 case SvcId::BreakDebugProcess:
4355 return SvcWrap_BreakDebugProcess64(system);
4356 case SvcId::TerminateDebugProcess:
4357 return SvcWrap_TerminateDebugProcess64(system);
4358 case SvcId::GetDebugEvent:
4359 return SvcWrap_GetDebugEvent64(system);
4360 case SvcId::ContinueDebugEvent:
4361 return SvcWrap_ContinueDebugEvent64(system);
4362 case SvcId::GetProcessList:
4363 return SvcWrap_GetProcessList64(system);
4364 case SvcId::GetThreadList:
4365 return SvcWrap_GetThreadList64(system);
4366 case SvcId::GetDebugThreadContext:
4367 return SvcWrap_GetDebugThreadContext64(system);
4368 case SvcId::SetDebugThreadContext:
4369 return SvcWrap_SetDebugThreadContext64(system);
4370 case SvcId::QueryDebugProcessMemory:
4371 return SvcWrap_QueryDebugProcessMemory64(system);
4372 case SvcId::ReadDebugProcessMemory:
4373 return SvcWrap_ReadDebugProcessMemory64(system);
4374 case SvcId::WriteDebugProcessMemory:
4375 return SvcWrap_WriteDebugProcessMemory64(system);
4376 case SvcId::SetHardwareBreakPoint:
4377 return SvcWrap_SetHardwareBreakPoint64(system);
4378 case SvcId::GetDebugThreadParam:
4379 return SvcWrap_GetDebugThreadParam64(system);
4380 case SvcId::GetSystemInfo:
4381 return SvcWrap_GetSystemInfo64(system);
4382 case SvcId::CreatePort:
4383 return SvcWrap_CreatePort64(system);
4384 case SvcId::ManageNamedPort:
4385 return SvcWrap_ManageNamedPort64(system);
4386 case SvcId::ConnectToPort:
4387 return SvcWrap_ConnectToPort64(system);
4388 case SvcId::SetProcessMemoryPermission:
4389 return SvcWrap_SetProcessMemoryPermission64(system);
4390 case SvcId::MapProcessMemory:
4391 return SvcWrap_MapProcessMemory64(system);
4392 case SvcId::UnmapProcessMemory:
4393 return SvcWrap_UnmapProcessMemory64(system);
4394 case SvcId::QueryProcessMemory:
4395 return SvcWrap_QueryProcessMemory64(system);
4396 case SvcId::MapProcessCodeMemory:
4397 return SvcWrap_MapProcessCodeMemory64(system);
4398 case SvcId::UnmapProcessCodeMemory:
4399 return SvcWrap_UnmapProcessCodeMemory64(system);
4400 case SvcId::CreateProcess:
4401 return SvcWrap_CreateProcess64(system);
4402 case SvcId::StartProcess:
4403 return SvcWrap_StartProcess64(system);
4404 case SvcId::TerminateProcess:
4405 return SvcWrap_TerminateProcess64(system);
4406 case SvcId::GetProcessInfo:
4407 return SvcWrap_GetProcessInfo64(system);
4408 case SvcId::CreateResourceLimit:
4409 return SvcWrap_CreateResourceLimit64(system);
4410 case SvcId::SetResourceLimitLimitValue:
4411 return SvcWrap_SetResourceLimitLimitValue64(system);
4412 case SvcId::CallSecureMonitor:
4413 return SvcWrap_CallSecureMonitor64(system);
4414 case SvcId::MapInsecureMemory:
4415 return SvcWrap_MapInsecureMemory64(system);
4416 case SvcId::UnmapInsecureMemory:
4417 return SvcWrap_UnmapInsecureMemory64(system);
4418 default:
4419 LOG_CRITICAL(Kernel_SVC, "Unknown SVC {:x}!", imm);
4420 break;
426 } 4421 }
427 return &SVC_Table_64[func_num];
428} 4422}
4423// clang-format on
429 4424
430void Call(Core::System& system, u32 immediate) { 4425void Call(Core::System& system, u32 imm) {
431 auto& kernel = system.Kernel(); 4426 auto& kernel = system.Kernel();
432 kernel.EnterSVCProfile(); 4427 kernel.EnterSVCProfile();
433 4428
434 auto* thread = GetCurrentThreadPointer(kernel); 4429 if (GetCurrentProcess(system.Kernel()).Is64BitProcess()) {
435 thread->SetIsCallingSvc(); 4430 Call64(system, imm);
436
437 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)
438 : GetSVCInfo32(immediate);
439 if (info) {
440 if (info->func) {
441 info->func(system);
442 } else {
443 LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
444 }
445 } else { 4431 } else {
446 LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate); 4432 Call32(system, imm);
447 } 4433 }
448 4434
449 kernel.ExitSVCProfile(); 4435 kernel.ExitSVCProfile();
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h
index b599f9a3d..36e619959 100644
--- a/src/core/hle/kernel/svc.h
+++ b/src/core/hle/kernel/svc.h
@@ -1,172 +1,536 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#pragma once 4// This file is automatically generated using svc_generator.py.
5 5
6#include "common/common_types.h" 6#pragma once
7#include "core/hle/kernel/svc_types.h"
8#include "core/hle/result.h"
9 7
10namespace Core { 8namespace Core {
11class System; 9class System;
12} 10}
13 11
14namespace Kernel::Svc { 12#include "common/common_types.h"
13#include "core/hle/kernel/svc_types.h"
14#include "core/hle/result.h"
15 15
16void Call(Core::System& system, u32 immediate); 16namespace Kernel::Svc {
17 17
18Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size); 18// clang-format off
19Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, MemoryPermission perm); 19Result SetHeapSize(Core::System& system, uintptr_t* out_address, uint64_t size);
20Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, u32 attr); 20Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
21Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size); 21Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
22Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size); 22Result MapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
23Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, 23Result UnmapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
24 VAddr query_address); 24Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
25void ExitProcess(Core::System& system); 25void ExitProcess(Core::System& system);
26Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, 26Result CreateThread(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
27 VAddr stack_bottom, u32 priority, s32 core_id);
28Result StartThread(Core::System& system, Handle thread_handle); 27Result StartThread(Core::System& system, Handle thread_handle);
29void ExitThread(Core::System& system); 28void ExitThread(Core::System& system);
30void SleepThread(Core::System& system, s64 nanoseconds); 29void SleepThread(Core::System& system, int64_t ns);
31Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle); 30Result GetThreadPriority(Core::System& system, int32_t* out_priority, Handle thread_handle);
32Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority); 31Result SetThreadPriority(Core::System& system, Handle thread_handle, int32_t priority);
33Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, 32Result GetThreadCoreMask(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
34 u64* out_affinity_mask); 33Result SetThreadCoreMask(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
35Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, 34int32_t GetCurrentProcessorNumber(Core::System& system);
36 u64 affinity_mask);
37u32 GetCurrentProcessorNumber(Core::System& system);
38Result SignalEvent(Core::System& system, Handle event_handle); 35Result SignalEvent(Core::System& system, Handle event_handle);
39Result ClearEvent(Core::System& system, Handle event_handle); 36Result ClearEvent(Core::System& system, Handle event_handle);
40Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size, 37Result MapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
41 MemoryPermission map_perm); 38Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
42Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size); 39Result CreateTransferMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
43Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size,
44 MemoryPermission map_perm);
45Result CloseHandle(Core::System& system, Handle handle); 40Result CloseHandle(Core::System& system, Handle handle);
46Result ResetSignal(Core::System& system, Handle handle); 41Result ResetSignal(Core::System& system, Handle handle);
47Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, 42Result WaitSynchronization(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
48 s64 nano_seconds);
49Result CancelSynchronization(Core::System& system, Handle handle); 43Result CancelSynchronization(Core::System& system, Handle handle);
50Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag); 44Result ArbitrateLock(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
51Result ArbitrateUnlock(Core::System& system, VAddr address); 45Result ArbitrateUnlock(Core::System& system, uint64_t address);
52Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag, 46Result WaitProcessWideKeyAtomic(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
53 s64 timeout_ns); 47void SignalProcessWideKey(Core::System& system, uint64_t cv_key, int32_t count);
54void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count); 48int64_t GetSystemTick(Core::System& system);
55u64 GetSystemTick(Core::System& system); 49Result ConnectToNamedPort(Core::System& system, Handle* out_handle, uint64_t name);
56Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address); 50Result SendSyncRequest(Core::System& system, Handle session_handle);
57Result SendSyncRequest(Core::System& system, Handle handle); 51Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
58Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle); 52Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
59Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle); 53Result GetProcessId(Core::System& system, uint64_t* out_process_id, Handle process_handle);
60void Break(Core::System& system, u32 reason, u64 info1, u64 info2); 54Result GetThreadId(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
61void OutputDebugString(Core::System& system, VAddr address, u64 len); 55void Break(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
62Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u64 info_sub_id); 56Result OutputDebugString(Core::System& system, uint64_t debug_str, uint64_t len);
63Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size); 57void ReturnFromException(Core::System& system, Result result);
64Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size); 58Result GetInfo(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
65Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, 59void FlushEntireDataCache(Core::System& system);
66 Handle resource_limit_handle, LimitableResource which); 60Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size);
67Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, 61Result MapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
68 Handle resource_limit_handle, LimitableResource which); 62Result UnmapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
69Result SetThreadActivity(Core::System& system, Handle thread_handle, 63Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
70 ThreadActivity thread_activity); 64Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags);
71Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle); 65Result GetResourceLimitLimitValue(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
72Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value, 66Result GetResourceLimitCurrentValue(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
73 s64 timeout_ns); 67Result SetThreadActivity(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
74Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value, 68Result GetThreadContext3(Core::System& system, uint64_t out_context, Handle thread_handle);
75 s32 count); 69Result WaitForAddress(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
70Result SignalToAddress(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
76void SynchronizePreemptionState(Core::System& system); 71void SynchronizePreemptionState(Core::System& system);
77void KernelDebug(Core::System& system, u32 kernel_debug_type, u64 param1, u64 param2, u64 param3); 72Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
78void ChangeKernelTraceState(Core::System& system, u32 trace_state); 73Result CreateIoPool(Core::System& system, Handle* out_handle, IoPoolType which);
79Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u32 is_light, 74Result CreateIoRegion(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
80 u64 name); 75void KernelDebug(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
81Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s32 num_handles, 76void ChangeKernelTraceState(Core::System& system, KernelTraceState kern_trace_state);
82 Handle reply_target, s64 timeout_ns); 77Result CreateSession(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
83Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read); 78Result AcceptSession(Core::System& system, Handle* out_handle, Handle port);
84Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size); 79Result ReplyAndReceive(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
85Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, 80Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
86 VAddr address, size_t size, MemoryPermission perm); 81Result CreateEvent(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
87Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids, 82Result MapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
88 u32 out_process_ids_size); 83Result UnmapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
89Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, 84Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
90 u32 out_thread_ids_size, Handle debug_handle); 85Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
91Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address, 86Result SetUnsafeLimit(Core::System& system, uint64_t limit);
92 u64 size, MemoryPermission perm); 87Result CreateCodeMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
93Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, 88Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
94 VAddr src_address, u64 size); 89void SleepSystem(Core::System& system);
95Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, 90Result ReadWriteRegister(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
96 VAddr src_address, u64 size); 91Result SetProcessActivity(Core::System& system, Handle process_handle, ProcessActivity process_activity);
97Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, 92Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
98 Handle process_handle, VAddr address); 93Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
99Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, 94Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
100 u64 src_address, u64 size); 95Result CreateInterruptEvent(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
101Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, 96Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
102 u64 src_address, u64 size); 97Result QueryIoMapping(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint64_t size);
103Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type); 98Result CreateDeviceAddressSpace(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
99Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
100Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
101Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
102Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
103Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
104Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
105Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
106Result FlushProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
107Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id);
108Result BreakDebugProcess(Core::System& system, Handle debug_handle);
109Result TerminateDebugProcess(Core::System& system, Handle debug_handle);
110Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle);
111Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
112Result GetProcessList(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
113Result GetThreadList(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
114Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
115Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
116Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
117Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
118Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
119Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
120Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
121Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
122Result CreatePort(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
123Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
124Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port);
125Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
126Result MapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
127Result UnmapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
128Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
129Result MapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
130Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
131Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
132Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
133Result TerminateProcess(Core::System& system, Handle process_handle);
134Result GetProcessInfo(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
104Result CreateResourceLimit(Core::System& system, Handle* out_handle); 135Result CreateResourceLimit(Core::System& system, Handle* out_handle);
105Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, 136Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
106 LimitableResource which, u64 limit_value); 137Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
107 138Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
108// 139
109 140Result SetHeapSize64From32(Core::System& system, uintptr_t* out_address, uint32_t size);
110Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size); 141Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, MemoryPermission perm);
111Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, u32 attr); 142Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, uint32_t mask, uint32_t attr);
112Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size); 143Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
113Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size); 144Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
114Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address, 145Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, uint32_t address);
115 u32 query_address); 146void ExitProcess64From32(Core::System& system);
116void ExitProcess32(Core::System& system); 147Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg, uint32_t stack_bottom, int32_t priority, int32_t core_id);
117Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, u32 entry_point, 148Result StartThread64From32(Core::System& system, Handle thread_handle);
118 u32 arg, u32 stack_top, s32 processor_id); 149void ExitThread64From32(Core::System& system);
119Result StartThread32(Core::System& system, Handle thread_handle); 150void SleepThread64From32(Core::System& system, int64_t ns);
120void ExitThread32(Core::System& system); 151Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority, Handle thread_handle);
121void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high); 152Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority);
122Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle); 153Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
123Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority); 154Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
124Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, 155int32_t GetCurrentProcessorNumber64From32(Core::System& system);
125 u32* out_affinity_mask_low, u32* out_affinity_mask_high); 156Result SignalEvent64From32(Core::System& system, Handle event_handle);
126Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, 157Result ClearEvent64From32(Core::System& system, Handle event_handle);
127 u32 affinity_mask_low, u32 affinity_mask_high); 158Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
128u32 GetCurrentProcessorNumber32(Core::System& system); 159Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size);
129Result SignalEvent32(Core::System& system, Handle event_handle); 160Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
130Result ClearEvent32(Core::System& system, Handle event_handle); 161Result CloseHandle64From32(Core::System& system, Handle handle);
131Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size, 162Result ResetSignal64From32(Core::System& system, Handle handle);
132 MemoryPermission map_perm); 163Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, int64_t timeout_ns);
133Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size); 164Result CancelSynchronization64From32(Core::System& system, Handle handle);
134Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, 165Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address, uint32_t tag);
135 MemoryPermission map_perm); 166Result ArbitrateUnlock64From32(Core::System& system, uint32_t address);
136Result CloseHandle32(Core::System& system, Handle handle); 167Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key, uint32_t tag, int64_t timeout_ns);
137Result ResetSignal32(Core::System& system, Handle handle); 168void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count);
138Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, 169int64_t GetSystemTick64From32(Core::System& system);
139 s32 num_handles, u32 timeout_high, s32* index); 170Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name);
140Result CancelSynchronization32(Core::System& system, Handle handle); 171Result SendSyncRequest64From32(Core::System& system, Handle session_handle);
141Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag); 172Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
142Result ArbitrateUnlock32(Core::System& system, u32 address); 173Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
143Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, 174Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle);
144 u32 timeout_ns_low, u32 timeout_ns_high); 175Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
145void SignalProcessWideKey32(Core::System& system, u32 cv_key, s32 count); 176void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size);
146void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high); 177Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len);
147Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, u32 port_name_address); 178void ReturnFromException64From32(Core::System& system, Result result);
148Result SendSyncRequest32(Core::System& system, Handle handle); 179Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
149Result GetProcessId32(Core::System& system, u32* out_process_id_low, u32* out_process_id_high, 180void FlushEntireDataCache64From32(Core::System& system);
150 Handle handle); 181Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size);
151Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high, 182Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
152 Handle thread_handle); 183Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
153void Break32(Core::System& system, u32 reason, u32 info1, u32 info2); 184Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
154void OutputDebugString32(Core::System& system, u32 address, u32 len); 185Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags);
155Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, 186Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
156 u32 info_id, u32 handle, u32 sub_id_high); 187Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
157Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size); 188Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
158Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size); 189Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle);
159Result SetThreadActivity32(Core::System& system, Handle thread_handle, 190Result WaitForAddress64From32(Core::System& system, uint32_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
160 ThreadActivity thread_activity); 191Result SignalToAddress64From32(Core::System& system, uint32_t address, SignalType signal_type, int32_t value, int32_t count);
161Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle); 192void SynchronizePreemptionState64From32(Core::System& system);
162Result WaitForAddress32(Core::System& system, u32 address, ArbitrationType arb_type, s32 value, 193Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
163 u32 timeout_ns_low, u32 timeout_ns_high); 194Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType which);
164Result SignalToAddress32(Core::System& system, u32 address, SignalType signal_type, s32 value, 195Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint32_t size, MemoryMapping mapping, MemoryPermission perm);
165 s32 count); 196void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
166Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read); 197void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state);
167Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size); 198Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint32_t name);
168Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation, 199Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port);
169 u64 address, u64 size, MemoryPermission perm); 200Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
170Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, u64 size); 201Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index, uint32_t message_buffer, uint32_t message_buffer_size, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
202Result CreateEvent64From32(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
203Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size, MemoryPermission perm);
204Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size);
205Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
206Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
207Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit);
208Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size);
209Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
210void SleepSystem64From32(Core::System& system);
211Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
212Result SetProcessActivity64From32(Core::System& system, Handle process_handle, ProcessActivity process_activity);
213Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
214Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size, MemoryPermission owner_perm);
215Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size);
216Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
217Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, uint32_t address);
218Result QueryIoMapping64From32(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint32_t size);
219Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
220Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
221Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
222Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
223Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
224Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address);
225Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
226Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
227Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
228Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id);
229Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle);
230Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle);
231Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle);
232Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags, uint32_t thread_ids, int32_t num_thread_ids);
233Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes, uint32_t out_process_ids, int32_t max_out_count);
234Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads, uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
235Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
236Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id, uint32_t context, uint32_t context_flags);
237Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint32_t address);
238Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle, uint32_t address, uint32_t size);
239Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer, uint32_t address, uint32_t size);
240Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
241Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
242Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
243Result CreatePort64From32(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint32_t name);
244Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name, int32_t max_sessions);
245Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port);
246Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
247Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
248Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
249Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
250Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
251Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
252Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters, uint32_t caps, int32_t num_caps);
253Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
254Result TerminateProcess64From32(Core::System& system, Handle process_handle);
255Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
256Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle);
257Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
258Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
259Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
260
261Result SetHeapSize64(Core::System& system, uintptr_t* out_address, uint64_t size);
262Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
263Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
264Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
265Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
266Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
267void ExitProcess64(Core::System& system);
268Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
269Result StartThread64(Core::System& system, Handle thread_handle);
270void ExitThread64(Core::System& system);
271void SleepThread64(Core::System& system, int64_t ns);
272Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle);
273Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority);
274Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
275Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
276int32_t GetCurrentProcessorNumber64(Core::System& system);
277Result SignalEvent64(Core::System& system, Handle event_handle);
278Result ClearEvent64(Core::System& system, Handle event_handle);
279Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
280Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
281Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
282Result CloseHandle64(Core::System& system, Handle handle);
283Result ResetSignal64(Core::System& system, Handle handle);
284Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
285Result CancelSynchronization64(Core::System& system, Handle handle);
286Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
287Result ArbitrateUnlock64(Core::System& system, uint64_t address);
288Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
289void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count);
290int64_t GetSystemTick64(Core::System& system);
291Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name);
292Result SendSyncRequest64(Core::System& system, Handle session_handle);
293Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
294Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
295Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle);
296Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
297void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
298Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len);
299void ReturnFromException64(Core::System& system, Result result);
300Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
301void FlushEntireDataCache64(Core::System& system);
302Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size);
303Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
304Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
305Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
306Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uintptr_t* out_tls_address, uint32_t* out_flags);
307Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
308Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
309Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
310Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle);
311Result WaitForAddress64(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
312Result SignalToAddress64(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
313void SynchronizePreemptionState64(Core::System& system);
314Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
315Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType which);
316Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
317void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
318void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state);
319Result CreateSession64(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
320Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port);
321Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
322Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
323Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
324Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
325Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
326Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
327Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
328Result SetUnsafeLimit64(Core::System& system, uint64_t limit);
329Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
330Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
331void SleepSystem64(Core::System& system);
332Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
333Result SetProcessActivity64(Core::System& system, Handle process_handle, ProcessActivity process_activity);
334Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
335Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
336Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
337Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
338Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
339Result QueryIoMapping64(Core::System& system, uintptr_t* out_address, uintptr_t* out_size, uint64_t physical_address, uint64_t size);
340Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
341Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
342Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
343Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
344Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
345Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
346Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
347Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
348Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
349Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id);
350Result BreakDebugProcess64(Core::System& system, Handle debug_handle);
351Result TerminateDebugProcess64(Core::System& system, Handle debug_handle);
352Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle);
353Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
354Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
355Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
356Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
357Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
358Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
359Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
360Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
361Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
362Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
363Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
364Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
365Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
366Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port);
367Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
368Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
369Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
370Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
371Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
372Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
373Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
374Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
375Result TerminateProcess64(Core::System& system, Handle process_handle);
376Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
377Result CreateResourceLimit64(Core::System& system, Handle* out_handle);
378Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
379Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
380Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
381
382enum class SvcId : u32 {
383 SetHeapSize = 0x1,
384 SetMemoryPermission = 0x2,
385 SetMemoryAttribute = 0x3,
386 MapMemory = 0x4,
387 UnmapMemory = 0x5,
388 QueryMemory = 0x6,
389 ExitProcess = 0x7,
390 CreateThread = 0x8,
391 StartThread = 0x9,
392 ExitThread = 0xa,
393 SleepThread = 0xb,
394 GetThreadPriority = 0xc,
395 SetThreadPriority = 0xd,
396 GetThreadCoreMask = 0xe,
397 SetThreadCoreMask = 0xf,
398 GetCurrentProcessorNumber = 0x10,
399 SignalEvent = 0x11,
400 ClearEvent = 0x12,
401 MapSharedMemory = 0x13,
402 UnmapSharedMemory = 0x14,
403 CreateTransferMemory = 0x15,
404 CloseHandle = 0x16,
405 ResetSignal = 0x17,
406 WaitSynchronization = 0x18,
407 CancelSynchronization = 0x19,
408 ArbitrateLock = 0x1a,
409 ArbitrateUnlock = 0x1b,
410 WaitProcessWideKeyAtomic = 0x1c,
411 SignalProcessWideKey = 0x1d,
412 GetSystemTick = 0x1e,
413 ConnectToNamedPort = 0x1f,
414 SendSyncRequestLight = 0x20,
415 SendSyncRequest = 0x21,
416 SendSyncRequestWithUserBuffer = 0x22,
417 SendAsyncRequestWithUserBuffer = 0x23,
418 GetProcessId = 0x24,
419 GetThreadId = 0x25,
420 Break = 0x26,
421 OutputDebugString = 0x27,
422 ReturnFromException = 0x28,
423 GetInfo = 0x29,
424 FlushEntireDataCache = 0x2a,
425 FlushDataCache = 0x2b,
426 MapPhysicalMemory = 0x2c,
427 UnmapPhysicalMemory = 0x2d,
428 GetDebugFutureThreadInfo = 0x2e,
429 GetLastThreadInfo = 0x2f,
430 GetResourceLimitLimitValue = 0x30,
431 GetResourceLimitCurrentValue = 0x31,
432 SetThreadActivity = 0x32,
433 GetThreadContext3 = 0x33,
434 WaitForAddress = 0x34,
435 SignalToAddress = 0x35,
436 SynchronizePreemptionState = 0x36,
437 GetResourceLimitPeakValue = 0x37,
438 CreateIoPool = 0x39,
439 CreateIoRegion = 0x3a,
440 KernelDebug = 0x3c,
441 ChangeKernelTraceState = 0x3d,
442 CreateSession = 0x40,
443 AcceptSession = 0x41,
444 ReplyAndReceiveLight = 0x42,
445 ReplyAndReceive = 0x43,
446 ReplyAndReceiveWithUserBuffer = 0x44,
447 CreateEvent = 0x45,
448 MapIoRegion = 0x46,
449 UnmapIoRegion = 0x47,
450 MapPhysicalMemoryUnsafe = 0x48,
451 UnmapPhysicalMemoryUnsafe = 0x49,
452 SetUnsafeLimit = 0x4a,
453 CreateCodeMemory = 0x4b,
454 ControlCodeMemory = 0x4c,
455 SleepSystem = 0x4d,
456 ReadWriteRegister = 0x4e,
457 SetProcessActivity = 0x4f,
458 CreateSharedMemory = 0x50,
459 MapTransferMemory = 0x51,
460 UnmapTransferMemory = 0x52,
461 CreateInterruptEvent = 0x53,
462 QueryPhysicalAddress = 0x54,
463 QueryIoMapping = 0x55,
464 CreateDeviceAddressSpace = 0x56,
465 AttachDeviceAddressSpace = 0x57,
466 DetachDeviceAddressSpace = 0x58,
467 MapDeviceAddressSpaceByForce = 0x59,
468 MapDeviceAddressSpaceAligned = 0x5a,
469 UnmapDeviceAddressSpace = 0x5c,
470 InvalidateProcessDataCache = 0x5d,
471 StoreProcessDataCache = 0x5e,
472 FlushProcessDataCache = 0x5f,
473 DebugActiveProcess = 0x60,
474 BreakDebugProcess = 0x61,
475 TerminateDebugProcess = 0x62,
476 GetDebugEvent = 0x63,
477 ContinueDebugEvent = 0x64,
478 GetProcessList = 0x65,
479 GetThreadList = 0x66,
480 GetDebugThreadContext = 0x67,
481 SetDebugThreadContext = 0x68,
482 QueryDebugProcessMemory = 0x69,
483 ReadDebugProcessMemory = 0x6a,
484 WriteDebugProcessMemory = 0x6b,
485 SetHardwareBreakPoint = 0x6c,
486 GetDebugThreadParam = 0x6d,
487 GetSystemInfo = 0x6f,
488 CreatePort = 0x70,
489 ManageNamedPort = 0x71,
490 ConnectToPort = 0x72,
491 SetProcessMemoryPermission = 0x73,
492 MapProcessMemory = 0x74,
493 UnmapProcessMemory = 0x75,
494 QueryProcessMemory = 0x76,
495 MapProcessCodeMemory = 0x77,
496 UnmapProcessCodeMemory = 0x78,
497 CreateProcess = 0x79,
498 StartProcess = 0x7a,
499 TerminateProcess = 0x7b,
500 GetProcessInfo = 0x7c,
501 CreateResourceLimit = 0x7d,
502 SetResourceLimitLimitValue = 0x7e,
503 CallSecureMonitor = 0x7f,
504 MapInsecureMemory = 0x90,
505 UnmapInsecureMemory = 0x91,
506};
507// clang-format on
508
509// Custom ABI.
510Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args);
511Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args);
512Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args);
513
514Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args);
515Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args);
516Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args);
517
518void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args);
519void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args);
520void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args);
521
522// Defined in svc_light_ipc.cpp.
523void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system);
524void SvcWrap_ReplyAndReceiveLight64(Core::System& system);
525
526void SvcWrap_SendSyncRequestLight64From32(Core::System& system);
527void SvcWrap_SendSyncRequestLight64(Core::System& system);
528
529// Defined in svc_secure_monitor_call.cpp.
530void SvcWrap_CallSecureMonitor64From32(Core::System& system);
531void SvcWrap_CallSecureMonitor64(Core::System& system);
532
533// Perform a supervisor call by index.
534void Call(Core::System& system, u32 imm);
171 535
172} // namespace Kernel::Svc 536} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_activity.cpp b/src/core/hle/kernel/svc/svc_activity.cpp
index 8774a5c98..63bc08555 100644
--- a/src/core/hle/kernel/svc/svc_activity.cpp
+++ b/src/core/hle/kernel/svc/svc_activity.cpp
@@ -16,18 +16,19 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle,
16 thread_activity); 16 thread_activity);
17 17
18 // Validate the activity. 18 // Validate the activity.
19 constexpr auto IsValidThreadActivity = [](ThreadActivity activity) { 19 static constexpr auto IsValidThreadActivity = [](ThreadActivity activity) {
20 return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused; 20 return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused;
21 }; 21 };
22 R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue); 22 R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue);
23 23
24 // Get the thread from its handle. 24 // Get the thread from its handle.
25 KScopedAutoObject thread = 25 KScopedAutoObject thread =
26 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); 26 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
27 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 27 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
28 28
29 // Check that the activity is being set on a non-current thread for the current process. 29 // Check that the activity is being set on a non-current thread for the current process.
30 R_UNLESS(thread->GetOwnerProcess() == system.Kernel().CurrentProcess(), ResultInvalidHandle); 30 R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()),
31 ResultInvalidHandle);
31 R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy); 32 R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy);
32 33
33 // Set the activity. 34 // Set the activity.
@@ -36,9 +37,30 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle,
36 return ResultSuccess; 37 return ResultSuccess;
37} 38}
38 39
39Result SetThreadActivity32(Core::System& system, Handle thread_handle, 40Result SetProcessActivity(Core::System& system, Handle process_handle,
41 ProcessActivity process_activity) {
42 UNIMPLEMENTED();
43 R_THROW(ResultNotImplemented);
44}
45
46Result SetThreadActivity64(Core::System& system, Handle thread_handle,
40 ThreadActivity thread_activity) { 47 ThreadActivity thread_activity) {
41 return SetThreadActivity(system, thread_handle, thread_activity); 48 return SetThreadActivity(system, thread_handle, thread_activity);
42} 49}
43 50
51Result SetProcessActivity64(Core::System& system, Handle process_handle,
52 ProcessActivity process_activity) {
53 return SetProcessActivity(system, process_handle, process_activity);
54}
55
56Result SetThreadActivity64From32(Core::System& system, Handle thread_handle,
57 ThreadActivity thread_activity) {
58 return SetThreadActivity(system, thread_handle, thread_activity);
59}
60
61Result SetProcessActivity64From32(Core::System& system, Handle process_handle,
62 ProcessActivity process_activity) {
63 return SetProcessActivity(system, process_handle, process_activity);
64}
65
44} // namespace Kernel::Svc 66} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_address_arbiter.cpp b/src/core/hle/kernel/svc/svc_address_arbiter.cpp
index 842107726..998bd3f22 100644
--- a/src/core/hle/kernel/svc/svc_address_arbiter.cpp
+++ b/src/core/hle/kernel/svc/svc_address_arbiter.cpp
@@ -72,13 +72,7 @@ Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_t
72 timeout = timeout_ns; 72 timeout = timeout_ns;
73 } 73 }
74 74
75 return system.Kernel().CurrentProcess()->WaitAddressArbiter(address, arb_type, value, timeout); 75 return GetCurrentProcess(system.Kernel()).WaitAddressArbiter(address, arb_type, value, timeout);
76}
77
78Result WaitForAddress32(Core::System& system, u32 address, ArbitrationType arb_type, s32 value,
79 u32 timeout_ns_low, u32 timeout_ns_high) {
80 const auto timeout = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32));
81 return WaitForAddress(system, address, arb_type, value, timeout);
82} 76}
83 77
84// Signals to an address (via Address Arbiter) 78// Signals to an address (via Address Arbiter)
@@ -101,13 +95,28 @@ Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_ty
101 return ResultInvalidEnumValue; 95 return ResultInvalidEnumValue;
102 } 96 }
103 97
104 return system.Kernel().CurrentProcess()->SignalAddressArbiter(address, signal_type, value, 98 return GetCurrentProcess(system.Kernel())
105 count); 99 .SignalAddressArbiter(address, signal_type, value, count);
106} 100}
107 101
108Result SignalToAddress32(Core::System& system, u32 address, SignalType signal_type, s32 value, 102Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
103 s64 timeout_ns) {
104 return WaitForAddress(system, address, arb_type, value, timeout_ns);
105}
106
107Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value,
109 s32 count) { 108 s32 count) {
110 return SignalToAddress(system, address, signal_type, value, count); 109 return SignalToAddress(system, address, signal_type, value, count);
111} 110}
112 111
112Result WaitForAddress64From32(Core::System& system, u32 address, ArbitrationType arb_type,
113 s32 value, s64 timeout_ns) {
114 return WaitForAddress(system, address, arb_type, value, timeout_ns);
115}
116
117Result SignalToAddress64From32(Core::System& system, u32 address, SignalType signal_type, s32 value,
118 s32 count) {
119 return SignalToAddress(system, address, signal_type, value, count);
120}
121
113} // namespace Kernel::Svc 122} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_address_translation.cpp b/src/core/hle/kernel/svc/svc_address_translation.cpp
index 299e22ae6..c25e144cd 100644
--- a/src/core/hle/kernel/svc/svc_address_translation.cpp
+++ b/src/core/hle/kernel/svc/svc_address_translation.cpp
@@ -2,5 +2,49 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
10 uint64_t address) {
11 UNIMPLEMENTED();
12 R_THROW(ResultNotImplemented);
13}
14
15Result QueryIoMapping(Core::System& system, uintptr_t* out_address, uintptr_t* out_size,
16 uint64_t physical_address, uint64_t size) {
17 UNIMPLEMENTED();
18 R_THROW(ResultNotImplemented);
19}
20
21Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
22 uint64_t address) {
23 R_RETURN(QueryPhysicalAddress(system, out_info, address));
24}
25
26Result QueryIoMapping64(Core::System& system, uintptr_t* out_address, uintptr_t* out_size,
27 uint64_t physical_address, uint64_t size) {
28 R_RETURN(QueryIoMapping(system, out_address, out_size, physical_address, size));
29}
30
31Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info,
32 uint32_t address) {
33 lp64::PhysicalMemoryInfo info{};
34 R_TRY(QueryPhysicalAddress(system, std::addressof(info), address));
35
36 *out_info = {
37 .physical_address = info.physical_address,
38 .virtual_address = static_cast<u32>(info.virtual_address),
39 .size = static_cast<u32>(info.size),
40 };
41 R_SUCCEED();
42}
43
44Result QueryIoMapping64From32(Core::System& system, uintptr_t* out_address, uintptr_t* out_size,
45 uint64_t physical_address, uint32_t size) {
46 R_RETURN(QueryIoMapping(system, reinterpret_cast<uintptr_t*>(out_address),
47 reinterpret_cast<uintptr_t*>(out_size), physical_address, size));
48}
49
50} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_cache.cpp b/src/core/hle/kernel/svc/svc_cache.cpp
index 42167d35b..598b71da5 100644
--- a/src/core/hle/kernel/svc/svc_cache.cpp
+++ b/src/core/hle/kernel/svc/svc_cache.cpp
@@ -9,7 +9,28 @@
9 9
10namespace Kernel::Svc { 10namespace Kernel::Svc {
11 11
12Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, u64 size) { 12void FlushEntireDataCache(Core::System& system) {
13 UNIMPLEMENTED();
14}
15
16Result FlushDataCache(Core::System& system, VAddr address, size_t size) {
17 UNIMPLEMENTED();
18 R_THROW(ResultNotImplemented);
19}
20
21Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
22 uint64_t size) {
23 UNIMPLEMENTED();
24 R_THROW(ResultNotImplemented);
25}
26
27Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
28 uint64_t size) {
29 UNIMPLEMENTED();
30 R_THROW(ResultNotImplemented);
31}
32
33Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 address, u64 size) {
13 // Validate address/size. 34 // Validate address/size.
14 R_UNLESS(size > 0, ResultInvalidSize); 35 R_UNLESS(size > 0, ResultInvalidSize);
15 R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory); 36 R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory);
@@ -17,7 +38,7 @@ Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64
17 38
18 // Get the process from its handle. 39 // Get the process from its handle.
19 KScopedAutoObject process = 40 KScopedAutoObject process =
20 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); 41 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
21 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 42 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
22 43
23 // Verify the region is within range. 44 // Verify the region is within range.
@@ -28,4 +49,50 @@ Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64
28 R_RETURN(system.Memory().FlushDataCache(*process, address, size)); 49 R_RETURN(system.Memory().FlushDataCache(*process, address, size));
29} 50}
30 51
52void FlushEntireDataCache64(Core::System& system) {
53 FlushEntireDataCache(system);
54}
55
56Result FlushDataCache64(Core::System& system, VAddr address, size_t size) {
57 R_RETURN(FlushDataCache(system, address, size));
58}
59
60Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
61 uint64_t size) {
62 R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
63}
64
65Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
66 uint64_t size) {
67 R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
68}
69
70Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
71 uint64_t size) {
72 R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
73}
74
75void FlushEntireDataCache64From32(Core::System& system) {
76 return FlushEntireDataCache(system);
77}
78
79Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size) {
80 R_RETURN(FlushDataCache(system, address, size));
81}
82
83Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle,
84 uint64_t address, uint64_t size) {
85 R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
86}
87
88Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
89 uint64_t size) {
90 R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
91}
92
93Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
94 uint64_t size) {
95 R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
96}
97
31} // namespace Kernel::Svc 98} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp
index 4cb21e101..538ff1c71 100644
--- a/src/core/hle/kernel/svc/svc_code_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_code_memory.cpp
@@ -46,7 +46,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t
46 R_UNLESS(code_mem != nullptr, ResultOutOfResource); 46 R_UNLESS(code_mem != nullptr, ResultOutOfResource);
47 47
48 // Verify that the region is in range. 48 // Verify that the region is in range.
49 R_UNLESS(system.CurrentProcess()->PageTable().Contains(address, size), 49 R_UNLESS(GetCurrentProcess(system.Kernel()).PageTable().Contains(address, size),
50 ResultInvalidCurrentMemory); 50 ResultInvalidCurrentMemory);
51 51
52 // Initialize the code memory. 52 // Initialize the code memory.
@@ -56,19 +56,16 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t
56 KCodeMemory::Register(kernel, code_mem); 56 KCodeMemory::Register(kernel, code_mem);
57 57
58 // Add the code memory to the handle table. 58 // Add the code memory to the handle table.
59 R_TRY(system.CurrentProcess()->GetHandleTable().Add(out, code_mem)); 59 R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, code_mem));
60 60
61 code_mem->Close(); 61 code_mem->Close();
62 62
63 return ResultSuccess; 63 return ResultSuccess;
64} 64}
65 65
66Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) { 66Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
67 return CreateCodeMemory(system, out, address, size); 67 CodeMemoryOperation operation, VAddr address, size_t size,
68} 68 MemoryPermission perm) {
69
70Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation,
71 VAddr address, size_t size, MemoryPermission perm) {
72 69
73 LOG_TRACE(Kernel_SVC, 70 LOG_TRACE(Kernel_SVC,
74 "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, " 71 "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, "
@@ -82,20 +79,22 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 op
82 R_UNLESS((address < address + size), ResultInvalidCurrentMemory); 79 R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
83 80
84 // Get the code memory from its handle. 81 // Get the code memory from its handle.
85 KScopedAutoObject code_mem = 82 KScopedAutoObject code_mem = GetCurrentProcess(system.Kernel())
86 system.CurrentProcess()->GetHandleTable().GetObject<KCodeMemory>(code_memory_handle); 83 .GetHandleTable()
84 .GetObject<KCodeMemory>(code_memory_handle);
87 R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle); 85 R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle);
88 86
89 // NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process. 87 // NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process.
90 // This enables homebrew usage of these SVCs for JIT. 88 // This enables homebrew usage of these SVCs for JIT.
91 89
92 // Perform the operation. 90 // Perform the operation.
93 switch (static_cast<CodeMemoryOperation>(operation)) { 91 switch (operation) {
94 case CodeMemoryOperation::Map: { 92 case CodeMemoryOperation::Map: {
95 // Check that the region is in range. 93 // Check that the region is in range.
96 R_UNLESS( 94 R_UNLESS(GetCurrentProcess(system.Kernel())
97 system.CurrentProcess()->PageTable().CanContain(address, size, KMemoryState::CodeOut), 95 .PageTable()
98 ResultInvalidMemoryRegion); 96 .CanContain(address, size, KMemoryState::CodeOut),
97 ResultInvalidMemoryRegion);
99 98
100 // Check the memory permission. 99 // Check the memory permission.
101 R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); 100 R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
@@ -105,9 +104,10 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 op
105 } break; 104 } break;
106 case CodeMemoryOperation::Unmap: { 105 case CodeMemoryOperation::Unmap: {
107 // Check that the region is in range. 106 // Check that the region is in range.
108 R_UNLESS( 107 R_UNLESS(GetCurrentProcess(system.Kernel())
109 system.CurrentProcess()->PageTable().CanContain(address, size, KMemoryState::CodeOut), 108 .PageTable()
110 ResultInvalidMemoryRegion); 109 .CanContain(address, size, KMemoryState::CodeOut),
110 ResultInvalidMemoryRegion);
111 111
112 // Check the memory permission. 112 // Check the memory permission.
113 R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); 113 R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
@@ -146,9 +146,26 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 op
146 return ResultSuccess; 146 return ResultSuccess;
147} 147}
148 148
149Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation, 149Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address,
150 u64 address, u64 size, MemoryPermission perm) { 150 uint64_t size) {
151 return ControlCodeMemory(system, code_memory_handle, operation, address, size, perm); 151 R_RETURN(CreateCodeMemory(system, out_handle, address, size));
152}
153
154Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle,
155 CodeMemoryOperation operation, uint64_t address, uint64_t size,
156 MemoryPermission perm) {
157 R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
158}
159
160Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address,
161 uint32_t size) {
162 R_RETURN(CreateCodeMemory(system, out_handle, address, size));
163}
164
165Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle,
166 CodeMemoryOperation operation, uint64_t address, uint64_t size,
167 MemoryPermission perm) {
168 R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
152} 169}
153 170
154} // namespace Kernel::Svc 171} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_condition_variable.cpp b/src/core/hle/kernel/svc/svc_condition_variable.cpp
index d6cfc87c5..8ad1a0b8f 100644
--- a/src/core/hle/kernel/svc/svc_condition_variable.cpp
+++ b/src/core/hle/kernel/svc/svc_condition_variable.cpp
@@ -43,14 +43,8 @@ Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_ke
43 } 43 }
44 44
45 // Wait on the condition variable. 45 // Wait on the condition variable.
46 return system.Kernel().CurrentProcess()->WaitConditionVariable( 46 return GetCurrentProcess(system.Kernel())
47 address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout); 47 .WaitConditionVariable(address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout);
48}
49
50Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag,
51 u32 timeout_ns_low, u32 timeout_ns_high) {
52 const auto timeout_ns = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32));
53 return WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns);
54} 48}
55 49
56/// Signal process wide key 50/// Signal process wide key
@@ -58,11 +52,25 @@ void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) {
58 LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count); 52 LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);
59 53
60 // Signal the condition variable. 54 // Signal the condition variable.
61 return system.Kernel().CurrentProcess()->SignalConditionVariable( 55 return GetCurrentProcess(system.Kernel())
62 Common::AlignDown(cv_key, sizeof(u32)), count); 56 .SignalConditionVariable(Common::AlignDown(cv_key, sizeof(u32)), count);
57}
58
59Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key,
60 uint32_t tag, int64_t timeout_ns) {
61 R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
62}
63
64void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count) {
65 SignalProcessWideKey(system, cv_key, count);
66}
67
68Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key,
69 uint32_t tag, int64_t timeout_ns) {
70 R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
63} 71}
64 72
65void SignalProcessWideKey32(Core::System& system, u32 cv_key, s32 count) { 73void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count) {
66 SignalProcessWideKey(system, cv_key, count); 74 SignalProcessWideKey(system, cv_key, count);
67} 75}
68 76
diff --git a/src/core/hle/kernel/svc/svc_debug.cpp b/src/core/hle/kernel/svc/svc_debug.cpp
index 299e22ae6..a14050fa7 100644
--- a/src/core/hle/kernel/svc/svc_debug.cpp
+++ b/src/core/hle/kernel/svc/svc_debug.cpp
@@ -2,5 +2,193 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id) {
10 UNIMPLEMENTED();
11 R_THROW(ResultNotImplemented);
12}
13
14Result BreakDebugProcess(Core::System& system, Handle debug_handle) {
15 UNIMPLEMENTED();
16 R_THROW(ResultNotImplemented);
17}
18
19Result TerminateDebugProcess(Core::System& system, Handle debug_handle) {
20 UNIMPLEMENTED();
21 R_THROW(ResultNotImplemented);
22}
23
24Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle) {
25 UNIMPLEMENTED();
26 R_THROW(ResultNotImplemented);
27}
28
29Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags,
30 uint64_t user_thread_ids, int32_t num_thread_ids) {
31 UNIMPLEMENTED();
32 R_THROW(ResultNotImplemented);
33}
34
35Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle,
36 uint64_t thread_id, uint32_t context_flags) {
37 UNIMPLEMENTED();
38 R_THROW(ResultNotImplemented);
39}
40
41Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id,
42 uint64_t user_context, uint32_t context_flags) {
43 UNIMPLEMENTED();
44 R_THROW(ResultNotImplemented);
45}
46
47Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info,
48 PageInfo* out_page_info, Handle debug_handle, uintptr_t address) {
49 UNIMPLEMENTED();
50 R_THROW(ResultNotImplemented);
51}
52
53Result ReadDebugProcessMemory(Core::System& system, uintptr_t buffer, Handle debug_handle,
54 uintptr_t address, size_t size) {
55 UNIMPLEMENTED();
56 R_THROW(ResultNotImplemented);
57}
58
59Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uintptr_t buffer,
60 uintptr_t address, size_t size) {
61 UNIMPLEMENTED();
62 R_THROW(ResultNotImplemented);
63}
64
65Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name,
66 uint64_t flags, uint64_t value) {
67 UNIMPLEMENTED();
68 R_THROW(ResultNotImplemented);
69}
70
71Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32,
72 Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
73 UNIMPLEMENTED();
74 R_THROW(ResultNotImplemented);
75}
76
77Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id) {
78 R_RETURN(DebugActiveProcess(system, out_handle, process_id));
79}
80
81Result BreakDebugProcess64(Core::System& system, Handle debug_handle) {
82 R_RETURN(BreakDebugProcess(system, debug_handle));
83}
84
85Result TerminateDebugProcess64(Core::System& system, Handle debug_handle) {
86 R_RETURN(TerminateDebugProcess(system, debug_handle));
87}
88
89Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle) {
90 R_RETURN(GetDebugEvent(system, out_info, debug_handle));
91}
92
93Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags,
94 uint64_t thread_ids, int32_t num_thread_ids) {
95 R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
96}
97
98Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle,
99 uint64_t thread_id, uint32_t context_flags) {
100 R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
101}
102
103Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id,
104 uint64_t context, uint32_t context_flags) {
105 R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
106}
107
108Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info,
109 PageInfo* out_page_info, Handle debug_handle, uint64_t address) {
110 R_RETURN(
111 QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
112}
113
114Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle,
115 uint64_t address, uint64_t size) {
116 R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
117}
118
119Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer,
120 uint64_t address, uint64_t size) {
121 R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
122}
123
124Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name,
125 uint64_t flags, uint64_t value) {
126 R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
127}
128
129Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32,
130 Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
131 R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
132}
133
134Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id) {
135 R_RETURN(DebugActiveProcess(system, out_handle, process_id));
136}
137
138Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle) {
139 R_RETURN(BreakDebugProcess(system, debug_handle));
140}
141
142Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle) {
143 R_RETURN(TerminateDebugProcess(system, debug_handle));
144}
145
146Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle) {
147 R_RETURN(GetDebugEvent(system, out_info, debug_handle));
148}
149
150Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags,
151 uint32_t thread_ids, int32_t num_thread_ids) {
152 R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
153}
154
155Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context,
156 Handle debug_handle, uint64_t thread_id,
157 uint32_t context_flags) {
158 R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
159}
160
161Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id,
162 uint32_t context, uint32_t context_flags) {
163 R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
164}
165
166Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info,
167 PageInfo* out_page_info, Handle debug_handle,
168 uint32_t address) {
169 R_RETURN(
170 QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
171}
172
173Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle,
174 uint32_t address, uint32_t size) {
175 R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
176}
177
178Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer,
179 uint32_t address, uint32_t size) {
180 R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
181}
182
183Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name,
184 uint64_t flags, uint64_t value) {
185 R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
186}
187
188Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32,
189 Handle debug_handle, uint64_t thread_id,
190 DebugThreadParam param) {
191 R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
192}
193
194} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_debug_string.cpp b/src/core/hle/kernel/svc/svc_debug_string.cpp
index 486e62cc4..d4bf062d1 100644
--- a/src/core/hle/kernel/svc/svc_debug_string.cpp
+++ b/src/core/hle/kernel/svc/svc_debug_string.cpp
@@ -8,18 +8,22 @@
8namespace Kernel::Svc { 8namespace Kernel::Svc {
9 9
10/// Used to output a message on a debug hardware unit - does nothing on a retail unit 10/// Used to output a message on a debug hardware unit - does nothing on a retail unit
11void OutputDebugString(Core::System& system, VAddr address, u64 len) { 11Result OutputDebugString(Core::System& system, VAddr address, u64 len) {
12 if (len == 0) { 12 R_SUCCEED_IF(len == 0);
13 return;
14 }
15 13
16 std::string str(len, '\0'); 14 std::string str(len, '\0');
17 system.Memory().ReadBlock(address, str.data(), str.size()); 15 system.Memory().ReadBlock(address, str.data(), str.size());
18 LOG_DEBUG(Debug_Emulated, "{}", str); 16 LOG_DEBUG(Debug_Emulated, "{}", str);
17
18 R_SUCCEED();
19}
20
21Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len) {
22 R_RETURN(OutputDebugString(system, debug_str, len));
19} 23}
20 24
21void OutputDebugString32(Core::System& system, u32 address, u32 len) { 25Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len) {
22 OutputDebugString(system, address, len); 26 R_RETURN(OutputDebugString(system, debug_str, len));
23} 27}
24 28
25} // namespace Kernel::Svc 29} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_device_address_space.cpp b/src/core/hle/kernel/svc/svc_device_address_space.cpp
index 299e22ae6..f68c0e6a9 100644
--- a/src/core/hle/kernel/svc/svc_device_address_space.cpp
+++ b/src/core/hle/kernel/svc/svc_device_address_space.cpp
@@ -1,6 +1,258 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/alignment.h"
5#include "common/scope_exit.h"
6#include "core/core.h"
7#include "core/hle/kernel/k_device_address_space.h"
8#include "core/hle/kernel/k_process.h"
4#include "core/hle/kernel/svc.h" 9#include "core/hle/kernel/svc.h"
5 10
6namespace Kernel::Svc {} // namespace Kernel::Svc 11namespace Kernel::Svc {
12
13constexpr inline u64 DeviceAddressSpaceAlignMask = (1ULL << 22) - 1;
14
15constexpr bool IsProcessAndDeviceAligned(uint64_t process_address, uint64_t device_address) {
16 return (process_address & DeviceAddressSpaceAlignMask) ==
17 (device_address & DeviceAddressSpaceAlignMask);
18}
19
20Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_address,
21 uint64_t das_size) {
22 // Validate input.
23 R_UNLESS(Common::IsAligned(das_address, PageSize), ResultInvalidMemoryRegion);
24 R_UNLESS(Common::IsAligned(das_size, PageSize), ResultInvalidMemoryRegion);
25 R_UNLESS(das_size > 0, ResultInvalidMemoryRegion);
26 R_UNLESS((das_address < das_address + das_size), ResultInvalidMemoryRegion);
27
28 // Create the device address space.
29 KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel());
30 R_UNLESS(das != nullptr, ResultOutOfResource);
31 SCOPE_EXIT({ das->Close(); });
32
33 // Initialize the device address space.
34 R_TRY(das->Initialize(das_address, das_size));
35
36 // Register the device address space.
37 KDeviceAddressSpace::Register(system.Kernel(), das);
38
39 // Add to the handle table.
40 R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, das));
41
42 R_SUCCEED();
43}
44
45Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
46 // Get the device address space.
47 KScopedAutoObject das = GetCurrentProcess(system.Kernel())
48 .GetHandleTable()
49 .GetObject<KDeviceAddressSpace>(das_handle);
50 R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
51
52 // Attach.
53 R_RETURN(das->Attach(device_name));
54}
55
56Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
57 // Get the device address space.
58 KScopedAutoObject das = GetCurrentProcess(system.Kernel())
59 .GetHandleTable()
60 .GetObject<KDeviceAddressSpace>(das_handle);
61 R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
62
63 // Detach.
64 R_RETURN(das->Detach(device_name));
65}
66
67constexpr bool IsValidDeviceMemoryPermission(MemoryPermission device_perm) {
68 switch (device_perm) {
69 case MemoryPermission::Read:
70 case MemoryPermission::Write:
71 case MemoryPermission::ReadWrite:
72 return true;
73 default:
74 return false;
75 }
76}
77
78Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle,
79 uint64_t process_address, size_t size, uint64_t device_address,
80 u32 option) {
81 // Decode the option.
82 const MapDeviceAddressSpaceOption option_pack{option};
83 const auto device_perm = option_pack.permission;
84 const auto reserved = option_pack.reserved;
85
86 // Validate input.
87 R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
88 R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
89 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
90 R_UNLESS(size > 0, ResultInvalidSize);
91 R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
92 R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
93 R_UNLESS((process_address == static_cast<uintptr_t>(process_address)),
94 ResultInvalidCurrentMemory);
95 R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
96 R_UNLESS(reserved == 0, ResultInvalidEnumValue);
97
98 // Get the device address space.
99 KScopedAutoObject das = GetCurrentProcess(system.Kernel())
100 .GetHandleTable()
101 .GetObject<KDeviceAddressSpace>(das_handle);
102 R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
103
104 // Get the process.
105 KScopedAutoObject process =
106 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
107 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
108
109 // Validate that the process address is within range.
110 auto& page_table = process->PageTable();
111 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
112
113 // Map.
114 R_RETURN(
115 das->MapByForce(std::addressof(page_table), process_address, size, device_address, option));
116}
117
118Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle,
119 uint64_t process_address, size_t size, uint64_t device_address,
120 u32 option) {
121 // Decode the option.
122 const MapDeviceAddressSpaceOption option_pack{option};
123 const auto device_perm = option_pack.permission;
124 const auto reserved = option_pack.reserved;
125
126 // Validate input.
127 R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
128 R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
129 R_UNLESS(IsProcessAndDeviceAligned(process_address, device_address), ResultInvalidAddress);
130 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
131 R_UNLESS(size > 0, ResultInvalidSize);
132 R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
133 R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
134 R_UNLESS((process_address == static_cast<uintptr_t>(process_address)),
135 ResultInvalidCurrentMemory);
136 R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
137 R_UNLESS(reserved == 0, ResultInvalidEnumValue);
138
139 // Get the device address space.
140 KScopedAutoObject das = GetCurrentProcess(system.Kernel())
141 .GetHandleTable()
142 .GetObject<KDeviceAddressSpace>(das_handle);
143 R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
144
145 // Get the process.
146 KScopedAutoObject process =
147 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
148 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
149
150 // Validate that the process address is within range.
151 auto& page_table = process->PageTable();
152 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
153
154 // Map.
155 R_RETURN(
156 das->MapAligned(std::addressof(page_table), process_address, size, device_address, option));
157}
158
159Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle,
160 uint64_t process_address, size_t size, uint64_t device_address) {
161 // Validate input.
162 R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
163 R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
164 R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
165 R_UNLESS(size > 0, ResultInvalidSize);
166 R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
167 R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
168 R_UNLESS((process_address == static_cast<uintptr_t>(process_address)),
169 ResultInvalidCurrentMemory);
170
171 // Get the device address space.
172 KScopedAutoObject das = GetCurrentProcess(system.Kernel())
173 .GetHandleTable()
174 .GetObject<KDeviceAddressSpace>(das_handle);
175 R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
176
177 // Get the process.
178 KScopedAutoObject process =
179 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
180 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
181
182 // Validate that the process address is within range.
183 auto& page_table = process->PageTable();
184 R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
185
186 R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address));
187}
188
189Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address,
190 uint64_t das_size) {
191 R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size));
192}
193
194Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) {
195 R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle));
196}
197
198Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) {
199 R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle));
200}
201
202Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle,
203 Handle process_handle, uint64_t process_address,
204 uint64_t size, uint64_t device_address, u32 option) {
205 R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size,
206 device_address, option));
207}
208
209Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle,
210 Handle process_handle, uint64_t process_address,
211 uint64_t size, uint64_t device_address, u32 option) {
212 R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size,
213 device_address, option));
214}
215
216Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle,
217 uint64_t process_address, uint64_t size, uint64_t device_address) {
218 R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size,
219 device_address));
220}
221
222Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle,
223 uint64_t das_address, uint64_t das_size) {
224 R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size));
225}
226
227Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name,
228 Handle das_handle) {
229 R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle));
230}
231
232Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name,
233 Handle das_handle) {
234 R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle));
235}
236
237Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle,
238 Handle process_handle, uint64_t process_address,
239 uint32_t size, uint64_t device_address, u32 option) {
240 R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size,
241 device_address, option));
242}
243
244Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle,
245 Handle process_handle, uint64_t process_address,
246 uint32_t size, uint64_t device_address, u32 option) {
247 R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size,
248 device_address, option));
249}
250
251Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle,
252 Handle process_handle, uint64_t process_address,
253 uint32_t size, uint64_t device_address) {
254 R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size,
255 device_address));
256}
257
258} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_event.cpp b/src/core/hle/kernel/svc/svc_event.cpp
index 885f02f50..a948493e8 100644
--- a/src/core/hle/kernel/svc/svc_event.cpp
+++ b/src/core/hle/kernel/svc/svc_event.cpp
@@ -15,7 +15,7 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
15 LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); 15 LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
16 16
17 // Get the current handle table. 17 // Get the current handle table.
18 const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 18 const KHandleTable& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
19 19
20 // Get the event. 20 // Get the event.
21 KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle); 21 KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
@@ -24,15 +24,11 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
24 return event->Signal(); 24 return event->Signal();
25} 25}
26 26
27Result SignalEvent32(Core::System& system, Handle event_handle) {
28 return SignalEvent(system, event_handle);
29}
30
31Result ClearEvent(Core::System& system, Handle event_handle) { 27Result ClearEvent(Core::System& system, Handle event_handle) {
32 LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); 28 LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
33 29
34 // Get the current handle table. 30 // Get the current handle table.
35 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 31 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
36 32
37 // Try to clear the writable event. 33 // Try to clear the writable event.
38 { 34 {
@@ -55,19 +51,15 @@ Result ClearEvent(Core::System& system, Handle event_handle) {
55 return ResultInvalidHandle; 51 return ResultInvalidHandle;
56} 52}
57 53
58Result ClearEvent32(Core::System& system, Handle event_handle) {
59 return ClearEvent(system, event_handle);
60}
61
62Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { 54Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
63 LOG_DEBUG(Kernel_SVC, "called"); 55 LOG_DEBUG(Kernel_SVC, "called");
64 56
65 // Get the kernel reference and handle table. 57 // Get the kernel reference and handle table.
66 auto& kernel = system.Kernel(); 58 auto& kernel = system.Kernel();
67 auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 59 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
68 60
69 // Reserve a new event from the process resource limit 61 // Reserve a new event from the process resource limit
70 KScopedResourceReservation event_reservation(kernel.CurrentProcess(), 62 KScopedResourceReservation event_reservation(GetCurrentProcessPointer(kernel),
71 LimitableResource::EventCountMax); 63 LimitableResource::EventCountMax);
72 R_UNLESS(event_reservation.Succeeded(), ResultLimitReached); 64 R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);
73 65
@@ -76,7 +68,7 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
76 R_UNLESS(event != nullptr, ResultOutOfResource); 68 R_UNLESS(event != nullptr, ResultOutOfResource);
77 69
78 // Initialize the event. 70 // Initialize the event.
79 event->Initialize(kernel.CurrentProcess()); 71 event->Initialize(GetCurrentProcessPointer(kernel));
80 72
81 // Commit the thread reservation. 73 // Commit the thread reservation.
82 event_reservation.Commit(); 74 event_reservation.Commit();
@@ -104,8 +96,29 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
104 return ResultSuccess; 96 return ResultSuccess;
105} 97}
106 98
107Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { 99Result SignalEvent64(Core::System& system, Handle event_handle) {
108 return CreateEvent(system, out_write, out_read); 100 R_RETURN(SignalEvent(system, event_handle));
101}
102
103Result ClearEvent64(Core::System& system, Handle event_handle) {
104 R_RETURN(ClearEvent(system, event_handle));
105}
106
107Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle) {
108 R_RETURN(CreateEvent(system, out_write_handle, out_read_handle));
109}
110
111Result SignalEvent64From32(Core::System& system, Handle event_handle) {
112 R_RETURN(SignalEvent(system, event_handle));
113}
114
115Result ClearEvent64From32(Core::System& system, Handle event_handle) {
116 R_RETURN(ClearEvent(system, event_handle));
117}
118
119Result CreateEvent64From32(Core::System& system, Handle* out_write_handle,
120 Handle* out_read_handle) {
121 R_RETURN(CreateEvent(system, out_write_handle, out_read_handle));
109} 122}
110 123
111} // namespace Kernel::Svc 124} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp
index fb9f133c1..c2782908d 100644
--- a/src/core/hle/kernel/svc/svc_exception.cpp
+++ b/src/core/hle/kernel/svc/svc_exception.cpp
@@ -12,10 +12,10 @@
12namespace Kernel::Svc { 12namespace Kernel::Svc {
13 13
14/// Break program execution 14/// Break program execution
15void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { 15void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
16 BreakReason break_reason = 16 BreakReason break_reason =
17 static_cast<BreakReason>(reason & ~static_cast<u32>(BreakReason::NotificationOnlyFlag)); 17 reason & static_cast<BreakReason>(~BreakReason::NotificationOnlyFlag);
18 bool notification_only = (reason & static_cast<u32>(BreakReason::NotificationOnlyFlag)) != 0; 18 bool notification_only = True(reason & BreakReason::NotificationOnlyFlag);
19 19
20 bool has_dumped_buffer{}; 20 bool has_dumped_buffer{};
21 std::vector<u8> debug_buffer; 21 std::vector<u8> debug_buffer;
@@ -90,9 +90,9 @@ void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
90 break; 90 break;
91 } 91 }
92 92
93 system.GetReporter().SaveSvcBreakReport(reason, notification_only, info1, info2, 93 system.GetReporter().SaveSvcBreakReport(
94 has_dumped_buffer ? std::make_optional(debug_buffer) 94 static_cast<u32>(reason), notification_only, info1, info2,
95 : std::nullopt); 95 has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
96 96
97 if (!notification_only) { 97 if (!notification_only) {
98 LOG_CRITICAL( 98 LOG_CRITICAL(
@@ -114,8 +114,24 @@ void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
114 } 114 }
115} 115}
116 116
117void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { 117void ReturnFromException(Core::System& system, Result result) {
118 Break(system, reason, info1, info2); 118 UNIMPLEMENTED();
119}
120
121void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size) {
122 Break(system, break_reason, arg, size);
123}
124
125void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size) {
126 Break(system, break_reason, arg, size);
127}
128
129void ReturnFromException64(Core::System& system, Result result) {
130 ReturnFromException(system, result);
131}
132
133void ReturnFromException64From32(Core::System& system, Result result) {
134 ReturnFromException(system, result);
119} 135}
120 136
121} // namespace Kernel::Svc 137} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index df5dd85a4..58dc47508 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -10,11 +10,12 @@
10namespace Kernel::Svc { 10namespace Kernel::Svc {
11 11
12/// Gets system/memory information for the current process 12/// Gets system/memory information for the current process
13Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u64 info_sub_id) { 13Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle handle,
14 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, 14 u64 info_sub_id) {
15 info_sub_id, handle); 15 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}",
16 info_id_type, info_sub_id, handle);
16 17
17 const auto info_id_type = static_cast<InfoType>(info_id); 18 u32 info_id = static_cast<u32>(info_id_type);
18 19
19 switch (info_id_type) { 20 switch (info_id_type) {
20 case InfoType::CoreMask: 21 case InfoType::CoreMask:
@@ -43,7 +44,7 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6
43 return ResultInvalidEnumValue; 44 return ResultInvalidEnumValue;
44 } 45 }
45 46
46 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 47 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
47 KScopedAutoObject process = handle_table.GetObject<KProcess>(handle); 48 KScopedAutoObject process = handle_table.GetObject<KProcess>(handle);
48 if (process.IsNull()) { 49 if (process.IsNull()) {
49 LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}", 50 LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}",
@@ -153,7 +154,7 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6
153 return ResultInvalidCombination; 154 return ResultInvalidCombination;
154 } 155 }
155 156
156 KProcess* const current_process = system.Kernel().CurrentProcess(); 157 KProcess* const current_process = GetCurrentProcessPointer(system.Kernel());
157 KHandleTable& handle_table = current_process->GetHandleTable(); 158 KHandleTable& handle_table = current_process->GetHandleTable();
158 const auto resource_limit = current_process->GetResourceLimit(); 159 const auto resource_limit = current_process->GetResourceLimit();
159 if (!resource_limit) { 160 if (!resource_limit) {
@@ -182,7 +183,7 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6
182 return ResultInvalidCombination; 183 return ResultInvalidCombination;
183 } 184 }
184 185
185 *result = system.Kernel().CurrentProcess()->GetRandomEntropy(info_sub_id); 186 *result = GetCurrentProcess(system.Kernel()).GetRandomEntropy(info_sub_id);
186 return ResultSuccess; 187 return ResultSuccess;
187 188
188 case InfoType::InitialProcessIdRange: 189 case InfoType::InitialProcessIdRange:
@@ -199,9 +200,9 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6
199 return ResultInvalidCombination; 200 return ResultInvalidCombination;
200 } 201 }
201 202
202 KScopedAutoObject thread = 203 KScopedAutoObject thread = GetCurrentProcess(system.Kernel())
203 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>( 204 .GetHandleTable()
204 static_cast<Handle>(handle)); 205 .GetObject<KThread>(static_cast<Handle>(handle));
205 if (thread.IsNull()) { 206 if (thread.IsNull()) {
206 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", 207 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
207 static_cast<Handle>(handle)); 208 static_cast<Handle>(handle));
@@ -248,7 +249,7 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6
248 R_UNLESS(info_sub_id == 0, ResultInvalidCombination); 249 R_UNLESS(info_sub_id == 0, ResultInvalidCombination);
249 250
250 // Get the handle table. 251 // Get the handle table.
251 KProcess* current_process = system.Kernel().CurrentProcess(); 252 KProcess* current_process = GetCurrentProcessPointer(system.Kernel());
252 KHandleTable& handle_table = current_process->GetHandleTable(); 253 KHandleTable& handle_table = current_process->GetHandleTable();
253 254
254 // Get a new handle for the current process. 255 // Get a new handle for the current process.
@@ -267,16 +268,30 @@ Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u6
267 } 268 }
268} 269}
269 270
270Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, 271Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle,
271 u32 info_id, u32 handle, u32 sub_id_high) { 272 uint64_t info_subtype) {
272 const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)}; 273 UNIMPLEMENTED();
273 u64 res_value{}; 274 R_THROW(ResultNotImplemented);
275}
276
277Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle,
278 uint64_t info_subtype) {
279 R_RETURN(GetInfo(system, out, info_type, handle, info_subtype));
280}
274 281
275 const Result result{GetInfo(system, &res_value, info_id, handle, sub_id)}; 282Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle,
276 *result_high = static_cast<u32>(res_value >> 32); 283 uint64_t info_subtype) {
277 *result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max()); 284 R_RETURN(GetSystemInfo(system, out, info_type, handle, info_subtype));
285}
286
287Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle,
288 uint64_t info_subtype) {
289 R_RETURN(GetInfo(system, out, info_type, handle, info_subtype));
290}
278 291
279 return result; 292Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type,
293 Handle handle, uint64_t info_subtype) {
294 R_RETURN(GetSystemInfo(system, out, info_type, handle, info_subtype));
280} 295}
281 296
282} // namespace Kernel::Svc 297} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_insecure_memory.cpp b/src/core/hle/kernel/svc/svc_insecure_memory.cpp
new file mode 100644
index 000000000..79882685d
--- /dev/null
+++ b/src/core/hle/kernel/svc/svc_insecure_memory.cpp
@@ -0,0 +1,35 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
6
7namespace Kernel::Svc {
8
9Result MapInsecureMemory(Core::System& system, uintptr_t address, size_t size) {
10 UNIMPLEMENTED();
11 R_THROW(ResultNotImplemented);
12}
13
14Result UnmapInsecureMemory(Core::System& system, uintptr_t address, size_t size) {
15 UNIMPLEMENTED();
16 R_THROW(ResultNotImplemented);
17}
18
19Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size) {
20 R_RETURN(MapInsecureMemory(system, address, size));
21}
22
23Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size) {
24 R_RETURN(UnmapInsecureMemory(system, address, size));
25}
26
27Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
28 R_RETURN(MapInsecureMemory(system, address, size));
29}
30
31Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
32 R_RETURN(UnmapInsecureMemory(system, address, size));
33}
34
35} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_interrupt_event.cpp b/src/core/hle/kernel/svc/svc_interrupt_event.cpp
index 299e22ae6..768b30a1f 100644
--- a/src/core/hle/kernel/svc/svc_interrupt_event.cpp
+++ b/src/core/hle/kernel/svc/svc_interrupt_event.cpp
@@ -2,5 +2,24 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9Result CreateInterruptEvent(Core::System& system, Handle* out, int32_t interrupt_id,
10 InterruptType type) {
11 UNIMPLEMENTED();
12 R_THROW(ResultNotImplemented);
13}
14
15Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id,
16 InterruptType interrupt_type) {
17 R_RETURN(CreateInterruptEvent(system, out_read_handle, interrupt_id, interrupt_type));
18}
19
20Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle,
21 int32_t interrupt_id, InterruptType interrupt_type) {
22 R_RETURN(CreateInterruptEvent(system, out_read_handle, interrupt_id, interrupt_type));
23}
24
25} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_io_pool.cpp b/src/core/hle/kernel/svc/svc_io_pool.cpp
index 299e22ae6..33f3d69bf 100644
--- a/src/core/hle/kernel/svc/svc_io_pool.cpp
+++ b/src/core/hle/kernel/svc/svc_io_pool.cpp
@@ -2,5 +2,70 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9Result CreateIoPool(Core::System& system, Handle* out, IoPoolType pool_type) {
10 UNIMPLEMENTED();
11 R_THROW(ResultNotImplemented);
12}
13
14Result CreateIoRegion(Core::System& system, Handle* out, Handle io_pool_handle, uint64_t phys_addr,
15 size_t size, MemoryMapping mapping, MemoryPermission perm) {
16 UNIMPLEMENTED();
17 R_THROW(ResultNotImplemented);
18}
19
20Result MapIoRegion(Core::System& system, Handle io_region_handle, uintptr_t address, size_t size,
21 MemoryPermission map_perm) {
22 UNIMPLEMENTED();
23 R_THROW(ResultNotImplemented);
24}
25
26Result UnmapIoRegion(Core::System& system, Handle io_region_handle, uintptr_t address,
27 size_t size) {
28 UNIMPLEMENTED();
29 R_THROW(ResultNotImplemented);
30}
31
32Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType pool_type) {
33 R_RETURN(CreateIoPool(system, out_handle, pool_type));
34}
35
36Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool,
37 uint64_t physical_address, uint64_t size, MemoryMapping mapping,
38 MemoryPermission perm) {
39 R_RETURN(CreateIoRegion(system, out_handle, io_pool, physical_address, size, mapping, perm));
40}
41
42Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size,
43 MemoryPermission perm) {
44 R_RETURN(MapIoRegion(system, io_region, address, size, perm));
45}
46
47Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size) {
48 R_RETURN(UnmapIoRegion(system, io_region, address, size));
49}
50
51Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType pool_type) {
52 R_RETURN(CreateIoPool(system, out_handle, pool_type));
53}
54
55Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool,
56 uint64_t physical_address, uint32_t size, MemoryMapping mapping,
57 MemoryPermission perm) {
58 R_RETURN(CreateIoRegion(system, out_handle, io_pool, physical_address, size, mapping, perm));
59}
60
61Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size,
62 MemoryPermission perm) {
63 R_RETURN(MapIoRegion(system, io_region, address, size, perm));
64}
65
66Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address,
67 uint32_t size) {
68 R_RETURN(UnmapIoRegion(system, io_region, address, size));
69}
70
71} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp
index dbb68e89a..a7a2c3b92 100644
--- a/src/core/hle/kernel/svc/svc_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_ipc.cpp
@@ -12,11 +12,9 @@ namespace Kernel::Svc {
12 12
13/// Makes a blocking IPC call to a service. 13/// Makes a blocking IPC call to a service.
14Result SendSyncRequest(Core::System& system, Handle handle) { 14Result SendSyncRequest(Core::System& system, Handle handle) {
15 auto& kernel = system.Kernel();
16
17 // Get the client session from its handle. 15 // Get the client session from its handle.
18 KScopedAutoObject session = 16 KScopedAutoObject session =
19 kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle); 17 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KClientSession>(handle);
20 R_UNLESS(session.IsNotNull(), ResultInvalidHandle); 18 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
21 19
22 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 20 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
@@ -24,20 +22,37 @@ Result SendSyncRequest(Core::System& system, Handle handle) {
24 return session->SendSyncRequest(); 22 return session->SendSyncRequest();
25} 23}
26 24
27Result SendSyncRequest32(Core::System& system, Handle handle) { 25Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer,
28 return SendSyncRequest(system, handle); 26 uint64_t message_buffer_size, Handle session_handle) {
27 UNIMPLEMENTED();
28 R_THROW(ResultNotImplemented);
29}
30
31Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle,
32 uint64_t message_buffer, uint64_t message_buffer_size,
33 Handle session_handle) {
34 UNIMPLEMENTED();
35 R_THROW(ResultNotImplemented);
29} 36}
30 37
31Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s32 num_handles, 38Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_addr, s32 num_handles,
32 Handle reply_target, s64 timeout_ns) { 39 Handle reply_target, s64 timeout_ns) {
33 auto& kernel = system.Kernel(); 40 auto& kernel = system.Kernel();
34 auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable(); 41 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
42
43 R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange);
44 R_UNLESS(system.Memory().IsValidVirtualAddressRange(
45 handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
46 ResultInvalidPointer);
47
48 std::vector<Handle> handles(num_handles);
49 system.Memory().ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
35 50
36 // Convert handle list to object table. 51 // Convert handle list to object table.
37 std::vector<KSynchronizationObject*> objs(num_handles); 52 std::vector<KSynchronizationObject*> objs(num_handles);
38 R_UNLESS( 53 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(),
39 handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles), 54 num_handles),
40 ResultInvalidHandle); 55 ResultInvalidHandle);
41 56
42 // Ensure handles are closed when we're done. 57 // Ensure handles are closed when we're done.
43 SCOPE_EXIT({ 58 SCOPE_EXIT({
@@ -86,4 +101,72 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s3
86 } 101 }
87} 102}
88 103
104Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index,
105 uint64_t message_buffer, uint64_t message_buffer_size,
106 uint64_t handles, int32_t num_handles, Handle reply_target,
107 int64_t timeout_ns) {
108 UNIMPLEMENTED();
109 R_THROW(ResultNotImplemented);
110}
111
112Result SendSyncRequest64(Core::System& system, Handle session_handle) {
113 R_RETURN(SendSyncRequest(system, session_handle));
114}
115
116Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer,
117 uint64_t message_buffer_size, Handle session_handle) {
118 R_RETURN(
119 SendSyncRequestWithUserBuffer(system, message_buffer, message_buffer_size, session_handle));
120}
121
122Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle,
123 uint64_t message_buffer, uint64_t message_buffer_size,
124 Handle session_handle) {
125 R_RETURN(SendAsyncRequestWithUserBuffer(system, out_event_handle, message_buffer,
126 message_buffer_size, session_handle));
127}
128
129Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles,
130 int32_t num_handles, Handle reply_target, int64_t timeout_ns) {
131 R_RETURN(ReplyAndReceive(system, out_index, handles, num_handles, reply_target, timeout_ns));
132}
133
134Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index,
135 uint64_t message_buffer, uint64_t message_buffer_size,
136 uint64_t handles, int32_t num_handles, Handle reply_target,
137 int64_t timeout_ns) {
138 R_RETURN(ReplyAndReceiveWithUserBuffer(system, out_index, message_buffer, message_buffer_size,
139 handles, num_handles, reply_target, timeout_ns));
140}
141
142Result SendSyncRequest64From32(Core::System& system, Handle session_handle) {
143 R_RETURN(SendSyncRequest(system, session_handle));
144}
145
146Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer,
147 uint32_t message_buffer_size, Handle session_handle) {
148 R_RETURN(
149 SendSyncRequestWithUserBuffer(system, message_buffer, message_buffer_size, session_handle));
150}
151
152Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle,
153 uint32_t message_buffer, uint32_t message_buffer_size,
154 Handle session_handle) {
155 R_RETURN(SendAsyncRequestWithUserBuffer(system, out_event_handle, message_buffer,
156 message_buffer_size, session_handle));
157}
158
159Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles,
160 int32_t num_handles, Handle reply_target, int64_t timeout_ns) {
161 R_RETURN(ReplyAndReceive(system, out_index, handles, num_handles, reply_target, timeout_ns));
162}
163
164Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index,
165 uint32_t message_buffer, uint32_t message_buffer_size,
166 uint32_t handles, int32_t num_handles,
167 Handle reply_target, int64_t timeout_ns) {
168 R_RETURN(ReplyAndReceiveWithUserBuffer(system, out_index, message_buffer, message_buffer_size,
169 handles, num_handles, reply_target, timeout_ns));
170}
171
89} // namespace Kernel::Svc 172} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_kernel_debug.cpp b/src/core/hle/kernel/svc/svc_kernel_debug.cpp
index 454255e7a..cee048279 100644
--- a/src/core/hle/kernel/svc/svc_kernel_debug.cpp
+++ b/src/core/hle/kernel/svc/svc_kernel_debug.cpp
@@ -5,15 +5,31 @@
5 5
6namespace Kernel::Svc { 6namespace Kernel::Svc {
7 7
8void KernelDebug([[maybe_unused]] Core::System& system, [[maybe_unused]] u32 kernel_debug_type, 8void KernelDebug(Core::System& system, KernelDebugType kernel_debug_type, u64 arg0, u64 arg1,
9 [[maybe_unused]] u64 param1, [[maybe_unused]] u64 param2, 9 u64 arg2) {
10 [[maybe_unused]] u64 param3) {
11 // Intentionally do nothing, as this does nothing in released kernel binaries. 10 // Intentionally do nothing, as this does nothing in released kernel binaries.
12} 11}
13 12
14void ChangeKernelTraceState([[maybe_unused]] Core::System& system, 13void ChangeKernelTraceState(Core::System& system, KernelTraceState trace_state) {
15 [[maybe_unused]] u32 trace_state) {
16 // Intentionally do nothing, as this does nothing in released kernel binaries. 14 // Intentionally do nothing, as this does nothing in released kernel binaries.
17} 15}
18 16
17void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0,
18 uint64_t arg1, uint64_t arg2) {
19 KernelDebug(system, kern_debug_type, arg0, arg1, arg2);
20}
21
22void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state) {
23 ChangeKernelTraceState(system, kern_trace_state);
24}
25
26void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0,
27 uint64_t arg1, uint64_t arg2) {
28 KernelDebug(system, kern_debug_type, arg0, arg1, arg2);
29}
30
31void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state) {
32 ChangeKernelTraceState(system, kern_trace_state);
33}
34
19} // namespace Kernel::Svc 35} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_light_ipc.cpp b/src/core/hle/kernel/svc/svc_light_ipc.cpp
index 299e22ae6..b76ce984c 100644
--- a/src/core/hle/kernel/svc/svc_light_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_light_ipc.cpp
@@ -1,6 +1,73 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/arm/arm_interface.h"
5#include "core/core.h"
4#include "core/hle/kernel/svc.h" 6#include "core/hle/kernel/svc.h"
7#include "core/hle/kernel/svc_results.h"
5 8
6namespace Kernel::Svc {} // namespace Kernel::Svc 9namespace Kernel::Svc {
10
11Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) {
12 UNIMPLEMENTED();
13 R_THROW(ResultNotImplemented);
14}
15
16Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) {
17 UNIMPLEMENTED();
18 R_THROW(ResultNotImplemented);
19}
20
21Result SendSyncRequestLight64(Core::System& system, Handle session_handle, u32* args) {
22 R_RETURN(SendSyncRequestLight(system, session_handle, args));
23}
24
25Result ReplyAndReceiveLight64(Core::System& system, Handle session_handle, u32* args) {
26 R_RETURN(ReplyAndReceiveLight(system, session_handle, args));
27}
28
29Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, u32* args) {
30 R_RETURN(SendSyncRequestLight(system, session_handle, args));
31}
32
33Result ReplyAndReceiveLight64From32(Core::System& system, Handle session_handle, u32* args) {
34 R_RETURN(ReplyAndReceiveLight(system, session_handle, args));
35}
36
37// Custom ABI implementation for light IPC.
38
39template <typename F>
40static void SvcWrap_LightIpc(Core::System& system, F&& cb) {
41 auto& core = system.CurrentArmInterface();
42 std::array<u32, 7> arguments{};
43
44 Handle session_handle = static_cast<Handle>(core.GetReg(0));
45 for (int i = 0; i < 7; i++) {
46 arguments[i] = static_cast<u32>(core.GetReg(i + 1));
47 }
48
49 Result ret = cb(system, session_handle, arguments.data());
50
51 core.SetReg(0, ret.raw);
52 for (int i = 0; i < 7; i++) {
53 core.SetReg(i + 1, arguments[i]);
54 }
55}
56
57void SvcWrap_SendSyncRequestLight64(Core::System& system) {
58 SvcWrap_LightIpc(system, SendSyncRequestLight64);
59}
60
61void SvcWrap_ReplyAndReceiveLight64(Core::System& system) {
62 SvcWrap_LightIpc(system, ReplyAndReceiveLight64);
63}
64
65void SvcWrap_SendSyncRequestLight64From32(Core::System& system) {
66 SvcWrap_LightIpc(system, SendSyncRequestLight64From32);
67}
68
69void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system) {
70 SvcWrap_LightIpc(system, ReplyAndReceiveLight64From32);
71}
72
73} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_lock.cpp b/src/core/hle/kernel/svc/svc_lock.cpp
index 45f2a6553..f3d3e140b 100644
--- a/src/core/hle/kernel/svc/svc_lock.cpp
+++ b/src/core/hle/kernel/svc/svc_lock.cpp
@@ -24,11 +24,7 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address,
24 return ResultInvalidAddress; 24 return ResultInvalidAddress;
25 } 25 }
26 26
27 return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag); 27 return GetCurrentProcess(system.Kernel()).WaitForAddress(thread_handle, address, tag);
28}
29
30Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag) {
31 return ArbitrateLock(system, thread_handle, address, tag);
32} 28}
33 29
34/// Unlock a mutex 30/// Unlock a mutex
@@ -47,11 +43,24 @@ Result ArbitrateUnlock(Core::System& system, VAddr address) {
47 return ResultInvalidAddress; 43 return ResultInvalidAddress;
48 } 44 }
49 45
50 return system.Kernel().CurrentProcess()->SignalToAddress(address); 46 return GetCurrentProcess(system.Kernel()).SignalToAddress(address);
47}
48
49Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag) {
50 R_RETURN(ArbitrateLock(system, thread_handle, address, tag));
51}
52
53Result ArbitrateUnlock64(Core::System& system, uint64_t address) {
54 R_RETURN(ArbitrateUnlock(system, address));
55}
56
57Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address,
58 uint32_t tag) {
59 R_RETURN(ArbitrateLock(system, thread_handle, address, tag));
51} 60}
52 61
53Result ArbitrateUnlock32(Core::System& system, u32 address) { 62Result ArbitrateUnlock64From32(Core::System& system, uint32_t address) {
54 return ArbitrateUnlock(system, address); 63 R_RETURN(ArbitrateUnlock(system, address));
55} 64}
56 65
57} // namespace Kernel::Svc 66} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_memory.cpp b/src/core/hle/kernel/svc/svc_memory.cpp
index f78b1239b..214bcd073 100644
--- a/src/core/hle/kernel/svc/svc_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_memory.cpp
@@ -113,7 +113,7 @@ Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, Memory
113 R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission); 113 R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission);
114 114
115 // Validate that the region is in range for the current process. 115 // Validate that the region is in range for the current process.
116 auto& page_table = system.Kernel().CurrentProcess()->PageTable(); 116 auto& page_table = GetCurrentProcess(system.Kernel()).PageTable();
117 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); 117 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
118 118
119 // Set the memory attribute. 119 // Set the memory attribute.
@@ -137,23 +137,19 @@ Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mas
137 R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination); 137 R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination);
138 138
139 // Validate that the region is in range for the current process. 139 // Validate that the region is in range for the current process.
140 auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; 140 auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
141 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); 141 R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
142 142
143 // Set the memory attribute. 143 // Set the memory attribute.
144 return page_table.SetMemoryAttribute(address, size, mask, attr); 144 return page_table.SetMemoryAttribute(address, size, mask, attr);
145} 145}
146 146
147Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, u32 attr) {
148 return SetMemoryAttribute(system, address, size, mask, attr);
149}
150
151/// Maps a memory range into a different range. 147/// Maps a memory range into a different range.
152Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { 148Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
153 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 149 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
154 src_addr, size); 150 src_addr, size);
155 151
156 auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; 152 auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
157 153
158 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; 154 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
159 result.IsError()) { 155 result.IsError()) {
@@ -163,16 +159,12 @@ Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size)
163 return page_table.MapMemory(dst_addr, src_addr, size); 159 return page_table.MapMemory(dst_addr, src_addr, size);
164} 160}
165 161
166Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) {
167 return MapMemory(system, dst_addr, src_addr, size);
168}
169
170/// Unmaps a region that was previously mapped with svcMapMemory 162/// Unmaps a region that was previously mapped with svcMapMemory
171Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { 163Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
172 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 164 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
173 src_addr, size); 165 src_addr, size);
174 166
175 auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; 167 auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
176 168
177 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; 169 if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
178 result.IsError()) { 170 result.IsError()) {
@@ -182,8 +174,44 @@ Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 siz
182 return page_table.UnmapMemory(dst_addr, src_addr, size); 174 return page_table.UnmapMemory(dst_addr, src_addr, size);
183} 175}
184 176
185Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { 177Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size,
186 return UnmapMemory(system, dst_addr, src_addr, size); 178 MemoryPermission perm) {
179 R_RETURN(SetMemoryPermission(system, address, size, perm));
180}
181
182Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask,
183 uint32_t attr) {
184 R_RETURN(SetMemoryAttribute(system, address, size, mask, attr));
185}
186
187Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address,
188 uint64_t size) {
189 R_RETURN(MapMemory(system, dst_address, src_address, size));
190}
191
192Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address,
193 uint64_t size) {
194 R_RETURN(UnmapMemory(system, dst_address, src_address, size));
195}
196
197Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size,
198 MemoryPermission perm) {
199 R_RETURN(SetMemoryPermission(system, address, size, perm));
200}
201
202Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size,
203 uint32_t mask, uint32_t attr) {
204 R_RETURN(SetMemoryAttribute(system, address, size, mask, attr));
205}
206
207Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address,
208 uint32_t size) {
209 R_RETURN(MapMemory(system, dst_address, src_address, size));
210}
211
212Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address,
213 uint32_t size) {
214 R_RETURN(UnmapMemory(system, dst_address, src_address, size));
187} 215}
188 216
189} // namespace Kernel::Svc 217} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_physical_memory.cpp b/src/core/hle/kernel/svc/svc_physical_memory.cpp
index 0fc262203..a1f534454 100644
--- a/src/core/hle/kernel/svc/svc_physical_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_physical_memory.cpp
@@ -16,18 +16,11 @@ Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
16 R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize); 16 R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize);
17 17
18 // Set the heap size. 18 // Set the heap size.
19 R_TRY(system.Kernel().CurrentProcess()->PageTable().SetHeapSize(out_address, size)); 19 R_TRY(GetCurrentProcess(system.Kernel()).PageTable().SetHeapSize(out_address, size));
20 20
21 return ResultSuccess; 21 return ResultSuccess;
22} 22}
23 23
24Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) {
25 VAddr temp_heap_addr{};
26 const Result result{SetHeapSize(system, &temp_heap_addr, heap_size)};
27 *heap_addr = static_cast<u32>(temp_heap_addr);
28 return result;
29}
30
31/// Maps memory at a desired address 24/// Maps memory at a desired address
32Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { 25Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
33 LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); 26 LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
@@ -52,7 +45,7 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
52 return ResultInvalidMemoryRegion; 45 return ResultInvalidMemoryRegion;
53 } 46 }
54 47
55 KProcess* const current_process{system.Kernel().CurrentProcess()}; 48 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
56 auto& page_table{current_process->PageTable()}; 49 auto& page_table{current_process->PageTable()};
57 50
58 if (current_process->GetSystemResourceSize() == 0) { 51 if (current_process->GetSystemResourceSize() == 0) {
@@ -77,10 +70,6 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
77 return page_table.MapPhysicalMemory(addr, size); 70 return page_table.MapPhysicalMemory(addr, size);
78} 71}
79 72
80Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) {
81 return MapPhysicalMemory(system, addr, size);
82}
83
84/// Unmaps memory previously mapped via MapPhysicalMemory 73/// Unmaps memory previously mapped via MapPhysicalMemory
85Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { 74Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
86 LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); 75 LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
@@ -105,7 +94,7 @@ Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
105 return ResultInvalidMemoryRegion; 94 return ResultInvalidMemoryRegion;
106 } 95 }
107 96
108 KProcess* const current_process{system.Kernel().CurrentProcess()}; 97 KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
109 auto& page_table{current_process->PageTable()}; 98 auto& page_table{current_process->PageTable()};
110 99
111 if (current_process->GetSystemResourceSize() == 0) { 100 if (current_process->GetSystemResourceSize() == 0) {
@@ -130,8 +119,67 @@ Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
130 return page_table.UnmapPhysicalMemory(addr, size); 119 return page_table.UnmapPhysicalMemory(addr, size);
131} 120}
132 121
133Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { 122Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size) {
134 return UnmapPhysicalMemory(system, addr, size); 123 UNIMPLEMENTED();
124 R_THROW(ResultNotImplemented);
125}
126
127Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size) {
128 UNIMPLEMENTED();
129 R_THROW(ResultNotImplemented);
130}
131
132Result SetUnsafeLimit(Core::System& system, uint64_t limit) {
133 UNIMPLEMENTED();
134 R_THROW(ResultNotImplemented);
135}
136
137Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size) {
138 R_RETURN(SetHeapSize(system, out_address, size));
139}
140
141Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size) {
142 R_RETURN(MapPhysicalMemory(system, address, size));
143}
144
145Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size) {
146 R_RETURN(UnmapPhysicalMemory(system, address, size));
147}
148
149Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size) {
150 R_RETURN(MapPhysicalMemoryUnsafe(system, address, size));
151}
152
153Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size) {
154 R_RETURN(UnmapPhysicalMemoryUnsafe(system, address, size));
155}
156
157Result SetUnsafeLimit64(Core::System& system, uint64_t limit) {
158 R_RETURN(SetUnsafeLimit(system, limit));
159}
160
161Result SetHeapSize64From32(Core::System& system, uintptr_t* out_address, uint32_t size) {
162 R_RETURN(SetHeapSize(system, out_address, size));
163}
164
165Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
166 R_RETURN(MapPhysicalMemory(system, address, size));
167}
168
169Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
170 R_RETURN(UnmapPhysicalMemory(system, address, size));
171}
172
173Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size) {
174 R_RETURN(MapPhysicalMemoryUnsafe(system, address, size));
175}
176
177Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size) {
178 R_RETURN(UnmapPhysicalMemoryUnsafe(system, address, size));
179}
180
181Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit) {
182 R_RETURN(SetUnsafeLimit(system, limit));
135} 183}
136 184
137} // namespace Kernel::Svc 185} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index cdfe0dd16..2f9bfcb52 100644
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -5,6 +5,7 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/k_client_port.h" 6#include "core/hle/kernel/k_client_port.h"
7#include "core/hle/kernel/k_client_session.h" 7#include "core/hle/kernel/k_client_session.h"
8#include "core/hle/kernel/k_object_name.h"
8#include "core/hle/kernel/k_port.h" 9#include "core/hle/kernel/k_port.h"
9#include "core/hle/kernel/k_process.h" 10#include "core/hle/kernel/k_process.h"
10#include "core/hle/kernel/svc.h" 11#include "core/hle/kernel/svc.h"
@@ -34,7 +35,7 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_add
34 35
35 // Get the current handle table. 36 // Get the current handle table.
36 auto& kernel = system.Kernel(); 37 auto& kernel = system.Kernel();
37 auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 38 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
38 39
39 // Find the client port. 40 // Find the client port.
40 auto port = kernel.CreateNamedServicePort(port_name); 41 auto port = kernel.CreateNamedServicePort(port_name);
@@ -63,9 +64,107 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_add
63 return ResultSuccess; 64 return ResultSuccess;
64} 65}
65 66
66Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, u32 port_name_address) { 67Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
68 int32_t max_sessions, bool is_light, uintptr_t name) {
69 UNIMPLEMENTED();
70 R_THROW(ResultNotImplemented);
71}
72
73Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
74 UNIMPLEMENTED();
75 R_THROW(ResultNotImplemented);
76}
77
78Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
79 int32_t max_sessions) {
80 // Copy the provided name from user memory to kernel memory.
81 std::array<char, KObjectName::NameLengthMax> name{};
82 system.Memory().ReadBlock(user_name, name.data(), sizeof(name));
83
84 // Validate that sessions and name are valid.
85 R_UNLESS(max_sessions >= 0, ResultOutOfRange);
86 R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
87
88 if (max_sessions > 0) {
89 // Get the current handle table.
90 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
91
92 // Create a new port.
93 KPort* port = KPort::Create(system.Kernel());
94 R_UNLESS(port != nullptr, ResultOutOfResource);
95
96 // Initialize the new port.
97 port->Initialize(max_sessions, false, "");
98
99 // Register the port.
100 KPort::Register(system.Kernel(), port);
101
102 // Ensure that our only reference to the port is in the handle table when we're done.
103 SCOPE_EXIT({
104 port->GetClientPort().Close();
105 port->GetServerPort().Close();
106 });
107
108 // Register the handle in the table.
109 R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort())));
110 ON_RESULT_FAILURE {
111 handle_table.Remove(*out_server_handle);
112 };
113
114 // Create a new object name.
115 R_TRY(KObjectName::NewFromName(system.Kernel(), std::addressof(port->GetClientPort()),
116 name.data()));
117 } else /* if (max_sessions == 0) */ {
118 // Ensure that this else case is correct.
119 ASSERT(max_sessions == 0);
120
121 // If we're closing, there's no server handle.
122 *out_server_handle = InvalidHandle;
123
124 // Delete the object.
125 R_TRY(KObjectName::Delete<KClientPort>(system.Kernel(), name.data()));
126 }
127
128 R_SUCCEED();
129}
130
131Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) {
132 R_RETURN(ConnectToNamedPort(system, out_handle, name));
133}
134
135Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle,
136 int32_t max_sessions, bool is_light, uint64_t name) {
137 R_RETURN(
138 CreatePort(system, out_server_handle, out_client_handle, max_sessions, is_light, name));
139}
140
141Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name,
142 int32_t max_sessions) {
143 R_RETURN(ManageNamedPort(system, out_server_handle, name, max_sessions));
144}
145
146Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port) {
147 R_RETURN(ConnectToPort(system, out_handle, port));
148}
149
150Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name) {
151 R_RETURN(ConnectToNamedPort(system, out_handle, name));
152}
153
154Result CreatePort64From32(Core::System& system, Handle* out_server_handle,
155 Handle* out_client_handle, int32_t max_sessions, bool is_light,
156 uint32_t name) {
157 R_RETURN(
158 CreatePort(system, out_server_handle, out_client_handle, max_sessions, is_light, name));
159}
160
161Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name,
162 int32_t max_sessions) {
163 R_RETURN(ManageNamedPort(system, out_server_handle, name, max_sessions));
164}
67 165
68 return ConnectToNamedPort(system, out_handle, port_name_address); 166Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port) {
167 R_RETURN(ConnectToPort(system, out_handle, port));
69} 168}
70 169
71} // namespace Kernel::Svc 170} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_power_management.cpp b/src/core/hle/kernel/svc/svc_power_management.cpp
index 299e22ae6..f605a0317 100644
--- a/src/core/hle/kernel/svc/svc_power_management.cpp
+++ b/src/core/hle/kernel/svc/svc_power_management.cpp
@@ -2,5 +2,20 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9void SleepSystem(Core::System& system) {
10 UNIMPLEMENTED();
11}
12
13void SleepSystem64(Core::System& system) {
14 return SleepSystem(system);
15}
16
17void SleepSystem64From32(Core::System& system) {
18 return SleepSystem(system);
19}
20
21} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_process.cpp b/src/core/hle/kernel/svc/svc_process.cpp
index d6c8b4561..c35d2be76 100644
--- a/src/core/hle/kernel/svc/svc_process.cpp
+++ b/src/core/hle/kernel/svc/svc_process.cpp
@@ -9,7 +9,7 @@ namespace Kernel::Svc {
9 9
10/// Exits the current process 10/// Exits the current process
11void ExitProcess(Core::System& system) { 11void ExitProcess(Core::System& system) {
12 auto* current_process = system.Kernel().CurrentProcess(); 12 auto* current_process = GetCurrentProcessPointer(system.Kernel());
13 13
14 LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); 14 LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
15 ASSERT_MSG(current_process->GetState() == KProcess::State::Running, 15 ASSERT_MSG(current_process->GetState() == KProcess::State::Running,
@@ -18,18 +18,14 @@ void ExitProcess(Core::System& system) {
18 system.Exit(); 18 system.Exit();
19} 19}
20 20
21void ExitProcess32(Core::System& system) {
22 ExitProcess(system);
23}
24
25/// Gets the ID of the specified process or a specified thread's owning process. 21/// Gets the ID of the specified process or a specified thread's owning process.
26Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { 22Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
27 LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); 23 LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
28 24
29 // Get the object from the handle table. 25 // Get the object from the handle table.
30 KScopedAutoObject obj = 26 KScopedAutoObject obj = GetCurrentProcess(system.Kernel())
31 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KAutoObject>( 27 .GetHandleTable()
32 static_cast<Handle>(handle)); 28 .GetObject<KAutoObject>(static_cast<Handle>(handle));
33 R_UNLESS(obj.IsNotNull(), ResultInvalidHandle); 29 R_UNLESS(obj.IsNotNull(), ResultInvalidHandle);
34 30
35 // Get the process from the object. 31 // Get the process from the object.
@@ -54,17 +50,8 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
54 return ResultSuccess; 50 return ResultSuccess;
55} 51}
56 52
57Result GetProcessId32(Core::System& system, u32* out_process_id_low, u32* out_process_id_high, 53Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_process_ids,
58 Handle handle) { 54 int32_t out_process_ids_size) {
59 u64 out_process_id{};
60 const auto result = GetProcessId(system, &out_process_id, handle);
61 *out_process_id_low = static_cast<u32>(out_process_id);
62 *out_process_id_high = static_cast<u32>(out_process_id >> 32);
63 return result;
64}
65
66Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids,
67 u32 out_process_ids_size) {
68 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", 55 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
69 out_process_ids, out_process_ids_size); 56 out_process_ids, out_process_ids_size);
70 57
@@ -76,10 +63,10 @@ Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_pr
76 return ResultOutOfRange; 63 return ResultOutOfRange;
77 } 64 }
78 65
79 const auto& kernel = system.Kernel(); 66 auto& kernel = system.Kernel();
80 const auto total_copy_size = out_process_ids_size * sizeof(u64); 67 const auto total_copy_size = out_process_ids_size * sizeof(u64);
81 68
82 if (out_process_ids_size > 0 && !kernel.CurrentProcess()->PageTable().IsInsideAddressSpace( 69 if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).PageTable().IsInsideAddressSpace(
83 out_process_ids, total_copy_size)) { 70 out_process_ids, total_copy_size)) {
84 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", 71 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
85 out_process_ids, out_process_ids + total_copy_size); 72 out_process_ids, out_process_ids + total_copy_size);
@@ -89,7 +76,8 @@ Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_pr
89 auto& memory = system.Memory(); 76 auto& memory = system.Memory();
90 const auto& process_list = kernel.GetProcessList(); 77 const auto& process_list = kernel.GetProcessList();
91 const auto num_processes = process_list.size(); 78 const auto num_processes = process_list.size();
92 const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); 79 const auto copy_amount =
80 std::min(static_cast<std::size_t>(out_process_ids_size), num_processes);
93 81
94 for (std::size_t i = 0; i < copy_amount; ++i) { 82 for (std::size_t i = 0; i < copy_amount; ++i) {
95 memory.Write64(out_process_ids, process_list[i]->GetProcessID()); 83 memory.Write64(out_process_ids, process_list[i]->GetProcessID());
@@ -100,10 +88,11 @@ Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_pr
100 return ResultSuccess; 88 return ResultSuccess;
101} 89}
102 90
103Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { 91Result GetProcessInfo(Core::System& system, s64* out, Handle process_handle,
104 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); 92 ProcessInfoType info_type) {
93 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, info_type);
105 94
106 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 95 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
107 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); 96 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
108 if (process.IsNull()) { 97 if (process.IsNull()) {
109 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", 98 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -111,14 +100,95 @@ Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32
111 return ResultInvalidHandle; 100 return ResultInvalidHandle;
112 } 101 }
113 102
114 const auto info_type = static_cast<ProcessInfoType>(type);
115 if (info_type != ProcessInfoType::ProcessState) { 103 if (info_type != ProcessInfoType::ProcessState) {
116 LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead", type); 104 LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead",
105 info_type);
117 return ResultInvalidEnumValue; 106 return ResultInvalidEnumValue;
118 } 107 }
119 108
120 *out = static_cast<u64>(process->GetState()); 109 *out = static_cast<s64>(process->GetState());
121 return ResultSuccess; 110 return ResultSuccess;
122} 111}
123 112
113Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps,
114 int32_t num_caps) {
115 UNIMPLEMENTED();
116 R_THROW(ResultNotImplemented);
117}
118
119Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id,
120 uint64_t main_thread_stack_size) {
121 UNIMPLEMENTED();
122 R_THROW(ResultNotImplemented);
123}
124
125Result TerminateProcess(Core::System& system, Handle process_handle) {
126 UNIMPLEMENTED();
127 R_THROW(ResultNotImplemented);
128}
129
130void ExitProcess64(Core::System& system) {
131 ExitProcess(system);
132}
133
134Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle) {
135 R_RETURN(GetProcessId(system, out_process_id, process_handle));
136}
137
138Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids,
139 int32_t max_out_count) {
140 R_RETURN(GetProcessList(system, out_num_processes, out_process_ids, max_out_count));
141}
142
143Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps,
144 int32_t num_caps) {
145 R_RETURN(CreateProcess(system, out_handle, parameters, caps, num_caps));
146}
147
148Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority,
149 int32_t core_id, uint64_t main_thread_stack_size) {
150 R_RETURN(StartProcess(system, process_handle, priority, core_id, main_thread_stack_size));
151}
152
153Result TerminateProcess64(Core::System& system, Handle process_handle) {
154 R_RETURN(TerminateProcess(system, process_handle));
155}
156
157Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle,
158 ProcessInfoType info_type) {
159 R_RETURN(GetProcessInfo(system, out_info, process_handle, info_type));
160}
161
162void ExitProcess64From32(Core::System& system) {
163 ExitProcess(system);
164}
165
166Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle) {
167 R_RETURN(GetProcessId(system, out_process_id, process_handle));
168}
169
170Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes,
171 uint32_t out_process_ids, int32_t max_out_count) {
172 R_RETURN(GetProcessList(system, out_num_processes, out_process_ids, max_out_count));
173}
174
175Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters,
176 uint32_t caps, int32_t num_caps) {
177 R_RETURN(CreateProcess(system, out_handle, parameters, caps, num_caps));
178}
179
180Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority,
181 int32_t core_id, uint64_t main_thread_stack_size) {
182 R_RETURN(StartProcess(system, process_handle, priority, core_id, main_thread_stack_size));
183}
184
185Result TerminateProcess64From32(Core::System& system, Handle process_handle) {
186 R_RETURN(TerminateProcess(system, process_handle));
187}
188
189Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle,
190 ProcessInfoType info_type) {
191 R_RETURN(GetProcessInfo(system, out_info, process_handle, info_type));
192}
193
124} // namespace Kernel::Svc 194} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_process_memory.cpp b/src/core/hle/kernel/svc/svc_process_memory.cpp
index b6ac43af2..4dfd9e5bb 100644
--- a/src/core/hle/kernel/svc/svc_process_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_process_memory.cpp
@@ -45,7 +45,7 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, V
45 45
46 // Get the process from its handle. 46 // Get the process from its handle.
47 KScopedAutoObject process = 47 KScopedAutoObject process =
48 system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle); 48 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
49 R_UNLESS(process.IsNotNull(), ResultInvalidHandle); 49 R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
50 50
51 // Validate that the address is in range. 51 // Validate that the address is in range.
@@ -71,7 +71,7 @@ Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_
71 R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory); 71 R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory);
72 72
73 // Get the processes. 73 // Get the processes.
74 KProcess* dst_process = system.CurrentProcess(); 74 KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
75 KScopedAutoObject src_process = 75 KScopedAutoObject src_process =
76 dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle); 76 dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
77 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); 77 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
@@ -114,7 +114,7 @@ Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle proces
114 R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory); 114 R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory);
115 115
116 // Get the processes. 116 // Get the processes.
117 KProcess* dst_process = system.CurrentProcess(); 117 KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
118 KScopedAutoObject src_process = 118 KScopedAutoObject src_process =
119 dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle); 119 dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
120 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); 120 R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
@@ -174,7 +174,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
174 return ResultInvalidCurrentMemory; 174 return ResultInvalidCurrentMemory;
175 } 175 }
176 176
177 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 177 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
178 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); 178 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
179 if (process.IsNull()) { 179 if (process.IsNull()) {
180 LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", 180 LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
@@ -242,7 +242,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
242 return ResultInvalidCurrentMemory; 242 return ResultInvalidCurrentMemory;
243 } 243 }
244 244
245 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 245 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
246 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); 246 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
247 if (process.IsNull()) { 247 if (process.IsNull()) {
248 LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", 248 LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
@@ -271,4 +271,54 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
271 KPageTable::ICacheInvalidationStrategy::InvalidateAll); 271 KPageTable::ICacheInvalidationStrategy::InvalidateAll);
272} 272}
273 273
274Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address,
275 uint64_t size, MemoryPermission perm) {
276 R_RETURN(SetProcessMemoryPermission(system, process_handle, address, size, perm));
277}
278
279Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle,
280 uint64_t src_address, uint64_t size) {
281 R_RETURN(MapProcessMemory(system, dst_address, process_handle, src_address, size));
282}
283
284Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle,
285 uint64_t src_address, uint64_t size) {
286 R_RETURN(UnmapProcessMemory(system, dst_address, process_handle, src_address, size));
287}
288
289Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address,
290 uint64_t src_address, uint64_t size) {
291 R_RETURN(MapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
292}
293
294Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address,
295 uint64_t src_address, uint64_t size) {
296 R_RETURN(UnmapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
297}
298
299Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle,
300 uint64_t address, uint64_t size, MemoryPermission perm) {
301 R_RETURN(SetProcessMemoryPermission(system, process_handle, address, size, perm));
302}
303
304Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle,
305 uint64_t src_address, uint32_t size) {
306 R_RETURN(MapProcessMemory(system, dst_address, process_handle, src_address, size));
307}
308
309Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle,
310 uint64_t src_address, uint32_t size) {
311 R_RETURN(UnmapProcessMemory(system, dst_address, process_handle, src_address, size));
312}
313
314Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle,
315 uint64_t dst_address, uint64_t src_address, uint64_t size) {
316 R_RETURN(MapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
317}
318
319Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle,
320 uint64_t dst_address, uint64_t src_address, uint64_t size) {
321 R_RETURN(UnmapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
322}
323
274} // namespace Kernel::Svc 324} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_processor.cpp b/src/core/hle/kernel/svc/svc_processor.cpp
index 8561cf74f..7602ce6c0 100644
--- a/src/core/hle/kernel/svc/svc_processor.cpp
+++ b/src/core/hle/kernel/svc/svc_processor.cpp
@@ -9,12 +9,16 @@
9namespace Kernel::Svc { 9namespace Kernel::Svc {
10 10
11/// Get which CPU core is executing the current thread 11/// Get which CPU core is executing the current thread
12u32 GetCurrentProcessorNumber(Core::System& system) { 12int32_t GetCurrentProcessorNumber(Core::System& system) {
13 LOG_TRACE(Kernel_SVC, "called"); 13 LOG_TRACE(Kernel_SVC, "called");
14 return static_cast<u32>(system.CurrentPhysicalCore().CoreIndex()); 14 return static_cast<int32_t>(system.CurrentPhysicalCore().CoreIndex());
15} 15}
16 16
17u32 GetCurrentProcessorNumber32(Core::System& system) { 17int32_t GetCurrentProcessorNumber64(Core::System& system) {
18 return GetCurrentProcessorNumber(system);
19}
20
21int32_t GetCurrentProcessorNumber64From32(Core::System& system) {
18 return GetCurrentProcessorNumber(system); 22 return GetCurrentProcessorNumber(system);
19} 23}
20 24
diff --git a/src/core/hle/kernel/svc/svc_query_memory.cpp b/src/core/hle/kernel/svc/svc_query_memory.cpp
index aac3b2eca..ee75ad370 100644
--- a/src/core/hle/kernel/svc/svc_query_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_query_memory.cpp
@@ -7,26 +7,22 @@
7 7
8namespace Kernel::Svc { 8namespace Kernel::Svc {
9 9
10Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, 10Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info,
11 VAddr query_address) { 11 VAddr query_address) {
12 LOG_TRACE(Kernel_SVC, 12 LOG_TRACE(Kernel_SVC,
13 "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " 13 "called, out_memory_info=0x{:016X}, "
14 "query_address=0x{:016X}", 14 "query_address=0x{:016X}",
15 memory_info_address, page_info_address, query_address); 15 out_memory_info, query_address);
16 16
17 return QueryProcessMemory(system, memory_info_address, page_info_address, CurrentProcess, 17 // Query memory is just QueryProcessMemory on the current process.
18 return QueryProcessMemory(system, out_memory_info, out_page_info, CurrentProcess,
18 query_address); 19 query_address);
19} 20}
20 21
21Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address, 22Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info,
22 u32 query_address) { 23 Handle process_handle, uint64_t address) {
23 return QueryMemory(system, memory_info_address, page_info_address, query_address);
24}
25
26Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address,
27 Handle process_handle, VAddr address) {
28 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); 24 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
29 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 25 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
30 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); 26 KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
31 if (process.IsNull()) { 27 if (process.IsNull()) {
32 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", 28 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -37,19 +33,33 @@ Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr
37 auto& memory{system.Memory()}; 33 auto& memory{system.Memory()};
38 const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; 34 const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
39 35
40 memory.Write64(memory_info_address + 0x00, memory_info.base_address); 36 memory.WriteBlock(out_memory_info, &memory_info, sizeof(memory_info));
41 memory.Write64(memory_info_address + 0x08, memory_info.size); 37
42 memory.Write32(memory_info_address + 0x10, static_cast<u32>(memory_info.state) & 0xff); 38 //! This is supposed to be part of the QueryInfo call.
43 memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attribute)); 39 *out_page_info = {};
44 memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.permission)); 40
45 memory.Write32(memory_info_address + 0x1c, memory_info.ipc_count); 41 R_SUCCEED();
46 memory.Write32(memory_info_address + 0x20, memory_info.device_count); 42}
47 memory.Write32(memory_info_address + 0x24, 0); 43
44Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info,
45 uint64_t address) {
46 R_RETURN(QueryMemory(system, out_memory_info, out_page_info, address));
47}
48 48
49 // Page info appears to be currently unused by the kernel and is always set to zero. 49Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info,
50 memory.Write32(page_info_address, 0); 50 Handle process_handle, uint64_t address) {
51 R_RETURN(QueryProcessMemory(system, out_memory_info, out_page_info, process_handle, address));
52}
53
54Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info,
55 uint32_t address) {
56 R_RETURN(QueryMemory(system, out_memory_info, out_page_info, address));
57}
51 58
52 return ResultSuccess; 59Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info,
60 PageInfo* out_page_info, Handle process_handle,
61 uint64_t address) {
62 R_RETURN(QueryProcessMemory(system, out_memory_info, out_page_info, process_handle, address));
53} 63}
54 64
55} // namespace Kernel::Svc 65} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_register.cpp b/src/core/hle/kernel/svc/svc_register.cpp
index 299e22ae6..b883e6618 100644
--- a/src/core/hle/kernel/svc/svc_register.cpp
+++ b/src/core/hle/kernel/svc/svc_register.cpp
@@ -2,5 +2,26 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9Result ReadWriteRegister(Core::System& system, uint32_t* out, uint64_t address, uint32_t mask,
10 uint32_t value) {
11 *out = 0;
12
13 UNIMPLEMENTED();
14 R_THROW(ResultNotImplemented);
15}
16
17Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address,
18 uint32_t mask, uint32_t value) {
19 R_RETURN(ReadWriteRegister(system, out_value, address, mask, value));
20}
21
22Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address,
23 uint32_t mask, uint32_t value) {
24 R_RETURN(ReadWriteRegister(system, out_value, address, mask, value));
25}
26
27} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_resource_limit.cpp b/src/core/hle/kernel/svc/svc_resource_limit.cpp
index 679ba10fa..88166299e 100644
--- a/src/core/hle/kernel/svc/svc_resource_limit.cpp
+++ b/src/core/hle/kernel/svc/svc_resource_limit.cpp
@@ -27,12 +27,12 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) {
27 KResourceLimit::Register(kernel, resource_limit); 27 KResourceLimit::Register(kernel, resource_limit);
28 28
29 // Add the limit to the handle table. 29 // Add the limit to the handle table.
30 R_TRY(kernel.CurrentProcess()->GetHandleTable().Add(out_handle, resource_limit)); 30 R_TRY(GetCurrentProcess(kernel).GetHandleTable().Add(out_handle, resource_limit));
31 31
32 return ResultSuccess; 32 return ResultSuccess;
33} 33}
34 34
35Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, 35Result GetResourceLimitLimitValue(Core::System& system, s64* out_limit_value,
36 Handle resource_limit_handle, LimitableResource which) { 36 Handle resource_limit_handle, LimitableResource which) {
37 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, 37 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle,
38 which); 38 which);
@@ -41,9 +41,9 @@ Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value,
41 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); 41 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue);
42 42
43 // Get the resource limit. 43 // Get the resource limit.
44 auto& kernel = system.Kernel(); 44 KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
45 KScopedAutoObject resource_limit = 45 .GetHandleTable()
46 kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle); 46 .GetObject<KResourceLimit>(resource_limit_handle);
47 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); 47 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
48 48
49 // Get the limit value. 49 // Get the limit value.
@@ -52,7 +52,7 @@ Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value,
52 return ResultSuccess; 52 return ResultSuccess;
53} 53}
54 54
55Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, 55Result GetResourceLimitCurrentValue(Core::System& system, s64* out_current_value,
56 Handle resource_limit_handle, LimitableResource which) { 56 Handle resource_limit_handle, LimitableResource which) {
57 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, 57 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle,
58 which); 58 which);
@@ -61,9 +61,9 @@ Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value
61 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); 61 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue);
62 62
63 // Get the resource limit. 63 // Get the resource limit.
64 auto& kernel = system.Kernel(); 64 KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
65 KScopedAutoObject resource_limit = 65 .GetHandleTable()
66 kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle); 66 .GetObject<KResourceLimit>(resource_limit_handle);
67 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); 67 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
68 68
69 // Get the current value. 69 // Get the current value.
@@ -73,7 +73,7 @@ Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value
73} 73}
74 74
75Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, 75Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle,
76 LimitableResource which, u64 limit_value) { 76 LimitableResource which, s64 limit_value) {
77 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", 77 LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}",
78 resource_limit_handle, which, limit_value); 78 resource_limit_handle, which, limit_value);
79 79
@@ -81,9 +81,9 @@ Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_ha
81 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); 81 R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue);
82 82
83 // Get the resource limit. 83 // Get the resource limit.
84 auto& kernel = system.Kernel(); 84 KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
85 KScopedAutoObject resource_limit = 85 .GetHandleTable()
86 kernel.CurrentProcess()->GetHandleTable().GetObject<KResourceLimit>(resource_limit_handle); 86 .GetObject<KResourceLimit>(resource_limit_handle);
87 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); 87 R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
88 88
89 // Set the limit value. 89 // Set the limit value.
@@ -92,4 +92,58 @@ Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_ha
92 return ResultSuccess; 92 return ResultSuccess;
93} 93}
94 94
95Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value,
96 Handle resource_limit_handle, LimitableResource which) {
97 UNIMPLEMENTED();
98 R_THROW(ResultNotImplemented);
99}
100
101Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value,
102 Handle resource_limit_handle, LimitableResource which) {
103 R_RETURN(GetResourceLimitLimitValue(system, out_limit_value, resource_limit_handle, which));
104}
105
106Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value,
107 Handle resource_limit_handle, LimitableResource which) {
108 R_RETURN(GetResourceLimitCurrentValue(system, out_current_value, resource_limit_handle, which));
109}
110
111Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value,
112 Handle resource_limit_handle, LimitableResource which) {
113 R_RETURN(GetResourceLimitPeakValue(system, out_peak_value, resource_limit_handle, which));
114}
115
116Result CreateResourceLimit64(Core::System& system, Handle* out_handle) {
117 R_RETURN(CreateResourceLimit(system, out_handle));
118}
119
120Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle,
121 LimitableResource which, int64_t limit_value) {
122 R_RETURN(SetResourceLimitLimitValue(system, resource_limit_handle, which, limit_value));
123}
124
125Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value,
126 Handle resource_limit_handle, LimitableResource which) {
127 R_RETURN(GetResourceLimitLimitValue(system, out_limit_value, resource_limit_handle, which));
128}
129
130Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value,
131 Handle resource_limit_handle, LimitableResource which) {
132 R_RETURN(GetResourceLimitCurrentValue(system, out_current_value, resource_limit_handle, which));
133}
134
135Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value,
136 Handle resource_limit_handle, LimitableResource which) {
137 R_RETURN(GetResourceLimitPeakValue(system, out_peak_value, resource_limit_handle, which));
138}
139
140Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle) {
141 R_RETURN(CreateResourceLimit(system, out_handle));
142}
143
144Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle,
145 LimitableResource which, int64_t limit_value) {
146 R_RETURN(SetResourceLimitLimitValue(system, resource_limit_handle, which, limit_value));
147}
148
95} // namespace Kernel::Svc 149} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp b/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp
index 299e22ae6..20f6ec643 100644
--- a/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp
+++ b/src/core/hle/kernel/svc/svc_secure_monitor_call.cpp
@@ -1,6 +1,53 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h"
5#include "core/hle/kernel/physical_core.h"
4#include "core/hle/kernel/svc.h" 6#include "core/hle/kernel/svc.h"
5 7
6namespace Kernel::Svc {} // namespace Kernel::Svc 8namespace Kernel::Svc {
9
10void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args) {
11 UNIMPLEMENTED();
12}
13
14void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args) {
15 CallSecureMonitor(system, args);
16}
17
18void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args) {
19 // CallSecureMonitor64From32 is not supported.
20 UNIMPLEMENTED_MSG("CallSecureMonitor64From32");
21}
22
23// Custom ABI for CallSecureMonitor.
24
25void SvcWrap_CallSecureMonitor64(Core::System& system) {
26 auto& core = system.CurrentPhysicalCore().ArmInterface();
27 lp64::SecureMonitorArguments args{};
28 for (int i = 0; i < 8; i++) {
29 args.r[i] = core.GetReg(i);
30 }
31
32 CallSecureMonitor64(system, &args);
33
34 for (int i = 0; i < 8; i++) {
35 core.SetReg(i, args.r[i]);
36 }
37}
38
39void SvcWrap_CallSecureMonitor64From32(Core::System& system) {
40 auto& core = system.CurrentPhysicalCore().ArmInterface();
41 ilp32::SecureMonitorArguments args{};
42 for (int i = 0; i < 8; i++) {
43 args.r[i] = static_cast<u32>(core.GetReg(i));
44 }
45
46 CallSecureMonitor64From32(system, &args);
47
48 for (int i = 0; i < 8; i++) {
49 core.SetReg(i, args.r[i]);
50 }
51}
52
53} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_session.cpp b/src/core/hle/kernel/svc/svc_session.cpp
index dac8ce33c..00fd1605e 100644
--- a/src/core/hle/kernel/svc/svc_session.cpp
+++ b/src/core/hle/kernel/svc/svc_session.cpp
@@ -13,7 +13,7 @@ namespace {
13 13
14template <typename T> 14template <typename T>
15Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) { 15Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) {
16 auto& process = *system.CurrentProcess(); 16 auto& process = GetCurrentProcess(system.Kernel());
17 auto& handle_table = process.GetHandleTable(); 17 auto& handle_table = process.GetHandleTable();
18 18
19 // Declare the session we're going to allocate. 19 // Declare the session we're going to allocate.
@@ -90,14 +90,39 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
90 90
91} // namespace 91} // namespace
92 92
93Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u32 is_light, 93Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, bool is_light,
94 u64 name) { 94 u64 name) {
95 if (is_light) { 95 if (is_light) {
96 // return CreateSession<KLightSession>(system, out_server, out_client, name); 96 // return CreateSession<KLightSession>(system, out_server, out_client, name);
97 return ResultUnknown; 97 return ResultNotImplemented;
98 } else { 98 } else {
99 return CreateSession<KSession>(system, out_server, out_client, name); 99 return CreateSession<KSession>(system, out_server, out_client, name);
100 } 100 }
101} 101}
102 102
103Result AcceptSession(Core::System& system, Handle* out_handle, Handle port_handle) {
104 UNIMPLEMENTED();
105 R_THROW(ResultNotImplemented);
106}
107
108Result CreateSession64(Core::System& system, Handle* out_server_session_handle,
109 Handle* out_client_session_handle, bool is_light, uint64_t name) {
110 R_RETURN(CreateSession(system, out_server_session_handle, out_client_session_handle, is_light,
111 name));
112}
113
114Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port) {
115 R_RETURN(AcceptSession(system, out_handle, port));
116}
117
118Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle,
119 Handle* out_client_session_handle, bool is_light, uint32_t name) {
120 R_RETURN(CreateSession(system, out_server_session_handle, out_client_session_handle, is_light,
121 name));
122}
123
124Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port) {
125 R_RETURN(AcceptSession(system, out_handle, port));
126}
127
103} // namespace Kernel::Svc 128} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_shared_memory.cpp b/src/core/hle/kernel/svc/svc_shared_memory.cpp
index d465bcbe7..18e0dc904 100644
--- a/src/core/hle/kernel/svc/svc_shared_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_shared_memory.cpp
@@ -42,7 +42,7 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address,
42 R_UNLESS(IsValidSharedMemoryPermission(map_perm), ResultInvalidNewMemoryPermission); 42 R_UNLESS(IsValidSharedMemoryPermission(map_perm), ResultInvalidNewMemoryPermission);
43 43
44 // Get the current process. 44 // Get the current process.
45 auto& process = *system.Kernel().CurrentProcess(); 45 auto& process = GetCurrentProcess(system.Kernel());
46 auto& page_table = process.PageTable(); 46 auto& page_table = process.PageTable();
47 47
48 // Get the shared memory. 48 // Get the shared memory.
@@ -67,11 +67,6 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address,
67 return ResultSuccess; 67 return ResultSuccess;
68} 68}
69 69
70Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size,
71 Svc::MemoryPermission map_perm) {
72 return MapSharedMemory(system, shmem_handle, address, size, map_perm);
73}
74
75Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size) { 70Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size) {
76 // Validate the address/size. 71 // Validate the address/size.
77 R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); 72 R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
@@ -80,7 +75,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr addres
80 R_UNLESS((address < address + size), ResultInvalidCurrentMemory); 75 R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
81 76
82 // Get the current process. 77 // Get the current process.
83 auto& process = *system.Kernel().CurrentProcess(); 78 auto& process = GetCurrentProcess(system.Kernel());
84 auto& page_table = process.PageTable(); 79 auto& page_table = process.PageTable();
85 80
86 // Get the shared memory. 81 // Get the shared memory.
@@ -99,8 +94,40 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr addres
99 return ResultSuccess; 94 return ResultSuccess;
100} 95}
101 96
102Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size) { 97Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size,
103 return UnmapSharedMemory(system, shmem_handle, address, size); 98 MemoryPermission owner_perm, MemoryPermission remote_perm) {
99 UNIMPLEMENTED();
100 R_THROW(ResultNotImplemented);
101}
102
103Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size,
104 MemoryPermission map_perm) {
105 R_RETURN(MapSharedMemory(system, shmem_handle, address, size, map_perm));
106}
107
108Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address,
109 uint64_t size) {
110 R_RETURN(UnmapSharedMemory(system, shmem_handle, address, size));
111}
112
113Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size,
114 MemoryPermission owner_perm, MemoryPermission remote_perm) {
115 R_RETURN(CreateSharedMemory(system, out_handle, size, owner_perm, remote_perm));
116}
117
118Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address,
119 uint32_t size, MemoryPermission map_perm) {
120 R_RETURN(MapSharedMemory(system, shmem_handle, address, size, map_perm));
121}
122
123Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address,
124 uint32_t size) {
125 R_RETURN(UnmapSharedMemory(system, shmem_handle, address, size));
126}
127
128Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size,
129 MemoryPermission owner_perm, MemoryPermission remote_perm) {
130 R_RETURN(CreateSharedMemory(system, out_handle, size, owner_perm, remote_perm));
104} 131}
105 132
106} // namespace Kernel::Svc 133} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 1bf6a612a..1a8f7e191 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -14,22 +14,18 @@ Result CloseHandle(Core::System& system, Handle handle) {
14 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); 14 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
15 15
16 // Remove the handle. 16 // Remove the handle.
17 R_UNLESS(system.Kernel().CurrentProcess()->GetHandleTable().Remove(handle), 17 R_UNLESS(GetCurrentProcess(system.Kernel()).GetHandleTable().Remove(handle),
18 ResultInvalidHandle); 18 ResultInvalidHandle);
19 19
20 return ResultSuccess; 20 return ResultSuccess;
21} 21}
22 22
23Result CloseHandle32(Core::System& system, Handle handle) {
24 return CloseHandle(system, handle);
25}
26
27/// Clears the signaled state of an event or process. 23/// Clears the signaled state of an event or process.
28Result ResetSignal(Core::System& system, Handle handle) { 24Result ResetSignal(Core::System& system, Handle handle) {
29 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); 25 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
30 26
31 // Get the current handle table. 27 // Get the current handle table.
32 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 28 const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
33 29
34 // Try to reset as readable event. 30 // Try to reset as readable event.
35 { 31 {
@@ -52,10 +48,6 @@ Result ResetSignal(Core::System& system, Handle handle) {
52 return ResultInvalidHandle; 48 return ResultInvalidHandle;
53} 49}
54 50
55Result ResetSignal32(Core::System& system, Handle handle) {
56 return ResetSignal(system, handle);
57}
58
59/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 51/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
60Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, 52Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles,
61 s64 nano_seconds) { 53 s64 nano_seconds) {
@@ -67,7 +59,7 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre
67 59
68 auto& kernel = system.Kernel(); 60 auto& kernel = system.Kernel();
69 std::vector<KSynchronizationObject*> objs(num_handles); 61 std::vector<KSynchronizationObject*> objs(num_handles);
70 const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 62 const auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
71 Handle* handles = system.Memory().GetPointer<Handle>(handles_address); 63 Handle* handles = system.Memory().GetPointer<Handle>(handles_address);
72 64
73 // Copy user handles. 65 // Copy user handles.
@@ -93,19 +85,13 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre
93 nano_seconds); 85 nano_seconds);
94} 86}
95 87
96Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address,
97 s32 num_handles, u32 timeout_high, s32* index) {
98 const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)};
99 return WaitSynchronization(system, index, handles_address, num_handles, nano_seconds);
100}
101
102/// Resumes a thread waiting on WaitSynchronization 88/// Resumes a thread waiting on WaitSynchronization
103Result CancelSynchronization(Core::System& system, Handle handle) { 89Result CancelSynchronization(Core::System& system, Handle handle) {
104 LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); 90 LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle);
105 91
106 // Get the thread from its handle. 92 // Get the thread from its handle.
107 KScopedAutoObject thread = 93 KScopedAutoObject thread =
108 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(handle); 94 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(handle);
109 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 95 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
110 96
111 // Cancel the thread's wait. 97 // Cancel the thread's wait.
@@ -113,10 +99,6 @@ Result CancelSynchronization(Core::System& system, Handle handle) {
113 return ResultSuccess; 99 return ResultSuccess;
114} 100}
115 101
116Result CancelSynchronization32(Core::System& system, Handle handle) {
117 return CancelSynchronization(system, handle);
118}
119
120void SynchronizePreemptionState(Core::System& system) { 102void SynchronizePreemptionState(Core::System& system) {
121 auto& kernel = system.Kernel(); 103 auto& kernel = system.Kernel();
122 104
@@ -124,7 +106,7 @@ void SynchronizePreemptionState(Core::System& system) {
124 KScopedSchedulerLock sl{kernel}; 106 KScopedSchedulerLock sl{kernel};
125 107
126 // If the current thread is pinned, unpin it. 108 // If the current thread is pinned, unpin it.
127 KProcess* cur_process = system.Kernel().CurrentProcess(); 109 KProcess* cur_process = GetCurrentProcessPointer(kernel);
128 const auto core_id = GetCurrentCoreId(kernel); 110 const auto core_id = GetCurrentCoreId(kernel);
129 111
130 if (cur_process->GetPinnedThread(core_id) == GetCurrentThreadPointer(kernel)) { 112 if (cur_process->GetPinnedThread(core_id) == GetCurrentThreadPointer(kernel)) {
@@ -136,4 +118,46 @@ void SynchronizePreemptionState(Core::System& system) {
136 } 118 }
137} 119}
138 120
121Result CloseHandle64(Core::System& system, Handle handle) {
122 R_RETURN(CloseHandle(system, handle));
123}
124
125Result ResetSignal64(Core::System& system, Handle handle) {
126 R_RETURN(ResetSignal(system, handle));
127}
128
129Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles,
130 int32_t num_handles, int64_t timeout_ns) {
131 R_RETURN(WaitSynchronization(system, out_index, handles, num_handles, timeout_ns));
132}
133
134Result CancelSynchronization64(Core::System& system, Handle handle) {
135 R_RETURN(CancelSynchronization(system, handle));
136}
137
138void SynchronizePreemptionState64(Core::System& system) {
139 SynchronizePreemptionState(system);
140}
141
142Result CloseHandle64From32(Core::System& system, Handle handle) {
143 R_RETURN(CloseHandle(system, handle));
144}
145
146Result ResetSignal64From32(Core::System& system, Handle handle) {
147 R_RETURN(ResetSignal(system, handle));
148}
149
150Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles,
151 int32_t num_handles, int64_t timeout_ns) {
152 R_RETURN(WaitSynchronization(system, out_index, handles, num_handles, timeout_ns));
153}
154
155Result CancelSynchronization64From32(Core::System& system, Handle handle) {
156 R_RETURN(CancelSynchronization(system, handle));
157}
158
159void SynchronizePreemptionState64From32(Core::System& system) {
160 SynchronizePreemptionState(system);
161}
162
139} // namespace Kernel::Svc 163} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index dd9f8e8b1..b39807841 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -20,7 +20,7 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) {
20 20
21/// Creates a new thread 21/// Creates a new thread
22Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, 22Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
23 VAddr stack_bottom, u32 priority, s32 core_id) { 23 VAddr stack_bottom, s32 priority, s32 core_id) {
24 LOG_DEBUG(Kernel_SVC, 24 LOG_DEBUG(Kernel_SVC,
25 "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, " 25 "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, "
26 "priority=0x{:08X}, core_id=0x{:08X}", 26 "priority=0x{:08X}, core_id=0x{:08X}",
@@ -28,7 +28,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point,
28 28
29 // Adjust core id, if it's the default magic. 29 // Adjust core id, if it's the default magic.
30 auto& kernel = system.Kernel(); 30 auto& kernel = system.Kernel();
31 auto& process = *kernel.CurrentProcess(); 31 auto& process = GetCurrentProcess(kernel);
32 if (core_id == IdealCoreUseProcessValue) { 32 if (core_id == IdealCoreUseProcessValue) {
33 core_id = process.GetIdealCoreId(); 33 core_id = process.GetIdealCoreId();
34 } 34 }
@@ -53,9 +53,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point,
53 } 53 }
54 54
55 // Reserve a new thread from the process resource limit (waiting up to 100ms). 55 // Reserve a new thread from the process resource limit (waiting up to 100ms).
56 KScopedResourceReservation thread_reservation( 56 KScopedResourceReservation thread_reservation(&process, LimitableResource::ThreadCountMax, 1,
57 kernel.CurrentProcess(), LimitableResource::ThreadCountMax, 1, 57 system.CoreTiming().GetGlobalTimeNs().count() +
58 system.CoreTiming().GetGlobalTimeNs().count() + 100000000); 58 100000000);
59 if (!thread_reservation.Succeeded()) { 59 if (!thread_reservation.Succeeded()) {
60 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread"); 60 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread");
61 return ResultLimitReached; 61 return ResultLimitReached;
@@ -91,18 +91,13 @@ Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point,
91 return ResultSuccess; 91 return ResultSuccess;
92} 92}
93 93
94Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, u32 entry_point,
95 u32 arg, u32 stack_top, s32 processor_id) {
96 return CreateThread(system, out_handle, entry_point, arg, stack_top, priority, processor_id);
97}
98
99/// Starts the thread for the provided handle 94/// Starts the thread for the provided handle
100Result StartThread(Core::System& system, Handle thread_handle) { 95Result StartThread(Core::System& system, Handle thread_handle) {
101 LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 96 LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
102 97
103 // Get the thread from its handle. 98 // Get the thread from its handle.
104 KScopedAutoObject thread = 99 KScopedAutoObject thread =
105 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); 100 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
106 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 101 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
107 102
108 // Try to start the thread. 103 // Try to start the thread.
@@ -115,10 +110,6 @@ Result StartThread(Core::System& system, Handle thread_handle) {
115 return ResultSuccess; 110 return ResultSuccess;
116} 111}
117 112
118Result StartThread32(Core::System& system, Handle thread_handle) {
119 return StartThread(system, thread_handle);
120}
121
122/// Called when a thread exits 113/// Called when a thread exits
123void ExitThread(Core::System& system) { 114void ExitThread(Core::System& system) {
124 LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); 115 LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
@@ -129,10 +120,6 @@ void ExitThread(Core::System& system) {
129 system.Kernel().UnregisterInUseObject(current_thread); 120 system.Kernel().UnregisterInUseObject(current_thread);
130} 121}
131 122
132void ExitThread32(Core::System& system) {
133 ExitThread(system);
134}
135
136/// Sleep the current thread 123/// Sleep the current thread
137void SleepThread(Core::System& system, s64 nanoseconds) { 124void SleepThread(Core::System& system, s64 nanoseconds) {
138 auto& kernel = system.Kernel(); 125 auto& kernel = system.Kernel();
@@ -160,13 +147,8 @@ void SleepThread(Core::System& system, s64 nanoseconds) {
160 } 147 }
161} 148}
162 149
163void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high) {
164 const auto nanoseconds = static_cast<s64>(u64{nanoseconds_low} | (u64{nanoseconds_high} << 32));
165 SleepThread(system, nanoseconds);
166}
167
168/// Gets the thread context 150/// Gets the thread context
169Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle) { 151Result GetThreadContext3(Core::System& system, VAddr out_context, Handle thread_handle) {
170 LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, 152 LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context,
171 thread_handle); 153 thread_handle);
172 154
@@ -174,11 +156,11 @@ Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_h
174 156
175 // Get the thread from its handle. 157 // Get the thread from its handle.
176 KScopedAutoObject thread = 158 KScopedAutoObject thread =
177 kernel.CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); 159 GetCurrentProcess(kernel).GetHandleTable().GetObject<KThread>(thread_handle);
178 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 160 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
179 161
180 // Require the handle be to a non-current thread in the current process. 162 // Require the handle be to a non-current thread in the current process.
181 const auto* current_process = kernel.CurrentProcess(); 163 const auto* current_process = GetCurrentProcessPointer(kernel);
182 R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId); 164 R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId);
183 165
184 // Verify that the thread isn't terminated. 166 // Verify that the thread isn't terminated.
@@ -223,17 +205,13 @@ Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_h
223 return ResultSuccess; 205 return ResultSuccess;
224} 206}
225 207
226Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle) {
227 return GetThreadContext(system, out_context, thread_handle);
228}
229
230/// Gets the priority for the specified thread 208/// Gets the priority for the specified thread
231Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) { 209Result GetThreadPriority(Core::System& system, s32* out_priority, Handle handle) {
232 LOG_TRACE(Kernel_SVC, "called"); 210 LOG_TRACE(Kernel_SVC, "called");
233 211
234 // Get the thread from its handle. 212 // Get the thread from its handle.
235 KScopedAutoObject thread = 213 KScopedAutoObject thread =
236 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(handle); 214 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(handle);
237 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 215 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
238 216
239 // Get the thread's priority. 217 // Get the thread's priority.
@@ -241,14 +219,10 @@ Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle)
241 return ResultSuccess; 219 return ResultSuccess;
242} 220}
243 221
244Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle) {
245 return GetThreadPriority(system, out_priority, handle);
246}
247
248/// Sets the priority for the specified thread 222/// Sets the priority for the specified thread
249Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { 223Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priority) {
250 // Get the current process. 224 // Get the current process.
251 KProcess& process = *system.Kernel().CurrentProcess(); 225 KProcess& process = GetCurrentProcess(system.Kernel());
252 226
253 // Validate the priority. 227 // Validate the priority.
254 R_UNLESS(HighestThreadPriority <= priority && priority <= LowestThreadPriority, 228 R_UNLESS(HighestThreadPriority <= priority && priority <= LowestThreadPriority,
@@ -264,12 +238,8 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priorit
264 return ResultSuccess; 238 return ResultSuccess;
265} 239}
266 240
267Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { 241Result GetThreadList(Core::System& system, s32* out_num_threads, VAddr out_thread_ids,
268 return SetThreadPriority(system, thread_handle, priority); 242 s32 out_thread_ids_size, Handle debug_handle) {
269}
270
271Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids,
272 u32 out_thread_ids_size, Handle debug_handle) {
273 // TODO: Handle this case when debug events are supported. 243 // TODO: Handle this case when debug events are supported.
274 UNIMPLEMENTED_IF(debug_handle != InvalidHandle); 244 UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
275 245
@@ -283,7 +253,7 @@ Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_threa
283 return ResultOutOfRange; 253 return ResultOutOfRange;
284 } 254 }
285 255
286 auto* const current_process = system.Kernel().CurrentProcess(); 256 auto* const current_process = GetCurrentProcessPointer(system.Kernel());
287 const auto total_copy_size = out_thread_ids_size * sizeof(u64); 257 const auto total_copy_size = out_thread_ids_size * sizeof(u64);
288 258
289 if (out_thread_ids_size > 0 && 259 if (out_thread_ids_size > 0 &&
@@ -296,7 +266,7 @@ Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_threa
296 auto& memory = system.Memory(); 266 auto& memory = system.Memory();
297 const auto& thread_list = current_process->GetThreadList(); 267 const auto& thread_list = current_process->GetThreadList();
298 const auto num_threads = thread_list.size(); 268 const auto num_threads = thread_list.size();
299 const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); 269 const auto copy_amount = std::min(static_cast<std::size_t>(out_thread_ids_size), num_threads);
300 270
301 auto list_iter = thread_list.cbegin(); 271 auto list_iter = thread_list.cbegin();
302 for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { 272 for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) {
@@ -308,13 +278,13 @@ Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_threa
308 return ResultSuccess; 278 return ResultSuccess;
309} 279}
310 280
311Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, 281Result GetThreadCoreMask(Core::System& system, s32* out_core_id, u64* out_affinity_mask,
312 u64* out_affinity_mask) { 282 Handle thread_handle) {
313 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); 283 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
314 284
315 // Get the thread from its handle. 285 // Get the thread from its handle.
316 KScopedAutoObject thread = 286 KScopedAutoObject thread =
317 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); 287 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
318 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 288 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
319 289
320 // Get the core mask. 290 // Get the core mask.
@@ -323,24 +293,15 @@ Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_co
323 return ResultSuccess; 293 return ResultSuccess;
324} 294}
325 295
326Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id,
327 u32* out_affinity_mask_low, u32* out_affinity_mask_high) {
328 u64 out_affinity_mask{};
329 const auto result = GetThreadCoreMask(system, thread_handle, out_core_id, &out_affinity_mask);
330 *out_affinity_mask_high = static_cast<u32>(out_affinity_mask >> 32);
331 *out_affinity_mask_low = static_cast<u32>(out_affinity_mask);
332 return result;
333}
334
335Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, 296Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id,
336 u64 affinity_mask) { 297 u64 affinity_mask) {
337 // Determine the core id/affinity mask. 298 // Determine the core id/affinity mask.
338 if (core_id == IdealCoreUseProcessValue) { 299 if (core_id == IdealCoreUseProcessValue) {
339 core_id = system.Kernel().CurrentProcess()->GetIdealCoreId(); 300 core_id = GetCurrentProcess(system.Kernel()).GetIdealCoreId();
340 affinity_mask = (1ULL << core_id); 301 affinity_mask = (1ULL << core_id);
341 } else { 302 } else {
342 // Validate the affinity mask. 303 // Validate the affinity mask.
343 const u64 process_core_mask = system.Kernel().CurrentProcess()->GetCoreMask(); 304 const u64 process_core_mask = GetCurrentProcess(system.Kernel()).GetCoreMask();
344 R_UNLESS((affinity_mask | process_core_mask) == process_core_mask, ResultInvalidCoreId); 305 R_UNLESS((affinity_mask | process_core_mask) == process_core_mask, ResultInvalidCoreId);
345 R_UNLESS(affinity_mask != 0, ResultInvalidCombination); 306 R_UNLESS(affinity_mask != 0, ResultInvalidCombination);
346 307
@@ -355,7 +316,7 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id
355 316
356 // Get the thread from its handle. 317 // Get the thread from its handle.
357 KScopedAutoObject thread = 318 KScopedAutoObject thread =
358 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); 319 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
359 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 320 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
360 321
361 // Set the core mask. 322 // Set the core mask.
@@ -364,17 +325,11 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id
364 return ResultSuccess; 325 return ResultSuccess;
365} 326}
366 327
367Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id,
368 u32 affinity_mask_low, u32 affinity_mask_high) {
369 const auto affinity_mask = u64{affinity_mask_low} | (u64{affinity_mask_high} << 32);
370 return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask);
371}
372
373/// Get the ID for the specified thread. 328/// Get the ID for the specified thread.
374Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { 329Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
375 // Get the thread from its handle. 330 // Get the thread from its handle.
376 KScopedAutoObject thread = 331 KScopedAutoObject thread =
377 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); 332 GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
378 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); 333 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
379 334
380 // Get the thread's id. 335 // Get the thread's id.
@@ -382,15 +337,101 @@ Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handl
382 return ResultSuccess; 337 return ResultSuccess;
383} 338}
384 339
385Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high, 340Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg,
386 Handle thread_handle) { 341 uint64_t stack_bottom, int32_t priority, int32_t core_id) {
387 u64 out_thread_id{}; 342 R_RETURN(CreateThread(system, out_handle, func, arg, stack_bottom, priority, core_id));
388 const Result result{GetThreadId(system, &out_thread_id, thread_handle)}; 343}
344
345Result StartThread64(Core::System& system, Handle thread_handle) {
346 R_RETURN(StartThread(system, thread_handle));
347}
348
349void ExitThread64(Core::System& system) {
350 return ExitThread(system);
351}
352
353void SleepThread64(Core::System& system, int64_t ns) {
354 return SleepThread(system, ns);
355}
356
357Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle) {
358 R_RETURN(GetThreadPriority(system, out_priority, thread_handle));
359}
360
361Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority) {
362 R_RETURN(SetThreadPriority(system, thread_handle, priority));
363}
364
365Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask,
366 Handle thread_handle) {
367 R_RETURN(GetThreadCoreMask(system, out_core_id, out_affinity_mask, thread_handle));
368}
369
370Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id,
371 uint64_t affinity_mask) {
372 R_RETURN(SetThreadCoreMask(system, thread_handle, core_id, affinity_mask));
373}
374
375Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle) {
376 R_RETURN(GetThreadId(system, out_thread_id, thread_handle));
377}
378
379Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle) {
380 R_RETURN(GetThreadContext3(system, out_context, thread_handle));
381}
389 382
390 *out_thread_id_low = static_cast<u32>(out_thread_id >> 32); 383Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids,
391 *out_thread_id_high = static_cast<u32>(out_thread_id & std::numeric_limits<u32>::max()); 384 int32_t max_out_count, Handle debug_handle) {
385 R_RETURN(GetThreadList(system, out_num_threads, out_thread_ids, max_out_count, debug_handle));
386}
387
388Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg,
389 uint32_t stack_bottom, int32_t priority, int32_t core_id) {
390 R_RETURN(CreateThread(system, out_handle, func, arg, stack_bottom, priority, core_id));
391}
392
393Result StartThread64From32(Core::System& system, Handle thread_handle) {
394 R_RETURN(StartThread(system, thread_handle));
395}
396
397void ExitThread64From32(Core::System& system) {
398 return ExitThread(system);
399}
400
401void SleepThread64From32(Core::System& system, int64_t ns) {
402 return SleepThread(system, ns);
403}
404
405Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority,
406 Handle thread_handle) {
407 R_RETURN(GetThreadPriority(system, out_priority, thread_handle));
408}
409
410Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority) {
411 R_RETURN(SetThreadPriority(system, thread_handle, priority));
412}
413
414Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id,
415 uint64_t* out_affinity_mask, Handle thread_handle) {
416 R_RETURN(GetThreadCoreMask(system, out_core_id, out_affinity_mask, thread_handle));
417}
418
419Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id,
420 uint64_t affinity_mask) {
421 R_RETURN(SetThreadCoreMask(system, thread_handle, core_id, affinity_mask));
422}
423
424Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle) {
425 R_RETURN(GetThreadId(system, out_thread_id, thread_handle));
426}
427
428Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle) {
429 R_RETURN(GetThreadContext3(system, out_context, thread_handle));
430}
392 431
393 return result; 432Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads,
433 uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle) {
434 R_RETURN(GetThreadList(system, out_num_threads, out_thread_ids, max_out_count, debug_handle));
394} 435}
395 436
396} // namespace Kernel::Svc 437} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_thread_profiler.cpp b/src/core/hle/kernel/svc/svc_thread_profiler.cpp
index 299e22ae6..40de7708b 100644
--- a/src/core/hle/kernel/svc/svc_thread_profiler.cpp
+++ b/src/core/hle/kernel/svc/svc_thread_profiler.cpp
@@ -2,5 +2,59 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/svc.h" 4#include "core/hle/kernel/svc.h"
5#include "core/hle/kernel/svc_results.h"
5 6
6namespace Kernel::Svc {} // namespace Kernel::Svc 7namespace Kernel::Svc {
8
9Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context,
10 uint64_t* out_thread_id, Handle debug_handle, int64_t ns) {
11 UNIMPLEMENTED();
12 R_THROW(ResultNotImplemented);
13}
14
15Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context,
16 uint64_t* out_tls_address, uint32_t* out_flags) {
17 UNIMPLEMENTED();
18 R_THROW(ResultNotImplemented);
19}
20
21Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context,
22 uint64_t* out_thread_id, Handle debug_handle, int64_t ns) {
23 R_RETURN(GetDebugFutureThreadInfo(system, out_context, out_thread_id, debug_handle, ns));
24}
25
26Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context,
27 uint64_t* out_tls_address, uint32_t* out_flags) {
28 R_RETURN(GetLastThreadInfo(system, out_context, out_tls_address, out_flags));
29}
30
31Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context,
32 uint64_t* out_thread_id, Handle debug_handle, int64_t ns) {
33 lp64::LastThreadContext context{};
34 R_TRY(
35 GetDebugFutureThreadInfo(system, std::addressof(context), out_thread_id, debug_handle, ns));
36
37 *out_context = {
38 .fp = static_cast<u32>(context.fp),
39 .sp = static_cast<u32>(context.sp),
40 .lr = static_cast<u32>(context.lr),
41 .pc = static_cast<u32>(context.pc),
42 };
43 R_SUCCEED();
44}
45
46Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context,
47 uint64_t* out_tls_address, uint32_t* out_flags) {
48 lp64::LastThreadContext context{};
49 R_TRY(GetLastThreadInfo(system, std::addressof(context), out_tls_address, out_flags));
50
51 *out_context = {
52 .fp = static_cast<u32>(context.fp),
53 .sp = static_cast<u32>(context.sp),
54 .lr = static_cast<u32>(context.lr),
55 .pc = static_cast<u32>(context.pc),
56 };
57 R_SUCCEED();
58}
59
60} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_tick.cpp b/src/core/hle/kernel/svc/svc_tick.cpp
index e9b4fd5a6..561336482 100644
--- a/src/core/hle/kernel/svc/svc_tick.cpp
+++ b/src/core/hle/kernel/svc/svc_tick.cpp
@@ -9,7 +9,7 @@
9namespace Kernel::Svc { 9namespace Kernel::Svc {
10 10
11/// This returns the total CPU ticks elapsed since the CPU was powered-on 11/// This returns the total CPU ticks elapsed since the CPU was powered-on
12u64 GetSystemTick(Core::System& system) { 12int64_t GetSystemTick(Core::System& system) {
13 LOG_TRACE(Kernel_SVC, "called"); 13 LOG_TRACE(Kernel_SVC, "called");
14 14
15 auto& core_timing = system.CoreTiming(); 15 auto& core_timing = system.CoreTiming();
@@ -21,13 +21,15 @@ u64 GetSystemTick(Core::System& system) {
21 core_timing.AddTicks(400U); 21 core_timing.AddTicks(400U);
22 } 22 }
23 23
24 return result; 24 return static_cast<int64_t>(result);
25} 25}
26 26
27void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) { 27int64_t GetSystemTick64(Core::System& system) {
28 const auto time = GetSystemTick(system); 28 return GetSystemTick(system);
29 *time_low = static_cast<u32>(time); 29}
30 *time_high = static_cast<u32>(time >> 32); 30
31int64_t GetSystemTick64From32(Core::System& system) {
32 return GetSystemTick(system);
31} 33}
32 34
33} // namespace Kernel::Svc 35} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp
index b14ae24a1..7ffc24adf 100644
--- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp
+++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp
@@ -39,11 +39,11 @@ Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u6
39 R_UNLESS(IsValidTransferMemoryPermission(map_perm), ResultInvalidNewMemoryPermission); 39 R_UNLESS(IsValidTransferMemoryPermission(map_perm), ResultInvalidNewMemoryPermission);
40 40
41 // Get the current process and handle table. 41 // Get the current process and handle table.
42 auto& process = *kernel.CurrentProcess(); 42 auto& process = GetCurrentProcess(kernel);
43 auto& handle_table = process.GetHandleTable(); 43 auto& handle_table = process.GetHandleTable();
44 44
45 // Reserve a new transfer memory from the process resource limit. 45 // Reserve a new transfer memory from the process resource limit.
46 KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), 46 KScopedResourceReservation trmem_reservation(&process,
47 LimitableResource::TransferMemoryCountMax); 47 LimitableResource::TransferMemoryCountMax);
48 R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached); 48 R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached);
49 49
@@ -72,8 +72,46 @@ Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u6
72 return ResultSuccess; 72 return ResultSuccess;
73} 73}
74 74
75Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, 75Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size,
76 MemoryPermission map_perm) { 76 MemoryPermission owner_perm) {
77 return CreateTransferMemory(system, out, address, size, map_perm); 77 UNIMPLEMENTED();
78 R_THROW(ResultNotImplemented);
78} 79}
80
81Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address,
82 uint64_t size) {
83 UNIMPLEMENTED();
84 R_THROW(ResultNotImplemented);
85}
86
87Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address,
88 uint64_t size, MemoryPermission owner_perm) {
89 R_RETURN(MapTransferMemory(system, trmem_handle, address, size, owner_perm));
90}
91
92Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address,
93 uint64_t size) {
94 R_RETURN(UnmapTransferMemory(system, trmem_handle, address, size));
95}
96
97Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address,
98 uint64_t size, MemoryPermission map_perm) {
99 R_RETURN(CreateTransferMemory(system, out_handle, address, size, map_perm));
100}
101
102Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address,
103 uint32_t size, MemoryPermission owner_perm) {
104 R_RETURN(MapTransferMemory(system, trmem_handle, address, size, owner_perm));
105}
106
107Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address,
108 uint32_t size) {
109 R_RETURN(UnmapTransferMemory(system, trmem_handle, address, size));
110}
111
112Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address,
113 uint32_t size, MemoryPermission map_perm) {
114 R_RETURN(CreateTransferMemory(system, out_handle, address, size, map_perm));
115}
116
79} // namespace Kernel::Svc 117} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc_generator.py b/src/core/hle/kernel/svc_generator.py
new file mode 100644
index 000000000..34d2ac659
--- /dev/null
+++ b/src/core/hle/kernel/svc_generator.py
@@ -0,0 +1,716 @@
1# SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2# SPDX-License-Identifier: GPL-2.0-or-later
3
4# Raw SVC definitions from the kernel.
5#
6# Avoid modifying the prototypes; see below for how to customize generation
7# for a given typename.
8SVCS = [
9 [0x01, "Result SetHeapSize(Address* out_address, Size size);"],
10 [0x02, "Result SetMemoryPermission(Address address, Size size, MemoryPermission perm);"],
11 [0x03, "Result SetMemoryAttribute(Address address, Size size, uint32_t mask, uint32_t attr);"],
12 [0x04, "Result MapMemory(Address dst_address, Address src_address, Size size);"],
13 [0x05, "Result UnmapMemory(Address dst_address, Address src_address, Size size);"],
14 [0x06, "Result QueryMemory(Address out_memory_info, PageInfo* out_page_info, Address address);"],
15 [0x07, "void ExitProcess();"],
16 [0x08, "Result CreateThread(Handle* out_handle, ThreadFunc func, Address arg, Address stack_bottom, int32_t priority, int32_t core_id);"],
17 [0x09, "Result StartThread(Handle thread_handle);"],
18 [0x0A, "void ExitThread();"],
19 [0x0B, "void SleepThread(int64_t ns);"],
20 [0x0C, "Result GetThreadPriority(int32_t* out_priority, Handle thread_handle);"],
21 [0x0D, "Result SetThreadPriority(Handle thread_handle, int32_t priority);"],
22 [0x0E, "Result GetThreadCoreMask(int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);"],
23 [0x0F, "Result SetThreadCoreMask(Handle thread_handle, int32_t core_id, uint64_t affinity_mask);"],
24 [0x10, "int32_t GetCurrentProcessorNumber();"],
25 [0x11, "Result SignalEvent(Handle event_handle);"],
26 [0x12, "Result ClearEvent(Handle event_handle);"],
27 [0x13, "Result MapSharedMemory(Handle shmem_handle, Address address, Size size, MemoryPermission map_perm);"],
28 [0x14, "Result UnmapSharedMemory(Handle shmem_handle, Address address, Size size);"],
29 [0x15, "Result CreateTransferMemory(Handle* out_handle, Address address, Size size, MemoryPermission map_perm);"],
30 [0x16, "Result CloseHandle(Handle handle);"],
31 [0x17, "Result ResetSignal(Handle handle);"],
32 [0x18, "Result WaitSynchronization(int32_t* out_index, Address handles, int32_t num_handles, int64_t timeout_ns);"],
33 [0x19, "Result CancelSynchronization(Handle handle);"],
34 [0x1A, "Result ArbitrateLock(Handle thread_handle, Address address, uint32_t tag);"],
35 [0x1B, "Result ArbitrateUnlock(Address address);"],
36 [0x1C, "Result WaitProcessWideKeyAtomic(Address address, Address cv_key, uint32_t tag, int64_t timeout_ns);"],
37 [0x1D, "void SignalProcessWideKey(Address cv_key, int32_t count);"],
38 [0x1E, "int64_t GetSystemTick();"],
39 [0x1F, "Result ConnectToNamedPort(Handle* out_handle, Address name);"],
40 [0x20, "Result SendSyncRequestLight(Handle session_handle);"],
41 [0x21, "Result SendSyncRequest(Handle session_handle);"],
42 [0x22, "Result SendSyncRequestWithUserBuffer(Address message_buffer, Size message_buffer_size, Handle session_handle);"],
43 [0x23, "Result SendAsyncRequestWithUserBuffer(Handle* out_event_handle, Address message_buffer, Size message_buffer_size, Handle session_handle);"],
44 [0x24, "Result GetProcessId(uint64_t* out_process_id, Handle process_handle);"],
45 [0x25, "Result GetThreadId(uint64_t* out_thread_id, Handle thread_handle);"],
46 [0x26, "void Break(BreakReason break_reason, Address arg, Size size);"],
47 [0x27, "Result OutputDebugString(Address debug_str, Size len);"],
48 [0x28, "void ReturnFromException(Result result);"],
49 [0x29, "Result GetInfo(uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);"],
50 [0x2A, "void FlushEntireDataCache();"],
51 [0x2B, "Result FlushDataCache(Address address, Size size);"],
52 [0x2C, "Result MapPhysicalMemory(Address address, Size size);"],
53 [0x2D, "Result UnmapPhysicalMemory(Address address, Size size);"],
54 [0x2E, "Result GetDebugFutureThreadInfo(LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);"],
55 [0x2F, "Result GetLastThreadInfo(LastThreadContext* out_context, Address* out_tls_address, uint32_t* out_flags);"],
56 [0x30, "Result GetResourceLimitLimitValue(int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);"],
57 [0x31, "Result GetResourceLimitCurrentValue(int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);"],
58 [0x32, "Result SetThreadActivity(Handle thread_handle, ThreadActivity thread_activity);"],
59 [0x33, "Result GetThreadContext3(Address out_context, Handle thread_handle);"],
60 [0x34, "Result WaitForAddress(Address address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);"],
61 [0x35, "Result SignalToAddress(Address address, SignalType signal_type, int32_t value, int32_t count);"],
62 [0x36, "void SynchronizePreemptionState();"],
63 [0x37, "Result GetResourceLimitPeakValue(int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);"],
64
65 [0x39, "Result CreateIoPool(Handle* out_handle, IoPoolType which);"],
66 [0x3A, "Result CreateIoRegion(Handle* out_handle, Handle io_pool, PhysicalAddress physical_address, Size size, MemoryMapping mapping, MemoryPermission perm);"],
67
68 [0x3C, "void KernelDebug(KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);"],
69 [0x3D, "void ChangeKernelTraceState(KernelTraceState kern_trace_state);"],
70
71 [0x40, "Result CreateSession(Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, Address name);"],
72 [0x41, "Result AcceptSession(Handle* out_handle, Handle port);"],
73 [0x42, "Result ReplyAndReceiveLight(Handle handle);"],
74 [0x43, "Result ReplyAndReceive(int32_t* out_index, Address handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);"],
75 [0x44, "Result ReplyAndReceiveWithUserBuffer(int32_t* out_index, Address message_buffer, Size message_buffer_size, Address handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);"],
76 [0x45, "Result CreateEvent(Handle* out_write_handle, Handle* out_read_handle);"],
77 [0x46, "Result MapIoRegion(Handle io_region, Address address, Size size, MemoryPermission perm);"],
78 [0x47, "Result UnmapIoRegion(Handle io_region, Address address, Size size);"],
79 [0x48, "Result MapPhysicalMemoryUnsafe(Address address, Size size);"],
80 [0x49, "Result UnmapPhysicalMemoryUnsafe(Address address, Size size);"],
81 [0x4A, "Result SetUnsafeLimit(Size limit);"],
82 [0x4B, "Result CreateCodeMemory(Handle* out_handle, Address address, Size size);"],
83 [0x4C, "Result ControlCodeMemory(Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);"],
84 [0x4D, "void SleepSystem();"],
85 [0x4E, "Result ReadWriteRegister(uint32_t* out_value, PhysicalAddress address, uint32_t mask, uint32_t value);"],
86 [0x4F, "Result SetProcessActivity(Handle process_handle, ProcessActivity process_activity);"],
87 [0x50, "Result CreateSharedMemory(Handle* out_handle, Size size, MemoryPermission owner_perm, MemoryPermission remote_perm);"],
88 [0x51, "Result MapTransferMemory(Handle trmem_handle, Address address, Size size, MemoryPermission owner_perm);"],
89 [0x52, "Result UnmapTransferMemory(Handle trmem_handle, Address address, Size size);"],
90 [0x53, "Result CreateInterruptEvent(Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);"],
91 [0x54, "Result QueryPhysicalAddress(PhysicalMemoryInfo* out_info, Address address);"],
92 [0x55, "Result QueryIoMapping(Address* out_address, Size* out_size, PhysicalAddress physical_address, Size size);"],
93 [0x56, "Result CreateDeviceAddressSpace(Handle* out_handle, uint64_t das_address, uint64_t das_size);"],
94 [0x57, "Result AttachDeviceAddressSpace(DeviceName device_name, Handle das_handle);"],
95 [0x58, "Result DetachDeviceAddressSpace(DeviceName device_name, Handle das_handle);"],
96 [0x59, "Result MapDeviceAddressSpaceByForce(Handle das_handle, Handle process_handle, uint64_t process_address, Size size, uint64_t device_address, uint32_t option);"],
97 [0x5A, "Result MapDeviceAddressSpaceAligned(Handle das_handle, Handle process_handle, uint64_t process_address, Size size, uint64_t device_address, uint32_t option);"],
98 [0x5C, "Result UnmapDeviceAddressSpace(Handle das_handle, Handle process_handle, uint64_t process_address, Size size, uint64_t device_address);"],
99 [0x5D, "Result InvalidateProcessDataCache(Handle process_handle, uint64_t address, uint64_t size);"],
100 [0x5E, "Result StoreProcessDataCache(Handle process_handle, uint64_t address, uint64_t size);"],
101 [0x5F, "Result FlushProcessDataCache(Handle process_handle, uint64_t address, uint64_t size);"],
102 [0x60, "Result DebugActiveProcess(Handle* out_handle, uint64_t process_id);"],
103 [0x61, "Result BreakDebugProcess(Handle debug_handle);"],
104 [0x62, "Result TerminateDebugProcess(Handle debug_handle);"],
105 [0x63, "Result GetDebugEvent(Address out_info, Handle debug_handle);"],
106 [0x64, "Result ContinueDebugEvent(Handle debug_handle, uint32_t flags, Address thread_ids, int32_t num_thread_ids);"],
107 [0x65, "Result GetProcessList(int32_t* out_num_processes, Address out_process_ids, int32_t max_out_count);"],
108 [0x66, "Result GetThreadList(int32_t* out_num_threads, Address out_thread_ids, int32_t max_out_count, Handle debug_handle);"],
109 [0x67, "Result GetDebugThreadContext(Address out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);"],
110 [0x68, "Result SetDebugThreadContext(Handle debug_handle, uint64_t thread_id, Address context, uint32_t context_flags);"],
111 [0x69, "Result QueryDebugProcessMemory(Address out_memory_info, PageInfo* out_page_info, Handle process_handle, Address address);"],
112 [0x6A, "Result ReadDebugProcessMemory(Address buffer, Handle debug_handle, Address address, Size size);"],
113 [0x6B, "Result WriteDebugProcessMemory(Handle debug_handle, Address buffer, Address address, Size size);"],
114 [0x6C, "Result SetHardwareBreakPoint(HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);"],
115 [0x6D, "Result GetDebugThreadParam(uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);"],
116
117 [0x6F, "Result GetSystemInfo(uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);"],
118 [0x70, "Result CreatePort(Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, Address name);"],
119 [0x71, "Result ManageNamedPort(Handle* out_server_handle, Address name, int32_t max_sessions);"],
120 [0x72, "Result ConnectToPort(Handle* out_handle, Handle port);"],
121 [0x73, "Result SetProcessMemoryPermission(Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);"],
122 [0x74, "Result MapProcessMemory(Address dst_address, Handle process_handle, uint64_t src_address, Size size);"],
123 [0x75, "Result UnmapProcessMemory(Address dst_address, Handle process_handle, uint64_t src_address, Size size);"],
124 [0x76, "Result QueryProcessMemory(Address out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);"],
125 [0x77, "Result MapProcessCodeMemory(Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);"],
126 [0x78, "Result UnmapProcessCodeMemory(Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);"],
127 [0x79, "Result CreateProcess(Handle* out_handle, Address parameters, Address caps, int32_t num_caps);"],
128 [0x7A, "Result StartProcess(Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);"],
129 [0x7B, "Result TerminateProcess(Handle process_handle);"],
130 [0x7C, "Result GetProcessInfo(int64_t* out_info, Handle process_handle, ProcessInfoType info_type);"],
131 [0x7D, "Result CreateResourceLimit(Handle* out_handle);"],
132 [0x7E, "Result SetResourceLimitLimitValue(Handle resource_limit_handle, LimitableResource which, int64_t limit_value);"],
133 [0x7F, "void CallSecureMonitor(SecureMonitorArguments args);"],
134
135 [0x90, "Result MapInsecureMemory(Address address, Size size);"],
136 [0x91, "Result UnmapInsecureMemory(Address address, Size size);"],
137]
138
139# These use a custom ABI, and therefore require custom wrappers
140SKIP_WRAPPERS = {
141 0x20: "SendSyncRequestLight",
142 0x42: "ReplyAndReceiveLight",
143 0x7F: "CallSecureMonitor",
144}
145
146BIT_32 = 0
147BIT_64 = 1
148
149REG_SIZES = [4, 8]
150SUFFIX_NAMES = ["64From32", "64"]
151TYPE_SIZES = {
152 # SVC types
153 "ArbitrationType": 4,
154 "BreakReason": 4,
155 "CodeMemoryOperation": 4,
156 "DebugThreadParam": 4,
157 "DeviceName": 4,
158 "HardwareBreakPointRegisterName": 4,
159 "Handle": 4,
160 "InfoType": 4,
161 "InterruptType": 4,
162 "IoPoolType": 4,
163 "KernelDebugType": 4,
164 "KernelTraceState": 4,
165 "LimitableResource": 4,
166 "MemoryMapping": 4,
167 "MemoryPermission": 4,
168 "PageInfo": 4,
169 "ProcessActivity": 4,
170 "ProcessInfoType": 4,
171 "Result": 4,
172 "SignalType": 4,
173 "SystemInfoType": 4,
174 "ThreadActivity": 4,
175
176 # Arch-specific types
177 "ilp32::LastThreadContext": 16,
178 "ilp32::PhysicalMemoryInfo": 16,
179 "ilp32::SecureMonitorArguments": 32,
180 "lp64::LastThreadContext": 32,
181 "lp64::PhysicalMemoryInfo": 24,
182 "lp64::SecureMonitorArguments": 64,
183
184 # Generic types
185 "bool": 1,
186 "int32_t": 4,
187 "int64_t": 8,
188 "uint32_t": 4,
189 "uint64_t": 8,
190 "void": 0,
191}
192
193TYPE_REPLACEMENTS = {
194 "Address": ["uint32_t", "uint64_t"],
195 "LastThreadContext": ["ilp32::LastThreadContext", "lp64::LastThreadContext"],
196 "PhysicalAddress": ["uint64_t", "uint64_t"],
197 "PhysicalMemoryInfo": ["ilp32::PhysicalMemoryInfo", "lp64::PhysicalMemoryInfo"],
198 "SecureMonitorArguments": ["ilp32::SecureMonitorArguments", "lp64::SecureMonitorArguments"],
199 "Size": ["uint32_t", "uint64_t"],
200 "ThreadFunc": ["uint32_t", "uint64_t"],
201}
202
203# Statically verify that the hardcoded sizes match the intended
204# sizes in C++.
205def emit_size_check():
206 lines = []
207
208 for type, size in TYPE_SIZES.items():
209 if type != "void":
210 lines.append(f"static_assert(sizeof({type}) == {size});")
211
212 return "\n".join(lines)
213
214
215# Replaces a type with an arch-specific one, if it exists.
216def substitute_type(name, bitness):
217 if name in TYPE_REPLACEMENTS:
218 return TYPE_REPLACEMENTS[name][bitness]
219 else:
220 return name
221
222
223class Argument:
224 def __init__(self, type_name, var_name, is_output, is_outptr, is_address):
225 self.type_name = type_name
226 self.var_name = var_name
227 self.is_output = is_output
228 self.is_outptr = is_outptr
229 self.is_address = is_address
230
231
232# Parses C-style string declarations for SVCs.
233def parse_declaration(declaration, bitness):
234 return_type, rest = declaration.split(" ", 1)
235 func_name, rest = rest.split("(", 1)
236 arg_names, rest = rest.split(")", 1)
237 argument_types = []
238
239 return_type = substitute_type(return_type, bitness)
240 assert return_type in TYPE_SIZES, f"Unknown type '{return_type}'"
241
242 if arg_names:
243 for arg_name in arg_names.split(", "):
244 type_name, var_name = arg_name.replace("*", "").split(" ", 1)
245
246 # All outputs must contain out_ in the name.
247 is_output = var_name == "out" or var_name.find("out_") != -1
248
249 # User-pointer outputs are not written to registers.
250 is_outptr = is_output and arg_name.find("*") == -1
251
252 # Special handling is performed for output addresses to avoid awkwardness
253 # in conversion for the 32-bit equivalents.
254 is_address = is_output and not is_outptr and \
255 type_name in ["Address", "Size"]
256 type_name = substitute_type(type_name, bitness)
257
258 assert type_name in TYPE_SIZES, f"Unknown type '{type_name}'"
259
260 argument_types.append(
261 Argument(type_name, var_name, is_output, is_outptr, is_address))
262
263 return (return_type, func_name, argument_types)
264
265
266class RegisterAllocator:
267 def __init__(self, num_regs, byte_size, parameter_count):
268 self.registers = {}
269 self.num_regs = num_regs
270 self.byte_size = byte_size
271 self.parameter_count = parameter_count
272
273 # Mark the given register as allocated, for use in layout
274 # calculation if the NGRN exceeds the ABI parameter count.
275 def allocate(self, i):
276 assert i not in self.registers, f"Register R{i} already allocated"
277 self.registers[i] = True
278 return i
279
280 # Calculate the next available location for a register;
281 # the NGRN has exceeded the ABI parameter count.
282 def allocate_first_free(self):
283 for i in range(0, self.num_regs):
284 if i in self.registers:
285 continue
286
287 self.allocate(i)
288 return i
289
290 assert False, "No registers available"
291
292 # Add a single register at the given NGRN.
293 # If the index exceeds the ABI parameter count, try to find a
294 # location to add it. Returns the output location and increment.
295 def add_single(self, ngrn):
296 if ngrn >= self.parameter_count:
297 return (self.allocate_first_free(), 0)
298 else:
299 return (self.allocate(ngrn), 1)
300
301 # Add registers at the given NGRN for a data type of
302 # the given size. Returns the output locations and increment.
303 def add(self, ngrn, data_size, align=True):
304 if data_size <= self.byte_size:
305 r, i = self.add_single(ngrn)
306 return ([r], i)
307
308 regs = []
309 inc = ngrn % 2 if align else 0
310 remaining_size = data_size
311 while remaining_size > 0:
312 r, i = self.add_single(ngrn + inc)
313 regs.append(r)
314 inc += i
315 remaining_size -= self.byte_size
316
317 return (regs, inc)
318
319
320def reg_alloc(bitness):
321 if bitness == 0:
322 # aapcs32: 4 4-byte registers
323 return RegisterAllocator(8, 4, 4)
324 elif bitness == 1:
325 # aapcs64: 8 8-byte registers
326 return RegisterAllocator(8, 8, 8)
327
328
329# Converts a parsed SVC declaration into register lists for
330# the return value, outputs, and inputs.
331def get_registers(parse_result, bitness):
332 output_alloc = reg_alloc(bitness)
333 input_alloc = reg_alloc(bitness)
334 return_type, _, arguments = parse_result
335
336 return_write = []
337 output_writes = []
338 input_reads = []
339
340 input_ngrn = 0
341 output_ngrn = 0
342
343 # Run the input calculation.
344 for arg in arguments:
345 if arg.is_output and not arg.is_outptr:
346 input_ngrn += 1
347 continue
348
349 regs, increment = input_alloc.add(
350 input_ngrn, TYPE_SIZES[arg.type_name], align=True)
351 input_reads.append([arg.type_name, arg.var_name, regs])
352 input_ngrn += increment
353
354 # Include the return value if this SVC returns a value.
355 if return_type != "void":
356 regs, increment = output_alloc.add(
357 output_ngrn, TYPE_SIZES[return_type], align=False)
358 return_write.append([return_type, regs])
359 output_ngrn += increment
360
361 # Run the output calculation.
362 for arg in arguments:
363 if not arg.is_output or arg.is_outptr:
364 continue
365
366 regs, increment = output_alloc.add(
367 output_ngrn, TYPE_SIZES[arg.type_name], align=False)
368 output_writes.append(
369 [arg.type_name, arg.var_name, regs, arg.is_address])
370 output_ngrn += increment
371
372 return (return_write, output_writes, input_reads)
373
374
375# Collects possibly multiple source registers into the named C++ value.
376def emit_gather(sources, name, type_name, reg_size):
377 get_fn = f"GetReg{reg_size*8}"
378
379 if len(sources) == 1:
380 s, = sources
381 line = f"{name} = Convert<{type_name}>({get_fn}(system, {s}));"
382 return [line]
383
384 var_type = f"std::array<uint{reg_size*8}_t, {len(sources)}>"
385 lines = [
386 f"{var_type} {name}_gather{{}};"
387 ]
388 for i in range(0, len(sources)):
389 lines.append(
390 f"{name}_gather[{i}] = {get_fn}(system, {sources[i]});")
391
392 lines.append(f"{name} = Convert<{type_name}>({name}_gather);")
393 return lines
394
395
396# Produces one or more statements which assign the named C++ value
397# into possibly multiple registers.
398def emit_scatter(destinations, name, reg_size):
399 set_fn = f"SetReg{reg_size*8}"
400 reg_type = f"uint{reg_size*8}_t"
401
402 if len(destinations) == 1:
403 d, = destinations
404 line = f"{set_fn}(system, {d}, Convert<{reg_type}>({name}));"
405 return [line]
406
407 var_type = f"std::array<{reg_type}, {len(destinations)}>"
408 lines = [
409 f"auto {name}_scatter = Convert<{var_type}>({name});"
410 ]
411
412 for i in range(0, len(destinations)):
413 lines.append(
414 f"{set_fn}(system, {destinations[i]}, {name}_scatter[{i}]);")
415
416 return lines
417
418
419def emit_lines(lines, indent=' '):
420 output_lines = []
421 first = True
422 for line in lines:
423 if line and not first:
424 output_lines.append(indent + line)
425 else:
426 output_lines.append(line)
427 first = False
428
429 return "\n".join(output_lines)
430
431
432# Emit a C++ function to wrap a guest SVC.
433def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size):
434 return_write, output_writes, input_reads = register_info
435 lines = [
436 f"static void SvcWrap_{wrapped_fn}{suffix}(Core::System& system) {{"
437 ]
438
439 # Get everything ready.
440 for return_type, _ in return_write:
441 lines.append(f"{return_type} ret{{}};")
442 if return_write:
443 lines.append("")
444
445 for output_type, var_name, _, is_address in output_writes:
446 output_type = "uintptr_t" if is_address else output_type
447 lines.append(f"{output_type} {var_name}{{}};")
448 for input_type, var_name, _ in input_reads:
449 lines.append(f"{input_type} {var_name}{{}};")
450
451 if output_writes or input_reads:
452 lines.append("")
453
454 for input_type, var_name, sources in input_reads:
455 lines += emit_gather(sources, var_name, input_type, byte_size)
456 if input_reads:
457 lines.append("")
458
459 # Build the call.
460 call_arguments = ["system"]
461 for arg in arguments:
462 if arg.is_output and not arg.is_outptr:
463 call_arguments.append(f"&{arg.var_name}")
464 else:
465 call_arguments.append(arg.var_name)
466
467 line = ""
468 if return_write:
469 line += "ret = "
470
471 line += f"{wrapped_fn}{suffix}({', '.join(call_arguments)});"
472 lines.append(line)
473
474 if return_write or output_writes:
475 lines.append("")
476
477 # Write back the return value and outputs.
478 for _, destinations in return_write:
479 lines += emit_scatter(destinations, "ret", byte_size)
480 for _, var_name, destinations, _ in output_writes:
481 lines += emit_scatter(destinations, var_name, byte_size)
482
483 # Finish.
484 return emit_lines(lines) + "\n}"
485
486
487COPYRIGHT = """\
488// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
489// SPDX-License-Identifier: GPL-2.0-or-later
490
491// This file is automatically generated using svc_generator.py.
492"""
493
494PROLOGUE_H = """
495#pragma once
496
497namespace Core {
498class System;
499}
500
501#include "common/common_types.h"
502#include "core/hle/kernel/svc_types.h"
503#include "core/hle/result.h"
504
505namespace Kernel::Svc {
506
507// clang-format off
508"""
509
510EPILOGUE_H = """
511// clang-format on
512
513// Custom ABI.
514Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args);
515Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args);
516Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args);
517
518Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args);
519Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args);
520Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args);
521
522void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args);
523void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args);
524void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args);
525
526// Defined in svc_light_ipc.cpp.
527void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system);
528void SvcWrap_ReplyAndReceiveLight64(Core::System& system);
529
530void SvcWrap_SendSyncRequestLight64From32(Core::System& system);
531void SvcWrap_SendSyncRequestLight64(Core::System& system);
532
533// Defined in svc_secure_monitor_call.cpp.
534void SvcWrap_CallSecureMonitor64From32(Core::System& system);
535void SvcWrap_CallSecureMonitor64(Core::System& system);
536
537// Perform a supervisor call by index.
538void Call(Core::System& system, u32 imm);
539
540} // namespace Kernel::Svc
541"""
542
543PROLOGUE_CPP = """
544#include <type_traits>
545
546#include "core/arm/arm_interface.h"
547#include "core/core.h"
548#include "core/hle/kernel/k_process.h"
549#include "core/hle/kernel/svc.h"
550
551namespace Kernel::Svc {
552
553static uint32_t GetReg32(Core::System& system, int n) {
554 return static_cast<uint32_t>(system.CurrentArmInterface().GetReg(n));
555}
556
557static void SetReg32(Core::System& system, int n, uint32_t result) {
558 system.CurrentArmInterface().SetReg(n, static_cast<uint64_t>(result));
559}
560
561static uint64_t GetReg64(Core::System& system, int n) {
562 return system.CurrentArmInterface().GetReg(n);
563}
564
565static void SetReg64(Core::System& system, int n, uint64_t result) {
566 system.CurrentArmInterface().SetReg(n, result);
567}
568
569// Like bit_cast, but handles the case when the source and dest
570// are differently-sized.
571template <typename To, typename From>
572 requires(std::is_trivial_v<To> && std::is_trivially_copyable_v<From>)
573static To Convert(const From& from) {
574 To to{};
575
576 if constexpr (sizeof(To) >= sizeof(From)) {
577 std::memcpy(&to, &from, sizeof(From));
578 } else {
579 std::memcpy(&to, &from, sizeof(To));
580 }
581
582 return to;
583}
584
585// clang-format off
586"""
587
588EPILOGUE_CPP = """
589// clang-format on
590
591void Call(Core::System& system, u32 imm) {
592 auto& kernel = system.Kernel();
593 kernel.EnterSVCProfile();
594
595 if (GetCurrentProcess(system.Kernel()).Is64BitProcess()) {
596 Call64(system, imm);
597 } else {
598 Call32(system, imm);
599 }
600
601 kernel.ExitSVCProfile();
602}
603
604} // namespace Kernel::Svc
605"""
606
607
608def emit_call(bitness, names, suffix):
609 bit_size = REG_SIZES[bitness]*8
610 indent = " "
611 lines = [
612 f"static void Call{bit_size}(Core::System& system, u32 imm) {{",
613 f"{indent}switch (static_cast<SvcId>(imm)) {{"
614 ]
615
616 for _, name in names:
617 lines.append(f"{indent}case SvcId::{name}:")
618 lines.append(f"{indent*2}return SvcWrap_{name}{suffix}(system);")
619
620 lines.append(f"{indent}default:")
621 lines.append(
622 f"{indent*2}LOG_CRITICAL(Kernel_SVC, \"Unknown SVC {{:x}}!\", imm);")
623 lines.append(f"{indent*2}break;")
624 lines.append(f"{indent}}}")
625 lines.append("}")
626
627 return "\n".join(lines)
628
629
630def build_fn_declaration(return_type, name, arguments):
631 arg_list = ["Core::System& system"]
632 for arg in arguments:
633 type_name = "uintptr_t" if arg.is_address else arg.type_name
634 pointer = "*" if arg.is_output and not arg.is_outptr else ""
635 arg_list.append(f"{type_name}{pointer} {arg.var_name}")
636
637 return f"{return_type} {name}({', '.join(arg_list)});"
638
639
640def build_enum_declarations():
641 lines = ["enum class SvcId : u32 {"]
642 indent = " "
643
644 for imm, decl in SVCS:
645 _, name, _ = parse_declaration(decl, BIT_64)
646 lines.append(f"{indent}{name} = {hex(imm)},")
647
648 lines.append("};")
649 return "\n".join(lines)
650
651
652def main():
653 arch_fw_declarations = [[], []]
654 svc_fw_declarations = []
655 wrapper_fns = []
656 names = []
657
658 for imm, decl in SVCS:
659 return_type, name, arguments = parse_declaration(decl, BIT_64)
660
661 if imm not in SKIP_WRAPPERS:
662 svc_fw_declarations.append(
663 build_fn_declaration(return_type, name, arguments))
664
665 names.append([imm, name])
666
667 for bitness in range(2):
668 byte_size = REG_SIZES[bitness]
669 suffix = SUFFIX_NAMES[bitness]
670
671 for imm, decl in SVCS:
672 if imm in SKIP_WRAPPERS:
673 continue
674
675 parse_result = parse_declaration(decl, bitness)
676 return_type, name, arguments = parse_result
677
678 register_info = get_registers(parse_result, bitness)
679 wrapper_fns.append(
680 emit_wrapper(name, suffix, register_info, arguments, byte_size))
681 arch_fw_declarations[bitness].append(
682 build_fn_declaration(return_type, name + suffix, arguments))
683
684 call_32 = emit_call(BIT_32, names, SUFFIX_NAMES[BIT_32])
685 call_64 = emit_call(BIT_64, names, SUFFIX_NAMES[BIT_64])
686 enum_decls = build_enum_declarations()
687
688 with open("svc.h", "w") as f:
689 f.write(COPYRIGHT)
690 f.write(PROLOGUE_H)
691 f.write("\n".join(svc_fw_declarations))
692 f.write("\n\n")
693 f.write("\n".join(arch_fw_declarations[BIT_32]))
694 f.write("\n\n")
695 f.write("\n".join(arch_fw_declarations[BIT_64]))
696 f.write("\n\n")
697 f.write(enum_decls)
698 f.write(EPILOGUE_H)
699
700 with open("svc.cpp", "w") as f:
701 f.write(COPYRIGHT)
702 f.write(PROLOGUE_CPP)
703 f.write(emit_size_check())
704 f.write("\n\n")
705 f.write("\n\n".join(wrapper_fns))
706 f.write("\n\n")
707 f.write(call_32)
708 f.write("\n\n")
709 f.write(call_64)
710 f.write(EPILOGUE_CPP)
711
712 print(f"Done (emitted {len(names)} definitions)")
713
714
715if __name__ == "__main__":
716 main()
diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h
index b7ca53085..e1ad78607 100644
--- a/src/core/hle/kernel/svc_results.h
+++ b/src/core/hle/kernel/svc_results.h
@@ -11,6 +11,7 @@ namespace Kernel {
11 11
12constexpr Result ResultOutOfSessions{ErrorModule::Kernel, 7}; 12constexpr Result ResultOutOfSessions{ErrorModule::Kernel, 7};
13constexpr Result ResultInvalidArgument{ErrorModule::Kernel, 14}; 13constexpr Result ResultInvalidArgument{ErrorModule::Kernel, 14};
14constexpr Result ResultNotImplemented{ErrorModule::Kernel, 33};
14constexpr Result ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; 15constexpr Result ResultNoSynchronizationObject{ErrorModule::Kernel, 57};
15constexpr Result ResultTerminationRequested{ErrorModule::Kernel, 59}; 16constexpr Result ResultTerminationRequested{ErrorModule::Kernel, 59};
16constexpr Result ResultInvalidSize{ErrorModule::Kernel, 101}; 17constexpr Result ResultInvalidSize{ErrorModule::Kernel, 101};
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index e90c35601..542c13461 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -168,6 +168,7 @@ enum class BreakReason : u32 {
168 168
169 NotificationOnlyFlag = 0x80000000, 169 NotificationOnlyFlag = 0x80000000,
170}; 170};
171DECLARE_ENUM_FLAG_OPERATORS(BreakReason);
171 172
172enum class DebugEvent : u32 { 173enum class DebugEvent : u32 {
173 CreateProcess = 0, 174 CreateProcess = 0,
@@ -596,6 +597,11 @@ enum class ProcessInfoType : u32 {
596 ProcessState = 0, 597 ProcessState = 0,
597}; 598};
598 599
600enum class ProcessActivity : u32 {
601 Runnable,
602 Paused,
603};
604
599struct CreateProcessParameter { 605struct CreateProcessParameter {
600 std::array<char, 12> name; 606 std::array<char, 12> name;
601 u32 version; 607 u32 version;
@@ -611,4 +617,9 @@ static_assert(sizeof(CreateProcessParameter) == 0x30);
611constexpr size_t NumSupervisorCalls = 0xC0; 617constexpr size_t NumSupervisorCalls = 0xC0;
612using SvcAccessFlagSet = std::bitset<NumSupervisorCalls>; 618using SvcAccessFlagSet = std::bitset<NumSupervisorCalls>;
613 619
620enum class InitialProcessIdRangeInfo : u64 {
621 Minimum = 0,
622 Maximum = 1,
623};
624
614} // namespace Kernel::Svc 625} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc_version.h b/src/core/hle/kernel/svc_version.h
index e4f47b34b..3eb95aa7b 100644
--- a/src/core/hle/kernel/svc_version.h
+++ b/src/core/hle/kernel/svc_version.h
@@ -35,11 +35,11 @@ constexpr inline u32 EncodeKernelVersion(u32 major, u32 minor) {
35} 35}
36 36
37constexpr inline u32 GetKernelMajorVersion(u32 encoded) { 37constexpr inline u32 GetKernelMajorVersion(u32 encoded) {
38 return std::bit_cast<decltype(KernelVersion::major_version)>(encoded).Value(); 38 return decltype(KernelVersion::major_version)::ExtractValue(encoded);
39} 39}
40 40
41constexpr inline u32 GetKernelMinorVersion(u32 encoded) { 41constexpr inline u32 GetKernelMinorVersion(u32 encoded) {
42 return std::bit_cast<decltype(KernelVersion::minor_version)>(encoded).Value(); 42 return decltype(KernelVersion::minor_version)::ExtractValue(encoded);
43} 43}
44 44
45// Nintendo doesn't support programs targeting SVC versions < 3.0. 45// Nintendo doesn't support programs targeting SVC versions < 3.0.
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
deleted file mode 100644
index 052be40dd..000000000
--- a/src/core/hle/kernel/svc_wrap.h
+++ /dev/null
@@ -1,733 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/common_types.h"
7#include "core/arm/arm_interface.h"
8#include "core/core.h"
9#include "core/hle/kernel/svc_types.h"
10#include "core/hle/result.h"
11#include "core/memory.h"
12
13namespace Kernel {
14
15static inline u64 Param(const Core::System& system, int n) {
16 return system.CurrentArmInterface().GetReg(n);
17}
18
19static inline u32 Param32(const Core::System& system, int n) {
20 return static_cast<u32>(system.CurrentArmInterface().GetReg(n));
21}
22
23/**
24 * HLE a function return from the current ARM userland process
25 * @param system System context
26 * @param result Result to return
27 */
28static inline void FuncReturn(Core::System& system, u64 result) {
29 system.CurrentArmInterface().SetReg(0, result);
30}
31
32static inline void FuncReturn32(Core::System& system, u32 result) {
33 system.CurrentArmInterface().SetReg(0, (u64)result);
34}
35
36////////////////////////////////////////////////////////////////////////////////////////////////////
37// Function wrappers that return type Result
38
39template <Result func(Core::System&, u64)>
40void SvcWrap64(Core::System& system) {
41 FuncReturn(system, func(system, Param(system, 0)).raw);
42}
43
44template <Result func(Core::System&, u64, u64)>
45void SvcWrap64(Core::System& system) {
46 FuncReturn(system, func(system, Param(system, 0), Param(system, 1)).raw);
47}
48
49template <Result func(Core::System&, u32)>
50void SvcWrap64(Core::System& system) {
51 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw);
52}
53
54template <Result func(Core::System&, u32, u32)>
55void SvcWrap64(Core::System& system) {
56 FuncReturn(
57 system,
58 func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw);
59}
60
61// Used by SetThreadActivity
62template <Result func(Core::System&, Handle, Svc::ThreadActivity)>
63void SvcWrap64(Core::System& system) {
64 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)),
65 static_cast<Svc::ThreadActivity>(Param(system, 1)))
66 .raw);
67}
68
69template <Result func(Core::System&, u32, u64, u64, u64)>
70void SvcWrap64(Core::System& system) {
71 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
72 Param(system, 2), Param(system, 3))
73 .raw);
74}
75
76// Used by MapProcessMemory and UnmapProcessMemory
77template <Result func(Core::System&, u64, u32, u64, u64)>
78void SvcWrap64(Core::System& system) {
79 FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)),
80 Param(system, 2), Param(system, 3))
81 .raw);
82}
83
84// Used by ControlCodeMemory
85template <Result func(Core::System&, Handle, u32, VAddr, size_t, Svc::MemoryPermission)>
86void SvcWrap64(Core::System& system) {
87 FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)),
88 static_cast<u32>(Param(system, 1)), Param(system, 2), Param(system, 3),
89 static_cast<Svc::MemoryPermission>(Param(system, 4)))
90 .raw);
91}
92
93template <Result func(Core::System&, u32*)>
94void SvcWrap64(Core::System& system) {
95 u32 param = 0;
96 const u32 retval = func(system, &param).raw;
97 system.CurrentArmInterface().SetReg(1, param);
98 FuncReturn(system, retval);
99}
100
101template <Result func(Core::System&, u32*, u32)>
102void SvcWrap64(Core::System& system) {
103 u32 param_1 = 0;
104 const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1))).raw;
105 system.CurrentArmInterface().SetReg(1, param_1);
106 FuncReturn(system, retval);
107}
108
109template <Result func(Core::System&, u32*, u32*)>
110void SvcWrap64(Core::System& system) {
111 u32 param_1 = 0;
112 u32 param_2 = 0;
113 const u32 retval = func(system, &param_1, &param_2).raw;
114
115 auto& arm_interface = system.CurrentArmInterface();
116 arm_interface.SetReg(1, param_1);
117 arm_interface.SetReg(2, param_2);
118
119 FuncReturn(system, retval);
120}
121
122template <Result func(Core::System&, u32*, u64)>
123void SvcWrap64(Core::System& system) {
124 u32 param_1 = 0;
125 const u32 retval = func(system, &param_1, Param(system, 1)).raw;
126 system.CurrentArmInterface().SetReg(1, param_1);
127 FuncReturn(system, retval);
128}
129
130template <Result func(Core::System&, u32*, u64, u32)>
131void SvcWrap64(Core::System& system) {
132 u32 param_1 = 0;
133 const u32 retval =
134 func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2))).raw;
135
136 system.CurrentArmInterface().SetReg(1, param_1);
137 FuncReturn(system, retval);
138}
139
140template <Result func(Core::System&, u64*, u32)>
141void SvcWrap64(Core::System& system) {
142 u64 param_1 = 0;
143 const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1))).raw;
144
145 system.CurrentArmInterface().SetReg(1, param_1);
146 FuncReturn(system, retval);
147}
148
149template <Result func(Core::System&, u64, u32)>
150void SvcWrap64(Core::System& system) {
151 FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw);
152}
153
154template <Result func(Core::System&, u64*, u64)>
155void SvcWrap64(Core::System& system) {
156 u64 param_1 = 0;
157 const u32 retval = func(system, &param_1, Param(system, 1)).raw;
158
159 system.CurrentArmInterface().SetReg(1, param_1);
160 FuncReturn(system, retval);
161}
162
163template <Result func(Core::System&, u64*, u32, u32)>
164void SvcWrap64(Core::System& system) {
165 u64 param_1 = 0;
166 const u32 retval = func(system, &param_1, static_cast<u32>(Param(system, 1)),
167 static_cast<u32>(Param(system, 2)))
168 .raw;
169
170 system.CurrentArmInterface().SetReg(1, param_1);
171 FuncReturn(system, retval);
172}
173
174// Used by GetResourceLimitLimitValue.
175template <Result func(Core::System&, u64*, Handle, Svc::LimitableResource)>
176void SvcWrap64(Core::System& system) {
177 u64 param_1 = 0;
178 const u32 retval = func(system, &param_1, static_cast<Handle>(Param(system, 1)),
179 static_cast<Svc::LimitableResource>(Param(system, 2)))
180 .raw;
181
182 system.CurrentArmInterface().SetReg(1, param_1);
183 FuncReturn(system, retval);
184}
185
186template <Result func(Core::System&, u32, u64)>
187void SvcWrap64(Core::System& system) {
188 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw);
189}
190
191// Used by SetResourceLimitLimitValue
192template <Result func(Core::System&, Handle, Svc::LimitableResource, u64)>
193void SvcWrap64(Core::System& system) {
194 FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)),
195 static_cast<Svc::LimitableResource>(Param(system, 1)), Param(system, 2))
196 .raw);
197}
198
199// Used by SetThreadCoreMask
200template <Result func(Core::System&, Handle, s32, u64)>
201void SvcWrap64(Core::System& system) {
202 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)),
203 static_cast<s32>(Param(system, 1)), Param(system, 2))
204 .raw);
205}
206
207// Used by GetThreadCoreMask
208template <Result func(Core::System&, Handle, s32*, u64*)>
209void SvcWrap64(Core::System& system) {
210 s32 param_1 = 0;
211 u64 param_2 = 0;
212 const Result retval = func(system, static_cast<u32>(Param(system, 2)), &param_1, &param_2);
213
214 system.CurrentArmInterface().SetReg(1, param_1);
215 system.CurrentArmInterface().SetReg(2, param_2);
216 FuncReturn(system, retval.raw);
217}
218
219template <Result func(Core::System&, u64, u64, u32, u32)>
220void SvcWrap64(Core::System& system) {
221 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
222 static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3)))
223 .raw);
224}
225
226template <Result func(Core::System&, u64, u64, u32, u64)>
227void SvcWrap64(Core::System& system) {
228 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
229 static_cast<u32>(Param(system, 2)), Param(system, 3))
230 .raw);
231}
232
233template <Result func(Core::System&, u32, u64, u32)>
234void SvcWrap64(Core::System& system) {
235 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
236 static_cast<u32>(Param(system, 2)))
237 .raw);
238}
239
240template <Result func(Core::System&, u64, u64, u64)>
241void SvcWrap64(Core::System& system) {
242 FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw);
243}
244
245template <Result func(Core::System&, u64, u64, u32)>
246void SvcWrap64(Core::System& system) {
247 FuncReturn(
248 system,
249 func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw);
250}
251
252// Used by SetMemoryPermission
253template <Result func(Core::System&, u64, u64, Svc::MemoryPermission)>
254void SvcWrap64(Core::System& system) {
255 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
256 static_cast<Svc::MemoryPermission>(Param(system, 2)))
257 .raw);
258}
259
260// Used by MapSharedMemory
261template <Result func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)>
262void SvcWrap64(Core::System& system) {
263 FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), Param(system, 1),
264 Param(system, 2), static_cast<Svc::MemoryPermission>(Param(system, 3)))
265 .raw);
266}
267
268template <Result func(Core::System&, u32, u64, u64)>
269void SvcWrap64(Core::System& system) {
270 FuncReturn(
271 system,
272 func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2)).raw);
273}
274
275// Used by WaitSynchronization
276template <Result func(Core::System&, s32*, u64, s32, s64)>
277void SvcWrap64(Core::System& system) {
278 s32 param_1 = 0;
279 const u32 retval = func(system, &param_1, Param(system, 1), static_cast<s32>(Param(system, 2)),
280 static_cast<s64>(Param(system, 3)))
281 .raw;
282
283 system.CurrentArmInterface().SetReg(1, param_1);
284 FuncReturn(system, retval);
285}
286
287template <Result func(Core::System&, u64, u64, u32, s64)>
288void SvcWrap64(Core::System& system) {
289 FuncReturn(system, func(system, Param(system, 0), Param(system, 1),
290 static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3)))
291 .raw);
292}
293
294// Used by GetInfo
295template <Result func(Core::System&, u64*, u64, Handle, u64)>
296void SvcWrap64(Core::System& system) {
297 u64 param_1 = 0;
298 const u32 retval = func(system, &param_1, Param(system, 1),
299 static_cast<Handle>(Param(system, 2)), Param(system, 3))
300 .raw;
301
302 system.CurrentArmInterface().SetReg(1, param_1);
303 FuncReturn(system, retval);
304}
305
306template <Result func(Core::System&, u32*, u64, u64, u64, u32, s32)>
307void SvcWrap64(Core::System& system) {
308 u32 param_1 = 0;
309 const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2), Param(system, 3),
310 static_cast<u32>(Param(system, 4)), static_cast<s32>(Param(system, 5)))
311 .raw;
312
313 system.CurrentArmInterface().SetReg(1, param_1);
314 FuncReturn(system, retval);
315}
316
317// Used by CreateTransferMemory
318template <Result func(Core::System&, Handle*, u64, u64, Svc::MemoryPermission)>
319void SvcWrap64(Core::System& system) {
320 u32 param_1 = 0;
321 const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2),
322 static_cast<Svc::MemoryPermission>(Param(system, 3)))
323 .raw;
324
325 system.CurrentArmInterface().SetReg(1, param_1);
326 FuncReturn(system, retval);
327}
328
329// Used by CreateCodeMemory
330template <Result func(Core::System&, Handle*, VAddr, size_t)>
331void SvcWrap64(Core::System& system) {
332 u32 param_1 = 0;
333 const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2)).raw;
334
335 system.CurrentArmInterface().SetReg(1, param_1);
336 FuncReturn(system, retval);
337}
338
339template <Result func(Core::System&, Handle*, u64, u32, u32)>
340void SvcWrap64(Core::System& system) {
341 u32 param_1 = 0;
342 const u32 retval = func(system, &param_1, Param(system, 1), static_cast<u32>(Param(system, 2)),
343 static_cast<u32>(Param(system, 3)))
344 .raw;
345
346 system.CurrentArmInterface().SetReg(1, param_1);
347 FuncReturn(system, retval);
348}
349
350// Used by CreateSession
351template <Result func(Core::System&, Handle*, Handle*, u32, u64)>
352void SvcWrap64(Core::System& system) {
353 Handle param_1 = 0;
354 Handle param_2 = 0;
355 const u32 retval = func(system, &param_1, &param_2, static_cast<u32>(Param(system, 2)),
356 static_cast<u32>(Param(system, 3)))
357 .raw;
358
359 system.CurrentArmInterface().SetReg(1, param_1);
360 system.CurrentArmInterface().SetReg(2, param_2);
361 FuncReturn(system, retval);
362}
363
364// Used by ReplyAndReceive
365template <Result func(Core::System&, s32*, Handle*, s32, Handle, s64)>
366void SvcWrap64(Core::System& system) {
367 s32 param_1 = 0;
368 s32 num_handles = static_cast<s32>(Param(system, 2));
369
370 std::vector<Handle> handles(num_handles);
371 system.Memory().ReadBlock(Param(system, 1), handles.data(), num_handles * sizeof(Handle));
372
373 const u32 retval = func(system, &param_1, handles.data(), num_handles,
374 static_cast<s32>(Param(system, 3)), static_cast<s64>(Param(system, 4)))
375 .raw;
376
377 system.CurrentArmInterface().SetReg(1, param_1);
378 FuncReturn(system, retval);
379}
380
381// Used by WaitForAddress
382template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)>
383void SvcWrap64(Core::System& system) {
384 FuncReturn(system,
385 func(system, Param(system, 0), static_cast<Svc::ArbitrationType>(Param(system, 1)),
386 static_cast<s32>(Param(system, 2)), static_cast<s64>(Param(system, 3)))
387 .raw);
388}
389
390// Used by SignalToAddress
391template <Result func(Core::System&, u64, Svc::SignalType, s32, s32)>
392void SvcWrap64(Core::System& system) {
393 FuncReturn(system,
394 func(system, Param(system, 0), static_cast<Svc::SignalType>(Param(system, 1)),
395 static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3)))
396 .raw);
397}
398
399////////////////////////////////////////////////////////////////////////////////////////////////////
400// Function wrappers that return type u32
401
402template <u32 func(Core::System&)>
403void SvcWrap64(Core::System& system) {
404 FuncReturn(system, func(system));
405}
406
407////////////////////////////////////////////////////////////////////////////////////////////////////
408// Function wrappers that return type u64
409
410template <u64 func(Core::System&)>
411void SvcWrap64(Core::System& system) {
412 FuncReturn(system, func(system));
413}
414
415////////////////////////////////////////////////////////////////////////////////////////////////////
416/// Function wrappers that return type void
417
418template <void func(Core::System&)>
419void SvcWrap64(Core::System& system) {
420 func(system);
421}
422
423template <void func(Core::System&, u32)>
424void SvcWrap64(Core::System& system) {
425 func(system, static_cast<u32>(Param(system, 0)));
426}
427
428template <void func(Core::System&, u32, u64, u64, u64)>
429void SvcWrap64(Core::System& system) {
430 func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2),
431 Param(system, 3));
432}
433
434template <void func(Core::System&, s64)>
435void SvcWrap64(Core::System& system) {
436 func(system, static_cast<s64>(Param(system, 0)));
437}
438
439template <void func(Core::System&, u64, s32)>
440void SvcWrap64(Core::System& system) {
441 func(system, Param(system, 0), static_cast<s32>(Param(system, 1)));
442}
443
444template <void func(Core::System&, u64, u64)>
445void SvcWrap64(Core::System& system) {
446 func(system, Param(system, 0), Param(system, 1));
447}
448
449template <void func(Core::System&, u64, u64, u64)>
450void SvcWrap64(Core::System& system) {
451 func(system, Param(system, 0), Param(system, 1), Param(system, 2));
452}
453
454template <void func(Core::System&, u32, u64, u64)>
455void SvcWrap64(Core::System& system) {
456 func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), Param(system, 2));
457}
458
459// Used by QueryMemory32, ArbitrateLock32
460template <Result func(Core::System&, u32, u32, u32)>
461void SvcWrap32(Core::System& system) {
462 FuncReturn32(system,
463 func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw);
464}
465
466// Used by Break32
467template <void func(Core::System&, u32, u32, u32)>
468void SvcWrap32(Core::System& system) {
469 func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2));
470}
471
472// Used by ExitProcess32, ExitThread32
473template <void func(Core::System&)>
474void SvcWrap32(Core::System& system) {
475 func(system);
476}
477
478// Used by GetCurrentProcessorNumber32
479template <u32 func(Core::System&)>
480void SvcWrap32(Core::System& system) {
481 FuncReturn32(system, func(system));
482}
483
484// Used by SleepThread32
485template <void func(Core::System&, u32, u32)>
486void SvcWrap32(Core::System& system) {
487 func(system, Param32(system, 0), Param32(system, 1));
488}
489
490// Used by CreateThread32
491template <Result func(Core::System&, Handle*, u32, u32, u32, u32, s32)>
492void SvcWrap32(Core::System& system) {
493 Handle param_1 = 0;
494
495 const u32 retval = func(system, &param_1, Param32(system, 0), Param32(system, 1),
496 Param32(system, 2), Param32(system, 3), Param32(system, 4))
497 .raw;
498
499 system.CurrentArmInterface().SetReg(1, param_1);
500 FuncReturn(system, retval);
501}
502
503// Used by GetInfo32
504template <Result func(Core::System&, u32*, u32*, u32, u32, u32, u32)>
505void SvcWrap32(Core::System& system) {
506 u32 param_1 = 0;
507 u32 param_2 = 0;
508
509 const u32 retval = func(system, &param_1, &param_2, Param32(system, 0), Param32(system, 1),
510 Param32(system, 2), Param32(system, 3))
511 .raw;
512
513 system.CurrentArmInterface().SetReg(1, param_1);
514 system.CurrentArmInterface().SetReg(2, param_2);
515 FuncReturn(system, retval);
516}
517
518// Used by GetThreadPriority32, ConnectToNamedPort32
519template <Result func(Core::System&, u32*, u32)>
520void SvcWrap32(Core::System& system) {
521 u32 param_1 = 0;
522 const u32 retval = func(system, &param_1, Param32(system, 1)).raw;
523 system.CurrentArmInterface().SetReg(1, param_1);
524 FuncReturn(system, retval);
525}
526
527// Used by GetThreadId32
528template <Result func(Core::System&, u32*, u32*, u32)>
529void SvcWrap32(Core::System& system) {
530 u32 param_1 = 0;
531 u32 param_2 = 0;
532
533 const u32 retval = func(system, &param_1, &param_2, Param32(system, 1)).raw;
534 system.CurrentArmInterface().SetReg(1, param_1);
535 system.CurrentArmInterface().SetReg(2, param_2);
536 FuncReturn(system, retval);
537}
538
539// Used by GetSystemTick32
540template <void func(Core::System&, u32*, u32*)>
541void SvcWrap32(Core::System& system) {
542 u32 param_1 = 0;
543 u32 param_2 = 0;
544
545 func(system, &param_1, &param_2);
546 system.CurrentArmInterface().SetReg(0, param_1);
547 system.CurrentArmInterface().SetReg(1, param_2);
548}
549
550// Used by CreateEvent32
551template <Result func(Core::System&, Handle*, Handle*)>
552void SvcWrap32(Core::System& system) {
553 Handle param_1 = 0;
554 Handle param_2 = 0;
555
556 const u32 retval = func(system, &param_1, &param_2).raw;
557 system.CurrentArmInterface().SetReg(1, param_1);
558 system.CurrentArmInterface().SetReg(2, param_2);
559 FuncReturn(system, retval);
560}
561
562// Used by GetThreadId32
563template <Result func(Core::System&, Handle, u32*, u32*, u32*)>
564void SvcWrap32(Core::System& system) {
565 u32 param_1 = 0;
566 u32 param_2 = 0;
567 u32 param_3 = 0;
568
569 const u32 retval = func(system, Param32(system, 2), &param_1, &param_2, &param_3).raw;
570 system.CurrentArmInterface().SetReg(1, param_1);
571 system.CurrentArmInterface().SetReg(2, param_2);
572 system.CurrentArmInterface().SetReg(3, param_3);
573 FuncReturn(system, retval);
574}
575
576// Used by GetThreadCoreMask32
577template <Result func(Core::System&, Handle, s32*, u32*, u32*)>
578void SvcWrap32(Core::System& system) {
579 s32 param_1 = 0;
580 u32 param_2 = 0;
581 u32 param_3 = 0;
582
583 const u32 retval = func(system, Param32(system, 2), &param_1, &param_2, &param_3).raw;
584 system.CurrentArmInterface().SetReg(1, param_1);
585 system.CurrentArmInterface().SetReg(2, param_2);
586 system.CurrentArmInterface().SetReg(3, param_3);
587 FuncReturn(system, retval);
588}
589
590// Used by SignalProcessWideKey32
591template <void func(Core::System&, u32, s32)>
592void SvcWrap32(Core::System& system) {
593 func(system, static_cast<u32>(Param(system, 0)), static_cast<s32>(Param(system, 1)));
594}
595
596// Used by SetThreadActivity32
597template <Result func(Core::System&, Handle, Svc::ThreadActivity)>
598void SvcWrap32(Core::System& system) {
599 const u32 retval = func(system, static_cast<Handle>(Param(system, 0)),
600 static_cast<Svc::ThreadActivity>(Param(system, 1)))
601 .raw;
602 FuncReturn(system, retval);
603}
604
605// Used by SetThreadPriority32
606template <Result func(Core::System&, Handle, u32)>
607void SvcWrap32(Core::System& system) {
608 const u32 retval =
609 func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw;
610 FuncReturn(system, retval);
611}
612
613// Used by SetMemoryAttribute32
614template <Result func(Core::System&, Handle, u32, u32, u32)>
615void SvcWrap32(Core::System& system) {
616 const u32 retval =
617 func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1)),
618 static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3)))
619 .raw;
620 FuncReturn(system, retval);
621}
622
623// Used by MapSharedMemory32
624template <Result func(Core::System&, Handle, u32, u32, Svc::MemoryPermission)>
625void SvcWrap32(Core::System& system) {
626 const u32 retval = func(system, static_cast<Handle>(Param(system, 0)),
627 static_cast<u32>(Param(system, 1)), static_cast<u32>(Param(system, 2)),
628 static_cast<Svc::MemoryPermission>(Param(system, 3)))
629 .raw;
630 FuncReturn(system, retval);
631}
632
633// Used by SetThreadCoreMask32
634template <Result func(Core::System&, Handle, s32, u32, u32)>
635void SvcWrap32(Core::System& system) {
636 const u32 retval =
637 func(system, static_cast<Handle>(Param(system, 0)), static_cast<s32>(Param(system, 1)),
638 static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3)))
639 .raw;
640 FuncReturn(system, retval);
641}
642
643// Used by WaitProcessWideKeyAtomic32
644template <Result func(Core::System&, u32, u32, Handle, u32, u32)>
645void SvcWrap32(Core::System& system) {
646 const u32 retval =
647 func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)),
648 static_cast<Handle>(Param(system, 2)), static_cast<u32>(Param(system, 3)),
649 static_cast<u32>(Param(system, 4)))
650 .raw;
651 FuncReturn(system, retval);
652}
653
654// Used by WaitForAddress32
655template <Result func(Core::System&, u32, Svc::ArbitrationType, s32, u32, u32)>
656void SvcWrap32(Core::System& system) {
657 const u32 retval = func(system, static_cast<u32>(Param(system, 0)),
658 static_cast<Svc::ArbitrationType>(Param(system, 1)),
659 static_cast<s32>(Param(system, 2)), static_cast<u32>(Param(system, 3)),
660 static_cast<u32>(Param(system, 4)))
661 .raw;
662 FuncReturn(system, retval);
663}
664
665// Used by SignalToAddress32
666template <Result func(Core::System&, u32, Svc::SignalType, s32, s32)>
667void SvcWrap32(Core::System& system) {
668 const u32 retval = func(system, static_cast<u32>(Param(system, 0)),
669 static_cast<Svc::SignalType>(Param(system, 1)),
670 static_cast<s32>(Param(system, 2)), static_cast<s32>(Param(system, 3)))
671 .raw;
672 FuncReturn(system, retval);
673}
674
675// Used by SendSyncRequest32, ArbitrateUnlock32
676template <Result func(Core::System&, u32)>
677void SvcWrap32(Core::System& system) {
678 FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw);
679}
680
681// Used by CreateTransferMemory32
682template <Result func(Core::System&, Handle*, u32, u32, Svc::MemoryPermission)>
683void SvcWrap32(Core::System& system) {
684 Handle handle = 0;
685 const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2),
686 static_cast<Svc::MemoryPermission>(Param32(system, 3)))
687 .raw;
688 system.CurrentArmInterface().SetReg(1, handle);
689 FuncReturn(system, retval);
690}
691
692// Used by WaitSynchronization32
693template <Result func(Core::System&, u32, u32, s32, u32, s32*)>
694void SvcWrap32(Core::System& system) {
695 s32 param_1 = 0;
696 const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2),
697 Param32(system, 3), &param_1)
698 .raw;
699 system.CurrentArmInterface().SetReg(1, param_1);
700 FuncReturn(system, retval);
701}
702
703// Used by CreateCodeMemory32
704template <Result func(Core::System&, Handle*, u32, u32)>
705void SvcWrap32(Core::System& system) {
706 Handle handle = 0;
707
708 const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2)).raw;
709
710 system.CurrentArmInterface().SetReg(1, handle);
711 FuncReturn(system, retval);
712}
713
714// Used by ControlCodeMemory32
715template <Result func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)>
716void SvcWrap32(Core::System& system) {
717 const u32 retval =
718 func(system, Param32(system, 0), Param32(system, 1), Param(system, 2), Param(system, 4),
719 static_cast<Svc::MemoryPermission>(Param32(system, 6)))
720 .raw;
721
722 FuncReturn(system, retval);
723}
724
725// Used by Invalidate/Store/FlushProcessDataCache32
726template <Result func(Core::System&, Handle, u64, u64)>
727void SvcWrap32(Core::System& system) {
728 const u64 address = (Param(system, 3) << 32) | Param(system, 2);
729 const u64 size = (Param(system, 4) << 32) | Param(system, 1);
730 FuncReturn32(system, func(system, Param32(system, 0), address, size).raw);
731}
732
733} // namespace Kernel
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 6d1084fd1..1495d64de 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -762,7 +762,7 @@ Result Module::Interface::InitializeApplicationInfoBase() {
762 // processes emulated. As we don't actually have pid support we should assume we're just using 762 // processes emulated. As we don't actually have pid support we should assume we're just using
763 // our own process 763 // our own process
764 const auto launch_property = 764 const auto launch_property =
765 system.GetARPManager().GetLaunchProperty(system.GetCurrentProcessProgramID()); 765 system.GetARPManager().GetLaunchProperty(system.GetApplicationProcessProgramID());
766 766
767 if (launch_property.Failed()) { 767 if (launch_property.Failed()) {
768 LOG_ERROR(Service_ACC, "Failed to get launch property"); 768 LOG_ERROR(Service_ACC, "Failed to get launch property");
@@ -806,7 +806,7 @@ void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx
806 bool is_locked = false; 806 bool is_locked = false;
807 807
808 if (res != Loader::ResultStatus::Success) { 808 if (res != Loader::ResultStatus::Success) {
809 const FileSys::PatchManager pm{system.GetCurrentProcessProgramID(), 809 const FileSys::PatchManager pm{system.GetApplicationProcessProgramID(),
810 system.GetFileSystemController(), 810 system.GetFileSystemController(),
811 system.GetContentProvider()}; 811 system.GetContentProvider()};
812 const auto nacp_unique = pm.GetControlMetadata().first; 812 const auto nacp_unique = pm.GetControlMetadata().first;
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index ebcf6e164..beb2da06e 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -24,7 +24,6 @@
24#include "core/hle/service/am/idle.h" 24#include "core/hle/service/am/idle.h"
25#include "core/hle/service/am/omm.h" 25#include "core/hle/service/am/omm.h"
26#include "core/hle/service/am/spsm.h" 26#include "core/hle/service/am/spsm.h"
27#include "core/hle/service/am/tcap.h"
28#include "core/hle/service/apm/apm_controller.h" 27#include "core/hle/service/apm/apm_controller.h"
29#include "core/hle/service/apm/apm_interface.h" 28#include "core/hle/service/apm/apm_interface.h"
30#include "core/hle/service/bcat/backend/backend.h" 29#include "core/hle/service/bcat/backend/backend.h"
@@ -79,7 +78,7 @@ IWindowController::IWindowController(Core::System& system_)
79IWindowController::~IWindowController() = default; 78IWindowController::~IWindowController() = default;
80 79
81void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { 80void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
82 const u64 process_id = system.CurrentProcess()->GetProcessID(); 81 const u64 process_id = system.ApplicationProcess()->GetProcessID();
83 82
84 LOG_DEBUG(Service_AM, "called. Process ID=0x{:016X}", process_id); 83 LOG_DEBUG(Service_AM, "called. Process ID=0x{:016X}", process_id);
85 84
@@ -1252,7 +1251,7 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
1252 } 1251 }
1253 1252
1254 auto transfer_mem = 1253 auto transfer_mem =
1255 system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle); 1254 system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle);
1256 1255
1257 if (transfer_mem.IsNull()) { 1256 if (transfer_mem.IsNull()) {
1258 LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); 1257 LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
@@ -1286,7 +1285,7 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
1286 } 1285 }
1287 1286
1288 auto transfer_mem = 1287 auto transfer_mem =
1289 system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle); 1288 system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle);
1290 1289
1291 if (transfer_mem.IsNull()) { 1290 if (transfer_mem.IsNull()) {
1292 LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); 1291 LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
@@ -1465,11 +1464,12 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
1465 const auto backend = BCAT::CreateBackendFromSettings(system, [this](u64 tid) { 1464 const auto backend = BCAT::CreateBackendFromSettings(system, [this](u64 tid) {
1466 return system.GetFileSystemController().GetBCATDirectory(tid); 1465 return system.GetFileSystemController().GetBCATDirectory(tid);
1467 }); 1466 });
1468 const auto build_id_full = system.GetCurrentProcessBuildID(); 1467 const auto build_id_full = system.GetApplicationProcessBuildID();
1469 u64 build_id{}; 1468 u64 build_id{};
1470 std::memcpy(&build_id, build_id_full.data(), sizeof(u64)); 1469 std::memcpy(&build_id, build_id_full.data(), sizeof(u64));
1471 1470
1472 auto data = backend->GetLaunchParameter({system.GetCurrentProcessProgramID(), build_id}); 1471 auto data =
1472 backend->GetLaunchParameter({system.GetApplicationProcessProgramID(), build_id});
1473 if (data.has_value()) { 1473 if (data.has_value()) {
1474 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1474 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1475 rb.Push(ResultSuccess); 1475 rb.Push(ResultSuccess);
@@ -1521,7 +1521,7 @@ void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
1521 LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]); 1521 LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]);
1522 1522
1523 FileSys::SaveDataAttribute attribute{}; 1523 FileSys::SaveDataAttribute attribute{};
1524 attribute.title_id = system.GetCurrentProcessProgramID(); 1524 attribute.title_id = system.GetApplicationProcessProgramID();
1525 attribute.user_id = user_id; 1525 attribute.user_id = user_id;
1526 attribute.type = FileSys::SaveDataType::SaveData; 1526 attribute.type = FileSys::SaveDataType::SaveData;
1527 const auto res = system.GetFileSystemController().CreateSaveData( 1527 const auto res = system.GetFileSystemController().CreateSaveData(
@@ -1551,7 +1551,7 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
1551 std::array<u8, 0x10> version_string{}; 1551 std::array<u8, 0x10> version_string{};
1552 1552
1553 const auto res = [this] { 1553 const auto res = [this] {
1554 const auto title_id = system.GetCurrentProcessProgramID(); 1554 const auto title_id = system.GetApplicationProcessProgramID();
1555 1555
1556 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), 1556 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
1557 system.GetContentProvider()}; 1557 system.GetContentProvider()};
@@ -1570,7 +1570,7 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
1570 const auto& version = res.first->GetVersionString(); 1570 const auto& version = res.first->GetVersionString();
1571 std::copy(version.begin(), version.end(), version_string.begin()); 1571 std::copy(version.begin(), version.end(), version_string.begin());
1572 } else { 1572 } else {
1573 constexpr char default_version[]{"1.0.0"}; 1573 static constexpr char default_version[]{"1.0.0"};
1574 std::memcpy(version_string.data(), default_version, sizeof(default_version)); 1574 std::memcpy(version_string.data(), default_version, sizeof(default_version));
1575 } 1575 }
1576 1576
@@ -1588,7 +1588,7 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
1588 u32 supported_languages = 0; 1588 u32 supported_languages = 0;
1589 1589
1590 const auto res = [this] { 1590 const auto res = [this] {
1591 const auto title_id = system.GetCurrentProcessProgramID(); 1591 const auto title_id = system.GetApplicationProcessProgramID();
1592 1592
1593 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), 1593 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
1594 system.GetContentProvider()}; 1594 system.GetContentProvider()};
@@ -1696,7 +1696,8 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
1696 static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size); 1696 static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size);
1697 1697
1698 system.GetFileSystemController().WriteSaveDataSize( 1698 system.GetFileSystemController().WriteSaveDataSize(
1699 type, system.GetCurrentProcessProgramID(), user_id, {new_normal_size, new_journal_size}); 1699 type, system.GetApplicationProcessProgramID(), user_id,
1700 {new_normal_size, new_journal_size});
1700 1701
1701 IPC::ResponseBuilder rb{ctx, 4}; 1702 IPC::ResponseBuilder rb{ctx, 4};
1702 rb.Push(ResultSuccess); 1703 rb.Push(ResultSuccess);
@@ -1720,7 +1721,7 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
1720 user_id[0]); 1721 user_id[0]);
1721 1722
1722 const auto size = system.GetFileSystemController().ReadSaveDataSize( 1723 const auto size = system.GetFileSystemController().ReadSaveDataSize(
1723 type, system.GetCurrentProcessProgramID(), user_id); 1724 type, system.GetApplicationProcessProgramID(), user_id);
1724 1725
1725 IPC::ResponseBuilder rb{ctx, 6}; 1726 IPC::ResponseBuilder rb{ctx, 6};
1726 rb.Push(ResultSuccess); 1727 rb.Push(ResultSuccess);
@@ -1838,7 +1839,6 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
1838 std::make_shared<IdleSys>(system)->InstallAsService(service_manager); 1839 std::make_shared<IdleSys>(system)->InstallAsService(service_manager);
1839 std::make_shared<OMM>(system)->InstallAsService(service_manager); 1840 std::make_shared<OMM>(system)->InstallAsService(service_manager);
1840 std::make_shared<SPSM>(system)->InstallAsService(service_manager); 1841 std::make_shared<SPSM>(system)->InstallAsService(service_manager);
1841 std::make_shared<TCAP>(system)->InstallAsService(service_manager);
1842} 1842}
1843 1843
1844IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) 1844IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp
index bae0d99a6..b013896b4 100644
--- a/src/core/hle/service/am/applets/applet_error.cpp
+++ b/src/core/hle/service/am/applets/applet_error.cpp
@@ -166,7 +166,7 @@ void Error::Execute() {
166 } 166 }
167 167
168 const auto callback = [this] { DisplayCompleted(); }; 168 const auto callback = [this] { DisplayCompleted(); };
169 const auto title_id = system.GetCurrentProcessProgramID(); 169 const auto title_id = system.GetApplicationProcessProgramID();
170 const auto& reporter{system.GetReporter()}; 170 const auto& reporter{system.GetReporter()};
171 171
172 switch (mode) { 172 switch (mode) {
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp
index e50acdaf6..1eefa85e3 100644
--- a/src/core/hle/service/am/applets/applet_general_backend.cpp
+++ b/src/core/hle/service/am/applets/applet_general_backend.cpp
@@ -186,7 +186,7 @@ void PhotoViewer::Execute() {
186 const auto callback = [this] { ViewFinished(); }; 186 const auto callback = [this] { ViewFinished(); };
187 switch (mode) { 187 switch (mode) {
188 case PhotoViewerAppletMode::CurrentApp: 188 case PhotoViewerAppletMode::CurrentApp:
189 frontend.ShowPhotosForApplication(system.GetCurrentProcessProgramID(), callback); 189 frontend.ShowPhotosForApplication(system.GetApplicationProcessProgramID(), callback);
190 break; 190 break;
191 case PhotoViewerAppletMode::AllApps: 191 case PhotoViewerAppletMode::AllApps:
192 frontend.ShowAllPhotos(callback); 192 frontend.ShowAllPhotos(callback);
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index 14aa6f69e..f061bae80 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -393,7 +393,7 @@ void WebBrowser::InitializeOffline() {
393 switch (document_kind) { 393 switch (document_kind) {
394 case DocumentKind::OfflineHtmlPage: 394 case DocumentKind::OfflineHtmlPage:
395 default: 395 default:
396 title_id = system.GetCurrentProcessProgramID(); 396 title_id = system.GetApplicationProcessProgramID();
397 nca_type = FileSys::ContentRecordType::HtmlDocument; 397 nca_type = FileSys::ContentRecordType::HtmlDocument;
398 additional_paths = "html-document"; 398 additional_paths = "html-document";
399 break; 399 break;
diff --git a/src/core/hle/service/am/tcap.cpp b/src/core/hle/service/am/tcap.cpp
deleted file mode 100644
index 818420e22..000000000
--- a/src/core/hle/service/am/tcap.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/am/tcap.h"
5
6namespace Service::AM {
7
8TCAP::TCAP(Core::System& system_) : ServiceFramework{system_, "tcap"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "GetContinuousHighSkinTemperatureEvent"},
12 {1, nullptr, "SetOperationMode"},
13 {2, nullptr, "LoadAndApplySettings"},
14 };
15 // clang-format on
16
17 RegisterHandlers(functions);
18}
19
20TCAP::~TCAP() = default;
21
22} // namespace Service::AM
diff --git a/src/core/hle/service/am/tcap.h b/src/core/hle/service/am/tcap.h
deleted file mode 100644
index 6b2148c29..000000000
--- a/src/core/hle/service/am/tcap.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::AM {
13
14class TCAP final : public ServiceFramework<TCAP> {
15public:
16 explicit TCAP(Core::System& system_);
17 ~TCAP() override;
18};
19
20} // namespace Service::AM
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 368ccd52f..7264f23f9 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -155,7 +155,7 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
155 IPC::ResponseBuilder rb{ctx, 3}; 155 IPC::ResponseBuilder rb{ctx, 3};
156 rb.Push(ResultSuccess); 156 rb.Push(ResultSuccess);
157 157
158 const auto current = system.GetCurrentProcessProgramID(); 158 const auto current = system.GetApplicationProcessProgramID();
159 159
160 const auto& disabled = Settings::values.disabled_addons[current]; 160 const auto& disabled = Settings::values.disabled_addons[current];
161 if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { 161 if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) {
@@ -182,7 +182,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
182 LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count, 182 LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count,
183 process_id); 183 process_id);
184 184
185 const auto current = system.GetCurrentProcessProgramID(); 185 const auto current = system.GetApplicationProcessProgramID();
186 186
187 std::vector<u32> out; 187 std::vector<u32> out;
188 const auto& disabled = Settings::values.disabled_addons[current]; 188 const auto& disabled = Settings::values.disabled_addons[current];
@@ -228,7 +228,7 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
228 IPC::ResponseBuilder rb{ctx, 4}; 228 IPC::ResponseBuilder rb{ctx, 4};
229 rb.Push(ResultSuccess); 229 rb.Push(ResultSuccess);
230 230
231 const auto title_id = system.GetCurrentProcessProgramID(); 231 const auto title_id = system.GetApplicationProcessProgramID();
232 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), 232 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
233 system.GetContentProvider()}; 233 system.GetContentProvider()};
234 234
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp
index 8a338d9b1..44b2927a6 100644
--- a/src/core/hle/service/apm/apm.cpp
+++ b/src/core/hle/service/apm/apm.cpp
@@ -14,8 +14,6 @@ void InstallInterfaces(Core::System& system) {
14 auto module_ = std::make_shared<Module>(); 14 auto module_ = std::make_shared<Module>();
15 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm") 15 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm")
16 ->InstallAsService(system.ServiceManager()); 16 ->InstallAsService(system.ServiceManager());
17 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:p")
18 ->InstallAsService(system.ServiceManager());
19 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am") 17 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am")
20 ->InstallAsService(system.ServiceManager()); 18 ->InstallAsService(system.ServiceManager());
21 std::make_shared<APM_Sys>(system, system.GetAPMController()) 19 std::make_shared<APM_Sys>(system, system.GetAPMController())
diff --git a/src/core/hle/service/apm/apm_controller.cpp b/src/core/hle/service/apm/apm_controller.cpp
index d6de84066..227fdd0cf 100644
--- a/src/core/hle/service/apm/apm_controller.cpp
+++ b/src/core/hle/service/apm/apm_controller.cpp
@@ -56,7 +56,7 @@ void Controller::SetPerformanceConfiguration(PerformanceMode mode,
56} 56}
57 57
58void Controller::SetFromCpuBoostMode(CpuBoostMode mode) { 58void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
59 constexpr std::array<PerformanceConfiguration, 3> BOOST_MODE_TO_CONFIG_MAP{{ 59 static constexpr std::array<PerformanceConfiguration, 3> BOOST_MODE_TO_CONFIG_MAP{{
60 PerformanceConfiguration::Config7, 60 PerformanceConfiguration::Config7,
61 PerformanceConfiguration::Config13, 61 PerformanceConfiguration::Config13,
62 PerformanceConfiguration::Config15, 62 PerformanceConfiguration::Config15,
diff --git a/src/core/hle/service/audio/auddbg.cpp b/src/core/hle/service/audio/auddbg.cpp
deleted file mode 100644
index 5541af300..000000000
--- a/src/core/hle/service/audio/auddbg.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/auddbg.h"
5
6namespace Service::Audio {
7
8AudDbg::AudDbg(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "RequestSuspendForDebug"},
12 {1, nullptr, "RequestResumeForDebug"},
13 };
14 // clang-format on
15
16 RegisterHandlers(functions);
17}
18
19AudDbg::~AudDbg() = default;
20
21} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/auddbg.h b/src/core/hle/service/audio/auddbg.h
deleted file mode 100644
index 8f26be5dc..000000000
--- a/src/core/hle/service/audio/auddbg.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class AudDbg final : public ServiceFramework<AudDbg> {
15public:
16 explicit AudDbg(Core::System& system_, const char* name);
17 ~AudDbg() override;
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp
deleted file mode 100644
index 98f4a6048..000000000
--- a/src/core/hle/service/audio/audin_a.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/audin_a.h"
5
6namespace Service::Audio {
7
8AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "RequestSuspend"},
12 {1, nullptr, "RequestResume"},
13 {2, nullptr, "GetProcessMasterVolume"},
14 {3, nullptr, "SetProcessMasterVolume"},
15 };
16 // clang-format on
17
18 RegisterHandlers(functions);
19}
20
21AudInA::~AudInA() = default;
22
23} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_a.h b/src/core/hle/service/audio/audin_a.h
deleted file mode 100644
index 19a927de5..000000000
--- a/src/core/hle/service/audio/audin_a.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class AudInA final : public ServiceFramework<AudInA> {
15public:
16 explicit AudInA(Core::System& system_);
17 ~AudInA() override;
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 97da71dfa..ed36e3448 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -2,17 +2,12 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/audio/audctl.h" 4#include "core/hle/service/audio/audctl.h"
5#include "core/hle/service/audio/auddbg.h"
6#include "core/hle/service/audio/audin_a.h"
7#include "core/hle/service/audio/audin_u.h" 5#include "core/hle/service/audio/audin_u.h"
8#include "core/hle/service/audio/audio.h" 6#include "core/hle/service/audio/audio.h"
9#include "core/hle/service/audio/audout_a.h"
10#include "core/hle/service/audio/audout_u.h" 7#include "core/hle/service/audio/audout_u.h"
11#include "core/hle/service/audio/audrec_a.h" 8#include "core/hle/service/audio/audrec_a.h"
12#include "core/hle/service/audio/audrec_u.h" 9#include "core/hle/service/audio/audrec_u.h"
13#include "core/hle/service/audio/audren_a.h"
14#include "core/hle/service/audio/audren_u.h" 10#include "core/hle/service/audio/audren_u.h"
15#include "core/hle/service/audio/codecctl.h"
16#include "core/hle/service/audio/hwopus.h" 11#include "core/hle/service/audio/hwopus.h"
17#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
18 13
@@ -20,21 +15,12 @@ namespace Service::Audio {
20 15
21void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 16void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
22 std::make_shared<AudCtl>(system)->InstallAsService(service_manager); 17 std::make_shared<AudCtl>(system)->InstallAsService(service_manager);
23 std::make_shared<AudOutA>(system)->InstallAsService(service_manager);
24 std::make_shared<AudOutU>(system)->InstallAsService(service_manager); 18 std::make_shared<AudOutU>(system)->InstallAsService(service_manager);
25 std::make_shared<AudInA>(system)->InstallAsService(service_manager);
26 std::make_shared<AudInU>(system)->InstallAsService(service_manager); 19 std::make_shared<AudInU>(system)->InstallAsService(service_manager);
27 std::make_shared<AudRecA>(system)->InstallAsService(service_manager); 20 std::make_shared<AudRecA>(system)->InstallAsService(service_manager);
28 std::make_shared<AudRecU>(system)->InstallAsService(service_manager); 21 std::make_shared<AudRecU>(system)->InstallAsService(service_manager);
29 std::make_shared<AudRenA>(system)->InstallAsService(service_manager);
30 std::make_shared<AudRenU>(system)->InstallAsService(service_manager); 22 std::make_shared<AudRenU>(system)->InstallAsService(service_manager);
31 std::make_shared<CodecCtl>(system)->InstallAsService(service_manager);
32 std::make_shared<HwOpus>(system)->InstallAsService(service_manager); 23 std::make_shared<HwOpus>(system)->InstallAsService(service_manager);
33
34 std::make_shared<AudDbg>(system, "audin:d")->InstallAsService(service_manager);
35 std::make_shared<AudDbg>(system, "audout:d")->InstallAsService(service_manager);
36 std::make_shared<AudDbg>(system, "audrec:d")->InstallAsService(service_manager);
37 std::make_shared<AudDbg>(system, "audren:d")->InstallAsService(service_manager);
38} 24}
39 25
40} // namespace Service::Audio 26} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp
deleted file mode 100644
index 5ecb99236..000000000
--- a/src/core/hle/service/audio/audout_a.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/audout_a.h"
5
6namespace Service::Audio {
7
8AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "RequestSuspend"},
12 {1, nullptr, "RequestResume"},
13 {2, nullptr, "GetProcessMasterVolume"},
14 {3, nullptr, "SetProcessMasterVolume"},
15 {4, nullptr, "GetProcessRecordVolume"},
16 {5, nullptr, "SetProcessRecordVolume"},
17 };
18 // clang-format on
19
20 RegisterHandlers(functions);
21}
22
23AudOutA::~AudOutA() = default;
24
25} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_a.h b/src/core/hle/service/audio/audout_a.h
deleted file mode 100644
index f641cffeb..000000000
--- a/src/core/hle/service/audio/audout_a.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class AudOutA final : public ServiceFramework<AudOutA> {
15public:
16 explicit AudOutA(Core::System& system_);
17 ~AudOutA() override;
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp
deleted file mode 100644
index e775ac3bf..000000000
--- a/src/core/hle/service/audio/audren_a.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/audren_a.h"
5
6namespace Service::Audio {
7
8AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "RequestSuspend"},
12 {1, nullptr, "RequestResume"},
13 {2, nullptr, "GetProcessMasterVolume"},
14 {3, nullptr, "SetProcessMasterVolume"},
15 {4, nullptr, "RegisterAppletResourceUserId"},
16 {5, nullptr, "UnregisterAppletResourceUserId"},
17 {6, nullptr, "GetProcessRecordVolume"},
18 {7, nullptr, "SetProcessRecordVolume"},
19 };
20 // clang-format on
21
22 RegisterHandlers(functions);
23}
24
25AudRenA::~AudRenA() = default;
26
27} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_a.h b/src/core/hle/service/audio/audren_a.h
deleted file mode 100644
index 9e08b4245..000000000
--- a/src/core/hle/service/audio/audren_a.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class AudRenA final : public ServiceFramework<AudRenA> {
15public:
16 explicit AudRenA(Core::System& system_);
17 ~AudRenA() override;
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 0ee28752c..7d730421d 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -455,7 +455,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
455 return; 455 return;
456 } 456 }
457 457
458 const auto& handle_table{system.CurrentProcess()->GetHandleTable()}; 458 const auto& handle_table{system.ApplicationProcess()->GetHandleTable()};
459 auto process{handle_table.GetObject<Kernel::KProcess>(process_handle)}; 459 auto process{handle_table.GetObject<Kernel::KProcess>(process_handle)};
460 auto transfer_memory{ 460 auto transfer_memory{
461 process->GetHandleTable().GetObject<Kernel::KTransferMemory>(transfer_memory_handle)}; 461 process->GetHandleTable().GetObject<Kernel::KTransferMemory>(transfer_memory_handle)};
diff --git a/src/core/hle/service/audio/codecctl.cpp b/src/core/hle/service/audio/codecctl.cpp
deleted file mode 100644
index 81b956d7e..000000000
--- a/src/core/hle/service/audio/codecctl.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/audio/codecctl.h"
5
6namespace Service::Audio {
7
8CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} {
9 static const FunctionInfo functions[] = {
10 {0, nullptr, "Initialize"},
11 {1, nullptr, "Finalize"},
12 {2, nullptr, "Sleep"},
13 {3, nullptr, "Wake"},
14 {4, nullptr, "SetVolume"},
15 {5, nullptr, "GetVolumeMax"},
16 {6, nullptr, "GetVolumeMin"},
17 {7, nullptr, "SetActiveTarget"},
18 {8, nullptr, "GetActiveTarget"},
19 {9, nullptr, "BindHeadphoneMicJackInterrupt"},
20 {10, nullptr, "IsHeadphoneMicJackInserted"},
21 {11, nullptr, "ClearHeadphoneMicJackInterrupt"},
22 {12, nullptr, "IsRequested"},
23 };
24 RegisterHandlers(functions);
25}
26
27CodecCtl::~CodecCtl() = default;
28
29} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/codecctl.h b/src/core/hle/service/audio/codecctl.h
deleted file mode 100644
index 34da98212..000000000
--- a/src/core/hle/service/audio/codecctl.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Audio {
13
14class CodecCtl final : public ServiceFramework<CodecCtl> {
15public:
16 explicit CodecCtl(Core::System& system_);
17 ~CodecCtl() override;
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp
index cbe690a5d..6e6fed227 100644
--- a/src/core/hle/service/bcat/bcat_module.cpp
+++ b/src/core/hle/service/bcat/bcat_module.cpp
@@ -176,8 +176,8 @@ private:
176 void RequestSyncDeliveryCache(Kernel::HLERequestContext& ctx) { 176 void RequestSyncDeliveryCache(Kernel::HLERequestContext& ctx) {
177 LOG_DEBUG(Service_BCAT, "called"); 177 LOG_DEBUG(Service_BCAT, "called");
178 178
179 backend.Synchronize({system.GetCurrentProcessProgramID(), 179 backend.Synchronize({system.GetApplicationProcessProgramID(),
180 GetCurrentBuildID(system.GetCurrentProcessBuildID())}, 180 GetCurrentBuildID(system.GetApplicationProcessBuildID())},
181 GetProgressBackend(SyncType::Normal)); 181 GetProgressBackend(SyncType::Normal));
182 182
183 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 183 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -193,8 +193,8 @@ private:
193 193
194 LOG_DEBUG(Service_BCAT, "called, name={}", name); 194 LOG_DEBUG(Service_BCAT, "called, name={}", name);
195 195
196 backend.SynchronizeDirectory({system.GetCurrentProcessProgramID(), 196 backend.SynchronizeDirectory({system.GetApplicationProcessProgramID(),
197 GetCurrentBuildID(system.GetCurrentProcessBuildID())}, 197 GetCurrentBuildID(system.GetApplicationProcessBuildID())},
198 name, GetProgressBackend(SyncType::Directory)); 198 name, GetProgressBackend(SyncType::Directory));
199 199
200 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 200 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -554,7 +554,7 @@ private:
554void Module::Interface::CreateDeliveryCacheStorageService(Kernel::HLERequestContext& ctx) { 554void Module::Interface::CreateDeliveryCacheStorageService(Kernel::HLERequestContext& ctx) {
555 LOG_DEBUG(Service_BCAT, "called"); 555 LOG_DEBUG(Service_BCAT, "called");
556 556
557 const auto title_id = system.GetCurrentProcessProgramID(); 557 const auto title_id = system.GetApplicationProcessProgramID();
558 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 558 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
559 rb.Push(ResultSuccess); 559 rb.Push(ResultSuccess);
560 rb.PushIpcInterface<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id)); 560 rb.PushIpcInterface<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id));
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 27675615b..2e5919330 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -63,7 +63,7 @@ enum class FatalType : u32 {
63}; 63};
64 64
65static void GenerateErrorReport(Core::System& system, Result error_code, const FatalInfo& info) { 65static void GenerateErrorReport(Core::System& system, Result error_code, const FatalInfo& info) {
66 const auto title_id = system.GetCurrentProcessProgramID(); 66 const auto title_id = system.GetApplicationProcessProgramID();
67 std::string crash_report = fmt::format( 67 std::string crash_report = fmt::format(
68 "Yuzu {}-{} crash report\n" 68 "Yuzu {}-{} crash report\n"
69 "Title ID: {:016x}\n" 69 "Title ID: {:016x}\n"
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 11c604a0f..177447bc1 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -317,7 +317,7 @@ ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFSCurrentProcess()
317 return ResultUnknown; 317 return ResultUnknown;
318 } 318 }
319 319
320 return romfs_factory->OpenCurrentProcess(system.GetCurrentProcessProgramID()); 320 return romfs_factory->OpenCurrentProcess(system.GetApplicationProcessProgramID());
321} 321}
322 322
323ResultVal<FileSys::VirtualFile> FileSystemController::OpenPatchedRomFS( 323ResultVal<FileSys::VirtualFile> FileSystemController::OpenPatchedRomFS(
@@ -502,7 +502,7 @@ FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataTy
502 const auto res = system.GetAppLoader().ReadControlData(nacp); 502 const auto res = system.GetAppLoader().ReadControlData(nacp);
503 503
504 if (res != Loader::ResultStatus::Success) { 504 if (res != Loader::ResultStatus::Success) {
505 const FileSys::PatchManager pm{system.GetCurrentProcessProgramID(), 505 const FileSys::PatchManager pm{system.GetApplicationProcessProgramID(),
506 system.GetFileSystemController(), 506 system.GetFileSystemController(),
507 system.GetContentProvider()}; 507 system.GetContentProvider()};
508 const auto metadata = pm.GetControlMetadata(); 508 const auto metadata = pm.GetControlMetadata();
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 447d624e1..e76346ca9 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -1036,8 +1036,9 @@ void FSP_SRV::OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx) {
1036 1036
1037 LOG_DEBUG(Service_FS, "called, program_index={}", program_index); 1037 LOG_DEBUG(Service_FS, "called, program_index={}", program_index);
1038 1038
1039 auto patched_romfs = fsc.OpenPatchedRomFSWithProgramIndex( 1039 auto patched_romfs =
1040 system.GetCurrentProcessProgramID(), program_index, FileSys::ContentRecordType::Program); 1040 fsc.OpenPatchedRomFSWithProgramIndex(system.GetApplicationProcessProgramID(), program_index,
1041 FileSys::ContentRecordType::Program);
1041 1042
1042 if (patched_romfs.Failed()) { 1043 if (patched_romfs.Failed()) {
1043 // TODO: Find the right error code to use here 1044 // TODO: Find the right error code to use here
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 80eba22e8..ba6f04d8d 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -1132,7 +1132,8 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
1132 return ResultSuccess; 1132 return ResultSuccess;
1133} 1133}
1134Result Controller_NPad::SetGyroscopeZeroDriftMode( 1134Result Controller_NPad::SetGyroscopeZeroDriftMode(
1135 const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) { 1135 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1136 Core::HID::GyroscopeZeroDriftMode drift_mode) {
1136 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); 1137 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1137 if (is_valid.IsError()) { 1138 if (is_valid.IsError()) {
1138 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); 1139 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
@@ -1140,14 +1141,16 @@ Result Controller_NPad::SetGyroscopeZeroDriftMode(
1140 } 1141 }
1141 1142
1142 auto& sixaxis = GetSixaxisState(sixaxis_handle); 1143 auto& sixaxis = GetSixaxisState(sixaxis_handle);
1144 auto& controller = GetControllerFromHandle(sixaxis_handle);
1143 sixaxis.gyroscope_zero_drift_mode = drift_mode; 1145 sixaxis.gyroscope_zero_drift_mode = drift_mode;
1146 controller.device->SetGyroscopeZeroDriftMode(drift_mode);
1144 1147
1145 return ResultSuccess; 1148 return ResultSuccess;
1146} 1149}
1147 1150
1148Result Controller_NPad::GetGyroscopeZeroDriftMode( 1151Result Controller_NPad::GetGyroscopeZeroDriftMode(
1149 const Core::HID::SixAxisSensorHandle& sixaxis_handle, 1152 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1150 GyroscopeZeroDriftMode& drift_mode) const { 1153 Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
1151 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); 1154 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1152 if (is_valid.IsError()) { 1155 if (is_valid.IsError()) {
1153 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); 1156 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 02cc00920..a5998c453 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -52,13 +52,6 @@ public:
52 // When the controller is requesting a motion update for the shared memory 52 // When the controller is requesting a motion update for the shared memory
53 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override; 53 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
54 54
55 // This is nn::hid::GyroscopeZeroDriftMode
56 enum class GyroscopeZeroDriftMode : u32 {
57 Loose = 0,
58 Standard = 1,
59 Tight = 2,
60 };
61
62 // This is nn::hid::NpadJoyHoldType 55 // This is nn::hid::NpadJoyHoldType
63 enum class NpadJoyHoldType : u64 { 56 enum class NpadJoyHoldType : u64 {
64 Vertical = 0, 57 Vertical = 0,
@@ -146,9 +139,9 @@ public:
146 Result DisconnectNpad(Core::HID::NpadIdType npad_id); 139 Result DisconnectNpad(Core::HID::NpadIdType npad_id);
147 140
148 Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 141 Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
149 GyroscopeZeroDriftMode drift_mode); 142 Core::HID::GyroscopeZeroDriftMode drift_mode);
150 Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 143 Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
151 GyroscopeZeroDriftMode& drift_mode) const; 144 Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
152 Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 145 Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
153 bool& is_at_rest) const; 146 bool& is_at_rest) const;
154 Result IsFirmwareUpdateAvailableForSixAxisSensor( 147 Result IsFirmwareUpdateAvailableForSixAxisSensor(
@@ -489,7 +482,8 @@ private:
489 Core::HID::SixAxisSensorFusionParameters fusion{}; 482 Core::HID::SixAxisSensorFusionParameters fusion{};
490 Core::HID::SixAxisSensorCalibrationParameter calibration{}; 483 Core::HID::SixAxisSensorCalibrationParameter calibration{};
491 Core::HID::SixAxisSensorIcInformation ic_information{}; 484 Core::HID::SixAxisSensorIcInformation ic_information{};
492 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; 485 Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
486 Core::HID::GyroscopeZeroDriftMode::Standard};
493 }; 487 };
494 488
495 struct NpadControllerData { 489 struct NpadControllerData {
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index ac2c0c76d..eb3c45a58 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -712,7 +712,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
712void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 712void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
713 IPC::RequestParser rp{ctx}; 713 IPC::RequestParser rp{ctx};
714 const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()}; 714 const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
715 const auto drift_mode{rp.PopEnum<Controller_NPad::GyroscopeZeroDriftMode>()}; 715 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
716 const auto applet_resource_user_id{rp.Pop<u64>()}; 716 const auto applet_resource_user_id{rp.Pop<u64>()};
717 717
718 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); 718 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
@@ -739,7 +739,7 @@ void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
739 739
740 const auto parameters{rp.PopRaw<Parameters>()}; 740 const auto parameters{rp.PopRaw<Parameters>()};
741 741
742 auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard}; 742 auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
743 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); 743 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
744 const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); 744 const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
745 745
@@ -764,7 +764,7 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
764 764
765 const auto parameters{rp.PopRaw<Parameters>()}; 765 const auto parameters{rp.PopRaw<Parameters>()};
766 766
767 const auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard}; 767 const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
768 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); 768 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
769 const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); 769 const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
770 770
@@ -1830,7 +1830,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1830 ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes"); 1830 ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
1831 ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes"); 1831 ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
1832 1832
1833 auto t_mem_1 = system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( 1833 auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
1834 t_mem_1_handle); 1834 t_mem_1_handle);
1835 1835
1836 if (t_mem_1.IsNull()) { 1836 if (t_mem_1.IsNull()) {
@@ -1840,7 +1840,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1840 return; 1840 return;
1841 } 1841 }
1842 1842
1843 auto t_mem_2 = system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( 1843 auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
1844 t_mem_2_handle); 1844 t_mem_2_handle);
1845 1845
1846 if (t_mem_2.IsNull()) { 1846 if (t_mem_2.IsNull()) {
@@ -2127,8 +2127,8 @@ void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
2127 2127
2128 ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes"); 2128 ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
2129 2129
2130 auto t_mem = 2130 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
2131 system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); 2131 t_mem_handle);
2132 2132
2133 if (t_mem.IsNull()) { 2133 if (t_mem.IsNull()) {
2134 LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle); 2134 LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
@@ -2734,25 +2734,11 @@ private:
2734 } 2734 }
2735}; 2735};
2736 2736
2737class HidTmp final : public ServiceFramework<HidTmp> {
2738public:
2739 explicit HidTmp(Core::System& system_) : ServiceFramework{system_, "hid:tmp"} {
2740 // clang-format off
2741 static const FunctionInfo functions[] = {
2742 {0, nullptr, "GetConsoleSixAxisSensorCalibrationValues"},
2743 };
2744 // clang-format on
2745
2746 RegisterHandlers(functions);
2747 }
2748};
2749
2750void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 2737void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
2751 std::make_shared<Hid>(system)->InstallAsService(service_manager); 2738 std::make_shared<Hid>(system)->InstallAsService(service_manager);
2752 std::make_shared<HidBus>(system)->InstallAsService(service_manager); 2739 std::make_shared<HidBus>(system)->InstallAsService(service_manager);
2753 std::make_shared<HidDbg>(system)->InstallAsService(service_manager); 2740 std::make_shared<HidDbg>(system)->InstallAsService(service_manager);
2754 std::make_shared<HidSys>(system)->InstallAsService(service_manager); 2741 std::make_shared<HidSys>(system)->InstallAsService(service_manager);
2755 std::make_shared<HidTmp>(system)->InstallAsService(service_manager);
2756 2742
2757 std::make_shared<Service::IRS::IRS>(system)->InstallAsService(service_manager); 2743 std::make_shared<Service::IRS::IRS>(system)->InstallAsService(service_manager);
2758 std::make_shared<Service::IRS::IRS_SYS>(system)->InstallAsService(service_manager); 2744 std::make_shared<Service::IRS::IRS_SYS>(system)->InstallAsService(service_manager);
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index 17252a84a..bd94e8f3d 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -449,8 +449,8 @@ void HidBus::EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) {
449 449
450 ASSERT_MSG(t_mem_size == 0x1000, "t_mem_size is not 0x1000 bytes"); 450 ASSERT_MSG(t_mem_size == 0x1000, "t_mem_size is not 0x1000 bytes");
451 451
452 auto t_mem = 452 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
453 system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); 453 t_mem_handle);
454 454
455 if (t_mem.IsNull()) { 455 if (t_mem.IsNull()) {
456 LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle); 456 LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 52f402c56..3bd418e92 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -196,8 +196,8 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
196 const auto parameters{rp.PopRaw<Parameters>()}; 196 const auto parameters{rp.PopRaw<Parameters>()};
197 const auto t_mem_handle{ctx.GetCopyHandle(0)}; 197 const auto t_mem_handle{ctx.GetCopyHandle(0)};
198 198
199 auto t_mem = 199 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
200 system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); 200 t_mem_handle);
201 201
202 if (t_mem.IsNull()) { 202 if (t_mem.IsNull()) {
203 LOG_ERROR(Service_IRS, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle); 203 LOG_ERROR(Service_IRS, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
@@ -445,8 +445,8 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
445 const auto parameters{rp.PopRaw<Parameters>()}; 445 const auto parameters{rp.PopRaw<Parameters>()};
446 const auto t_mem_handle{ctx.GetCopyHandle(0)}; 446 const auto t_mem_handle{ctx.GetCopyHandle(0)};
447 447
448 auto t_mem = 448 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
449 system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); 449 t_mem_handle);
450 450
451 u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress()); 451 u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress());
452 452
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp
index 1295a44c7..47a1277ea 100644
--- a/src/core/hle/service/jit/jit.cpp
+++ b/src/core/hle/service/jit/jit.cpp
@@ -353,9 +353,9 @@ public:
353 return; 353 return;
354 } 354 }
355 355
356 // Fetch using the handle table for the current process here, 356 // Fetch using the handle table for the application process here,
357 // since we are not multiprocess yet. 357 // since we are not multiprocess yet.
358 const auto& handle_table{system.CurrentProcess()->GetHandleTable()}; 358 const auto& handle_table{system.ApplicationProcess()->GetHandleTable()};
359 359
360 auto process{handle_table.GetObject<Kernel::KProcess>(process_handle)}; 360 auto process{handle_table.GetObject<Kernel::KProcess>(process_handle)};
361 if (process.IsNull()) { 361 if (process.IsNull()) {
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 652441bc2..2d4d6fe3e 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -246,7 +246,7 @@ public:
246 return; 246 return;
247 } 247 }
248 248
249 if (system.GetCurrentProcessProgramID() != header.application_id) { 249 if (system.GetApplicationProcessProgramID() != header.application_id) {
250 LOG_ERROR(Service_LDR, 250 LOG_ERROR(Service_LDR,
251 "Attempting to load NRR with title ID other than current process. (actual " 251 "Attempting to load NRR with title ID other than current process. (actual "
252 "{:016X})!", 252 "{:016X})!",
@@ -542,15 +542,16 @@ public:
542 } 542 }
543 543
544 // Map memory for the NRO 544 // Map memory for the NRO
545 const auto map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, bss_address, 545 const auto map_result{MapNro(system.ApplicationProcess(), nro_address, nro_size,
546 bss_size, nro_size + bss_size)}; 546 bss_address, bss_size, nro_size + bss_size)};
547 if (map_result.Failed()) { 547 if (map_result.Failed()) {
548 IPC::ResponseBuilder rb{ctx, 2}; 548 IPC::ResponseBuilder rb{ctx, 2};
549 rb.Push(map_result.Code()); 549 rb.Push(map_result.Code());
550 } 550 }
551 551
552 // Load the NRO into the mapped memory 552 // Load the NRO into the mapped memory
553 if (const auto result{LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; 553 if (const auto result{
554 LoadNro(system.ApplicationProcess(), header, nro_address, *map_result)};
554 result.IsError()) { 555 result.IsError()) {
555 IPC::ResponseBuilder rb{ctx, 2}; 556 IPC::ResponseBuilder rb{ctx, 2};
556 rb.Push(map_result.Code()); 557 rb.Push(map_result.Code());
@@ -570,7 +571,7 @@ public:
570 571
571 Result UnmapNro(const NROInfo& info) { 572 Result UnmapNro(const NROInfo& info) {
572 // Each region must be unmapped separately to validate memory state 573 // Each region must be unmapped separately to validate memory state
573 auto& page_table{system.CurrentProcess()->PageTable()}; 574 auto& page_table{system.ApplicationProcess()->PageTable()};
574 575
575 if (info.bss_size != 0) { 576 if (info.bss_size != 0) {
576 CASCADE_CODE(page_table.UnmapCodeMemory( 577 CASCADE_CODE(page_table.UnmapCodeMemory(
@@ -641,7 +642,7 @@ public:
641 LOG_WARNING(Service_LDR, "(STUBBED) called"); 642 LOG_WARNING(Service_LDR, "(STUBBED) called");
642 643
643 initialized = true; 644 initialized = true;
644 current_map_addr = system.CurrentProcess()->PageTable().GetAliasCodeRegionStart(); 645 current_map_addr = system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart();
645 646
646 IPC::ResponseBuilder rb{ctx, 2}; 647 IPC::ResponseBuilder rb{ctx, 2};
647 rb.Push(ResultSuccess); 648 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index e67a76f55..7a6bbbba7 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -618,7 +618,7 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat
618 sizeof(ApplicationArea) - data.size()); 618 sizeof(ApplicationArea) - data.size());
619 619
620 // TODO: Investigate why the title id needs to be moddified 620 // TODO: Investigate why the title id needs to be moddified
621 tag_data.title_id = system.GetCurrentProcessProgramID(); 621 tag_data.title_id = system.GetApplicationProcessProgramID();
622 tag_data.title_id = tag_data.title_id | 0x30000000ULL; 622 tag_data.title_id = tag_data.title_id | 0x30000000ULL;
623 tag_data.settings.settings.appdata_initialized.Assign(1); 623 tag_data.settings.settings.appdata_initialized.Assign(1);
624 tag_data.application_area_id = access_id; 624 tag_data.application_area_id = access_id;
diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.h b/src/core/hle/service/nvdrv/core/syncpoint_manager.h
index 4f2cefae5..7728ff596 100644
--- a/src/core/hle/service/nvdrv/core/syncpoint_manager.h
+++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.h
@@ -124,7 +124,7 @@ private:
124 //!< value 124 //!< value
125 }; 125 };
126 126
127 constexpr static std::size_t SyncpointCount{192}; 127 static constexpr std::size_t SyncpointCount{192};
128 std::array<SyncpointInfo, SyncpointCount> syncpoints{}; 128 std::array<SyncpointInfo, SyncpointCount> syncpoints{};
129 std::mutex reservation_lock; 129 std::mutex reservation_lock;
130 130
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 0cdde82a7..e12025560 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -150,9 +150,9 @@ NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::vector<u8
150 const auto check_failing = [&]() { 150 const auto check_failing = [&]() {
151 if (events[slot].fails > 2) { 151 if (events[slot].fails > 2) {
152 { 152 {
153 auto lk = system.StallProcesses(); 153 auto lk = system.StallApplication();
154 host1x_syncpoint_manager.WaitHost(fence_id, target_value); 154 host1x_syncpoint_manager.WaitHost(fence_id, target_value);
155 system.UnstallProcesses(); 155 system.UnstallApplication();
156 } 156 }
157 params.value.raw = target_value; 157 params.value.raw = target_value;
158 return true; 158 return true;
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 29c1e0f01..277afe0b4 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -127,7 +127,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::vector<u8>& output) {
127 return result; 127 return result;
128 } 128 }
129 bool is_out_io{}; 129 bool is_out_io{};
130 ASSERT(system.CurrentProcess() 130 ASSERT(system.ApplicationProcess()
131 ->PageTable() 131 ->PageTable()
132 .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, 132 .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address,
133 handle_description->size, 133 handle_description->size,
@@ -254,7 +254,7 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::vector<u8>& output) {
254 254
255 if (auto freeInfo{file.FreeHandle(params.handle, false)}) { 255 if (auto freeInfo{file.FreeHandle(params.handle, false)}) {
256 if (freeInfo->can_unlock) { 256 if (freeInfo->can_unlock) {
257 ASSERT(system.CurrentProcess() 257 ASSERT(system.ApplicationProcess()
258 ->PageTable() 258 ->PageTable()
259 .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) 259 .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size)
260 .IsSuccess()); 260 .IsSuccess());
diff --git a/src/core/hle/service/pctl/pctl_module.cpp b/src/core/hle/service/pctl/pctl_module.cpp
index 2a123b42d..083609b34 100644
--- a/src/core/hle/service/pctl/pctl_module.cpp
+++ b/src/core/hle/service/pctl/pctl_module.cpp
@@ -187,7 +187,7 @@ private:
187 187
188 // TODO(ogniK): Recovery flag initialization for pctl:r 188 // TODO(ogniK): Recovery flag initialization for pctl:r
189 189
190 const auto tid = system.GetCurrentProcessProgramID(); 190 const auto tid = system.GetApplicationProcessProgramID();
191 if (tid != 0) { 191 if (tid != 0) {
192 const FileSys::PatchManager pm{tid, system.GetFileSystemController(), 192 const FileSys::PatchManager pm{tid, system.GetFileSystemController(),
193 system.GetContentProvider()}; 193 system.GetContentProvider()};
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
index f7a497a14..98037a8d4 100644
--- a/src/core/hle/service/pcv/pcv.cpp
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -52,32 +52,6 @@ public:
52 } 52 }
53}; 53};
54 54
55class PCV_ARB final : public ServiceFramework<PCV_ARB> {
56public:
57 explicit PCV_ARB(Core::System& system_) : ServiceFramework{system_, "pcv:arb"} {
58 // clang-format off
59 static const FunctionInfo functions[] = {
60 {0, nullptr, "ReleaseControl"},
61 };
62 // clang-format on
63
64 RegisterHandlers(functions);
65 }
66};
67
68class PCV_IMM final : public ServiceFramework<PCV_IMM> {
69public:
70 explicit PCV_IMM(Core::System& system_) : ServiceFramework{system_, "pcv:imm"} {
71 // clang-format off
72 static const FunctionInfo functions[] = {
73 {0, nullptr, "SetClockRate"},
74 };
75 // clang-format on
76
77 RegisterHandlers(functions);
78 }
79};
80
81class IClkrstSession final : public ServiceFramework<IClkrstSession> { 55class IClkrstSession final : public ServiceFramework<IClkrstSession> {
82public: 56public:
83 explicit IClkrstSession(Core::System& system_, DeviceCode deivce_code_) 57 explicit IClkrstSession(Core::System& system_, DeviceCode deivce_code_)
@@ -169,8 +143,6 @@ public:
169 143
170void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 144void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
171 std::make_shared<PCV>(system)->InstallAsService(sm); 145 std::make_shared<PCV>(system)->InstallAsService(sm);
172 std::make_shared<PCV_ARB>(system)->InstallAsService(sm);
173 std::make_shared<PCV_IMM>(system)->InstallAsService(sm);
174 std::make_shared<CLKRST>(system, "clkrst")->InstallAsService(sm); 146 std::make_shared<CLKRST>(system, "clkrst")->InstallAsService(sm);
175 std::make_shared<CLKRST>(system, "clkrst:i")->InstallAsService(sm); 147 std::make_shared<CLKRST>(system, "clkrst:i")->InstallAsService(sm);
176 std::make_shared<CLKRST_A>(system)->InstallAsService(sm); 148 std::make_shared<CLKRST_A>(system)->InstallAsService(sm);
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 01040b32a..90c5f8756 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -71,7 +71,7 @@ private:
71 Type, process_id, data1.size(), data2.size()); 71 Type, process_id, data1.size(), data2.size());
72 72
73 const auto& reporter{system.GetReporter()}; 73 const auto& reporter{system.GetReporter()};
74 reporter.SavePlayReport(Type, system.GetCurrentProcessProgramID(), {data1, data2}, 74 reporter.SavePlayReport(Type, system.GetApplicationProcessProgramID(), {data1, data2},
75 process_id); 75 process_id);
76 76
77 IPC::ResponseBuilder rb{ctx, 2}; 77 IPC::ResponseBuilder rb{ctx, 2};
@@ -99,7 +99,7 @@ private:
99 Type, user_id[1], user_id[0], process_id, data1.size(), data2.size()); 99 Type, user_id[1], user_id[0], process_id, data1.size(), data2.size());
100 100
101 const auto& reporter{system.GetReporter()}; 101 const auto& reporter{system.GetReporter()};
102 reporter.SavePlayReport(Type, system.GetCurrentProcessProgramID(), {data1, data2}, 102 reporter.SavePlayReport(Type, system.GetApplicationProcessProgramID(), {data1, data2},
103 process_id, user_id); 103 process_id, user_id);
104 104
105 IPC::ResponseBuilder rb{ctx, 2}; 105 IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0de67f1e1..1ffc1c694 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -68,7 +68,6 @@
68#include "core/hle/service/time/time.h" 68#include "core/hle/service/time/time.h"
69#include "core/hle/service/usb/usb.h" 69#include "core/hle/service/usb/usb.h"
70#include "core/hle/service/vi/vi.h" 70#include "core/hle/service/vi/vi.h"
71#include "core/hle/service/wlan/wlan.h"
72#include "core/reporter.h" 71#include "core/reporter.h"
73 72
74namespace Service { 73namespace Service {
@@ -306,7 +305,6 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
306 Time::InstallInterfaces(system); 305 Time::InstallInterfaces(system);
307 USB::InstallInterfaces(*sm, system); 306 USB::InstallInterfaces(*sm, system);
308 VI::InstallInterfaces(*sm, system, *nv_flinger, *hos_binder_driver_server); 307 VI::InstallInterfaces(*sm, system, *nv_flinger, *hos_binder_driver_server);
309 WLAN::InstallInterfaces(*sm, system);
310} 308}
311 309
312Services::~Services() = default; 310Services::~Services() = default;
diff --git a/src/core/hle/service/sockets/ethc.cpp b/src/core/hle/service/sockets/ethc.cpp
deleted file mode 100644
index c12ea999b..000000000
--- a/src/core/hle/service/sockets/ethc.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/service/sockets/ethc.h"
5
6namespace Service::Sockets {
7
8ETHC_C::ETHC_C(Core::System& system_) : ServiceFramework{system_, "ethc:c"} {
9 // clang-format off
10 static const FunctionInfo functions[] = {
11 {0, nullptr, "Initialize"},
12 {1, nullptr, "Cancel"},
13 {2, nullptr, "GetResult"},
14 {3, nullptr, "GetMediaList"},
15 {4, nullptr, "SetMediaType"},
16 {5, nullptr, "GetMediaType"},
17 {6, nullptr, "Unknown6"},
18 };
19 // clang-format on
20
21 RegisterHandlers(functions);
22}
23
24ETHC_C::~ETHC_C() = default;
25
26ETHC_I::ETHC_I(Core::System& system_) : ServiceFramework{system_, "ethc:i"} {
27 // clang-format off
28 static const FunctionInfo functions[] = {
29 {0, nullptr, "GetReadableHandle"},
30 {1, nullptr, "Cancel"},
31 {2, nullptr, "GetResult"},
32 {3, nullptr, "GetInterfaceList"},
33 {4, nullptr, "GetInterfaceCount"},
34 };
35 // clang-format on
36
37 RegisterHandlers(functions);
38}
39
40ETHC_I::~ETHC_I() = default;
41
42} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/ethc.h b/src/core/hle/service/sockets/ethc.h
deleted file mode 100644
index 7c5759a96..000000000
--- a/src/core/hle/service/sockets/ethc.h
+++ /dev/null
@@ -1,26 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::Sockets {
13
14class ETHC_C final : public ServiceFramework<ETHC_C> {
15public:
16 explicit ETHC_C(Core::System& system_);
17 ~ETHC_C() override;
18};
19
20class ETHC_I final : public ServiceFramework<ETHC_I> {
21public:
22 explicit ETHC_I(Core::System& system_);
23 ~ETHC_I() override;
24};
25
26} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp
index 8d3ba6f96..b191b5cf5 100644
--- a/src/core/hle/service/sockets/sockets.cpp
+++ b/src/core/hle/service/sockets/sockets.cpp
@@ -2,7 +2,6 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/sockets/bsd.h" 4#include "core/hle/service/sockets/bsd.h"
5#include "core/hle/service/sockets/ethc.h"
6#include "core/hle/service/sockets/nsd.h" 5#include "core/hle/service/sockets/nsd.h"
7#include "core/hle/service/sockets/sfdnsres.h" 6#include "core/hle/service/sockets/sfdnsres.h"
8#include "core/hle/service/sockets/sockets.h" 7#include "core/hle/service/sockets/sockets.h"
@@ -14,9 +13,6 @@ void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system
14 std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager); 13 std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager);
15 std::make_shared<BSDCFG>(system)->InstallAsService(service_manager); 14 std::make_shared<BSDCFG>(system)->InstallAsService(service_manager);
16 15
17 std::make_shared<ETHC_C>(system)->InstallAsService(service_manager);
18 std::make_shared<ETHC_I>(system)->InstallAsService(service_manager);
19
20 std::make_shared<NSD>(system, "nsd:a")->InstallAsService(service_manager); 16 std::make_shared<NSD>(system, "nsd:a")->InstallAsService(service_manager);
21 std::make_shared<NSD>(system, "nsd:u")->InstallAsService(service_manager); 17 std::make_shared<NSD>(system, "nsd:u")->InstallAsService(service_manager);
22 18
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index f9ada7c93..973f7837a 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -286,7 +286,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) {
286} 286}
287 287
288static bool ParsePosixName(const char* name, TimeZoneRule& rule) { 288static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
289 constexpr char default_rule[]{",M4.1.0,M10.5.0"}; 289 static constexpr char default_rule[]{",M4.1.0,M10.5.0"};
290 const char* std_name{name}; 290 const char* std_name{name};
291 int std_len{}; 291 int std_len{};
292 int offset{}; 292 int offset{};
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp
deleted file mode 100644
index 226e3034c..000000000
--- a/src/core/hle/service/wlan/wlan.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <memory>
5
6#include "core/hle/service/service.h"
7#include "core/hle/service/sm/sm.h"
8#include "core/hle/service/wlan/wlan.h"
9
10namespace Service::WLAN {
11
12class WLANInfra final : public ServiceFramework<WLANInfra> {
13public:
14 explicit WLANInfra(Core::System& system_) : ServiceFramework{system_, "wlan:inf"} {
15 // clang-format off
16 static const FunctionInfo functions[] = {
17 {0, nullptr, "OpenMode"},
18 {1, nullptr, "CloseMode"},
19 {2, nullptr, "GetMacAddress"},
20 {3, nullptr, "StartScan"},
21 {4, nullptr, "StopScan"},
22 {5, nullptr, "Connect"},
23 {6, nullptr, "CancelConnect"},
24 {7, nullptr, "Disconnect"},
25 {8, nullptr, "GetConnectionEvent"},
26 {9, nullptr, "GetConnectionStatus"},
27 {10, nullptr, "GetState"},
28 {11, nullptr, "GetScanResult"},
29 {12, nullptr, "GetRssi"},
30 {13, nullptr, "ChangeRxAntenna"},
31 {14, nullptr, "GetFwVersion"},
32 {15, nullptr, "RequestSleep"},
33 {16, nullptr, "RequestWakeUp"},
34 {17, nullptr, "RequestIfUpDown"},
35 {18, nullptr, "Unknown18"},
36 {19, nullptr, "Unknown19"},
37 {20, nullptr, "Unknown20"},
38 {21, nullptr, "Unknown21"},
39 {22, nullptr, "Unknown22"},
40 {23, nullptr, "Unknown23"},
41 {24, nullptr, "Unknown24"},
42 {25, nullptr, "Unknown25"},
43 {26, nullptr, "Unknown26"},
44 {27, nullptr, "Unknown27"},
45 {28, nullptr, "Unknown28"},
46 {29, nullptr, "Unknown29"},
47 {30, nullptr, "Unknown30"},
48 {31, nullptr, "Unknown31"},
49 {32, nullptr, "Unknown32"},
50 {33, nullptr, "Unknown33"},
51 {34, nullptr, "Unknown34"},
52 {35, nullptr, "Unknown35"},
53 {36, nullptr, "Unknown36"},
54 {37, nullptr, "Unknown37"},
55 {38, nullptr, "Unknown38"},
56 };
57 // clang-format on
58
59 RegisterHandlers(functions);
60 }
61};
62
63class WLANLocal final : public ServiceFramework<WLANLocal> {
64public:
65 explicit WLANLocal(Core::System& system_) : ServiceFramework{system_, "wlan:lcl"} {
66 // clang-format off
67 static const FunctionInfo functions[] = {
68 {0, nullptr, "Unknown0"},
69 {1, nullptr, "Unknown1"},
70 {2, nullptr, "Unknown2"},
71 {3, nullptr, "Unknown3"},
72 {4, nullptr, "Unknown4"},
73 {5, nullptr, "Unknown5"},
74 {6, nullptr, "GetMacAddress"},
75 {7, nullptr, "CreateBss"},
76 {8, nullptr, "DestroyBss"},
77 {9, nullptr, "StartScan"},
78 {10, nullptr, "StopScan"},
79 {11, nullptr, "Connect"},
80 {12, nullptr, "CancelConnect"},
81 {13, nullptr, "Join"},
82 {14, nullptr, "CancelJoin"},
83 {15, nullptr, "Disconnect"},
84 {16, nullptr, "SetBeaconLostCount"},
85 {17, nullptr, "Unknown17"},
86 {18, nullptr, "Unknown18"},
87 {19, nullptr, "Unknown19"},
88 {20, nullptr, "GetBssIndicationEvent"},
89 {21, nullptr, "GetBssIndicationInfo"},
90 {22, nullptr, "GetState"},
91 {23, nullptr, "GetAllowedChannels"},
92 {24, nullptr, "AddIe"},
93 {25, nullptr, "DeleteIe"},
94 {26, nullptr, "Unknown26"},
95 {27, nullptr, "Unknown27"},
96 {28, nullptr, "CreateRxEntry"},
97 {29, nullptr, "DeleteRxEntry"},
98 {30, nullptr, "Unknown30"},
99 {31, nullptr, "Unknown31"},
100 {32, nullptr, "AddMatchingDataToRxEntry"},
101 {33, nullptr, "RemoveMatchingDataFromRxEntry"},
102 {34, nullptr, "GetScanResult"},
103 {35, nullptr, "Unknown35"},
104 {36, nullptr, "SetActionFrameWithBeacon"},
105 {37, nullptr, "CancelActionFrameWithBeacon"},
106 {38, nullptr, "CreateRxEntryForActionFrame"},
107 {39, nullptr, "DeleteRxEntryForActionFrame"},
108 {40, nullptr, "Unknown40"},
109 {41, nullptr, "Unknown41"},
110 {42, nullptr, "CancelGetActionFrame"},
111 {43, nullptr, "GetRssi"},
112 {44, nullptr, "Unknown44"},
113 {45, nullptr, "Unknown45"},
114 {46, nullptr, "Unknown46"},
115 {47, nullptr, "Unknown47"},
116 {48, nullptr, "Unknown48"},
117 {49, nullptr, "Unknown49"},
118 {50, nullptr, "Unknown50"},
119 {51, nullptr, "Unknown51"},
120 };
121 // clang-format on
122
123 RegisterHandlers(functions);
124 }
125};
126
127class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> {
128public:
129 explicit WLANLocalGetFrame(Core::System& system_) : ServiceFramework{system_, "wlan:lg"} {
130 // clang-format off
131 static const FunctionInfo functions[] = {
132 {0, nullptr, "Unknown"},
133 };
134 // clang-format on
135
136 RegisterHandlers(functions);
137 }
138};
139
140class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> {
141public:
142 explicit WLANSocketGetFrame(Core::System& system_) : ServiceFramework{system_, "wlan:sg"} {
143 // clang-format off
144 static const FunctionInfo functions[] = {
145 {0, nullptr, "Unknown"},
146 };
147 // clang-format on
148
149 RegisterHandlers(functions);
150 }
151};
152
153class WLANSocketManager final : public ServiceFramework<WLANSocketManager> {
154public:
155 explicit WLANSocketManager(Core::System& system_) : ServiceFramework{system_, "wlan:soc"} {
156 // clang-format off
157 static const FunctionInfo functions[] = {
158 {0, nullptr, "Unknown0"},
159 {1, nullptr, "Unknown1"},
160 {2, nullptr, "Unknown2"},
161 {3, nullptr, "Unknown3"},
162 {4, nullptr, "Unknown4"},
163 {5, nullptr, "Unknown5"},
164 {6, nullptr, "GetMacAddress"},
165 {7, nullptr, "SwitchTsfTimerFunction"},
166 {8, nullptr, "Unknown8"},
167 {9, nullptr, "Unknown9"},
168 {10, nullptr, "Unknown10"},
169 {11, nullptr, "Unknown11"},
170 {12, nullptr, "Unknown12"},
171 };
172 // clang-format on
173
174 RegisterHandlers(functions);
175 }
176};
177
178void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
179 std::make_shared<WLANInfra>(system)->InstallAsService(sm);
180 std::make_shared<WLANLocal>(system)->InstallAsService(sm);
181 std::make_shared<WLANLocalGetFrame>(system)->InstallAsService(sm);
182 std::make_shared<WLANSocketGetFrame>(system)->InstallAsService(sm);
183 std::make_shared<WLANSocketManager>(system)->InstallAsService(sm);
184}
185
186} // namespace Service::WLAN
diff --git a/src/core/hle/service/wlan/wlan.h b/src/core/hle/service/wlan/wlan.h
deleted file mode 100644
index 535c3bf0d..000000000
--- a/src/core/hle/service/wlan/wlan.h
+++ /dev/null
@@ -1,18 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6namespace Core {
7class System;
8}
9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::WLAN {
15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
17
18} // namespace Service::WLAN
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 4c3b3c655..a5c384fb5 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -145,7 +145,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
145 145
146 // Apply cheats if they exist and the program has a valid title ID 146 // Apply cheats if they exist and the program has a valid title ID
147 if (pm) { 147 if (pm) {
148 system.SetCurrentProcessBuildID(nso_header.build_id); 148 system.SetApplicationProcessBuildID(nso_header.build_id);
149 const auto cheats = pm->CreateCheatList(nso_header.build_id); 149 const auto cheats = pm->CreateCheatList(nso_header.build_id);
150 if (!cheats.empty()) { 150 if (!cheats.empty()) {
151 system.RegisterCheatList(cheats, nso_header.build_id, load_base, image_size); 151 system.RegisterCheatList(cheats, nso_header.build_id, load_base, image_size);
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index af9660b55..4397fcfb1 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -247,11 +247,11 @@ struct Memory::Impl {
247 } 247 }
248 248
249 void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) { 249 void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
250 ReadBlockImpl<false>(*system.CurrentProcess(), src_addr, dest_buffer, size); 250 ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
251 } 251 }
252 252
253 void ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) { 253 void ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
254 ReadBlockImpl<true>(*system.CurrentProcess(), src_addr, dest_buffer, size); 254 ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size);
255 } 255 }
256 256
257 template <bool UNSAFE> 257 template <bool UNSAFE>
@@ -279,11 +279,11 @@ struct Memory::Impl {
279 } 279 }
280 280
281 void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { 281 void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
282 WriteBlockImpl<false>(*system.CurrentProcess(), dest_addr, src_buffer, size); 282 WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
283 } 283 }
284 284
285 void WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { 285 void WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
286 WriteBlockImpl<true>(*system.CurrentProcess(), dest_addr, src_buffer, size); 286 WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size);
287 } 287 }
288 288
289 void ZeroBlock(const Kernel::KProcess& process, const VAddr dest_addr, const std::size_t size) { 289 void ZeroBlock(const Kernel::KProcess& process, const VAddr dest_addr, const std::size_t size) {
@@ -711,7 +711,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
711} 711}
712 712
713bool Memory::IsValidVirtualAddress(const VAddr vaddr) const { 713bool Memory::IsValidVirtualAddress(const VAddr vaddr) const {
714 const Kernel::KProcess& process = *system.CurrentProcess(); 714 const Kernel::KProcess& process = *system.ApplicationProcess();
715 const auto& page_table = process.PageTable().PageTableImpl(); 715 const auto& page_table = process.PageTable().PageTableImpl();
716 const size_t page = vaddr >> YUZU_PAGEBITS; 716 const size_t page = vaddr >> YUZU_PAGEBITS;
717 if (page >= page_table.pointers.size()) { 717 if (page >= page_table.pointers.size()) {
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index ffdbacc18..44ee39648 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -191,10 +191,10 @@ void CheatEngine::Initialize() {
191 }); 191 });
192 core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event); 192 core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event);
193 193
194 metadata.process_id = system.CurrentProcess()->GetProcessID(); 194 metadata.process_id = system.ApplicationProcess()->GetProcessID();
195 metadata.title_id = system.GetCurrentProcessProgramID(); 195 metadata.title_id = system.GetApplicationProcessProgramID();
196 196
197 const auto& page_table = system.CurrentProcess()->PageTable(); 197 const auto& page_table = system.ApplicationProcess()->PageTable();
198 metadata.heap_extents = { 198 metadata.heap_extents = {
199 .base = page_table.GetHeapRegionStart(), 199 .base = page_table.GetHeapRegionStart(),
200 .size = page_table.GetHeapRegionSize(), 200 .size = page_table.GetHeapRegionSize(),
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 59dfb8767..708ae17aa 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -110,7 +110,7 @@ json GetProcessorStateData(const std::string& architecture, u64 entry_point, u64
110} 110}
111 111
112json GetProcessorStateDataAuto(Core::System& system) { 112json GetProcessorStateDataAuto(Core::System& system) {
113 const auto* process{system.CurrentProcess()}; 113 const auto* process{system.ApplicationProcess()};
114 auto& arm{system.CurrentArmInterface()}; 114 auto& arm{system.CurrentArmInterface()};
115 115
116 Core::ARM_Interface::ThreadContext64 context{}; 116 Core::ARM_Interface::ThreadContext64 context{};
@@ -234,7 +234,7 @@ void Reporter::SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64
234 } 234 }
235 235
236 const auto timestamp = GetTimestamp(); 236 const auto timestamp = GetTimestamp();
237 const auto title_id = system.GetCurrentProcessProgramID(); 237 const auto title_id = system.GetApplicationProcessProgramID();
238 auto out = GetFullDataAuto(timestamp, title_id, system); 238 auto out = GetFullDataAuto(timestamp, title_id, system);
239 239
240 auto break_out = json{ 240 auto break_out = json{
@@ -261,7 +261,7 @@ void Reporter::SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u
261 } 261 }
262 262
263 const auto timestamp = GetTimestamp(); 263 const auto timestamp = GetTimestamp();
264 const auto title_id = system.GetCurrentProcessProgramID(); 264 const auto title_id = system.GetApplicationProcessProgramID();
265 auto out = GetFullDataAuto(timestamp, title_id, system); 265 auto out = GetFullDataAuto(timestamp, title_id, system);
266 266
267 auto function_out = GetHLERequestContextData(ctx, system.Memory()); 267 auto function_out = GetHLERequestContextData(ctx, system.Memory());
@@ -283,7 +283,7 @@ void Reporter::SaveUnimplementedAppletReport(
283 } 283 }
284 284
285 const auto timestamp = GetTimestamp(); 285 const auto timestamp = GetTimestamp();
286 const auto title_id = system.GetCurrentProcessProgramID(); 286 const auto title_id = system.GetApplicationProcessProgramID();
287 auto out = GetFullDataAuto(timestamp, title_id, system); 287 auto out = GetFullDataAuto(timestamp, title_id, system);
288 288
289 out["applet_common_args"] = { 289 out["applet_common_args"] = {
@@ -376,7 +376,7 @@ void Reporter::SaveUserReport() const {
376 } 376 }
377 377
378 const auto timestamp = GetTimestamp(); 378 const auto timestamp = GetTimestamp();
379 const auto title_id = system.GetCurrentProcessProgramID(); 379 const auto title_id = system.GetApplicationProcessProgramID();
380 380
381 SaveToFile(GetFullDataAuto(timestamp, title_id, system), 381 SaveToFile(GetFullDataAuto(timestamp, title_id, system),
382 GetPath("user_report", title_id, timestamp)); 382 GetPath("user_report", title_id, timestamp));
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 8d5f2be2f..9178b00ca 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -34,7 +34,7 @@ static u64 GenerateTelemetryId() {
34 mbedtls_entropy_context entropy; 34 mbedtls_entropy_context entropy;
35 mbedtls_entropy_init(&entropy); 35 mbedtls_entropy_init(&entropy);
36 mbedtls_ctr_drbg_context ctr_drbg; 36 mbedtls_ctr_drbg_context ctr_drbg;
37 constexpr std::array<char, 18> personalization{{"yuzu Telemetry ID"}}; 37 static constexpr std::array<char, 18> personalization{{"yuzu Telemetry ID"}};
38 38
39 mbedtls_ctr_drbg_init(&ctr_drbg); 39 mbedtls_ctr_drbg_init(&ctr_drbg);
40 ASSERT(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 40 ASSERT(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp
index 4fcfb4510..b4cd39a20 100644
--- a/src/input_common/drivers/joycon.cpp
+++ b/src/input_common/drivers/joycon.cpp
@@ -16,7 +16,7 @@ namespace InputCommon {
16 16
17Joycons::Joycons(const std::string& input_engine_) : InputEngine(input_engine_) { 17Joycons::Joycons(const std::string& input_engine_) : InputEngine(input_engine_) {
18 // Avoid conflicting with SDL driver 18 // Avoid conflicting with SDL driver
19 if (!Settings::values.enable_joycon_driver) { 19 if (!Settings::values.enable_joycon_driver && !Settings::values.enable_procon_driver) {
20 return; 20 return;
21 } 21 }
22 LOG_INFO(Input, "Joycon driver Initialization started"); 22 LOG_INFO(Input, "Joycon driver Initialization started");
@@ -46,6 +46,12 @@ void Joycons::Reset() {
46 } 46 }
47 device->Stop(); 47 device->Stop();
48 } 48 }
49 for (const auto& device : pro_controller) {
50 if (!device) {
51 continue;
52 }
53 device->Stop();
54 }
49 SDL_hid_exit(); 55 SDL_hid_exit();
50} 56}
51 57
@@ -61,6 +67,11 @@ void Joycons::Setup() {
61 PreSetController(GetIdentifier(port, Joycon::ControllerType::Right)); 67 PreSetController(GetIdentifier(port, Joycon::ControllerType::Right));
62 device = std::make_shared<Joycon::JoyconDriver>(port++); 68 device = std::make_shared<Joycon::JoyconDriver>(port++);
63 } 69 }
70 port = 0;
71 for (auto& device : pro_controller) {
72 PreSetController(GetIdentifier(port, Joycon::ControllerType::Pro));
73 device = std::make_shared<Joycon::JoyconDriver>(port++);
74 }
64 75
65 scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); }); 76 scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); });
66} 77}
@@ -116,6 +127,9 @@ bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const {
116 // Check if device already exist 127 // Check if device already exist
117 switch (type) { 128 switch (type) {
118 case Joycon::ControllerType::Left: 129 case Joycon::ControllerType::Left:
130 if (!Settings::values.enable_joycon_driver) {
131 return false;
132 }
119 for (const auto& device : left_joycons) { 133 for (const auto& device : left_joycons) {
120 if (is_handle_identical(device)) { 134 if (is_handle_identical(device)) {
121 return false; 135 return false;
@@ -123,12 +137,25 @@ bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const {
123 } 137 }
124 break; 138 break;
125 case Joycon::ControllerType::Right: 139 case Joycon::ControllerType::Right:
140 if (!Settings::values.enable_joycon_driver) {
141 return false;
142 }
126 for (const auto& device : right_joycons) { 143 for (const auto& device : right_joycons) {
127 if (is_handle_identical(device)) { 144 if (is_handle_identical(device)) {
128 return false; 145 return false;
129 } 146 }
130 } 147 }
131 break; 148 break;
149 case Joycon::ControllerType::Pro:
150 if (!Settings::values.enable_procon_driver) {
151 return false;
152 }
153 for (const auto& device : pro_controller) {
154 if (is_handle_identical(device)) {
155 return false;
156 }
157 }
158 break;
132 default: 159 default:
133 return false; 160 return false;
134 } 161 }
@@ -199,6 +226,14 @@ std::shared_ptr<Joycon::JoyconDriver> Joycons::GetNextFreeHandle(
199 return *unconnected_device; 226 return *unconnected_device;
200 } 227 }
201 } 228 }
229 if (type == Joycon::ControllerType::Pro) {
230 const auto unconnected_device = std::ranges::find_if(
231 pro_controller, [](auto& device) { return !device->IsConnected(); });
232
233 if (unconnected_device != pro_controller.end()) {
234 return *unconnected_device;
235 }
236 }
202 return nullptr; 237 return nullptr;
203} 238}
204 239
@@ -355,7 +390,7 @@ void Joycons::OnMotionUpdate(std::size_t port, Joycon::ControllerType type, int
355void Joycons::OnRingConUpdate(f32 ring_data) { 390void Joycons::OnRingConUpdate(f32 ring_data) {
356 // To simplify ring detection it will always be mapped to an empty identifier for all 391 // To simplify ring detection it will always be mapped to an empty identifier for all
357 // controllers 392 // controllers
358 constexpr PadIdentifier identifier = { 393 static constexpr PadIdentifier identifier = {
359 .guid = Common::UUID{}, 394 .guid = Common::UUID{},
360 .port = 0, 395 .port = 0,
361 .pad = 0, 396 .pad = 0,
@@ -409,6 +444,15 @@ std::shared_ptr<Joycon::JoyconDriver> Joycons::GetHandle(PadIdentifier identifie
409 } 444 }
410 } 445 }
411 446
447 if (type == Joycon::ControllerType::Pro) {
448 const auto matching_device = std::ranges::find_if(
449 pro_controller, [is_handle_active](auto& device) { return is_handle_active(device); });
450
451 if (matching_device != pro_controller.end()) {
452 return *matching_device;
453 }
454 }
455
412 return nullptr; 456 return nullptr;
413} 457}
414 458
@@ -455,6 +499,9 @@ std::vector<Common::ParamPackage> Joycons::GetInputDevices() const {
455 for (const auto& controller : right_joycons) { 499 for (const auto& controller : right_joycons) {
456 add_entry(controller); 500 add_entry(controller);
457 } 501 }
502 for (const auto& controller : pro_controller) {
503 add_entry(controller);
504 }
458 505
459 // List dual joycon pairs 506 // List dual joycon pairs
460 for (std::size_t i = 0; i < MaxSupportedControllers; i++) { 507 for (std::size_t i = 0; i < MaxSupportedControllers; i++) {
diff --git a/src/input_common/drivers/joycon.h b/src/input_common/drivers/joycon.h
index 2149ab7fd..473ba1b9e 100644
--- a/src/input_common/drivers/joycon.h
+++ b/src/input_common/drivers/joycon.h
@@ -106,6 +106,7 @@ private:
106 // Joycon types are split by type to ease supporting dualjoycon configurations 106 // Joycon types are split by type to ease supporting dualjoycon configurations
107 std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> left_joycons{}; 107 std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> left_joycons{};
108 std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> right_joycons{}; 108 std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> right_joycons{};
109 std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> pro_controller{};
109}; 110};
110 111
111} // namespace InputCommon 112} // namespace InputCommon
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
index faf9cbdc3..da50e0a24 100644
--- a/src/input_common/drivers/mouse.cpp
+++ b/src/input_common/drivers/mouse.cpp
@@ -15,23 +15,39 @@ constexpr int mouse_axis_y = 1;
15constexpr int wheel_axis_x = 2; 15constexpr int wheel_axis_x = 2;
16constexpr int wheel_axis_y = 3; 16constexpr int wheel_axis_y = 3;
17constexpr int motion_wheel_y = 4; 17constexpr int motion_wheel_y = 4;
18constexpr int touch_axis_x = 10;
19constexpr int touch_axis_y = 11;
20constexpr PadIdentifier identifier = { 18constexpr PadIdentifier identifier = {
21 .guid = Common::UUID{}, 19 .guid = Common::UUID{},
22 .port = 0, 20 .port = 0,
23 .pad = 0, 21 .pad = 0,
24}; 22};
25 23
24constexpr PadIdentifier real_mouse_identifier = {
25 .guid = Common::UUID{},
26 .port = 1,
27 .pad = 0,
28};
29
30constexpr PadIdentifier touch_identifier = {
31 .guid = Common::UUID{},
32 .port = 2,
33 .pad = 0,
34};
35
26Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) { 36Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
27 PreSetController(identifier); 37 PreSetController(identifier);
38 PreSetController(real_mouse_identifier);
39 PreSetController(touch_identifier);
40
41 // Initialize all mouse axis
28 PreSetAxis(identifier, mouse_axis_x); 42 PreSetAxis(identifier, mouse_axis_x);
29 PreSetAxis(identifier, mouse_axis_y); 43 PreSetAxis(identifier, mouse_axis_y);
30 PreSetAxis(identifier, wheel_axis_x); 44 PreSetAxis(identifier, wheel_axis_x);
31 PreSetAxis(identifier, wheel_axis_y); 45 PreSetAxis(identifier, wheel_axis_y);
32 PreSetAxis(identifier, motion_wheel_y); 46 PreSetAxis(identifier, motion_wheel_y);
33 PreSetAxis(identifier, touch_axis_x); 47 PreSetAxis(real_mouse_identifier, mouse_axis_x);
34 PreSetAxis(identifier, touch_axis_y); 48 PreSetAxis(real_mouse_identifier, mouse_axis_y);
49 PreSetAxis(touch_identifier, mouse_axis_x);
50 PreSetAxis(touch_identifier, mouse_axis_y);
35 update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); }); 51 update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
36} 52}
37 53
@@ -39,7 +55,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
39 Common::SetCurrentThreadName("Mouse"); 55 Common::SetCurrentThreadName("Mouse");
40 constexpr int update_time = 10; 56 constexpr int update_time = 10;
41 while (!stop_token.stop_requested()) { 57 while (!stop_token.stop_requested()) {
42 if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) { 58 if (Settings::values.mouse_panning) {
43 // Slow movement by 4% 59 // Slow movement by 4%
44 last_mouse_change *= 0.96f; 60 last_mouse_change *= 0.96f;
45 const float sensitivity = 61 const float sensitivity =
@@ -57,17 +73,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
57 } 73 }
58} 74}
59 75
60void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) { 76void Mouse::Move(int x, int y, int center_x, int center_y) {
61 // If native mouse is enabled just set the screen coordinates
62 if (Settings::values.mouse_enabled) {
63 SetAxis(identifier, mouse_axis_x, touch_x);
64 SetAxis(identifier, mouse_axis_y, touch_y);
65 return;
66 }
67
68 SetAxis(identifier, touch_axis_x, touch_x);
69 SetAxis(identifier, touch_axis_y, touch_y);
70
71 if (Settings::values.mouse_panning) { 77 if (Settings::values.mouse_panning) {
72 auto mouse_change = 78 auto mouse_change =
73 (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); 79 (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
@@ -113,20 +119,41 @@ void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int
113 } 119 }
114} 120}
115 121
116void Mouse::PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button) { 122void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
117 SetAxis(identifier, touch_axis_x, touch_x); 123 SetAxis(real_mouse_identifier, mouse_axis_x, touch_x);
118 SetAxis(identifier, touch_axis_y, touch_y); 124 SetAxis(real_mouse_identifier, mouse_axis_y, touch_y);
125}
126
127void Mouse::TouchMove(f32 touch_x, f32 touch_y) {
128 SetAxis(touch_identifier, mouse_axis_x, touch_x);
129 SetAxis(touch_identifier, mouse_axis_y, touch_y);
130}
131
132void Mouse::PressButton(int x, int y, MouseButton button) {
119 SetButton(identifier, static_cast<int>(button), true); 133 SetButton(identifier, static_cast<int>(button), true);
134
120 // Set initial analog parameters 135 // Set initial analog parameters
121 mouse_origin = {x, y}; 136 mouse_origin = {x, y};
122 last_mouse_position = {x, y}; 137 last_mouse_position = {x, y};
123 button_pressed = true; 138 button_pressed = true;
124} 139}
125 140
141void Mouse::PressMouseButton(MouseButton button) {
142 SetButton(real_mouse_identifier, static_cast<int>(button), true);
143}
144
145void Mouse::PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button) {
146 SetAxis(touch_identifier, mouse_axis_x, touch_x);
147 SetAxis(touch_identifier, mouse_axis_y, touch_y);
148 SetButton(touch_identifier, static_cast<int>(button), true);
149}
150
126void Mouse::ReleaseButton(MouseButton button) { 151void Mouse::ReleaseButton(MouseButton button) {
127 SetButton(identifier, static_cast<int>(button), false); 152 SetButton(identifier, static_cast<int>(button), false);
153 SetButton(real_mouse_identifier, static_cast<int>(button), false);
154 SetButton(touch_identifier, static_cast<int>(button), false);
128 155
129 if (!Settings::values.mouse_panning && !Settings::values.mouse_enabled) { 156 if (!Settings::values.mouse_panning) {
130 SetAxis(identifier, mouse_axis_x, 0); 157 SetAxis(identifier, mouse_axis_x, 0);
131 SetAxis(identifier, mouse_axis_y, 0); 158 SetAxis(identifier, mouse_axis_y, 0);
132 } 159 }
diff --git a/src/input_common/drivers/mouse.h b/src/input_common/drivers/mouse.h
index 72073cc23..f3b65bdd1 100644
--- a/src/input_common/drivers/mouse.h
+++ b/src/input_common/drivers/mouse.h
@@ -37,13 +37,43 @@ public:
37 * @param center_x the x-coordinate of the middle of the screen 37 * @param center_x the x-coordinate of the middle of the screen
38 * @param center_y the y-coordinate of the middle of the screen 38 * @param center_y the y-coordinate of the middle of the screen
39 */ 39 */
40 void MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y); 40 void Move(int x, int y, int center_x, int center_y);
41 41
42 /** 42 /**
43 * Sets the status of all buttons bound with the key to pressed 43 * Signals that real mouse has moved.
44 * @param key_code the code of the key to press 44 * @param x the absolute position on the touchscreen of the cursor
45 * @param y the absolute position on the touchscreen of the cursor
45 */ 46 */
46 void PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button); 47 void MouseMove(f32 touch_x, f32 touch_y);
48
49 /**
50 * Signals that touch finger has moved.
51 * @param x the absolute position on the touchscreen of the cursor
52 * @param y the absolute position on the touchscreen of the cursor
53 */
54 void TouchMove(f32 touch_x, f32 touch_y);
55
56 /**
57 * Sets the status of a button to pressed
58 * @param x the x-coordinate of the cursor
59 * @param y the y-coordinate of the cursor
60 * @param button the id of the button to press
61 */
62 void PressButton(int x, int y, MouseButton button);
63
64 /**
65 * Sets the status of a mouse button to pressed
66 * @param button the id of the button to press
67 */
68 void PressMouseButton(MouseButton button);
69
70 /**
71 * Sets the status of touch finger to pressed
72 * @param x the absolute position on the touchscreen of the cursor
73 * @param y the absolute position on the touchscreen of the cursor
74 * @param button the id of the button to press
75 */
76 void PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button);
47 77
48 /** 78 /**
49 * Sets the status of all buttons bound with the key to released 79 * Sets the status of all buttons bound with the key to released
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index d975eb815..5c20b3426 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -343,6 +343,14 @@ void SDLDriver::InitJoystick(int joystick_index) {
343 } 343 }
344 } 344 }
345 345
346 if (Settings::values.enable_procon_driver) {
347 if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) {
348 LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index);
349 SDL_JoystickClose(sdl_joystick);
350 return;
351 }
352 }
353
346 std::scoped_lock lock{joystick_map_mutex}; 354 std::scoped_lock lock{joystick_map_mutex};
347 if (joystick_map.find(guid) == joystick_map.end()) { 355 if (joystick_map.find(guid) == joystick_map.end()) {
348 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); 356 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller);
@@ -465,13 +473,19 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
465 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); 473 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
466 SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); 474 SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
467 475
468 // Disable hidapi drivers for switch controllers when the custom joycon driver is enabled 476 // Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled
469 if (Settings::values.enable_joycon_driver) { 477 if (Settings::values.enable_joycon_driver) {
470 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0"); 478 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0");
471 } else { 479 } else {
472 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); 480 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1");
473 } 481 }
474 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1"); 482
483 // Disable hidapi drivers for pro controllers when the custom joycon driver is enabled
484 if (Settings::values.enable_procon_driver) {
485 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0");
486 } else {
487 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1");
488 }
475 489
476 // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native 490 // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native
477 // driver on Linux. 491 // driver on Linux.
@@ -602,7 +616,7 @@ bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
602 const auto joystick = 616 const auto joystick =
603 GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); 617 GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
604 618
605 constexpr Common::Input::VibrationStatus test_vibration{ 619 static constexpr Common::Input::VibrationStatus test_vibration{
606 .low_amplitude = 1, 620 .low_amplitude = 1,
607 .low_frequency = 160.0f, 621 .low_frequency = 160.0f,
608 .high_amplitude = 1, 622 .high_amplitude = 1,
@@ -610,7 +624,7 @@ bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
610 .type = Common::Input::VibrationAmplificationType::Exponential, 624 .type = Common::Input::VibrationAmplificationType::Exponential,
611 }; 625 };
612 626
613 constexpr Common::Input::VibrationStatus zero_vibration{ 627 static constexpr Common::Input::VibrationStatus zero_vibration{
614 .low_amplitude = 0, 628 .low_amplitude = 0,
615 .low_frequency = 160.0f, 629 .low_frequency = 160.0f,
616 .high_amplitude = 0, 630 .high_amplitude = 0,
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp
index 8f94c9f45..e65b6b845 100644
--- a/src/input_common/helpers/joycon_driver.cpp
+++ b/src/input_common/helpers/joycon_driver.cpp
@@ -543,9 +543,10 @@ void JoyconDriver::SetCallbacks(const JoyconCallbacks& callbacks) {
543 543
544DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, 544DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info,
545 ControllerType& controller_type) { 545 ControllerType& controller_type) {
546 static constexpr std::array<std::pair<u32, ControllerType>, 2> supported_devices{ 546 static constexpr std::array<std::pair<u32, ControllerType>, 6> supported_devices{
547 std::pair<u32, ControllerType>{0x2006, ControllerType::Left}, 547 std::pair<u32, ControllerType>{0x2006, ControllerType::Left},
548 {0x2007, ControllerType::Right}, 548 {0x2007, ControllerType::Right},
549 {0x2009, ControllerType::Pro},
549 }; 550 };
550 constexpr u16 nintendo_vendor_id = 0x057e; 551 constexpr u16 nintendo_vendor_id = 0x057e;
551 552
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp
index d6e49d2c5..6990a86b9 100644
--- a/src/input_common/input_mapping.cpp
+++ b/src/input_common/input_mapping.cpp
@@ -194,6 +194,10 @@ bool MappingFactory::IsDriverValid(const MappingData& data) const {
194 if (data.engine == "keyboard" && data.pad.port != 0) { 194 if (data.engine == "keyboard" && data.pad.port != 0) {
195 return false; 195 return false;
196 } 196 }
197 // Only port 0 can be mapped on the mouse
198 if (data.engine == "mouse" && data.pad.port != 0) {
199 return false;
200 }
197 // To prevent mapping with two devices we disable any UDP except motion 201 // To prevent mapping with two devices we disable any UDP except motion
198 if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" && 202 if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" &&
199 data.type != EngineInputType::Motion) { 203 data.type != EngineInputType::Motion) {
diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
index 1b006e811..c3c2281bb 100644
--- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
@@ -310,12 +310,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
310 if (runtime_info.force_early_z) { 310 if (runtime_info.force_early_z) {
311 header += "layout(early_fragment_tests)in;"; 311 header += "layout(early_fragment_tests)in;";
312 } 312 }
313 if (info.uses_sample_id) {
314 header += "in int gl_SampleID;";
315 }
316 if (info.stores_sample_mask) {
317 header += "out int gl_SampleMask[];";
318 }
319 break; 313 break;
320 case Stage::Compute: 314 case Stage::Compute:
321 stage_name = "cs"; 315 stage_name = "cs";
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index a42453e90..17a6d4888 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -292,7 +292,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
292 292
293 Optimization::PositionPass(env, program); 293 Optimization::PositionPass(env, program);
294 294
295 Optimization::GlobalMemoryToStorageBufferPass(program, host_info); 295 Optimization::GlobalMemoryToStorageBufferPass(program);
296 Optimization::TexturePass(env, program, host_info); 296 Optimization::TexturePass(env, program, host_info);
297 297
298 if (Settings::values.resolution_info.active) { 298 if (Settings::values.resolution_info.active) {
diff --git a/src/shader_recompiler/host_translate_info.h b/src/shader_recompiler/host_translate_info.h
index 55fc48768..2aaa6c5ea 100644
--- a/src/shader_recompiler/host_translate_info.h
+++ b/src/shader_recompiler/host_translate_info.h
@@ -15,7 +15,6 @@ struct HostTranslateInfo {
15 bool needs_demote_reorder{}; ///< True when the device needs DemoteToHelperInvocation reordered 15 bool needs_demote_reorder{}; ///< True when the device needs DemoteToHelperInvocation reordered
16 bool support_snorm_render_buffer{}; ///< True when the device supports SNORM render buffers 16 bool support_snorm_render_buffer{}; ///< True when the device supports SNORM render buffers
17 bool support_viewport_index_layer{}; ///< True when the device supports gl_Layer in VS 17 bool support_viewport_index_layer{}; ///< True when the device supports gl_Layer in VS
18 u32 min_ssbo_alignment{}; ///< Minimum alignment supported by the device for SSBOs
19 bool support_geometry_shader_passthrough{}; ///< True when the device supports geometry 18 bool support_geometry_shader_passthrough{}; ///< True when the device supports geometry
20 ///< passthrough shaders 19 ///< passthrough shaders
21}; 20};
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
index 9101722ba..336338e62 100644
--- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
+++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
@@ -11,7 +11,6 @@
11#include "shader_recompiler/frontend/ir/breadth_first_search.h" 11#include "shader_recompiler/frontend/ir/breadth_first_search.h"
12#include "shader_recompiler/frontend/ir/ir_emitter.h" 12#include "shader_recompiler/frontend/ir/ir_emitter.h"
13#include "shader_recompiler/frontend/ir/value.h" 13#include "shader_recompiler/frontend/ir/value.h"
14#include "shader_recompiler/host_translate_info.h"
15#include "shader_recompiler/ir_opt/passes.h" 14#include "shader_recompiler/ir_opt/passes.h"
16 15
17namespace Shader::Optimization { 16namespace Shader::Optimization {
@@ -403,7 +402,7 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageInfo& info)
403} 402}
404 403
405/// Returns the offset in indices (not bytes) for an equivalent storage instruction 404/// Returns the offset in indices (not bytes) for an equivalent storage instruction
406IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer, u32 alignment) { 405IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer) {
407 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; 406 IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
408 IR::U32 offset; 407 IR::U32 offset;
409 if (const std::optional<LowAddrInfo> low_addr{TrackLowAddress(&inst)}) { 408 if (const std::optional<LowAddrInfo> low_addr{TrackLowAddress(&inst)}) {
@@ -416,10 +415,7 @@ IR::U32 StorageOffset(IR::Block& block, IR::Inst& inst, StorageBufferAddr buffer
416 } 415 }
417 // Subtract the least significant 32 bits from the guest offset. The result is the storage 416 // Subtract the least significant 32 bits from the guest offset. The result is the storage
418 // buffer offset in bytes. 417 // buffer offset in bytes.
419 IR::U32 low_cbuf{ir.GetCbuf(ir.Imm32(buffer.index), ir.Imm32(buffer.offset))}; 418 const IR::U32 low_cbuf{ir.GetCbuf(ir.Imm32(buffer.index), ir.Imm32(buffer.offset))};
420
421 // Align the offset base to match the host alignment requirements
422 low_cbuf = ir.BitwiseAnd(low_cbuf, ir.Imm32(~(alignment - 1U)));
423 return ir.ISub(offset, low_cbuf); 419 return ir.ISub(offset, low_cbuf);
424} 420}
425 421
@@ -514,7 +510,7 @@ void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index,
514} 510}
515} // Anonymous namespace 511} // Anonymous namespace
516 512
517void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateInfo& host_info) { 513void GlobalMemoryToStorageBufferPass(IR::Program& program) {
518 StorageInfo info; 514 StorageInfo info;
519 for (IR::Block* const block : program.post_order_blocks) { 515 for (IR::Block* const block : program.post_order_blocks) {
520 for (IR::Inst& inst : block->Instructions()) { 516 for (IR::Inst& inst : block->Instructions()) {
@@ -538,8 +534,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateIn
538 const IR::U32 index{IR::Value{static_cast<u32>(info.set.index_of(it))}}; 534 const IR::U32 index{IR::Value{static_cast<u32>(info.set.index_of(it))}};
539 IR::Block* const block{storage_inst.block}; 535 IR::Block* const block{storage_inst.block};
540 IR::Inst* const inst{storage_inst.inst}; 536 IR::Inst* const inst{storage_inst.inst};
541 const IR::U32 offset{ 537 const IR::U32 offset{StorageOffset(*block, *inst, storage_buffer)};
542 StorageOffset(*block, *inst, storage_buffer, host_info.min_ssbo_alignment)};
543 Replace(*block, *inst, index, offset); 538 Replace(*block, *inst, index, offset);
544 } 539 }
545} 540}
diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h
index 4ffad1172..1f8f2ba95 100644
--- a/src/shader_recompiler/ir_opt/passes.h
+++ b/src/shader_recompiler/ir_opt/passes.h
@@ -15,7 +15,7 @@ namespace Shader::Optimization {
15void CollectShaderInfoPass(Environment& env, IR::Program& program); 15void CollectShaderInfoPass(Environment& env, IR::Program& program);
16void ConstantPropagationPass(Environment& env, IR::Program& program); 16void ConstantPropagationPass(Environment& env, IR::Program& program);
17void DeadCodeEliminationPass(IR::Program& program); 17void DeadCodeEliminationPass(IR::Program& program);
18void GlobalMemoryToStorageBufferPass(IR::Program& program, const HostTranslateInfo& host_info); 18void GlobalMemoryToStorageBufferPass(IR::Program& program);
19void IdentityRemovalPass(IR::Program& program); 19void IdentityRemovalPass(IR::Program& program);
20void LowerFp16ToFp32(IR::Program& program); 20void LowerFp16ToFp32(IR::Program& program);
21void LowerInt64ToInt32(IR::Program& program); 21void LowerInt64ToInt32(IR::Program& program);
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 627917ab6..06fd40851 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -1938,21 +1938,14 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s
1938 bool is_written) const { 1938 bool is_written) const {
1939 const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); 1939 const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr);
1940 const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8); 1940 const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8);
1941 const u32 alignment = runtime.GetStorageBufferAlignment(); 1941 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
1942
1943 const GPUVAddr aligned_gpu_addr = Common::AlignDown(gpu_addr, alignment);
1944 const u32 aligned_size =
1945 Common::AlignUp(static_cast<u32>(gpu_addr - aligned_gpu_addr) + size, alignment);
1946
1947 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(aligned_gpu_addr);
1948 if (!cpu_addr || size == 0) { 1942 if (!cpu_addr || size == 0) {
1949 return NULL_BINDING; 1943 return NULL_BINDING;
1950 } 1944 }
1951 1945 const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE);
1952 const VAddr cpu_end = Common::AlignUp(*cpu_addr + aligned_size, Core::Memory::YUZU_PAGESIZE);
1953 const Binding binding{ 1946 const Binding binding{
1954 .cpu_addr = *cpu_addr, 1947 .cpu_addr = *cpu_addr,
1955 .size = is_written ? aligned_size : static_cast<u32>(cpu_end - *cpu_addr), 1948 .size = is_written ? size : static_cast<u32>(cpu_end - *cpu_addr),
1956 .buffer_id = BufferId{}, 1949 .buffer_id = BufferId{},
1957 }; 1950 };
1958 return binding; 1951 return binding;
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index ae9da6290..614d61db4 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -186,6 +186,7 @@ bool Maxwell3D::IsMethodExecutable(u32 method) {
186 case MAXWELL3D_REG_INDEX(launch_dma): 186 case MAXWELL3D_REG_INDEX(launch_dma):
187 case MAXWELL3D_REG_INDEX(inline_data): 187 case MAXWELL3D_REG_INDEX(inline_data):
188 case MAXWELL3D_REG_INDEX(fragment_barrier): 188 case MAXWELL3D_REG_INDEX(fragment_barrier):
189 case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache):
189 case MAXWELL3D_REG_INDEX(tiled_cache_barrier): 190 case MAXWELL3D_REG_INDEX(tiled_cache_barrier):
190 return true; 191 return true;
191 default: 192 default:
@@ -258,7 +259,7 @@ u32 Maxwell3D::GetMaxCurrentVertices() {
258size_t Maxwell3D::EstimateIndexBufferSize() { 259size_t Maxwell3D::EstimateIndexBufferSize() {
259 GPUVAddr start_address = regs.index_buffer.StartAddress(); 260 GPUVAddr start_address = regs.index_buffer.StartAddress();
260 GPUVAddr end_address = regs.index_buffer.EndAddress(); 261 GPUVAddr end_address = regs.index_buffer.EndAddress();
261 constexpr std::array<size_t, 4> max_sizes = { 262 static constexpr std::array<size_t, 4> max_sizes = {
262 std::numeric_limits<u8>::max(), std::numeric_limits<u16>::max(), 263 std::numeric_limits<u8>::max(), std::numeric_limits<u16>::max(),
263 std::numeric_limits<u32>::max(), std::numeric_limits<u32>::max()}; 264 std::numeric_limits<u32>::max(), std::numeric_limits<u32>::max()};
264 const size_t byte_size = regs.index_buffer.FormatSizeInBytes(); 265 const size_t byte_size = regs.index_buffer.FormatSizeInBytes();
@@ -375,6 +376,9 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
375 return; 376 return;
376 case MAXWELL3D_REG_INDEX(fragment_barrier): 377 case MAXWELL3D_REG_INDEX(fragment_barrier):
377 return rasterizer->FragmentBarrier(); 378 return rasterizer->FragmentBarrier();
379 case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache):
380 rasterizer->InvalidateGPUCache();
381 return rasterizer->WaitForIdle();
378 case MAXWELL3D_REG_INDEX(tiled_cache_barrier): 382 case MAXWELL3D_REG_INDEX(tiled_cache_barrier):
379 return rasterizer->TiledCacheBarrier(); 383 return rasterizer->TiledCacheBarrier();
380 default: 384 default:
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index c6d54be63..7024a19cf 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -99,7 +99,7 @@ struct GPU::Impl {
99 99
100 /// Signal the ending of command list. 100 /// Signal the ending of command list.
101 void OnCommandListEnd() { 101 void OnCommandListEnd() {
102 gpu_thread.OnCommandListEnd(); 102 rasterizer->ReleaseFences();
103 } 103 }
104 104
105 /// Request a host GPU memory flush from the CPU. 105 /// Request a host GPU memory flush from the CPU.
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 164a5252a..9c103c0d4 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -40,8 +40,6 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
40 scheduler.Push(submit_list->channel, std::move(submit_list->entries)); 40 scheduler.Push(submit_list->channel, std::move(submit_list->entries));
41 } else if (const auto* data = std::get_if<SwapBuffersCommand>(&next.data)) { 41 } else if (const auto* data = std::get_if<SwapBuffersCommand>(&next.data)) {
42 renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); 42 renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr);
43 } else if (std::holds_alternative<OnCommandListEndCommand>(next.data)) {
44 rasterizer->ReleaseFences();
45 } else if (std::holds_alternative<GPUTickCommand>(next.data)) { 43 } else if (std::holds_alternative<GPUTickCommand>(next.data)) {
46 system.GPU().TickWork(); 44 system.GPU().TickWork();
47 } else if (const auto* flush = std::get_if<FlushRegionCommand>(&next.data)) { 45 } else if (const auto* flush = std::get_if<FlushRegionCommand>(&next.data)) {
@@ -110,10 +108,6 @@ void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) {
110 rasterizer->OnCPUWrite(addr, size); 108 rasterizer->OnCPUWrite(addr, size);
111} 109}
112 110
113void ThreadManager::OnCommandListEnd() {
114 PushCommand(OnCommandListEndCommand());
115}
116
117u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) { 111u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) {
118 if (!is_async) { 112 if (!is_async) {
119 // In synchronous GPU mode, block the caller until the command has executed 113 // In synchronous GPU mode, block the caller until the command has executed
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h
index c71a419c7..90bcb5958 100644
--- a/src/video_core/gpu_thread.h
+++ b/src/video_core/gpu_thread.h
@@ -77,16 +77,12 @@ struct FlushAndInvalidateRegionCommand final {
77 u64 size; 77 u64 size;
78}; 78};
79 79
80/// Command called within the gpu, to schedule actions after a command list end
81struct OnCommandListEndCommand final {};
82
83/// Command to make the gpu look into pending requests 80/// Command to make the gpu look into pending requests
84struct GPUTickCommand final {}; 81struct GPUTickCommand final {};
85 82
86using CommandData = 83using CommandData =
87 std::variant<std::monostate, SubmitListCommand, SwapBuffersCommand, FlushRegionCommand, 84 std::variant<std::monostate, SubmitListCommand, SwapBuffersCommand, FlushRegionCommand,
88 InvalidateRegionCommand, FlushAndInvalidateRegionCommand, OnCommandListEndCommand, 85 InvalidateRegionCommand, FlushAndInvalidateRegionCommand, GPUTickCommand>;
89 GPUTickCommand>;
90 86
91struct CommandDataContainer { 87struct CommandDataContainer {
92 CommandDataContainer() = default; 88 CommandDataContainer() = default;
@@ -134,8 +130,6 @@ public:
134 /// Notify rasterizer that any caches of the specified region should be flushed and invalidated 130 /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
135 void FlushAndInvalidateRegion(VAddr addr, u64 size); 131 void FlushAndInvalidateRegion(VAddr addr, u64 size);
136 132
137 void OnCommandListEnd();
138
139 void TickGPU(); 133 void TickGPU();
140 134
141private: 135private:
diff --git a/src/video_core/host1x/codecs/codec.cpp b/src/video_core/host1x/codecs/codec.cpp
index 42e7d6e4f..3e9022dce 100644
--- a/src/video_core/host1x/codecs/codec.cpp
+++ b/src/video_core/host1x/codecs/codec.cpp
@@ -152,6 +152,8 @@ bool Codec::CreateGpuAvDevice() {
152void Codec::InitializeAvCodecContext() { 152void Codec::InitializeAvCodecContext() {
153 av_codec_ctx = avcodec_alloc_context3(av_codec); 153 av_codec_ctx = avcodec_alloc_context3(av_codec);
154 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0); 154 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
155 av_codec_ctx->thread_count = 0;
156 av_codec_ctx->thread_type &= ~FF_THREAD_FRAME;
155} 157}
156 158
157void Codec::InitializeGpuDecoder() { 159void Codec::InitializeGpuDecoder() {
diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp
index 36a04e4e0..10d7ef884 100644
--- a/src/video_core/host1x/vic.cpp
+++ b/src/video_core/host1x/vic.cpp
@@ -189,9 +189,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
189 for (std::size_t y = 0; y < frame_height; ++y) { 189 for (std::size_t y = 0; y < frame_height; ++y) {
190 const std::size_t src = y * stride; 190 const std::size_t src = y * stride;
191 const std::size_t dst = y * aligned_width; 191 const std::size_t dst = y * aligned_width;
192 for (std::size_t x = 0; x < frame_width; ++x) { 192 std::memcpy(luma_buffer.data() + dst, luma_src + src, frame_width);
193 luma_buffer[dst + x] = luma_src[src + x];
194 }
195 } 193 }
196 host1x.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), 194 host1x.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(),
197 luma_buffer.size()); 195 luma_buffer.size());
@@ -205,15 +203,15 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
205 // Frame from FFmpeg software 203 // Frame from FFmpeg software
206 // Populate chroma buffer from both channels with interleaving. 204 // Populate chroma buffer from both channels with interleaving.
207 const std::size_t half_width = frame_width / 2; 205 const std::size_t half_width = frame_width / 2;
206 u8* chroma_buffer_data = chroma_buffer.data();
208 const u8* chroma_b_src = frame->data[1]; 207 const u8* chroma_b_src = frame->data[1];
209 const u8* chroma_r_src = frame->data[2]; 208 const u8* chroma_r_src = frame->data[2];
210 for (std::size_t y = 0; y < half_height; ++y) { 209 for (std::size_t y = 0; y < half_height; ++y) {
211 const std::size_t src = y * half_stride; 210 const std::size_t src = y * half_stride;
212 const std::size_t dst = y * aligned_width; 211 const std::size_t dst = y * aligned_width;
213
214 for (std::size_t x = 0; x < half_width; ++x) { 212 for (std::size_t x = 0; x < half_width; ++x) {
215 chroma_buffer[dst + x * 2] = chroma_b_src[src + x]; 213 chroma_buffer_data[dst + x * 2] = chroma_b_src[src + x];
216 chroma_buffer[dst + x * 2 + 1] = chroma_r_src[src + x]; 214 chroma_buffer_data[dst + x * 2 + 1] = chroma_r_src[src + x];
217 } 215 }
218 } 216 }
219 break; 217 break;
@@ -225,9 +223,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
225 for (std::size_t y = 0; y < half_height; ++y) { 223 for (std::size_t y = 0; y < half_height; ++y) {
226 const std::size_t src = y * stride; 224 const std::size_t src = y * stride;
227 const std::size_t dst = y * aligned_width; 225 const std::size_t dst = y * aligned_width;
228 for (std::size_t x = 0; x < frame_width; ++x) { 226 std::memcpy(chroma_buffer.data() + dst, chroma_src + src, frame_width);
229 chroma_buffer[dst + x] = chroma_src[src + x];
230 }
231 } 227 }
232 break; 228 break;
233 } 229 }
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index 52cd5bb81..2442c3c29 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -22,6 +22,8 @@ set(SHADER_FILES
22 convert_d24s8_to_abgr8.frag 22 convert_d24s8_to_abgr8.frag
23 convert_depth_to_float.frag 23 convert_depth_to_float.frag
24 convert_float_to_depth.frag 24 convert_float_to_depth.frag
25 convert_msaa_to_non_msaa.comp
26 convert_non_msaa_to_msaa.comp
25 convert_s8d24_to_abgr8.frag 27 convert_s8d24_to_abgr8.frag
26 full_screen_triangle.vert 28 full_screen_triangle.vert
27 fxaa.frag 29 fxaa.frag
diff --git a/src/video_core/host_shaders/convert_msaa_to_non_msaa.comp b/src/video_core/host_shaders/convert_msaa_to_non_msaa.comp
new file mode 100644
index 000000000..fc3854d18
--- /dev/null
+++ b/src/video_core/host_shaders/convert_msaa_to_non_msaa.comp
@@ -0,0 +1,30 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#version 450 core
5layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
6
7layout (binding = 0, rgba8) uniform readonly restrict image2DMSArray msaa_in;
8layout (binding = 1, rgba8) uniform writeonly restrict image2DArray output_img;
9
10void main() {
11 const ivec3 coords = ivec3(gl_GlobalInvocationID);
12 if (any(greaterThanEqual(coords, imageSize(msaa_in)))) {
13 return;
14 }
15
16 // TODO: Specialization constants for num_samples?
17 const int num_samples = imageSamples(msaa_in);
18 for (int curr_sample = 0; curr_sample < num_samples; ++curr_sample) {
19 const vec4 pixel = imageLoad(msaa_in, coords, curr_sample);
20
21 const int single_sample_x = 2 * coords.x + (curr_sample & 1);
22 const int single_sample_y = 2 * coords.y + ((curr_sample / 2) & 1);
23 const ivec3 dest_coords = ivec3(single_sample_x, single_sample_y, coords.z);
24
25 if (any(greaterThanEqual(dest_coords, imageSize(output_img)))) {
26 continue;
27 }
28 imageStore(output_img, dest_coords, pixel);
29 }
30}
diff --git a/src/video_core/host_shaders/convert_non_msaa_to_msaa.comp b/src/video_core/host_shaders/convert_non_msaa_to_msaa.comp
new file mode 100644
index 000000000..dedd962f1
--- /dev/null
+++ b/src/video_core/host_shaders/convert_non_msaa_to_msaa.comp
@@ -0,0 +1,29 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#version 450 core
5layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
6
7layout (binding = 0, rgba8) uniform readonly restrict image2DArray img_in;
8layout (binding = 1, rgba8) uniform writeonly restrict image2DMSArray output_msaa;
9
10void main() {
11 const ivec3 coords = ivec3(gl_GlobalInvocationID);
12 if (any(greaterThanEqual(coords, imageSize(output_msaa)))) {
13 return;
14 }
15
16 // TODO: Specialization constants for num_samples?
17 const int num_samples = imageSamples(output_msaa);
18 for (int curr_sample = 0; curr_sample < num_samples; ++curr_sample) {
19 const int single_sample_x = 2 * coords.x + (curr_sample & 1);
20 const int single_sample_y = 2 * coords.y + ((curr_sample / 2) & 1);
21 const ivec3 single_coords = ivec3(single_sample_x, single_sample_y, coords.z);
22
23 if (any(greaterThanEqual(single_coords, imageSize(img_in)))) {
24 continue;
25 }
26 const vec4 pixel = imageLoad(img_in, single_coords);
27 imageStore(output_msaa, coords, curr_sample, pixel);
28 }
29}
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 9ebfb6179..cf56392ef 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -216,7 +216,7 @@ private:
216 std::vector<u64> big_page_continous; 216 std::vector<u64> big_page_continous;
217 std::vector<std::pair<VAddr, std::size_t>> page_stash{}; 217 std::vector<std::pair<VAddr, std::size_t>> page_stash{};
218 218
219 constexpr static size_t continous_bits = 64; 219 static constexpr size_t continous_bits = 64;
220 220
221 const size_t unique_identifier; 221 const size_t unique_identifier;
222 std::unique_ptr<VideoCommon::InvalidationAccumulator> accumulator; 222 std::unique_ptr<VideoCommon::InvalidationAccumulator> accumulator;
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index bb1962073..a8c3f8b67 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -160,10 +160,6 @@ public:
160 return device.CanReportMemoryUsage(); 160 return device.CanReportMemoryUsage();
161 } 161 }
162 162
163 u32 GetStorageBufferAlignment() const {
164 return static_cast<u32>(device.GetShaderStorageBufferAlignment());
165 }
166
167private: 163private:
168 static constexpr std::array PABO_LUT{ 164 static constexpr std::array PABO_LUT{
169 GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, 165 GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV, GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV,
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 626ea7dcb..479bb8ba3 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -236,7 +236,6 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
236 .needs_demote_reorder = device.IsAmd(), 236 .needs_demote_reorder = device.IsAmd(),
237 .support_snorm_render_buffer = false, 237 .support_snorm_render_buffer = false,
238 .support_viewport_index_layer = device.HasVertexViewportLayer(), 238 .support_viewport_index_layer = device.HasVertexViewportLayer(),
239 .min_ssbo_alignment = static_cast<u32>(device.GetShaderStorageBufferAlignment()),
240 .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(), 239 .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),
241 } { 240 } {
242 if (use_asynchronous_shaders) { 241 if (use_asynchronous_shaders) {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 9f7ce7414..eb6e43a08 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -557,6 +557,14 @@ void TextureCacheRuntime::CopyImage(Image& dst_image, Image& src_image,
557 } 557 }
558} 558}
559 559
560void TextureCacheRuntime::CopyImageMSAA(Image& dst_image, Image& src_image,
561 std::span<const VideoCommon::ImageCopy> copies) {
562 LOG_DEBUG(Render_OpenGL, "Copying from {} samples to {} samples", src_image.info.num_samples,
563 dst_image.info.num_samples);
564 // TODO: Leverage the format conversion pass if possible/accurate.
565 util_shaders.CopyMSAA(dst_image, src_image, copies);
566}
567
560void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, 568void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
561 std::span<const VideoCommon::ImageCopy> copies) { 569 std::span<const VideoCommon::ImageCopy> copies) {
562 LOG_DEBUG(Render_OpenGL, "Converting {} to {}", src.info.format, dst.info.format); 570 LOG_DEBUG(Render_OpenGL, "Converting {} to {}", src.info.format, dst.info.format);
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 5d9d370f2..e30875496 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -93,12 +93,19 @@ public:
93 return device.CanReportMemoryUsage(); 93 return device.CanReportMemoryUsage();
94 } 94 }
95 95
96 bool ShouldReinterpret([[maybe_unused]] Image& dst, [[maybe_unused]] Image& src) { 96 bool ShouldReinterpret([[maybe_unused]] Image& dst,
97 [[maybe_unused]] Image& src) const noexcept {
98 return true;
99 }
100
101 bool CanUploadMSAA() const noexcept {
97 return true; 102 return true;
98 } 103 }
99 104
100 void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); 105 void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
101 106
107 void CopyImageMSAA(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
108
102 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); 109 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
103 110
104 void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) { 111 void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 404def62e..2c7ac210b 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -12,6 +12,8 @@
12#include "video_core/host_shaders/astc_decoder_comp.h" 12#include "video_core/host_shaders/astc_decoder_comp.h"
13#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h" 13#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h"
14#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h" 14#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h"
15#include "video_core/host_shaders/convert_msaa_to_non_msaa_comp.h"
16#include "video_core/host_shaders/convert_non_msaa_to_msaa_comp.h"
15#include "video_core/host_shaders/opengl_convert_s8d24_comp.h" 17#include "video_core/host_shaders/opengl_convert_s8d24_comp.h"
16#include "video_core/host_shaders/opengl_copy_bc4_comp.h" 18#include "video_core/host_shaders/opengl_copy_bc4_comp.h"
17#include "video_core/host_shaders/pitch_unswizzle_comp.h" 19#include "video_core/host_shaders/pitch_unswizzle_comp.h"
@@ -51,7 +53,9 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
51 block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)), 53 block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
52 pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)), 54 pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
53 copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)), 55 copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
54 convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)) { 56 convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)),
57 convert_ms_to_nonms_program(MakeProgram(CONVERT_MSAA_TO_NON_MSAA_COMP)),
58 convert_nonms_to_ms_program(MakeProgram(CONVERT_NON_MSAA_TO_MSAA_COMP)) {
55 const auto swizzle_table = Tegra::Texture::MakeSwizzleTable(); 59 const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
56 swizzle_table_buffer.Create(); 60 swizzle_table_buffer.Create();
57 glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0); 61 glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
@@ -269,6 +273,33 @@ void UtilShaders::ConvertS8D24(Image& dst_image, std::span<const ImageCopy> copi
269 program_manager.RestoreGuestCompute(); 273 program_manager.RestoreGuestCompute();
270} 274}
271 275
276void UtilShaders::CopyMSAA(Image& dst_image, Image& src_image,
277 std::span<const VideoCommon::ImageCopy> copies) {
278 const bool is_ms_to_non_ms = src_image.info.num_samples > 1 && dst_image.info.num_samples == 1;
279 const auto program_handle =
280 is_ms_to_non_ms ? convert_ms_to_nonms_program.handle : convert_nonms_to_ms_program.handle;
281 program_manager.BindComputeProgram(program_handle);
282
283 for (const ImageCopy& copy : copies) {
284 ASSERT(copy.src_subresource.base_layer == 0);
285 ASSERT(copy.src_subresource.num_layers == 1);
286 ASSERT(copy.dst_subresource.base_layer == 0);
287 ASSERT(copy.dst_subresource.num_layers == 1);
288
289 glBindImageTexture(0, src_image.StorageHandle(), copy.src_subresource.base_level, GL_TRUE,
290 0, GL_READ_ONLY, GL_RGBA8);
291 glBindImageTexture(1, dst_image.StorageHandle(), copy.dst_subresource.base_level, GL_TRUE,
292 0, GL_WRITE_ONLY, GL_RGBA8);
293
294 const u32 num_dispatches_x = Common::DivCeil(copy.extent.width, 8U);
295 const u32 num_dispatches_y = Common::DivCeil(copy.extent.height, 8U);
296 const u32 num_dispatches_z = copy.extent.depth;
297
298 glDispatchCompute(num_dispatches_x, num_dispatches_y, num_dispatches_z);
299 }
300 program_manager.RestoreGuestCompute();
301}
302
272GLenum StoreFormat(u32 bytes_per_block) { 303GLenum StoreFormat(u32 bytes_per_block) {
273 switch (bytes_per_block) { 304 switch (bytes_per_block) {
274 case 1: 305 case 1:
diff --git a/src/video_core/renderer_opengl/util_shaders.h b/src/video_core/renderer_opengl/util_shaders.h
index 44efb6ecf..9013808e7 100644
--- a/src/video_core/renderer_opengl/util_shaders.h
+++ b/src/video_core/renderer_opengl/util_shaders.h
@@ -40,6 +40,9 @@ public:
40 40
41 void ConvertS8D24(Image& dst_image, std::span<const VideoCommon::ImageCopy> copies); 41 void ConvertS8D24(Image& dst_image, std::span<const VideoCommon::ImageCopy> copies);
42 42
43 void CopyMSAA(Image& dst_image, Image& src_image,
44 std::span<const VideoCommon::ImageCopy> copies);
45
43private: 46private:
44 ProgramManager& program_manager; 47 ProgramManager& program_manager;
45 48
@@ -51,6 +54,8 @@ private:
51 OGLProgram pitch_unswizzle_program; 54 OGLProgram pitch_unswizzle_program;
52 OGLProgram copy_bc4_program; 55 OGLProgram copy_bc4_program;
53 OGLProgram convert_s8d24_program; 56 OGLProgram convert_s8d24_program;
57 OGLProgram convert_ms_to_nonms_program;
58 OGLProgram convert_nonms_to_ms_program;
54}; 59};
55 60
56GLenum StoreFormat(u32 bytes_per_block); 61GLenum StoreFormat(u32 bytes_per_block);
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 1cfb4c2ff..b0153a502 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -330,10 +330,6 @@ bool BufferCacheRuntime::CanReportMemoryUsage() const {
330 return device.CanReportMemoryUsage(); 330 return device.CanReportMemoryUsage();
331} 331}
332 332
333u32 BufferCacheRuntime::GetStorageBufferAlignment() const {
334 return static_cast<u32>(device.GetStorageBufferAlignment());
335}
336
337void BufferCacheRuntime::Finish() { 333void BufferCacheRuntime::Finish() {
338 scheduler.Finish(); 334 scheduler.Finish();
339} 335}
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index 06539c733..183b33632 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -73,8 +73,6 @@ public:
73 73
74 bool CanReportMemoryUsage() const; 74 bool CanReportMemoryUsage() const;
75 75
76 u32 GetStorageBufferAlignment() const;
77
78 [[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size); 76 [[nodiscard]] StagingBufferRef UploadStagingBuffer(size_t size);
79 77
80 [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size); 78 [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size);
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index f91bb5a1d..baedc4424 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -548,31 +548,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
548 static_vector<VkVertexInputBindingDescription, 32> vertex_bindings; 548 static_vector<VkVertexInputBindingDescription, 32> vertex_bindings;
549 static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors; 549 static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors;
550 static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes; 550 static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes;
551 if (key.state.dynamic_vertex_input) { 551 if (!key.state.dynamic_vertex_input) {
552 const size_t num_vertex_arrays = std::min(
553 key.state.attributes.size(), static_cast<size_t>(device.GetMaxVertexInputBindings()));
554 for (size_t index = 0; index < num_vertex_arrays; ++index) {
555 const u32 type = key.state.DynamicAttributeType(index);
556 if (!stage_infos[0].loads.Generic(index) || type == 0) {
557 continue;
558 }
559 vertex_attributes.push_back({
560 .location = static_cast<u32>(index),
561 .binding = 0,
562 .format = type == 1 ? VK_FORMAT_R32_SFLOAT
563 : type == 2 ? VK_FORMAT_R32_SINT
564 : VK_FORMAT_R32_UINT,
565 .offset = 0,
566 });
567 }
568 if (!vertex_attributes.empty()) {
569 vertex_bindings.push_back({
570 .binding = 0,
571 .stride = 4,
572 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
573 });
574 }
575 } else {
576 const size_t num_vertex_arrays = std::min( 552 const size_t num_vertex_arrays = std::min(
577 Maxwell::NumVertexArrays, static_cast<size_t>(device.GetMaxVertexInputBindings())); 553 Maxwell::NumVertexArrays, static_cast<size_t>(device.GetMaxVertexInputBindings()));
578 for (size_t index = 0; index < num_vertex_arrays; ++index) { 554 for (size_t index = 0; index < num_vertex_arrays; ++index) {
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 7e69b11d8..0684cceed 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -344,7 +344,6 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
344 driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE, 344 driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE,
345 .support_snorm_render_buffer = true, 345 .support_snorm_render_buffer = true,
346 .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(), 346 .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
347 .min_ssbo_alignment = static_cast<u32>(device.GetStorageBufferAlignment()),
348 .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), 347 .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
349 }; 348 };
350 349
diff --git a/src/video_core/renderer_vulkan/vk_smaa.cpp b/src/video_core/renderer_vulkan/vk_smaa.cpp
index 8eb735489..f8735189d 100644
--- a/src/video_core/renderer_vulkan/vk_smaa.cpp
+++ b/src/video_core/renderer_vulkan/vk_smaa.cpp
@@ -468,7 +468,7 @@ VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector<VkDescriptorImageInfo>
468} 468}
469 469
470void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) { 470void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) {
471 constexpr std::array<VkImageSubresourceRange, 1> subresources{{{ 471 static constexpr std::array<VkImageSubresourceRange, 1> subresources{{{
472 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 472 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
473 .baseMipLevel = 0, 473 .baseMipLevel = 0,
474 .levelCount = 1, 474 .levelCount = 1,
@@ -528,8 +528,8 @@ SMAA::SMAA(const Device& device, MemoryAllocator& allocator, size_t image_count,
528} 528}
529 529
530void SMAA::CreateImages() { 530void SMAA::CreateImages() {
531 constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT}; 531 static constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT};
532 constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT}; 532 static constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT};
533 533
534 std::tie(m_static_images[Area], m_static_buffer_commits[Area]) = 534 std::tie(m_static_images[Area], m_static_buffer_commits[Area]) =
535 CreateWrappedImage(m_device, m_allocator, area_extent, VK_FORMAT_R8G8_UNORM); 535 CreateWrappedImage(m_device, m_allocator, area_extent, VK_FORMAT_R8G8_UNORM);
@@ -586,12 +586,12 @@ void SMAA::CreateSampler() {
586 586
587void SMAA::CreateShaders() { 587void SMAA::CreateShaders() {
588 // These match the order of the SMAAStage enum 588 // These match the order of the SMAAStage enum
589 constexpr std::array vert_shader_sources{ 589 static constexpr std::array vert_shader_sources{
590 ARRAY_TO_SPAN(SMAA_EDGE_DETECTION_VERT_SPV), 590 ARRAY_TO_SPAN(SMAA_EDGE_DETECTION_VERT_SPV),
591 ARRAY_TO_SPAN(SMAA_BLENDING_WEIGHT_CALCULATION_VERT_SPV), 591 ARRAY_TO_SPAN(SMAA_BLENDING_WEIGHT_CALCULATION_VERT_SPV),
592 ARRAY_TO_SPAN(SMAA_NEIGHBORHOOD_BLENDING_VERT_SPV), 592 ARRAY_TO_SPAN(SMAA_NEIGHBORHOOD_BLENDING_VERT_SPV),
593 }; 593 };
594 constexpr std::array frag_shader_sources{ 594 static constexpr std::array frag_shader_sources{
595 ARRAY_TO_SPAN(SMAA_EDGE_DETECTION_FRAG_SPV), 595 ARRAY_TO_SPAN(SMAA_EDGE_DETECTION_FRAG_SPV),
596 ARRAY_TO_SPAN(SMAA_BLENDING_WEIGHT_CALCULATION_FRAG_SPV), 596 ARRAY_TO_SPAN(SMAA_BLENDING_WEIGHT_CALCULATION_FRAG_SPV),
597 ARRAY_TO_SPAN(SMAA_NEIGHBORHOOD_BLENDING_FRAG_SPV), 597 ARRAY_TO_SPAN(SMAA_NEIGHBORHOOD_BLENDING_FRAG_SPV),
@@ -675,8 +675,8 @@ void SMAA::UploadImages(Scheduler& scheduler) {
675 return; 675 return;
676 } 676 }
677 677
678 constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT}; 678 static constexpr VkExtent2D area_extent{AREATEX_WIDTH, AREATEX_HEIGHT};
679 constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT}; 679 static constexpr VkExtent2D search_extent{SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT};
680 680
681 UploadImage(m_device, m_allocator, scheduler, m_static_images[Area], area_extent, 681 UploadImage(m_device, m_allocator, scheduler, m_static_images[Area], area_extent,
682 VK_FORMAT_R8G8_UNORM, ARRAY_TO_SPAN(areaTexBytes)); 682 VK_FORMAT_R8G8_UNORM, ARRAY_TO_SPAN(areaTexBytes));
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index d39372ec4..9b85dfb5e 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1230,6 +1230,11 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
1230 }); 1230 });
1231} 1231}
1232 1232
1233void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
1234 std::span<const VideoCommon::ImageCopy> copies) {
1235 UNIMPLEMENTED_MSG("Copying images with different samples is not implemented in Vulkan.");
1236}
1237
1233u64 TextureCacheRuntime::GetDeviceLocalMemory() const { 1238u64 TextureCacheRuntime::GetDeviceLocalMemory() const {
1234 return device.GetDeviceLocalMemory(); 1239 return device.GetDeviceLocalMemory();
1235} 1240}
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 1f27a3589..0ce39616f 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -70,6 +70,8 @@ public:
70 70
71 void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); 71 void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
72 72
73 void CopyImageMSAA(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
74
73 bool ShouldReinterpret(Image& dst, Image& src); 75 bool ShouldReinterpret(Image& dst, Image& src);
74 76
75 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); 77 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
@@ -80,6 +82,11 @@ public:
80 return false; 82 return false;
81 } 83 }
82 84
85 bool CanUploadMSAA() const noexcept {
86 // TODO: Implement buffer to MSAA uploads
87 return false;
88 }
89
83 void AccelerateImageUpload(Image&, const StagingBufferRef&, 90 void AccelerateImageUpload(Image&, const StagingBufferRef&,
84 std::span<const VideoCommon::SwizzleParameters>); 91 std::span<const VideoCommon::SwizzleParameters>);
85 92
@@ -106,7 +113,7 @@ public:
106 std::optional<ASTCDecoderPass> astc_decoder_pass; 113 std::optional<ASTCDecoderPass> astc_decoder_pass;
107 const Settings::ResolutionScalingInfo& resolution; 114 const Settings::ResolutionScalingInfo& resolution;
108 115
109 constexpr static size_t indexing_slots = 8 * sizeof(size_t); 116 static constexpr size_t indexing_slots = 8 * sizeof(size_t);
110 std::array<vk::Buffer, indexing_slots> buffers{}; 117 std::array<vk::Buffer, indexing_slots> buffers{};
111 std::array<std::unique_ptr<MemoryCommit>, indexing_slots> buffer_commits{}; 118 std::array<std::unique_ptr<MemoryCommit>, indexing_slots> buffer_commits{};
112}; 119};
diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp
index c42594149..db04943eb 100644
--- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp
+++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp
@@ -48,7 +48,7 @@ void TurboMode::Run(std::stop_token stop_token) {
48 auto commit = m_allocator.Commit(buffer, MemoryUsage::DeviceLocal); 48 auto commit = m_allocator.Commit(buffer, MemoryUsage::DeviceLocal);
49 49
50 // Create the descriptor pool to contain our descriptor. 50 // Create the descriptor pool to contain our descriptor.
51 constexpr VkDescriptorPoolSize pool_size{ 51 static constexpr VkDescriptorPoolSize pool_size{
52 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 52 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
53 .descriptorCount = 1, 53 .descriptorCount = 1,
54 }; 54 };
@@ -63,7 +63,7 @@ void TurboMode::Run(std::stop_token stop_token) {
63 }); 63 });
64 64
65 // Create the descriptor set layout from the pool. 65 // Create the descriptor set layout from the pool.
66 constexpr VkDescriptorSetLayoutBinding layout_binding{ 66 static constexpr VkDescriptorSetLayoutBinding layout_binding{
67 .binding = 0, 67 .binding = 0,
68 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 68 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
69 .descriptorCount = 1, 69 .descriptorCount = 1,
diff --git a/src/video_core/texture_cache/formatter.cpp b/src/video_core/texture_cache/formatter.cpp
index 418890126..30f72361d 100644
--- a/src/video_core/texture_cache/formatter.cpp
+++ b/src/video_core/texture_cache/formatter.cpp
@@ -22,6 +22,9 @@ std::string Name(const ImageBase& image) {
22 const u32 num_layers = image.info.resources.layers; 22 const u32 num_layers = image.info.resources.layers;
23 const u32 num_levels = image.info.resources.levels; 23 const u32 num_levels = image.info.resources.levels;
24 std::string resource; 24 std::string resource;
25 if (image.info.num_samples > 1) {
26 resource += fmt::format(":{}xMSAA", image.info.num_samples);
27 }
25 if (num_layers > 1) { 28 if (num_layers > 1) {
26 resource += fmt::format(":L{}", num_layers); 29 resource += fmt::format(":L{}", num_layers);
27 } 30 }
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 1b01990a4..3e2cbb0b0 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -773,7 +773,7 @@ void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) {
773 image.flags &= ~ImageFlagBits::CpuModified; 773 image.flags &= ~ImageFlagBits::CpuModified;
774 TrackImage(image, image_id); 774 TrackImage(image, image_id);
775 775
776 if (image.info.num_samples > 1) { 776 if (image.info.num_samples > 1 && !runtime.CanUploadMSAA()) {
777 LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented"); 777 LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented");
778 return; 778 return;
779 } 779 }
@@ -1167,14 +1167,14 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
1167 if (True(overlap.flags & ImageFlagBits::GpuModified)) { 1167 if (True(overlap.flags & ImageFlagBits::GpuModified)) {
1168 new_image.flags |= ImageFlagBits::GpuModified; 1168 new_image.flags |= ImageFlagBits::GpuModified;
1169 } 1169 }
1170 const auto& resolution = Settings::values.resolution_info;
1171 const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value();
1172 const u32 up_scale = can_rescale ? resolution.up_scale : 1;
1173 const u32 down_shift = can_rescale ? resolution.down_shift : 0;
1174 auto copies = MakeShrinkImageCopies(new_info, overlap.info, base, up_scale, down_shift);
1170 if (overlap.info.num_samples != new_image.info.num_samples) { 1175 if (overlap.info.num_samples != new_image.info.num_samples) {
1171 LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented"); 1176 runtime.CopyImageMSAA(new_image, overlap, std::move(copies));
1172 } else { 1177 } else {
1173 const auto& resolution = Settings::values.resolution_info;
1174 const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value();
1175 const u32 up_scale = can_rescale ? resolution.up_scale : 1;
1176 const u32 down_shift = can_rescale ? resolution.down_shift : 0;
1177 auto copies = MakeShrinkImageCopies(new_info, overlap.info, base, up_scale, down_shift);
1178 runtime.CopyImage(new_image, overlap, std::move(copies)); 1178 runtime.CopyImage(new_image, overlap, std::move(copies));
1179 } 1179 }
1180 if (True(overlap.flags & ImageFlagBits::Tracked)) { 1180 if (True(overlap.flags & ImageFlagBits::Tracked)) {
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 03acc68d9..697f86641 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -573,10 +573,6 @@ u32 CalculateUnswizzledSizeBytes(const ImageInfo& info) noexcept {
573 if (info.type == ImageType::Buffer) { 573 if (info.type == ImageType::Buffer) {
574 return info.size.width * BytesPerBlock(info.format); 574 return info.size.width * BytesPerBlock(info.format);
575 } 575 }
576 if (info.num_samples > 1) {
577 // Multisample images can't be uploaded or downloaded to the host
578 return 0;
579 }
580 if (info.type == ImageType::Linear) { 576 if (info.type == ImageType::Linear) {
581 return info.pitch * Common::DivCeil(info.size.height, DefaultBlockHeight(info.format)); 577 return info.pitch * Common::DivCeil(info.size.height, DefaultBlockHeight(info.format));
582 } 578 }
@@ -703,7 +699,6 @@ ImageViewType RenderTargetImageViewType(const ImageInfo& info) noexcept {
703std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageInfo& src, 699std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageInfo& src,
704 SubresourceBase base, u32 up_scale, u32 down_shift) { 700 SubresourceBase base, u32 up_scale, u32 down_shift) {
705 ASSERT(dst.resources.levels >= src.resources.levels); 701 ASSERT(dst.resources.levels >= src.resources.levels);
706 ASSERT(dst.num_samples == src.num_samples);
707 702
708 const bool is_dst_3d = dst.type == ImageType::e3D; 703 const bool is_dst_3d = dst.type == ImageType::e3D;
709 if (is_dst_3d) { 704 if (is_dst_3d) {
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 59120cd09..95bcdd37b 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -29,7 +29,7 @@ constexpr u32 pdep(u32 value) {
29 29
30template <u32 mask, u32 incr_amount> 30template <u32 mask, u32 incr_amount>
31void incrpdep(u32& value) { 31void incrpdep(u32& value) {
32 constexpr u32 swizzled_incr = pdep<mask>(incr_amount); 32 static constexpr u32 swizzled_incr = pdep<mask>(incr_amount);
33 value = ((value | ~mask) + swizzled_incr) & mask; 33 value = ((value | ~mask) + swizzled_incr) & mask;
34} 34}
35 35
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index d65991734..17acd3933 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -67,7 +67,7 @@ void EmuThread::run() {
67 emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); 67 emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
68 if (Settings::values.use_disk_shader_cache.GetValue()) { 68 if (Settings::values.use_disk_shader_cache.GetValue()) {
69 m_system.Renderer().ReadRasterizer()->LoadDiskResources( 69 m_system.Renderer().ReadRasterizer()->LoadDiskResources(
70 m_system.GetCurrentProcessProgramID(), stop_token, 70 m_system.GetApplicationProcessProgramID(), stop_token,
71 [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { 71 [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
72 emit LoadProgress(stage, value, total); 72 emit LoadProgress(stage, value, total);
73 }); 73 });
@@ -401,12 +401,6 @@ qreal GRenderWindow::windowPixelRatio() const {
401 return devicePixelRatioF(); 401 return devicePixelRatioF();
402} 402}
403 403
404std::pair<u32, u32> GRenderWindow::ScaleTouch(const QPointF& pos) const {
405 const qreal pixel_ratio = windowPixelRatio();
406 return {static_cast<u32>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})),
407 static_cast<u32>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))};
408}
409
410void GRenderWindow::closeEvent(QCloseEvent* event) { 404void GRenderWindow::closeEvent(QCloseEvent* event) {
411 emit Closed(); 405 emit Closed();
412 QWidget::closeEvent(event); 406 QWidget::closeEvent(event);
@@ -649,10 +643,12 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
649 // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse 643 // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
650 // coordinates and map them to the current render area 644 // coordinates and map them to the current render area
651 const auto pos = mapFromGlobal(QCursor::pos()); 645 const auto pos = mapFromGlobal(QCursor::pos());
652 const auto [x, y] = ScaleTouch(pos); 646 const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
653 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
654 const auto button = QtButtonToMouseButton(event->button()); 647 const auto button = QtButtonToMouseButton(event->button());
655 input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, button); 648
649 input_subsystem->GetMouse()->PressMouseButton(button);
650 input_subsystem->GetMouse()->PressButton(pos.x(), pos.y(), button);
651 input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, button);
656 652
657 emit MouseActivity(); 653 emit MouseActivity();
658} 654}
@@ -665,11 +661,13 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
665 // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse 661 // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
666 // coordinates and map them to the current render area 662 // coordinates and map them to the current render area
667 const auto pos = mapFromGlobal(QCursor::pos()); 663 const auto pos = mapFromGlobal(QCursor::pos());
668 const auto [x, y] = ScaleTouch(pos); 664 const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
669 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
670 const int center_x = width() / 2; 665 const int center_x = width() / 2;
671 const int center_y = height() / 2; 666 const int center_y = height() / 2;
672 input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y); 667
668 input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
669 input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
670 input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
673 671
674 if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) { 672 if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
675 QCursor::setPos(mapToGlobal(QPoint{center_x, center_y})); 673 QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
@@ -697,8 +695,8 @@ void GRenderWindow::wheelEvent(QWheelEvent* event) {
697void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { 695void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
698 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); 696 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
699 for (const auto& touch_point : touch_points) { 697 for (const auto& touch_point : touch_points) {
700 const auto [x, y] = ScaleTouch(touch_point.pos()); 698 const auto pos = touch_point.pos();
701 const auto [touch_x, touch_y] = MapToTouchScreen(x, y); 699 const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
702 input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, touch_point.id()); 700 input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, touch_point.id());
703 } 701 }
704} 702}
@@ -707,8 +705,8 @@ void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) {
707 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); 705 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
708 input_subsystem->GetTouchScreen()->ClearActiveFlag(); 706 input_subsystem->GetTouchScreen()->ClearActiveFlag();
709 for (const auto& touch_point : touch_points) { 707 for (const auto& touch_point : touch_points) {
710 const auto [x, y] = ScaleTouch(touch_point.pos()); 708 const auto pos = touch_point.pos();
711 const auto [touch_x, touch_y] = MapToTouchScreen(x, y); 709 const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
712 input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, touch_point.id()); 710 input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, touch_point.id());
713 } 711 }
714 input_subsystem->GetTouchScreen()->ReleaseInactiveTouch(); 712 input_subsystem->GetTouchScreen()->ReleaseInactiveTouch();
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 092c6206f..627e19f42 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -184,8 +184,6 @@ public:
184 184
185 void CaptureScreenshot(const QString& screenshot_path); 185 void CaptureScreenshot(const QString& screenshot_path);
186 186
187 std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
188
189 /** 187 /**
190 * Instructs the window to re-launch the application using the specified program_index. 188 * Instructs the window to re-launch the application using the specified program_index.
191 * @param program_index Specifies the index within the application of the program to launch. 189 * @param program_index Specifies the index within the application of the program to launch.
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 35fef506a..db68ed259 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -441,6 +441,7 @@ void Config::ReadControlValues() {
441 Settings::values.mouse_panning = false; 441 Settings::values.mouse_panning = false;
442 ReadBasicSetting(Settings::values.mouse_panning_sensitivity); 442 ReadBasicSetting(Settings::values.mouse_panning_sensitivity);
443 ReadBasicSetting(Settings::values.enable_joycon_driver); 443 ReadBasicSetting(Settings::values.enable_joycon_driver);
444 ReadBasicSetting(Settings::values.enable_procon_driver);
444 445
445 ReadBasicSetting(Settings::values.tas_enable); 446 ReadBasicSetting(Settings::values.tas_enable);
446 ReadBasicSetting(Settings::values.tas_loop); 447 ReadBasicSetting(Settings::values.tas_loop);
@@ -1102,6 +1103,7 @@ void Config::SaveValues() {
1102 SaveRendererValues(); 1103 SaveRendererValues();
1103 SaveAudioValues(); 1104 SaveAudioValues();
1104 SaveSystemValues(); 1105 SaveSystemValues();
1106 qt_config->sync();
1105} 1107}
1106 1108
1107void Config::SaveAudioValues() { 1109void Config::SaveAudioValues() {
@@ -1141,6 +1143,7 @@ void Config::SaveControlValues() {
1141 WriteGlobalSetting(Settings::values.motion_enabled); 1143 WriteGlobalSetting(Settings::values.motion_enabled);
1142 WriteBasicSetting(Settings::values.enable_raw_input); 1144 WriteBasicSetting(Settings::values.enable_raw_input);
1143 WriteBasicSetting(Settings::values.enable_joycon_driver); 1145 WriteBasicSetting(Settings::values.enable_joycon_driver);
1146 WriteBasicSetting(Settings::values.enable_procon_driver);
1144 WriteBasicSetting(Settings::values.keyboard_enabled); 1147 WriteBasicSetting(Settings::values.keyboard_enabled);
1145 WriteBasicSetting(Settings::values.emulate_analog_keyboard); 1148 WriteBasicSetting(Settings::values.emulate_analog_keyboard);
1146 WriteBasicSetting(Settings::values.mouse_panning_sensitivity); 1149 WriteBasicSetting(Settings::values.mouse_panning_sensitivity);
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 77b976e74..8d81322f3 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -139,6 +139,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() {
139 Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked(); 139 Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked();
140 Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); 140 Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked();
141 Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked(); 141 Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked();
142 Settings::values.enable_procon_driver = ui->enable_procon_driver->isChecked();
142} 143}
143 144
144void ConfigureInputAdvanced::LoadConfiguration() { 145void ConfigureInputAdvanced::LoadConfiguration() {
@@ -174,6 +175,7 @@ void ConfigureInputAdvanced::LoadConfiguration() {
174 ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue()); 175 ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue());
175 ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); 176 ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue());
176 ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue()); 177 ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue());
178 ui->enable_procon_driver->setChecked(Settings::values.enable_procon_driver.GetValue());
177 179
178 UpdateUIEnabled(); 180 UpdateUIEnabled();
179} 181}
diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui
index 75d96d3ab..0eb2b34bc 100644
--- a/src/yuzu/configuration/configure_input_advanced.ui
+++ b/src/yuzu/configuration/configure_input_advanced.ui
@@ -2712,6 +2712,22 @@
2712 </widget> 2712 </widget>
2713 </item> 2713 </item>
2714 <item row="6" column="0"> 2714 <item row="6" column="0">
2715 <widget class="QCheckBox" name="enable_procon_driver">
2716 <property name="toolTip">
2717 <string>Requires restarting yuzu</string>
2718 </property>
2719 <property name="minimumSize">
2720 <size>
2721 <width>0</width>
2722 <height>23</height>
2723 </size>
2724 </property>
2725 <property name="text">
2726 <string>Enable direct Pro Controller driver [EXPERIMENTAL]</string>
2727 </property>
2728 </widget>
2729 </item>
2730 <item row="7" column="0">
2715 <widget class="QCheckBox" name="mouse_panning"> 2731 <widget class="QCheckBox" name="mouse_panning">
2716 <property name="minimumSize"> 2732 <property name="minimumSize">
2717 <size> 2733 <size>
@@ -2724,7 +2740,7 @@
2724 </property> 2740 </property>
2725 </widget> 2741 </widget>
2726 </item> 2742 </item>
2727 <item row="6" column="2"> 2743 <item row="7" column="2">
2728 <widget class="QSpinBox" name="mouse_panning_sensitivity"> 2744 <widget class="QSpinBox" name="mouse_panning_sensitivity">
2729 <property name="toolTip"> 2745 <property name="toolTip">
2730 <string>Mouse sensitivity</string> 2746 <string>Mouse sensitivity</string>
@@ -2746,14 +2762,14 @@
2746 </property> 2762 </property>
2747 </widget> 2763 </widget>
2748 </item> 2764 </item>
2749 <item row="7" column="0"> 2765 <item row="8" column="0">
2750 <widget class="QLabel" name="motion_touch"> 2766 <widget class="QLabel" name="motion_touch">
2751 <property name="text"> 2767 <property name="text">
2752 <string>Motion / Touch</string> 2768 <string>Motion / Touch</string>
2753 </property> 2769 </property>
2754 </widget> 2770 </widget>
2755 </item> 2771 </item>
2756 <item row="7" column="2"> 2772 <item row="8" column="2">
2757 <widget class="QPushButton" name="buttonMotionTouch"> 2773 <widget class="QPushButton" name="buttonMotionTouch">
2758 <property name="text"> 2774 <property name="text">
2759 <string>Configure</string> 2775 <string>Configure</string>
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 723690e71..50b62293e 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -1490,7 +1490,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
1490 } 1490 }
1491 1491
1492 const auto button = GRenderWindow::QtButtonToMouseButton(event->button()); 1492 const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
1493 input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button); 1493 input_subsystem->GetMouse()->PressButton(0, 0, button);
1494} 1494}
1495 1495
1496void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) { 1496void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) {
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp
index 1275f10c8..71afbc423 100644
--- a/src/yuzu/configuration/configure_ringcon.cpp
+++ b/src/yuzu/configuration/configure_ringcon.cpp
@@ -371,7 +371,7 @@ void ConfigureRingController::mousePressEvent(QMouseEvent* event) {
371 } 371 }
372 372
373 const auto button = GRenderWindow::QtButtonToMouseButton(event->button()); 373 const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
374 input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button); 374 input_subsystem->GetMouse()->PressButton(0, 0, button);
375} 375}
376 376
377void ConfigureRingController::keyPressEvent(QKeyEvent* event) { 377void ConfigureRingController::keyPressEvent(QKeyEvent* event) {
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 22aa19c56..c21828b1d 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -870,6 +870,7 @@ void GameList::ToggleFavorite(u64 program_id) {
870 tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true); 870 tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true);
871 } 871 }
872 } 872 }
873 SaveConfig();
873} 874}
874 875
875void GameList::AddFavorite(u64 program_id) { 876void GameList::AddFavorite(u64 program_id) {
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index f7ff93ed9..64e5af4c1 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -122,6 +122,7 @@ signals:
122 void AddDirectory(); 122 void AddDirectory();
123 void ShowList(bool show); 123 void ShowList(bool show);
124 void PopulatingCompleted(); 124 void PopulatingCompleted();
125 void SaveConfig();
125 126
126private slots: 127private slots:
127 void OnItemExpanded(const QModelIndex& item); 128 void OnItemExpanded(const QModelIndex& item);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f28268e9b..f233b065e 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -219,7 +219,7 @@ static void LogRuntimes() {
219#ifdef _MSC_VER 219#ifdef _MSC_VER
220 // It is possible that the name of the dll will change. 220 // It is possible that the name of the dll will change.
221 // vcruntime140.dll is for 2015 and onwards 221 // vcruntime140.dll is for 2015 and onwards
222 constexpr char runtime_dll_name[] = "vcruntime140.dll"; 222 static constexpr char runtime_dll_name[] = "vcruntime140.dll";
223 UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr); 223 UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr);
224 bool runtime_version_inspection_worked = false; 224 bool runtime_version_inspection_worked = false;
225 if (sz > 0) { 225 if (sz > 0) {
@@ -805,6 +805,8 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
805 layout.screen.GetHeight() / scale_ratio); 805 layout.screen.GetHeight() / scale_ratio);
806 web_browser_view.move(layout.screen.left / scale_ratio, 806 web_browser_view.move(layout.screen.left / scale_ratio,
807 (layout.screen.top / scale_ratio) + menuBar()->height()); 807 (layout.screen.top / scale_ratio) + menuBar()->height());
808 web_browser_view.setZoomFactor(static_cast<qreal>(layout.screen.GetWidth() / scale_ratio) /
809 static_cast<qreal>(Layout::ScreenUndocked::Width));
808 810
809 web_browser_view.setFocus(); 811 web_browser_view.setFocus();
810 web_browser_view.show(); 812 web_browser_view.show();
@@ -1163,6 +1165,14 @@ void GMainWindow::InitializeHotkeys() {
1163 Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue()); 1165 Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
1164 }); 1166 });
1165 connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] { 1167 connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
1168 if (Settings::values.mouse_enabled) {
1169 Settings::values.mouse_panning = false;
1170 QMessageBox::warning(
1171 this, tr("Emulated mouse is enabled"),
1172 tr("Real mouse input and mouse panning are incompatible. Please disable the "
1173 "emulated mouse in input advanced settings to allow mouse panning."));
1174 return;
1175 }
1166 Settings::values.mouse_panning = !Settings::values.mouse_panning; 1176 Settings::values.mouse_panning = !Settings::values.mouse_panning;
1167 if (Settings::values.mouse_panning) { 1177 if (Settings::values.mouse_panning) {
1168 render_window->installEventFilter(render_window); 1178 render_window->installEventFilter(render_window);
@@ -1269,6 +1279,7 @@ void GMainWindow::ConnectWidgetEvents() {
1269 connect(game_list, &GameList::ShowList, this, &GMainWindow::OnGameListShowList); 1279 connect(game_list, &GameList::ShowList, this, &GMainWindow::OnGameListShowList);
1270 connect(game_list, &GameList::PopulatingCompleted, 1280 connect(game_list, &GameList::PopulatingCompleted,
1271 [this] { multiplayer_state->UpdateGameList(game_list->GetModel()); }); 1281 [this] { multiplayer_state->UpdateGameList(game_list->GetModel()); });
1282 connect(game_list, &GameList::SaveConfig, this, &GMainWindow::OnSaveConfig);
1272 1283
1273 connect(game_list, &GameList::OpenPerGameGeneralRequested, this, 1284 connect(game_list, &GameList::OpenPerGameGeneralRequested, this,
1274 &GMainWindow::OnGameListOpenPerGameProperties); 1285 &GMainWindow::OnGameListOpenPerGameProperties);
@@ -1777,7 +1788,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1777 std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())} 1788 std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}
1778 .filename()); 1789 .filename());
1779 } 1790 }
1780 const bool is_64bit = system->Kernel().CurrentProcess()->Is64BitProcess(); 1791 const bool is_64bit = system->Kernel().ApplicationProcess()->Is64BitProcess();
1781 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)"); 1792 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
1782 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit") 1793 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit")
1783 .arg(QString::fromStdString(title_name), instruction_set_suffix) 1794 .arg(QString::fromStdString(title_name), instruction_set_suffix)
@@ -2652,6 +2663,8 @@ void GMainWindow::OnGameListAddDirectory() {
2652 } else { 2663 } else {
2653 LOG_WARNING(Frontend, "Selected directory is already in the game list"); 2664 LOG_WARNING(Frontend, "Selected directory is already in the game list");
2654 } 2665 }
2666
2667 OnSaveConfig();
2655} 2668}
2656 2669
2657void GMainWindow::OnGameListShowList(bool show) { 2670void GMainWindow::OnGameListShowList(bool show) {
@@ -3013,8 +3026,10 @@ void GMainWindow::OnRestartGame() {
3013 if (!system->IsPoweredOn()) { 3026 if (!system->IsPoweredOn()) {
3014 return; 3027 return;
3015 } 3028 }
3016 // Make a copy since BootGame edits game_path 3029 // Make a copy since ShutdownGame edits game_path
3017 BootGame(QString(current_game_path)); 3030 const auto current_game = QString(current_game_path);
3031 ShutdownGame();
3032 BootGame(current_game);
3018} 3033}
3019 3034
3020void GMainWindow::OnPauseGame() { 3035void GMainWindow::OnPauseGame() {
@@ -3378,6 +3393,7 @@ void GMainWindow::OnConfigureTas() {
3378 return; 3393 return;
3379 } else if (result == QDialog::Accepted) { 3394 } else if (result == QDialog::Accepted) {
3380 dialog.ApplyConfiguration(); 3395 dialog.ApplyConfiguration();
3396 OnSaveConfig();
3381 } 3397 }
3382} 3398}
3383 3399
@@ -3530,7 +3546,7 @@ void GMainWindow::OnToggleGraphicsAPI() {
3530} 3546}
3531 3547
3532void GMainWindow::OnConfigurePerGame() { 3548void GMainWindow::OnConfigurePerGame() {
3533 const u64 title_id = system->GetCurrentProcessProgramID(); 3549 const u64 title_id = system->GetApplicationProcessProgramID();
3534 OpenPerGameConfiguration(title_id, current_game_path.toStdString()); 3550 OpenPerGameConfiguration(title_id, current_game_path.toStdString());
3535} 3551}
3536 3552
@@ -3689,7 +3705,7 @@ void GMainWindow::OnCaptureScreenshot() {
3689 return; 3705 return;
3690 } 3706 }
3691 3707
3692 const u64 title_id = system->GetCurrentProcessProgramID(); 3708 const u64 title_id = system->GetApplicationProcessProgramID();
3693 const auto screenshot_path = 3709 const auto screenshot_path =
3694 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir)); 3710 QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir));
3695 const auto date = 3711 const auto date =
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 9c34cdc6e..3b6dce296 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -178,6 +178,7 @@ void Config::ReadValues() {
178 178
179 ReadSetting("ControlsGeneral", Settings::values.enable_raw_input); 179 ReadSetting("ControlsGeneral", Settings::values.enable_raw_input);
180 ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver); 180 ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver);
181 ReadSetting("ControlsGeneral", Settings::values.enable_procon_driver);
181 ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard); 182 ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard);
182 ReadSetting("ControlsGeneral", Settings::values.vibration_enabled); 183 ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
183 ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations); 184 ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 5450b8c38..5153cdb79 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -62,7 +62,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
62 const auto mouse_button = SDLButtonToMouseButton(button); 62 const auto mouse_button = SDLButtonToMouseButton(button);
63 if (state == SDL_PRESSED) { 63 if (state == SDL_PRESSED) {
64 const auto [touch_x, touch_y] = MouseToTouchPos(x, y); 64 const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
65 input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, mouse_button); 65 input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
66 input_subsystem->GetMouse()->PressMouseButton(mouse_button);
67 input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, mouse_button);
66 } else { 68 } else {
67 input_subsystem->GetMouse()->ReleaseButton(mouse_button); 69 input_subsystem->GetMouse()->ReleaseButton(mouse_button);
68 } 70 }
@@ -70,7 +72,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
70 72
71void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { 73void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
72 const auto [touch_x, touch_y] = MouseToTouchPos(x, y); 74 const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
73 input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, 0, 0); 75 input_subsystem->GetMouse()->Move(x, y, 0, 0);
76 input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
77 input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
74} 78}
75 79
76void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) { 80void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index d1f7b1d49..77edd58ca 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -405,7 +405,7 @@ int main(int argc, char** argv) {
405 405
406 if (Settings::values.use_disk_shader_cache.GetValue()) { 406 if (Settings::values.use_disk_shader_cache.GetValue()) {
407 system.Renderer().ReadRasterizer()->LoadDiskResources( 407 system.Renderer().ReadRasterizer()->LoadDiskResources(
408 system.GetCurrentProcessProgramID(), std::stop_token{}, 408 system.GetApplicationProcessProgramID(), std::stop_token{},
409 [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); 409 [](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
410 } 410 }
411 411