Compare commits

...

165 Commits

Author SHA1 Message Date
bunnei 71d4abcfd4 cmake: Remove use of bintray for externals.
- Bintray will be deprecated on May 1st 2021 (https://bintray.com/)
- We were previously using this for Qt (non-Windows) and SDL.
- I've moved to bundled SDL on Windows.
2021-04-15 23:12:23 -07:00
bunnei 0a5bc8ec14 Merge pull request #6119 from german77/SDLMapping
InputCommon: Address mapping and naming issues with SDL2
2021-04-15 21:40:35 -07:00
bunnei 60511976bb Merge pull request #6199 from lioncash/log-ns
common/log: Move Log namespace into the Common namespace
2021-04-14 21:29:44 -07:00
Lioncash 2a341c9969 log/backend: Correct order of const in copy constructor
Follows our predominant coding style. Also explicitly specifies the move
constructor/assignment operator as well.
2021-04-14 23:11:01 -04:00
Lioncash 64606aefcf common/log: Move Log namespace into the Common namespace
Forgot to move this over when I moved the rest of the source files with
lacking namespaces over.
2021-04-14 23:10:58 -04:00
bunnei de5bf640b7 Merge pull request #6196 from bunnei/asserts-setting
core: settings: Add setting for debug assertions and disable by default.
2021-04-14 17:47:18 -07:00
bunnei a4c6712a4b common: Move settings to common from core.
- Removes a dependency on core and input_common from common.
2021-04-14 16:24:03 -07:00
bunnei c6c0771b12 core: settings: Add setting for debug assertions and disable by default.
- This is a developer-only setting and no longer needs to be enabled by default.
- Also adds "use_auto_stub" setting to SDL frontend while we are here.
- Supersedes #1340.
2021-04-14 16:24:02 -07:00
bunnei eedbe8351c Merge pull request #6197 from ameerj/kreslimit-cleanup
k_resource_limit: Cleanup of member variables/headers
2021-04-14 14:25:51 -07:00
bunnei 62a8505345 Merge pull request #6195 from Morph1984/controller-applet-motion
applets/controller: Hook up the "Motion" button functionality
2021-04-13 21:53:34 -07:00
ameerj 2067115c78 k_resource_limit: Minor cleanup of member variables/headers 2021-04-14 00:40:33 -04:00
bunnei bb922d6ff6 Merge pull request #6185 from ameerj/process-reslimit
kernel/process: Replace process resource limit instance with the kernel's resource limit
2021-04-13 21:08:59 -07:00
bunnei 8146c8c5e7 Merge pull request #6191 from lioncash/vdtor
engine_interface: Add missing virtual destructor
2021-04-13 19:59:10 -07:00
bunnei 12a343ed8d Merge pull request #6190 from lioncash/constfn2
vk_master_semaphore: Add missing const qualifier for IsFree()
2021-04-13 17:52:38 -07:00
bunnei 62b560e8e3 Merge pull request #6188 from lioncash/bits
vk_texture_cache: Make use of bit_cast where applicable
2021-04-13 16:44:49 -07:00
bunnei 154eb3cfbe Merge pull request #6187 from lioncash/sign-conv
texure_cache/util: Resolve implicit sign conversions with std::reduce
2021-04-13 09:46:32 -07:00
Morph 10ca4c9490 applets/controller: Hook up the "Motion" button functionality
I forgot to hook this up during the development of the controller applet, this PR amends that.
2021-04-13 10:05:07 -04:00
bunnei 335a3cc115 Merge pull request #6186 from lioncash/cache-erase
query_cache: Make use of std::erase_if
2021-04-12 17:52:34 -07:00
bunnei 7f06276192 Merge pull request #6193 from lioncash/incguard
nvidia_flags: Add missing header guard
2021-04-12 16:59:02 -07:00
Lioncash ff6a83e0fe nvidia_flags: Add missing header guard
Prevents potential inclusion compilation errors.
2021-04-12 19:18:48 -04:00
ameerj 5e85bc3d23 kernel/process: Replace process resource limit instance with the kernel's resource limit
This commit addresses the inaccurate behavior of kernel processes creating their own resource limit, rather than utilizing the kernel's system-wide resource limit instance.
2021-04-12 16:14:19 -04:00
bunnei 8e7734bf40 Merge pull request #6192 from lioncash/discard
k_thread: Remove [[nodiscard]] attribute from ClearWaitCancelled()
2021-04-12 11:12:45 -07:00
Lioncash 0fb3773924 k_thread: Remove [[nodiscard]] attribute from ClearWaitCancelled()
This function has a void return value, so this attribute doesn't apply
to it.
2021-04-12 10:17:38 -04:00
Lioncash 31932904c5 engine_interface: Add missing virtual destructor
Eliminates a potential bug vector related to inheritance. Plus, we
should generally be specifying the destructor as virtual within purely
virtual interfaces to begin with.
2021-04-12 09:53:55 -04:00
Lioncash 9b331a5fb5 vk_master_semaphore: Deduplicate atomic access within IsFree()
We can just reuse the already existing KnownGpuTick() to deduplicate the
access.
2021-04-12 09:41:55 -04:00
Lioncash c5f5d6e7f6 vk_master_semaphore: Add missing const qualifier for IsFree()
This member function doesn't modify class state.
2021-04-12 09:41:23 -04:00
Lioncash 4198c92ed0 vk_texture_cache: Make use of Common::BitCast where applicable
Also clarify the TODO comment a little more on the lacking
implementations for std::bit_cast.
2021-04-12 09:17:36 -04:00
Lioncash fddb278aa3 texure_cache/util: Resolve implicit sign conversions with std::reduce
Amends implicit sign conversions occurring with usages of std::reduce
and also relocates it to its own utility function to reduce verbosity a
little bit.
2021-04-12 05:21:53 -04:00
Lioncash 4209588505 query_cache: Make use of std::erase_if
Same behavior, but much more straightforward to read.
2021-04-12 04:51:18 -04:00
bunnei 26d60014d0 Merge pull request #6135 from Morph1984/borderless-windowed-fullscreen
configure_graphics: Add Borderless Windowed fullscreen mode
2021-04-11 21:23:59 -07:00
Rodrigo Locatti ddbd1387aa Merge pull request #6181 from Joshua-Ashton/robustness_features
vulkan_device: Enable EXT_robustness2 features
2021-04-11 20:42:14 -03:00
Rodrigo Locatti 9f1cf99ea0 Merge pull request #6182 from Joshua-Ashton/null-offset
vk_buffer_cache: Fix offset for NULL vertex buffers
2021-04-11 20:41:48 -03:00
bunnei 0c19147e09 Merge pull request #6170 from Morph1984/more-time-fixes
service: time: Setup the network clock with the local clock context
2021-04-11 10:50:08 -07:00
LC 55b7d8e322 Merge pull request #6183 from MerryMage/dynarmic
externals: Update dynarmic to b2a4da5e
2021-04-11 11:16:34 -04:00
MerryMage a208c7b059 externals: Update dynarmic to b2a4da5e 2021-04-11 15:39:45 +01:00
Joshua Ashton 0ec6cb942d vk_buffer_cache: Fix offset for NULL vertex buffers
The Vulkan spec states:
If an element of pBuffers is VK_NULL_HANDLE, then the corresponding element of pOffsets must be zero.

https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdBindVertexBuffers2EXT.html#VUID-vkCmdBindVertexBuffers2EXT-pBuffers-04112
2021-04-11 10:34:52 +01:00
Morph 9bd71f4064 Merge pull request #6180 from Joshua-Ashton/device_loss_fix
renderer_vulkan: Check return value of AcquireNextImage
2021-04-11 05:08:32 -04:00
Joshua Ashton 08337a492d vulkan_device: Enable EXT_robustness2 features
When this was being made mandatory, these enablement of these features was removed, but this is still needed.

Fixes: 757fd1e917 ("vulkan_device: Require VK_EXT_robustness2")
2021-04-11 09:48:38 +01:00
Joshua Ashton bcf58c8210 renderer_vulkan: Check return value of AcquireNextImage
We can get into a really bad state by ignoring this
leading to device loss and using incorrect resources.
2021-04-11 09:27:50 +01:00
bunnei 4f60818eae Merge pull request #6167 from Morph1984/time-fix
service: time: Fix CalculateStandardUserSystemClockDifferenceByUser
2021-04-10 22:11:53 -07:00
bunnei 290b452ea1 Merge pull request #6112 from ogniK5377/pctl
pctl: Rework how pctl works to be more accurate
2021-04-10 21:09:54 -07:00
bunnei 1063e0be48 Merge pull request #6172 from degasus/cmake_opus
externals: Search for shared opus installation.
2021-04-10 02:27:02 -07:00
bunnei b04877dd95 Merge pull request #6099 from bunnei/derive-mem
Kernel Rework: Derive memory regions from board layout.
2021-04-10 00:02:52 -07:00
bunnei 31c80b8c6f Merge pull request #6171 from german77/services
service: Update service function tables and use proper names
2021-04-09 22:47:34 -07:00
bunnei c6d2af16b5 Merge pull request #6156 from lioncash/lock-discard
kernel: Mark lock helper classes as [[nodiscard]]
2021-04-09 21:42:26 -07:00
bunnei 9cf8bcc75c Merge pull request #6113 from german77/playhistory
Friend: Stub GetPlayHistoryRegistrationKey
2021-04-09 20:50:13 -07:00
bunnei 96d07b4949 Merge pull request #6158 from german77/hidServiceTables
hid: Update service function tables
2021-04-09 16:10:06 -07:00
bunnei d6e5e053a6 Merge pull request #6162 from degasus/no_spin_loops
video_core: Avoid spin loops.
2021-04-09 11:52:18 -07:00
bunnei c34249559d Merge pull request #6164 from Morph1984/service-update-12.x
service: Update service function tables
2021-04-09 10:59:27 -07:00
Morph 9c85bcbecc ns: Update to 12.x 2021-04-09 00:49:47 -04:00
Morph 467ef54e2a aoc_u: Update to 12.x 2021-04-09 00:49:47 -04:00
Morph 8a9e834fc2 nim: Update to 12.x 2021-04-09 00:49:47 -04:00
Morph e0bddf8f07 npns: Update to 12.x 2021-04-09 00:49:47 -04:00
Morph 5ce0e127da bgtc: Update to 12.x and implement OpenTaskService 2021-04-09 00:49:47 -04:00
Morph 6af7bd02b2 vi: Update to 12.x 2021-04-09 00:49:47 -04:00
Morph 7e62452ac8 erpt: Update to 12.x 2021-04-09 00:49:46 -04:00
Morph 5ec2fdceca btm: Update to 12.x 2021-04-09 00:49:46 -04:00
Morph 214ef2dd8a btdrv: Update to 12.x 2021-04-09 00:49:46 -04:00
bunnei c1017efb4a Merge pull request #6168 from Morph1984/stub-SetNpadAnalogStickUseCenterClamp
service: hid: Stub SetAnalogStickUseCenterClamp
2021-04-08 21:16:47 -07:00
german77 09a8e08109 wlan: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 ac14ef70b5 usb: Use proper names 2021-04-08 19:40:25 -06:00
german77 35abd560c4 ITimeZoneService: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 e7530b341e spl: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 01928b1d17 sfdnsres: Use proper names 2021-04-08 19:40:25 -06:00
german77 ff1201210c nsd: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 f90041a2d4 ethc: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 6c81332ca7 sm: Use proper names, update to 12.x 2021-04-08 19:40:25 -06:00
german77 7133bfdd2c set_sys: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 556c5df745 pctl_module: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 4530b58eb0 pcie: Use proper names 2021-04-08 19:40:25 -06:00
german77 53f1560a24 olsc: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 c37b8a1028 pl_u: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 278c38aa4a ldr: Use proper names 2021-04-08 19:40:25 -06:00
german77 a4e2821530 arp: Use proper names, update to 12.x 2021-04-08 19:40:25 -06:00
german77 a83f0f7154 caps_u: Update to 12.x 2021-04-08 19:40:25 -06:00
german77 dbc4c8e314 caps_a: Update to 12.x 2021-04-08 19:40:24 -06:00
german77 03790771a6 bpc: Use proper names 2021-04-08 19:40:24 -06:00
german77 0377618288 bcat_module: Update to 12.x 2021-04-08 19:40:24 -06:00
german77 247b1c14d2 codecctl: Use proper names 2021-04-08 19:40:24 -06:00
german77 ec0e644fb0 audren_u: Use proper names 2021-04-08 19:40:24 -06:00
german77 8f1300cd31 audren_a: Use proper names 2021-04-08 19:40:24 -06:00
german77 6219da627b audrec_u: Use proper names, update to 12.x 2021-04-08 19:40:24 -06:00
german77 5ce97bf0a0 audrec_a: Use proper names 2021-04-08 19:40:24 -06:00
german77 b059db74c5 audout_u: Use proper names 2021-04-08 19:40:24 -06:00
german77 c51d9e0b0a audout_a: Use proper names 2021-04-08 19:40:24 -06:00
german77 d7f2078e7b audin_u: Use proper names 2021-04-08 19:40:24 -06:00
german77 b6bbc0d483 audin_a: Use proper names 2021-04-08 19:40:24 -06:00
bunnei 701b6c2fb8 Merge pull request #6155 from ameerj/kernel-12-rescnt
kernel: Increase event and session counts
2021-04-08 18:21:00 -07:00
bunnei d894818bb3 Merge pull request #6157 from Morph1984/am-update-12.x
service: am: Update service function tables
2021-04-08 16:37:59 -07:00
bunnei 1744fa6ecf Merge pull request #6062 from ameerj/auto-stub
service: Add a toggle for auto stub fallback
2021-04-08 15:32:41 -07:00
Markus Wick 5096ed5e0a externals: Search for shared opus installation.
We had used conan for opus before, but there was a bug in the AVX detection.
However we still had the Findopus.cmake file within the repository, but not used.

This patch reenables the Findopus helper and prefer the system wide installation of opus.
2021-04-08 23:49:32 +02:00
bunnei dfac2e2d25 Merge pull request #6145 from lat9nq/nvhost_empty_memcpy
nvhost_nvdec_common: Avoid memcpy with null pointers
2021-04-08 13:23:05 -07:00
Morph 2283fccc1b service: time: Setup the network clock with the local clock context
Setting the network time allows some time based events using the network clock to not reset.
2021-04-08 13:26:38 -04:00
bunnei 415dfb6cd3 Merge pull request #6154 from lioncash/svcrange2
svc: Expand SVC tables
2021-04-08 09:21:55 -07:00
Morph 8e545deab9 service: hid: Stub SetAnalogStickUseCenterClamp
- Used by eBASEBALLパワフルプロ野球2020
2021-04-08 03:41:06 -04:00
bunnei 15a07f0282 Merge pull request #6160 from Morph1984/fs-update-12.x
service: fs: Update service function tables
2021-04-07 20:54:42 -07:00
Morph 28d3661a5c service: time: Fix CalculateStandardUserSystemClockDifferenceByUser
CalculateStandardUserSystemClockDifferenceByUser passes in the ClockSnapshots through 2 input buffers and not as raw arguments. Fix this by reading the 2 input buffers instead of popping raw arguments.
2021-04-07 23:34:14 -04:00
bunnei 262a70223f Merge pull request #6143 from lat9nq/nvhost_null_memcpy
nvhost_ctrl_gpu: Avoid sending null pointer to memcpy
2021-04-07 16:50:22 -07:00
bunnei 535e50db1c Merge pull request #6159 from Morph1984/acc-update-12.x
service: acc: Update service function tables
2021-04-07 14:37:59 -07:00
Markus Wick e8bd9aed8b video_core: Use a CV for blocking commands.
There is no need for a busy loop here. Let's just use a condition variable to save some power.
2021-04-07 22:38:52 +02:00
Markus Wick e6fb49fa4b video_core/gpu_thread: Keep the write lock for allocating the fence.
Else the fence might get submited out-of-order into the queue, which makes testing them pointless.
Overhead should be tiny as the mutex is just moved from the queue to the writing code.
2021-04-07 22:38:52 +02:00
Markus Wick 5145133a60 video_core/gpu_thread: Implement a ShutDown method.
This was implicitly done by `is_powered_on = false`, however the explicit method allows us to block until the GPU is actually gone.

This should fix a race condition while removing the other subsystems while the GPU is still active.
2021-04-07 22:38:52 +02:00
Markus Wick 4aec060f6d common/threadsafe_queue: Provide Wait() method.
It shall block until there is something to consume in the queue.

And use it for the GPU emulation instead of the spin loop.
This is only in booting the emulator, however in BOTW this is the case for about 1 second.
2021-04-07 22:38:52 +02:00
bunnei 3173a53db9 Merge pull request #6130 from degasus/better_assert_handling
common: Move assert failure handling into a cpp file.
2021-04-07 13:35:41 -07:00
bunnei d490f6dcf8 Merge pull request #6153 from lioncash/svcrange
process_capability: Handle extended SVC range
2021-04-07 13:01:40 -07:00
bunnei 6dc35caad1 Merge pull request #6161 from Morph1984/audio-update-12.x
service: audio: Update service function tables
2021-04-07 10:39:05 -07:00
Morph a2d40b8185 hwopus: Update to 12.x 2021-04-07 02:57:39 -04:00
Morph 1ad4c98a5c IFile: Update to 12.x 2021-04-07 02:49:19 -04:00
Morph c44db90ad1 fsp-srv: Update to 12.x 2021-04-07 02:46:29 -04:00
Morph 531e797795 dauth_o: Update to 11.x 2021-04-07 02:15:55 -04:00
Morph ded420cfeb acc_u1: Update to 12.x 2021-04-07 02:15:55 -04:00
Morph 63caeca6ba acc_su: Update to 12.x 2021-04-07 02:15:55 -04:00
german77 4fe05d7b42 hid: Update service function tables 2021-04-07 01:15:38 -05:00
Morph 63ebf2a328 ISelfController: Update to 11.x 2021-04-07 02:00:19 -04:00
Morph d04120169d IApplicationFunctions: Update to 11.x 2021-04-07 01:59:35 -04:00
Morph ad0d5818a6 IDebugFunctions: Update to 12.x 2021-04-07 01:53:04 -04:00
Morph 49ec5784b0 ICommonStateGetter: Update to 12.x 2021-04-07 01:53:04 -04:00
Morph 4cdc701fd3 IGlobalStateController: Update to 12.x 2021-04-07 01:53:04 -04:00
Morph 95fa89da27 IHomeMenuFunctions: Update to 12.x 2021-04-07 01:53:04 -04:00
Lioncash 530a5a1d09 Amend bizarre clang-format suggestions 2021-04-07 01:52:08 -04:00
Lioncash 1e964604bb k_scoped_scheduler_lock_and_sleep: Mark class as [[nodiscard]]
Prevents logic bugs from slipping through.
2021-04-07 01:45:04 -04:00
Lioncash c018769016 k_scoped_lock: delete copy and move assignment operators
If we delete the copy and move constructor, we should also be deleting
the copy and move assignment operators (and even if this were intended,
it would be pretty odd to not document why it's done this way).
2021-04-07 01:25:57 -04:00
Lioncash bc30aa8249 k_scoped_lock: Mark class as [[nodiscard]]
Prevents logic bugs of the kind described in the previous commit from
slipping through.
2021-04-07 01:23:08 -04:00
Lioncash 97e2604575 k_scheduler: Mark KScopedSchedulerLock as [[nodiscard]]
Prevents logic bugs like:

KScopedSchedulerLock{kernel};

instead of:

KScopedSchedulerLock lk{kernel};

from slipping through.
2021-04-07 01:19:29 -04:00
ameerj 24900674b7 kernel: Increase event and session counts
12.x increased the number of available sessions and event resource counts
2021-04-07 01:01:05 -04:00
bunnei 068b2ffbcc Merge pull request #6146 from lat9nq/vp9_empty_memcpy
vp9: Avoid memcpy with null pointers
2021-04-06 21:57:43 -07:00
Lioncash 55fc808d64 svc: Expand SVC tables
12.x expanded the range of SVC entries from 0x7F to 0xBF (with all new
entries being unused), so we can expand it to also match.
2021-04-07 00:55:33 -04:00
Morph 8ce31f1c8e config: Default to exclusive fullscreen mode on platforms other than Windows
Several issues have been reported with the borderless windowed fullscreen mode on *nix platforms. Default to exclusive fullscreen mode on these platforms for now.
2021-04-06 05:58:57 -04:00
Morph 01ea0f3c74 configure_graphics: Add Borderless Windowed fullscreen mode
The borderless windowed fullscreen mode solves several issues with the presentation of the overlay dialogs and on-screen keyboard in exclusive fullscreen mode, and also has other benefits such as smoother gameplay, lower latency and a significant reduction in screen tearing.

Co-authored-by: Its-Rei <kupfel@gmail.com>
2021-04-06 05:58:57 -04:00
lat9nq 2cc42e40c5 nvhost_nvdec_common: Avoid memcpy with null pointers
Avoid sending null pointer to memcpy as reported by Undefined Behavious
Sanitizer.

Co-authored-by: LC <mathew1800@gmail.com>
2021-04-05 16:40:03 -04:00
lat9nq 638c892edf nvhost_ctrl_gpu: Avoid sending null pointer to memcpy
Undefined Behaviour Sanitizer reports a null pointer is being sent to
memcpy, thought it's "guaranteed to never be null". Guard it with an if
statement, and log when the action has been averted.
2021-04-05 00:49:09 -04:00
lat9nq a60653dcd3 vp9: Avoid memcpy with null pointers
Avoid sending null pointer to memcpy as reported by Undefined Behaviour
Sanitizer. Replaces the std::memcpy calls in SpliceVectors with
std::copy calls. Opting to replace all the memcpy's with copy's.

Co-authored-by: LC <mathew1800@gmail.com>
2021-04-05 00:44:38 -04:00
Markus Wick 9be819faaf common: Move assert failure handling into a cpp file.
Advantage: Altering the handler does not need a full recompilation.
Disadvantage: noreturn is droped, so the caller is a bit slower.

We quite often run yuzu with a YOLO assertion handler. In fact, only very few
games run at all with asserts. This patch allows developers to patch the handler
without recompiling everything. The overhead of the missing "noreturn" attribute
shoul be negletable.
2021-04-04 21:19:33 +02:00
german77 d9db1d125e InputCommon: Name properly xbox 360 and one controllers, Fix mappings for Nintendo Pro controllers 2021-03-30 21:40:36 -05:00
ameerj 54c1e0897d configuration: Add auto stub toggle that resets on boot
Auto-stub is an experimental debugging feature that may cause unforseen bugs. This adds a toggle to only allow auto-stubbing unimplemented functions when explicitly enabled when yuzu is launched.
2021-03-30 13:40:31 -04:00
ameerj e6e61424d4 service: Auto stub fallback
For simple services we can implement an automatic stub fallback to help with compatibility until a proper implementation is done.

Co-Authored-By: Chloe <25727384+ognik5377@users.noreply.github.com>
2021-03-30 13:40:31 -04:00
Chloe Marcec 4930242c20 Addressed issues 2021-03-30 20:27:27 +11:00
german77 b2fb5c60e1 Friend: Stub GetPlayHistoryRegistrationKey 2021-03-27 08:25:36 -05:00
Chloe Marcec e9a1f29e93 pctl: Rework how pctl works to be more accurate
Introduces the usage of compatibilities to allow it the module to be closer to how it works on hardware.
2021-03-27 02:03:18 +11:00
bunnei 10d6e9f32b hle: kernel: Breakup InitializeMemoryLayout. 2021-03-23 18:47:16 -07:00
bunnei fb91647bca hle: kernel: k_memory_region_type: Minor code cleanup. 2021-03-23 18:42:04 -07:00
bunnei 4eac8703d2 hle: kernel: k_memory_region: Minor code cleanup. 2021-03-23 18:37:39 -07:00
bunnei 9032d21365 hle: kernel: k_memory_layout: Use pair instead of tuple. 2021-03-23 18:35:01 -07:00
bunnei a32190d0c2 hle: kernel: k_system_control: Remove unnecessary inline. 2021-03-23 18:33:29 -07:00
bunnei ab5995c7ae common: common_sizes: Move sizes to the Common namespace. 2021-03-23 18:31:46 -07:00
bunnei 1d78190843 hle: kernel: Merge KMemoryRegionAttr and KMemoryRegionType.
- Fixes clang errors with mixed enum arithmetic.
2021-03-21 15:53:21 -07:00
bunnei 3ffbe50e7d hle: kernel: Remove unused variable. 2021-03-21 15:47:24 -07:00
bunnei fc5205fc84 hle: kernel: k_memory_region_type: Remove extra ". 2021-03-21 15:47:05 -07:00
bunnei 1996cae9cb hle: kernel: k_memory_layout: Move KMemoryRegionAllocator out of global. 2021-03-21 14:45:13 -07:00
bunnei 343eaecd38 hle: kernel: k_memory_layout: Derive memory regions based on board layout. 2021-03-21 14:45:13 -07:00
bunnei 8d0ba7ee49 common: common_sizes: Move Invalid to Size_* prefix and add missing values. 2021-03-21 14:45:03 -07:00
bunnei 80688362cf hle: kernel: k_memory_region: Refactor to simplify code. 2021-03-21 14:45:03 -07:00
bunnei edbc505e52 hle: kernel: board: k_system_control: Extend to include memory region sizes. 2021-03-21 14:45:03 -07:00
bunnei 10265ad0e4 hle: kernel: board: Add secure_monitor module. 2021-03-21 14:45:03 -07:00
bunnei 28be8aec9a common: Move common sizes to their own header for code reuse. 2021-03-21 14:45:03 -07:00
bunnei 01f04fee32 hle: kernel: k_address_space_info: Cleanup. 2021-03-21 14:45:02 -07:00
bunnei f2e1441567 hle: kernel: Add k_trace module. 2021-03-21 14:45:02 -07:00
bunnei 5762517728 hle: kernel: KSystemControl: Update to reflect board-specific behavior. 2021-03-21 14:45:02 -07:00
bunnei a439867f2c hle: kernel: KMemoryManager: Add CalculateManagementOverheadSize. 2021-03-21 14:45:02 -07:00
bunnei 43a29b5803 hle: kernel: KMemoryManager: Add aliases. 2021-03-21 14:45:02 -07:00
bunnei c17beefe3d hle: kernel: Add architecture and board specific memory regions. 2021-03-21 14:45:02 -07:00
bunnei 3fb64da452 hle: kernel: KMemoryRegion: Derive region values. 2021-03-21 14:45:02 -07:00
bunnei 5872561077 hle: kernel: Migrate some code from Common::SpinLock to KSpinLock. 2021-03-21 14:45:02 -07:00
bunnei 541b4353e4 hle: kernel: Add initial KMemoryRegionType module. 2021-03-21 14:45:02 -07:00
bunnei 778e0f8ec1 hle: kernel: Move KMemoryRegion to its own module and update. 2021-03-21 14:45:02 -07:00
238 changed files with 3779 additions and 824 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ steps:
displayName: 'Install vulkan-sdk'
- script: python -m pip install --upgrade pip conan
displayName: 'Install conan'
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cmake --install . --config Release && cd ..
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 -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} -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cmake --install . --config Release && cd ..
displayName: 'Configure CMake'
- task: MSBuild@1
displayName: 'Build'
+38 -40
View File
@@ -11,6 +11,7 @@ project(yuzu)
# Set bundled sdl2/qt as dependent options.
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
option(ENABLE_QT "Enable the Qt frontend" ON)
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
@@ -166,12 +167,12 @@ macro(yuzu_find_packages)
# Cmake Pkg Prefix Version Conan Pkg
"Catch2 2.13 catch2/2.13.0"
"fmt 7.1 fmt/7.1.2"
# can't use until https://github.com/bincrafters/community/issues/1173
#"libzip 1.5 libzip/1.5.2@bincrafters/stable"
"lz4 1.8 lz4/1.9.2"
"nlohmann_json 3.8 nlohmann_json/3.8.0"
"ZLIB 1.2 zlib/1.2.11"
"zstd 1.4 zstd/1.4.8"
# can't use opus until AVX check is fixed: https://github.com/yuzu-emu/yuzu/pull/4068
#"opus 1.3 opus/1.3.1"
)
foreach(PACKAGE ${REQUIRED_LIBS})
@@ -249,22 +250,44 @@ if(ENABLE_QT)
if (ENABLE_QT_TRANSLATION)
find_package(Qt5 REQUIRED COMPONENTS LinguistTools ${QT_PREFIX_HINT})
endif()
if (NOT Qt5_FOUND)
list(APPEND CONAN_REQUIRED_LIBS "qt/5.14.1@bincrafters/stable")
endif()
endif()
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the yuzu_find_package
if(ENABLE_SDL2)
if(EXISTS ${CMAKE_BINARY_DIR}/sdl2Config.cmake)
include(${CMAKE_BINARY_DIR}/sdl2Config.cmake)
list(APPEND CMAKE_MODULE_PATH "${CONAN_SDL2_ROOT_RELEASE}")
list(APPEND CMAKE_PREFIX_PATH "${CONAN_SDL2_ROOT_RELEASE}")
endif()
find_package(SDL2)
if (NOT SDL2_FOUND)
# otherwise add this to the list of libraries to install
list(APPEND CONAN_REQUIRED_LIBS "sdl2/2.0.14@bincrafters/stable")
if (ENABLE_SDL2)
if (YUZU_USE_BUNDLED_SDL2)
# Detect toolchain and platform
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
set(SDL2_VER "SDL2-2.0.14")
else()
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
endif()
if (DEFINED SDL2_VER)
download_bundled_external("sdl2/" ${SDL2_VER} SDL2_PREFIX)
endif()
set(SDL2_FOUND YES)
set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers")
set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
add_library(SDL2 INTERFACE)
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
else()
find_package(SDL2 REQUIRED)
# Some installations don't set SDL2_LIBRARIES
if("${SDL2_LIBRARIES}" STREQUAL "")
message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
set(SDL2_LIBRARIES "SDL2::SDL2")
endif()
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
add_library(SDL2 INTERFACE)
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
endif()
else()
set(SDL2_FOUND NO)
endif()
# Install any missing dependencies with conan install
@@ -285,9 +308,6 @@ if (CONAN_REQUIRED_LIBS)
)
conan_check(VERSION 1.24.0 REQUIRED)
# Add the bincrafters remote
conan_add_remote(NAME bincrafters
URL https://api.bintray.com/conan/bincrafters/public-conan)
# Manually add iconv to fix a dep conflict between qt and sdl2
# We don't need to add it through find_package or anything since the other two can find it just fine
@@ -338,11 +358,6 @@ if (CONAN_REQUIRED_LIBS)
find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets)
endif()
endif()
if(ENABLE_SDL2)
list(APPEND CMAKE_MODULE_PATH "${CONAN_SDL2_ROOT_RELEASE}")
list(APPEND CMAKE_PREFIX_PATH "${CONAN_SDL2_ROOT_RELEASE}")
find_package(SDL2 REQUIRED)
endif()
endif()
@@ -358,23 +373,6 @@ elseif (TARGET Boost::boost)
add_library(boost ALIAS Boost::boost)
endif()
if (TARGET sdl2::sdl2)
# imported from the conan generated sdl2Config.cmake
set_target_properties(sdl2::sdl2 PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(SDL2 ALIAS sdl2::sdl2)
elseif(SDL2_FOUND)
# found through the system package manager
# Some installations don't set SDL2_LIBRARIES
if("${SDL2_LIBRARIES}" STREQUAL "")
message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
set(SDL2_LIBRARIES "SDL2::SDL2")
endif()
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
add_library(SDL2 INTERFACE)
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
endif()
# Ensure libusb is properly configured (based on dolphin libusb include)
if(NOT APPLE)
include(FindPkgConfig)
+5 -1
View File
@@ -97,4 +97,8 @@ if (ENABLE_WEB_SERVICE)
endif()
# Opus
add_subdirectory(opus)
find_package(opus 1.3)
if (NOT opus_FOUND)
message(STATUS "opus 1.3 or newer not found, falling back to externals")
add_subdirectory(opus EXCLUDE_FROM_ALL)
endif()
+1 -1
View File
@@ -28,7 +28,7 @@ if(opus_FOUND)
endif()
if(opus_FOUND AND NOT TARGET Opus::Opus)
add_library(Opus::Opus UNKNOWN IMPORTED)
add_library(Opus::Opus UNKNOWN IMPORTED GLOBAL)
set_target_properties(Opus::Opus PROPERTIES
IMPORTED_LOCATION "${opus_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_opus_CFLAGS_OTHER}"
+2
View File
@@ -252,3 +252,5 @@ PRIVATE
opus/silk/float
opus/src
)
add_library(Opus::Opus ALIAS opus)
+1 -1
View File
@@ -7,7 +7,7 @@
#include "audio_core/sink_details.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/settings.h"
#include "common/settings.h"
namespace AudioCore {
+1 -1
View File
@@ -11,8 +11,8 @@
#include "audio_core/info_updater.h"
#include "audio_core/voice_context.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/memory.h"
#include "core/settings.h"
namespace {
[[nodiscard]] static constexpr s16 ClampToS16(s32 value) {
+1 -1
View File
@@ -11,7 +11,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/ring_buffer.h"
#include "core/settings.h"
#include "common/settings.h"
#ifdef _WIN32
#include <objbase.h>
+1 -1
View File
@@ -11,8 +11,8 @@
#include "audio_core/stream.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core_timing.h"
#include "core/settings.h"
namespace AudioCore {
+6
View File
@@ -97,6 +97,7 @@ add_custom_command(OUTPUT scm_rev.cpp
add_library(common STATIC
algorithm.h
alignment.h
assert.cpp
assert.h
atomic_ops.h
detached_tasks.cpp
@@ -109,6 +110,7 @@ add_library(common STATIC
cityhash.h
common_funcs.h
common_paths.h
common_sizes.h
common_types.h
concepts.h
div_ceil.h
@@ -150,6 +152,10 @@ add_library(common STATIC
scm_rev.cpp
scm_rev.h
scope_exit.h
settings.cpp
settings.h
settings_input.cpp
settings_input.h
spin_lock.cpp
spin_lock.h
stream.cpp
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/settings.h"
void assert_handle_failure() {
if (Settings::values.use_debug_asserts) {
Crash();
}
}
+8 -6
View File
@@ -4,10 +4,13 @@
#pragma once
#include <cstdlib>
#include "common/common_funcs.h"
#include "common/logging/log.h"
// Sometimes we want to try to continue even after hitting an assert.
// However touching this file yields a global recompilation as this header is included almost
// everywhere. So let's just move the handling of the failed assert to a single cpp file.
void assert_handle_failure();
// For asserts we'd like to keep all the junk executed when an assert happens away from the
// important code in the function. One way of doing this is to put all the relevant code inside a
// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
@@ -17,15 +20,14 @@
// enough for our purposes.
template <typename Fn>
#if defined(_MSC_VER)
[[msvc::noinline, noreturn]]
[[msvc::noinline]]
#elif defined(__GNUC__)
[[gnu::cold, gnu::noinline, noreturn]]
[[gnu::cold, gnu::noinline]]
#endif
static void
assert_noinline_call(const Fn& fn) {
fn();
Crash();
exit(1); // Keeps GCC's mouth shut about this actually returning
assert_handle_failure();
}
#define ASSERT(_a_) \
+43
View File
@@ -0,0 +1,43 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <limits>
#include "common/common_types.h"
namespace Common {
enum : u64 {
Size_1_KB = 0x400ULL,
Size_64_KB = 64ULL * Size_1_KB,
Size_128_KB = 128ULL * Size_1_KB,
Size_1_MB = 0x100000ULL,
Size_2_MB = 2ULL * Size_1_MB,
Size_4_MB = 4ULL * Size_1_MB,
Size_5_MB = 5ULL * Size_1_MB,
Size_14_MB = 14ULL * Size_1_MB,
Size_32_MB = 32ULL * Size_1_MB,
Size_33_MB = 33ULL * Size_1_MB,
Size_128_MB = 128ULL * Size_1_MB,
Size_448_MB = 448ULL * Size_1_MB,
Size_507_MB = 507ULL * Size_1_MB,
Size_562_MB = 562ULL * Size_1_MB,
Size_1554_MB = 1554ULL * Size_1_MB,
Size_2048_MB = 2048ULL * Size_1_MB,
Size_2193_MB = 2193ULL * Size_1_MB,
Size_3285_MB = 3285ULL * Size_1_MB,
Size_4916_MB = 4916ULL * Size_1_MB,
Size_1_GB = 0x40000000ULL,
Size_2_GB = 2ULL * Size_1_GB,
Size_4_GB = 4ULL * Size_1_GB,
Size_6_GB = 6ULL * Size_1_GB,
Size_8_GB = 8ULL * Size_1_GB,
Size_64_GB = 64ULL * Size_1_GB,
Size_512_GB = 512ULL * Size_1_GB,
Size_Invalid = std::numeric_limits<u64>::max(),
};
} // namespace Common
+16 -12
View File
@@ -21,11 +21,11 @@
#include "common/logging/backend.h"
#include "common/logging/log.h"
#include "common/logging/text_formatter.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "common/threadsafe_queue.h"
#include "core/settings.h"
namespace Log {
namespace Common::Log {
/**
* Static state as a singleton.
@@ -37,8 +37,11 @@ public:
return backend;
}
Impl(Impl const&) = delete;
const Impl& operator=(Impl const&) = delete;
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
Impl(Impl&&) = delete;
Impl& operator=(Impl&&) = delete;
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string message) {
@@ -132,7 +135,7 @@ private:
std::mutex writing_mutex;
std::thread backend_thread;
std::vector<std::unique_ptr<Backend>> backends;
Common::MPSCQueue<Log::Entry> message_queue;
MPSCQueue<Entry> message_queue;
Filter filter;
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
};
@@ -146,16 +149,16 @@ void ColorConsoleBackend::Write(const Entry& entry) {
}
FileBackend::FileBackend(const std::string& filename) : bytes_written(0) {
if (Common::FS::Exists(filename + ".old.txt")) {
Common::FS::Delete(filename + ".old.txt");
if (FS::Exists(filename + ".old.txt")) {
FS::Delete(filename + ".old.txt");
}
if (Common::FS::Exists(filename)) {
Common::FS::Rename(filename, filename + ".old.txt");
if (FS::Exists(filename)) {
FS::Rename(filename, filename + ".old.txt");
}
// _SH_DENYWR allows read only access to the file for other programs.
// It is #defined to 0 on other platforms
file = Common::FS::IOFile(filename, "w", _SH_DENYWR);
file = FS::IOFile(filename, "w", _SH_DENYWR);
}
void FileBackend::Write(const Entry& entry) {
@@ -182,7 +185,7 @@ void FileBackend::Write(const Entry& entry) {
void DebuggerBackend::Write(const Entry& entry) {
#ifdef _WIN32
::OutputDebugStringW(Common::UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
#endif
}
@@ -212,6 +215,7 @@ void DebuggerBackend::Write(const Entry& entry) {
SUB(Service, ARP) \
SUB(Service, BCAT) \
SUB(Service, BPC) \
SUB(Service, BGTC) \
SUB(Service, BTDRV) \
SUB(Service, BTM) \
SUB(Service, Capture) \
@@ -341,4 +345,4 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
instance.PushEntry(log_class, log_level, filename, line_num, function,
fmt::vformat(format, args));
}
} // namespace Log
} // namespace Common::Log
+2 -2
View File
@@ -11,7 +11,7 @@
#include "common/logging/filter.h"
#include "common/logging/log.h"
namespace Log {
namespace Common::Log {
class Filter;
@@ -135,4 +135,4 @@ const char* GetLevelName(Level log_level);
* never get the message
*/
void SetGlobalFilter(const Filter& filter);
} // namespace Log
} // namespace Common::Log
+2 -2
View File
@@ -7,7 +7,7 @@
#include "common/logging/filter.h"
#include "common/string_util.h"
namespace Log {
namespace Common::Log {
namespace {
template <typename It>
Level GetLevelByName(const It begin, const It end) {
@@ -103,4 +103,4 @@ bool Filter::IsDebug() const {
});
}
} // namespace Log
} // namespace Common::Log
+2 -2
View File
@@ -9,7 +9,7 @@
#include <string_view>
#include "common/logging/log.h"
namespace Log {
namespace Common::Log {
/**
* Implements a log message filter which allows different log classes to have different minimum
@@ -51,4 +51,4 @@ public:
private:
std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels;
};
} // namespace Log
} // namespace Common::Log
+21 -14
View File
@@ -7,7 +7,7 @@
#include <fmt/format.h>
#include "common/common_types.h"
namespace Log {
namespace Common::Log {
// trims up to and including the last of ../, ..\, src/, src\ in a string
constexpr const char* TrimSourcePath(std::string_view source) {
@@ -66,6 +66,7 @@ enum class Class : ClassType {
Service_ARP, ///< The ARP service
Service_Audio, ///< The Audio (Audio control) service
Service_BCAT, ///< The BCAT service
Service_BGTC, ///< The BGTC (Background Task Controller) service
Service_BPC, ///< The BPC service
Service_BTDRV, ///< The Bluetooth driver service
Service_BTM, ///< The BTM service
@@ -147,28 +148,34 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
fmt::make_format_args(args...));
}
} // namespace Log
} // namespace Common::Log
#ifdef _DEBUG
#define LOG_TRACE(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, \
::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__)
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__VA_ARGS__)
#else
#define LOG_TRACE(log_class, fmt, ...) (void(0))
#endif
#define LOG_DEBUG(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, \
::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__)
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__VA_ARGS__)
#define LOG_INFO(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, \
::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__)
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__VA_ARGS__)
#define LOG_WARNING(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, \
::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__)
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__VA_ARGS__)
#define LOG_ERROR(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, \
::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__)
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__VA_ARGS__)
#define LOG_CRITICAL(log_class, ...) \
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, \
::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__)
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__VA_ARGS__)
+2 -2
View File
@@ -16,7 +16,7 @@
#include "common/logging/text_formatter.h"
#include "common/string_util.h"
namespace Log {
namespace Common::Log {
std::string FormatLogMessage(const Entry& entry) {
unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000);
@@ -108,4 +108,4 @@ void PrintColoredMessage(const Entry& entry) {
#undef ESC
#endif
}
} // namespace Log
} // namespace Common::Log
+2 -2
View File
@@ -7,7 +7,7 @@
#include <cstddef>
#include <string>
namespace Log {
namespace Common::Log {
struct Entry;
@@ -17,4 +17,4 @@ std::string FormatLogMessage(const Entry& entry);
void PrintMessage(const Entry& entry);
/// Prints the same message as `PrintMessage`, but colored according to the severity level.
void PrintColoredMessage(const Entry& entry);
} // namespace Log
} // namespace Common::Log
+2
View File
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Common {
/// Configure platform specific flags for Nvidia's driver
@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -7,10 +7,7 @@
#include "common/assert.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/hid/hid.h"
#include "core/settings.h"
#include "video_core/renderer_base.h"
#include "common/settings.h"
namespace Settings {
@@ -32,14 +29,6 @@ std::string GetTimeZoneString() {
return timezones[time_zone_index];
}
void Apply(Core::System& system) {
if (system.IsPoweredOn()) {
system.Renderer().RefreshBaseSettings();
}
Service::HID::ReloadInputDevices();
}
void LogSettings() {
const auto log_setting = [](std::string_view name, const auto& value) {
LOG_INFO(Config, "{}: {}", name, value);
@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -11,16 +11,13 @@
#include <optional>
#include <string>
#include <vector>
#include "common/common_types.h"
#include "input_common/settings.h"
namespace Core {
class System;
}
#include "common/common_types.h"
#include "common/settings_input.h"
namespace Settings {
enum class RendererBackend {
enum class RendererBackend : u32 {
OpenGL = 0,
Vulkan = 1,
};
@@ -31,7 +28,7 @@ enum class GPUAccuracy : u32 {
Extreme = 2,
};
enum class CPUAccuracy {
enum class CPUAccuracy : u32 {
Accurate = 0,
Unsafe = 1,
DebugMode = 2,
@@ -139,6 +136,7 @@ struct Values {
Setting<int> vulkan_device;
Setting<u16> resolution_factor{1};
Setting<int> fullscreen_mode;
Setting<int> aspect_ratio;
Setting<int> max_anisotropy;
Setting<bool> use_frame_limit;
@@ -222,6 +220,8 @@ struct Values {
bool quest_flag;
bool disable_macro_jit;
bool extended_logging;
bool use_debug_asserts;
bool use_auto_stub;
// Miscellaneous
std::string log_filter;
@@ -253,7 +253,6 @@ float Volume();
std::string GetTimeZoneString();
void Apply(Core::System& system);
void LogSettings();
// Restore the global state of all applicable settings in the Values struct
@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "input_common/settings.h"
#include "common/settings_input.h"
namespace Settings {
namespace NativeButton {
@@ -6,6 +6,7 @@
#include <array>
#include <string>
#include "common/common_types.h"
namespace Settings {
+9 -1
View File
@@ -83,11 +83,15 @@ public:
return true;
}
T PopWait() {
void Wait() {
if (Empty()) {
std::unique_lock lock{cv_mutex};
cv.wait(lock, [this]() { return !Empty(); });
}
}
T PopWait() {
Wait();
T t;
Pop(t);
return t;
@@ -156,6 +160,10 @@ public:
return spsc_queue.Pop(t);
}
void Wait() {
spsc_queue.Wait();
}
T PopWait() {
return spsc_queue.PopWait();
}
+9 -4
View File
@@ -141,6 +141,9 @@ add_library(core STATIC
hardware_interrupt_manager.h
hle/ipc.h
hle/ipc_helpers.h
hle/kernel/board/nintendo/nx/k_system_control.cpp
hle/kernel/board/nintendo/nx/k_system_control.h
hle/kernel/board/nintendo/nx/secure_monitor.h
hle/kernel/client_port.cpp
hle/kernel/client_port.h
hle/kernel/client_session.cpp
@@ -169,9 +172,13 @@ add_library(core STATIC
hle/kernel/k_memory_block.h
hle/kernel/k_memory_block_manager.cpp
hle/kernel/k_memory_block_manager.h
hle/kernel/k_memory_layout.cpp
hle/kernel/k_memory_layout.board.nintendo_nx.cpp
hle/kernel/k_memory_layout.h
hle/kernel/k_memory_manager.cpp
hle/kernel/k_memory_manager.h
hle/kernel/k_memory_region.h
hle/kernel/k_memory_region_type.h
hle/kernel/k_page_bitmap.h
hle/kernel/k_page_heap.cpp
hle/kernel/k_page_heap.h
@@ -196,11 +203,11 @@ add_library(core STATIC
hle/kernel/k_spin_lock.h
hle/kernel/k_synchronization_object.cpp
hle/kernel/k_synchronization_object.h
hle/kernel/k_system_control.cpp
hle/kernel/k_system_control.h
hle/kernel/k_thread.cpp
hle/kernel/k_thread.h
hle/kernel/k_thread_queue.h
hle/kernel/k_trace.h
hle/kernel/k_writable_event.cpp
hle/kernel/k_writable_event.h
hle/kernel/kernel.cpp
@@ -614,8 +621,6 @@ add_library(core STATIC
perf_stats.h
reporter.cpp
reporter.h
settings.cpp
settings.h
telemetry_session.cpp
telemetry_session.h
tools/freezer.cpp
@@ -666,7 +671,7 @@ endif()
create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls opus zip)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus zip)
if (YUZU_ENABLE_BOXCAT)
target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT)
+1 -1
View File
@@ -10,6 +10,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/page_table.h"
#include "common/settings.h"
#include "core/arm/cpu_interrupt_handler.h"
#include "core/arm/dynarmic/arm_dynarmic_32.h"
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
@@ -18,7 +19,6 @@
#include "core/core_timing.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"
#include "core/settings.h"
namespace Core {
+1 -1
View File
@@ -9,6 +9,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/page_table.h"
#include "common/settings.h"
#include "core/arm/cpu_interrupt_handler.h"
#include "core/arm/dynarmic/arm_dynarmic_64.h"
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
@@ -19,7 +20,6 @@
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"
#include "core/settings.h"
namespace Core {
+11 -2
View File
@@ -9,6 +9,7 @@
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "core/arm/exclusive_monitor.h"
#include "core/core.h"
@@ -36,6 +37,7 @@
#include "core/hle/service/apm/controller.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/glue/manager.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/time/time_manager.h"
@@ -45,7 +47,6 @@
#include "core/network/network.h"
#include "core/perf_stats.h"
#include "core/reporter.h"
#include "core/settings.h"
#include "core/telemetry_session.h"
#include "core/tools/freezer.h"
#include "video_core/renderer_base.h"
@@ -296,7 +297,7 @@ struct System::Impl {
exit_lock = false;
if (gpu_core) {
gpu_core->WaitIdle();
gpu_core->ShutDown();
}
services.reset();
@@ -774,4 +775,12 @@ void System::ExecuteProgram(std::size_t program_index) {
}
}
void System::ApplySettings() {
if (IsPoweredOn()) {
Renderer().RefreshBaseSettings();
}
Service::HID::ReloadInputDevices();
}
} // namespace Core
+3
View File
@@ -388,6 +388,9 @@ public:
*/
void ExecuteProgram(std::size_t program_index);
/// Applies any changes to settings to this core instance.
void ApplySettings();
private:
System();
+1 -1
View File
@@ -22,6 +22,7 @@
#include "common/file_util.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "core/crypto/aes_util.h"
#include "core/crypto/key_manager.h"
@@ -32,7 +33,6 @@
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h"
#include "core/settings.h"
namespace Core::Crypto {
namespace {
+8
View File
@@ -100,6 +100,14 @@ u64 NACP::GetDeviceSaveDataSize() const {
return raw.device_save_data_size;
}
u32 NACP::GetParentalControlFlag() const {
return raw.parental_control;
}
const std::array<u8, 0x20>& NACP::GetRatingAge() const {
return raw.rating_age;
}
std::vector<u8> NACP::GetRawBytes() const {
std::vector<u8> out(sizeof(RawNACP));
std::memcpy(out.data(), &raw, sizeof(RawNACP));
+2
View File
@@ -114,6 +114,8 @@ public:
std::vector<u8> GetRawBytes() const;
bool GetUserAccountSwitchLock() const;
u64 GetDeviceSaveDataSize() const;
u32 GetParentalControlFlag() const;
const std::array<u8, 0x20>& GetRatingAge() const;
private:
RawNACP raw{};
+1 -1
View File
@@ -10,6 +10,7 @@
#include "common/file_util.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/common_funcs.h"
@@ -25,7 +26,6 @@
#include "core/loader/loader.h"
#include "core/loader/nso.h"
#include "core/memory/cheat_engine.h"
#include "core/settings.h"
namespace FileSys {
namespace {
+1 -1
View File
@@ -2,9 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/settings.h"
#include "core/frontend/applets/profile_select.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/settings.h"
namespace Core::Frontend {
+1 -1
View File
@@ -4,9 +4,9 @@
#include <cmath>
#include <mutex>
#include "common/settings.h"
#include "core/frontend/emu_window.h"
#include "core/frontend/input.h"
#include "core/settings.h"
namespace Core::Frontend {
+1 -1
View File
@@ -5,8 +5,8 @@
#include <cmath>
#include "common/assert.h"
#include "common/settings.h"
#include "core/frontend/framebuffer_layout.h"
#include "core/settings.h"
namespace Layout {
@@ -0,0 +1,20 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// All architectures must define NumArchitectureDeviceRegions.
constexpr inline const auto NumArchitectureDeviceRegions = 3;
constexpr inline const auto KMemoryRegionType_Uart =
KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 0);
constexpr inline const auto KMemoryRegionType_InterruptCpuInterface =
KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 1)
.SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_InterruptDistributor =
KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 2)
.SetAttribute(KMemoryRegionAttr_NoUserMap);
static_assert(KMemoryRegionType_Uart.GetValue() == (0x1D));
static_assert(KMemoryRegionType_InterruptCpuInterface.GetValue() ==
(0x2D | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_InterruptDistributor.GetValue() ==
(0x4D | KMemoryRegionAttr_NoUserMap));
@@ -0,0 +1,52 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// All architectures must define NumBoardDeviceRegions.
constexpr inline const auto NumBoardDeviceRegions = 6;
// UNUSED: .Derive(NumBoardDeviceRegions, 0);
constexpr inline const auto KMemoryRegionType_MemoryController =
KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 1)
.SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_MemoryController1 =
KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 2)
.SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_MemoryController0 =
KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 3)
.SetAttribute(KMemoryRegionAttr_NoUserMap);
constexpr inline const auto KMemoryRegionType_PowerManagementController =
KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 4).DeriveTransition();
constexpr inline const auto KMemoryRegionType_LegacyLpsDevices =
KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 5);
static_assert(KMemoryRegionType_MemoryController.GetValue() ==
(0x55 | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_MemoryController1.GetValue() ==
(0x65 | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_MemoryController0.GetValue() ==
(0x95 | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_PowerManagementController.GetValue() == (0x1A5));
static_assert(KMemoryRegionType_LegacyLpsDevices.GetValue() == 0xC5);
constexpr inline const auto NumLegacyLpsDevices = 7;
constexpr inline const auto KMemoryRegionType_LegacyLpsExceptionVectors =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 0);
constexpr inline const auto KMemoryRegionType_LegacyLpsIram =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 1);
constexpr inline const auto KMemoryRegionType_LegacyLpsFlowController =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 2);
constexpr inline const auto KMemoryRegionType_LegacyLpsPrimaryICtlr =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 3);
constexpr inline const auto KMemoryRegionType_LegacyLpsSemaphore =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 4);
constexpr inline const auto KMemoryRegionType_LegacyLpsAtomics =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 5);
constexpr inline const auto KMemoryRegionType_LegacyLpsClkRst =
KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 6);
static_assert(KMemoryRegionType_LegacyLpsExceptionVectors.GetValue() == 0x3C5);
static_assert(KMemoryRegionType_LegacyLpsIram.GetValue() == 0x5C5);
static_assert(KMemoryRegionType_LegacyLpsFlowController.GetValue() == 0x6C5);
static_assert(KMemoryRegionType_LegacyLpsPrimaryICtlr.GetValue() == 0x9C5);
static_assert(KMemoryRegionType_LegacyLpsSemaphore.GetValue() == 0xAC5);
static_assert(KMemoryRegionType_LegacyLpsAtomics.GetValue() == 0xCC5);
static_assert(KMemoryRegionType_LegacyLpsClkRst.GetValue() == 0x11C5);
@@ -0,0 +1,164 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <random>
#include "common/common_sizes.h"
#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h"
#include "core/hle/kernel/k_trace.h"
namespace Kernel::Board::Nintendo::Nx {
namespace impl {
constexpr const std::size_t RequiredNonSecureSystemMemorySizeVi = 0x2238 * 4 * 1024;
constexpr const std::size_t RequiredNonSecureSystemMemorySizeNvservices = 0x710 * 4 * 1024;
constexpr const std::size_t RequiredNonSecureSystemMemorySizeMisc = 0x80 * 4 * 1024;
} // namespace impl
constexpr const std::size_t RequiredNonSecureSystemMemorySize =
impl::RequiredNonSecureSystemMemorySizeVi + impl::RequiredNonSecureSystemMemorySizeNvservices +
impl::RequiredNonSecureSystemMemorySizeMisc;
namespace {
u32 GetMemoryModeForInit() {
return 0x01;
}
u32 GetMemorySizeForInit() {
return 0;
}
Smc::MemoryArrangement GetMemoryArrangeForInit() {
switch (GetMemoryModeForInit() & 0x3F) {
case 0x01:
default:
return Smc::MemoryArrangement_4GB;
case 0x02:
return Smc::MemoryArrangement_4GBForAppletDev;
case 0x03:
return Smc::MemoryArrangement_4GBForSystemDev;
case 0x11:
return Smc::MemoryArrangement_6GB;
case 0x12:
return Smc::MemoryArrangement_6GBForAppletDev;
case 0x21:
return Smc::MemoryArrangement_8GB;
}
}
} // namespace
// Initialization.
size_t KSystemControl::Init::GetIntendedMemorySize() {
switch (GetMemorySizeForInit()) {
case Smc::MemorySize_4GB:
default: // All invalid modes should go to 4GB.
return Common::Size_4_GB;
case Smc::MemorySize_6GB:
return Common::Size_6_GB;
case Smc::MemorySize_8GB:
return Common::Size_8_GB;
}
}
PAddr KSystemControl::Init::GetKernelPhysicalBaseAddress(u64 base_address) {
return base_address;
}
bool KSystemControl::Init::ShouldIncreaseThreadResourceLimit() {
return true;
}
std::size_t KSystemControl::Init::GetApplicationPoolSize() {
// Get the base pool size.
const size_t base_pool_size = []() -> size_t {
switch (GetMemoryArrangeForInit()) {
case Smc::MemoryArrangement_4GB:
default:
return Common::Size_3285_MB;
case Smc::MemoryArrangement_4GBForAppletDev:
return Common::Size_2048_MB;
case Smc::MemoryArrangement_4GBForSystemDev:
return Common::Size_3285_MB;
case Smc::MemoryArrangement_6GB:
return Common::Size_4916_MB;
case Smc::MemoryArrangement_6GBForAppletDev:
return Common::Size_3285_MB;
case Smc::MemoryArrangement_8GB:
return Common::Size_4916_MB;
}
}();
// Return (possibly) adjusted size.
return base_pool_size;
}
size_t KSystemControl::Init::GetAppletPoolSize() {
// Get the base pool size.
const size_t base_pool_size = []() -> size_t {
switch (GetMemoryArrangeForInit()) {
case Smc::MemoryArrangement_4GB:
default:
return Common::Size_507_MB;
case Smc::MemoryArrangement_4GBForAppletDev:
return Common::Size_1554_MB;
case Smc::MemoryArrangement_4GBForSystemDev:
return Common::Size_448_MB;
case Smc::MemoryArrangement_6GB:
return Common::Size_562_MB;
case Smc::MemoryArrangement_6GBForAppletDev:
return Common::Size_2193_MB;
case Smc::MemoryArrangement_8GB:
return Common::Size_2193_MB;
}
}();
// Return (possibly) adjusted size.
constexpr size_t ExtraSystemMemoryForAtmosphere = Common::Size_33_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
}
size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() {
// Verify that our minimum is at least as large as Nintendo's.
constexpr size_t MinimumSize = RequiredNonSecureSystemMemorySize;
static_assert(MinimumSize >= 0x29C8000);
return MinimumSize;
}
namespace {
template <typename F>
u64 GenerateUniformRange(u64 min, u64 max, F f) {
// Handle the case where the difference is too large to represent.
if (max == std::numeric_limits<u64>::max() && min == std::numeric_limits<u64>::min()) {
return f();
}
// Iterate until we get a value in range.
const u64 range_size = ((max + 1) - min);
const u64 effective_max = (std::numeric_limits<u64>::max() / range_size) * range_size;
while (true) {
if (const u64 rnd = f(); rnd < effective_max) {
return min + (rnd % range_size);
}
}
}
} // Anonymous namespace
u64 KSystemControl::GenerateRandomU64() {
static std::random_device device;
static std::mt19937 gen(device());
static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
return distribution(gen);
}
u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
return GenerateUniformRange(min, max, GenerateRandomU64);
}
} // namespace Kernel::Board::Nintendo::Nx
@@ -0,0 +1,28 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace Kernel::Board::Nintendo::Nx {
class KSystemControl {
public:
class Init {
public:
// Initialization.
static std::size_t GetIntendedMemorySize();
static PAddr GetKernelPhysicalBaseAddress(u64 base_address);
static bool ShouldIncreaseThreadResourceLimit();
static std::size_t GetApplicationPoolSize();
static std::size_t GetAppletPoolSize();
static std::size_t GetMinimumNonSecureSystemPoolSize();
};
static u64 GenerateRandomRange(u64 min, u64 max);
static u64 GenerateRandomU64();
};
} // namespace Kernel::Board::Nintendo::Nx
@@ -0,0 +1,26 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace Kernel::Board::Nintendo::Nx::Smc {
enum MemorySize {
MemorySize_4GB = 0,
MemorySize_6GB = 1,
MemorySize_8GB = 2,
};
enum MemoryArrangement {
MemoryArrangement_4GB = 0,
MemoryArrangement_4GBForAppletDev = 1,
MemoryArrangement_4GBForSystemDev = 2,
MemoryArrangement_6GB = 3,
MemoryArrangement_6GBForAppletDev = 4,
MemoryArrangement_8GB = 5,
};
} // namespace Kernel::Board::Nintendo::Nx::Smc
+16 -27
View File
@@ -5,45 +5,34 @@
#include <array>
#include "common/assert.h"
#include "common/common_sizes.h"
#include "core/hle/kernel/k_address_space_info.h"
namespace Kernel {
namespace {
enum : u64 {
Size_1_MB = 0x100000,
Size_2_MB = 2 * Size_1_MB,
Size_128_MB = 128 * Size_1_MB,
Size_1_GB = 0x40000000,
Size_2_GB = 2 * Size_1_GB,
Size_4_GB = 4 * Size_1_GB,
Size_6_GB = 6 * Size_1_GB,
Size_64_GB = 64 * Size_1_GB,
Size_512_GB = 512 * Size_1_GB,
Invalid = std::numeric_limits<u64>::max(),
};
// clang-format off
constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{
{ .bit_width = 32, .address = Size_2_MB , .size = Size_1_GB - Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, },
{ .bit_width = 32, .address = Size_1_GB , .size = Size_4_GB - Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
{ .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, },
{ .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, },
{ .bit_width = 36, .address = Size_128_MB, .size = Size_2_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, },
{ .bit_width = 36, .address = Size_2_GB , .size = Size_64_GB - Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
{ .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
{ .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, },
{ .bit_width = 39, .address = Size_128_MB, .size = Size_512_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, },
{ .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall },
{ .bit_width = 39, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
{ .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, },
{ .bit_width = 39, .address = Invalid , .size = Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, },
{ .bit_width = 32, .address = Common::Size_2_MB , .size = Common::Size_1_GB - Common::Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, },
{ .bit_width = 32, .address = Common::Size_1_GB , .size = Common::Size_4_GB - Common::Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
{ .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, },
{ .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, },
{ .bit_width = 36, .address = Common::Size_128_MB , .size = Common::Size_2_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, },
{ .bit_width = 36, .address = Common::Size_2_GB , .size = Common::Size_64_GB - Common::Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
{ .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
{ .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, },
{ .bit_width = 39, .address = Common::Size_128_MB , .size = Common::Size_512_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, },
{ .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall },
{ .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
{ .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, },
{ .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, },
}};
// clang-format on
constexpr bool IsAllowedIndexForAddress(std::size_t index) {
return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Invalid;
return index < AddressSpaceInfos.size() &&
AddressSpaceInfos[index].address != Common::Size_Invalid;
}
using IndexArray =
@@ -0,0 +1,199 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/alignment.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_system_control.h"
#include "core/hle/kernel/k_trace.h"
namespace Kernel {
namespace {
constexpr size_t CarveoutAlignment = 0x20000;
constexpr size_t CarveoutSizeMax = (512ULL * 1024 * 1024) - CarveoutAlignment;
bool SetupPowerManagementControllerMemoryRegion(KMemoryLayout& memory_layout) {
// Above firmware 2.0.0, the PMC is not mappable.
return memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x7000E000, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap) &&
memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x7000E400, 0xC00,
KMemoryRegionType_PowerManagementController | KMemoryRegionAttr_NoUserMap);
}
void InsertPoolPartitionRegionIntoBothTrees(KMemoryLayout& memory_layout, size_t start, size_t size,
KMemoryRegionType phys_type,
KMemoryRegionType virt_type, u32& cur_attr) {
const u32 attr = cur_attr++;
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(start, size,
static_cast<u32>(phys_type), attr));
const KMemoryRegion* phys = memory_layout.GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(
static_cast<u32>(phys_type), attr);
ASSERT(phys != nullptr);
ASSERT(phys->GetEndAddress() != 0);
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(phys->GetPairAddress(), size,
static_cast<u32>(virt_type), attr));
}
} // namespace
namespace Init {
void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout) {
ASSERT(SetupPowerManagementControllerMemoryRegion(memory_layout));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x70019000, 0x1000, KMemoryRegionType_MemoryController | KMemoryRegionAttr_NoUserMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x7001C000, 0x1000, KMemoryRegionType_MemoryController0 | KMemoryRegionAttr_NoUserMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x7001D000, 0x1000, KMemoryRegionType_MemoryController1 | KMemoryRegionAttr_NoUserMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x50040000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x50041000, 0x1000,
KMemoryRegionType_InterruptDistributor | KMemoryRegionAttr_ShouldKernelMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x50042000, 0x1000,
KMemoryRegionType_InterruptCpuInterface | KMemoryRegionAttr_ShouldKernelMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x50043000, 0x1D000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
// Map IRAM unconditionally, to support debug-logging-to-iram build config.
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x40000000, 0x40000, KMemoryRegionType_LegacyLpsIram | KMemoryRegionAttr_ShouldKernelMap));
// Above firmware 2.0.0, prevent mapping the bpmp exception vectors or the ipatch region.
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x6000F000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
0x6001DC00, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap));
}
void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout) {
const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize();
const PAddr physical_memory_base_address =
KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress);
// Insert blocks into the tree.
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
physical_memory_base_address, intended_memory_size, KMemoryRegionType_Dram));
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
physical_memory_base_address, ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly));
// Insert the KTrace block at the end of Dram, if KTrace is enabled.
static_assert(!IsKTraceEnabled || KTraceBufferSize > 0);
if constexpr (IsKTraceEnabled) {
const PAddr ktrace_buffer_phys_addr =
physical_memory_base_address + intended_memory_size - KTraceBufferSize;
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
ktrace_buffer_phys_addr, KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer));
}
}
void SetupPoolPartitionMemoryRegions(KMemoryLayout& memory_layout) {
// Start by identifying the extents of the DRAM memory region.
const auto dram_extents = memory_layout.GetMainMemoryPhysicalExtents();
ASSERT(dram_extents.GetEndAddress() != 0);
// Determine the end of the pool region.
const u64 pool_end = dram_extents.GetEndAddress() - KTraceBufferSize;
// Find the start of the kernel DRAM region.
const KMemoryRegion* kernel_dram_region =
memory_layout.GetPhysicalMemoryRegionTree().FindFirstDerived(
KMemoryRegionType_DramKernelBase);
ASSERT(kernel_dram_region != nullptr);
const u64 kernel_dram_start = kernel_dram_region->GetAddress();
ASSERT(Common::IsAligned(kernel_dram_start, CarveoutAlignment));
// Find the start of the pool partitions region.
const KMemoryRegion* pool_partitions_region =
memory_layout.GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(
KMemoryRegionType_DramPoolPartition, 0);
ASSERT(pool_partitions_region != nullptr);
const u64 pool_partitions_start = pool_partitions_region->GetAddress();
// Setup the pool partition layouts.
// On 5.0.0+, setup modern 4-pool-partition layout.
// Get Application and Applet pool sizes.
const size_t application_pool_size = KSystemControl::Init::GetApplicationPoolSize();
const size_t applet_pool_size = KSystemControl::Init::GetAppletPoolSize();
const size_t unsafe_system_pool_min_size =
KSystemControl::Init::GetMinimumNonSecureSystemPoolSize();
// Decide on starting addresses for our pools.
const u64 application_pool_start = pool_end - application_pool_size;
const u64 applet_pool_start = application_pool_start - applet_pool_size;
const u64 unsafe_system_pool_start = std::min(
kernel_dram_start + CarveoutSizeMax,
Common::AlignDown(applet_pool_start - unsafe_system_pool_min_size, CarveoutAlignment));
const size_t unsafe_system_pool_size = applet_pool_start - unsafe_system_pool_start;
// We want to arrange application pool depending on where the middle of dram is.
const u64 dram_midpoint = (dram_extents.GetAddress() + dram_extents.GetEndAddress()) / 2;
u32 cur_pool_attr = 0;
size_t total_overhead_size = 0;
if (dram_extents.GetEndAddress() <= dram_midpoint || dram_midpoint <= application_pool_start) {
InsertPoolPartitionRegionIntoBothTrees(
memory_layout, application_pool_start, application_pool_size,
KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool,
cur_pool_attr);
total_overhead_size +=
KMemoryManager::CalculateManagementOverheadSize(application_pool_size);
} else {
const size_t first_application_pool_size = dram_midpoint - application_pool_start;
const size_t second_application_pool_size =
application_pool_start + application_pool_size - dram_midpoint;
InsertPoolPartitionRegionIntoBothTrees(
memory_layout, application_pool_start, first_application_pool_size,
KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool,
cur_pool_attr);
InsertPoolPartitionRegionIntoBothTrees(
memory_layout, dram_midpoint, second_application_pool_size,
KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool,
cur_pool_attr);
total_overhead_size +=
KMemoryManager::CalculateManagementOverheadSize(first_application_pool_size);
total_overhead_size +=
KMemoryManager::CalculateManagementOverheadSize(second_application_pool_size);
}
// Insert the applet pool.
InsertPoolPartitionRegionIntoBothTrees(memory_layout, applet_pool_start, applet_pool_size,
KMemoryRegionType_DramAppletPool,
KMemoryRegionType_VirtualDramAppletPool, cur_pool_attr);
total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(applet_pool_size);
// Insert the nonsecure system pool.
InsertPoolPartitionRegionIntoBothTrees(
memory_layout, unsafe_system_pool_start, unsafe_system_pool_size,
KMemoryRegionType_DramSystemNonSecurePool, KMemoryRegionType_VirtualDramSystemNonSecurePool,
cur_pool_attr);
total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(unsafe_system_pool_size);
// Insert the pool management region.
total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(
(unsafe_system_pool_start - pool_partitions_start) - total_overhead_size);
const u64 pool_management_start = unsafe_system_pool_start - total_overhead_size;
const size_t pool_management_size = total_overhead_size;
u32 pool_management_attr = 0;
InsertPoolPartitionRegionIntoBothTrees(
memory_layout, pool_management_start, pool_management_size,
KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement,
pool_management_attr);
// Insert the system pool.
const u64 system_pool_size = pool_management_start - pool_partitions_start;
InsertPoolPartitionRegionIntoBothTrees(memory_layout, pool_partitions_start, system_pool_size,
KMemoryRegionType_DramSystemPool,
KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr);
}
} // namespace Init
} // namespace Kernel
+166
View File
@@ -0,0 +1,166 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <array>
#include "common/alignment.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_system_control.h"
namespace Kernel {
namespace {
template <typename... Args>
KMemoryRegion* AllocateRegion(KMemoryRegionAllocator& memory_region_allocator, Args&&... args) {
return memory_region_allocator.Allocate(std::forward<Args>(args)...);
}
} // namespace
KMemoryRegionTree::KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_)
: memory_region_allocator{memory_region_allocator_} {}
void KMemoryRegionTree::InsertDirectly(u64 address, u64 last_address, u32 attr, u32 type_id) {
this->insert(*AllocateRegion(memory_region_allocator, address, last_address, attr, type_id));
}
bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) {
// Locate the memory region that contains the address.
KMemoryRegion* found = this->FindModifiable(address);
// We require that the old attr is correct.
if (found->GetAttributes() != old_attr) {
return false;
}
// We further require that the region can be split from the old region.
const u64 inserted_region_end = address + size;
const u64 inserted_region_last = inserted_region_end - 1;
if (found->GetLastAddress() < inserted_region_last) {
return false;
}
// Further, we require that the type id is a valid transformation.
if (!found->CanDerive(type_id)) {
return false;
}
// Cache information from the region before we remove it.
const u64 old_address = found->GetAddress();
const u64 old_last = found->GetLastAddress();
const u64 old_pair = found->GetPairAddress();
const u32 old_type = found->GetType();
// Erase the existing region from the tree.
this->erase(this->iterator_to(*found));
// Insert the new region into the tree.
if (old_address == address) {
// Reuse the old object for the new region, if we can.
found->Reset(address, inserted_region_last, old_pair, new_attr, type_id);
this->insert(*found);
} else {
// If we can't re-use, adjust the old region.
found->Reset(old_address, address - 1, old_pair, old_attr, old_type);
this->insert(*found);
// Insert a new region for the split.
const u64 new_pair = (old_pair != std::numeric_limits<u64>::max())
? old_pair + (address - old_address)
: old_pair;
this->insert(*AllocateRegion(memory_region_allocator, address, inserted_region_last,
new_pair, new_attr, type_id));
}
// If we need to insert a region after the region, do so.
if (old_last != inserted_region_last) {
const u64 after_pair = (old_pair != std::numeric_limits<u64>::max())
? old_pair + (inserted_region_end - old_address)
: old_pair;
this->insert(*AllocateRegion(memory_region_allocator, inserted_region_end, old_last,
after_pair, old_attr, old_type));
}
return true;
}
VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id) {
// We want to find the total extents of the type id.
const auto extents = this->GetDerivedRegionExtents(static_cast<KMemoryRegionType>(type_id));
// Ensure that our alignment is correct.
ASSERT(Common::IsAligned(extents.GetAddress(), alignment));
const u64 first_address = extents.GetAddress();
const u64 last_address = extents.GetLastAddress();
const u64 first_index = first_address / alignment;
const u64 last_index = last_address / alignment;
while (true) {
const u64 candidate =
KSystemControl::GenerateRandomRange(first_index, last_index) * alignment;
// Ensure that the candidate doesn't overflow with the size.
if (!(candidate < candidate + size)) {
continue;
}
const u64 candidate_last = candidate + size - 1;
// Ensure that the candidate fits within the region.
if (candidate_last > last_address) {
continue;
}
// Locate the candidate region, and ensure it fits and has the correct type id.
if (const auto& candidate_region = *this->Find(candidate);
!(candidate_last <= candidate_region.GetLastAddress() &&
candidate_region.GetType() == type_id)) {
continue;
}
return candidate;
}
}
KMemoryLayout::KMemoryLayout()
: virtual_tree{memory_region_allocator}, physical_tree{memory_region_allocator},
virtual_linear_tree{memory_region_allocator}, physical_linear_tree{memory_region_allocator} {}
void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
VAddr linear_virtual_start) {
// Set static differences.
linear_phys_to_virt_diff = linear_virtual_start - aligned_linear_phys_start;
linear_virt_to_phys_diff = aligned_linear_phys_start - linear_virtual_start;
// Initialize linear trees.
for (auto& region : GetPhysicalMemoryRegionTree()) {
if (region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
GetPhysicalLinearMemoryRegionTree().InsertDirectly(
region.GetAddress(), region.GetLastAddress(), region.GetAttributes(),
region.GetType());
}
}
for (auto& region : GetVirtualMemoryRegionTree()) {
if (region.IsDerivedFrom(KMemoryRegionType_Dram)) {
GetVirtualLinearMemoryRegionTree().InsertDirectly(
region.GetAddress(), region.GetLastAddress(), region.GetAttributes(),
region.GetType());
}
}
}
size_t KMemoryLayout::GetResourceRegionSizeForInit() {
// Calculate resource region size based on whether we allow extra threads.
const bool use_extra_resources = KSystemControl::Init::ShouldIncreaseThreadResourceLimit();
size_t resource_region_size =
KernelResourceSize + (use_extra_resources ? KernelSlabHeapAdditionalSize : 0);
return resource_region_size;
}
} // namespace Kernel
+358 -49
View File
@@ -1,23 +1,69 @@
// Copyright 2020 yuzu Emulator Project
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <utility>
#include "common/alignment.h"
#include "common/common_sizes.h"
#include "common/common_types.h"
#include "core/device_memory.h"
#include "core/hle/kernel/k_memory_region.h"
#include "core/hle/kernel/k_memory_region_type.h"
#include "core/hle/kernel/memory_types.h"
namespace Kernel {
constexpr std::size_t KernelAslrAlignment = 2 * 1024 * 1024;
constexpr std::size_t L1BlockSize = Common::Size_1_GB;
constexpr std::size_t L2BlockSize = Common::Size_2_MB;
constexpr std::size_t GetMaximumOverheadSize(std::size_t size) {
return (Common::DivideUp(size, L1BlockSize) + Common::DivideUp(size, L2BlockSize)) * PageSize;
}
constexpr std::size_t MainMemorySize = Common::Size_4_GB;
constexpr std::size_t MainMemorySizeMax = Common::Size_8_GB;
constexpr std::size_t ReservedEarlyDramSize = 0x60000;
constexpr std::size_t DramPhysicalAddress = 0x80000000;
constexpr std::size_t KernelAslrAlignment = Common::Size_2_MB;
constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39;
constexpr std::size_t KernelPhysicalAddressSpaceWidth = 1ULL << 48;
constexpr std::size_t KernelVirtualAddressSpaceBase = 0ULL - KernelVirtualAddressSpaceWidth;
constexpr std::size_t KernelVirtualAddressSpaceEnd =
KernelVirtualAddressSpaceBase + (KernelVirtualAddressSpaceWidth - KernelAslrAlignment);
constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceEnd - 1;
constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceEnd - 1ULL;
constexpr std::size_t KernelVirtualAddressSpaceSize =
KernelVirtualAddressSpaceEnd - KernelVirtualAddressSpaceBase;
constexpr std::size_t KernelVirtualAddressCodeBase = KernelVirtualAddressSpaceBase;
constexpr std::size_t KernelVirtualAddressCodeSize = 0x62000;
constexpr std::size_t KernelVirtualAddressCodeEnd =
KernelVirtualAddressCodeBase + KernelVirtualAddressCodeSize;
constexpr std::size_t KernelPhysicalAddressSpaceBase = 0ULL;
constexpr std::size_t KernelPhysicalAddressSpaceEnd =
KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceWidth;
constexpr std::size_t KernelPhysicalAddressSpaceLast = KernelPhysicalAddressSpaceEnd - 1ULL;
constexpr std::size_t KernelPhysicalAddressSpaceSize =
KernelPhysicalAddressSpaceEnd - KernelPhysicalAddressSpaceBase;
constexpr std::size_t KernelPhysicalAddressCodeBase = DramPhysicalAddress + ReservedEarlyDramSize;
constexpr std::size_t KernelPageTableHeapSize = GetMaximumOverheadSize(MainMemorySizeMax);
constexpr std::size_t KernelInitialPageHeapSize = Common::Size_128_KB;
constexpr std::size_t KernelSlabHeapDataSize = Common::Size_5_MB;
constexpr std::size_t KernelSlabHeapGapsSize = Common::Size_2_MB - Common::Size_64_KB;
constexpr std::size_t KernelSlabHeapSize = KernelSlabHeapDataSize + KernelSlabHeapGapsSize;
// NOTE: This is calculated from KThread slab counts, assuming KThread size <= 0x860.
constexpr std::size_t KernelSlabHeapAdditionalSize = 0x68000ULL;
constexpr std::size_t KernelResourceSize =
KernelPageTableHeapSize + KernelInitialPageHeapSize + KernelSlabHeapSize;
constexpr bool IsKernelAddressKey(VAddr key) {
return KernelVirtualAddressSpaceBase <= key && key <= KernelVirtualAddressSpaceLast;
@@ -27,64 +73,327 @@ constexpr bool IsKernelAddress(VAddr address) {
return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd;
}
class KMemoryRegion final {
friend class KMemoryLayout;
public:
constexpr PAddr StartAddress() const {
return start_address;
}
constexpr PAddr EndAddress() const {
return end_address;
}
private:
constexpr KMemoryRegion() = default;
constexpr KMemoryRegion(PAddr start_address, PAddr end_address)
: start_address{start_address}, end_address{end_address} {}
const PAddr start_address{};
const PAddr end_address{};
};
class KMemoryLayout final {
public:
constexpr const KMemoryRegion& Application() const {
return application;
KMemoryLayout();
KMemoryRegionTree& GetVirtualMemoryRegionTree() {
return virtual_tree;
}
const KMemoryRegionTree& GetVirtualMemoryRegionTree() const {
return virtual_tree;
}
KMemoryRegionTree& GetPhysicalMemoryRegionTree() {
return physical_tree;
}
const KMemoryRegionTree& GetPhysicalMemoryRegionTree() const {
return physical_tree;
}
KMemoryRegionTree& GetVirtualLinearMemoryRegionTree() {
return virtual_linear_tree;
}
const KMemoryRegionTree& GetVirtualLinearMemoryRegionTree() const {
return virtual_linear_tree;
}
KMemoryRegionTree& GetPhysicalLinearMemoryRegionTree() {
return physical_linear_tree;
}
const KMemoryRegionTree& GetPhysicalLinearMemoryRegionTree() const {
return physical_linear_tree;
}
constexpr const KMemoryRegion& Applet() const {
return applet;
VAddr GetLinearVirtualAddress(PAddr address) const {
return address + linear_phys_to_virt_diff;
}
PAddr GetLinearPhysicalAddress(VAddr address) const {
return address + linear_virt_to_phys_diff;
}
constexpr const KMemoryRegion& System() const {
return system;
const KMemoryRegion* FindVirtual(VAddr address) const {
return Find(address, GetVirtualMemoryRegionTree());
}
const KMemoryRegion* FindPhysical(PAddr address) const {
return Find(address, GetPhysicalMemoryRegionTree());
}
static constexpr KMemoryLayout GetDefaultLayout() {
constexpr std::size_t application_size{0xcd500000};
constexpr std::size_t applet_size{0x1fb00000};
constexpr PAddr application_start_address{Core::DramMemoryMap::End - application_size};
constexpr PAddr application_end_address{Core::DramMemoryMap::End};
constexpr PAddr applet_start_address{application_start_address - applet_size};
constexpr PAddr applet_end_address{applet_start_address + applet_size};
constexpr PAddr system_start_address{Core::DramMemoryMap::SlabHeapEnd};
constexpr PAddr system_end_address{applet_start_address};
return {application_start_address, application_end_address, applet_start_address,
applet_end_address, system_start_address, system_end_address};
const KMemoryRegion* FindVirtualLinear(VAddr address) const {
return Find(address, GetVirtualLinearMemoryRegionTree());
}
const KMemoryRegion* FindPhysicalLinear(PAddr address) const {
return Find(address, GetPhysicalLinearMemoryRegionTree());
}
VAddr GetMainStackTopAddress(s32 core_id) const {
return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscMainStack);
}
VAddr GetIdleStackTopAddress(s32 core_id) const {
return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscIdleStack);
}
VAddr GetExceptionStackTopAddress(s32 core_id) const {
return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscExceptionStack);
}
VAddr GetSlabRegionAddress() const {
return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelSlab))
.GetAddress();
}
const KMemoryRegion& GetDeviceRegion(KMemoryRegionType type) const {
return Dereference(GetPhysicalMemoryRegionTree().FindFirstDerived(type));
}
PAddr GetDevicePhysicalAddress(KMemoryRegionType type) const {
return GetDeviceRegion(type).GetAddress();
}
VAddr GetDeviceVirtualAddress(KMemoryRegionType type) const {
return GetDeviceRegion(type).GetPairAddress();
}
const KMemoryRegion& GetPoolManagementRegion() const {
return Dereference(
GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_VirtualDramPoolManagement));
}
const KMemoryRegion& GetPageTableHeapRegion() const {
return Dereference(
GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_VirtualDramKernelPtHeap));
}
const KMemoryRegion& GetKernelStackRegion() const {
return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelStack));
}
const KMemoryRegion& GetTempRegion() const {
return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelTemp));
}
const KMemoryRegion& GetKernelTraceBufferRegion() const {
return Dereference(GetVirtualLinearMemoryRegionTree().FindByType(
KMemoryRegionType_VirtualDramKernelTraceBuffer));
}
const KMemoryRegion& GetVirtualLinearRegion(VAddr address) const {
return Dereference(FindVirtualLinear(address));
}
const KMemoryRegion* GetPhysicalKernelTraceBufferRegion() const {
return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_KernelTraceBuffer);
}
const KMemoryRegion* GetPhysicalOnMemoryBootImageRegion() const {
return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_OnMemoryBootImage);
}
const KMemoryRegion* GetPhysicalDTBRegion() const {
return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DTB);
}
bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
KMemoryRegionType_DramUserPool);
}
bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address) const {
return IsTypedAddress(region, address, GetVirtualLinearMemoryRegionTree(),
KMemoryRegionType_VirtualDramUserPool);
}
bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address, size_t size) const {
return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
KMemoryRegionType_DramUserPool);
}
bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address, size_t size) const {
return IsTypedAddress(region, address, size, GetVirtualLinearMemoryRegionTree(),
KMemoryRegionType_VirtualDramUserPool);
}
bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped));
}
bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address,
size_t size) const {
return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped));
}
std::pair<size_t, size_t> GetTotalAndKernelMemorySizes() const {
size_t total_size = 0, kernel_size = 0;
for (const auto& region : GetPhysicalMemoryRegionTree()) {
if (region.IsDerivedFrom(KMemoryRegionType_Dram)) {
total_size += region.GetSize();
if (!region.IsDerivedFrom(KMemoryRegionType_DramUserPool)) {
kernel_size += region.GetSize();
}
}
}
return std::make_pair(total_size, kernel_size);
}
void InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
VAddr linear_virtual_start);
static size_t GetResourceRegionSizeForInit();
auto GetKernelRegionExtents() const {
return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel);
}
auto GetKernelCodeRegionExtents() const {
return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelCode);
}
auto GetKernelStackRegionExtents() const {
return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelStack);
}
auto GetKernelMiscRegionExtents() const {
return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelMisc);
}
auto GetKernelSlabRegionExtents() const {
return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelSlab);
}
auto GetLinearRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionAttr_LinearMapped);
}
auto GetLinearRegionVirtualExtents() const {
const auto physical = GetLinearRegionPhysicalExtents();
return KMemoryRegion(GetLinearVirtualAddress(physical.GetAddress()),
GetLinearVirtualAddress(physical.GetLastAddress()), 0,
KMemoryRegionType_None);
}
auto GetMainMemoryPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Dram);
}
auto GetCarveoutRegionExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionAttr_CarveoutProtected);
}
auto GetKernelRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramKernelBase);
}
auto GetKernelCodeRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramKernelCode);
}
auto GetKernelSlabRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramKernelSlab);
}
auto GetKernelPageTableHeapRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramKernelPtHeap);
}
auto GetKernelInitPageTableRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramKernelInitPt);
}
auto GetKernelPoolManagementRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramPoolManagement);
}
auto GetKernelPoolPartitionRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramPoolPartition);
}
auto GetKernelSystemPoolRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramSystemPool);
}
auto GetKernelSystemNonSecurePoolRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramSystemNonSecurePool);
}
auto GetKernelAppletPoolRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramAppletPool);
}
auto GetKernelApplicationPoolRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_DramApplicationPool);
}
auto GetKernelTraceBufferRegionPhysicalExtents() const {
return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionType_KernelTraceBuffer);
}
private:
constexpr KMemoryLayout(PAddr application_start_address, std::size_t application_size,
PAddr applet_start_address, std::size_t applet_size,
PAddr system_start_address, std::size_t system_size)
: application{application_start_address, application_size},
applet{applet_start_address, applet_size}, system{system_start_address, system_size} {}
template <typename AddressType>
static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address,
const KMemoryRegionTree& tree, KMemoryRegionType type) {
// Check if the cached region already contains the address.
if (region != nullptr && region->Contains(address)) {
return true;
}
const KMemoryRegion application;
const KMemoryRegion applet;
const KMemoryRegion system;
// Find the containing region, and update the cache.
if (const KMemoryRegion* found = tree.Find(address);
found != nullptr && found->IsDerivedFrom(type)) {
region = found;
return true;
} else {
return false;
}
}
template <typename AddressType>
static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, size_t size,
const KMemoryRegionTree& tree, KMemoryRegionType type) {
// Get the end of the checked region.
const u64 last_address = address + size - 1;
// Walk the tree to verify the region is correct.
const KMemoryRegion* cur =
(region != nullptr && region->Contains(address)) ? region : tree.Find(address);
while (cur != nullptr && cur->IsDerivedFrom(type)) {
if (last_address <= cur->GetLastAddress()) {
region = cur;
return true;
}
cur = cur->GetNext();
}
return false;
}
template <typename AddressType>
static const KMemoryRegion* Find(AddressType address, const KMemoryRegionTree& tree) {
return tree.Find(address);
}
static KMemoryRegion& Dereference(KMemoryRegion* region) {
ASSERT(region != nullptr);
return *region;
}
static const KMemoryRegion& Dereference(const KMemoryRegion* region) {
ASSERT(region != nullptr);
return *region;
}
VAddr GetStackTopAddress(s32 core_id, KMemoryRegionType type) const {
const auto& region = Dereference(
GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id)));
ASSERT(region.GetEndAddress() != 0);
return region.GetEndAddress();
}
private:
u64 linear_phys_to_virt_diff{};
u64 linear_virt_to_phys_diff{};
KMemoryRegionAllocator memory_region_allocator;
KMemoryRegionTree virtual_tree;
KMemoryRegionTree physical_tree;
KMemoryRegionTree virtual_linear_tree;
KMemoryRegionTree physical_linear_tree;
};
namespace Init {
// These should be generic, regardless of board.
void SetupPoolPartitionMemoryRegions(KMemoryLayout& memory_layout);
// These may be implemented in a board-specific manner.
void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout);
void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout);
} // namespace Init
} // namespace Kernel
+12
View File
@@ -173,4 +173,16 @@ ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_page
return RESULT_SUCCESS;
}
std::size_t KMemoryManager::Impl::CalculateManagementOverheadSize(std::size_t region_size) {
const std::size_t ref_count_size = (region_size / PageSize) * sizeof(u16);
const std::size_t optimize_map_size =
(Common::AlignUp((region_size / PageSize), Common::BitSize<u64>()) /
Common::BitSize<u64>()) *
sizeof(u64);
const std::size_t manager_meta_size =
Common::AlignUp(optimize_map_size + ref_count_size, PageSize);
const std::size_t page_heap_size = KPageHeap::CalculateManagementOverheadSize(region_size);
return manager_meta_size + page_heap_size;
}
} // namespace Kernel
+18
View File
@@ -29,6 +29,10 @@ public:
Shift = 4,
Mask = (0xF << Shift),
// Aliases.
Unsafe = Application,
Secure = System,
};
enum class Direction : u32 {
@@ -56,6 +60,10 @@ public:
static constexpr std::size_t MaxManagerCount = 10;
public:
static std::size_t CalculateManagementOverheadSize(std::size_t region_size) {
return Impl::CalculateManagementOverheadSize(region_size);
}
static constexpr u32 EncodeOption(Pool pool, Direction dir) {
return (static_cast<u32>(pool) << static_cast<u32>(Pool::Shift)) |
(static_cast<u32>(dir) << static_cast<u32>(Direction::Shift));
@@ -85,6 +93,16 @@ private:
KPageHeap heap;
Pool pool{};
public:
static std::size_t CalculateManagementOverheadSize(std::size_t region_size);
static constexpr std::size_t CalculateOptimizedProcessOverheadSize(
std::size_t region_size) {
return (Common::AlignUp((region_size / PageSize), Common::BitSize<u64>()) /
Common::BitSize<u64>()) *
sizeof(u64);
}
public:
Impl() = default;
+350
View File
@@ -0,0 +1,350 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/assert.h"
#include "common/common_types.h"
#include "common/intrusive_red_black_tree.h"
#include "core/hle/kernel/k_memory_region_type.h"
namespace Kernel {
class KMemoryRegionAllocator;
class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>,
NonCopyable {
friend class KMemoryRegionTree;
public:
constexpr KMemoryRegion() = default;
constexpr KMemoryRegion(u64 address_, u64 last_address_)
: address{address_}, last_address{last_address_} {}
constexpr KMemoryRegion(u64 address_, u64 last_address_, u64 pair_address_, u32 attributes_,
u32 type_id_)
: address(address_), last_address(last_address_), pair_address(pair_address_),
attributes(attributes_), type_id(type_id_) {}
constexpr KMemoryRegion(u64 address_, u64 last_address_, u32 attributes_, u32 type_id_)
: KMemoryRegion(address_, last_address_, std::numeric_limits<u64>::max(), attributes_,
type_id_) {}
static constexpr int Compare(const KMemoryRegion& lhs, const KMemoryRegion& rhs) {
if (lhs.GetAddress() < rhs.GetAddress()) {
return -1;
} else if (lhs.GetAddress() <= rhs.GetLastAddress()) {
return 0;
} else {
return 1;
}
}
private:
constexpr void Reset(u64 a, u64 la, u64 p, u32 r, u32 t) {
address = a;
pair_address = p;
last_address = la;
attributes = r;
type_id = t;
}
public:
constexpr u64 GetAddress() const {
return address;
}
constexpr u64 GetPairAddress() const {
return pair_address;
}
constexpr u64 GetLastAddress() const {
return last_address;
}
constexpr u64 GetEndAddress() const {
return this->GetLastAddress() + 1;
}
constexpr size_t GetSize() const {
return this->GetEndAddress() - this->GetAddress();
}
constexpr u32 GetAttributes() const {
return attributes;
}
constexpr u32 GetType() const {
return type_id;
}
constexpr void SetType(u32 type) {
ASSERT(this->CanDerive(type));
type_id = type;
}
constexpr bool Contains(u64 address) const {
ASSERT(this->GetEndAddress() != 0);
return this->GetAddress() <= address && address <= this->GetLastAddress();
}
constexpr bool IsDerivedFrom(u32 type) const {
return (this->GetType() | type) == this->GetType();
}
constexpr bool HasTypeAttribute(u32 attr) const {
return (this->GetType() | attr) == this->GetType();
}
constexpr bool CanDerive(u32 type) const {
return (this->GetType() | type) == type;
}
constexpr void SetPairAddress(u64 a) {
pair_address = a;
}
constexpr void SetTypeAttribute(u32 attr) {
type_id |= attr;
}
private:
u64 address{};
u64 last_address{};
u64 pair_address{};
u32 attributes{};
u32 type_id{};
};
class KMemoryRegionTree final : NonCopyable {
public:
struct DerivedRegionExtents {
const KMemoryRegion* first_region{};
const KMemoryRegion* last_region{};
constexpr DerivedRegionExtents() = default;
constexpr u64 GetAddress() const {
return this->first_region->GetAddress();
}
constexpr u64 GetLastAddress() const {
return this->last_region->GetLastAddress();
}
constexpr u64 GetEndAddress() const {
return this->GetLastAddress() + 1;
}
constexpr size_t GetSize() const {
return this->GetEndAddress() - this->GetAddress();
}
};
private:
using TreeType =
Common::IntrusiveRedBlackTreeBaseTraits<KMemoryRegion>::TreeType<KMemoryRegion>;
public:
using value_type = TreeType::value_type;
using size_type = TreeType::size_type;
using difference_type = TreeType::difference_type;
using pointer = TreeType::pointer;
using const_pointer = TreeType::const_pointer;
using reference = TreeType::reference;
using const_reference = TreeType::const_reference;
using iterator = TreeType::iterator;
using const_iterator = TreeType::const_iterator;
private:
TreeType m_tree{};
KMemoryRegionAllocator& memory_region_allocator;
public:
explicit KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_);
public:
KMemoryRegion* FindModifiable(u64 address) {
if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->end()) {
return std::addressof(*it);
} else {
return nullptr;
}
}
const KMemoryRegion* Find(u64 address) const {
if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->cend()) {
return std::addressof(*it);
} else {
return nullptr;
}
}
const KMemoryRegion* FindByType(KMemoryRegionType type_id) const {
for (auto it = this->cbegin(); it != this->cend(); ++it) {
if (it->GetType() == static_cast<u32>(type_id)) {
return std::addressof(*it);
}
}
return nullptr;
}
const KMemoryRegion* FindByTypeAndAttribute(u32 type_id, u32 attr) const {
for (auto it = this->cbegin(); it != this->cend(); ++it) {
if (it->GetType() == type_id && it->GetAttributes() == attr) {
return std::addressof(*it);
}
}
return nullptr;
}
const KMemoryRegion* FindFirstDerived(KMemoryRegionType type_id) const {
for (auto it = this->cbegin(); it != this->cend(); it++) {
if (it->IsDerivedFrom(type_id)) {
return std::addressof(*it);
}
}
return nullptr;
}
const KMemoryRegion* FindLastDerived(KMemoryRegionType type_id) const {
const KMemoryRegion* region = nullptr;
for (auto it = this->begin(); it != this->end(); it++) {
if (it->IsDerivedFrom(type_id)) {
region = std::addressof(*it);
}
}
return region;
}
DerivedRegionExtents GetDerivedRegionExtents(KMemoryRegionType type_id) const {
DerivedRegionExtents extents;
ASSERT(extents.first_region == nullptr);
ASSERT(extents.last_region == nullptr);
for (auto it = this->cbegin(); it != this->cend(); it++) {
if (it->IsDerivedFrom(type_id)) {
if (extents.first_region == nullptr) {
extents.first_region = std::addressof(*it);
}
extents.last_region = std::addressof(*it);
}
}
ASSERT(extents.first_region != nullptr);
ASSERT(extents.last_region != nullptr);
return extents;
}
DerivedRegionExtents GetDerivedRegionExtents(u32 type_id) const {
return GetDerivedRegionExtents(static_cast<KMemoryRegionType>(type_id));
}
public:
void InsertDirectly(u64 address, u64 last_address, u32 attr = 0, u32 type_id = 0);
bool Insert(u64 address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
VAddr GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
VAddr GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id,
size_t guard_size) {
return this->GetRandomAlignedRegion(size + 2 * guard_size, alignment, type_id) + guard_size;
}
public:
// Iterator accessors.
iterator begin() {
return m_tree.begin();
}
const_iterator begin() const {
return m_tree.begin();
}
iterator end() {
return m_tree.end();
}
const_iterator end() const {
return m_tree.end();
}
const_iterator cbegin() const {
return this->begin();
}
const_iterator cend() const {
return this->end();
}
iterator iterator_to(reference ref) {
return m_tree.iterator_to(ref);
}
const_iterator iterator_to(const_reference ref) const {
return m_tree.iterator_to(ref);
}
// Content management.
bool empty() const {
return m_tree.empty();
}
reference back() {
return m_tree.back();
}
const_reference back() const {
return m_tree.back();
}
reference front() {
return m_tree.front();
}
const_reference front() const {
return m_tree.front();
}
iterator insert(reference ref) {
return m_tree.insert(ref);
}
iterator erase(iterator it) {
return m_tree.erase(it);
}
iterator find(const_reference ref) const {
return m_tree.find(ref);
}
iterator nfind(const_reference ref) const {
return m_tree.nfind(ref);
}
};
class KMemoryRegionAllocator final : NonCopyable {
public:
static constexpr size_t MaxMemoryRegions = 200;
constexpr KMemoryRegionAllocator() = default;
template <typename... Args>
KMemoryRegion* Allocate(Args&&... args) {
// Ensure we stay within the bounds of our heap.
ASSERT(this->num_regions < MaxMemoryRegions);
// Create the new region.
KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]);
new (region) KMemoryRegion(std::forward<Args>(args)...);
return region;
}
private:
std::array<KMemoryRegion, MaxMemoryRegions> region_heap{};
size_t num_regions{};
};
} // namespace Kernel
+338
View File
@@ -0,0 +1,338 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/bit_util.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#define ARCH_ARM64
#define BOARD_NINTENDO_NX
namespace Kernel {
enum KMemoryRegionType : u32 {
KMemoryRegionAttr_CarveoutProtected = 0x04000000,
KMemoryRegionAttr_DidKernelMap = 0x08000000,
KMemoryRegionAttr_ShouldKernelMap = 0x10000000,
KMemoryRegionAttr_UserReadOnly = 0x20000000,
KMemoryRegionAttr_NoUserMap = 0x40000000,
KMemoryRegionAttr_LinearMapped = 0x80000000,
};
DECLARE_ENUM_FLAG_OPERATORS(KMemoryRegionType);
namespace impl {
constexpr size_t BitsForDeriveSparse(size_t n) {
return n + 1;
}
constexpr size_t BitsForDeriveDense(size_t n) {
size_t low = 0, high = 1;
for (size_t i = 0; i < n - 1; ++i) {
if ((++low) == high) {
++high;
low = 0;
}
}
return high + 1;
}
class KMemoryRegionTypeValue {
public:
using ValueType = std::underlying_type_t<KMemoryRegionType>;
constexpr KMemoryRegionTypeValue() = default;
constexpr operator KMemoryRegionType() const {
return static_cast<KMemoryRegionType>(m_value);
}
constexpr ValueType GetValue() const {
return m_value;
}
constexpr const KMemoryRegionTypeValue& Finalize() {
m_finalized = true;
return *this;
}
constexpr const KMemoryRegionTypeValue& SetSparseOnly() {
m_sparse_only = true;
return *this;
}
constexpr const KMemoryRegionTypeValue& SetDenseOnly() {
m_dense_only = true;
return *this;
}
constexpr KMemoryRegionTypeValue& SetAttribute(u32 attr) {
m_value |= attr;
return *this;
}
constexpr KMemoryRegionTypeValue DeriveInitial(
size_t i, size_t next = Common::BitSize<ValueType>()) const {
KMemoryRegionTypeValue new_type = *this;
new_type.m_value = (ValueType{1} << i);
new_type.m_next_bit = next;
return new_type;
}
constexpr KMemoryRegionTypeValue DeriveAttribute(u32 attr) const {
KMemoryRegionTypeValue new_type = *this;
new_type.m_value |= attr;
return new_type;
}
constexpr KMemoryRegionTypeValue DeriveTransition(size_t ofs = 0, size_t adv = 1) const {
KMemoryRegionTypeValue new_type = *this;
new_type.m_value |= (ValueType{1} << (m_next_bit + ofs));
new_type.m_next_bit += adv;
return new_type;
}
constexpr KMemoryRegionTypeValue DeriveSparse(size_t ofs, size_t n, size_t i) const {
KMemoryRegionTypeValue new_type = *this;
new_type.m_value |= (ValueType{1} << (m_next_bit + ofs));
new_type.m_value |= (ValueType{1} << (m_next_bit + ofs + 1 + i));
new_type.m_next_bit += ofs + n + 1;
return new_type;
}
constexpr KMemoryRegionTypeValue Derive(size_t n, size_t i) const {
size_t low = 0, high = 1;
for (size_t j = 0; j < i; ++j) {
if ((++low) == high) {
++high;
low = 0;
}
}
KMemoryRegionTypeValue new_type = *this;
new_type.m_value |= (ValueType{1} << (m_next_bit + low));
new_type.m_value |= (ValueType{1} << (m_next_bit + high));
new_type.m_next_bit += BitsForDeriveDense(n);
return new_type;
}
constexpr KMemoryRegionTypeValue Advance(size_t n) const {
KMemoryRegionTypeValue new_type = *this;
new_type.m_next_bit += n;
return new_type;
}
constexpr bool IsAncestorOf(ValueType v) const {
return (m_value | v) == v;
}
private:
constexpr KMemoryRegionTypeValue(ValueType v) : m_value(v) {}
private:
ValueType m_value{};
size_t m_next_bit{};
bool m_finalized{};
bool m_sparse_only{};
bool m_dense_only{};
};
} // namespace impl
constexpr auto KMemoryRegionType_None = impl::KMemoryRegionTypeValue();
constexpr auto KMemoryRegionType_Kernel = KMemoryRegionType_None.DeriveInitial(0, 2);
constexpr auto KMemoryRegionType_Dram = KMemoryRegionType_None.DeriveInitial(1, 2);
static_assert(KMemoryRegionType_Kernel.GetValue() == 0x1);
static_assert(KMemoryRegionType_Dram.GetValue() == 0x2);
constexpr auto KMemoryRegionType_DramKernelBase =
KMemoryRegionType_Dram.DeriveSparse(0, 3, 0)
.SetAttribute(KMemoryRegionAttr_NoUserMap)
.SetAttribute(KMemoryRegionAttr_CarveoutProtected);
constexpr auto KMemoryRegionType_DramReservedBase = KMemoryRegionType_Dram.DeriveSparse(0, 3, 1);
constexpr auto KMemoryRegionType_DramHeapBase =
KMemoryRegionType_Dram.DeriveSparse(0, 3, 2).SetAttribute(KMemoryRegionAttr_LinearMapped);
static_assert(KMemoryRegionType_DramKernelBase.GetValue() ==
(0xE | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_DramReservedBase.GetValue() == (0x16));
static_assert(KMemoryRegionType_DramHeapBase.GetValue() == (0x26 | KMemoryRegionAttr_LinearMapped));
constexpr auto KMemoryRegionType_DramKernelCode =
KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 0);
constexpr auto KMemoryRegionType_DramKernelSlab =
KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 1);
constexpr auto KMemoryRegionType_DramKernelPtHeap =
KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 2).SetAttribute(
KMemoryRegionAttr_LinearMapped);
constexpr auto KMemoryRegionType_DramKernelInitPt =
KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 3).SetAttribute(
KMemoryRegionAttr_LinearMapped);
static_assert(KMemoryRegionType_DramKernelCode.GetValue() ==
(0xCE | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_DramKernelSlab.GetValue() ==
(0x14E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_DramKernelPtHeap.GetValue() ==
(0x24E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap |
KMemoryRegionAttr_LinearMapped));
static_assert(KMemoryRegionType_DramKernelInitPt.GetValue() ==
(0x44E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap |
KMemoryRegionAttr_LinearMapped));
constexpr auto KMemoryRegionType_DramReservedEarly =
KMemoryRegionType_DramReservedBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap);
static_assert(KMemoryRegionType_DramReservedEarly.GetValue() ==
(0x16 | KMemoryRegionAttr_NoUserMap));
constexpr auto KMemoryRegionType_KernelTraceBuffer =
KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 0)
.SetAttribute(KMemoryRegionAttr_LinearMapped)
.SetAttribute(KMemoryRegionAttr_UserReadOnly);
constexpr auto KMemoryRegionType_OnMemoryBootImage =
KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 1);
constexpr auto KMemoryRegionType_DTB = KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 2);
static_assert(KMemoryRegionType_KernelTraceBuffer.GetValue() ==
(0xD6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_UserReadOnly));
static_assert(KMemoryRegionType_OnMemoryBootImage.GetValue() == 0x156);
static_assert(KMemoryRegionType_DTB.GetValue() == 0x256);
constexpr auto KMemoryRegionType_DramPoolPartition =
KMemoryRegionType_DramHeapBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap);
static_assert(KMemoryRegionType_DramPoolPartition.GetValue() ==
(0x26 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap));
constexpr auto KMemoryRegionType_DramPoolManagement =
KMemoryRegionType_DramPoolPartition.DeriveTransition(0, 2).DeriveTransition().SetAttribute(
KMemoryRegionAttr_CarveoutProtected);
constexpr auto KMemoryRegionType_DramUserPool =
KMemoryRegionType_DramPoolPartition.DeriveTransition(1, 2).DeriveTransition();
static_assert(KMemoryRegionType_DramPoolManagement.GetValue() ==
(0x166 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap |
KMemoryRegionAttr_CarveoutProtected));
static_assert(KMemoryRegionType_DramUserPool.GetValue() ==
(0x1A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap));
constexpr auto KMemoryRegionType_DramApplicationPool = KMemoryRegionType_DramUserPool.Derive(4, 0);
constexpr auto KMemoryRegionType_DramAppletPool = KMemoryRegionType_DramUserPool.Derive(4, 1);
constexpr auto KMemoryRegionType_DramSystemNonSecurePool =
KMemoryRegionType_DramUserPool.Derive(4, 2);
constexpr auto KMemoryRegionType_DramSystemPool =
KMemoryRegionType_DramUserPool.Derive(4, 3).SetAttribute(KMemoryRegionAttr_CarveoutProtected);
static_assert(KMemoryRegionType_DramApplicationPool.GetValue() ==
(0x7A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_DramAppletPool.GetValue() ==
(0xBA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_DramSystemNonSecurePool.GetValue() ==
(0xDA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap));
static_assert(KMemoryRegionType_DramSystemPool.GetValue() ==
(0x13A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap |
KMemoryRegionAttr_CarveoutProtected));
constexpr auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 3, 0);
constexpr auto KMemoryRegionType_VirtualDramKernelPtHeap =
KMemoryRegionType_Dram.DeriveSparse(1, 3, 1);
constexpr auto KMemoryRegionType_VirtualDramKernelTraceBuffer =
KMemoryRegionType_Dram.DeriveSparse(1, 3, 2);
static_assert(KMemoryRegionType_VirtualDramHeapBase.GetValue() == 0x1A);
static_assert(KMemoryRegionType_VirtualDramKernelPtHeap.GetValue() == 0x2A);
static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A);
constexpr auto KMemoryRegionType_VirtualDramKernelInitPt =
KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0);
constexpr auto KMemoryRegionType_VirtualDramPoolManagement =
KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1);
constexpr auto KMemoryRegionType_VirtualDramUserPool =
KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2);
static_assert(KMemoryRegionType_VirtualDramKernelInitPt.GetValue() == 0x19A);
static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x29A);
static_assert(KMemoryRegionType_VirtualDramUserPool.GetValue() == 0x31A);
// NOTE: For unknown reason, the pools are derived out-of-order here. It's worth eventually trying
// to understand why Nintendo made this choice.
// UNUSED: .Derive(6, 0);
// UNUSED: .Derive(6, 1);
constexpr auto KMemoryRegionType_VirtualDramAppletPool =
KMemoryRegionType_VirtualDramUserPool.Derive(6, 2);
constexpr auto KMemoryRegionType_VirtualDramApplicationPool =
KMemoryRegionType_VirtualDramUserPool.Derive(6, 3);
constexpr auto KMemoryRegionType_VirtualDramSystemNonSecurePool =
KMemoryRegionType_VirtualDramUserPool.Derive(6, 4);
constexpr auto KMemoryRegionType_VirtualDramSystemPool =
KMemoryRegionType_VirtualDramUserPool.Derive(6, 5);
static_assert(KMemoryRegionType_VirtualDramAppletPool.GetValue() == 0x1B1A);
static_assert(KMemoryRegionType_VirtualDramApplicationPool.GetValue() == 0x271A);
static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x2B1A);
static_assert(KMemoryRegionType_VirtualDramSystemPool.GetValue() == 0x331A);
constexpr auto KMemoryRegionType_ArchDeviceBase =
KMemoryRegionType_Kernel.DeriveTransition(0, 1).SetSparseOnly();
constexpr auto KMemoryRegionType_BoardDeviceBase =
KMemoryRegionType_Kernel.DeriveTransition(0, 2).SetDenseOnly();
static_assert(KMemoryRegionType_ArchDeviceBase.GetValue() == 0x5);
static_assert(KMemoryRegionType_BoardDeviceBase.GetValue() == 0x5);
#if defined(ARCH_ARM64)
#include "core/hle/kernel/arch/arm64/k_memory_region_device_types.inc"
#elif defined(ARCH_ARM)
#error "Unimplemented"
#else
// Default to no architecture devices.
constexpr auto NumArchitectureDeviceRegions = 0;
#endif
static_assert(NumArchitectureDeviceRegions >= 0);
#if defined(BOARD_NINTENDO_NX)
#include "core/hle/kernel/board/nintendo/nx/k_memory_region_device_types.inc"
#else
// Default to no board devices.
constexpr auto NumBoardDeviceRegions = 0;
#endif
static_assert(NumBoardDeviceRegions >= 0);
constexpr auto KMemoryRegionType_KernelCode = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 0);
constexpr auto KMemoryRegionType_KernelStack = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 1);
constexpr auto KMemoryRegionType_KernelMisc = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 2);
constexpr auto KMemoryRegionType_KernelSlab = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 3);
static_assert(KMemoryRegionType_KernelCode.GetValue() == 0x19);
static_assert(KMemoryRegionType_KernelStack.GetValue() == 0x29);
static_assert(KMemoryRegionType_KernelMisc.GetValue() == 0x49);
static_assert(KMemoryRegionType_KernelSlab.GetValue() == 0x89);
constexpr auto KMemoryRegionType_KernelMiscDerivedBase =
KMemoryRegionType_KernelMisc.DeriveTransition();
static_assert(KMemoryRegionType_KernelMiscDerivedBase.GetValue() == 0x149);
// UNUSED: .Derive(7, 0);
constexpr auto KMemoryRegionType_KernelMiscMainStack =
KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 1);
constexpr auto KMemoryRegionType_KernelMiscMappedDevice =
KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 2);
constexpr auto KMemoryRegionType_KernelMiscExceptionStack =
KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 3);
constexpr auto KMemoryRegionType_KernelMiscUnknownDebug =
KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 4);
// UNUSED: .Derive(7, 5);
constexpr auto KMemoryRegionType_KernelMiscIdleStack =
KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 6);
static_assert(KMemoryRegionType_KernelMiscMainStack.GetValue() == 0xB49);
static_assert(KMemoryRegionType_KernelMiscMappedDevice.GetValue() == 0xD49);
static_assert(KMemoryRegionType_KernelMiscExceptionStack.GetValue() == 0x1349);
static_assert(KMemoryRegionType_KernelMiscUnknownDebug.GetValue() == 0x1549);
static_assert(KMemoryRegionType_KernelMiscIdleStack.GetValue() == 0x2349);
constexpr auto KMemoryRegionType_KernelTemp = KMemoryRegionType_Kernel.Advance(2).Derive(2, 0);
static_assert(KMemoryRegionType_KernelTemp.GetValue() == 0x31);
constexpr KMemoryRegionType GetTypeForVirtualLinearMapping(u32 type_id) {
if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) {
return KMemoryRegionType_VirtualDramKernelTraceBuffer;
} else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) {
return KMemoryRegionType_VirtualDramKernelPtHeap;
} else {
return KMemoryRegionType_Dram;
}
}
} // namespace Kernel
+4 -9
View File
@@ -2,21 +2,16 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// This file references various implementation details from Atmosphere, an open-source firmware for
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
#include "common/assert.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel {
constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
: Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
KResourceLimit::KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_)
: Object{kernel}, lock{kernel}, cond_var{kernel}, core_timing(core_timing_) {}
KResourceLimit::~KResourceLimit() = default;
s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
@@ -83,7 +78,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
}
bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout);
return Reserve(which, value, core_timing.GetGlobalTimeNs().count() + DefaultTimeout);
}
bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
@@ -114,7 +109,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
}
if (current_hints[index] + value <= limit_values[index] &&
(timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) {
(timeout < 0 || core_timing.GetGlobalTimeNs().count() < timeout)) {
waiter_count++;
cond_var.Wait(&lock, timeout);
waiter_count--;
+4 -8
View File
@@ -2,9 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// This file references various implementation details from Atmosphere, an open-source firmware for
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
#pragma once
#include <array>
@@ -15,8 +12,8 @@
union ResultCode;
namespace Core {
class System;
namespace Core::Timing {
class CoreTiming;
}
namespace Kernel {
@@ -37,7 +34,7 @@ constexpr bool IsValidResourceType(LimitableResource type) {
class KResourceLimit final : public Object {
public:
explicit KResourceLimit(KernelCore& kernel, Core::System& system);
explicit KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_);
~KResourceLimit();
s64 GetLimitValue(LimitableResource which) const;
@@ -75,7 +72,6 @@ private:
mutable KLightLock lock;
s32 waiter_count{};
KLightConditionVariable cond_var;
KernelCore& kernel;
Core::System& system;
const Core::Timing::CoreTiming& core_timing;
};
} // namespace Kernel
+11 -11
View File
@@ -62,7 +62,7 @@ void KScheduler::RescheduleCores(KernelCore& kernel, u64 cores_pending_reschedul
}
u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) {
std::scoped_lock lock{guard};
KScopedSpinLock lk{guard};
if (KThread* prev_highest_thread = state.highest_priority_thread;
prev_highest_thread != highest_thread) {
if (prev_highest_thread != nullptr) {
@@ -637,11 +637,11 @@ void KScheduler::RescheduleCurrentCore() {
if (phys_core.IsInterrupted()) {
phys_core.ClearInterrupt();
}
guard.lock();
guard.Lock();
if (state.needs_scheduling.load()) {
Schedule();
} else {
guard.unlock();
guard.Unlock();
}
}
@@ -669,7 +669,7 @@ void KScheduler::Unload(KThread* thread) {
} else {
prev_thread = nullptr;
}
thread->context_guard.unlock();
thread->context_guard.Unlock();
}
}
@@ -713,7 +713,7 @@ void KScheduler::ScheduleImpl() {
// If we're not actually switching thread, there's nothing to do.
if (next_thread == current_thread.load()) {
guard.unlock();
guard.Unlock();
return;
}
@@ -732,7 +732,7 @@ void KScheduler::ScheduleImpl() {
} else {
old_context = &idle_thread->GetHostContext();
}
guard.unlock();
guard.Unlock();
Common::Fiber::YieldTo(*old_context, *switch_fiber);
/// When a thread wakes up, the scheduler may have changed to other in another core.
@@ -748,24 +748,24 @@ void KScheduler::OnSwitch(void* this_scheduler) {
void KScheduler::SwitchToCurrent() {
while (true) {
{
std::scoped_lock lock{guard};
KScopedSpinLock lk{guard};
current_thread.store(state.highest_priority_thread);
state.needs_scheduling.store(false);
}
const auto is_switch_pending = [this] {
std::scoped_lock lock{guard};
KScopedSpinLock lk{guard};
return state.needs_scheduling.load();
};
do {
auto next_thread = current_thread.load();
if (next_thread != nullptr) {
next_thread->context_guard.lock();
next_thread->context_guard.Lock();
if (next_thread->GetRawState() != ThreadState::Runnable) {
next_thread->context_guard.unlock();
next_thread->context_guard.Unlock();
break;
}
if (next_thread->GetActiveCore() != core_id) {
next_thread->context_guard.unlock();
next_thread->context_guard.Unlock();
break;
}
}
+4 -7
View File
@@ -2,19 +2,16 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// This file references various implementation details from Atmosphere, an open-source firmware for
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
#pragma once
#include <atomic>
#include "common/common_types.h"
#include "common/spin_lock.h"
#include "core/hle/kernel/global_scheduler_context.h"
#include "core/hle/kernel/k_priority_queue.h"
#include "core/hle/kernel/k_scheduler_lock.h"
#include "core/hle/kernel/k_scoped_lock.h"
#include "core/hle/kernel/k_spin_lock.h"
namespace Common {
class Fiber;
@@ -195,12 +192,12 @@ private:
u64 last_context_switch_time{};
const s32 core_id;
Common::SpinLock guard{};
KSpinLock guard{};
};
class KScopedSchedulerLock : KScopedLock<GlobalSchedulerContext::LockType> {
class [[nodiscard]] KScopedSchedulerLock : KScopedLock<GlobalSchedulerContext::LockType> {
public:
explicit KScopedSchedulerLock(KernelCore& kernel);
explicit KScopedSchedulerLock(KernelCore & kernel);
~KScopedSchedulerLock();
};
+4 -7
View File
@@ -2,14 +2,11 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
// This file references various implementation details from Atmosphere, an open-source firmware for
// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
#pragma once
#include "common/assert.h"
#include "common/spin_lock.h"
#include "core/hardware_properties.h"
#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
@@ -34,7 +31,7 @@ public:
} else {
// Otherwise, we want to disable scheduling and acquire the spinlock.
SchedulerType::DisableScheduling(kernel);
spin_lock.lock();
spin_lock.Lock();
// For debug, ensure that our state is valid.
ASSERT(lock_count == 0);
@@ -58,7 +55,7 @@ public:
// Note that we no longer hold the lock, and unlock the spinlock.
owner_thread = nullptr;
spin_lock.unlock();
spin_lock.Unlock();
// Enable scheduling, and perform a rescheduling operation.
SchedulerType::EnableScheduling(kernel, cores_needing_scheduling);
@@ -67,7 +64,7 @@ public:
private:
KernelCore& kernel;
Common::SpinLock spin_lock{};
KAlignedSpinLock spin_lock{};
s32 lock_count{};
KThread* owner_thread{};
};
+8 -5
View File
@@ -20,19 +20,22 @@ concept KLockable = !std::is_reference_v<T> && requires(T & t) {
};
template <typename T>
requires KLockable<T> class KScopedLock {
requires KLockable<T> class [[nodiscard]] KScopedLock {
public:
explicit KScopedLock(T* l) : lock_ptr(l) {
explicit KScopedLock(T * l) : lock_ptr(l) {
this->lock_ptr->Lock();
}
explicit KScopedLock(T& l) : KScopedLock(std::addressof(l)) { /* ... */
}
explicit KScopedLock(T & l) : KScopedLock(std::addressof(l)) {}
~KScopedLock() {
this->lock_ptr->Unlock();
}
KScopedLock(const KScopedLock&) = delete;
KScopedLock(KScopedLock&&) = delete;
KScopedLock& operator=(const KScopedLock&) = delete;
KScopedLock(KScopedLock &&) = delete;
KScopedLock& operator=(KScopedLock&&) = delete;
private:
T* lock_ptr;
@@ -15,9 +15,9 @@
namespace Kernel {
class KScopedSchedulerLockAndSleep {
class [[nodiscard]] KScopedSchedulerLockAndSleep {
public:
explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, KThread* t, s64 timeout)
explicit KScopedSchedulerLockAndSleep(KernelCore & kernel, KThread * t, s64 timeout)
: kernel(kernel), thread(t), timeout_tick(timeout) {
// Lock the scheduler.
kernel.GlobalSchedulerContext().scheduler_lock.Lock();
+6
View File
@@ -28,6 +28,12 @@ private:
std::atomic_flag lck = ATOMIC_FLAG_INIT;
};
// TODO(bunnei): Alias for now, in case we want to implement these accurately in the future.
using KAlignedSpinLock = KSpinLock;
using KNotAlignedSpinLock = KSpinLock;
using KScopedSpinLock = KScopedLock<KSpinLock>;
using KScopedAlignedSpinLock = KScopedLock<KAlignedSpinLock>;
using KScopedNotAlignedSpinLock = KScopedLock<KNotAlignedSpinLock>;
} // namespace Kernel
-42
View File
@@ -1,42 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <random>
#include "core/hle/kernel/k_system_control.h"
namespace Kernel {
namespace {
template <typename F>
u64 GenerateUniformRange(u64 min, u64 max, F f) {
// Handle the case where the difference is too large to represent.
if (max == std::numeric_limits<u64>::max() && min == std::numeric_limits<u64>::min()) {
return f();
}
// Iterate until we get a value in range.
const u64 range_size = ((max + 1) - min);
const u64 effective_max = (std::numeric_limits<u64>::max() / range_size) * range_size;
while (true) {
if (const u64 rnd = f(); rnd < effective_max) {
return min + (rnd % range_size);
}
}
}
} // Anonymous namespace
u64 KSystemControl::GenerateRandomU64() {
static std::random_device device;
static std::mt19937 gen(device());
static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
return distribution(gen);
}
u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
return GenerateUniformRange(min, max, GenerateRandomU64);
}
} // namespace Kernel
+11 -7
View File
@@ -6,14 +6,18 @@
#include "common/common_types.h"
#define BOARD_NINTENDO_NX
#ifdef BOARD_NINTENDO_NX
#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
namespace Kernel {
class KSystemControl {
public:
KSystemControl() = default;
static u64 GenerateRandomRange(u64 min, u64 max);
static u64 GenerateRandomU64();
};
using Kernel::Board::Nintendo::Nx::KSystemControl;
} // namespace Kernel
#else
#error "Unknown board for KSystemControl"
#endif
+3 -3
View File
@@ -14,10 +14,10 @@
#include "common/common_types.h"
#include "common/intrusive_red_black_tree.h"
#include "common/spin_lock.h"
#include "core/arm/arm_interface.h"
#include "core/hle/kernel/k_affinity_mask.h"
#include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/svc_common.h"
@@ -402,7 +402,7 @@ public:
return wait_cancelled;
}
[[nodiscard]] void ClearWaitCancelled() {
void ClearWaitCancelled() {
wait_cancelled = false;
}
@@ -732,7 +732,7 @@ private:
s8 priority_inheritance_count{};
bool resource_limit_release_hint{};
StackParameters stack_parameters{};
Common::SpinLock context_guard{};
KSpinLock context_guard{};
// For emulation
std::shared_ptr<Common::Fiber> host_context{};
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Kernel {
constexpr bool IsKTraceEnabled = false;
constexpr std::size_t KTraceBufferSize = IsKTraceEnabled ? 16 * 1024 * 1024 : 0;
} // namespace Kernel
+321 -41
View File
@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -12,6 +12,7 @@
#include <utility>
#include "common/assert.h"
#include "common/common_sizes.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/thread.h"
@@ -66,8 +67,13 @@ struct KernelCore::Impl {
is_phantom_mode_for_singlecore = false;
InitializePhysicalCores();
InitializeSystemResourceLimit(kernel, system);
InitializeMemoryLayout();
// Derive the initial memory layout from the emulated board
KMemoryLayout memory_layout;
DeriveInitialMemoryLayout(memory_layout);
InitializeMemoryLayout(memory_layout);
InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout);
InitializeSlabHeaps();
InitializeSchedulers();
InitializeSuspendThreads();
InitializePreemption(kernel);
@@ -136,27 +142,33 @@ struct KernelCore::Impl {
}
// Creates the default system resource limit
void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) {
system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
void InitializeSystemResourceLimit(KernelCore& kernel,
const Core::Timing::CoreTiming& core_timing,
const KMemoryLayout& memory_layout) {
system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing);
const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
// If setting the default system values fails, then something seriously wrong has occurred.
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000)
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size)
.IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
.IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 933).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess());
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size);
// Derived from recent software updates. The kernel reserves 27MB
constexpr u64 kernel_size{0x1b00000};
if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) {
UNREACHABLE();
}
// Reserve secure applet memory, introduced in firmware 5.0.0
constexpr u64 secure_applet_memory_size{0x400000};
constexpr u64 secure_applet_memory_size{Common::Size_4_MB};
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
secure_applet_memory_size));
// This memory seems to be reserved on hardware, but is not reserved/used by yuzu.
// Likely Horizon OS reserved memory
// TODO(ameerj): Derive the memory rather than hardcode it.
constexpr u64 unknown_reserved_memory{0x2f896000};
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
unknown_reserved_memory));
}
void InitializePreemption(KernelCore& kernel) {
@@ -268,51 +280,319 @@ struct KernelCore::Impl {
return schedulers[thread_id]->GetCurrentThread();
}
void InitializeMemoryLayout() {
// Initialize memory layout
constexpr KMemoryLayout layout{KMemoryLayout::GetDefaultLayout()};
void DeriveInitialMemoryLayout(KMemoryLayout& memory_layout) {
// Insert the root region for the virtual memory tree, from which all other regions will
// derive.
memory_layout.GetVirtualMemoryRegionTree().InsertDirectly(
KernelVirtualAddressSpaceBase,
KernelVirtualAddressSpaceBase + KernelVirtualAddressSpaceSize - 1);
// Insert the root region for the physical memory tree, from which all other regions will
// derive.
memory_layout.GetPhysicalMemoryRegionTree().InsertDirectly(
KernelPhysicalAddressSpaceBase,
KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1);
// Save start and end for ease of use.
const VAddr code_start_virt_addr = KernelVirtualAddressCodeBase;
const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd;
// Setup the containing kernel region.
constexpr size_t KernelRegionSize = Common::Size_1_GB;
constexpr size_t KernelRegionAlign = Common::Size_1_GB;
constexpr VAddr kernel_region_start =
Common::AlignDown(code_start_virt_addr, KernelRegionAlign);
size_t kernel_region_size = KernelRegionSize;
if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) {
kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start;
}
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel));
// Setup the code region.
constexpr size_t CodeRegionAlign = PageSize;
constexpr VAddr code_region_start =
Common::AlignDown(code_start_virt_addr, CodeRegionAlign);
constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign);
constexpr size_t code_region_size = code_region_end - code_region_start;
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
code_region_start, code_region_size, KMemoryRegionType_KernelCode));
// Setup board-specific device physical regions.
Init::SetupDevicePhysicalMemoryRegions(memory_layout);
// Determine the amount of space needed for the misc region.
size_t misc_region_needed_size;
{
// Each core has a one page stack for all three stack types (Main, Idle, Exception).
misc_region_needed_size = Core::Hardware::NUM_CPU_CORES * (3 * (PageSize + PageSize));
// Account for each auto-map device.
for (const auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
if (region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) {
// Check that the region is valid.
ASSERT(region.GetEndAddress() != 0);
// Account for the region.
misc_region_needed_size +=
PageSize + (Common::AlignUp(region.GetLastAddress(), PageSize) -
Common::AlignDown(region.GetAddress(), PageSize));
}
}
// Multiply the needed size by three, to account for the need for guard space.
misc_region_needed_size *= 3;
}
// Decide on the actual size for the misc region.
constexpr size_t MiscRegionAlign = KernelAslrAlignment;
constexpr size_t MiscRegionMinimumSize = Common::Size_32_MB;
const size_t misc_region_size = Common::AlignUp(
std::max(misc_region_needed_size, MiscRegionMinimumSize), MiscRegionAlign);
ASSERT(misc_region_size > 0);
// Setup the misc region.
const VAddr misc_region_start =
memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel);
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc));
// Setup the stack region.
constexpr size_t StackRegionSize = Common::Size_14_MB;
constexpr size_t StackRegionAlign = KernelAslrAlignment;
const VAddr stack_region_start =
memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel);
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack));
// Determine the size of the resource region.
const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit();
// Determine the size of the slab region.
const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize);
ASSERT(slab_region_size <= resource_region_size);
// Setup the slab region.
const PAddr code_start_phys_addr = KernelPhysicalAddressCodeBase;
const PAddr code_end_phys_addr = code_start_phys_addr + code_region_size;
const PAddr slab_start_phys_addr = code_end_phys_addr;
const PAddr slab_end_phys_addr = slab_start_phys_addr + slab_region_size;
constexpr size_t SlabRegionAlign = KernelAslrAlignment;
const size_t slab_region_needed_size =
Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) -
Common::AlignDown(code_end_phys_addr, SlabRegionAlign);
const VAddr slab_region_start =
memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) +
(code_end_phys_addr % SlabRegionAlign);
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab));
// Setup the temp region.
constexpr size_t TempRegionSize = Common::Size_128_MB;
constexpr size_t TempRegionAlign = KernelAslrAlignment;
const VAddr temp_region_start =
memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel);
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize,
KMemoryRegionType_KernelTemp));
// Automatically map in devices that have auto-map attributes.
for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
// We only care about kernel regions.
if (!region.IsDerivedFrom(KMemoryRegionType_Kernel)) {
continue;
}
// Check whether we should map the region.
if (!region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) {
continue;
}
// If this region has already been mapped, no need to consider it.
if (region.HasTypeAttribute(KMemoryRegionAttr_DidKernelMap)) {
continue;
}
// Check that the region is valid.
ASSERT(region.GetEndAddress() != 0);
// Set the attribute to note we've mapped this region.
region.SetTypeAttribute(KMemoryRegionAttr_DidKernelMap);
// Create a virtual pair region and insert it into the tree.
const PAddr map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize);
const size_t map_size =
Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr;
const VAddr map_virt_addr =
memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize);
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice));
region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr);
}
Init::SetupDramPhysicalMemoryRegions(memory_layout);
// Insert a physical region for the kernel code region.
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode));
// Insert a physical region for the kernel slab region.
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab));
// Determine size available for kernel page table heaps, requiring > 8 MB.
const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size;
const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr;
ASSERT(page_table_heap_size / Common::Size_4_MB > 2);
// Insert a physical region for the kernel page table heap region
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap));
// All DRAM regions that we haven't tagged by this point will be mapped under the linear
// mapping. Tag them.
for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
if (region.GetType() == KMemoryRegionType_Dram) {
// Check that the region is valid.
ASSERT(region.GetEndAddress() != 0);
// Set the linear map attribute.
region.SetTypeAttribute(KMemoryRegionAttr_LinearMapped);
}
}
// Get the linear region extents.
const auto linear_extents =
memory_layout.GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
KMemoryRegionAttr_LinearMapped);
ASSERT(linear_extents.GetEndAddress() != 0);
// Setup the linear mapping region.
constexpr size_t LinearRegionAlign = Common::Size_1_GB;
const PAddr aligned_linear_phys_start =
Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign);
const size_t linear_region_size =
Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) -
aligned_linear_phys_start;
const VAddr linear_region_start =
memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign);
const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start;
// Map and create regions for all the linearly-mapped data.
{
PAddr cur_phys_addr = 0;
u64 cur_size = 0;
for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
continue;
}
ASSERT(region.GetEndAddress() != 0);
if (cur_size == 0) {
cur_phys_addr = region.GetAddress();
cur_size = region.GetSize();
} else if (cur_phys_addr + cur_size == region.GetAddress()) {
cur_size += region.GetSize();
} else {
cur_phys_addr = region.GetAddress();
cur_size = region.GetSize();
}
const VAddr region_virt_addr =
region.GetAddress() + linear_region_phys_to_virt_diff;
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
region_virt_addr, region.GetSize(),
GetTypeForVirtualLinearMapping(region.GetType())));
region.SetPairAddress(region_virt_addr);
KMemoryRegion* virt_region =
memory_layout.GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr);
ASSERT(virt_region != nullptr);
virt_region->SetPairAddress(region.GetAddress());
}
}
// Insert regions for the initial page table region.
ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt));
ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize,
KMemoryRegionType_VirtualDramKernelInitPt));
// All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to
// some pool partition. Tag them.
for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
if (region.GetType() == (KMemoryRegionType_Dram | KMemoryRegionAttr_LinearMapped)) {
region.SetType(KMemoryRegionType_DramPoolPartition);
}
}
// Setup all other memory regions needed to arrange the pool partitions.
Init::SetupPoolPartitionMemoryRegions(memory_layout);
// Cache all linear regions in their own trees for faster access, later.
memory_layout.InitializeLinearMemoryRegionTrees(aligned_linear_phys_start,
linear_region_start);
}
void InitializeMemoryLayout(const KMemoryLayout& memory_layout) {
const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents();
const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents();
const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents();
// Initialize memory managers
memory_manager = std::make_unique<KMemoryManager>();
memory_manager->InitializeManager(KMemoryManager::Pool::Application,
application_pool.GetAddress(),
application_pool.GetEndAddress());
memory_manager->InitializeManager(KMemoryManager::Pool::Applet, applet_pool.GetAddress(),
applet_pool.GetEndAddress());
memory_manager->InitializeManager(KMemoryManager::Pool::System, system_pool.GetAddress(),
system_pool.GetEndAddress());
// Setup memory regions for emulated processes
// TODO(bunnei): These should not be hardcoded regions initialized within the kernel
constexpr std::size_t hid_size{0x40000};
constexpr std::size_t font_size{0x1100000};
constexpr std::size_t irs_size{0x8000};
constexpr std::size_t time_size{0x1000};
constexpr PAddr hid_addr{layout.System().StartAddress()};
constexpr PAddr font_pa{layout.System().StartAddress() + hid_size};
constexpr PAddr irs_addr{layout.System().StartAddress() + hid_size + font_size};
constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size};
// Initialize memory manager
memory_manager = std::make_unique<KMemoryManager>();
memory_manager->InitializeManager(KMemoryManager::Pool::Application,
layout.Application().StartAddress(),
layout.Application().EndAddress());
memory_manager->InitializeManager(KMemoryManager::Pool::Applet,
layout.Applet().StartAddress(),
layout.Applet().EndAddress());
memory_manager->InitializeManager(KMemoryManager::Pool::System,
layout.System().StartAddress(),
layout.System().EndAddress());
const PAddr hid_phys_addr{system_pool.GetAddress()};
const PAddr font_phys_addr{system_pool.GetAddress() + hid_size};
const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size};
const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size};
hid_shared_mem = Kernel::KSharedMemory::Create(
system.Kernel(), system.DeviceMemory(), nullptr, {hid_addr, hid_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, hid_addr, hid_size,
system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size,
"HID:SharedMemory");
font_shared_mem = Kernel::KSharedMemory::Create(
system.Kernel(), system.DeviceMemory(), nullptr, {font_pa, font_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, font_pa, font_size,
system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size,
"Font:SharedMemory");
irs_shared_mem = Kernel::KSharedMemory::Create(
system.Kernel(), system.DeviceMemory(), nullptr, {irs_addr, irs_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, irs_addr, irs_size,
system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size,
"IRS:SharedMemory");
time_shared_mem = Kernel::KSharedMemory::Create(
system.Kernel(), system.DeviceMemory(), nullptr, {time_addr, time_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, time_addr, time_size,
system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
"Time:SharedMemory");
}
void InitializeSlabHeaps() {
// Allocate slab heaps
user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>();
constexpr u64 user_slab_heap_size{0x1ef000};
// TODO(ameerj): This should be derived, not hardcoded within the kernel
constexpr u64 user_slab_heap_size{0x3de000};
// Reserve slab heaps
ASSERT(
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size));
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project / PPSSPP Project
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+3 -23
View File
@@ -10,6 +10,7 @@
#include "common/alignment.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/device_memory.h"
#include "core/file_sys/program_metadata.h"
@@ -26,7 +27,6 @@
#include "core/hle/kernel/svc_results.h"
#include "core/hle/lock.h"
#include "core/memory.h"
#include "core/settings.h"
namespace Kernel {
namespace {
@@ -120,9 +120,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
std::shared_ptr<Process> process = std::make_shared<Process>(system);
process->name = std::move(name);
// TODO: This is inaccurate
// The process should hold a reference to the kernel-wide resource limit.
process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
process->resource_limit = kernel.GetSystemResourceLimit();
process->status = ProcessStatus::Created;
process->program_id = 0;
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -160,17 +158,13 @@ void Process::DecrementThreadCount() {
}
u64 Process::GetTotalPhysicalMemoryAvailable() const {
// TODO: This is expected to always return the application memory pool size after accurately
// reserving kernel resources. The current workaround uses a process-local resource limit of
// application memory pool size, which is inaccurate.
const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
main_thread_stack_size};
ASSERT(capacity == kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
if (capacity < memory_usage_capacity) {
return capacity;
}
return memory_usage_capacity;
}
@@ -272,10 +266,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
system_resource_size = metadata.GetSystemResourceSize();
image_size = code_size;
// Set initial resource limits
resource_limit->SetLimitValue(
LimitableResource::PhysicalMemory,
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
code_size + system_resource_size);
if (!memory_reservation.Succeeded()) {
@@ -324,16 +314,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
UNREACHABLE();
}
// Set initial resource limits
resource_limit->SetLimitValue(
LimitableResource::PhysicalMemory,
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
resource_limit->SetLimitValue(LimitableResource::Threads, 608);
resource_limit->SetLimitValue(LimitableResource::Events, 700);
resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
resource_limit->SetLimitValue(LimitableResource::Sessions, 894);
// Create TLS region
tls_region_address = CreateTLSRegion();
memory_reservation.Commit();
+133 -1
View File
@@ -2156,7 +2156,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle)
LOG_DEBUG(Kernel_SVC, "called");
auto& kernel = system.Kernel();
auto resource_limit = std::make_shared<KResourceLimit>(kernel, system);
auto resource_limit = std::make_shared<KResourceLimit>(kernel, system.CoreTiming());
auto* const current_process = kernel.CurrentProcess();
ASSERT(current_process != nullptr);
@@ -2455,6 +2455,74 @@ static const FunctionDef SVC_Table_32[] = {
{0x79, nullptr, "Unknown"},
{0x7A, nullptr, "Unknown"},
{0x7B, nullptr, "TerminateProcess32"},
{0x7C, nullptr, "GetProcessInfo32"},
{0x7D, nullptr, "CreateResourceLimit32"},
{0x7E, nullptr, "SetResourceLimitLimitValue32"},
{0x7F, nullptr, "CallSecureMonitor32"},
{0x80, nullptr, "Unknown"},
{0x81, nullptr, "Unknown"},
{0x82, nullptr, "Unknown"},
{0x83, nullptr, "Unknown"},
{0x84, nullptr, "Unknown"},
{0x85, nullptr, "Unknown"},
{0x86, nullptr, "Unknown"},
{0x87, nullptr, "Unknown"},
{0x88, nullptr, "Unknown"},
{0x89, nullptr, "Unknown"},
{0x8A, nullptr, "Unknown"},
{0x8B, nullptr, "Unknown"},
{0x8C, nullptr, "Unknown"},
{0x8D, nullptr, "Unknown"},
{0x8E, nullptr, "Unknown"},
{0x8F, nullptr, "Unknown"},
{0x90, nullptr, "Unknown"},
{0x91, nullptr, "Unknown"},
{0x92, nullptr, "Unknown"},
{0x93, nullptr, "Unknown"},
{0x94, nullptr, "Unknown"},
{0x95, nullptr, "Unknown"},
{0x96, nullptr, "Unknown"},
{0x97, nullptr, "Unknown"},
{0x98, nullptr, "Unknown"},
{0x99, nullptr, "Unknown"},
{0x9A, nullptr, "Unknown"},
{0x9B, nullptr, "Unknown"},
{0x9C, nullptr, "Unknown"},
{0x9D, nullptr, "Unknown"},
{0x9E, nullptr, "Unknown"},
{0x9F, nullptr, "Unknown"},
{0xA0, nullptr, "Unknown"},
{0xA1, nullptr, "Unknown"},
{0xA2, nullptr, "Unknown"},
{0xA3, nullptr, "Unknown"},
{0xA4, nullptr, "Unknown"},
{0xA5, nullptr, "Unknown"},
{0xA6, nullptr, "Unknown"},
{0xA7, nullptr, "Unknown"},
{0xA8, nullptr, "Unknown"},
{0xA9, nullptr, "Unknown"},
{0xAA, nullptr, "Unknown"},
{0xAB, nullptr, "Unknown"},
{0xAC, nullptr, "Unknown"},
{0xAD, nullptr, "Unknown"},
{0xAE, nullptr, "Unknown"},
{0xAF, nullptr, "Unknown"},
{0xB0, nullptr, "Unknown"},
{0xB1, nullptr, "Unknown"},
{0xB2, nullptr, "Unknown"},
{0xB3, nullptr, "Unknown"},
{0xB4, nullptr, "Unknown"},
{0xB5, nullptr, "Unknown"},
{0xB6, nullptr, "Unknown"},
{0xB7, nullptr, "Unknown"},
{0xB8, nullptr, "Unknown"},
{0xB9, nullptr, "Unknown"},
{0xBA, nullptr, "Unknown"},
{0xBB, nullptr, "Unknown"},
{0xBC, nullptr, "Unknown"},
{0xBD, nullptr, "Unknown"},
{0xBE, nullptr, "Unknown"},
{0xBF, nullptr, "Unknown"},
};
static const FunctionDef SVC_Table_64[] = {
@@ -2586,6 +2654,70 @@ static const FunctionDef SVC_Table_64[] = {
{0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"},
{0x7E, SvcWrap64<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"},
{0x7F, nullptr, "CallSecureMonitor"},
{0x80, nullptr, "Unknown"},
{0x81, nullptr, "Unknown"},
{0x82, nullptr, "Unknown"},
{0x83, nullptr, "Unknown"},
{0x84, nullptr, "Unknown"},
{0x85, nullptr, "Unknown"},
{0x86, nullptr, "Unknown"},
{0x87, nullptr, "Unknown"},
{0x88, nullptr, "Unknown"},
{0x89, nullptr, "Unknown"},
{0x8A, nullptr, "Unknown"},
{0x8B, nullptr, "Unknown"},
{0x8C, nullptr, "Unknown"},
{0x8D, nullptr, "Unknown"},
{0x8E, nullptr, "Unknown"},
{0x8F, nullptr, "Unknown"},
{0x90, nullptr, "Unknown"},
{0x91, nullptr, "Unknown"},
{0x92, nullptr, "Unknown"},
{0x93, nullptr, "Unknown"},
{0x94, nullptr, "Unknown"},
{0x95, nullptr, "Unknown"},
{0x96, nullptr, "Unknown"},
{0x97, nullptr, "Unknown"},
{0x98, nullptr, "Unknown"},
{0x99, nullptr, "Unknown"},
{0x9A, nullptr, "Unknown"},
{0x9B, nullptr, "Unknown"},
{0x9C, nullptr, "Unknown"},
{0x9D, nullptr, "Unknown"},
{0x9E, nullptr, "Unknown"},
{0x9F, nullptr, "Unknown"},
{0xA0, nullptr, "Unknown"},
{0xA1, nullptr, "Unknown"},
{0xA2, nullptr, "Unknown"},
{0xA3, nullptr, "Unknown"},
{0xA4, nullptr, "Unknown"},
{0xA5, nullptr, "Unknown"},
{0xA6, nullptr, "Unknown"},
{0xA7, nullptr, "Unknown"},
{0xA8, nullptr, "Unknown"},
{0xA9, nullptr, "Unknown"},
{0xAA, nullptr, "Unknown"},
{0xAB, nullptr, "Unknown"},
{0xAC, nullptr, "Unknown"},
{0xAD, nullptr, "Unknown"},
{0xAE, nullptr, "Unknown"},
{0xAF, nullptr, "Unknown"},
{0xB0, nullptr, "Unknown"},
{0xB1, nullptr, "Unknown"},
{0xB2, nullptr, "Unknown"},
{0xB3, nullptr, "Unknown"},
{0xB4, nullptr, "Unknown"},
{0xB5, nullptr, "Unknown"},
{0xB6, nullptr, "Unknown"},
{0xB7, nullptr, "Unknown"},
{0xB8, nullptr, "Unknown"},
{0xB9, nullptr, "Unknown"},
{0xBA, nullptr, "Unknown"},
{0xBB, nullptr, "Unknown"},
{0xBC, nullptr, "Unknown"},
{0xBD, nullptr, "Unknown"},
{0xBE, nullptr, "Unknown"},
{0xBF, nullptr, "Unknown"},
};
static const FunctionDef* GetSVCInfo32(u32 func_num) {
+11 -6
View File
@@ -610,12 +610,17 @@ public:
explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData
{1, nullptr, "LoadAuthenticationTokenCache"}, // 6.0.0+
{2, nullptr, "InvalidateAuthenticationTokenCache"}, // 6.0.0+
{10, nullptr, "EnsureEdgeTokenCacheAsync"}, // 6.0.0+
{11, nullptr, "LoadEdgeTokenCache"}, // 6.0.0+
{12, nullptr, "InvalidateEdgeTokenCache"}, // 6.0.0+
{0, nullptr, "EnsureAuthenticationTokenCacheAsync"},
{1, nullptr, "LoadAuthenticationTokenCache"},
{2, nullptr, "InvalidateAuthenticationTokenCache"},
{10, nullptr, "EnsureEdgeTokenCacheAsync"},
{11, nullptr, "LoadEdgeTokenCache"},
{12, nullptr, "InvalidateEdgeTokenCache"},
{20, nullptr, "EnsureApplicationAuthenticationCacheAsync"},
{21, nullptr, "LoadApplicationAuthenticationTokenCache"},
{22, nullptr, "LoadApplicationNetworkServiceClientConfigCache"},
{23, nullptr, "IsApplicationAuthenticationCacheAvailable"},
{24, nullptr, "InvalidateApplicationAuthenticationCache"},
};
// clang-format on
+19 -17
View File
@@ -17,28 +17,30 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{3, &ACC_SU::ListOpenUsers, "ListOpenUsers"},
{4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"},
{5, &ACC_SU::GetProfile, "GetProfile"},
{6, nullptr, "GetProfileDigest"}, // 3.0.0+
{6, nullptr, "GetProfileDigest"},
{50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
{51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
{99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
{60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
{99, nullptr, "DebugActivateOpenContextRetention"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
{102, nullptr, "GetBaasAccountManagerForSystemService"},
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{104, nullptr, "GetProfileUpdateNotifier"},
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
{106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
{106, nullptr, "GetProfileSyncNotifier"},
{110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{112, nullptr, "LoadSaveDataThumbnail"},
{113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
{120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+
{130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+
{140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
{150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+
{190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0
{191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+
{113, nullptr, "GetSaveDataThumbnailExistence"},
{120, nullptr, "ListOpenUsersInApplication"},
{130, nullptr, "ActivateOpenContextRetention"},
{140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
{150, nullptr, "AuthenticateApplicationAsync"},
{151, nullptr, "Unknown151"},
{152, nullptr, "Unknown152"},
{190, nullptr, "GetUserLastOpenedApplication"},
{191, nullptr, "ActivateOpenContextHolder"},
{200, nullptr, "BeginUserRegistration"},
{201, nullptr, "CompleteUserRegistration"},
{202, nullptr, "CancelUserRegistration"},
@@ -46,15 +48,15 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{204, nullptr, "SetUserPosition"},
{205, &ACC_SU::GetProfileEditor, "GetProfileEditor"},
{206, nullptr, "CompleteUserRegistrationForcibly"},
{210, nullptr, "CreateFloatingRegistrationRequest"}, // 3.0.0+
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+
{210, nullptr, "CreateFloatingRegistrationRequest"},
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
{230, nullptr, "AuthenticateServiceAsync"},
{250, nullptr, "GetBaasAccountAdministrator"},
{290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, // 3.0.0+
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
{299, nullptr, "SuspendBackgroundDaemon"},
{997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+
{997, nullptr, "DebugInvalidateTokenCacheForUser"},
{998, nullptr, "DebugSetUserStateClose"},
{999, nullptr, "DebugSetUserStateOpen"},
};
+15 -13
View File
@@ -17,29 +17,31 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{3, &ACC_U1::ListOpenUsers, "ListOpenUsers"},
{4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"},
{5, &ACC_U1::GetProfile, "GetProfile"},
{6, nullptr, "GetProfileDigest"}, // 3.0.0+
{6, nullptr, "GetProfileDigest"},
{50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
{51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
{99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
{60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
{99, nullptr, "DebugActivateOpenContextRetention"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
{102, nullptr, "GetBaasAccountManagerForSystemService"},
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{104, nullptr, "GetProfileUpdateNotifier"},
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
{106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
{106, nullptr, "GetProfileSyncNotifier"},
{110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{112, nullptr, "LoadSaveDataThumbnail"},
{113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
{120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+
{130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+
{140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
{150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+
{190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0
{191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+
{997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+
{113, nullptr, "GetSaveDataThumbnailExistence"},
{120, nullptr, "ListOpenUsersInApplication"},
{130, nullptr, "ActivateOpenContextRetention"},
{140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
{150, nullptr, "AuthenticateApplicationAsync"},
{151, nullptr, "Unknown151"},
{152, nullptr, "Unknown152"},
{190, nullptr, "GetUserLastOpenedApplication"},
{191, nullptr, "ActivateOpenContextHolder"},
{997, nullptr, "DebugInvalidateTokenCacheForUser"},
{998, nullptr, "DebugSetUserStateClose"},
{999, nullptr, "DebugSetUserStateOpen"},
};
+1 -1
View File
@@ -8,8 +8,8 @@
#include <fmt/format.h>
#include "common/file_util.h"
#include "common/settings.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/settings.h"
namespace Service::Account {
+23 -1
View File
@@ -7,6 +7,7 @@
#include <cinttypes>
#include <cstring>
#include "audio_core/audio_renderer.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -41,7 +42,6 @@
#include "core/hle/service/set/set.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/vi/vi.h"
#include "core/settings.h"
namespace Service::AM {
@@ -231,6 +231,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
{10, nullptr, "PerformSystemButtonPressing"},
{20, nullptr, "InvalidateTransitionLayer"},
{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
{31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
{40, nullptr, "GetAppletResourceUsageInfo"},
{100, nullptr, "SetCpuBoostModeForApplet"},
{101, nullptr, "CancelCpuBoostModeForApplet"},
@@ -242,6 +243,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
{130, nullptr, "FriendInvitationSetApplicationParameter"},
{131, nullptr, "FriendInvitationClearApplicationParameter"},
{132, nullptr, "FriendInvitationPushApplicationParameter"},
{900, nullptr, "GetGrcProcessLaunchedSystemEvent"},
};
// clang-format on
@@ -297,6 +299,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
{91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
{100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
{110, nullptr, "SetApplicationAlbumUserData"},
{120, nullptr, "SaveCurrentScreenshot"},
{1000, nullptr, "GetDebugStorageChannel"},
};
// clang-format on
@@ -645,6 +648,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{11, nullptr, "ReleaseSleepLock"},
{12, nullptr, "ReleaseSleepLockTransiently"},
{13, nullptr, "GetAcquiredSleepLockEvent"},
{14, nullptr, "GetWakeupCount"},
{20, nullptr, "PushToGeneralChannel"},
{30, nullptr, "GetHomeButtonReaderLockAccessor"},
{31, nullptr, "GetReaderLockAccessorEx"},
@@ -656,6 +660,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"},
{54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"},
{55, nullptr, "IsInControllerFirmwareUpdateSection"},
{59, nullptr, "SetVrPositionForDebug"},
{60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"},
{61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"},
{62, nullptr, "GetHdcpAuthenticationState"},
@@ -664,14 +669,21 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{65, nullptr, "GetApplicationIdByContentActionName"},
{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
{67, nullptr, "CancelCpuBoostMode"},
{68, nullptr, "GetBuiltInDisplayType"},
{80, nullptr, "PerformSystemButtonPressingIfInFocus"},
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
{91, nullptr, "GetCurrentPerformanceConfiguration"},
{100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
{110, nullptr, "OpenMyGpuErrorHandler"},
{200, nullptr, "GetOperationModeSystemInfo"},
{300, nullptr, "GetSettingsPlatformRegion"},
{400, nullptr, "ActivateMigrationService"},
{401, nullptr, "DeactivateMigrationService"},
{500, nullptr, "DisableSleepTillShutdown"},
{501, nullptr, "SuppressDisablingSleepTemporarily"},
{502, nullptr, "IsSleepEnabled"},
{503, nullptr, "IsDisablingSleepSuppressed"},
{900, nullptr, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"},
};
// clang-format on
@@ -1203,11 +1215,14 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
{26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
{27, nullptr, "CreateCacheStorage"},
{28, nullptr, "GetSaveDataSizeMax"},
{29, nullptr, "GetCacheStorageMax"},
{30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
{31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
{32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
{33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
{34, nullptr, "SelectApplicationLicense"},
{35, nullptr, "GetDeviceSaveDataSizeMax"},
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
{50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
{60, nullptr, "SetMediaPlaybackStateForApplication"},
@@ -1231,6 +1246,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
{131, nullptr, "SetDelayTimeToAbortOnGpuError"},
{140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
{141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"},
{150, nullptr, "GetNotificationStorageChannelEvent"},
@@ -1239,6 +1255,8 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{170, nullptr, "SetHdcpAuthenticationActivated"},
{180, nullptr, "GetLaunchRequiredVersion"},
{181, nullptr, "UpgradeLaunchRequiredVersion"},
{190, nullptr, "SendServerMaintenanceOverlayNotification"},
{200, nullptr, "GetLastApplicationExitReason"},
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
{1000, nullptr, "CreateMovieMaker"},
{1001, nullptr, "PrepareForJit"},
@@ -1705,9 +1723,12 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
{21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"},
{30, nullptr, "GetHomeButtonWriterLockAccessor"},
{31, nullptr, "GetWriterLockAccessorEx"},
{40, nullptr, "IsSleepEnabled"},
{41, nullptr, "IsRebootEnabled"},
{100, nullptr, "PopRequestLaunchApplicationForDebug"},
{110, nullptr, "IsForceTerminateApplicationDisabledForDebug"},
{200, nullptr, "LaunchDevMenu"},
{1000, nullptr, "SetLastApplicationExitReason"},
};
// clang-format on
@@ -1751,6 +1772,7 @@ IGlobalStateController::IGlobalStateController(Core::System& system_)
{13, nullptr, "UpdateDefaultDisplayResolution"},
{14, nullptr, "ShouldSleepOnBoot"},
{15, nullptr, "GetHdcpAuthenticationFailedEvent"},
{30, nullptr, "OpenCradleFirmwareUpdater"},
};
// clang-format on
+3 -1
View File
@@ -7,6 +7,7 @@
#include <vector>
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
@@ -21,7 +22,6 @@
#include "core/hle/kernel/process.h"
#include "core/hle/service/aoc/aoc_u.h"
#include "core/loader/loader.h"
#include "core/settings.h"
namespace Service::AOC {
@@ -118,8 +118,10 @@ AOC_U::AOC_U(Core::System& system_)
{7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"},
{8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"},
{9, nullptr, "GetAddOnContentLostErrorCode"},
{10, nullptr, "GetAddOnContentListChangedEventWithProcessId"},
{100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"},
{101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"},
{110, nullptr, "CreateContentsServiceManager"},
};
// clang-format on
+1 -1
View File
@@ -7,9 +7,9 @@
#include <utility>
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core_timing.h"
#include "core/hle/service/apm/controller.h"
#include "core/settings.h"
namespace Service::APM {
+4 -4
View File
@@ -9,10 +9,10 @@ namespace Service::Audio {
AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestSuspendAudioIns"},
{1, nullptr, "RequestResumeAudioIns"},
{2, nullptr, "GetAudioInsProcessMasterVolume"},
{3, nullptr, "SetAudioInsProcessMasterVolume"},
{0, nullptr, "RequestSuspend"},
{1, nullptr, "RequestResume"},
{2, nullptr, "GetProcessMasterVolume"},
{3, nullptr, "SetProcessMasterVolume"},
};
// clang-format on
+7 -7
View File
@@ -15,19 +15,19 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetAudioInState"},
{1, nullptr, "StartAudioIn"},
{2, nullptr, "StopAudioIn"},
{1, nullptr, "Start"},
{2, nullptr, "Stop"},
{3, nullptr, "AppendAudioInBuffer"},
{4, nullptr, "RegisterBufferEvent"},
{5, nullptr, "GetReleasedAudioInBuffer"},
{6, nullptr, "ContainsAudioInBuffer"},
{7, nullptr, "AppendAudioInBufferWithUserEvent"},
{7, nullptr, "AppendUacInBuffer"},
{8, nullptr, "AppendAudioInBufferAuto"},
{9, nullptr, "GetReleasedAudioInBufferAuto"},
{10, nullptr, "AppendAudioInBufferWithUserEventAuto"},
{9, nullptr, "GetReleasedAudioInBuffersAuto"},
{10, nullptr, "AppendUacInBufferAuto"},
{11, nullptr, "GetAudioInBufferCount"},
{12, nullptr, "SetAudioInDeviceGain"},
{13, nullptr, "GetAudioInDeviceGain"},
{12, nullptr, "SetDeviceGain"},
{13, nullptr, "GetDeviceGain"},
{14, nullptr, "FlushAudioInBuffers"},
};
// clang-format on
+6 -6
View File
@@ -9,12 +9,12 @@ namespace Service::Audio {
AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestSuspendAudioOuts"},
{1, nullptr, "RequestResumeAudioOuts"},
{2, nullptr, "GetAudioOutsProcessMasterVolume"},
{3, nullptr, "SetAudioOutsProcessMasterVolume"},
{4, nullptr, "GetAudioOutsProcessRecordVolume"},
{5, nullptr, "SetAudioOutsProcessRecordVolume"},
{0, nullptr, "RequestSuspend"},
{1, nullptr, "RequestResume"},
{2, nullptr, "GetProcessMasterVolume"},
{3, nullptr, "SetProcessMasterVolume"},
{4, nullptr, "GetProcessRecordVolume"},
{5, nullptr, "SetProcessRecordVolume"},
};
// clang-format on
+3 -3
View File
@@ -49,11 +49,11 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
{1, &IAudioOut::StartAudioOut, "StartAudioOut"},
{2, &IAudioOut::StopAudioOut, "StopAudioOut"},
{1, &IAudioOut::StartAudioOut, "Start"},
{2, &IAudioOut::StopAudioOut, "Stop"},
{3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"},
{4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
{5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"},
{5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffers"},
{6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
{7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"},
{8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
+2 -2
View File
@@ -9,8 +9,8 @@ namespace Service::Audio {
AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestSuspendFinalOutputRecorders"},
{1, nullptr, "RequestResumeFinalOutputRecorders"},
{0, nullptr, "RequestSuspend"},
{1, nullptr, "RequestResume"},
};
// clang-format on
+4 -3
View File
@@ -13,16 +13,17 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetFinalOutputRecorderState"},
{1, nullptr, "StartFinalOutputRecorder"},
{2, nullptr, "StopFinalOutputRecorder"},
{1, nullptr, "Start"},
{2, nullptr, "Stop"},
{3, nullptr, "AppendFinalOutputRecorderBuffer"},
{4, nullptr, "RegisterBufferEvent"},
{5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
{5, nullptr, "GetReleasedFinalOutputRecorderBuffers"},
{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
{7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
{10, nullptr, "FlushFinalOutputRecorderBuffers"},
{11, nullptr, "AttachWorkBuffer"},
};
// clang-format on
+6 -6
View File
@@ -9,14 +9,14 @@ namespace Service::Audio {
AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestSuspendAudioRenderers"},
{1, nullptr, "RequestResumeAudioRenderers"},
{2, nullptr, "GetAudioRenderersProcessMasterVolume"},
{3, nullptr, "SetAudioRenderersProcessMasterVolume"},
{0, nullptr, "RequestSuspend"},
{1, nullptr, "RequestResume"},
{2, nullptr, "GetProcessMasterVolume"},
{3, nullptr, "SetProcessMasterVolume"},
{4, nullptr, "RegisterAppletResourceUserId"},
{5, nullptr, "UnregisterAppletResourceUserId"},
{6, nullptr, "GetAudioRenderersProcessRecordVolume"},
{7, nullptr, "SetAudioRenderersProcessRecordVolume"},
{6, nullptr, "GetProcessRecordVolume"},
{7, nullptr, "SetProcessRecordVolume"},
};
// clang-format on
+3 -3
View File
@@ -332,9 +332,9 @@ AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"}
// clang-format off
static const FunctionInfo functions[] = {
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetWorkBufferSize"},
{2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"},
{3, &AudRenU::OpenAudioRendererAuto, "OpenAudioRendererAuto"},
{3, &AudRenU::OpenAudioRendererForManualExecution, "OpenAudioRendererForManualExecution"},
{4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"},
};
// clang-format on
@@ -665,7 +665,7 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1'));
}
void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
void AudRenU::OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
OpenAudioRendererImpl(ctx);
+1 -1
View File
@@ -25,7 +25,7 @@ private:
void OpenAudioRenderer(Kernel::HLERequestContext& ctx);
void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
void GetAudioDeviceService(Kernel::HLERequestContext& ctx);
void OpenAudioRendererAuto(Kernel::HLERequestContext& ctx);
void OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx);
void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx);
void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
+13 -13
View File
@@ -8,19 +8,19 @@ namespace Service::Audio {
CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} {
static const FunctionInfo functions[] = {
{0, nullptr, "InitializeCodecController"},
{1, nullptr, "FinalizeCodecController"},
{2, nullptr, "SleepCodecController"},
{3, nullptr, "WakeCodecController"},
{4, nullptr, "SetCodecVolume"},
{5, nullptr, "GetCodecVolumeMax"},
{6, nullptr, "GetCodecVolumeMin"},
{7, nullptr, "SetCodecActiveTarget"},
{8, nullptr, "GetCodecActiveTarget"},
{9, nullptr, "BindCodecHeadphoneMicJackInterrupt"},
{10, nullptr, "IsCodecHeadphoneMicJackInserted"},
{11, nullptr, "ClearCodecHeadphoneMicJackInterrupt"},
{12, nullptr, "IsCodecDeviceRequested"},
{0, nullptr, "Initialize"},
{1, nullptr, "Finalize"},
{2, nullptr, "Sleep"},
{3, nullptr, "Wake"},
{4, nullptr, "SetVolume"},
{5, nullptr, "GetVolumeMax"},
{6, nullptr, "GetVolumeMin"},
{7, nullptr, "SetActiveTarget"},
{8, nullptr, "GetActiveTarget"},
{9, nullptr, "BindHeadphoneMicJackInterrupt"},
{10, nullptr, "IsHeadphoneMicJackInserted"},
{11, nullptr, "ClearHeadphoneMicJackInterrupt"},
{12, nullptr, "IsRequested"},
};
RegisterHandlers(functions);
}
+4
View File
@@ -297,6 +297,10 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
{2, nullptr, "OpenOpusDecoderForMultiStream"},
{3, nullptr, "GetWorkBufferSizeForMultiStream"},
{4, nullptr, "OpenHardwareOpusDecoderEx"},
{5, nullptr, "GetWorkBufferSizeEx"},
{6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"},
{7, nullptr, "GetWorkBufferSizeForMultiStreamEx"},
};
RegisterHandlers(functions);
}
+1 -1
View File
@@ -9,6 +9,7 @@
#include "common/hex_util.h"
#include "common/logging/backend.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_libzip.h"
@@ -16,7 +17,6 @@
#include "core/frontend/applets/error.h"
#include "core/hle/service/am/applets/applets.h"
#include "core/hle/service/bcat/backend/boxcat.h"
#include "core/settings.h"
namespace Service::BCAT {
namespace {
+3 -1
View File
@@ -7,6 +7,7 @@
#include "backend/boxcat.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/vfs.h"
@@ -18,7 +19,6 @@
#include "core/hle/service/bcat/bcat.h"
#include "core/hle/service/bcat/module.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/settings.h"
namespace Service::BCAT {
@@ -155,10 +155,12 @@ public:
{30210, nullptr, "SetDeliveryTaskTimer"},
{30300, nullptr, "RegisterSystemApplicationDeliveryTasks"},
{90100, nullptr, "EnumerateBackgroundDeliveryTask"},
{90101, nullptr, "Unknown90101"},
{90200, nullptr, "GetDeliveryList"},
{90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"},
{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
{90300, nullptr, "GetPushNotificationLog"},
{90301, nullptr, "Unknown90301"},
};
// clang-format on
RegisterHandlers(functions);
+2 -2
View File
@@ -29,8 +29,8 @@ public:
{11, nullptr, "CreateWakeupTimerEx"},
{12, nullptr, "GetLastEnabledWakeupTimerType"},
{13, nullptr, "CleanAllWakeupTimers"},
{14, nullptr, "Unknown"},
{15, nullptr, "Unknown2"},
{14, nullptr, "GetPowerButton"},
{15, nullptr, "SetEnableWakeupTimer"},
};
// clang-format on
+19
View File
@@ -156,6 +156,25 @@ public:
{97, nullptr, "RegisterBleHidEvent"},
{98, nullptr, "SetBleScanParameter"},
{99, nullptr, "MoveToSecondaryPiconet"},
{100, nullptr, "IsBluetoothEnabled"},
{128, nullptr, "AcquireAudioEvent"},
{129, nullptr, "GetAudioEventInfo"},
{130, nullptr, "OpenAudioConnection"},
{131, nullptr, "CloseAudioConnection"},
{132, nullptr, "OpenAudioOut"},
{133, nullptr, "CloseAudioOut"},
{134, nullptr, "AcquireAudioOutStateChangedEvent"},
{135, nullptr, "StartAudioOut"},
{136, nullptr, "StopAudioOut"},
{137, nullptr, "GetAudioOutState"},
{138, nullptr, "GetAudioOutFeedingCodec"},
{139, nullptr, "GetAudioOutFeedingParameter"},
{140, nullptr, "AcquireAudioOutBufferAvailableEvent"},
{141, nullptr, "SendAudioData"},
{142, nullptr, "AcquireAudioControlInputStateChangedEvent"},
{143, nullptr, "GetAudioControlInputState"},
{144, nullptr, "AcquireAudioConnectionStateChangedEvent"},
{145, nullptr, "GetConnectedAudioDevice"},
{256, nullptr, "IsManufacturingMode"},
{257, nullptr, "EmulateBluetoothCrash"},
{258, nullptr, "GetBleChannelMap"},
+1
View File
@@ -223,6 +223,7 @@ public:
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
{13, nullptr, "Unknown13"},
};
// clang-format on
+1
View File
@@ -49,6 +49,7 @@ CAPS_A::CAPS_A(Core::System& system_) : ServiceFramework{system_, "caps:a"} {
{16, nullptr, "GetAlbumMountResult"},
{17, nullptr, "GetAlbumUsage16"},
{18, nullptr, "Unknown18"},
{19, nullptr, "Unknown19"},
{100, nullptr, "GetAlbumFileCountEx0"},
{101, nullptr, "GetAlbumFileListEx0"},
{202, nullptr, "SaveEditedScreenShot"},
+1
View File
@@ -43,6 +43,7 @@ CAPS_U::CAPS_U(Core::System& system_) : ServiceFramework{system_, "caps:u"} {
{141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"},
{142, &CAPS_U::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"},
{143, nullptr, "GetAlbumFileList4AaeUidAruid"},
{144, nullptr, "GetAllAlbumFileList3AaeAruid"},
{60002, nullptr, "OpenAccessorSessionForApplication"},
};
// clang-format on
+6 -1
View File
@@ -16,7 +16,7 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SubmitContext"},
{1, nullptr, "CreateReport"},
{1, nullptr, "CreateReportV0"},
{2, nullptr, "SetInitialLaunchSettingsCompletionTime"},
{3, nullptr, "ClearInitialLaunchSettingsCompletionTime"},
{4, nullptr, "UpdatePowerOnTime"},
@@ -26,6 +26,11 @@ public:
{8, nullptr, "ClearApplicationLaunchTime"},
{9, nullptr, "SubmitAttachment"},
{10, nullptr, "CreateReportWithAttachments"},
{11, nullptr, "CreateReport"},
{20, nullptr, "RegisterRunningApplet"},
{21, nullptr, "UnregisterRunningApplet"},
{22, nullptr, "UpdateAppletSuspendedDuration"},
{30, nullptr, "InvalidateForcedShutdownDetection"},
};
// clang-format on
@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/file_util.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/bis_factory.h"
#include "core/file_sys/card_image.h"
@@ -26,7 +27,6 @@
#include "core/hle/service/filesystem/fsp_pr.h"
#include "core/hle/service/filesystem/fsp_srv.h"
#include "core/loader/loader.h"
#include "core/settings.h"
namespace Service::FileSystem {
+14 -5
View File
@@ -118,9 +118,13 @@ public:
explicit IFile(Core::System& system_, FileSys::VirtualFile backend_)
: ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {
static const FunctionInfo functions[] = {
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
{2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
{4, &IFile::GetSize, "GetSize"}, {5, nullptr, "OperateRange"},
{0, &IFile::Read, "Read"},
{1, &IFile::Write, "Write"},
{2, &IFile::Flush, "Flush"},
{3, &IFile::SetSize, "SetSize"},
{4, &IFile::GetSize, "GetSize"},
{5, nullptr, "OperateRange"},
{6, nullptr, "OperateRangeWithBuffer"},
};
RegisterHandlers(functions);
}
@@ -708,7 +712,10 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
{85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"},
{86, nullptr, "OpenSaveDataMover"},
{87, nullptr, "OpenSaveDataTransferManagerForRepair"},
{100, nullptr, "OpenImageDirectoryFileSystem"},
{101, nullptr, "OpenBaseFileSystem"},
{102, nullptr, "FormatBaseFileSystem"},
{110, nullptr, "OpenContentStorageFileSystem"},
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
{130, nullptr, "OpenCustomStorageFileSystem"},
@@ -764,10 +771,12 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{1008, nullptr, "OpenRegisteredUpdatePartition"},
{1009, nullptr, "GetAndClearMemoryReportInfo"},
{1010, nullptr, "SetDataStorageRedirectTarget"},
{1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
{1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"},
{1012, nullptr, "GetFsStackUsage"},
{1013, nullptr, "UnsetSaveDataRootPath"},
{1014, nullptr, "OutputMultiProgramTagAccessLog"},
{1016, nullptr, "FlushAccessLogOnSdCard"},
{1017, nullptr, "OutputApplicationInfoAccessLog"},
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
{1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"},
@@ -1051,7 +1060,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 4};
+1 -1
View File
@@ -53,7 +53,7 @@ private:
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
void GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx);
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
FileSystemController& fsc;
+13 -1
View File
@@ -38,7 +38,7 @@ public:
{10600, nullptr, "DeclareOpenOnlinePlaySession"},
{10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"},
{10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"},
{10700, nullptr, "GetPlayHistoryRegistrationKey"},
{10700, &IFriendService::GetPlayHistoryRegistrationKey, "GetPlayHistoryRegistrationKey"},
{10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"},
{10702, nullptr, "AddPlayHistory"},
{11000, nullptr, "GetProfileImageUrl"},
@@ -153,6 +153,18 @@ private:
rb.Push(RESULT_SUCCESS);
}
void GetPlayHistoryRegistrationKey(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto local_play = rp.Pop<bool>();
const auto uuid = rp.PopRaw<Common::UUID>();
LOG_WARNING(Service_Friend, "(STUBBED) called local_play={} uuid={}", local_play,
uuid.Format());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetFriendList(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto friend_offset = rp.Pop<u32>();
+9 -2
View File
@@ -41,6 +41,12 @@ ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_)
{1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"},
{2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"},
{3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"},
{4, nullptr, "GetApplicationInstanceUnregistrationNotifier"},
{5, nullptr, "ListApplicationInstanceId"},
{6, nullptr, "GetMicroApplicationInstanceId"},
{7, nullptr, "GetApplicationCertificate"},
{9998, nullptr, "GetPreomiaApplicationLaunchProperty"},
{9999, nullptr, "GetPreomiaApplicationControlProperty"},
};
// clang-format on
@@ -243,7 +249,8 @@ ARP_W::ARP_W(Core::System& system_, ARPManager& manager_)
// clang-format off
static const FunctionInfo functions[] = {
{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
{1, &ARP_W::DeleteProperties, "DeleteProperties"},
{1, &ARP_W::UnregisterApplicationInstance , "UnregisterApplicationInstance "},
{2, nullptr, "AcquireUpdater"},
};
// clang-format on
@@ -270,7 +277,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface(registrar);
}
void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) {
void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto process_id = rp.PopRaw<u64>();
+1 -1
View File
@@ -32,7 +32,7 @@ public:
private:
void AcquireRegistrar(Kernel::HLERequestContext& ctx);
void DeleteProperties(Kernel::HLERequestContext& ctx);
void UnregisterApplicationInstance(Kernel::HLERequestContext& ctx);
ARPManager& manager;
std::shared_ptr<IRegistrar> registrar;

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