Compare commits

..

165 commits

Author SHA1 Message Date
The yuzu Community 6efd335eda Update translations (2023-03-01) 2023-03-01 02:49:50 +00:00
liamwhite 1346b14bef
Merge pull request #9877 from abouvier/cmake-boost
cmake: use correct boost imported targets
2023-02-28 18:40:44 -05:00
liamwhite 304d6e9870
Merge pull request #9862 from abouvier/cmake-components
cmake: support components in find modules
2023-02-28 16:36:28 -05:00
Alexandre Bouvier 57fd8b1f45 cmake: use correct boost imported targets 2023-02-28 17:56:01 +01:00
Alexandre Bouvier 7b8a5413ad cmake: support components in find modules 2023-02-28 17:46:20 +01:00
liamwhite b44527a259
Merge pull request #9851 from abouvier/openssl-vcpkg
externals: use openssl from vcpkg
2023-02-28 11:39:32 -05:00
Alexandre Bouvier 0245c5dc49 externals: use openssl from vcpkg 2023-02-28 06:39:54 +01:00
liamwhite a78a475815
Merge pull request #9844 from abouvier/jwt-fix
cmake: fix cpp-jwt build
2023-02-27 19:46:19 -05:00
liamwhite 22432668be
Merge pull request #9859 from liamwhite/tmem-use
service: avoid direct pointer access of transfer memory objects
2023-02-27 19:46:10 -05:00
liamwhite 50575c317e
Merge pull request #9874 from german77/violet
service: btm: Fix handle functions
2023-02-27 19:46:01 -05:00
Matías Locatti 5f2cbf53d7
Merge pull request #9872 from goldenx86/partialLTO
Partial LTO
2023-02-27 19:38:36 -03:00
Matías Locatti c38bb96a2c Partially apply LTO to only core and video_core projects. 2023-02-27 18:44:14 -03:00
Narr the Reg 71ca956d5c service: btm: Fix handle functions 2023-02-27 12:40:47 -06:00
bunnei 2b4ba90329
Merge pull request #9871 from yuzu-emu/revert-9824-burning-profiles
Revert "yuzu: config: Remove player 8 and 9 from config file"
2023-02-26 22:18:25 -08:00
Narr the Reg ff11fdb07e
Revert "yuzu: config: Remove player 8 and 9 from config file" 2023-02-26 14:39:13 -06:00
liamwhite 26c1edf2f0
Merge pull request #9849 from ameerj/async-astc
texture_cache: Add asynchronous ASTC texture decoding
2023-02-26 09:20:12 -05:00
liamwhite c50a930bbb
Merge pull request #9824 from german77/burning-profiles
yuzu: config: Remove player 8 and 9 from config file
2023-02-26 09:20:02 -05:00
Narr the Reg 60688bf0d5 yuzu: config: Remove player 8 and 9 from config file 2023-02-25 22:20:32 -06:00
liamwhite 833afb7ce3
Merge pull request #9848 from german77/metroid_motion
input_common: Implement dedicated motion from mouse
2023-02-25 12:44:13 -05:00
liamwhite 290ec3eb2f
Merge pull request #9857 from german77/fwupdate
core: Update service function tables to 16.0.0+
2023-02-25 12:44:06 -05:00
liamwhite d5bfc36e90
Merge pull request #9861 from german77/bustype
core: hidbus: Fix BusType size
2023-02-25 12:44:00 -05:00
liamwhite 5eeadde3c8
Merge pull request #9863 from german77/max-clock
config: Fix per game Force max clock
2023-02-25 12:43:53 -05:00
german77 cfd69e2e58 config: Fix per game Force max clock 2023-02-25 10:12:07 -06:00
Narr the Reg 5e4ea04a64 core: hidbus: Fix BusType size 2023-02-24 21:22:27 -06:00
Narr the Reg 39ca7b2928 core: Update service function tables to 16.0.0+ 2023-02-24 18:17:36 -06:00
Liam 975186ad4d am: avoid direct pointer access of transfer memory objects 2023-02-24 12:50:54 -05:00
Liam de4e5db330 hid: avoid direct pointer access of transfer memory objects 2023-02-24 12:48:07 -05:00
liamwhite ca8a804a3c
Merge pull request #9842 from german77/proper_real_mouse
core: hid: Fix native mouse mapping
2023-02-22 22:08:35 -05:00
ameerj b5bcd8c71b configuration: Add async ASTC decode setting 2023-02-22 18:21:09 -05:00
ameerj 090bc588e5 texture_cache: Add async texture decoding 2023-02-22 00:26:07 -05:00
Narr the Reg 739a81055f core: hid: Restore motion state on refresh and clamp motion values 2023-02-21 21:55:23 -06:00
Narr the Reg 673accd630 input_common: Implement dedicated motion from mouse 2023-02-21 21:55:22 -06:00
Narr the Reg db2785082b settings: Add more input settings to the log 2023-02-21 19:48:38 -06:00
Narr the Reg 9477181d09 core: hid: Fix native mouse mappings 2023-02-21 19:48:38 -06:00
liamwhite 8f3e2a1b48
Merge pull request #9847 from german77/timeout
yuzu: Set a lower timeout for discord presence
2023-02-21 20:39:19 -05:00
Narr the Reg d482ec32a4 yuzu: Set a lower timeout for discord presence 2023-02-21 18:23:58 -06:00
Alexandre Bouvier 2bf9602e83 cmake: fix cpp-jwt build 2023-02-22 01:13:35 +01:00
liamwhite 11f6bb1532
Merge pull request #9846 from merryhime/type-const
svc: Fix type consistency (exposed on macOS)
2023-02-21 18:58:04 -05:00
liamwhite ba05301e1b
Merge pull request #9841 from abouvier/httplib-update
externals: Update cpp-httplib to latest
2023-02-21 18:57:55 -05:00
liamwhite 5a657488e1
Merge pull request #9843 from MonsterDruide1/network-connreset
net: translate ECONNRESET network error
2023-02-21 18:57:37 -05:00
Merry c9678bda24 svc: Fix type consistency (exposed on macOS) 2023-02-21 21:39:17 +00:00
Alexandre Bouvier 83afc12475 externals: Update cpp-httplib to latest 2023-02-21 20:55:37 +01:00
MonsterDruide1 d746cfc018 net: translate ECONNRESET network error 2023-02-21 20:47:59 +01:00
liamwhite 89221ca7d5
Merge pull request #9834 from german77/reverted
Qt: Reintroduce scaling for touch input
2023-02-20 09:05:49 -05:00
german77 165ebbb63c Qt: Reintroduce scaling for touch input 2023-02-19 17:52:44 -06:00
liamwhite 898c5d35a5
Merge pull request #9771 from ameerj/host-thread-id
kernel: Refactor thread_local variable usage
2023-02-19 13:12:43 -05:00
liamwhite a4d0663158
Merge pull request #9588 from liamwhite/bylaws-reverts
Revert "shader_recompiler: Align SSBO offsets to meet host requirements"
2023-02-19 13:11:57 -05:00
liamwhite e531d1fae9
Merge pull request #9815 from german77/qt-mouse
Qt: Fix mouse scalling
2023-02-18 16:25:48 -05:00
Morph 41183b622f
Merge pull request #9825 from liamwhite/object-name
kernel: add KObjectName
2023-02-18 16:22:50 -05:00
bunnei e91ff9b7bd
Merge pull request #9810 from Kelebek1/nvdec_threads
Allow >1 cpu threads on video decoding, disable multi-frame decoding
2023-02-17 09:44:38 -08:00
Liam 1773a1039f kernel: add KObjectName 2023-02-17 09:16:05 -05:00
Mai 61b1772e51
Merge pull request #9817 from german77/save
yuzu: Write to config file on important config changes
2023-02-16 22:58:29 -05:00
Narr the Reg 0a88c7dbbe yuzu: Shutdown game on restart to reload per game config 2023-02-16 21:17:30 -06:00
Narr the Reg df9c8bdfd9 yuzu: Write to config file on important config changes 2023-02-16 21:17:01 -06:00
bunnei 889bfce447
Merge pull request #9802 from Kelebek1/wait_data_cache
Re-add the invalidate_texture_data_cache register
2023-02-16 12:27:24 -08:00
bunnei 744434de38
Merge pull request #9769 from Kelebek1/audio_oob
[audio_core] Fix depop prepare
2023-02-16 12:26:23 -08:00
Narr the Reg 17207939e5 input_common: Split mouse input into individual devices 2023-02-16 14:22:13 -06:00
german77 57aaf00a0c Qt: Fix mouse scalling 2023-02-15 20:57:45 -06:00
liamwhite 6d77de96da
Merge pull request #9796 from liamwhite/current
general: rename CurrentProcess to ApplicationProcess
2023-02-15 17:42:45 -05:00
liamwhite 04d2d2ef5f
Merge pull request #9782 from arades79/fix-consexpr-value-declaration-usage
Fix consexpr value declaration usage
2023-02-15 17:42:38 -05:00
bunnei 0eb40117af
Merge pull request #9809 from liamwhite/unused-service
service: remove deleted services
2023-02-15 12:33:59 -08:00
bunnei 3599ef2077
Merge pull request #9811 from yuzu-emu/revert-9793-borderless-hidpi
Revert "main: Fix borderless fullscreen for high dpi scaled displays"
2023-02-14 18:27:21 -08:00
arades79 98631b45b6
remove constexpr from virtual function
Signed-off-by: arades79 <scravers@protonmail.com>
2023-02-14 19:14:29 -05:00
liamwhite 58a2c19982
Revert "main: Fix borderless fullscreen for high dpi scaled displays" 2023-02-14 16:29:35 -05:00
Kelebek1 3b50906f00 Reimplement the invalidate_texture_data_cache register 2023-02-14 19:34:10 +00:00
Kelebek1 139b645aa2 Allow >1 cpu threads on video decoding, disable multi-frame decoding 2023-02-14 18:55:46 +00:00
Liam 79fbdfca17 service: remove deleted services 2023-02-14 12:38:21 -05:00
arades79 880b6e9795 use a string view to skip allocation
Signed-off-by: arades79 <scravers@protonmail.com>
2023-02-14 12:35:40 -05:00
arades79 683019878f remove static from pointer sized or smaller types for aesthetics, change constexpr static to static constexpr for consistency
Signed-off-by: arades79 <scravers@protonmail.com>
2023-02-14 12:35:39 -05:00
arades79 26e44a3be4 apply clang-format
Signed-off-by: arades79 <scravers@protonmail.com>
2023-02-14 12:35:39 -05:00
arades79 392a029ef4 don't use static inside constexpr function
Signed-off-by: arades79 <scravers@protonmail.com>
2023-02-14 12:33:11 -05:00
arades79 45e13b03f3 add static lifetime to constexpr values to force compile time evaluation where possible
Signed-off-by: arades79 <scravers@protonmail.com>
2023-02-14 12:33:11 -05:00
liamwhite 5f5a6e4b2e
Merge pull request #9795 from Kelebek1/biquad_fix
[audio_core] Use different state offset for each biquad filter channel
2023-02-14 09:11:26 -05:00
liamwhite d87db919f9
Merge pull request #9793 from Morph1984/borderless-hidpi
main: Fix borderless fullscreen for high dpi scaled displays
2023-02-14 09:11:15 -05:00
Liam ceda2d280e general: rename CurrentProcess to ApplicationProcess 2023-02-13 19:03:12 -05:00
Kelebek1 3a90ed99be Fix biquad filter command's state buffer offset 2023-02-13 16:21:29 +00:00
Liam 4363ca304a kernel: use GetCurrentProcess 2023-02-13 11:05:14 -05:00
bunnei 770a49616d
Merge pull request #9784 from m-HD/master
settings: added missing graphical settings to RestoreGlobalState()
2023-02-12 21:49:45 -08:00
Morph d6677b50f6 main: Fix borderless fullscreen for high dpi scaled displays
On Windows, a borderless window will be treated the same as exclusive fullscreen
when the window geometry matches the physical dimensions of the screen.
However, with High DPI scaling, when the devicePixelRatioF() is > 1, the borderless
window apparently is not treated as exclusive fullscreen and functions correctly.
One can verify and replicate this behavior by using a high resolution (4K) display,
and switching between 100% and 200% scaling in Windows' display settings.
At 100%, without the addition of 1, it is treated as exclusive fullscreen.
At 200%, with or without the addition of 1, it is treated as borderless windowed.
Therefore, we can use (read: abuse) this difference in behavior to fix this issue for
those with higher resolution displays when the Qt scaling ratio is > 1.
Should this behavior be changed in the future, please revisit this workaround.
2023-02-12 21:58:49 -05:00
bunnei 8b74047b1b
Merge pull request #9757 from german77/gyro
core: hid: Use gyro thresholds modes set by the game
2023-02-12 00:19:22 -08:00
bunnei f70fcdb873
Merge pull request #9746 from ameerj/ogl-msaa-texcache
texture_cache: OpenGL: Implement MSAA uploads and copies
2023-02-12 00:18:52 -08:00
m-HD 9df92bad2a
Update settings.cpp
added missing graphical settings to RestoreGlobalState()
2023-02-12 02:58:39 +01:00
liamwhite fbba6e10bc
Merge pull request #9781 from ColinKinloch/info_id_typo
kernel/svc: Fix undefined info_id
2023-02-11 20:13:54 -05:00
ameerj 93cf2b3ca8 texture_cache: OpenGL: Implement MSAA uploads and copies 2023-02-11 15:43:07 -05:00
Colin Kinloch 868ab0d3b4 kernel/svc: Fix undefined info_id 2023-02-11 18:00:34 +00:00
liamwhite c97b5c9ff9
Merge pull request #9777 from vonchenplus/speed_up_video_copy
video_core: Speed up video frame data copy
2023-02-11 12:35:16 -05:00
Kelebek1 2e02ed8bb5 Add fallback for memory read/write in case the address goes over a 4K page 2023-02-11 16:27:43 +00:00
liamwhite 709879cfc1
Merge pull request #9773 from bunnei/fix-process-resource
core: kernel: k_process: Use application system resource.
2023-02-11 10:28:50 -05:00
liamwhite 89c09d639a
Merge pull request #9768 from merryhime/biquad-rounding
biquad_filter: Fix rounding in ApplyBiquadFilterInt
2023-02-11 10:28:42 -05:00
liamwhite 1040f1f503
Merge pull request #9744 from behunin/quick-release
gpu_thread: Remove OnCommandListEndCommand
2023-02-11 10:28:30 -05:00
FengChen 4adf39edf2 video_core: Speed up video frame data copy 2023-02-11 22:18:54 +08:00
Kelebek1 19e1ea6a02 Fix depop prepare receiving bad mix infos and writing out of bounds, and update aux a bit, may help 2023-02-11 10:21:25 +00:00
bunnei abd826ba87
Merge pull request #9742 from liamwhite/svc-wrap-only
kernel/svc: switch to generated wrappers
2023-02-10 21:41:22 -08:00
bunnei 023ac943aa
Merge pull request #9759 from german77/pro_controller
input_common: Reintroduce custom pro controller support
2023-02-10 21:14:40 -08:00
bunnei e79270507b core: kernel: k_process: Use application system resource. 2023-02-10 21:03:39 -08:00
ameerj 5e746da981 kernel: Refactor thread_local variable usage
On MSVC at least, there seems to be a non-trivial overhead to calling GetHostThreadId().

This slightly reworks the host_thread_id variable to reduce some of the complexity around its usage, along with some small refactors around current_thread and dummy thread
2023-02-10 20:43:06 -05:00
Merry 3c60bc36a1 biquad_filter: Clamp f64 in ApplyBiquadFilterFloat 2023-02-10 20:43:34 +00:00
Merry 9bdcb1070f biquad_filter: Fix rounding in ApplyBiquadFilterInt 2023-02-10 20:34:52 +00:00
liamwhite b3a8c0dc49
Merge pull request #9761 from Morph1984/oops
main: Re-add QtWebEngine zoom factor
2023-02-10 10:54:10 -05:00
bunnei 84743fd6ce
Merge pull request #9765 from liamwhite/ffs-apple
kernel: avoid usage of bit_cast
2023-02-10 07:53:40 -08:00
Liam 36b70dec05 kernel: avoid usage of bit_cast 2023-02-10 09:13:58 -05:00
Morph 3fbb93e5c9 main: Re-add QtWebEngine zoom factor
For some reason, I had removed this in ad6cec71ec

This should fix any improperly scaled web applets.
2023-02-09 22:57:37 -05:00
liamwhite c5743d5499
Merge pull request #9736 from Kelebek1/dynamic_vertex_attribs
Remove fake vertex bindings when dynamic state is enabled
2023-02-09 22:14:55 -05:00
liamwhite cbb289fbee
Merge pull request #9750 from ameerj/glsl-sample-id-mask
glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
2023-02-09 22:14:47 -05:00
liamwhite c0b36c2d26
Merge pull request #9758 from german77/multi_audio
audio: cubeb: Fix yuzu crashing when it test for latency
2023-02-09 22:14:33 -05:00
Narr the Reg acba9a6b76 input_common: Reintroduce custom pro controller support 2023-02-09 20:08:54 -06:00
Narr the Reg 7c0dcea96c audio: cubeb: Fix yuzu crashing when it test for latency 2023-02-09 19:38:03 -06:00
Narr the Reg 5e9fa5def5 core: hid: Use gyro thresholds modes set by the game 2023-02-09 19:07:50 -06:00
Matías Locatti 7bad3a7e5e
Merge pull request #9749 from ameerj/pr9559-partial-revert
buffer_base: Partially revert changes from #9559
2023-02-09 17:53:45 -03:00
ameerj eb9f16dce4 buffer_base: Partially revert changes from #9559
This fixes a regression where Yoshi's Crafted World (and potentially other titles) would enter an infinite loop when GPU Accuracy was set to "Normal"
2023-02-08 19:37:23 -05:00
ameerj 04139cb3ed glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
These built-ins seem to be available without needing to be declared for fragment shaders, similar i.e. to gl_FragDepth
2023-02-08 19:34:39 -05:00
liamwhite f6477b91f9
Merge pull request #9747 from german77/SetSupportedNpadIdTypes
service: hid: Return error if arguments of SetSupportedNpadIdType is invalid
2023-02-08 10:09:26 -05:00
Narr the Reg c27006e99d service: hid: Return error if arguments of SetSupportedNpadIdType is invalid 2023-02-07 21:11:39 -06:00
Mai f3b532d091
Merge pull request #9739 from liamwhite/old-gcc-fix
kernel: fix compilation with older gcc
2023-02-07 22:10:35 -05:00
Behunin 8551ac6008 Remove OnCommandListEndCommand
Call rasterizer->ReleaseFences() directly
2023-02-07 17:21:17 -07:00
Liam 2415d37ea2 kernel/svc: switch to generated wrappers 2023-02-06 23:57:44 -05:00
liamwhite 1f3e8d633a
Merge pull request #4949 from Morph1984/hidpi-temp-fix
main: Enable High DPI fixes for Qt >= 5.14
2023-02-06 23:20:49 -05:00
bunnei ecbf74b87a
Merge pull request #9644 from SaiKai/volume_quicksetting
add volume quicksetting with volume slider
2023-02-06 17:10:44 -08:00
bunnei 01cb49973a
Merge pull request #9735 from merryhime/dynarmic-6.4.5
dynarmic: Update to 6.4.5
2023-02-06 17:09:17 -08:00
Liam 82c2a3da9f kernel: fix compilation with older gcc 2023-02-06 13:14:27 -05:00
liamwhite 72f78a48e3
Merge pull request #9737 from goldenx86/yuzu_cmd
Update yuzu_cmd's default_ini.h
2023-02-06 09:08:27 -05:00
Matías Locatti 69eaad18a5
Update yuzu_cmd's default_ini.h
Rename FSR, add missing resolution multipliers, and SMAA
2023-02-06 06:01:51 -03:00
Kelebek1 8ae2a664d2 Remove fake vertex bindings when dynamic state is enabled 2023-02-05 22:28:03 +00:00
Merry 3f852c61d1 dynarmic: Update to 6.4.5 2023-02-05 21:49:32 +00:00
Mai 0373000143
Merge pull request #9731 from liamwhite/svc-move-only
kernel/svc: Split implementations into separate files
2023-02-05 02:26:52 -05:00
Liam 92eb091ddb kernel/svc: Split implementations into separate files 2023-02-04 22:37:43 -05:00
bunnei a64fc3ee77
Merge pull request #9720 from SoRadGaming/discordPresenceUpdate
Game Image with Discord RPC
2023-02-04 18:37:21 -08:00
Sorab 923c17f1ae Add Game Icon for Discord RPC
Connected to Yuzu Compatibility Page
2023-02-05 12:40:57 +11:00
liamwhite f5ed51bdf3
Merge pull request #9730 from german77/cmd_arg
yuzu_cmd: Order arguments alphabetically and port arguments from Qt
2023-02-04 15:01:17 -05:00
liamwhite 236b54376d
Merge pull request #9729 from german77/sdl_input
yuzu_cmd: Fix touch and controller input
2023-02-04 15:01:07 -05:00
liamwhite 7f56b0c49f
Merge pull request #9728 from ameerj/s32-value
shader_recompiler/value.h: Remove lingering references to S32
2023-02-04 15:00:54 -05:00
german77 3cd0b816cc yuzu_cmd: Order arguments alphabetically and port arguments from Qt 2023-02-04 11:33:29 -06:00
german77 ebca59b8e9 yuzu_cmd: Fix mismatching controller input 2023-02-04 11:05:57 -06:00
german77 424643f9af yuzu_cmd: Fix touch input 2023-02-04 10:31:12 -06:00
ameerj 4678f53463 shader_recompiler/value.h: Remove lingering references to S32 2023-02-04 00:13:47 -05:00
bunnei 5aca9386cf
Merge pull request #9717 from german77/less_is_better
input_common: Simplify stick from button
2023-02-03 16:09:29 -08:00
bunnei 193b513bf5
Merge pull request #9719 from ameerj/hle-ipc-span-copy
Revert #9718, Copy HLE Read Buffer for OutputAccessLogToSdCard
2023-02-03 15:42:18 -08:00
Jonas Gutenschwager 2a491f7aaa
remove disambiguation argument from mute text
Co-authored-by: Morph <39850852+Morph1984@users.noreply.github.com>
2023-02-04 00:00:20 +01:00
ameerj 979e4d9950 fsp_srv: Copy HLE Read Buffer for OutputAccessLogToSdCard 2023-02-03 00:12:16 -05:00
ameerj 2d2522693e Revert "Merge pull request #9718 from yuzu-emu/revert-9508-hle-ipc-buffer-span"
This reverts commit 25fc5c0e11, reversing
changes made to af20e25081.
2023-02-03 00:08:45 -05:00
Mai 9083ad816f
Merge pull request #9713 from unfamiliarplace/master
Added 'Hide empty rooms' toggle to lobby
2023-02-02 23:54:48 -05:00
bunnei 25fc5c0e11
Merge pull request #9718 from yuzu-emu/revert-9508-hle-ipc-buffer-span
Revert "hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer"
2023-02-02 19:04:50 -08:00
bunnei af20e25081
Merge pull request #9704 from liamwhite/das
kernel: add KDeviceAddressSpace
2023-02-02 19:00:23 -08:00
Luke Sawczak 54ab154696 added 'Hide empty rooms' toggle to lobby
fixed typo

fixed typo

fixed typo

clang
2023-02-02 18:46:28 -06:00
liamwhite b01698775b
Revert "hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer" 2023-02-02 15:53:28 -05:00
Narr the Reg 2f2e88c3fb input_common: Simplify stick from button 2023-02-02 10:13:27 -06:00
liamwhite 8a33f8bd30
Merge pull request #9708 from ameerj/gl-context-flush
gl_shader_cache: Force context flush when loading disk shader cache
2023-02-01 22:38:13 -05:00
liamwhite a9a860a4f7
Merge pull request #9703 from ameerj/txq-ms
shaders: Fix TXQ with MSAA textures
2023-02-01 22:38:00 -05:00
Liam 7d1c3a3f59 kernel: add KDeviceAddressSpace 2023-02-01 17:18:21 -05:00
bunnei 92c5ab33b7
Merge pull request #9696 from german77/please_forgive_me_for_this_sin
input_common: Implement turbo buttons
2023-02-01 12:08:34 -08:00
german77 ce1895497d yuzu: config: Draw turbo buttons with a different color 2023-02-01 12:42:06 -06:00
german77 75e81885b0 input_common: Implement turbo buttons 2023-02-01 12:42:05 -06:00
Mai c4aa833d61
Merge pull request #9711 from zhaobot/tx-update-20230201062139
Update translations (2023-02-01)
2023-02-01 01:26:51 -05:00
The yuzu Community 6ef4bee98e Update translations (2023-02-01) 2023-02-01 06:21:50 +00:00
ameerj 720ff38097 gl_compute_pipeline: Force context flush when loading shader cache 2023-01-29 21:32:12 -05:00
ameerj 01eeda74a6 gl_graphics_pipeline: Force context flush when loading shader cache 2023-01-29 20:26:49 -05:00
ameerj a63e17566a spirv: Fix TXQ with MSAA textures 2023-01-29 13:47:30 -05:00
ameerj a1d8306bfd emit_glasm_image: Fix TXQ with MSAA textures 2023-01-29 13:42:34 -05:00
ameerj 08feba2b56 emit_glsl_image: Implement TXQ with MSAA textures
Also fixes for texture buffers, which do not have mips eithers.
2023-01-29 13:31:47 -05:00
Morph ad6cec71ec main: Convert to device independent coordinates for scaling
devicePixelRatioF() returns the scaling ratio when high dpi scaling is enabled.
When high dpi scaling is enabled, the raw screen coordinate system is scaled to device independent coordinates.
2023-01-25 21:16:05 -05:00
Morph 5be85c556e main: Use passthrough scaling for non-windows OSes
They should be better than windows when handling fractional scaling ratios.
2023-01-25 21:16:04 -05:00
Morph 6a1b089a50 main: Enable High DPI fixes for Qt >= 5.14
This uses Qt's new high DPI application attributes for scaling the current window.
However, these aren't perfect as scaling with non integer scales will cause artifacts in UI, icons and other elements.
Therefore, we use a heuristic to select an appropriate integer scale value depending on the current screen resolution and applies this to the application.
2023-01-25 21:16:04 -05:00
Jonas Gutenschwager 4653effad8 add volume quicksetting with volume slider 2023-01-19 15:13:23 +01:00
Liam 505923f0f3 Revert "shader_recompiler: Align SSBO offsets to meet host requirements"
This reverts commit 8804a4eb23.
2023-01-07 15:50:58 -05:00
Liam 57a4388e2d Revert "Vulkan, OpenGL: Hook up storage buffer alignment code"
This reverts commit 9e2997c4b6.
2023-01-07 15:48:50 -05:00
313 changed files with 30269 additions and 18058 deletions

View file

@ -9,7 +9,7 @@ parameters:
steps:
- script: choco install vulkan-sdk
displayName: 'Install vulkan-sdk'
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
displayName: 'Configure CMake'
- task: MSBuild@1
displayName: 'Build'

3
.gitmodules vendored
View file

@ -13,9 +13,6 @@
[submodule "dynarmic"]
path = externals/dynarmic
url = https://github.com/MerryMage/dynarmic.git
[submodule "libressl"]
path = externals/libressl
url = https://github.com/citra-emu/ext-libressl-portable.git
[submodule "libusb"]
path = externals/libusb/libusb
url = https://github.com/libusb/libusb.git

View file

@ -56,6 +56,8 @@ option(YUZU_USE_BUNDLED_VCPKG "Use vcpkg for yuzu dependencies" "${MSVC}")
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ON)
option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF)
if (YUZU_USE_BUNDLED_VCPKG)
@ -65,6 +67,9 @@ if (YUZU_USE_BUNDLED_VCPKG)
if (YUZU_CRASH_DUMPS)
list(APPEND VCPKG_MANIFEST_FEATURES "dbghelp")
endif()
if (ENABLE_WEB_SERVICE)
list(APPEND VCPKG_MANIFEST_FEATURES "web-service")
endif()
include(${CMAKE_SOURCE_DIR}/externals/vcpkg/scripts/buildsystems/vcpkg.cmake)
elseif(NOT "$ENV{VCPKG_TOOLCHAIN_FILE}" STREQUAL "")
@ -205,10 +210,11 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# =======================================================================
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(Boost 1.73.0 REQUIRED context)
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
find_package(inih MODULE)
find_package(LLVM MODULE)
find_package(inih 52 MODULE COMPONENTS INIReader)
find_package(LLVM MODULE COMPONENTS Demangle)
find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3 MODULE)
@ -241,26 +247,13 @@ endif()
if (ENABLE_WEB_SERVICE)
find_package(cpp-jwt 1.4 CONFIG)
find_package(httplib 0.11 MODULE)
find_package(httplib 0.12 MODULE COMPONENTS OpenSSL)
endif()
if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)
endif()
find_package(Boost 1.73.0 COMPONENTS context)
if (Boost_FOUND)
set(Boost_LIBRARIES Boost::boost)
# Conditionally add Boost::context only if the found Boost package provides it
# The old version is missing Boost::context, so we want to avoid adding in that case
# The new version requires adding Boost::context to prevent linking issues
if (TARGET Boost::context)
list(APPEND Boost_LIBRARIES Boost::context)
endif()
else()
message(FATAL_ERROR "Boost 1.73.0 or newer not found")
endif()
# boost:asio has functions that require AcceptEx et al
if (MINGW)
find_library(MSWSOCK_LIBRARY mswsock REQUIRED)
@ -457,14 +450,6 @@ if (ENABLE_SDL2)
endif()
endif()
# Reexport some targets that are named differently when using the upstream CmakeConfig
# In order to ALIAS targets to a new name, they first need to be IMPORTED_GLOBAL
# Dynarmic checks for target `boost` and so we want to make sure it can find it through our system instead of using their external
if (TARGET Boost::boost)
set_target_properties(Boost::boost PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(boost ALIAS Boost::boost)
endif()
# List of all FFmpeg components required
set(FFmpeg_COMPONENTS
avcodec
@ -580,11 +565,7 @@ function(create_target_directory_groups target_name)
endfunction()
# Prevent boost from linking against libs when building
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
-DBOOST_SYSTEM_NO_LIB
-DBOOST_DATE_TIME_NO_LIB
-DBOOST_REGEX_NO_LIB
)
target_link_libraries(Boost::headers INTERFACE Boost::disable_autolinking)
# Adjustments for MSVC + Ninja
if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja")
add_compile_options(

View file

@ -2,15 +2,25 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
find_package(LLVM QUIET CONFIG)
find_package(LLVM QUIET COMPONENTS CONFIG)
if (LLVM_FOUND)
separate_arguments(LLVM_DEFINITIONS)
if (LLVMDemangle IN_LIST LLVM_AVAILABLE_LIBS)
set(LLVM_Demangle_FOUND TRUE)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVM CONFIG_MODE)
find_package_handle_standard_args(LLVM HANDLE_COMPONENTS CONFIG_MODE)
if (LLVM_FOUND AND NOT TARGET LLVM::Demangle)
if (LLVM_FOUND AND LLVM_Demangle_FOUND AND NOT TARGET LLVM::Demangle)
add_library(LLVM::Demangle INTERFACE IMPORTED)
llvm_map_components_to_libnames(LLVM_LIBRARIES demangle)
target_compile_definitions(LLVM::Demangle INTERFACE ${LLVM_DEFINITIONS})
target_include_directories(LLVM::Demangle INTERFACE ${LLVM_INCLUDE_DIRS})
# prefer shared LLVM: https://github.com/llvm/llvm-project/issues/34593
# but use ugly hack because llvm_config doesn't support interface library
add_library(_dummy_lib SHARED EXCLUDE_FROM_ALL src/yuzu/main.cpp)
llvm_config(_dummy_lib USE_SHARED demangle)
get_target_property(LLVM_LIBRARIES _dummy_lib LINK_LIBRARIES)
target_link_libraries(LLVM::Demangle INTERFACE ${LLVM_LIBRARIES})
endif()

View file

@ -6,13 +6,23 @@ include(FindPackageHandleStandardArgs)
find_package(httplib QUIET CONFIG)
if (httplib_CONSIDERED_CONFIGS)
find_package_handle_standard_args(httplib CONFIG_MODE)
find_package_handle_standard_args(httplib HANDLE_COMPONENTS CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
pkg_search_module(HTTPLIB QUIET IMPORTED_TARGET cpp-httplib)
if ("-DCPPHTTPLIB_OPENSSL_SUPPORT" IN_LIST HTTPLIB_CFLAGS_OTHER)
set(httplib_OpenSSL_FOUND TRUE)
endif()
if ("-DCPPHTTPLIB_ZLIB_SUPPORT" IN_LIST HTTPLIB_CFLAGS_OTHER)
set(httplib_ZLIB_FOUND TRUE)
endif()
if ("-DCPPHTTPLIB_BROTLI_SUPPORT" IN_LIST HTTPLIB_CFLAGS_OTHER)
set(httplib_Brotli_FOUND TRUE)
endif()
find_package_handle_standard_args(httplib
REQUIRED_VARS HTTPLIB_INCLUDEDIR
VERSION_VAR HTTPLIB_VERSION
HANDLE_COMPONENTS
)
endif()

View file

@ -3,14 +3,25 @@
# SPDX-License-Identifier: GPL-3.0-or-later
find_package(PkgConfig QUIET)
pkg_search_module(INIREADER QUIET IMPORTED_TARGET INIReader)
pkg_search_module(INIH QUIET IMPORTED_TARGET inih)
if (INIReader IN_LIST inih_FIND_COMPONENTS)
pkg_search_module(INIREADER QUIET IMPORTED_TARGET INIReader)
if (INIREADER_FOUND)
set(inih_INIReader_FOUND TRUE)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(inih
REQUIRED_VARS INIREADER_LINK_LIBRARIES
VERSION_VAR INIREADER_VERSION
REQUIRED_VARS INIH_LINK_LIBRARIES
VERSION_VAR INIH_VERSION
HANDLE_COMPONENTS
)
if (inih_FOUND AND NOT TARGET inih::INIReader)
if (inih_FOUND AND NOT TARGET inih::inih)
add_library(inih::inih ALIAS PkgConfig::INIH)
endif()
if (inih_FOUND AND inih_INIReader_FOUND AND NOT TARGET inih::INIReader)
add_library(inih::INIReader ALIAS PkgConfig::INIREADER)
endif()

1281
dist/languages/ca.ts vendored

File diff suppressed because it is too large Load diff

1279
dist/languages/cs.ts vendored

File diff suppressed because it is too large Load diff

1277
dist/languages/da.ts vendored

File diff suppressed because it is too large Load diff

1345
dist/languages/de.ts vendored

File diff suppressed because it is too large Load diff

1285
dist/languages/el.ts vendored

File diff suppressed because it is too large Load diff

1422
dist/languages/es.ts vendored

File diff suppressed because it is too large Load diff

1339
dist/languages/fr.ts vendored

File diff suppressed because it is too large Load diff

1279
dist/languages/id.ts vendored

File diff suppressed because it is too large Load diff

1331
dist/languages/it.ts vendored

File diff suppressed because it is too large Load diff

1398
dist/languages/ja_JP.ts vendored

File diff suppressed because it is too large Load diff

1368
dist/languages/ko_KR.ts vendored

File diff suppressed because it is too large Load diff

1285
dist/languages/nb.ts vendored

File diff suppressed because it is too large Load diff

1291
dist/languages/nl.ts vendored

File diff suppressed because it is too large Load diff

1688
dist/languages/pl.ts vendored

File diff suppressed because it is too large Load diff

1657
dist/languages/pt_BR.ts vendored

File diff suppressed because it is too large Load diff

1659
dist/languages/pt_PT.ts vendored

File diff suppressed because it is too large Load diff

1437
dist/languages/ru_RU.ts vendored

File diff suppressed because it is too large Load diff

1293
dist/languages/sv.ts vendored

File diff suppressed because it is too large Load diff

1285
dist/languages/tr_TR.ts vendored

File diff suppressed because it is too large Load diff

1365
dist/languages/uk.ts vendored

File diff suppressed because it is too large Load diff

1361
dist/languages/zh_CN.ts vendored

File diff suppressed because it is too large Load diff

1285
dist/languages/zh_TW.ts vendored

File diff suppressed because it is too large Load diff

View file

@ -102,41 +102,16 @@ add_subdirectory(sirit EXCLUDE_FROM_ALL)
# httplib
if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (NOT WIN32)
find_package(OpenSSL 1.1)
if (OPENSSL_FOUND)
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
endif()
endif()
if (WIN32 OR NOT OPENSSL_FOUND)
# LibreSSL
set(LIBRESSL_SKIP_INSTALL ON)
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
get_directory_property(OPENSSL_LIBRARIES
DIRECTORY libressl
DEFINITION OPENSSL_LIBS)
endif()
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./cpp-httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
if (WIN32)
target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
endif()
add_library(httplib::httplib ALIAS httplib)
set(HTTPLIB_REQUIRE_OPENSSL ON)
add_subdirectory(cpp-httplib EXCLUDE_FROM_ALL)
endif()
# cpp-jwt
if (ENABLE_WEB_SERVICE AND NOT TARGET cpp-jwt::cpp-jwt)
add_library(cpp-jwt INTERFACE)
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
add_library(cpp-jwt::cpp-jwt ALIAS cpp-jwt)
set(CPP_JWT_BUILD_EXAMPLES OFF)
set(CPP_JWT_BUILD_TESTS OFF)
set(CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF)
add_subdirectory(cpp-jwt EXCLUDE_FROM_ALL)
endif()
# Opus

@ -1 +1 @@
Subproject commit 305a7abcb9b4e9e349843c6d563212e6c1bbbf21
Subproject commit 6d963fbe8d415399d65e94db7910bbd22fe3741c

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit befe547d5631024a70d81d2ccee808bbfcb3854e
Subproject commit 165621a872ffb802c7a26ef5900e1e62681f1a88

1
externals/libressl vendored

@ -1 +0,0 @@
Subproject commit 8929f818fd748fd31a34fec7c04558399e13014a

View file

@ -132,7 +132,7 @@ void AudioRenderer::CreateSinkStreams() {
}
void AudioRenderer::ThreadFunc() {
constexpr char name[]{"AudioRenderer"};
static constexpr char name[]{"AudioRenderer"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);

View file

@ -251,8 +251,8 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
const auto& parameter{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
const auto state{
reinterpret_cast<VoiceState::BiquadFilterState*>(effect_info.GetStateBuffer())};
const auto state{reinterpret_cast<VoiceState::BiquadFilterState*>(
effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))};
cmd.input = buffer_offset + parameter.inputs[channel];
cmd.output = buffer_offset + parameter.outputs[channel];

View file

@ -46,7 +46,7 @@ void CommandGenerator::GenerateDataSourceCommand(VoiceInfo& voice_info,
while (destination != nullptr) {
if (destination->IsConfigured()) {
auto mix_id{destination->GetMixId()};
if (mix_id < mix_context.GetCount()) {
if (mix_id < mix_context.GetCount() && mix_id != UnusedSplitterId) {
auto mix_info{mix_context.GetInfo(mix_id)};
command_buffer.GenerateDepopPrepareCommand(
voice_info.node_id, voice_state, render_context.depop_buffer,

View file

@ -4,6 +4,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/aux_.h"
#include "audio_core/renderer/effect/aux_.h"
#include "core/core.h"
#include "core/memory.h"
namespace AudioCore::AudioRenderer {
@ -19,10 +20,24 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
return;
}
auto info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(aux_info))};
info->read_offset = 0;
info->write_offset = 0;
info->total_sample_count = 0;
AuxInfo::AuxInfoDsp info{};
auto info_ptr{&info};
bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))};
if (host_safe) [[likely]] {
info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info);
} else {
memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
info_ptr->read_offset = 0;
info_ptr->write_offset = 0;
info_ptr->total_sample_count = 0;
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
}
/**
@ -40,11 +55,10 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
* @param update_count - If non-zero, send_info_ will be updated.
* @return Number of samples written.
*/
static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_info_,
[[maybe_unused]] u32 sample_count, const CpuAddr send_buffer,
const u32 count_max, std::span<const s32> input,
const u32 write_count_, const u32 write_offset,
const u32 update_count) {
static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
[[maybe_unused]] u32 sample_count, CpuAddr send_buffer, u32 count_max,
std::span<const s32> input, u32 write_count_, u32 write_offset,
u32 update_count) {
if (write_count_ > count_max) {
LOG_ERROR(Service_Audio,
"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
return 0;
}
if (send_info_ == 0) {
LOG_ERROR(Service_Audio, "send_info_ is 0!");
return 0;
}
if (input.empty()) {
LOG_ERROR(Service_Audio, "input buffer is empty!");
return 0;
@ -67,33 +86,47 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
}
AuxInfo::AuxInfoDsp send_info{};
memory.ReadBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp));
auto send_ptr = &send_info;
bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
u32 target_write_offset{send_info.write_offset + write_offset};
if (target_write_offset > count_max || write_count_ == 0) {
if (host_safe) [[likely]] {
send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_);
} else {
memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
u32 target_write_offset{send_ptr->write_offset + write_offset};
if (target_write_offset > count_max) {
return 0;
}
u32 write_count{write_count_};
u32 write_pos{0};
u32 read_pos{0};
while (write_count > 0) {
u32 to_write{std::min(count_max - target_write_offset, write_count)};
if (to_write > 0) {
const auto write_addr = send_buffer + target_write_offset * sizeof(s32);
bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))};
if (write_safe) [[likely]] {
auto ptr = memory.GetPointer(write_addr);
std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32));
} else {
memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32),
&input[write_pos], to_write * sizeof(s32));
&input[read_pos], to_write * sizeof(s32));
}
target_write_offset = (target_write_offset + to_write) % count_max;
write_count -= to_write;
write_pos += to_write;
read_pos += to_write;
}
if (update_count) {
send_info.write_offset = (send_info.write_offset + update_count) % count_max;
send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max;
}
memory.WriteBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp));
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
return write_count_;
}
@ -102,7 +135,7 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_in
* Read the given memory at return_buffer into the output mix buffer, and update return_info_ if
* update_count is set, to notify the game that an update happened.
*
* @param memory - Core memory for writing.
* @param memory - Core memory for reading.
* @param return_info_ - Meta information for where to read the mix buffer.
* @param return_buffer - Memory address to read the samples from.
* @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
* @param update_count - If non-zero, send_info_ will be updated.
* @return Number of samples read.
*/
static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_info_,
const CpuAddr return_buffer, const u32 count_max, std::span<s32> output,
const u32 count_, const u32 read_offset, const u32 update_count) {
static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
CpuAddr return_buffer, u32 count_max, std::span<s32> output,
u32 read_count_, u32 read_offset, u32 update_count) {
if (count_max == 0) {
return 0;
}
if (count_ > count_max) {
if (read_count_ > count_max) {
LOG_ERROR(Service_Audio, "count must be smaller than count_max! count {}, count_max {}",
count_, count_max);
read_count_, count_max);
return 0;
}
if (return_info_ == 0) {
LOG_ERROR(Service_Audio, "return_info_ is 0!");
return 0;
}
@ -136,35 +174,49 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_i
}
AuxInfo::AuxInfoDsp return_info{};
memory.ReadBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp));
auto return_ptr = &return_info;
bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
u32 target_read_offset{return_info.read_offset + read_offset};
if (host_safe) [[likely]] {
return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_);
} else {
memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
u32 target_read_offset{return_ptr->read_offset + read_offset};
if (target_read_offset > count_max) {
return 0;
}
u32 read_count{count_};
u32 read_pos{0};
u32 read_count{read_count_};
u32 write_pos{0};
while (read_count > 0) {
u32 to_read{std::min(count_max - target_read_offset, read_count)};
if (to_read > 0) {
const auto read_addr = return_buffer + target_read_offset * sizeof(s32);
bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))};
if (read_safe) [[likely]] {
auto ptr = memory.GetPointer(read_addr);
std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32));
} else {
memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32),
&output[read_pos], to_read * sizeof(s32));
&output[write_pos], to_read * sizeof(s32));
}
target_read_offset = (target_read_offset + to_read) % count_max;
read_count -= to_read;
read_pos += to_read;
write_pos += to_read;
}
if (update_count) {
return_info.read_offset = (return_info.read_offset + update_count) % count_max;
return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max;
}
memory.WriteBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp));
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
return count_;
return read_count_;
}
void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
@ -189,7 +241,7 @@ void AuxCommand::Process(const ADSP::CommandListProcessor& processor) {
update_count)};
if (read != processor.sample_count) {
std::memset(&output_buffer[read], 0, processor.sample_count - read);
std::memset(&output_buffer[read], 0, (processor.sample_count - read) * sizeof(s32));
}
} else {
ResetAuxBufferDsp(*processor.memory, send_buffer_info);

View file

@ -4,6 +4,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/biquad_filter.h"
#include "audio_core/renderer/voice/voice_state.h"
#include "common/bit_cast.h"
namespace AudioCore::AudioRenderer {
/**
@ -19,21 +20,21 @@ namespace AudioCore::AudioRenderer {
void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b_, std::array<s16, 2>& a_,
VoiceState::BiquadFilterState& state, const u32 sample_count) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
constexpr f64 min{std::numeric_limits<s32>::min()};
constexpr f64 max{std::numeric_limits<s32>::max()};
std::array<f64, 3> b{Common::FixedPoint<50, 14>::from_base(b_[0]).to_double(),
Common::FixedPoint<50, 14>::from_base(b_[1]).to_double(),
Common::FixedPoint<50, 14>::from_base(b_[2]).to_double()};
std::array<f64, 2> a{Common::FixedPoint<50, 14>::from_base(a_[0]).to_double(),
Common::FixedPoint<50, 14>::from_base(a_[1]).to_double()};
std::array<f64, 4> s{state.s0.to_double(), state.s1.to_double(), state.s2.to_double(),
state.s3.to_double()};
std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1),
Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)};
for (u32 i = 0; i < sample_count; i++) {
f64 in_sample{static_cast<f64>(input[i])};
auto sample{in_sample * b[0] + s[0] * b[1] + s[1] * b[2] + s[2] * a[0] + s[3] * a[1]};
output[i] = static_cast<s32>(std::clamp(static_cast<s64>(sample), min, max));
output[i] = static_cast<s32>(std::clamp(sample, min, max));
s[1] = s[0];
s[0] = in_sample;
@ -41,10 +42,10 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
s[2] = sample;
}
state.s0 = s[0];
state.s1 = s[1];
state.s2 = s[2];
state.s3 = s[3];
state.s0 = Common::BitCast<s64>(s[0]);
state.s1 = Common::BitCast<s64>(s[1]);
state.s2 = Common::BitCast<s64>(s[2]);
state.s3 = Common::BitCast<s64>(s[3]);
}
/**
@ -58,29 +59,20 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
* @param sample_count - Number of samples to process.
*/
static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b_, std::array<s16, 2>& a_,
std::array<s16, 3>& b, std::array<s16, 2>& a,
VoiceState::BiquadFilterState& state, const u32 sample_count) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
std::array<Common::FixedPoint<50, 14>, 3> b{
Common::FixedPoint<50, 14>::from_base(b_[0]),
Common::FixedPoint<50, 14>::from_base(b_[1]),
Common::FixedPoint<50, 14>::from_base(b_[2]),
};
std::array<Common::FixedPoint<50, 14>, 3> a{
Common::FixedPoint<50, 14>::from_base(a_[0]),
Common::FixedPoint<50, 14>::from_base(a_[1]),
};
for (u32 i = 0; i < sample_count; i++) {
s64 in_sample{input[i]};
auto sample{in_sample * b[0] + state.s0};
const auto out_sample{std::clamp(sample.to_long(), min, max)};
const s64 in_sample{input[i]};
const s64 sample{in_sample * b[0] + state.s0};
const s64 out_sample{std::clamp<s64>((sample + (1 << 13)) >> 14, min, max)};
output[i] = static_cast<s32>(out_sample);
state.s0 = state.s1 + b[1] * in_sample + a[0] * out_sample;
state.s1 = 0 + b[2] * in_sample + a[1] * out_sample;
state.s1 = b[2] * in_sample + a[1] * out_sample;
}
}

View file

@ -244,16 +244,16 @@ template <size_t NumChannels>
static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state,
std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
};
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3,
};
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
2, 0, 0, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 0, 0, 0, 0, 5, 5, 5,
};

View file

@ -252,16 +252,16 @@ template <size_t NumChannels>
static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
0, 0, 1, 1, 0, 1, 0, 0, 1, 1,
};
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
0, 0, 1, 1, 0, 1, 2, 2, 3, 3,
};
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
0, 0, 1, 1, 2, 2, 4, 4, 5, 5,
};

View file

@ -19,24 +19,24 @@ namespace AudioCore::AudioRenderer {
static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
const u32 target_sample_count, const u32 source_sample_count,
UpsamplerState* state) {
constexpr u32 WindowSize = 10;
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
static constexpr u32 WindowSize = 10;
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f,
-0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f,
};
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f,
-0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f,
};
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f,
-0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f,
};
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f,
-0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f,
};
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f,
-0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f,
};

View file

@ -127,7 +127,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
render_device = params.rendering_device;
execution_mode = params.execution_mode;
core.Memory().ZeroBlock(*core.Kernel().CurrentProcess(), transfer_memory->GetSourceAddress(),
core.Memory().ZeroBlock(*core.ApplicationProcess(), transfer_memory->GetSourceAddress(),
transfer_memory_size);
// Note: We're not actually using the transfer memory because it's a pain to code for.

View file

@ -94,7 +94,7 @@ bool SystemManager::Remove(System& system_) {
}
void SystemManager::ThreadFunc() {
constexpr char name[]{"AudioRenderSystemManager"};
static constexpr char name[]{"AudioRenderSystemManager"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);

View file

@ -19,10 +19,10 @@ struct VoiceState {
* State of the voice's biquad filter.
*/
struct BiquadFilterState {
Common::FixedPoint<50, 14> s0;
Common::FixedPoint<50, 14> s1;
Common::FixedPoint<50, 14> s2;
Common::FixedPoint<50, 14> s3;
s64 s0;
s64 s1;
s64 s2;
s64 s3;
};
/**

View file

@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
std::vector<std::string> device_list;
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
return {};
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT};
cubeb_device_collection collection;
if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) {
@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
u32 GetCubebLatency() {
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
// Return a large latency so we choose SDL instead.
return 10000u;
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;

View file

@ -35,7 +35,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
if (system_channels == 6 && device_channels == 2) {
// We're given 6 channels, but our device only outputs 2, so downmix.
constexpr std::array<f32, 4> down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f};
static constexpr std::array<f32, 4> down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f};
for (u32 read_index = 0, write_index = 0; read_index < samples.size();
read_index += system_channels, write_index += device_channels) {
@ -202,7 +202,7 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
// If we're paused or going to shut down, we don't want to consume buffers as coretiming is
// paused and we'll desync, so just play silence.
if (system.IsPaused() || system.IsShuttingDown()) {
constexpr std::array<s16, 6> silence{};
static constexpr std::array<s16, 6> silence{};
for (size_t i = frames_written; i < num_frames; i++) {
std::memcpy(&output_buffer[i * frame_size], &silence[0], frame_size_bytes);
}
@ -270,7 +270,7 @@ void SinkStream::Stall() {
if (stalled_lock) {
return;
}
stalled_lock = system.StallProcesses();
stalled_lock = system.StallApplication();
}
void SinkStream::Unstall() {
@ -278,7 +278,7 @@ void SinkStream::Unstall() {
if (!stalled_lock) {
return;
}
system.UnstallProcesses();
system.UnstallApplication();
stalled_lock.unlock();
}

View file

@ -176,7 +176,7 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
if (YUZU_USE_PRECOMPILED_HEADERS)

View file

@ -130,6 +130,8 @@ struct ButtonStatus {
bool inverted{};
// Press once to activate, press again to release
bool toggle{};
// Spams the button when active
bool turbo{};
// Internal lock for the toggle status
bool locked{};
};

View file

@ -23,6 +23,7 @@ public:
buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
~ScratchBuffer() = default;
ScratchBuffer(ScratchBuffer&&) = default;
/// This will only grow the buffer's capacity if size is greater than the current capacity.
/// The previously held data will remain intact.

View file

@ -59,6 +59,7 @@ void LogSettings() {
values.use_asynchronous_gpu_emulation.GetValue());
log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
log_setting("Renderer_AsyncASTC", values.async_astc.GetValue());
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
@ -76,6 +77,13 @@ void LogSettings() {
log_setting("Debugging_GDBStub", values.use_gdbstub.GetValue());
log_setting("Input_EnableMotion", values.motion_enabled.GetValue());
log_setting("Input_EnableVibration", values.vibration_enabled.GetValue());
log_setting("Input_EnableTouch", values.touchscreen.enabled);
log_setting("Input_EnableMouse", values.mouse_enabled.GetValue());
log_setting("Input_EnableKeyboard", values.keyboard_enabled.GetValue());
log_setting("Input_EnableRingController", values.enable_ring_controller.GetValue());
log_setting("Input_EnableIrSensor", values.enable_ir_sensor.GetValue());
log_setting("Input_EnableCustomJoycon", values.enable_joycon_driver.GetValue());
log_setting("Input_EnableCustomProController", values.enable_procon_driver.GetValue());
log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue());
}
@ -199,7 +207,11 @@ void RestoreGlobalState(bool is_powered_on) {
values.renderer_backend.SetGlobal(true);
values.renderer_force_max_clock.SetGlobal(true);
values.vulkan_device.SetGlobal(true);
values.fullscreen_mode.SetGlobal(true);
values.aspect_ratio.SetGlobal(true);
values.resolution_setup.SetGlobal(true);
values.scaling_filter.SetGlobal(true);
values.anti_aliasing.SetGlobal(true);
values.max_anisotropy.SetGlobal(true);
values.use_speed_limit.SetGlobal(true);
values.speed_limit.SetGlobal(true);
@ -208,6 +220,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.use_asynchronous_gpu_emulation.SetGlobal(true);
values.nvdec_emulation.SetGlobal(true);
values.accelerate_astc.SetGlobal(true);
values.async_astc.SetGlobal(true);
values.use_vsync.SetGlobal(true);
values.shader_backend.SetGlobal(true);
values.use_asynchronous_shaders.SetGlobal(true);

View file

@ -453,6 +453,7 @@ struct Values {
SwitchableSetting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"};
SwitchableSetting<bool> async_astc{false, "async_astc"};
SwitchableSetting<bool> use_vsync{true, "use_vsync"};
SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL,
ShaderBackend::SPIRV, "shader_backend"};
@ -488,6 +489,7 @@ struct Values {
Setting<bool> enable_raw_input{false, "enable_raw_input"};
Setting<bool> controller_navigation{true, "controller_navigation"};
Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
Setting<bool> enable_procon_driver{false, "enable_procon_driver"};
SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};

View file

@ -195,6 +195,8 @@ add_library(core STATIC
hle/kernel/k_condition_variable.cpp
hle/kernel/k_condition_variable.h
hle/kernel/k_debug.h
hle/kernel/k_device_address_space.cpp
hle/kernel/k_device_address_space.h
hle/kernel/k_dynamic_page_manager.h
hle/kernel/k_dynamic_resource_manager.h
hle/kernel/k_dynamic_slab_heap.h
@ -223,6 +225,8 @@ add_library(core STATIC
hle/kernel/k_memory_manager.h
hle/kernel/k_memory_region.h
hle/kernel/k_memory_region_type.h
hle/kernel/k_object_name.cpp
hle/kernel/k_object_name.h
hle/kernel/k_page_bitmap.h
hle/kernel/k_page_buffer.cpp
hle/kernel/k_page_buffer.h
@ -296,7 +300,43 @@ add_library(core STATIC
hle/kernel/svc.h
hle/kernel/svc_common.h
hle/kernel/svc_types.h
hle/kernel/svc_wrap.h
hle/kernel/svc/svc_activity.cpp
hle/kernel/svc/svc_address_arbiter.cpp
hle/kernel/svc/svc_address_translation.cpp
hle/kernel/svc/svc_cache.cpp
hle/kernel/svc/svc_code_memory.cpp
hle/kernel/svc/svc_condition_variable.cpp
hle/kernel/svc/svc_debug.cpp
hle/kernel/svc/svc_debug_string.cpp
hle/kernel/svc/svc_device_address_space.cpp
hle/kernel/svc/svc_event.cpp
hle/kernel/svc/svc_exception.cpp
hle/kernel/svc/svc_info.cpp
hle/kernel/svc/svc_insecure_memory.cpp
hle/kernel/svc/svc_interrupt_event.cpp
hle/kernel/svc/svc_io_pool.cpp
hle/kernel/svc/svc_ipc.cpp
hle/kernel/svc/svc_kernel_debug.cpp
hle/kernel/svc/svc_light_ipc.cpp
hle/kernel/svc/svc_lock.cpp
hle/kernel/svc/svc_memory.cpp
hle/kernel/svc/svc_physical_memory.cpp
hle/kernel/svc/svc_port.cpp
hle/kernel/svc/svc_power_management.cpp
hle/kernel/svc/svc_process.cpp
hle/kernel/svc/svc_process_memory.cpp
hle/kernel/svc/svc_processor.cpp
hle/kernel/svc/svc_query_memory.cpp
hle/kernel/svc/svc_register.cpp
hle/kernel/svc/svc_resource_limit.cpp
hle/kernel/svc/svc_secure_monitor_call.cpp
hle/kernel/svc/svc_session.cpp
hle/kernel/svc/svc_shared_memory.cpp
hle/kernel/svc/svc_synchronization.cpp
hle/kernel/svc/svc_thread.cpp
hle/kernel/svc/svc_thread_profiler.cpp
hle/kernel/svc/svc_tick.cpp
hle/kernel/svc/svc_transfer_memory.cpp
hle/result.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h
@ -346,8 +386,6 @@ add_library(core STATIC
hle/service/am/omm.h
hle/service/am/spsm.cpp
hle/service/am/spsm.h
hle/service/am/tcap.cpp
hle/service/am/tcap.h
hle/service/aoc/aoc_u.cpp
hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp
@ -358,28 +396,18 @@ add_library(core STATIC
hle/service/apm/apm_interface.h
hle/service/audio/audctl.cpp
hle/service/audio/audctl.h
hle/service/audio/auddbg.cpp
hle/service/audio/auddbg.h
hle/service/audio/audin_a.cpp
hle/service/audio/audin_a.h
hle/service/audio/audin_u.cpp
hle/service/audio/audin_u.h
hle/service/audio/audio.cpp
hle/service/audio/audio.h
hle/service/audio/audout_a.cpp
hle/service/audio/audout_a.h
hle/service/audio/audout_u.cpp
hle/service/audio/audout_u.h
hle/service/audio/audrec_a.cpp
hle/service/audio/audrec_a.h
hle/service/audio/audrec_u.cpp
hle/service/audio/audrec_u.h
hle/service/audio/audren_a.cpp
hle/service/audio/audren_a.h
hle/service/audio/audren_u.cpp
hle/service/audio/audren_u.h
hle/service/audio/codecctl.cpp
hle/service/audio/codecctl.h
hle/service/audio/errors.h
hle/service/audio/hwopus.cpp
hle/service/audio/hwopus.h
@ -674,8 +702,6 @@ add_library(core STATIC
hle/service/sm/sm_controller.h
hle/service/sockets/bsd.cpp
hle/service/sockets/bsd.h
hle/service/sockets/ethc.cpp
hle/service/sockets/ethc.h
hle/service/sockets/nsd.cpp
hle/service/sockets/nsd.h
hle/service/sockets/sfdnsres.cpp
@ -742,8 +768,6 @@ add_library(core STATIC
hle/service/vi/vi_s.h
hle/service/vi/vi_u.cpp
hle/service/vi/vi_u.h
hle/service/wlan/wlan.cpp
hle/service/wlan/wlan.h
internal_network/network.cpp
internal_network/network.h
internal_network/network_interface.cpp
@ -808,7 +832,7 @@ endif()
create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
if (MINGW)
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
endif()
@ -837,3 +861,7 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(core PRIVATE precompiled_headers.h)
endif()
if (YUZU_ENABLE_LTO)
set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

View file

@ -43,9 +43,9 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
std::map<std::string, Symbols::Symbols> symbols;
for (const auto& module : modules) {
symbols.insert_or_assign(module.second,
Symbols::GetSymbols(module.first, system.Memory(),
system.CurrentProcess()->Is64BitProcess()));
symbols.insert_or_assign(
module.second, Symbols::GetSymbols(module.first, system.Memory(),
system.ApplicationProcess()->Is64BitProcess()));
}
for (auto& entry : out) {

View file

@ -5,6 +5,7 @@
#include <array>
#include <span>
#include <string>
#include <vector>
#include <dynarmic/interface/halt_reason.h>

View file

@ -186,7 +186,7 @@ struct System::Impl {
void Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
kernel.Suspend(false);
kernel.SuspendApplication(false);
core_timing.SyncPause(false);
is_paused.store(false, std::memory_order_relaxed);
}
@ -195,7 +195,7 @@ struct System::Impl {
std::unique_lock<std::mutex> lk(suspend_guard);
core_timing.SyncPause(true);
kernel.Suspend(true);
kernel.SuspendApplication(true);
is_paused.store(true, std::memory_order_relaxed);
}
@ -203,17 +203,17 @@ struct System::Impl {
return is_paused.load(std::memory_order_relaxed);
}
std::unique_lock<std::mutex> StallProcesses() {
std::unique_lock<std::mutex> StallApplication() {
std::unique_lock<std::mutex> lk(suspend_guard);
kernel.Suspend(true);
kernel.SuspendApplication(true);
core_timing.SyncPause(true);
return lk;
}
void UnstallProcesses() {
void UnstallApplication() {
if (!IsPaused()) {
core_timing.SyncPause(false);
kernel.Suspend(false);
kernel.SuspendApplication(false);
}
}
@ -221,7 +221,7 @@ struct System::Impl {
debugger = std::make_unique<Debugger>(system, port);
}
SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
// Setting changes may require a full system reinitialization (e.g., disabling multicore).
@ -273,7 +273,7 @@ struct System::Impl {
return SystemResultStatus::ErrorGetLoader;
}
SystemResultStatus init_result{SetupForMainProcess(system, emu_window)};
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
@ -302,7 +302,7 @@ struct System::Impl {
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
}
AddGlueRegistrationForProcess(*app_loader, *main_process);
kernel.MakeCurrentProcess(main_process);
kernel.MakeApplicationProcess(main_process);
kernel.InitializeCores();
// Initialize cheat engine
@ -585,12 +585,12 @@ void System::DetachDebugger() {
}
}
std::unique_lock<std::mutex> System::StallProcesses() {
return impl->StallProcesses();
std::unique_lock<std::mutex> System::StallApplication() {
return impl->StallApplication();
}
void System::UnstallProcesses() {
impl->UnstallProcesses();
void System::UnstallApplication() {
impl->UnstallApplication();
}
void System::InitializeDebugger() {
@ -648,8 +648,8 @@ const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const {
return impl->kernel.GlobalSchedulerContext();
}
Kernel::KProcess* System::CurrentProcess() {
return impl->kernel.CurrentProcess();
Kernel::KProcess* System::ApplicationProcess() {
return impl->kernel.ApplicationProcess();
}
Core::DeviceMemory& System::DeviceMemory() {
@ -660,8 +660,8 @@ const Core::DeviceMemory& System::DeviceMemory() const {
return *impl->device_memory;
}
const Kernel::KProcess* System::CurrentProcess() const {
return impl->kernel.CurrentProcess();
const Kernel::KProcess* System::ApplicationProcess() const {
return impl->kernel.ApplicationProcess();
}
ARM_Interface& System::ArmInterface(std::size_t core_index) {
@ -760,8 +760,8 @@ const Core::SpeedLimiter& System::SpeedLimiter() const {
return impl->speed_limiter;
}
u64 System::GetCurrentProcessProgramID() const {
return impl->kernel.CurrentProcess()->GetProgramID();
u64 System::GetApplicationProcessProgramID() const {
return impl->kernel.ApplicationProcess()->GetProgramID();
}
Loader::ResultStatus System::GetGameName(std::string& out) const {
@ -880,11 +880,11 @@ bool System::GetExitLock() const {
return impl->exit_lock;
}
void System::SetCurrentProcessBuildID(const CurrentBuildProcessID& id) {
void System::SetApplicationProcessBuildID(const CurrentBuildProcessID& id) {
impl->build_id = id;
}
const System::CurrentBuildProcessID& System::GetCurrentProcessBuildID() const {
const System::CurrentBuildProcessID& System::GetApplicationProcessBuildID() const {
return impl->build_id;
}

View file

@ -184,8 +184,8 @@ public:
/// Forcibly detach the debugger if it is running.
void DetachDebugger();
std::unique_lock<std::mutex> StallProcesses();
void UnstallProcesses();
std::unique_lock<std::mutex> StallApplication();
void UnstallApplication();
/**
* Initialize the debugger.
@ -295,11 +295,11 @@ public:
/// Gets the manager for the guest device memory
[[nodiscard]] const Core::DeviceMemory& DeviceMemory() const;
/// Provides a pointer to the current process
[[nodiscard]] Kernel::KProcess* CurrentProcess();
/// Provides a pointer to the application process
[[nodiscard]] Kernel::KProcess* ApplicationProcess();
/// Provides a constant pointer to the current process.
[[nodiscard]] const Kernel::KProcess* CurrentProcess() const;
/// Provides a constant pointer to the application process.
[[nodiscard]] const Kernel::KProcess* ApplicationProcess() const;
/// Provides a reference to the core timing instance.
[[nodiscard]] Timing::CoreTiming& CoreTiming();
@ -331,7 +331,7 @@ public:
/// Provides a constant reference to the speed limiter
[[nodiscard]] const Core::SpeedLimiter& SpeedLimiter() const;
[[nodiscard]] u64 GetCurrentProcessProgramID() const;
[[nodiscard]] u64 GetApplicationProcessProgramID() const;
/// Gets the name of the current game
[[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
@ -396,8 +396,8 @@ public:
void SetExitLock(bool locked);
[[nodiscard]] bool GetExitLock() const;
void SetCurrentProcessBuildID(const CurrentBuildProcessID& id);
[[nodiscard]] const CurrentBuildProcessID& GetCurrentProcessBuildID() const;
void SetApplicationProcessBuildID(const CurrentBuildProcessID& id);
[[nodiscard]] const CurrentBuildProcessID& GetApplicationProcessBuildID() const;
/// Register a host thread as an emulated CPU Core.
void RegisterCoreThread(std::size_t id);

View file

@ -45,7 +45,7 @@ CoreTiming::~CoreTiming() {
}
void CoreTiming::ThreadEntry(CoreTiming& instance) {
constexpr char name[] = "HostTiming";
static constexpr char name[] = "HostTiming";
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);

View file

@ -96,7 +96,7 @@ static std::string EscapeXML(std::string_view data) {
GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_)
: DebuggerFrontend(backend_), system{system_} {
if (system.CurrentProcess()->Is64BitProcess()) {
if (system.ApplicationProcess()->Is64BitProcess()) {
arch = std::make_unique<GDBStubA64>();
} else {
arch = std::make_unique<GDBStubA32>();
@ -340,15 +340,15 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) {
success = true;
break;
case BreakpointType::WriteWatch:
success = system.CurrentProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
break;
case BreakpointType::ReadWatch:
success = system.CurrentProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
break;
case BreakpointType::AccessWatch:
success = system.CurrentProcess()->InsertWatchpoint(
success = system.ApplicationProcess()->InsertWatchpoint(
system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
break;
case BreakpointType::Hardware:
@ -391,15 +391,15 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
break;
}
case BreakpointType::WriteWatch:
success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
break;
case BreakpointType::ReadWatch:
success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
break;
case BreakpointType::AccessWatch:
success = system.CurrentProcess()->RemoveWatchpoint(
success = system.ApplicationProcess()->RemoveWatchpoint(
system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
break;
case BreakpointType::Hardware:
@ -482,7 +482,7 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory&
static std::optional<std::string> GetThreadName(Core::System& system,
const Kernel::KThread* thread) {
if (system.CurrentProcess()->Is64BitProcess()) {
if (system.ApplicationProcess()->Is64BitProcess()) {
return GetNameFromThreadType64(system.Memory(), thread);
} else {
return GetNameFromThreadType32(system.Memory(), thread);
@ -555,7 +555,7 @@ void GDBStub::HandleQuery(std::string_view command) {
SendReply(fmt::format("TextSeg={:x}", main->first));
} else {
SendReply(fmt::format("TextSeg={:x}",
system.CurrentProcess()->PageTable().GetCodeRegionStart()));
system.ApplicationProcess()->PageTable().GetCodeRegionStart()));
}
} else if (command.starts_with("Xfer:libraries:read::")) {
Loader::AppLoader::Modules modules;
@ -729,7 +729,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
std::string_view command_str{reinterpret_cast<const char*>(&command[0]), command.size()};
std::string reply;
auto* process = system.CurrentProcess();
auto* process = system.ApplicationProcess();
auto& page_table = process->PageTable();
const char* commands = "Commands:\n"

View file

@ -41,9 +41,8 @@ static void PutSIMDRegister(std::array<u32, 64>& simd_regs, size_t offset, const
// For sample XML files see the GDB source /gdb/features
// This XML defines what the registers are for this specific ARM device
std::string GDBStubA64::GetTargetXML() const {
constexpr const char* target_xml =
R"(<?xml version="1.0"?>
std::string_view GDBStubA64::GetTargetXML() const {
return R"(<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>aarch64</architecture>
@ -178,8 +177,6 @@ std::string GDBStubA64::GetTargetXML() const {
<reg name="fpcr" bitsize="32"/>
</feature>
</target>)";
return target_xml;
}
std::string GDBStubA64::RegRead(const Kernel::KThread* thread, size_t id) const {
@ -270,9 +267,8 @@ u32 GDBStubA64::BreakpointInstruction() const {
return 0xd4200000;
}
std::string GDBStubA32::GetTargetXML() const {
constexpr const char* target_xml =
R"(<?xml version="1.0"?>
std::string_view GDBStubA32::GetTargetXML() const {
return R"(<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>arm</architecture>
@ -378,8 +374,6 @@ std::string GDBStubA32::GetTargetXML() const {
<reg name="fpscr" bitsize="32" type="int" group="float" regnum="80"/>
</feature>
</target>)";
return target_xml;
}
std::string GDBStubA32::RegRead(const Kernel::KThread* thread, size_t id) const {

View file

@ -16,7 +16,7 @@ namespace Core {
class GDBStubArch {
public:
virtual ~GDBStubArch() = default;
virtual std::string GetTargetXML() const = 0;
virtual std::string_view GetTargetXML() const = 0;
virtual std::string RegRead(const Kernel::KThread* thread, size_t id) const = 0;
virtual void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const = 0;
virtual std::string ReadRegisters(const Kernel::KThread* thread) const = 0;
@ -27,7 +27,7 @@ public:
class GDBStubA64 final : public GDBStubArch {
public:
std::string GetTargetXML() const override;
std::string_view GetTargetXML() const override;
std::string RegRead(const Kernel::KThread* thread, size_t id) const override;
void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override;
std::string ReadRegisters(const Kernel::KThread* thread) const override;
@ -47,7 +47,7 @@ private:
class GDBStubA32 final : public GDBStubArch {
public:
std::string GetTargetXML() const override;
std::string_view GetTargetXML() const override;
std::string RegRead(const Kernel::KThread* thread, size_t id) const override;
void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override;
std::string ReadRegisters(const Kernel::KThread* thread) const override;

View file

@ -41,12 +41,12 @@ static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
return IPSFileType::Error;
}
constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
static constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) {
return IPSFileType::IPS;
}
constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
static constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) {
return IPSFileType::IPS32;
}
@ -55,12 +55,12 @@ static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
}
static bool IsEOF(IPSFileType type, const std::vector<u8>& data) {
constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
static constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) {
return true;
}
constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
static constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin());
}

View file

@ -71,7 +71,7 @@ static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bo
}
static std::string GetCNMTName(TitleType type, u64 title_id) {
constexpr std::array<const char*, 9> TITLE_TYPE_NAMES{
static constexpr std::array<const char*, 9> TITLE_TYPE_NAMES{
"SystemProgram",
"SystemData",
"SystemUpdate",

View file

@ -172,7 +172,7 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
// be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
if (title_id == 0) {
title_id = system.GetCurrentProcessProgramID();
title_id = system.GetApplicationProcessProgramID();
}
}

View file

@ -23,7 +23,8 @@ void EmulatedConsole::SetTouchParams() {
// We can't use mouse as touch if native mouse is enabled
if (!Settings::values.mouse_enabled) {
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
touch_params[index++] =
Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
}
touch_params[index++] =

View file

@ -12,6 +12,7 @@
namespace Core::HID {
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
constexpr s32 HID_TRIGGER_MAX = 0x7fff;
constexpr u32 TURBO_BUTTON_DELAY = 4;
// Use a common UUID for TAS and Virtual Gamepad
constexpr Common::UUID TAS_UUID =
Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
@ -362,7 +363,17 @@ void EmulatedController::ReloadInput() {
SetMotion(callback, index);
},
});
motion_devices[index]->ForceUpdate();
// Restore motion state
auto& emulated_motion = controller.motion_values[index].emulated;
auto& motion = controller.motion_state[index];
emulated_motion.ResetRotations();
emulated_motion.ResetQuaternion();
motion.accel = emulated_motion.GetAcceleration();
motion.gyro = emulated_motion.GetGyroscope();
motion.rotation = emulated_motion.GetRotations();
motion.orientation = emulated_motion.GetOrientation();
motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity);
}
for (std::size_t index = 0; index < camera_devices.size(); ++index) {
@ -447,6 +458,7 @@ void EmulatedController::ReloadInput() {
},
});
}
turbo_button_state = 0;
}
void EmulatedController::UnloadInput() {
@ -687,6 +699,7 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
}
current_status.toggle = new_status.toggle;
current_status.turbo = new_status.turbo;
current_status.uuid = uuid;
// Update button status with current
@ -954,7 +967,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
raw_status.gyro.y.value,
raw_status.gyro.z.value,
});
emulated.SetGyroThreshold(raw_status.gyro.x.properties.threshold);
emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold);
emulated.UpdateRotation(raw_status.delta_timestamp);
emulated.UpdateOrientation(raw_status.delta_timestamp);
force_update_motion = raw_status.force_update;
@ -1281,6 +1294,26 @@ void EmulatedController::SetLedPattern() {
}
}
void EmulatedController::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode) {
for (auto& motion : controller.motion_values) {
switch (mode) {
case GyroscopeZeroDriftMode::Loose:
motion_sensitivity = motion.emulated.IsAtRestLoose;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdLoose);
break;
case GyroscopeZeroDriftMode::Tight:
motion_sensitivity = motion.emulated.IsAtRestThight;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdThight);
break;
case GyroscopeZeroDriftMode::Standard:
default:
motion_sensitivity = motion.emulated.IsAtRestStandard;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdStandard);
break;
}
}
}
void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) {
supported_style_tag = supported_styles;
if (!is_connected) {
@ -1548,7 +1581,7 @@ NpadButtonState EmulatedController::GetNpadButtons() const {
if (is_configuring) {
return {};
}
return controller.npad_button_state;
return {controller.npad_button_state.raw & GetTurboButtonMask()};
}
DebugPadButton EmulatedController::GetDebugPadButtons() const {
@ -1656,4 +1689,74 @@ void EmulatedController::DeleteCallback(int key) {
}
callback_list.erase(iterator);
}
void EmulatedController::TurboButtonUpdate() {
turbo_button_state = (turbo_button_state + 1) % (TURBO_BUTTON_DELAY * 2);
}
NpadButton EmulatedController::GetTurboButtonMask() const {
// Apply no mask when disabled
if (turbo_button_state < TURBO_BUTTON_DELAY) {
return {NpadButton::All};
}
NpadButtonState button_mask{};
for (std::size_t index = 0; index < controller.button_values.size(); ++index) {
if (!controller.button_values[index].turbo) {
continue;
}
switch (index) {
case Settings::NativeButton::A:
button_mask.a.Assign(1);
break;
case Settings::NativeButton::B:
button_mask.b.Assign(1);
break;
case Settings::NativeButton::X:
button_mask.x.Assign(1);
break;
case Settings::NativeButton::Y:
button_mask.y.Assign(1);
break;
case Settings::NativeButton::L:
button_mask.l.Assign(1);
break;
case Settings::NativeButton::R:
button_mask.r.Assign(1);
break;
case Settings::NativeButton::ZL:
button_mask.zl.Assign(1);
break;
case Settings::NativeButton::ZR:
button_mask.zr.Assign(1);
break;
case Settings::NativeButton::DLeft:
button_mask.left.Assign(1);
break;
case Settings::NativeButton::DUp:
button_mask.up.Assign(1);
break;
case Settings::NativeButton::DRight:
button_mask.right.Assign(1);
break;
case Settings::NativeButton::DDown:
button_mask.down.Assign(1);
break;
case Settings::NativeButton::SL:
button_mask.left_sl.Assign(1);
button_mask.right_sl.Assign(1);
break;
case Settings::NativeButton::SR:
button_mask.left_sr.Assign(1);
button_mask.right_sr.Assign(1);
break;
default:
break;
}
}
return static_cast<NpadButton>(~button_mask.raw);
}
} // namespace Core::HID

View file

@ -398,6 +398,9 @@ public:
/// Asks the output device to change the player led pattern
void SetLedPattern();
/// Changes sensitivity of the motion sensor
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode);
/**
* Adds a callback to the list of events
* @param update_callback A ConsoleUpdateCallback that will be triggered
@ -411,6 +414,9 @@ public:
*/
void DeleteCallback(int key);
/// Swaps the state of the turbo buttons
void TurboButtonUpdate();
private:
/// creates input devices from params
void LoadDevices();
@ -511,6 +517,8 @@ private:
*/
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
NpadButton GetTurboButtonMask() const;
const NpadIdType npad_id_type;
NpadStyleIndex npad_type{NpadStyleIndex::None};
NpadStyleIndex original_npad_type{NpadStyleIndex::None};
@ -518,8 +526,9 @@ private:
bool is_connected{false};
bool is_configuring{false};
bool system_buttons_enabled{true};
f32 motion_sensitivity{0.01f};
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
bool force_update_motion{false};
u32 turbo_button_state{0};
// Temporary values to avoid doing changes while the controller is in configuring mode
NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};

View file

@ -19,49 +19,53 @@ void EmulatedDevices::ReloadFromSettings() {
void EmulatedDevices::ReloadInput() {
// If you load any device here add the equivalent to the UnloadInput() function
// Native Mouse is mapped on port 1, pad 0
const Common::ParamPackage mouse_params{"engine:mouse,port:1,pad:0"};
// Keyboard keys is mapped on port 1, pad 0 for normal keys, pad 1 for moddifier keys
const Common::ParamPackage keyboard_params{"engine:keyboard,port:1"};
std::size_t key_index = 0;
for (auto& mouse_device : mouse_button_devices) {
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("button", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_params);
Common::ParamPackage mouse_button_params = mouse_params;
mouse_button_params.Set("button", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_button_params);
key_index++;
}
mouse_stick_device =
Common::Input::CreateInputDeviceFromString("engine:mouse,axis_x:0,axis_y:1");
Common::ParamPackage mouse_position_params = mouse_params;
mouse_position_params.Set("axis_x", 0);
mouse_position_params.Set("axis_y", 1);
mouse_position_params.Set("deadzone", 0.0f);
mouse_position_params.Set("range", 1.0f);
mouse_position_params.Set("threshold", 0.0f);
mouse_stick_device = Common::Input::CreateInputDevice(mouse_position_params);
// First two axis are reserved for mouse position
key_index = 2;
for (auto& mouse_device : mouse_analog_devices) {
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("axis", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_params);
for (auto& mouse_device : mouse_wheel_devices) {
Common::ParamPackage mouse_wheel_params = mouse_params;
mouse_wheel_params.Set("axis", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_wheel_params);
key_index++;
}
key_index = 0;
for (auto& keyboard_device : keyboard_devices) {
// Keyboard keys are only mapped on port 1, pad 0
Common::ParamPackage keyboard_params;
keyboard_params.Set("engine", "keyboard");
keyboard_params.Set("button", static_cast<int>(key_index));
keyboard_params.Set("port", 1);
keyboard_params.Set("pad", 0);
keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
Common::ParamPackage keyboard_key_params = keyboard_params;
keyboard_key_params.Set("button", static_cast<int>(key_index));
keyboard_key_params.Set("pad", 0);
keyboard_device = Common::Input::CreateInputDevice(keyboard_key_params);
key_index++;
}
key_index = 0;
for (auto& keyboard_device : keyboard_modifier_devices) {
// Keyboard moddifiers are only mapped on port 1, pad 1
Common::ParamPackage keyboard_params;
keyboard_params.Set("engine", "keyboard");
keyboard_params.Set("button", static_cast<int>(key_index));
keyboard_params.Set("port", 1);
keyboard_params.Set("pad", 1);
keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
Common::ParamPackage keyboard_moddifier_params = keyboard_params;
keyboard_moddifier_params.Set("button", static_cast<int>(key_index));
keyboard_moddifier_params.Set("pad", 1);
keyboard_device = Common::Input::CreateInputDevice(keyboard_moddifier_params);
key_index++;
}
@ -77,14 +81,14 @@ void EmulatedDevices::ReloadInput() {
});
}
for (std::size_t index = 0; index < mouse_analog_devices.size(); ++index) {
if (!mouse_analog_devices[index]) {
for (std::size_t index = 0; index < mouse_wheel_devices.size(); ++index) {
if (!mouse_wheel_devices[index]) {
continue;
}
mouse_analog_devices[index]->SetCallback({
mouse_wheel_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetMouseAnalog(callback, index);
SetMouseWheel(callback, index);
},
});
}
@ -92,7 +96,9 @@ void EmulatedDevices::ReloadInput() {
if (mouse_stick_device) {
mouse_stick_device->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetMouseStick(callback); },
[this](const Common::Input::CallbackStatus& callback) {
SetMousePosition(callback);
},
});
}
@ -125,7 +131,7 @@ void EmulatedDevices::UnloadInput() {
for (auto& button : mouse_button_devices) {
button.reset();
}
for (auto& analog : mouse_analog_devices) {
for (auto& analog : mouse_wheel_devices) {
analog.reset();
}
mouse_stick_device.reset();
@ -359,18 +365,18 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba
TriggerOnChange(DeviceTriggerType::Mouse);
}
void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= device_status.mouse_analog_values.size()) {
void EmulatedDevices::SetMouseWheel(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= device_status.mouse_wheel_values.size()) {
return;
}
std::unique_lock lock{mutex};
const auto analog_value = TransformToAnalog(callback);
device_status.mouse_analog_values[index] = analog_value;
device_status.mouse_wheel_values[index] = analog_value;
if (is_configuring) {
device_status.mouse_position_state = {};
device_status.mouse_wheel_state = {};
lock.unlock();
TriggerOnChange(DeviceTriggerType::Mouse);
return;
@ -389,7 +395,7 @@ void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callba
TriggerOnChange(DeviceTriggerType::Mouse);
}
void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callback) {
void EmulatedDevices::SetMousePosition(const Common::Input::CallbackStatus& callback) {
std::unique_lock lock{mutex};
const auto touch_value = TransformToTouch(callback);

View file

@ -23,8 +23,8 @@ using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputD
Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseButton::NumMouseButtons>;
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>;
using MouseWheelDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
using MouseButtonParams =
@ -36,7 +36,7 @@ using KeyboardModifierValues =
std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonValues =
std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
using MouseAnalogValues =
using MouseWheelValues =
std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickValue = Common::Input::TouchStatus;
@ -50,7 +50,7 @@ struct DeviceStatus {
KeyboardValues keyboard_values{};
KeyboardModifierValues keyboard_moddifier_values{};
MouseButtonValues mouse_button_values{};
MouseAnalogValues mouse_analog_values{};
MouseWheelValues mouse_wheel_values{};
MouseStickValue mouse_stick_value{};
// Data for HID serices
@ -111,15 +111,6 @@ public:
/// Reverts any mapped changes made that weren't saved
void RestoreConfig();
// Returns the current mapped ring device
Common::ParamPackage GetRingParam() const;
/**
* Updates the current mapped ring device
* @param param ParamPackage with ring sensor data to be mapped
*/
void SetRingParam(Common::ParamPackage param);
/// Returns the latest status of button input from the keyboard with parameters
KeyboardValues GetKeyboardValues() const;
@ -187,19 +178,13 @@ private:
* @param callback A CallbackStatus containing the wheel status
* @param index wheel ID to be updated
*/
void SetMouseAnalog(const Common::Input::CallbackStatus& callback, std::size_t index);
void SetMouseWheel(const Common::Input::CallbackStatus& callback, std::size_t index);
/**
* Updates the mouse position status of the mouse device
* @param callback A CallbackStatus containing the position status
*/
void SetMouseStick(const Common::Input::CallbackStatus& callback);
/**
* Updates the ring analog sensor status of the ring controller
* @param callback A CallbackStatus containing the force status
*/
void SetRingAnalog(const Common::Input::CallbackStatus& callback);
void SetMousePosition(const Common::Input::CallbackStatus& callback);
/**
* Triggers a callback that something has changed on the device status
@ -212,7 +197,7 @@ private:
KeyboardDevices keyboard_devices;
KeyboardModifierDevices keyboard_modifier_devices;
MouseButtonDevices mouse_button_devices;
MouseAnalogDevices mouse_analog_devices;
MouseWheelDevices mouse_wheel_devices;
MouseStickDevice mouse_stick_device;
mutable std::mutex mutex;

View file

@ -282,6 +282,13 @@ enum class VibrationGcErmCommand : u64 {
StopHard = 2,
};
// This is nn::hid::GyroscopeZeroDriftMode
enum class GyroscopeZeroDriftMode : u32 {
Loose = 0,
Standard = 1,
Tight = 2,
};
// This is nn::hid::NpadStyleTag
struct NpadStyleTag {
union {

View file

@ -9,7 +9,9 @@ namespace Core::HID {
MotionInput::MotionInput() {
// Initialize PID constants with default values
SetPID(0.3f, 0.005f, 0.0f);
SetGyroThreshold(0.007f);
SetGyroThreshold(ThresholdStandard);
ResetQuaternion();
ResetRotations();
}
void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
@ -20,17 +22,25 @@ void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
accel = acceleration;
accel.x = std::clamp(accel.x, -AccelMaxValue, AccelMaxValue);
accel.y = std::clamp(accel.y, -AccelMaxValue, AccelMaxValue);
accel.z = std::clamp(accel.z, -AccelMaxValue, AccelMaxValue);
}
void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
gyro = gyroscope - gyro_bias;
gyro.x = std::clamp(gyro.x, -GyroMaxValue, GyroMaxValue);
gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue);
// Auto adjust drift to minimize drift
if (!IsMoving(0.1f)) {
if (!IsMoving(IsAtRestRelaxed)) {
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
if (gyro.Length() < gyro_threshold) {
if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
gyro = {};
} else {
only_accelerometer = false;
@ -49,6 +59,10 @@ void MotionInput::SetGyroThreshold(f32 threshold) {
gyro_threshold = threshold;
}
void MotionInput::SetUserGyroThreshold(f32 threshold) {
user_gyro_threshold = threshold / ThresholdStandard;
}
void MotionInput::EnableReset(bool reset) {
reset_enabled = reset;
}
@ -57,6 +71,10 @@ void MotionInput::ResetRotations() {
rotations = {};
}
void MotionInput::ResetQuaternion() {
quat = {{0.0f, 0.0f, -1.0f}, 0.0f};
}
bool MotionInput::IsMoving(f32 sensitivity) const {
return gyro.Length() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f;
}
@ -208,7 +226,7 @@ void MotionInput::ResetOrientation() {
if (!reset_enabled || only_accelerometer) {
return;
}
if (!IsMoving(0.5f) && accel.z <= -0.9f) {
if (!IsMoving(IsAtRestRelaxed) && accel.z <= -0.9f) {
++reset_counter;
if (reset_counter > 900) {
quat.w = 0;

View file

@ -11,6 +11,18 @@ namespace Core::HID {
class MotionInput {
public:
static constexpr float ThresholdLoose = 0.01f;
static constexpr float ThresholdStandard = 0.007f;
static constexpr float ThresholdThight = 0.002f;
static constexpr float IsAtRestRelaxed = 0.05f;
static constexpr float IsAtRestLoose = 0.02f;
static constexpr float IsAtRestStandard = 0.01f;
static constexpr float IsAtRestThight = 0.005f;
static constexpr float GyroMaxValue = 5.0f;
static constexpr float AccelMaxValue = 7.0f;
explicit MotionInput();
MotionInput(const MotionInput&) = default;
@ -26,8 +38,12 @@ public:
void SetGyroBias(const Common::Vec3f& bias);
void SetGyroThreshold(f32 threshold);
/// Applies a modifier on top of the normal gyro threshold
void SetUserGyroThreshold(f32 threshold);
void EnableReset(bool reset);
void ResetRotations();
void ResetQuaternion();
void UpdateRotation(u64 elapsed_time);
void UpdateOrientation(u64 elapsed_time);
@ -57,7 +73,7 @@ private:
Common::Vec3f derivative_error;
// Quaternion containing the device orientation
Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f};
Common::Quaternion<f32> quat;
// Number of full rotations in each axis
Common::Vec3f rotations;
@ -74,6 +90,9 @@ private:
// Minimum gyro amplitude to detect if the device is moving
f32 gyro_threshold = 0.0f;
// Multiplies gyro_threshold by this value
f32 user_gyro_threshold = 0.0f;
// Number of invalid sequential data
u32 reset_counter = 0;

View file

@ -148,7 +148,7 @@ public:
if (context->GetManager()->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
kernel.CurrentProcess()->GetResourceLimit()->Reserve(
kernel.ApplicationProcess()->GetResourceLimit()->Reserve(
Kernel::LimitableResource::SessionCountMax, 1);
auto* session = Kernel::KSession::Create(kernel);

View file

@ -11,10 +11,12 @@
#include "core/hle/kernel/init/init_slab_setup.h"
#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_debug.h"
#include "core/hle/kernel/k_device_address_space.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_event_info.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_object_name.h"
#include "core/hle/kernel/k_page_buffer.h"
#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/k_process.h"
@ -43,10 +45,12 @@ namespace Kernel::Init {
HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ##__VA_ARGS__) \
HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \
HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ##__VA_ARGS__) \
HANDLER(KDeviceAddressSpace, (SLAB_COUNT(KDeviceAddressSpace)), ##__VA_ARGS__) \
HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) \
HANDLER(KThreadLocalPage, \
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
##__VA_ARGS__) \
HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ##__VA_ARGS__) \
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \

View file

@ -203,23 +203,23 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) {
Result KCapabilities::MapRegion_(const u32 cap, KPageTable* page_table) {
// Map each region into the process's page table.
R_RETURN(ProcessMapRegionCapability(
return ProcessMapRegionCapability(
cap, [](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
// R_RETURN(page_table->MapRegion(region_type, perm));
UNIMPLEMENTED();
R_SUCCEED();
}));
});
}
Result KCapabilities::CheckMapRegion(KernelCore& kernel, const u32 cap) {
// Check that each region has a physical backing store.
R_RETURN(ProcessMapRegionCapability(
return ProcessMapRegionCapability(
cap, [&](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
R_UNLESS(kernel.MemoryLayout().GetPhysicalMemoryRegionTree().FindFirstDerived(
region_type) != nullptr,
ResultOutOfRange);
R_SUCCEED();
}));
});
}
Result KCapabilities::SetInterruptPairCapability(const u32 cap) {

View file

@ -60,7 +60,8 @@ bool KClientPort::IsSignaled() const {
Result KClientPort::CreateSession(KClientSession** out) {
// Reserve a new session from the resource limit.
KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
//! FIXME: we are reserving this from the wrong resource limit!
KScopedResourceReservation session_reservation(kernel.ApplicationProcess()->GetResourceLimit(),
LimitableResource::SessionCountMax);
R_UNLESS(session_reservation.Succeeded(), ResultLimitReached);

View file

@ -21,7 +21,7 @@ KCodeMemory::KCodeMemory(KernelCore& kernel_)
Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) {
// Set members.
m_owner = kernel.CurrentProcess();
m_owner = GetCurrentProcessPointer(kernel);
// Get the owner page table.
auto& page_table = m_owner->PageTable();
@ -74,7 +74,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
R_UNLESS(!m_is_mapped, ResultInvalidState);
// Map the memory.
R_TRY(kernel.CurrentProcess()->PageTable().MapPageGroup(
R_TRY(GetCurrentProcess(kernel).PageTable().MapPageGroup(
address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
// Mark ourselves as mapped.
@ -91,8 +91,8 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) {
KScopedLightLock lk(m_lock);
// Unmap the memory.
R_TRY(kernel.CurrentProcess()->PageTable().UnmapPageGroup(address, *m_page_group,
KMemoryState::CodeOut));
R_TRY(GetCurrentProcess(kernel).PageTable().UnmapPageGroup(address, *m_page_group,
KMemoryState::CodeOut));
// Mark ourselves as unmapped.
m_is_mapped = false;

View file

@ -164,8 +164,8 @@ Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value)
R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask));
// Get the lock owner thread.
owner_thread = kernel.CurrentProcess()
->GetHandleTable()
owner_thread = GetCurrentProcess(kernel)
.GetHandleTable()
.GetObjectWithoutPseudoHandle<KThread>(handle)
.ReleasePointerUnsafe();
R_UNLESS(owner_thread != nullptr, ResultInvalidHandle);
@ -213,8 +213,8 @@ void KConditionVariable::SignalImpl(KThread* thread) {
thread->EndWait(ResultSuccess);
} else {
// Get the previous owner.
KThread* owner_thread = kernel.CurrentProcess()
->GetHandleTable()
KThread* owner_thread = GetCurrentProcess(kernel)
.GetHandleTable()
.GetObjectWithoutPseudoHandle<KThread>(
static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
.ReleasePointerUnsafe();

View file

@ -0,0 +1,150 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h"
#include "core/core.h"
#include "core/hle/kernel/k_device_address_space.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel {
KDeviceAddressSpace::KDeviceAddressSpace(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer(kernel_), m_lock(kernel_), m_is_initialized(false) {}
KDeviceAddressSpace::~KDeviceAddressSpace() = default;
void KDeviceAddressSpace::Initialize() {
// This just forwards to the device page table manager.
// KDevicePageTable::Initialize();
}
// Member functions.
Result KDeviceAddressSpace::Initialize(u64 address, u64 size) {
// Initialize the device page table.
// R_TRY(m_table.Initialize(address, size));
// Set member variables.
m_space_address = address;
m_space_size = size;
m_is_initialized = true;
R_SUCCEED();
}
void KDeviceAddressSpace::Finalize() {
// Finalize the table.
// m_table.Finalize();
}
Result KDeviceAddressSpace::Attach(Svc::DeviceName device_name) {
// Lock the address space.
KScopedLightLock lk(m_lock);
// Attach.
// R_RETURN(m_table.Attach(device_name, m_space_address, m_space_size));
R_SUCCEED();
}
Result KDeviceAddressSpace::Detach(Svc::DeviceName device_name) {
// Lock the address space.
KScopedLightLock lk(m_lock);
// Detach.
// R_RETURN(m_table.Detach(device_name));
R_SUCCEED();
}
Result KDeviceAddressSpace::Map(KPageTable* page_table, VAddr process_address, size_t size,
u64 device_address, u32 option, bool is_aligned) {
// Check that the address falls within the space.
R_UNLESS((m_space_address <= device_address &&
device_address + size - 1 <= m_space_address + m_space_size - 1),
ResultInvalidCurrentMemory);
// Decode the option.
const Svc::MapDeviceAddressSpaceOption option_pack{option};
const auto device_perm = option_pack.permission.Value();
const auto flags = option_pack.flags.Value();
const auto reserved = option_pack.reserved.Value();
// Validate the option.
// TODO: It is likely that this check for flags == none is only on NX board.
R_UNLESS(flags == Svc::MapDeviceAddressSpaceFlag::None, ResultInvalidEnumValue);
R_UNLESS(reserved == 0, ResultInvalidEnumValue);
// Lock the address space.
KScopedLightLock lk(m_lock);
// Lock the page table to prevent concurrent device mapping operations.
// KScopedLightLock pt_lk = page_table->AcquireDeviceMapLock();
// Lock the pages.
bool is_io{};
R_TRY(page_table->LockForMapDeviceAddressSpace(std::addressof(is_io), process_address, size,
ConvertToKMemoryPermission(device_perm),
is_aligned, true));
// Ensure that if we fail, we don't keep unmapped pages locked.
ON_RESULT_FAILURE {
ASSERT(page_table->UnlockForDeviceAddressSpace(process_address, size) == ResultSuccess);
};
// Check that the io status is allowable.
if (is_io) {
R_UNLESS(static_cast<u32>(flags & Svc::MapDeviceAddressSpaceFlag::NotIoRegister) == 0,
ResultInvalidCombination);
}
// Map the pages.
{
// Perform the mapping.
// R_TRY(m_table.Map(page_table, process_address, size, device_address, device_perm,
// is_aligned, is_io));
// Ensure that we unmap the pages if we fail to update the protections.
// NOTE: Nintendo does not check the result of this unmap call.
// ON_RESULT_FAILURE { m_table.Unmap(device_address, size); };
// Update the protections in accordance with how much we mapped.
// R_TRY(page_table->UnlockForDeviceAddressSpacePartialMap(process_address, size));
}
// We succeeded.
R_SUCCEED();
}
Result KDeviceAddressSpace::Unmap(KPageTable* page_table, VAddr process_address, size_t size,
u64 device_address) {
// Check that the address falls within the space.
R_UNLESS((m_space_address <= device_address &&
device_address + size - 1 <= m_space_address + m_space_size - 1),
ResultInvalidCurrentMemory);
// Lock the address space.
KScopedLightLock lk(m_lock);
// Lock the page table to prevent concurrent device mapping operations.
// KScopedLightLock pt_lk = page_table->AcquireDeviceMapLock();
// Lock the pages.
R_TRY(page_table->LockForUnmapDeviceAddressSpace(process_address, size, true));
// Unmap the pages.
{
// If we fail to unmap, we want to do a partial unlock.
// ON_RESULT_FAILURE {
// ASSERT(page_table->UnlockForDeviceAddressSpacePartialMap(process_address, size) ==
// ResultSuccess);
// };
// Perform the unmap.
// R_TRY(m_table.Unmap(page_table, process_address, size, device_address));
}
// Unlock the pages.
ASSERT(page_table->UnlockForDeviceAddressSpace(process_address, size) == ResultSuccess);
R_SUCCEED();
}
} // namespace Kernel

View file

@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <string>
#include "common/common_types.h"
#include "core/hle/kernel/k_page_table.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/result.h"
namespace Kernel {
class KDeviceAddressSpace final
: public KAutoObjectWithSlabHeapAndContainer<KDeviceAddressSpace, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KDeviceAddressSpace, KAutoObject);
public:
explicit KDeviceAddressSpace(KernelCore& kernel);
~KDeviceAddressSpace();
Result Initialize(u64 address, u64 size);
void Finalize();
bool IsInitialized() const {
return m_is_initialized;
}
static void PostDestroy(uintptr_t arg) {}
Result Attach(Svc::DeviceName device_name);
Result Detach(Svc::DeviceName device_name);
Result MapByForce(KPageTable* page_table, VAddr process_address, size_t size,
u64 device_address, u32 option) {
R_RETURN(this->Map(page_table, process_address, size, device_address, option, false));
}
Result MapAligned(KPageTable* page_table, VAddr process_address, size_t size,
u64 device_address, u32 option) {
R_RETURN(this->Map(page_table, process_address, size, device_address, option, true));
}
Result Unmap(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address);
static void Initialize();
private:
Result Map(KPageTable* page_table, VAddr process_address, size_t size, u64 device_address,
u32 option, bool is_aligned);
private:
KLightLock m_lock;
// KDevicePageTable m_table;
u64 m_space_address{};
u64 m_space_size{};
bool m_is_initialized{};
};
} // namespace Kernel

View file

@ -90,7 +90,8 @@ public:
// Handle pseudo-handles.
if constexpr (std::derived_from<KProcess, T>) {
if (handle == Svc::PseudoHandle::CurrentProcess) {
auto* const cur_process = m_kernel.CurrentProcess();
//! FIXME: this is the wrong process!
auto* const cur_process = m_kernel.ApplicationProcess();
ASSERT(cur_process != nullptr);
return cur_process;
}

View file

@ -16,7 +16,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) {
auto& current_thread = GetCurrentThread(kernel);
if (auto* process = kernel.CurrentProcess(); process) {
if (auto* process = GetCurrentProcessPointer(kernel); process) {
// If the user disable count is set, we may need to pin the current thread.
if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) {
KScopedSchedulerLock sl{kernel};

View file

@ -0,0 +1,102 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/k_object_name.h"
namespace Kernel {
KObjectNameGlobalData::KObjectNameGlobalData(KernelCore& kernel) : m_object_list_lock{kernel} {}
KObjectNameGlobalData::~KObjectNameGlobalData() = default;
void KObjectName::Initialize(KAutoObject* obj, const char* name) {
// Set member variables.
m_object = obj;
std::strncpy(m_name.data(), name, sizeof(m_name) - 1);
m_name[sizeof(m_name) - 1] = '\x00';
// Open a reference to the object we hold.
m_object->Open();
}
bool KObjectName::MatchesName(const char* name) const {
return std::strncmp(m_name.data(), name, sizeof(m_name)) == 0;
}
Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name) {
// Create a new object name.
KObjectName* new_name = KObjectName::Allocate(kernel);
R_UNLESS(new_name != nullptr, ResultOutOfResource);
// Initialize the new name.
new_name->Initialize(obj, name);
// Check if there's an existing name.
{
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Ensure we have exclusive access to the global list.
KScopedLightLock lk{gd.GetObjectListLock()};
// If the object doesn't exist, put it into the list.
KScopedAutoObject existing_object = FindImpl(kernel, name);
if (existing_object.IsNull()) {
gd.GetObjectList().push_back(*new_name);
R_SUCCEED();
}
}
// The object already exists, which is an error condition. Perform cleanup.
obj->Close();
KObjectName::Free(kernel, new_name);
R_THROW(ResultInvalidState);
}
Result KObjectName::Delete(KernelCore& kernel, KAutoObject* obj, const char* compare_name) {
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Ensure we have exclusive access to the global list.
KScopedLightLock lk{gd.GetObjectListLock()};
// Find a matching entry in the list, and delete it.
for (auto& name : gd.GetObjectList()) {
if (name.MatchesName(compare_name) && obj == name.GetObject()) {
// We found a match, clean up its resources.
obj->Close();
gd.GetObjectList().erase(gd.GetObjectList().iterator_to(name));
KObjectName::Free(kernel, std::addressof(name));
R_SUCCEED();
}
}
// We didn't find the object in the list.
R_THROW(ResultNotFound);
}
KScopedAutoObject<KAutoObject> KObjectName::Find(KernelCore& kernel, const char* name) {
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Ensure we have exclusive access to the global list.
KScopedLightLock lk{gd.GetObjectListLock()};
return FindImpl(kernel, name);
}
KScopedAutoObject<KAutoObject> KObjectName::FindImpl(KernelCore& kernel, const char* compare_name) {
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Try to find a matching object in the global list.
for (const auto& name : gd.GetObjectList()) {
if (name.MatchesName(compare_name)) {
return name.GetObject();
}
}
// There's no matching entry in the list.
return nullptr;
}
} // namespace Kernel

View file

@ -0,0 +1,86 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <memory>
#include <boost/intrusive/list.hpp>
#include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel {
class KObjectNameGlobalData;
class KObjectName : public KSlabAllocated<KObjectName>, public boost::intrusive::list_base_hook<> {
public:
explicit KObjectName(KernelCore&) {}
virtual ~KObjectName() = default;
static constexpr size_t NameLengthMax = 12;
using List = boost::intrusive::list<KObjectName>;
static Result NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name);
static Result Delete(KernelCore& kernel, KAutoObject* obj, const char* name);
static KScopedAutoObject<KAutoObject> Find(KernelCore& kernel, const char* name);
template <typename Derived>
static Result Delete(KernelCore& kernel, const char* name) {
// Find the object.
KScopedAutoObject obj = Find(kernel, name);
R_UNLESS(obj.IsNotNull(), ResultNotFound);
// Cast the object to the desired type.
Derived* derived = obj->DynamicCast<Derived*>();
R_UNLESS(derived != nullptr, ResultNotFound);
// Check that the object is closed.
R_UNLESS(derived->IsServerClosed(), ResultInvalidState);
return Delete(kernel, obj.GetPointerUnsafe(), name);
}
template <typename Derived>
requires(std::derived_from<Derived, KAutoObject>)
static KScopedAutoObject<Derived> Find(KernelCore& kernel, const char* name) {
return Find(kernel, name);
}
private:
static KScopedAutoObject<KAutoObject> FindImpl(KernelCore& kernel, const char* name);
void Initialize(KAutoObject* obj, const char* name);
bool MatchesName(const char* name) const;
KAutoObject* GetObject() const {
return m_object;
}
private:
std::array<char, NameLengthMax> m_name{};
KAutoObject* m_object{};
};
class KObjectNameGlobalData {
public:
explicit KObjectNameGlobalData(KernelCore& kernel);
~KObjectNameGlobalData();
KLightLock& GetObjectListLock() {
return m_object_list_lock;
}
KObjectName::List& GetObjectList() {
return m_object_list;
}
private:
KLightLock m_object_list_lock;
KObjectName::List m_object_list;
};
} // namespace Kernel

View file

@ -370,7 +370,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
// Initialize proces address space
if (const Result result{page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
0x8000000, code_size, &kernel.GetSystemSystemResource(), resource_limit)};
0x8000000, code_size, &kernel.GetAppSystemResource(), resource_limit)};
result.IsError()) {
R_RETURN(result);
}

View file

@ -328,7 +328,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
}
void KScheduler::SwitchThread(KThread* next_thread) {
KProcess* const cur_process = kernel.CurrentProcess();
KProcess* const cur_process = GetCurrentProcessPointer(kernel);
KThread* const cur_thread = GetCurrentThreadPointer(kernel);
// 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
void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
// Validate preconditions.
ASSERT(CanSchedule(kernel));
ASSERT(kernel.CurrentProcess() != nullptr);
ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
// Get the current thread and process.
KThread& cur_thread = GetCurrentThread(kernel);
KProcess& cur_process = *kernel.CurrentProcess();
KProcess& cur_process = GetCurrentProcess(kernel);
// If the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@ -728,11 +728,11 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
// Validate preconditions.
ASSERT(CanSchedule(kernel));
ASSERT(kernel.CurrentProcess() != nullptr);
ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
// Get the current thread and process.
KThread& cur_thread = GetCurrentThread(kernel);
KProcess& cur_process = *kernel.CurrentProcess();
KProcess& cur_process = GetCurrentProcess(kernel);
// If the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@ -816,11 +816,11 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
void KScheduler::YieldToAnyThread(KernelCore& kernel) {
// Validate preconditions.
ASSERT(CanSchedule(kernel));
ASSERT(kernel.CurrentProcess() != nullptr);
ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
// Get the current thread and process.
KThread& cur_thread = GetCurrentThread(kernel);
KProcess& cur_process = *kernel.CurrentProcess();
KProcess& cur_process = GetCurrentProcess(kernel);
// If the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {

View file

@ -33,7 +33,8 @@ void KSession::Initialize(KClientPort* port_, const std::string& name_) {
name = name_;
// Set our owner process.
process = kernel.CurrentProcess();
//! FIXME: this is the wrong process!
process = kernel.ApplicationProcess();
process->Open();
// Set our port.

View file

@ -1266,6 +1266,14 @@ KThread& GetCurrentThread(KernelCore& kernel) {
return *GetCurrentThreadPointer(kernel);
}
KProcess* GetCurrentProcessPointer(KernelCore& kernel) {
return GetCurrentThread(kernel).GetOwnerProcess();
}
KProcess& GetCurrentProcess(KernelCore& kernel) {
return *GetCurrentProcessPointer(kernel);
}
s32 GetCurrentCoreId(KernelCore& kernel) {
return GetCurrentThread(kernel).GetCurrentCore();
}

View file

@ -110,6 +110,8 @@ enum class StepState : u32 {
void SetCurrentThread(KernelCore& kernel, KThread* thread);
[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel);
[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
[[nodiscard]] KProcess* GetCurrentProcessPointer(KernelCore& kernel);
[[nodiscard]] KProcess& GetCurrentProcess(KernelCore& kernel);
[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>,

View file

@ -16,7 +16,7 @@ KTransferMemory::~KTransferMemory() = default;
Result KTransferMemory::Initialize(VAddr address_, std::size_t size_,
Svc::MemoryPermission owner_perm_) {
// Set members.
owner = kernel.CurrentProcess();
owner = GetCurrentProcessPointer(kernel);
// TODO(bunnei): Lock for transfer memory

View file

@ -29,6 +29,7 @@
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_object_name.h"
#include "core/hle/kernel/k_page_buffer.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
@ -84,6 +85,7 @@ struct KernelCore::Impl {
InitializeShutdownThreads();
InitializePhysicalCores();
InitializePreemption(kernel);
InitializeGlobalData(kernel);
// Initialize the Dynamic Slab Heaps.
{
@ -102,13 +104,13 @@ struct KernelCore::Impl {
void InitializeCores() {
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
cores[core_id]->Initialize((*current_process).Is64BitProcess());
system.Memory().SetCurrentPageTable(*current_process, core_id);
cores[core_id]->Initialize((*application_process).Is64BitProcess());
system.Memory().SetCurrentPageTable(*application_process, core_id);
}
}
void CloseCurrentProcess() {
KProcess* old_process = current_process.exchange(nullptr);
void CloseApplicationProcess() {
KProcess* old_process = application_process.exchange(nullptr);
if (old_process == nullptr) {
return;
}
@ -182,7 +184,7 @@ struct KernelCore::Impl {
}
}
CloseCurrentProcess();
CloseApplicationProcess();
// Track kernel objects that were not freed on shutdown
{
@ -194,6 +196,8 @@ struct KernelCore::Impl {
}
}
object_name_global_data.reset();
// Ensure that the object list container is finalized and properly shutdown.
global_object_list_container->Finalize();
global_object_list_container.reset();
@ -363,27 +367,29 @@ struct KernelCore::Impl {
}
}
void MakeCurrentProcess(KProcess* process) {
current_process = process;
void InitializeGlobalData(KernelCore& kernel) {
object_name_global_data = std::make_unique<KObjectNameGlobalData>(kernel);
}
static inline thread_local u32 host_thread_id = UINT32_MAX;
void MakeApplicationProcess(KProcess* process) {
application_process = process;
}
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
u32 GetHostThreadId(std::size_t core_id) {
if (host_thread_id == UINT32_MAX) {
// The first four slots are reserved for CPU core threads
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u32>(core_id);
}
static inline thread_local u8 host_thread_id = UINT8_MAX;
/// Sets the host thread ID for the caller.
u32 SetHostThreadId(std::size_t core_id) {
// This should only be called during core init.
ASSERT(host_thread_id == UINT8_MAX);
// The first four slots are reserved for CPU core threads
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u8>(core_id);
return host_thread_id;
}
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
u32 GetHostThreadId() {
if (host_thread_id == UINT32_MAX) {
host_thread_id = next_host_thread_id++;
}
/// Gets the host thread ID for the caller
u32 GetHostThreadId() const {
return host_thread_id;
}
@ -391,23 +397,19 @@ struct KernelCore::Impl {
KThread* GetHostDummyThread(KThread* existing_thread) {
auto initialize = [this](KThread* thread) {
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId()));
thread->SetName(fmt::format("DummyThread:{}", next_host_thread_id++));
return thread;
};
thread_local KThread raw_thread{system.Kernel()};
thread_local KThread* thread = nullptr;
if (thread == nullptr) {
thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread;
}
thread_local KThread* thread = existing_thread ? existing_thread : initialize(&raw_thread);
return thread;
}
/// Registers a CPU core thread by allocating a host thread ID for it
void RegisterCoreThread(std::size_t core_id) {
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
const auto this_id = GetHostThreadId(core_id);
const auto this_id = SetHostThreadId(core_id);
if (!is_multicore) {
single_core_thread_id = this_id;
}
@ -415,7 +417,6 @@ struct KernelCore::Impl {
/// Registers a new host thread by allocating a host thread ID for it
void RegisterHostThread(KThread* existing_thread) {
[[maybe_unused]] const auto this_id = GetHostThreadId();
[[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread);
}
@ -445,11 +446,9 @@ struct KernelCore::Impl {
static inline thread_local KThread* current_thread{nullptr};
KThread* GetCurrentEmuThread() {
const auto thread_id = GetCurrentHostThreadID();
if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
return GetHostDummyThread(nullptr);
if (!current_thread) {
current_thread = GetHostDummyThread(nullptr);
}
return current_thread;
}
@ -821,7 +820,7 @@ struct KernelCore::Impl {
// Lists all processes that exist in the current session.
std::vector<KProcess*> process_list;
std::atomic<KProcess*> current_process{};
std::atomic<KProcess*> application_process{};
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
std::unique_ptr<Kernel::KHardwareTimer> hardware_timer;
@ -838,6 +837,8 @@ struct KernelCore::Impl {
std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container;
std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
/// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC.
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
@ -941,20 +942,20 @@ void KernelCore::AppendNewProcess(KProcess* process) {
impl->process_list.push_back(process);
}
void KernelCore::MakeCurrentProcess(KProcess* process) {
impl->MakeCurrentProcess(process);
void KernelCore::MakeApplicationProcess(KProcess* process) {
impl->MakeApplicationProcess(process);
}
KProcess* KernelCore::CurrentProcess() {
return impl->current_process;
KProcess* KernelCore::ApplicationProcess() {
return impl->application_process;
}
const KProcess* KernelCore::CurrentProcess() const {
return impl->current_process;
const KProcess* KernelCore::ApplicationProcess() const {
return impl->application_process;
}
void KernelCore::CloseCurrentProcess() {
impl->CloseCurrentProcess();
void KernelCore::CloseApplicationProcess() {
impl->CloseApplicationProcess();
}
const std::vector<KProcess*>& KernelCore::GetProcessList() const {
@ -1002,7 +1003,7 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
}
Kernel::KScheduler* KernelCore::CurrentScheduler() {
u32 core_id = impl->GetCurrentHostThreadID();
const u32 core_id = impl->GetCurrentHostThreadID();
if (core_id >= Core::Hardware::NUM_CPU_CORES) {
// This is expected when called from not a guest thread
return {};
@ -1138,6 +1139,10 @@ void KernelCore::SetCurrentEmuThread(KThread* thread) {
impl->SetCurrentEmuThread(thread);
}
KObjectNameGlobalData& KernelCore::ObjectNameGlobalData() {
return *impl->object_name_global_data;
}
KMemoryManager& KernelCore::MemoryManager() {
return *impl->memory_manager;
}
@ -1146,6 +1151,14 @@ const KMemoryManager& KernelCore::MemoryManager() const {
return *impl->memory_manager;
}
KSystemResource& KernelCore::GetAppSystemResource() {
return *impl->app_system_resource;
}
const KSystemResource& KernelCore::GetAppSystemResource() const {
return *impl->app_system_resource;
}
KSystemResource& KernelCore::GetSystemSystemResource() {
return *impl->sys_system_resource;
}
@ -1194,12 +1207,12 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const {
return *impl->hidbus_shared_mem;
}
void KernelCore::Suspend(bool suspended) {
void KernelCore::SuspendApplication(bool suspended) {
const bool should_suspend{exception_exited || suspended};
const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
//! This refers to the application process, not the current process.
KScopedAutoObject<KProcess> process = CurrentProcess();
// Get the application process.
KScopedAutoObject<KProcess> process = ApplicationProcess();
if (process.IsNull()) {
return;
}
@ -1210,8 +1223,8 @@ void KernelCore::Suspend(bool suspended) {
// Wait for process execution to stop.
bool must_wait{should_suspend};
// KernelCore::Suspend must be called from locked context, or we
// could race another call to SetActivity, interfering with waiting.
// KernelCore::SuspendApplication must be called from locked context,
// or we could race another call to SetActivity, interfering with waiting.
while (must_wait) {
KScopedSchedulerLock sl{*this};
@ -1245,9 +1258,9 @@ bool KernelCore::IsShuttingDown() const {
return impl->IsShuttingDown();
}
void KernelCore::ExceptionalExit() {
void KernelCore::ExceptionalExitApplication() {
exception_exited = true;
Suspend(true);
SuspendApplication(true);
}
void KernelCore::EnterSVCProfile() {

View file

@ -35,6 +35,7 @@ class GlobalSchedulerContext;
class KAutoObjectWithListContainer;
class KClientSession;
class KDebug;
class KDeviceAddressSpace;
class KDynamicPageManager;
class KEvent;
class KEventInfo;
@ -43,6 +44,8 @@ class KHardwareTimer;
class KLinkedListNode;
class KMemoryLayout;
class KMemoryManager;
class KObjectName;
class KObjectNameGlobalData;
class KPageBuffer;
class KPageBufferSlabHeap;
class KPort;
@ -130,17 +133,17 @@ public:
/// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(KProcess* process);
/// Makes the given process the new current process.
void MakeCurrentProcess(KProcess* process);
/// Makes the given process the new application process.
void MakeApplicationProcess(KProcess* process);
/// Retrieves a pointer to the current process.
KProcess* CurrentProcess();
/// Retrieves a pointer to the application process.
KProcess* ApplicationProcess();
/// Retrieves a const pointer to the current process.
const KProcess* CurrentProcess() const;
/// Retrieves a const pointer to the application process.
const KProcess* ApplicationProcess() const;
/// Closes the current process.
void CloseCurrentProcess();
/// Closes the application process.
void CloseApplicationProcess();
/// Retrieves the list of processes.
const std::vector<KProcess*>& GetProcessList() const;
@ -239,12 +242,21 @@ public:
/// Register the current thread as a non CPU core thread.
void RegisterHostThread(KThread* existing_thread = nullptr);
/// Gets global data for KObjectName.
KObjectNameGlobalData& ObjectNameGlobalData();
/// Gets the virtual memory manager for the kernel.
KMemoryManager& MemoryManager();
/// Gets the virtual memory manager for the kernel.
const KMemoryManager& MemoryManager() const;
/// Gets the application resource manager.
KSystemResource& GetAppSystemResource();
/// Gets the application resource manager.
const KSystemResource& GetAppSystemResource() const;
/// Gets the system resource manager.
KSystemResource& GetSystemSystemResource();
@ -281,11 +293,11 @@ public:
/// Gets the shared memory object for HIDBus services.
const Kernel::KSharedMemory& GetHidBusSharedMem() const;
/// Suspend/unsuspend all processes.
void Suspend(bool suspend);
/// Suspend/unsuspend application process.
void SuspendApplication(bool suspend);
/// Exceptional exit all processes.
void ExceptionalExit();
/// Exceptional exit application process.
void ExceptionalExitApplication();
/// Notify emulated CPU cores to shut down.
void ShutdownCores();
@ -359,10 +371,14 @@ public:
return slab_heap_container->transfer_memory;
} else if constexpr (std::is_same_v<T, KCodeMemory>) {
return slab_heap_container->code_memory;
} else if constexpr (std::is_same_v<T, KDeviceAddressSpace>) {
return slab_heap_container->device_address_space;
} else if constexpr (std::is_same_v<T, KPageBuffer>) {
return slab_heap_container->page_buffer;
} else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
return slab_heap_container->thread_local_page;
} else if constexpr (std::is_same_v<T, KObjectName>) {
return slab_heap_container->object_name;
} else if constexpr (std::is_same_v<T, KSessionRequest>) {
return slab_heap_container->session_request;
} else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
@ -431,8 +447,10 @@ private:
KSlabHeap<KThread> thread;
KSlabHeap<KTransferMemory> transfer_memory;
KSlabHeap<KCodeMemory> code_memory;
KSlabHeap<KDeviceAddressSpace> device_address_space;
KSlabHeap<KPageBuffer> page_buffer;
KSlabHeap<KThreadLocalPage> thread_local_page;
KSlabHeap<KObjectName> object_name;
KSlabHeap<KSessionRequest> session_request;
KSlabHeap<KSecureSystemResource> secure_system_resource;
KSlabHeap<KEventInfo> event_info;

View file

@ -3,6 +3,7 @@
#pragma once
#include <condition_variable>
#include <cstddef>
#include <memory>
#include <mutex>

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,536 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// This file is automatically generated using svc_generator.py.
#include "common/common_types.h"
#pragma once
namespace Core {
class System;
}
#include "common/common_types.h"
#include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h"
namespace Kernel::Svc {
void Call(Core::System& system, u32 immediate);
// clang-format off
Result SetHeapSize(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
Result MapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
void ExitProcess(Core::System& system);
Result CreateThread(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread(Core::System& system, Handle thread_handle);
void ExitThread(Core::System& system);
void SleepThread(Core::System& system, int64_t ns);
Result GetThreadPriority(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber(Core::System& system);
Result SignalEvent(Core::System& system, Handle event_handle);
Result ClearEvent(Core::System& system, Handle event_handle);
Result MapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
Result CreateTransferMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result CloseHandle(Core::System& system, Handle handle);
Result ResetSignal(Core::System& system, Handle handle);
Result WaitSynchronization(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization(Core::System& system, Handle handle);
Result ArbitrateLock(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
Result ArbitrateUnlock(Core::System& system, uint64_t address);
Result WaitProcessWideKeyAtomic(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey(Core::System& system, uint64_t cv_key, int32_t count);
int64_t GetSystemTick(Core::System& system);
Result ConnectToNamedPort(Core::System& system, Handle* out_handle, uint64_t name);
Result SendSyncRequest(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result GetProcessId(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
Result OutputDebugString(Core::System& system, uint64_t debug_str, uint64_t len);
void ReturnFromException(Core::System& system, Result result);
Result GetInfo(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache(Core::System& system);
Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size);
Result MapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext3(Core::System& system, uint64_t out_context, Handle thread_handle);
Result WaitForAddress(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState(Core::System& system);
Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
Result AcceptSession(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result 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);
Result CreateEvent(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
Result UnmapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
Result SetUnsafeLimit(Core::System& system, uint64_t limit);
Result CreateCodeMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem(Core::System& system);
Result ReadWriteRegister(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
Result CreateInterruptEvent(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
Result CreateDeviceAddressSpace(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess(Core::System& system, Handle debug_handle);
Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle);
Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
Result GetProcessList(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
Result GetThreadList(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result UnmapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess(Core::System& system, Handle process_handle);
Result GetProcessInfo(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
Result SetHeapSize64From32(Core::System& system, uint64_t* out_address, uint32_t size);
Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, MemoryPermission perm);
Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, uint32_t mask, uint32_t attr);
Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, uint32_t address);
void ExitProcess64From32(Core::System& system);
Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg, uint32_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread64From32(Core::System& system, Handle thread_handle);
void ExitThread64From32(Core::System& system);
void SleepThread64From32(Core::System& system, int64_t ns);
Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber64From32(Core::System& system);
Result SignalEvent64From32(Core::System& system, Handle event_handle);
Result ClearEvent64From32(Core::System& system, Handle event_handle);
Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size);
Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
Result CloseHandle64From32(Core::System& system, Handle handle);
Result ResetSignal64From32(Core::System& system, Handle handle);
Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization64From32(Core::System& system, Handle handle);
Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address, uint32_t tag);
Result ArbitrateUnlock64From32(Core::System& system, uint32_t address);
Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count);
int64_t GetSystemTick64From32(Core::System& system);
Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name);
Result SendSyncRequest64From32(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size);
Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len);
void ReturnFromException64From32(Core::System& system, Result result);
Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache64From32(Core::System& system);
Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size);
Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle);
Result WaitForAddress64From32(Core::System& system, uint32_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress64From32(Core::System& system, uint32_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState64From32(Core::System& system);
Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint32_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint32_t name);
Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result 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);
Result CreateEvent64From32(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size, MemoryPermission perm);
Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size);
Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit);
Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size);
Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem64From32(Core::System& system);
Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity64From32(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size);
Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, uint32_t address);
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint32_t size);
Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address);
Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle);
Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle);
Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags, uint32_t thread_ids, int32_t num_thread_ids);
Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes, uint32_t out_process_ids, int32_t max_out_count);
Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads, uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id, uint32_t context, uint32_t context_flags);
Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint32_t address);
Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle, uint32_t address, uint32_t size);
Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer, uint32_t address, uint32_t size);
Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort64From32(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint32_t name);
Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name, int32_t max_sessions);
Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters, uint32_t caps, int32_t num_caps);
Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess64From32(Core::System& system, Handle process_handle);
Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
void ExitProcess64(Core::System& system);
Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread64(Core::System& system, Handle thread_handle);
void ExitThread64(Core::System& system);
void SleepThread64(Core::System& system, int64_t ns);
Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber64(Core::System& system);
Result SignalEvent64(Core::System& system, Handle event_handle);
Result ClearEvent64(Core::System& system, Handle event_handle);
Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result CloseHandle64(Core::System& system, Handle handle);
Result ResetSignal64(Core::System& system, Handle handle);
Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization64(Core::System& system, Handle handle);
Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
Result ArbitrateUnlock64(Core::System& system, uint64_t address);
Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count);
int64_t GetSystemTick64(Core::System& system);
Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name);
Result SendSyncRequest64(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len);
void ReturnFromException64(Core::System& system, Result result);
Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache64(Core::System& system);
Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size);
Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle);
Result WaitForAddress64(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress64(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState64(Core::System& system);
Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession64(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result 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);
Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
Result SetUnsafeLimit64(Core::System& system, uint64_t limit);
Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem64(Core::System& system);
Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity64(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess64(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess64(Core::System& system, Handle debug_handle);
Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle);
Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess64(Core::System& system, Handle process_handle);
Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit64(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
enum class SvcId : u32 {
SetHeapSize = 0x1,
SetMemoryPermission = 0x2,
SetMemoryAttribute = 0x3,
MapMemory = 0x4,
UnmapMemory = 0x5,
QueryMemory = 0x6,
ExitProcess = 0x7,
CreateThread = 0x8,
StartThread = 0x9,
ExitThread = 0xa,
SleepThread = 0xb,
GetThreadPriority = 0xc,
SetThreadPriority = 0xd,
GetThreadCoreMask = 0xe,
SetThreadCoreMask = 0xf,
GetCurrentProcessorNumber = 0x10,
SignalEvent = 0x11,
ClearEvent = 0x12,
MapSharedMemory = 0x13,
UnmapSharedMemory = 0x14,
CreateTransferMemory = 0x15,
CloseHandle = 0x16,
ResetSignal = 0x17,
WaitSynchronization = 0x18,
CancelSynchronization = 0x19,
ArbitrateLock = 0x1a,
ArbitrateUnlock = 0x1b,
WaitProcessWideKeyAtomic = 0x1c,
SignalProcessWideKey = 0x1d,
GetSystemTick = 0x1e,
ConnectToNamedPort = 0x1f,
SendSyncRequestLight = 0x20,
SendSyncRequest = 0x21,
SendSyncRequestWithUserBuffer = 0x22,
SendAsyncRequestWithUserBuffer = 0x23,
GetProcessId = 0x24,
GetThreadId = 0x25,
Break = 0x26,
OutputDebugString = 0x27,
ReturnFromException = 0x28,
GetInfo = 0x29,
FlushEntireDataCache = 0x2a,
FlushDataCache = 0x2b,
MapPhysicalMemory = 0x2c,
UnmapPhysicalMemory = 0x2d,
GetDebugFutureThreadInfo = 0x2e,
GetLastThreadInfo = 0x2f,
GetResourceLimitLimitValue = 0x30,
GetResourceLimitCurrentValue = 0x31,
SetThreadActivity = 0x32,
GetThreadContext3 = 0x33,
WaitForAddress = 0x34,
SignalToAddress = 0x35,
SynchronizePreemptionState = 0x36,
GetResourceLimitPeakValue = 0x37,
CreateIoPool = 0x39,
CreateIoRegion = 0x3a,
KernelDebug = 0x3c,
ChangeKernelTraceState = 0x3d,
CreateSession = 0x40,
AcceptSession = 0x41,
ReplyAndReceiveLight = 0x42,
ReplyAndReceive = 0x43,
ReplyAndReceiveWithUserBuffer = 0x44,
CreateEvent = 0x45,
MapIoRegion = 0x46,
UnmapIoRegion = 0x47,
MapPhysicalMemoryUnsafe = 0x48,
UnmapPhysicalMemoryUnsafe = 0x49,
SetUnsafeLimit = 0x4a,
CreateCodeMemory = 0x4b,
ControlCodeMemory = 0x4c,
SleepSystem = 0x4d,
ReadWriteRegister = 0x4e,
SetProcessActivity = 0x4f,
CreateSharedMemory = 0x50,
MapTransferMemory = 0x51,
UnmapTransferMemory = 0x52,
CreateInterruptEvent = 0x53,
QueryPhysicalAddress = 0x54,
QueryIoMapping = 0x55,
CreateDeviceAddressSpace = 0x56,
AttachDeviceAddressSpace = 0x57,
DetachDeviceAddressSpace = 0x58,
MapDeviceAddressSpaceByForce = 0x59,
MapDeviceAddressSpaceAligned = 0x5a,
UnmapDeviceAddressSpace = 0x5c,
InvalidateProcessDataCache = 0x5d,
StoreProcessDataCache = 0x5e,
FlushProcessDataCache = 0x5f,
DebugActiveProcess = 0x60,
BreakDebugProcess = 0x61,
TerminateDebugProcess = 0x62,
GetDebugEvent = 0x63,
ContinueDebugEvent = 0x64,
GetProcessList = 0x65,
GetThreadList = 0x66,
GetDebugThreadContext = 0x67,
SetDebugThreadContext = 0x68,
QueryDebugProcessMemory = 0x69,
ReadDebugProcessMemory = 0x6a,
WriteDebugProcessMemory = 0x6b,
SetHardwareBreakPoint = 0x6c,
GetDebugThreadParam = 0x6d,
GetSystemInfo = 0x6f,
CreatePort = 0x70,
ManageNamedPort = 0x71,
ConnectToPort = 0x72,
SetProcessMemoryPermission = 0x73,
MapProcessMemory = 0x74,
UnmapProcessMemory = 0x75,
QueryProcessMemory = 0x76,
MapProcessCodeMemory = 0x77,
UnmapProcessCodeMemory = 0x78,
CreateProcess = 0x79,
StartProcess = 0x7a,
TerminateProcess = 0x7b,
GetProcessInfo = 0x7c,
CreateResourceLimit = 0x7d,
SetResourceLimitLimitValue = 0x7e,
CallSecureMonitor = 0x7f,
MapInsecureMemory = 0x90,
UnmapInsecureMemory = 0x91,
};
// clang-format on
// Custom ABI.
Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args);
Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args);
Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args);
Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args);
void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args);
void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args);
void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args);
// Defined in svc_light_ipc.cpp.
void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system);
void SvcWrap_ReplyAndReceiveLight64(Core::System& system);
void SvcWrap_SendSyncRequestLight64From32(Core::System& system);
void SvcWrap_SendSyncRequestLight64(Core::System& system);
// Defined in svc_secure_monitor_call.cpp.
void SvcWrap_CallSecureMonitor64From32(Core::System& system);
void SvcWrap_CallSecureMonitor64(Core::System& system);
// Perform a supervisor call by index.
void Call(Core::System& system, u32 imm);
} // namespace Kernel::Svc

View file

@ -0,0 +1,66 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
/// Sets the thread activity
Result SetThreadActivity(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity) {
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", thread_handle,
thread_activity);
// Validate the activity.
static constexpr auto IsValidThreadActivity = [](ThreadActivity activity) {
return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused;
};
R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue);
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Check that the activity is being set on a non-current thread for the current process.
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()),
ResultInvalidHandle);
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy);
// Set the activity.
R_TRY(thread->SetActivity(thread_activity));
return ResultSuccess;
}
Result SetProcessActivity(Core::System& system, Handle process_handle,
ProcessActivity process_activity) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetThreadActivity64(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity) {
return SetThreadActivity(system, thread_handle, thread_activity);
}
Result SetProcessActivity64(Core::System& system, Handle process_handle,
ProcessActivity process_activity) {
return SetProcessActivity(system, process_handle, process_activity);
}
Result SetThreadActivity64From32(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity) {
return SetThreadActivity(system, thread_handle, thread_activity);
}
Result SetProcessActivity64From32(Core::System& system, Handle process_handle,
ProcessActivity process_activity) {
return SetProcessActivity(system, process_handle, process_activity);
}
} // namespace Kernel::Svc

View file

@ -0,0 +1,122 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/svc_types.h"
namespace Kernel::Svc {
namespace {
constexpr bool IsValidSignalType(Svc::SignalType type) {
switch (type) {
case Svc::SignalType::Signal:
case Svc::SignalType::SignalAndIncrementIfEqual:
case Svc::SignalType::SignalAndModifyByWaitingCountIfEqual:
return true;
default:
return false;
}
}
constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) {
switch (type) {
case Svc::ArbitrationType::WaitIfLessThan:
case Svc::ArbitrationType::DecrementAndWaitIfLessThan:
case Svc::ArbitrationType::WaitIfEqual:
return true;
default:
return false;
}
}
} // namespace
// Wait for an address (via Address Arbiter)
Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
s64 timeout_ns) {
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}",
address, arb_type, value, timeout_ns);
// Validate input.
if (IsKernelAddress(address)) {
LOG_ERROR(Kernel_SVC, "Attempting to wait on kernel address (address={:08X})", address);
return ResultInvalidCurrentMemory;
}
if (!Common::IsAligned(address, sizeof(s32))) {
LOG_ERROR(Kernel_SVC, "Wait address must be 4 byte aligned (address={:08X})", address);
return ResultInvalidAddress;
}
if (!IsValidArbitrationType(arb_type)) {
LOG_ERROR(Kernel_SVC, "Invalid arbitration type specified (type={})", arb_type);
return ResultInvalidEnumValue;
}
// Convert timeout from nanoseconds to ticks.
s64 timeout{};
if (timeout_ns > 0) {
const s64 offset_tick(timeout_ns);
if (offset_tick > 0) {
timeout = offset_tick + 2;
if (timeout <= 0) {
timeout = std::numeric_limits<s64>::max();
}
} else {
timeout = std::numeric_limits<s64>::max();
}
} else {
timeout = timeout_ns;
}
return GetCurrentProcess(system.Kernel()).WaitAddressArbiter(address, arb_type, value, timeout);
}
// Signals to an address (via Address Arbiter)
Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value,
s32 count) {
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}",
address, signal_type, value, count);
// Validate input.
if (IsKernelAddress(address)) {
LOG_ERROR(Kernel_SVC, "Attempting to signal to a kernel address (address={:08X})", address);
return ResultInvalidCurrentMemory;
}
if (!Common::IsAligned(address, sizeof(s32))) {
LOG_ERROR(Kernel_SVC, "Signaled address must be 4 byte aligned (address={:08X})", address);
return ResultInvalidAddress;
}
if (!IsValidSignalType(signal_type)) {
LOG_ERROR(Kernel_SVC, "Invalid signal type specified (type={})", signal_type);
return ResultInvalidEnumValue;
}
return GetCurrentProcess(system.Kernel())
.SignalAddressArbiter(address, signal_type, value, count);
}
Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
s64 timeout_ns) {
return WaitForAddress(system, address, arb_type, value, timeout_ns);
}
Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value,
s32 count) {
return SignalToAddress(system, address, signal_type, value, count);
}
Result WaitForAddress64From32(Core::System& system, u32 address, ArbitrationType arb_type,
s32 value, s64 timeout_ns) {
return WaitForAddress(system, address, arb_type, value, timeout_ns);
}
Result SignalToAddress64From32(Core::System& system, u32 address, SignalType signal_type, s32 value,
s32 count) {
return SignalToAddress(system, address, signal_type, value, count);
}
} // namespace Kernel::Svc

View file

@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
uint64_t address) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size,
uint64_t physical_address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
uint64_t address) {
R_RETURN(QueryPhysicalAddress(system, out_info, address));
}
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size,
uint64_t physical_address, uint64_t size) {
R_RETURN(QueryIoMapping(system, out_address, out_size, physical_address, size));
}
Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info,
uint32_t address) {
lp64::PhysicalMemoryInfo info{};
R_TRY(QueryPhysicalAddress(system, std::addressof(info), address));
*out_info = {
.physical_address = info.physical_address,
.virtual_address = static_cast<u32>(info.virtual_address),
.size = static_cast<u32>(info.size),
};
R_SUCCEED();
}
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size,
uint64_t physical_address, uint32_t size) {
R_RETURN(QueryIoMapping(system, reinterpret_cast<uint64_t*>(out_address),
reinterpret_cast<uint64_t*>(out_size), physical_address, size));
}
} // namespace Kernel::Svc

View file

@ -0,0 +1,98 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/svc_types.h"
namespace Kernel::Svc {
void FlushEntireDataCache(Core::System& system) {
UNIMPLEMENTED();
}
Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 address, u64 size) {
// Validate address/size.
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS(address == static_cast<uint64_t>(address), ResultInvalidCurrentMemory);
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
// Get the process from its handle.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Verify the region is within range.
auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Perform the operation.
R_RETURN(system.Memory().FlushDataCache(*process, address, size));
}
void FlushEntireDataCache64(Core::System& system) {
FlushEntireDataCache(system);
}
Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(FlushDataCache(system, address, size));
}
Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
}
Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
}
Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
}
void FlushEntireDataCache64From32(Core::System& system) {
return FlushEntireDataCache(system);
}
Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(FlushDataCache(system, address, size));
}
Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle,
uint64_t address, uint64_t size) {
R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
}
Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
}
Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
}
} // namespace Kernel::Svc

View file

@ -0,0 +1,171 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"
namespace Kernel::Svc {
namespace {
constexpr bool IsValidMapCodeMemoryPermission(MemoryPermission perm) {
return perm == MemoryPermission::ReadWrite;
}
constexpr bool IsValidMapToOwnerCodeMemoryPermission(MemoryPermission perm) {
return perm == MemoryPermission::Read || perm == MemoryPermission::ReadExecute;
}
constexpr bool IsValidUnmapCodeMemoryPermission(MemoryPermission perm) {
return perm == MemoryPermission::None;
}
constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm) {
return perm == MemoryPermission::None;
}
} // namespace
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64_t size) {
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);
// Get kernel instance.
auto& kernel = system.Kernel();
// Validate address / size.
R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
// Create the code memory.
KCodeMemory* code_mem = KCodeMemory::Create(kernel);
R_UNLESS(code_mem != nullptr, ResultOutOfResource);
// Verify that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel()).PageTable().Contains(address, size),
ResultInvalidCurrentMemory);
// Initialize the code memory.
R_TRY(code_mem->Initialize(system.DeviceMemory(), address, size));
// Register the code memory.
KCodeMemory::Register(kernel, code_mem);
// Add the code memory to the handle table.
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, code_mem));
code_mem->Close();
return ResultSuccess;
}
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
CodeMemoryOperation operation, VAddr address, uint64_t size,
MemoryPermission perm) {
LOG_TRACE(Kernel_SVC,
"called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, "
"permission=0x{:X}",
code_memory_handle, operation, address, size, perm);
// Validate the address / size.
R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
// Get the code memory from its handle.
KScopedAutoObject code_mem = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KCodeMemory>(code_memory_handle);
R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle);
// NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process.
// This enables homebrew usage of these SVCs for JIT.
// Perform the operation.
switch (operation) {
case CodeMemoryOperation::Map: {
// Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel())
.PageTable()
.CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
// Check the memory permission.
R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Map the memory.
R_TRY(code_mem->Map(address, size));
} break;
case CodeMemoryOperation::Unmap: {
// Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel())
.PageTable()
.CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
// Check the memory permission.
R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Unmap the memory.
R_TRY(code_mem->Unmap(address, size));
} break;
case CodeMemoryOperation::MapToOwner: {
// Check that the region is in range.
R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size,
KMemoryState::GeneratedCode),
ResultInvalidMemoryRegion);
// Check the memory permission.
R_UNLESS(IsValidMapToOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Map the memory to its owner.
R_TRY(code_mem->MapToOwner(address, size, perm));
} break;
case CodeMemoryOperation::UnmapFromOwner: {
// Check that the region is in range.
R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size,
KMemoryState::GeneratedCode),
ResultInvalidMemoryRegion);
// Check the memory permission.
R_UNLESS(IsValidUnmapFromOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Unmap the memory from its owner.
R_TRY(code_mem->UnmapFromOwner(address, size));
} break;
default:
return ResultInvalidEnumValue;
}
return ResultSuccess;
}
Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address,
uint64_t size) {
R_RETURN(CreateCodeMemory(system, out_handle, address, size));
}
Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle,
CodeMemoryOperation operation, uint64_t address, uint64_t size,
MemoryPermission perm) {
R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
}
Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address,
uint32_t size) {
R_RETURN(CreateCodeMemory(system, out_handle, address, size));
}
Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle,
CodeMemoryOperation operation, uint64_t address, uint64_t size,
MemoryPermission perm) {
R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
}
} // namespace Kernel::Svc

View file

@ -0,0 +1,77 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
/// Wait process wide key atomic
Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag,
s64 timeout_ns) {
LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address,
cv_key, tag, timeout_ns);
// Validate input.
if (IsKernelAddress(address)) {
LOG_ERROR(Kernel_SVC, "Attempted to wait on kernel address (address={:08X})", address);
return ResultInvalidCurrentMemory;
}
if (!Common::IsAligned(address, sizeof(s32))) {
LOG_ERROR(Kernel_SVC, "Address must be 4 byte aligned (address={:08X})", address);
return ResultInvalidAddress;
}
// Convert timeout from nanoseconds to ticks.
s64 timeout{};
if (timeout_ns > 0) {
const s64 offset_tick(timeout_ns);
if (offset_tick > 0) {
timeout = offset_tick + 2;
if (timeout <= 0) {
timeout = std::numeric_limits<s64>::max();
}
} else {
timeout = std::numeric_limits<s64>::max();
}
} else {
timeout = timeout_ns;
}
// Wait on the condition variable.
return GetCurrentProcess(system.Kernel())
.WaitConditionVariable(address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout);
}
/// Signal process wide key
void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) {
LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);
// Signal the condition variable.
return GetCurrentProcess(system.Kernel())
.SignalConditionVariable(Common::AlignDown(cv_key, sizeof(u32)), count);
}
Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key,
uint32_t tag, int64_t timeout_ns) {
R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
}
void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count) {
SignalProcessWideKey(system, cv_key, count);
}
Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key,
uint32_t tag, int64_t timeout_ns) {
R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
}
void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count) {
SignalProcessWideKey(system, cv_key, count);
}
} // namespace Kernel::Svc

View file

@ -0,0 +1,194 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result BreakDebugProcess(Core::System& system, Handle debug_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result TerminateDebugProcess(Core::System& system, Handle debug_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags,
uint64_t user_thread_ids, int32_t num_thread_ids) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle,
uint64_t thread_id, uint32_t context_flags) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id,
uint64_t user_context, uint32_t context_flags) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info,
PageInfo* out_page_info, Handle process_handle, uint64_t address) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle,
uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer,
uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name,
uint64_t flags, uint64_t value) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32,
Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id) {
R_RETURN(DebugActiveProcess(system, out_handle, process_id));
}
Result BreakDebugProcess64(Core::System& system, Handle debug_handle) {
R_RETURN(BreakDebugProcess(system, debug_handle));
}
Result TerminateDebugProcess64(Core::System& system, Handle debug_handle) {
R_RETURN(TerminateDebugProcess(system, debug_handle));
}
Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle) {
R_RETURN(GetDebugEvent(system, out_info, debug_handle));
}
Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags,
uint64_t thread_ids, int32_t num_thread_ids) {
R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
}
Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle,
uint64_t thread_id, uint32_t context_flags) {
R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
}
Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id,
uint64_t context, uint32_t context_flags) {
R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
}
Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info,
PageInfo* out_page_info, Handle debug_handle, uint64_t address) {
R_RETURN(
QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
}
Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle,
uint64_t address, uint64_t size) {
R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
}
Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer,
uint64_t address, uint64_t size) {
R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
}
Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name,
uint64_t flags, uint64_t value) {
R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
}
Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32,
Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
}
Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id) {
R_RETURN(DebugActiveProcess(system, out_handle, process_id));
}
Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle) {
R_RETURN(BreakDebugProcess(system, debug_handle));
}
Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle) {
R_RETURN(TerminateDebugProcess(system, debug_handle));
}
Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle) {
R_RETURN(GetDebugEvent(system, out_info, debug_handle));
}
Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags,
uint32_t thread_ids, int32_t num_thread_ids) {
R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
}
Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context,
Handle debug_handle, uint64_t thread_id,
uint32_t context_flags) {
R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
}
Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id,
uint32_t context, uint32_t context_flags) {
R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
}
Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info,
PageInfo* out_page_info, Handle debug_handle,
uint32_t address) {
R_RETURN(
QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
}
Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle,
uint32_t address, uint32_t size) {
R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
}
Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer,
uint32_t address, uint32_t size) {
R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
}
Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name,
uint64_t flags, uint64_t value) {
R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
}
Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32,
Handle debug_handle, uint64_t thread_id,
DebugThreadParam param) {
R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
}
} // namespace Kernel::Svc

Some files were not shown because too many files have changed in this diff Show more