diff options
Diffstat (limited to 'src')
118 files changed, 3268 insertions, 495 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 788516ded..9f8dafa3b 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -97,6 +97,7 @@ add_custom_command(OUTPUT scm_rev.cpp | |||
| 97 | add_library(common STATIC | 97 | add_library(common STATIC |
| 98 | algorithm.h | 98 | algorithm.h |
| 99 | alignment.h | 99 | alignment.h |
| 100 | assert.cpp | ||
| 100 | assert.h | 101 | assert.h |
| 101 | atomic_ops.h | 102 | atomic_ops.h |
| 102 | detached_tasks.cpp | 103 | detached_tasks.cpp |
| @@ -109,6 +110,7 @@ add_library(common STATIC | |||
| 109 | cityhash.h | 110 | cityhash.h |
| 110 | common_funcs.h | 111 | common_funcs.h |
| 111 | common_paths.h | 112 | common_paths.h |
| 113 | common_sizes.h | ||
| 112 | common_types.h | 114 | common_types.h |
| 113 | concepts.h | 115 | concepts.h |
| 114 | div_ceil.h | 116 | div_ceil.h |
diff --git a/src/common/assert.cpp b/src/common/assert.cpp new file mode 100644 index 000000000..d7d91b96b --- /dev/null +++ b/src/common/assert.cpp | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | |||
| 7 | #include "common/common_funcs.h" | ||
| 8 | |||
| 9 | void assert_handle_failure() { | ||
| 10 | Crash(); | ||
| 11 | } | ||
diff --git a/src/common/assert.h b/src/common/assert.h index 06d7b5612..b3ba35c0f 100644 --- a/src/common/assert.h +++ b/src/common/assert.h | |||
| @@ -4,10 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstdlib> | ||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 10 | 8 | ||
| 9 | // Sometimes we want to try to continue even after hitting an assert. | ||
| 10 | // However touching this file yields a global recompilation as this header is included almost | ||
| 11 | // everywhere. So let's just move the handling of the failed assert to a single cpp file. | ||
| 12 | void assert_handle_failure(); | ||
| 13 | |||
| 11 | // For asserts we'd like to keep all the junk executed when an assert happens away from the | 14 | // For asserts we'd like to keep all the junk executed when an assert happens away from the |
| 12 | // important code in the function. One way of doing this is to put all the relevant code inside a | 15 | // important code in the function. One way of doing this is to put all the relevant code inside a |
| 13 | // lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to | 16 | // lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to |
| @@ -17,15 +20,14 @@ | |||
| 17 | // enough for our purposes. | 20 | // enough for our purposes. |
| 18 | template <typename Fn> | 21 | template <typename Fn> |
| 19 | #if defined(_MSC_VER) | 22 | #if defined(_MSC_VER) |
| 20 | [[msvc::noinline, noreturn]] | 23 | [[msvc::noinline]] |
| 21 | #elif defined(__GNUC__) | 24 | #elif defined(__GNUC__) |
| 22 | [[gnu::cold, gnu::noinline, noreturn]] | 25 | [[gnu::cold, gnu::noinline]] |
| 23 | #endif | 26 | #endif |
| 24 | static void | 27 | static void |
| 25 | assert_noinline_call(const Fn& fn) { | 28 | assert_noinline_call(const Fn& fn) { |
| 26 | fn(); | 29 | fn(); |
| 27 | Crash(); | 30 | assert_handle_failure(); |
| 28 | exit(1); // Keeps GCC's mouth shut about this actually returning | ||
| 29 | } | 31 | } |
| 30 | 32 | ||
| 31 | #define ASSERT(_a_) \ | 33 | #define ASSERT(_a_) \ |
diff --git a/src/common/common_sizes.h b/src/common/common_sizes.h new file mode 100644 index 000000000..7e9fd968b --- /dev/null +++ b/src/common/common_sizes.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <limits> | ||
| 8 | |||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | namespace Common { | ||
| 12 | |||
| 13 | enum : u64 { | ||
| 14 | Size_1_KB = 0x400ULL, | ||
| 15 | Size_64_KB = 64ULL * Size_1_KB, | ||
| 16 | Size_128_KB = 128ULL * Size_1_KB, | ||
| 17 | Size_1_MB = 0x100000ULL, | ||
| 18 | Size_2_MB = 2ULL * Size_1_MB, | ||
| 19 | Size_4_MB = 4ULL * Size_1_MB, | ||
| 20 | Size_5_MB = 5ULL * Size_1_MB, | ||
| 21 | Size_14_MB = 14ULL * Size_1_MB, | ||
| 22 | Size_32_MB = 32ULL * Size_1_MB, | ||
| 23 | Size_33_MB = 33ULL * Size_1_MB, | ||
| 24 | Size_128_MB = 128ULL * Size_1_MB, | ||
| 25 | Size_448_MB = 448ULL * Size_1_MB, | ||
| 26 | Size_507_MB = 507ULL * Size_1_MB, | ||
| 27 | Size_562_MB = 562ULL * Size_1_MB, | ||
| 28 | Size_1554_MB = 1554ULL * Size_1_MB, | ||
| 29 | Size_2048_MB = 2048ULL * Size_1_MB, | ||
| 30 | Size_2193_MB = 2193ULL * Size_1_MB, | ||
| 31 | Size_3285_MB = 3285ULL * Size_1_MB, | ||
| 32 | Size_4916_MB = 4916ULL * Size_1_MB, | ||
| 33 | Size_1_GB = 0x40000000ULL, | ||
| 34 | Size_2_GB = 2ULL * Size_1_GB, | ||
| 35 | Size_4_GB = 4ULL * Size_1_GB, | ||
| 36 | Size_6_GB = 6ULL * Size_1_GB, | ||
| 37 | Size_8_GB = 8ULL * Size_1_GB, | ||
| 38 | Size_64_GB = 64ULL * Size_1_GB, | ||
| 39 | Size_512_GB = 512ULL * Size_1_GB, | ||
| 40 | Size_Invalid = std::numeric_limits<u64>::max(), | ||
| 41 | }; | ||
| 42 | |||
| 43 | } // namespace Common | ||
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 2d4d2e9e7..4575df24d 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -212,6 +212,7 @@ void DebuggerBackend::Write(const Entry& entry) { | |||
| 212 | SUB(Service, ARP) \ | 212 | SUB(Service, ARP) \ |
| 213 | SUB(Service, BCAT) \ | 213 | SUB(Service, BCAT) \ |
| 214 | SUB(Service, BPC) \ | 214 | SUB(Service, BPC) \ |
| 215 | SUB(Service, BGTC) \ | ||
| 215 | SUB(Service, BTDRV) \ | 216 | SUB(Service, BTDRV) \ |
| 216 | SUB(Service, BTM) \ | 217 | SUB(Service, BTM) \ |
| 217 | SUB(Service, Capture) \ | 218 | SUB(Service, Capture) \ |
diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 835894918..3d7b7dab7 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h | |||
| @@ -66,6 +66,7 @@ enum class Class : ClassType { | |||
| 66 | Service_ARP, ///< The ARP service | 66 | Service_ARP, ///< The ARP service |
| 67 | Service_Audio, ///< The Audio (Audio control) service | 67 | Service_Audio, ///< The Audio (Audio control) service |
| 68 | Service_BCAT, ///< The BCAT service | 68 | Service_BCAT, ///< The BCAT service |
| 69 | Service_BGTC, ///< The BGTC (Background Task Controller) service | ||
| 69 | Service_BPC, ///< The BPC service | 70 | Service_BPC, ///< The BPC service |
| 70 | Service_BTDRV, ///< The Bluetooth driver service | 71 | Service_BTDRV, ///< The Bluetooth driver service |
| 71 | Service_BTM, ///< The BTM service | 72 | Service_BTM, ///< The BTM service |
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h index a4647314a..ad04df8ca 100644 --- a/src/common/threadsafe_queue.h +++ b/src/common/threadsafe_queue.h | |||
| @@ -83,11 +83,15 @@ public: | |||
| 83 | return true; | 83 | return true; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | T PopWait() { | 86 | void Wait() { |
| 87 | if (Empty()) { | 87 | if (Empty()) { |
| 88 | std::unique_lock lock{cv_mutex}; | 88 | std::unique_lock lock{cv_mutex}; |
| 89 | cv.wait(lock, [this]() { return !Empty(); }); | 89 | cv.wait(lock, [this]() { return !Empty(); }); |
| 90 | } | 90 | } |
| 91 | } | ||
| 92 | |||
| 93 | T PopWait() { | ||
| 94 | Wait(); | ||
| 91 | T t; | 95 | T t; |
| 92 | Pop(t); | 96 | Pop(t); |
| 93 | return t; | 97 | return t; |
| @@ -156,6 +160,10 @@ public: | |||
| 156 | return spsc_queue.Pop(t); | 160 | return spsc_queue.Pop(t); |
| 157 | } | 161 | } |
| 158 | 162 | ||
| 163 | void Wait() { | ||
| 164 | spsc_queue.Wait(); | ||
| 165 | } | ||
| 166 | |||
| 159 | T PopWait() { | 167 | T PopWait() { |
| 160 | return spsc_queue.PopWait(); | 168 | return spsc_queue.PopWait(); |
| 161 | } | 169 | } |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 17f251c37..167ee13f3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -141,6 +141,9 @@ add_library(core STATIC | |||
| 141 | hardware_interrupt_manager.h | 141 | hardware_interrupt_manager.h |
| 142 | hle/ipc.h | 142 | hle/ipc.h |
| 143 | hle/ipc_helpers.h | 143 | hle/ipc_helpers.h |
| 144 | hle/kernel/board/nintendo/nx/k_system_control.cpp | ||
| 145 | hle/kernel/board/nintendo/nx/k_system_control.h | ||
| 146 | hle/kernel/board/nintendo/nx/secure_monitor.h | ||
| 144 | hle/kernel/client_port.cpp | 147 | hle/kernel/client_port.cpp |
| 145 | hle/kernel/client_port.h | 148 | hle/kernel/client_port.h |
| 146 | hle/kernel/client_session.cpp | 149 | hle/kernel/client_session.cpp |
| @@ -169,9 +172,13 @@ add_library(core STATIC | |||
| 169 | hle/kernel/k_memory_block.h | 172 | hle/kernel/k_memory_block.h |
| 170 | hle/kernel/k_memory_block_manager.cpp | 173 | hle/kernel/k_memory_block_manager.cpp |
| 171 | hle/kernel/k_memory_block_manager.h | 174 | hle/kernel/k_memory_block_manager.h |
| 175 | hle/kernel/k_memory_layout.cpp | ||
| 176 | hle/kernel/k_memory_layout.board.nintendo_nx.cpp | ||
| 172 | hle/kernel/k_memory_layout.h | 177 | hle/kernel/k_memory_layout.h |
| 173 | hle/kernel/k_memory_manager.cpp | 178 | hle/kernel/k_memory_manager.cpp |
| 174 | hle/kernel/k_memory_manager.h | 179 | hle/kernel/k_memory_manager.h |
| 180 | hle/kernel/k_memory_region.h | ||
| 181 | hle/kernel/k_memory_region_type.h | ||
| 175 | hle/kernel/k_page_bitmap.h | 182 | hle/kernel/k_page_bitmap.h |
| 176 | hle/kernel/k_page_heap.cpp | 183 | hle/kernel/k_page_heap.cpp |
| 177 | hle/kernel/k_page_heap.h | 184 | hle/kernel/k_page_heap.h |
| @@ -196,11 +203,11 @@ add_library(core STATIC | |||
| 196 | hle/kernel/k_spin_lock.h | 203 | hle/kernel/k_spin_lock.h |
| 197 | hle/kernel/k_synchronization_object.cpp | 204 | hle/kernel/k_synchronization_object.cpp |
| 198 | hle/kernel/k_synchronization_object.h | 205 | hle/kernel/k_synchronization_object.h |
| 199 | hle/kernel/k_system_control.cpp | ||
| 200 | hle/kernel/k_system_control.h | 206 | hle/kernel/k_system_control.h |
| 201 | hle/kernel/k_thread.cpp | 207 | hle/kernel/k_thread.cpp |
| 202 | hle/kernel/k_thread.h | 208 | hle/kernel/k_thread.h |
| 203 | hle/kernel/k_thread_queue.h | 209 | hle/kernel/k_thread_queue.h |
| 210 | hle/kernel/k_trace.h | ||
| 204 | hle/kernel/k_writable_event.cpp | 211 | hle/kernel/k_writable_event.cpp |
| 205 | hle/kernel/k_writable_event.h | 212 | hle/kernel/k_writable_event.h |
| 206 | hle/kernel/kernel.cpp | 213 | hle/kernel/kernel.cpp |
| @@ -666,7 +673,7 @@ endif() | |||
| 666 | create_target_directory_groups(core) | 673 | create_target_directory_groups(core) |
| 667 | 674 | ||
| 668 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | 675 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) |
| 669 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls opus zip) | 676 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus zip) |
| 670 | 677 | ||
| 671 | if (YUZU_ENABLE_BOXCAT) | 678 | if (YUZU_ENABLE_BOXCAT) |
| 672 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) | 679 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 305f56ff1..56b47e671 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -296,7 +296,7 @@ struct System::Impl { | |||
| 296 | exit_lock = false; | 296 | exit_lock = false; |
| 297 | 297 | ||
| 298 | if (gpu_core) { | 298 | if (gpu_core) { |
| 299 | gpu_core->WaitIdle(); | 299 | gpu_core->ShutDown(); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | services.reset(); | 302 | services.reset(); |
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index b0a130345..f66759815 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp | |||
| @@ -100,6 +100,14 @@ u64 NACP::GetDeviceSaveDataSize() const { | |||
| 100 | return raw.device_save_data_size; | 100 | return raw.device_save_data_size; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | u32 NACP::GetParentalControlFlag() const { | ||
| 104 | return raw.parental_control; | ||
| 105 | } | ||
| 106 | |||
| 107 | const std::array<u8, 0x20>& NACP::GetRatingAge() const { | ||
| 108 | return raw.rating_age; | ||
| 109 | } | ||
| 110 | |||
| 103 | std::vector<u8> NACP::GetRawBytes() const { | 111 | std::vector<u8> NACP::GetRawBytes() const { |
| 104 | std::vector<u8> out(sizeof(RawNACP)); | 112 | std::vector<u8> out(sizeof(RawNACP)); |
| 105 | std::memcpy(out.data(), &raw, sizeof(RawNACP)); | 113 | std::memcpy(out.data(), &raw, sizeof(RawNACP)); |
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 403c4219a..dd9837cf5 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h | |||
| @@ -114,6 +114,8 @@ public: | |||
| 114 | std::vector<u8> GetRawBytes() const; | 114 | std::vector<u8> GetRawBytes() const; |
| 115 | bool GetUserAccountSwitchLock() const; | 115 | bool GetUserAccountSwitchLock() const; |
| 116 | u64 GetDeviceSaveDataSize() const; | 116 | u64 GetDeviceSaveDataSize() const; |
| 117 | u32 GetParentalControlFlag() const; | ||
| 118 | const std::array<u8, 0x20>& GetRatingAge() const; | ||
| 117 | 119 | ||
| 118 | private: | 120 | private: |
| 119 | RawNACP raw{}; | 121 | RawNACP raw{}; |
diff --git a/src/core/hle/kernel/arch/arm64/k_memory_region_device_types.inc b/src/core/hle/kernel/arch/arm64/k_memory_region_device_types.inc new file mode 100644 index 000000000..857b512ba --- /dev/null +++ b/src/core/hle/kernel/arch/arm64/k_memory_region_device_types.inc | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // All architectures must define NumArchitectureDeviceRegions. | ||
| 6 | constexpr inline const auto NumArchitectureDeviceRegions = 3; | ||
| 7 | |||
| 8 | constexpr inline const auto KMemoryRegionType_Uart = | ||
| 9 | KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 0); | ||
| 10 | constexpr inline const auto KMemoryRegionType_InterruptCpuInterface = | ||
| 11 | KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 1) | ||
| 12 | .SetAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 13 | constexpr inline const auto KMemoryRegionType_InterruptDistributor = | ||
| 14 | KMemoryRegionType_ArchDeviceBase.DeriveSparse(0, NumArchitectureDeviceRegions, 2) | ||
| 15 | .SetAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 16 | static_assert(KMemoryRegionType_Uart.GetValue() == (0x1D)); | ||
| 17 | static_assert(KMemoryRegionType_InterruptCpuInterface.GetValue() == | ||
| 18 | (0x2D | KMemoryRegionAttr_NoUserMap)); | ||
| 19 | static_assert(KMemoryRegionType_InterruptDistributor.GetValue() == | ||
| 20 | (0x4D | KMemoryRegionAttr_NoUserMap)); | ||
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_memory_region_device_types.inc b/src/core/hle/kernel/board/nintendo/nx/k_memory_region_device_types.inc new file mode 100644 index 000000000..58d6c0b16 --- /dev/null +++ b/src/core/hle/kernel/board/nintendo/nx/k_memory_region_device_types.inc | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // All architectures must define NumBoardDeviceRegions. | ||
| 6 | constexpr inline const auto NumBoardDeviceRegions = 6; | ||
| 7 | // UNUSED: .Derive(NumBoardDeviceRegions, 0); | ||
| 8 | constexpr inline const auto KMemoryRegionType_MemoryController = | ||
| 9 | KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 1) | ||
| 10 | .SetAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 11 | constexpr inline const auto KMemoryRegionType_MemoryController1 = | ||
| 12 | KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 2) | ||
| 13 | .SetAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 14 | constexpr inline const auto KMemoryRegionType_MemoryController0 = | ||
| 15 | KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 3) | ||
| 16 | .SetAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 17 | constexpr inline const auto KMemoryRegionType_PowerManagementController = | ||
| 18 | KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 4).DeriveTransition(); | ||
| 19 | constexpr inline const auto KMemoryRegionType_LegacyLpsDevices = | ||
| 20 | KMemoryRegionType_BoardDeviceBase.Derive(NumBoardDeviceRegions, 5); | ||
| 21 | static_assert(KMemoryRegionType_MemoryController.GetValue() == | ||
| 22 | (0x55 | KMemoryRegionAttr_NoUserMap)); | ||
| 23 | static_assert(KMemoryRegionType_MemoryController1.GetValue() == | ||
| 24 | (0x65 | KMemoryRegionAttr_NoUserMap)); | ||
| 25 | static_assert(KMemoryRegionType_MemoryController0.GetValue() == | ||
| 26 | (0x95 | KMemoryRegionAttr_NoUserMap)); | ||
| 27 | static_assert(KMemoryRegionType_PowerManagementController.GetValue() == (0x1A5)); | ||
| 28 | |||
| 29 | static_assert(KMemoryRegionType_LegacyLpsDevices.GetValue() == 0xC5); | ||
| 30 | |||
| 31 | constexpr inline const auto NumLegacyLpsDevices = 7; | ||
| 32 | constexpr inline const auto KMemoryRegionType_LegacyLpsExceptionVectors = | ||
| 33 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 0); | ||
| 34 | constexpr inline const auto KMemoryRegionType_LegacyLpsIram = | ||
| 35 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 1); | ||
| 36 | constexpr inline const auto KMemoryRegionType_LegacyLpsFlowController = | ||
| 37 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 2); | ||
| 38 | constexpr inline const auto KMemoryRegionType_LegacyLpsPrimaryICtlr = | ||
| 39 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 3); | ||
| 40 | constexpr inline const auto KMemoryRegionType_LegacyLpsSemaphore = | ||
| 41 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 4); | ||
| 42 | constexpr inline const auto KMemoryRegionType_LegacyLpsAtomics = | ||
| 43 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 5); | ||
| 44 | constexpr inline const auto KMemoryRegionType_LegacyLpsClkRst = | ||
| 45 | KMemoryRegionType_LegacyLpsDevices.Derive(NumLegacyLpsDevices, 6); | ||
| 46 | static_assert(KMemoryRegionType_LegacyLpsExceptionVectors.GetValue() == 0x3C5); | ||
| 47 | static_assert(KMemoryRegionType_LegacyLpsIram.GetValue() == 0x5C5); | ||
| 48 | static_assert(KMemoryRegionType_LegacyLpsFlowController.GetValue() == 0x6C5); | ||
| 49 | static_assert(KMemoryRegionType_LegacyLpsPrimaryICtlr.GetValue() == 0x9C5); | ||
| 50 | static_assert(KMemoryRegionType_LegacyLpsSemaphore.GetValue() == 0xAC5); | ||
| 51 | static_assert(KMemoryRegionType_LegacyLpsAtomics.GetValue() == 0xCC5); | ||
| 52 | static_assert(KMemoryRegionType_LegacyLpsClkRst.GetValue() == 0x11C5); | ||
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp new file mode 100644 index 000000000..86472b5ce --- /dev/null +++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <random> | ||
| 6 | |||
| 7 | #include "common/common_sizes.h" | ||
| 8 | #include "core/hle/kernel/board/nintendo/nx/k_system_control.h" | ||
| 9 | #include "core/hle/kernel/board/nintendo/nx/secure_monitor.h" | ||
| 10 | #include "core/hle/kernel/k_trace.h" | ||
| 11 | |||
| 12 | namespace Kernel::Board::Nintendo::Nx { | ||
| 13 | |||
| 14 | namespace impl { | ||
| 15 | |||
| 16 | constexpr const std::size_t RequiredNonSecureSystemMemorySizeVi = 0x2238 * 4 * 1024; | ||
| 17 | constexpr const std::size_t RequiredNonSecureSystemMemorySizeNvservices = 0x710 * 4 * 1024; | ||
| 18 | constexpr const std::size_t RequiredNonSecureSystemMemorySizeMisc = 0x80 * 4 * 1024; | ||
| 19 | |||
| 20 | } // namespace impl | ||
| 21 | |||
| 22 | constexpr const std::size_t RequiredNonSecureSystemMemorySize = | ||
| 23 | impl::RequiredNonSecureSystemMemorySizeVi + impl::RequiredNonSecureSystemMemorySizeNvservices + | ||
| 24 | impl::RequiredNonSecureSystemMemorySizeMisc; | ||
| 25 | |||
| 26 | namespace { | ||
| 27 | |||
| 28 | u32 GetMemoryModeForInit() { | ||
| 29 | return 0x01; | ||
| 30 | } | ||
| 31 | |||
| 32 | u32 GetMemorySizeForInit() { | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | |||
| 36 | Smc::MemoryArrangement GetMemoryArrangeForInit() { | ||
| 37 | switch (GetMemoryModeForInit() & 0x3F) { | ||
| 38 | case 0x01: | ||
| 39 | default: | ||
| 40 | return Smc::MemoryArrangement_4GB; | ||
| 41 | case 0x02: | ||
| 42 | return Smc::MemoryArrangement_4GBForAppletDev; | ||
| 43 | case 0x03: | ||
| 44 | return Smc::MemoryArrangement_4GBForSystemDev; | ||
| 45 | case 0x11: | ||
| 46 | return Smc::MemoryArrangement_6GB; | ||
| 47 | case 0x12: | ||
| 48 | return Smc::MemoryArrangement_6GBForAppletDev; | ||
| 49 | case 0x21: | ||
| 50 | return Smc::MemoryArrangement_8GB; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } // namespace | ||
| 54 | |||
| 55 | // Initialization. | ||
| 56 | size_t KSystemControl::Init::GetIntendedMemorySize() { | ||
| 57 | switch (GetMemorySizeForInit()) { | ||
| 58 | case Smc::MemorySize_4GB: | ||
| 59 | default: // All invalid modes should go to 4GB. | ||
| 60 | return Common::Size_4_GB; | ||
| 61 | case Smc::MemorySize_6GB: | ||
| 62 | return Common::Size_6_GB; | ||
| 63 | case Smc::MemorySize_8GB: | ||
| 64 | return Common::Size_8_GB; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | PAddr KSystemControl::Init::GetKernelPhysicalBaseAddress(u64 base_address) { | ||
| 69 | return base_address; | ||
| 70 | } | ||
| 71 | |||
| 72 | bool KSystemControl::Init::ShouldIncreaseThreadResourceLimit() { | ||
| 73 | return true; | ||
| 74 | } | ||
| 75 | |||
| 76 | std::size_t KSystemControl::Init::GetApplicationPoolSize() { | ||
| 77 | // Get the base pool size. | ||
| 78 | const size_t base_pool_size = []() -> size_t { | ||
| 79 | switch (GetMemoryArrangeForInit()) { | ||
| 80 | case Smc::MemoryArrangement_4GB: | ||
| 81 | default: | ||
| 82 | return Common::Size_3285_MB; | ||
| 83 | case Smc::MemoryArrangement_4GBForAppletDev: | ||
| 84 | return Common::Size_2048_MB; | ||
| 85 | case Smc::MemoryArrangement_4GBForSystemDev: | ||
| 86 | return Common::Size_3285_MB; | ||
| 87 | case Smc::MemoryArrangement_6GB: | ||
| 88 | return Common::Size_4916_MB; | ||
| 89 | case Smc::MemoryArrangement_6GBForAppletDev: | ||
| 90 | return Common::Size_3285_MB; | ||
| 91 | case Smc::MemoryArrangement_8GB: | ||
| 92 | return Common::Size_4916_MB; | ||
| 93 | } | ||
| 94 | }(); | ||
| 95 | |||
| 96 | // Return (possibly) adjusted size. | ||
| 97 | return base_pool_size; | ||
| 98 | } | ||
| 99 | |||
| 100 | size_t KSystemControl::Init::GetAppletPoolSize() { | ||
| 101 | // Get the base pool size. | ||
| 102 | const size_t base_pool_size = []() -> size_t { | ||
| 103 | switch (GetMemoryArrangeForInit()) { | ||
| 104 | case Smc::MemoryArrangement_4GB: | ||
| 105 | default: | ||
| 106 | return Common::Size_507_MB; | ||
| 107 | case Smc::MemoryArrangement_4GBForAppletDev: | ||
| 108 | return Common::Size_1554_MB; | ||
| 109 | case Smc::MemoryArrangement_4GBForSystemDev: | ||
| 110 | return Common::Size_448_MB; | ||
| 111 | case Smc::MemoryArrangement_6GB: | ||
| 112 | return Common::Size_562_MB; | ||
| 113 | case Smc::MemoryArrangement_6GBForAppletDev: | ||
| 114 | return Common::Size_2193_MB; | ||
| 115 | case Smc::MemoryArrangement_8GB: | ||
| 116 | return Common::Size_2193_MB; | ||
| 117 | } | ||
| 118 | }(); | ||
| 119 | |||
| 120 | // Return (possibly) adjusted size. | ||
| 121 | constexpr size_t ExtraSystemMemoryForAtmosphere = Common::Size_33_MB; | ||
| 122 | return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize; | ||
| 123 | } | ||
| 124 | |||
| 125 | size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() { | ||
| 126 | // Verify that our minimum is at least as large as Nintendo's. | ||
| 127 | constexpr size_t MinimumSize = RequiredNonSecureSystemMemorySize; | ||
| 128 | static_assert(MinimumSize >= 0x29C8000); | ||
| 129 | |||
| 130 | return MinimumSize; | ||
| 131 | } | ||
| 132 | |||
| 133 | namespace { | ||
| 134 | template <typename F> | ||
| 135 | u64 GenerateUniformRange(u64 min, u64 max, F f) { | ||
| 136 | // Handle the case where the difference is too large to represent. | ||
| 137 | if (max == std::numeric_limits<u64>::max() && min == std::numeric_limits<u64>::min()) { | ||
| 138 | return f(); | ||
| 139 | } | ||
| 140 | |||
| 141 | // Iterate until we get a value in range. | ||
| 142 | const u64 range_size = ((max + 1) - min); | ||
| 143 | const u64 effective_max = (std::numeric_limits<u64>::max() / range_size) * range_size; | ||
| 144 | while (true) { | ||
| 145 | if (const u64 rnd = f(); rnd < effective_max) { | ||
| 146 | return min + (rnd % range_size); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | } // Anonymous namespace | ||
| 152 | |||
| 153 | u64 KSystemControl::GenerateRandomU64() { | ||
| 154 | static std::random_device device; | ||
| 155 | static std::mt19937 gen(device()); | ||
| 156 | static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); | ||
| 157 | return distribution(gen); | ||
| 158 | } | ||
| 159 | |||
| 160 | u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) { | ||
| 161 | return GenerateUniformRange(min, max, GenerateRandomU64); | ||
| 162 | } | ||
| 163 | |||
| 164 | } // namespace Kernel::Board::Nintendo::Nx | ||
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.h b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h new file mode 100644 index 000000000..52f230ced --- /dev/null +++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace Kernel::Board::Nintendo::Nx { | ||
| 10 | |||
| 11 | class KSystemControl { | ||
| 12 | public: | ||
| 13 | class Init { | ||
| 14 | public: | ||
| 15 | // Initialization. | ||
| 16 | static std::size_t GetIntendedMemorySize(); | ||
| 17 | static PAddr GetKernelPhysicalBaseAddress(u64 base_address); | ||
| 18 | static bool ShouldIncreaseThreadResourceLimit(); | ||
| 19 | static std::size_t GetApplicationPoolSize(); | ||
| 20 | static std::size_t GetAppletPoolSize(); | ||
| 21 | static std::size_t GetMinimumNonSecureSystemPoolSize(); | ||
| 22 | }; | ||
| 23 | |||
| 24 | static u64 GenerateRandomRange(u64 min, u64 max); | ||
| 25 | static u64 GenerateRandomU64(); | ||
| 26 | }; | ||
| 27 | |||
| 28 | } // namespace Kernel::Board::Nintendo::Nx | ||
diff --git a/src/core/hle/kernel/board/nintendo/nx/secure_monitor.h b/src/core/hle/kernel/board/nintendo/nx/secure_monitor.h new file mode 100644 index 000000000..0c366b252 --- /dev/null +++ b/src/core/hle/kernel/board/nintendo/nx/secure_monitor.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace Kernel::Board::Nintendo::Nx::Smc { | ||
| 10 | |||
| 11 | enum MemorySize { | ||
| 12 | MemorySize_4GB = 0, | ||
| 13 | MemorySize_6GB = 1, | ||
| 14 | MemorySize_8GB = 2, | ||
| 15 | }; | ||
| 16 | |||
| 17 | enum MemoryArrangement { | ||
| 18 | MemoryArrangement_4GB = 0, | ||
| 19 | MemoryArrangement_4GBForAppletDev = 1, | ||
| 20 | MemoryArrangement_4GBForSystemDev = 2, | ||
| 21 | MemoryArrangement_6GB = 3, | ||
| 22 | MemoryArrangement_6GBForAppletDev = 4, | ||
| 23 | MemoryArrangement_8GB = 5, | ||
| 24 | }; | ||
| 25 | |||
| 26 | } // namespace Kernel::Board::Nintendo::Nx::Smc | ||
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp index 24944d15b..c7549f7a2 100644 --- a/src/core/hle/kernel/k_address_space_info.cpp +++ b/src/core/hle/kernel/k_address_space_info.cpp | |||
| @@ -5,45 +5,34 @@ | |||
| 5 | #include <array> | 5 | #include <array> |
| 6 | 6 | ||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/common_sizes.h" | ||
| 8 | #include "core/hle/kernel/k_address_space_info.h" | 9 | #include "core/hle/kernel/k_address_space_info.h" |
| 9 | 10 | ||
| 10 | namespace Kernel { | 11 | namespace Kernel { |
| 11 | 12 | ||
| 12 | namespace { | 13 | namespace { |
| 13 | 14 | ||
| 14 | enum : u64 { | ||
| 15 | Size_1_MB = 0x100000, | ||
| 16 | Size_2_MB = 2 * Size_1_MB, | ||
| 17 | Size_128_MB = 128 * Size_1_MB, | ||
| 18 | Size_1_GB = 0x40000000, | ||
| 19 | Size_2_GB = 2 * Size_1_GB, | ||
| 20 | Size_4_GB = 4 * Size_1_GB, | ||
| 21 | Size_6_GB = 6 * Size_1_GB, | ||
| 22 | Size_64_GB = 64 * Size_1_GB, | ||
| 23 | Size_512_GB = 512 * Size_1_GB, | ||
| 24 | Invalid = std::numeric_limits<u64>::max(), | ||
| 25 | }; | ||
| 26 | |||
| 27 | // clang-format off | 15 | // clang-format off |
| 28 | constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{ | 16 | constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{ |
| 29 | { .bit_width = 32, .address = Size_2_MB , .size = Size_1_GB - Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, }, | 17 | { .bit_width = 32, .address = Common::Size_2_MB , .size = Common::Size_1_GB - Common::Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, }, |
| 30 | { .bit_width = 32, .address = Size_1_GB , .size = Size_4_GB - Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, }, | 18 | { .bit_width = 32, .address = Common::Size_1_GB , .size = Common::Size_4_GB - Common::Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, }, |
| 31 | { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, }, | 19 | { .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, }, |
| 32 | { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, }, | 20 | { .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, }, |
| 33 | { .bit_width = 36, .address = Size_128_MB, .size = Size_2_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, }, | 21 | { .bit_width = 36, .address = Common::Size_128_MB , .size = Common::Size_2_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, }, |
| 34 | { .bit_width = 36, .address = Size_2_GB , .size = Size_64_GB - Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, }, | 22 | { .bit_width = 36, .address = Common::Size_2_GB , .size = Common::Size_64_GB - Common::Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, }, |
| 35 | { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, }, | 23 | { .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, }, |
| 36 | { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, }, | 24 | { .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, }, |
| 37 | { .bit_width = 39, .address = Size_128_MB, .size = Size_512_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, }, | 25 | { .bit_width = 39, .address = Common::Size_128_MB , .size = Common::Size_512_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, }, |
| 38 | { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall }, | 26 | { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall }, |
| 39 | { .bit_width = 39, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, }, | 27 | { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, }, |
| 40 | { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, }, | 28 | { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, }, |
| 41 | { .bit_width = 39, .address = Invalid , .size = Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, }, | 29 | { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, }, |
| 42 | }}; | 30 | }}; |
| 43 | // clang-format on | 31 | // clang-format on |
| 44 | 32 | ||
| 45 | constexpr bool IsAllowedIndexForAddress(std::size_t index) { | 33 | constexpr bool IsAllowedIndexForAddress(std::size_t index) { |
| 46 | return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Invalid; | 34 | return index < AddressSpaceInfos.size() && |
| 35 | AddressSpaceInfos[index].address != Common::Size_Invalid; | ||
| 47 | } | 36 | } |
| 48 | 37 | ||
| 49 | using IndexArray = | 38 | using IndexArray = |
diff --git a/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp b/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp new file mode 100644 index 000000000..a78551291 --- /dev/null +++ b/src/core/hle/kernel/k_memory_layout.board.nintendo_nx.cpp | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/alignment.h" | ||
| 6 | #include "core/hle/kernel/k_memory_layout.h" | ||
| 7 | #include "core/hle/kernel/k_memory_manager.h" | ||
| 8 | #include "core/hle/kernel/k_system_control.h" | ||
| 9 | #include "core/hle/kernel/k_trace.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | namespace { | ||
| 14 | |||
| 15 | constexpr size_t CarveoutAlignment = 0x20000; | ||
| 16 | constexpr size_t CarveoutSizeMax = (512ULL * 1024 * 1024) - CarveoutAlignment; | ||
| 17 | |||
| 18 | bool SetupPowerManagementControllerMemoryRegion(KMemoryLayout& memory_layout) { | ||
| 19 | // Above firmware 2.0.0, the PMC is not mappable. | ||
| 20 | return memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 21 | 0x7000E000, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap) && | ||
| 22 | memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 23 | 0x7000E400, 0xC00, | ||
| 24 | KMemoryRegionType_PowerManagementController | KMemoryRegionAttr_NoUserMap); | ||
| 25 | } | ||
| 26 | |||
| 27 | void InsertPoolPartitionRegionIntoBothTrees(KMemoryLayout& memory_layout, size_t start, size_t size, | ||
| 28 | KMemoryRegionType phys_type, | ||
| 29 | KMemoryRegionType virt_type, u32& cur_attr) { | ||
| 30 | const u32 attr = cur_attr++; | ||
| 31 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(start, size, | ||
| 32 | static_cast<u32>(phys_type), attr)); | ||
| 33 | const KMemoryRegion* phys = memory_layout.GetPhysicalMemoryRegionTree().FindByTypeAndAttribute( | ||
| 34 | static_cast<u32>(phys_type), attr); | ||
| 35 | ASSERT(phys != nullptr); | ||
| 36 | ASSERT(phys->GetEndAddress() != 0); | ||
| 37 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(phys->GetPairAddress(), size, | ||
| 38 | static_cast<u32>(virt_type), attr)); | ||
| 39 | } | ||
| 40 | |||
| 41 | } // namespace | ||
| 42 | |||
| 43 | namespace Init { | ||
| 44 | |||
| 45 | void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout) { | ||
| 46 | ASSERT(SetupPowerManagementControllerMemoryRegion(memory_layout)); | ||
| 47 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 48 | 0x70019000, 0x1000, KMemoryRegionType_MemoryController | KMemoryRegionAttr_NoUserMap)); | ||
| 49 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 50 | 0x7001C000, 0x1000, KMemoryRegionType_MemoryController0 | KMemoryRegionAttr_NoUserMap)); | ||
| 51 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 52 | 0x7001D000, 0x1000, KMemoryRegionType_MemoryController1 | KMemoryRegionAttr_NoUserMap)); | ||
| 53 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 54 | 0x50040000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap)); | ||
| 55 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 56 | 0x50041000, 0x1000, | ||
| 57 | KMemoryRegionType_InterruptDistributor | KMemoryRegionAttr_ShouldKernelMap)); | ||
| 58 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 59 | 0x50042000, 0x1000, | ||
| 60 | KMemoryRegionType_InterruptCpuInterface | KMemoryRegionAttr_ShouldKernelMap)); | ||
| 61 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 62 | 0x50043000, 0x1D000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap)); | ||
| 63 | |||
| 64 | // Map IRAM unconditionally, to support debug-logging-to-iram build config. | ||
| 65 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 66 | 0x40000000, 0x40000, KMemoryRegionType_LegacyLpsIram | KMemoryRegionAttr_ShouldKernelMap)); | ||
| 67 | |||
| 68 | // Above firmware 2.0.0, prevent mapping the bpmp exception vectors or the ipatch region. | ||
| 69 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 70 | 0x6000F000, 0x1000, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap)); | ||
| 71 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 72 | 0x6001DC00, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap)); | ||
| 73 | } | ||
| 74 | |||
| 75 | void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout) { | ||
| 76 | const size_t intended_memory_size = KSystemControl::Init::GetIntendedMemorySize(); | ||
| 77 | const PAddr physical_memory_base_address = | ||
| 78 | KSystemControl::Init::GetKernelPhysicalBaseAddress(DramPhysicalAddress); | ||
| 79 | |||
| 80 | // Insert blocks into the tree. | ||
| 81 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 82 | physical_memory_base_address, intended_memory_size, KMemoryRegionType_Dram)); | ||
| 83 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 84 | physical_memory_base_address, ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly)); | ||
| 85 | |||
| 86 | // Insert the KTrace block at the end of Dram, if KTrace is enabled. | ||
| 87 | static_assert(!IsKTraceEnabled || KTraceBufferSize > 0); | ||
| 88 | if constexpr (IsKTraceEnabled) { | ||
| 89 | const PAddr ktrace_buffer_phys_addr = | ||
| 90 | physical_memory_base_address + intended_memory_size - KTraceBufferSize; | ||
| 91 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 92 | ktrace_buffer_phys_addr, KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer)); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | void SetupPoolPartitionMemoryRegions(KMemoryLayout& memory_layout) { | ||
| 97 | // Start by identifying the extents of the DRAM memory region. | ||
| 98 | const auto dram_extents = memory_layout.GetMainMemoryPhysicalExtents(); | ||
| 99 | ASSERT(dram_extents.GetEndAddress() != 0); | ||
| 100 | |||
| 101 | // Determine the end of the pool region. | ||
| 102 | const u64 pool_end = dram_extents.GetEndAddress() - KTraceBufferSize; | ||
| 103 | |||
| 104 | // Find the start of the kernel DRAM region. | ||
| 105 | const KMemoryRegion* kernel_dram_region = | ||
| 106 | memory_layout.GetPhysicalMemoryRegionTree().FindFirstDerived( | ||
| 107 | KMemoryRegionType_DramKernelBase); | ||
| 108 | ASSERT(kernel_dram_region != nullptr); | ||
| 109 | |||
| 110 | const u64 kernel_dram_start = kernel_dram_region->GetAddress(); | ||
| 111 | ASSERT(Common::IsAligned(kernel_dram_start, CarveoutAlignment)); | ||
| 112 | |||
| 113 | // Find the start of the pool partitions region. | ||
| 114 | const KMemoryRegion* pool_partitions_region = | ||
| 115 | memory_layout.GetPhysicalMemoryRegionTree().FindByTypeAndAttribute( | ||
| 116 | KMemoryRegionType_DramPoolPartition, 0); | ||
| 117 | ASSERT(pool_partitions_region != nullptr); | ||
| 118 | const u64 pool_partitions_start = pool_partitions_region->GetAddress(); | ||
| 119 | |||
| 120 | // Setup the pool partition layouts. | ||
| 121 | // On 5.0.0+, setup modern 4-pool-partition layout. | ||
| 122 | |||
| 123 | // Get Application and Applet pool sizes. | ||
| 124 | const size_t application_pool_size = KSystemControl::Init::GetApplicationPoolSize(); | ||
| 125 | const size_t applet_pool_size = KSystemControl::Init::GetAppletPoolSize(); | ||
| 126 | const size_t unsafe_system_pool_min_size = | ||
| 127 | KSystemControl::Init::GetMinimumNonSecureSystemPoolSize(); | ||
| 128 | |||
| 129 | // Decide on starting addresses for our pools. | ||
| 130 | const u64 application_pool_start = pool_end - application_pool_size; | ||
| 131 | const u64 applet_pool_start = application_pool_start - applet_pool_size; | ||
| 132 | const u64 unsafe_system_pool_start = std::min( | ||
| 133 | kernel_dram_start + CarveoutSizeMax, | ||
| 134 | Common::AlignDown(applet_pool_start - unsafe_system_pool_min_size, CarveoutAlignment)); | ||
| 135 | const size_t unsafe_system_pool_size = applet_pool_start - unsafe_system_pool_start; | ||
| 136 | |||
| 137 | // We want to arrange application pool depending on where the middle of dram is. | ||
| 138 | const u64 dram_midpoint = (dram_extents.GetAddress() + dram_extents.GetEndAddress()) / 2; | ||
| 139 | u32 cur_pool_attr = 0; | ||
| 140 | size_t total_overhead_size = 0; | ||
| 141 | if (dram_extents.GetEndAddress() <= dram_midpoint || dram_midpoint <= application_pool_start) { | ||
| 142 | InsertPoolPartitionRegionIntoBothTrees( | ||
| 143 | memory_layout, application_pool_start, application_pool_size, | ||
| 144 | KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool, | ||
| 145 | cur_pool_attr); | ||
| 146 | total_overhead_size += | ||
| 147 | KMemoryManager::CalculateManagementOverheadSize(application_pool_size); | ||
| 148 | } else { | ||
| 149 | const size_t first_application_pool_size = dram_midpoint - application_pool_start; | ||
| 150 | const size_t second_application_pool_size = | ||
| 151 | application_pool_start + application_pool_size - dram_midpoint; | ||
| 152 | InsertPoolPartitionRegionIntoBothTrees( | ||
| 153 | memory_layout, application_pool_start, first_application_pool_size, | ||
| 154 | KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool, | ||
| 155 | cur_pool_attr); | ||
| 156 | InsertPoolPartitionRegionIntoBothTrees( | ||
| 157 | memory_layout, dram_midpoint, second_application_pool_size, | ||
| 158 | KMemoryRegionType_DramApplicationPool, KMemoryRegionType_VirtualDramApplicationPool, | ||
| 159 | cur_pool_attr); | ||
| 160 | total_overhead_size += | ||
| 161 | KMemoryManager::CalculateManagementOverheadSize(first_application_pool_size); | ||
| 162 | total_overhead_size += | ||
| 163 | KMemoryManager::CalculateManagementOverheadSize(second_application_pool_size); | ||
| 164 | } | ||
| 165 | |||
| 166 | // Insert the applet pool. | ||
| 167 | InsertPoolPartitionRegionIntoBothTrees(memory_layout, applet_pool_start, applet_pool_size, | ||
| 168 | KMemoryRegionType_DramAppletPool, | ||
| 169 | KMemoryRegionType_VirtualDramAppletPool, cur_pool_attr); | ||
| 170 | total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(applet_pool_size); | ||
| 171 | |||
| 172 | // Insert the nonsecure system pool. | ||
| 173 | InsertPoolPartitionRegionIntoBothTrees( | ||
| 174 | memory_layout, unsafe_system_pool_start, unsafe_system_pool_size, | ||
| 175 | KMemoryRegionType_DramSystemNonSecurePool, KMemoryRegionType_VirtualDramSystemNonSecurePool, | ||
| 176 | cur_pool_attr); | ||
| 177 | total_overhead_size += KMemoryManager::CalculateManagementOverheadSize(unsafe_system_pool_size); | ||
| 178 | |||
| 179 | // Insert the pool management region. | ||
| 180 | total_overhead_size += KMemoryManager::CalculateManagementOverheadSize( | ||
| 181 | (unsafe_system_pool_start - pool_partitions_start) - total_overhead_size); | ||
| 182 | const u64 pool_management_start = unsafe_system_pool_start - total_overhead_size; | ||
| 183 | const size_t pool_management_size = total_overhead_size; | ||
| 184 | u32 pool_management_attr = 0; | ||
| 185 | InsertPoolPartitionRegionIntoBothTrees( | ||
| 186 | memory_layout, pool_management_start, pool_management_size, | ||
| 187 | KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement, | ||
| 188 | pool_management_attr); | ||
| 189 | |||
| 190 | // Insert the system pool. | ||
| 191 | const u64 system_pool_size = pool_management_start - pool_partitions_start; | ||
| 192 | InsertPoolPartitionRegionIntoBothTrees(memory_layout, pool_partitions_start, system_pool_size, | ||
| 193 | KMemoryRegionType_DramSystemPool, | ||
| 194 | KMemoryRegionType_VirtualDramSystemPool, cur_pool_attr); | ||
| 195 | } | ||
| 196 | |||
| 197 | } // namespace Init | ||
| 198 | |||
| 199 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp new file mode 100644 index 000000000..fb1e2435f --- /dev/null +++ b/src/core/hle/kernel/k_memory_layout.cpp | |||
| @@ -0,0 +1,166 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | |||
| 7 | #include "common/alignment.h" | ||
| 8 | #include "core/hle/kernel/k_memory_layout.h" | ||
| 9 | #include "core/hle/kernel/k_system_control.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | namespace { | ||
| 14 | |||
| 15 | template <typename... Args> | ||
| 16 | KMemoryRegion* AllocateRegion(KMemoryRegionAllocator& memory_region_allocator, Args&&... args) { | ||
| 17 | return memory_region_allocator.Allocate(std::forward<Args>(args)...); | ||
| 18 | } | ||
| 19 | |||
| 20 | } // namespace | ||
| 21 | |||
| 22 | KMemoryRegionTree::KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_) | ||
| 23 | : memory_region_allocator{memory_region_allocator_} {} | ||
| 24 | |||
| 25 | void KMemoryRegionTree::InsertDirectly(u64 address, u64 last_address, u32 attr, u32 type_id) { | ||
| 26 | this->insert(*AllocateRegion(memory_region_allocator, address, last_address, attr, type_id)); | ||
| 27 | } | ||
| 28 | |||
| 29 | bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) { | ||
| 30 | // Locate the memory region that contains the address. | ||
| 31 | KMemoryRegion* found = this->FindModifiable(address); | ||
| 32 | |||
| 33 | // We require that the old attr is correct. | ||
| 34 | if (found->GetAttributes() != old_attr) { | ||
| 35 | return false; | ||
| 36 | } | ||
| 37 | |||
| 38 | // We further require that the region can be split from the old region. | ||
| 39 | const u64 inserted_region_end = address + size; | ||
| 40 | const u64 inserted_region_last = inserted_region_end - 1; | ||
| 41 | if (found->GetLastAddress() < inserted_region_last) { | ||
| 42 | return false; | ||
| 43 | } | ||
| 44 | |||
| 45 | // Further, we require that the type id is a valid transformation. | ||
| 46 | if (!found->CanDerive(type_id)) { | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | |||
| 50 | // Cache information from the region before we remove it. | ||
| 51 | const u64 old_address = found->GetAddress(); | ||
| 52 | const u64 old_last = found->GetLastAddress(); | ||
| 53 | const u64 old_pair = found->GetPairAddress(); | ||
| 54 | const u32 old_type = found->GetType(); | ||
| 55 | |||
| 56 | // Erase the existing region from the tree. | ||
| 57 | this->erase(this->iterator_to(*found)); | ||
| 58 | |||
| 59 | // Insert the new region into the tree. | ||
| 60 | if (old_address == address) { | ||
| 61 | // Reuse the old object for the new region, if we can. | ||
| 62 | found->Reset(address, inserted_region_last, old_pair, new_attr, type_id); | ||
| 63 | this->insert(*found); | ||
| 64 | } else { | ||
| 65 | // If we can't re-use, adjust the old region. | ||
| 66 | found->Reset(old_address, address - 1, old_pair, old_attr, old_type); | ||
| 67 | this->insert(*found); | ||
| 68 | |||
| 69 | // Insert a new region for the split. | ||
| 70 | const u64 new_pair = (old_pair != std::numeric_limits<u64>::max()) | ||
| 71 | ? old_pair + (address - old_address) | ||
| 72 | : old_pair; | ||
| 73 | this->insert(*AllocateRegion(memory_region_allocator, address, inserted_region_last, | ||
| 74 | new_pair, new_attr, type_id)); | ||
| 75 | } | ||
| 76 | |||
| 77 | // If we need to insert a region after the region, do so. | ||
| 78 | if (old_last != inserted_region_last) { | ||
| 79 | const u64 after_pair = (old_pair != std::numeric_limits<u64>::max()) | ||
| 80 | ? old_pair + (inserted_region_end - old_address) | ||
| 81 | : old_pair; | ||
| 82 | this->insert(*AllocateRegion(memory_region_allocator, inserted_region_end, old_last, | ||
| 83 | after_pair, old_attr, old_type)); | ||
| 84 | } | ||
| 85 | |||
| 86 | return true; | ||
| 87 | } | ||
| 88 | |||
| 89 | VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id) { | ||
| 90 | // We want to find the total extents of the type id. | ||
| 91 | const auto extents = this->GetDerivedRegionExtents(static_cast<KMemoryRegionType>(type_id)); | ||
| 92 | |||
| 93 | // Ensure that our alignment is correct. | ||
| 94 | ASSERT(Common::IsAligned(extents.GetAddress(), alignment)); | ||
| 95 | |||
| 96 | const u64 first_address = extents.GetAddress(); | ||
| 97 | const u64 last_address = extents.GetLastAddress(); | ||
| 98 | |||
| 99 | const u64 first_index = first_address / alignment; | ||
| 100 | const u64 last_index = last_address / alignment; | ||
| 101 | |||
| 102 | while (true) { | ||
| 103 | const u64 candidate = | ||
| 104 | KSystemControl::GenerateRandomRange(first_index, last_index) * alignment; | ||
| 105 | |||
| 106 | // Ensure that the candidate doesn't overflow with the size. | ||
| 107 | if (!(candidate < candidate + size)) { | ||
| 108 | continue; | ||
| 109 | } | ||
| 110 | |||
| 111 | const u64 candidate_last = candidate + size - 1; | ||
| 112 | |||
| 113 | // Ensure that the candidate fits within the region. | ||
| 114 | if (candidate_last > last_address) { | ||
| 115 | continue; | ||
| 116 | } | ||
| 117 | |||
| 118 | // Locate the candidate region, and ensure it fits and has the correct type id. | ||
| 119 | if (const auto& candidate_region = *this->Find(candidate); | ||
| 120 | !(candidate_last <= candidate_region.GetLastAddress() && | ||
| 121 | candidate_region.GetType() == type_id)) { | ||
| 122 | continue; | ||
| 123 | } | ||
| 124 | |||
| 125 | return candidate; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | KMemoryLayout::KMemoryLayout() | ||
| 130 | : virtual_tree{memory_region_allocator}, physical_tree{memory_region_allocator}, | ||
| 131 | virtual_linear_tree{memory_region_allocator}, physical_linear_tree{memory_region_allocator} {} | ||
| 132 | |||
| 133 | void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start, | ||
| 134 | VAddr linear_virtual_start) { | ||
| 135 | // Set static differences. | ||
| 136 | linear_phys_to_virt_diff = linear_virtual_start - aligned_linear_phys_start; | ||
| 137 | linear_virt_to_phys_diff = aligned_linear_phys_start - linear_virtual_start; | ||
| 138 | |||
| 139 | // Initialize linear trees. | ||
| 140 | for (auto& region : GetPhysicalMemoryRegionTree()) { | ||
| 141 | if (region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) { | ||
| 142 | GetPhysicalLinearMemoryRegionTree().InsertDirectly( | ||
| 143 | region.GetAddress(), region.GetLastAddress(), region.GetAttributes(), | ||
| 144 | region.GetType()); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | for (auto& region : GetVirtualMemoryRegionTree()) { | ||
| 149 | if (region.IsDerivedFrom(KMemoryRegionType_Dram)) { | ||
| 150 | GetVirtualLinearMemoryRegionTree().InsertDirectly( | ||
| 151 | region.GetAddress(), region.GetLastAddress(), region.GetAttributes(), | ||
| 152 | region.GetType()); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | size_t KMemoryLayout::GetResourceRegionSizeForInit() { | ||
| 158 | // Calculate resource region size based on whether we allow extra threads. | ||
| 159 | const bool use_extra_resources = KSystemControl::Init::ShouldIncreaseThreadResourceLimit(); | ||
| 160 | size_t resource_region_size = | ||
| 161 | KernelResourceSize + (use_extra_resources ? KernelSlabHeapAdditionalSize : 0); | ||
| 162 | |||
| 163 | return resource_region_size; | ||
| 164 | } | ||
| 165 | |||
| 166 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index 0821d2d8c..288642d9a 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/src/core/hle/kernel/k_memory_layout.h | |||
| @@ -1,23 +1,69 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <utility> | ||
| 8 | |||
| 9 | #include "common/alignment.h" | ||
| 10 | #include "common/common_sizes.h" | ||
| 7 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 8 | #include "core/device_memory.h" | 12 | #include "core/device_memory.h" |
| 13 | #include "core/hle/kernel/k_memory_region.h" | ||
| 14 | #include "core/hle/kernel/k_memory_region_type.h" | ||
| 15 | #include "core/hle/kernel/memory_types.h" | ||
| 9 | 16 | ||
| 10 | namespace Kernel { | 17 | namespace Kernel { |
| 11 | 18 | ||
| 12 | constexpr std::size_t KernelAslrAlignment = 2 * 1024 * 1024; | 19 | constexpr std::size_t L1BlockSize = Common::Size_1_GB; |
| 20 | constexpr std::size_t L2BlockSize = Common::Size_2_MB; | ||
| 21 | |||
| 22 | constexpr std::size_t GetMaximumOverheadSize(std::size_t size) { | ||
| 23 | return (Common::DivideUp(size, L1BlockSize) + Common::DivideUp(size, L2BlockSize)) * PageSize; | ||
| 24 | } | ||
| 25 | |||
| 26 | constexpr std::size_t MainMemorySize = Common::Size_4_GB; | ||
| 27 | constexpr std::size_t MainMemorySizeMax = Common::Size_8_GB; | ||
| 28 | |||
| 29 | constexpr std::size_t ReservedEarlyDramSize = 0x60000; | ||
| 30 | constexpr std::size_t DramPhysicalAddress = 0x80000000; | ||
| 31 | |||
| 32 | constexpr std::size_t KernelAslrAlignment = Common::Size_2_MB; | ||
| 13 | constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39; | 33 | constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39; |
| 14 | constexpr std::size_t KernelPhysicalAddressSpaceWidth = 1ULL << 48; | 34 | constexpr std::size_t KernelPhysicalAddressSpaceWidth = 1ULL << 48; |
| 35 | |||
| 15 | constexpr std::size_t KernelVirtualAddressSpaceBase = 0ULL - KernelVirtualAddressSpaceWidth; | 36 | constexpr std::size_t KernelVirtualAddressSpaceBase = 0ULL - KernelVirtualAddressSpaceWidth; |
| 16 | constexpr std::size_t KernelVirtualAddressSpaceEnd = | 37 | constexpr std::size_t KernelVirtualAddressSpaceEnd = |
| 17 | KernelVirtualAddressSpaceBase + (KernelVirtualAddressSpaceWidth - KernelAslrAlignment); | 38 | KernelVirtualAddressSpaceBase + (KernelVirtualAddressSpaceWidth - KernelAslrAlignment); |
| 18 | constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceEnd - 1; | 39 | constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceEnd - 1ULL; |
| 19 | constexpr std::size_t KernelVirtualAddressSpaceSize = | 40 | constexpr std::size_t KernelVirtualAddressSpaceSize = |
| 20 | KernelVirtualAddressSpaceEnd - KernelVirtualAddressSpaceBase; | 41 | KernelVirtualAddressSpaceEnd - KernelVirtualAddressSpaceBase; |
| 42 | constexpr std::size_t KernelVirtualAddressCodeBase = KernelVirtualAddressSpaceBase; | ||
| 43 | constexpr std::size_t KernelVirtualAddressCodeSize = 0x62000; | ||
| 44 | constexpr std::size_t KernelVirtualAddressCodeEnd = | ||
| 45 | KernelVirtualAddressCodeBase + KernelVirtualAddressCodeSize; | ||
| 46 | |||
| 47 | constexpr std::size_t KernelPhysicalAddressSpaceBase = 0ULL; | ||
| 48 | constexpr std::size_t KernelPhysicalAddressSpaceEnd = | ||
| 49 | KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceWidth; | ||
| 50 | constexpr std::size_t KernelPhysicalAddressSpaceLast = KernelPhysicalAddressSpaceEnd - 1ULL; | ||
| 51 | constexpr std::size_t KernelPhysicalAddressSpaceSize = | ||
| 52 | KernelPhysicalAddressSpaceEnd - KernelPhysicalAddressSpaceBase; | ||
| 53 | constexpr std::size_t KernelPhysicalAddressCodeBase = DramPhysicalAddress + ReservedEarlyDramSize; | ||
| 54 | |||
| 55 | constexpr std::size_t KernelPageTableHeapSize = GetMaximumOverheadSize(MainMemorySizeMax); | ||
| 56 | constexpr std::size_t KernelInitialPageHeapSize = Common::Size_128_KB; | ||
| 57 | |||
| 58 | constexpr std::size_t KernelSlabHeapDataSize = Common::Size_5_MB; | ||
| 59 | constexpr std::size_t KernelSlabHeapGapsSize = Common::Size_2_MB - Common::Size_64_KB; | ||
| 60 | constexpr std::size_t KernelSlabHeapSize = KernelSlabHeapDataSize + KernelSlabHeapGapsSize; | ||
| 61 | |||
| 62 | // NOTE: This is calculated from KThread slab counts, assuming KThread size <= 0x860. | ||
| 63 | constexpr std::size_t KernelSlabHeapAdditionalSize = 0x68000ULL; | ||
| 64 | |||
| 65 | constexpr std::size_t KernelResourceSize = | ||
| 66 | KernelPageTableHeapSize + KernelInitialPageHeapSize + KernelSlabHeapSize; | ||
| 21 | 67 | ||
| 22 | constexpr bool IsKernelAddressKey(VAddr key) { | 68 | constexpr bool IsKernelAddressKey(VAddr key) { |
| 23 | return KernelVirtualAddressSpaceBase <= key && key <= KernelVirtualAddressSpaceLast; | 69 | return KernelVirtualAddressSpaceBase <= key && key <= KernelVirtualAddressSpaceLast; |
| @@ -27,64 +73,327 @@ constexpr bool IsKernelAddress(VAddr address) { | |||
| 27 | return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; | 73 | return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd; |
| 28 | } | 74 | } |
| 29 | 75 | ||
| 30 | class KMemoryRegion final { | 76 | class KMemoryLayout final { |
| 31 | friend class KMemoryLayout; | ||
| 32 | |||
| 33 | public: | 77 | public: |
| 34 | constexpr PAddr StartAddress() const { | 78 | KMemoryLayout(); |
| 35 | return start_address; | 79 | |
| 80 | KMemoryRegionTree& GetVirtualMemoryRegionTree() { | ||
| 81 | return virtual_tree; | ||
| 82 | } | ||
| 83 | const KMemoryRegionTree& GetVirtualMemoryRegionTree() const { | ||
| 84 | return virtual_tree; | ||
| 85 | } | ||
| 86 | KMemoryRegionTree& GetPhysicalMemoryRegionTree() { | ||
| 87 | return physical_tree; | ||
| 88 | } | ||
| 89 | const KMemoryRegionTree& GetPhysicalMemoryRegionTree() const { | ||
| 90 | return physical_tree; | ||
| 91 | } | ||
| 92 | KMemoryRegionTree& GetVirtualLinearMemoryRegionTree() { | ||
| 93 | return virtual_linear_tree; | ||
| 94 | } | ||
| 95 | const KMemoryRegionTree& GetVirtualLinearMemoryRegionTree() const { | ||
| 96 | return virtual_linear_tree; | ||
| 97 | } | ||
| 98 | KMemoryRegionTree& GetPhysicalLinearMemoryRegionTree() { | ||
| 99 | return physical_linear_tree; | ||
| 100 | } | ||
| 101 | const KMemoryRegionTree& GetPhysicalLinearMemoryRegionTree() const { | ||
| 102 | return physical_linear_tree; | ||
| 103 | } | ||
| 104 | |||
| 105 | VAddr GetLinearVirtualAddress(PAddr address) const { | ||
| 106 | return address + linear_phys_to_virt_diff; | ||
| 107 | } | ||
| 108 | PAddr GetLinearPhysicalAddress(VAddr address) const { | ||
| 109 | return address + linear_virt_to_phys_diff; | ||
| 110 | } | ||
| 111 | |||
| 112 | const KMemoryRegion* FindVirtual(VAddr address) const { | ||
| 113 | return Find(address, GetVirtualMemoryRegionTree()); | ||
| 114 | } | ||
| 115 | const KMemoryRegion* FindPhysical(PAddr address) const { | ||
| 116 | return Find(address, GetPhysicalMemoryRegionTree()); | ||
| 117 | } | ||
| 118 | |||
| 119 | const KMemoryRegion* FindVirtualLinear(VAddr address) const { | ||
| 120 | return Find(address, GetVirtualLinearMemoryRegionTree()); | ||
| 121 | } | ||
| 122 | const KMemoryRegion* FindPhysicalLinear(PAddr address) const { | ||
| 123 | return Find(address, GetPhysicalLinearMemoryRegionTree()); | ||
| 124 | } | ||
| 125 | |||
| 126 | VAddr GetMainStackTopAddress(s32 core_id) const { | ||
| 127 | return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscMainStack); | ||
| 128 | } | ||
| 129 | VAddr GetIdleStackTopAddress(s32 core_id) const { | ||
| 130 | return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscIdleStack); | ||
| 131 | } | ||
| 132 | VAddr GetExceptionStackTopAddress(s32 core_id) const { | ||
| 133 | return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscExceptionStack); | ||
| 134 | } | ||
| 135 | |||
| 136 | VAddr GetSlabRegionAddress() const { | ||
| 137 | return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelSlab)) | ||
| 138 | .GetAddress(); | ||
| 139 | } | ||
| 140 | |||
| 141 | const KMemoryRegion& GetDeviceRegion(KMemoryRegionType type) const { | ||
| 142 | return Dereference(GetPhysicalMemoryRegionTree().FindFirstDerived(type)); | ||
| 143 | } | ||
| 144 | PAddr GetDevicePhysicalAddress(KMemoryRegionType type) const { | ||
| 145 | return GetDeviceRegion(type).GetAddress(); | ||
| 146 | } | ||
| 147 | VAddr GetDeviceVirtualAddress(KMemoryRegionType type) const { | ||
| 148 | return GetDeviceRegion(type).GetPairAddress(); | ||
| 149 | } | ||
| 150 | |||
| 151 | const KMemoryRegion& GetPoolManagementRegion() const { | ||
| 152 | return Dereference( | ||
| 153 | GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_VirtualDramPoolManagement)); | ||
| 154 | } | ||
| 155 | const KMemoryRegion& GetPageTableHeapRegion() const { | ||
| 156 | return Dereference( | ||
| 157 | GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_VirtualDramKernelPtHeap)); | ||
| 158 | } | ||
| 159 | const KMemoryRegion& GetKernelStackRegion() const { | ||
| 160 | return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelStack)); | ||
| 161 | } | ||
| 162 | const KMemoryRegion& GetTempRegion() const { | ||
| 163 | return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelTemp)); | ||
| 164 | } | ||
| 165 | |||
| 166 | const KMemoryRegion& GetKernelTraceBufferRegion() const { | ||
| 167 | return Dereference(GetVirtualLinearMemoryRegionTree().FindByType( | ||
| 168 | KMemoryRegionType_VirtualDramKernelTraceBuffer)); | ||
| 169 | } | ||
| 170 | |||
| 171 | const KMemoryRegion& GetVirtualLinearRegion(VAddr address) const { | ||
| 172 | return Dereference(FindVirtualLinear(address)); | ||
| 173 | } | ||
| 174 | |||
| 175 | const KMemoryRegion* GetPhysicalKernelTraceBufferRegion() const { | ||
| 176 | return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_KernelTraceBuffer); | ||
| 177 | } | ||
| 178 | const KMemoryRegion* GetPhysicalOnMemoryBootImageRegion() const { | ||
| 179 | return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_OnMemoryBootImage); | ||
| 180 | } | ||
| 181 | const KMemoryRegion* GetPhysicalDTBRegion() const { | ||
| 182 | return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DTB); | ||
| 183 | } | ||
| 184 | |||
| 185 | bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address) const { | ||
| 186 | return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(), | ||
| 187 | KMemoryRegionType_DramUserPool); | ||
| 188 | } | ||
| 189 | bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address) const { | ||
| 190 | return IsTypedAddress(region, address, GetVirtualLinearMemoryRegionTree(), | ||
| 191 | KMemoryRegionType_VirtualDramUserPool); | ||
| 192 | } | ||
| 193 | |||
| 194 | bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address, size_t size) const { | ||
| 195 | return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(), | ||
| 196 | KMemoryRegionType_DramUserPool); | ||
| 197 | } | ||
| 198 | bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address, size_t size) const { | ||
| 199 | return IsTypedAddress(region, address, size, GetVirtualLinearMemoryRegionTree(), | ||
| 200 | KMemoryRegionType_VirtualDramUserPool); | ||
| 201 | } | ||
| 202 | |||
| 203 | bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address) const { | ||
| 204 | return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(), | ||
| 205 | static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped)); | ||
| 206 | } | ||
| 207 | bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address, | ||
| 208 | size_t size) const { | ||
| 209 | return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(), | ||
| 210 | static_cast<KMemoryRegionType>(KMemoryRegionAttr_LinearMapped)); | ||
| 211 | } | ||
| 212 | |||
| 213 | std::pair<size_t, size_t> GetTotalAndKernelMemorySizes() const { | ||
| 214 | size_t total_size = 0, kernel_size = 0; | ||
| 215 | for (const auto& region : GetPhysicalMemoryRegionTree()) { | ||
| 216 | if (region.IsDerivedFrom(KMemoryRegionType_Dram)) { | ||
| 217 | total_size += region.GetSize(); | ||
| 218 | if (!region.IsDerivedFrom(KMemoryRegionType_DramUserPool)) { | ||
| 219 | kernel_size += region.GetSize(); | ||
| 220 | } | ||
| 221 | } | ||
| 222 | } | ||
| 223 | return std::make_pair(total_size, kernel_size); | ||
| 224 | } | ||
| 225 | |||
| 226 | void InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start, | ||
| 227 | VAddr linear_virtual_start); | ||
| 228 | static size_t GetResourceRegionSizeForInit(); | ||
| 229 | |||
| 230 | auto GetKernelRegionExtents() const { | ||
| 231 | return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel); | ||
| 232 | } | ||
| 233 | auto GetKernelCodeRegionExtents() const { | ||
| 234 | return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelCode); | ||
| 235 | } | ||
| 236 | auto GetKernelStackRegionExtents() const { | ||
| 237 | return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelStack); | ||
| 238 | } | ||
| 239 | auto GetKernelMiscRegionExtents() const { | ||
| 240 | return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelMisc); | ||
| 241 | } | ||
| 242 | auto GetKernelSlabRegionExtents() const { | ||
| 243 | return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelSlab); | ||
| 244 | } | ||
| 245 | |||
| 246 | auto GetLinearRegionPhysicalExtents() const { | ||
| 247 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 248 | KMemoryRegionAttr_LinearMapped); | ||
| 249 | } | ||
| 250 | |||
| 251 | auto GetLinearRegionVirtualExtents() const { | ||
| 252 | const auto physical = GetLinearRegionPhysicalExtents(); | ||
| 253 | return KMemoryRegion(GetLinearVirtualAddress(physical.GetAddress()), | ||
| 254 | GetLinearVirtualAddress(physical.GetLastAddress()), 0, | ||
| 255 | KMemoryRegionType_None); | ||
| 256 | } | ||
| 257 | |||
| 258 | auto GetMainMemoryPhysicalExtents() const { | ||
| 259 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Dram); | ||
| 260 | } | ||
| 261 | auto GetCarveoutRegionExtents() const { | ||
| 262 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 263 | KMemoryRegionAttr_CarveoutProtected); | ||
| 264 | } | ||
| 265 | |||
| 266 | auto GetKernelRegionPhysicalExtents() const { | ||
| 267 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 268 | KMemoryRegionType_DramKernelBase); | ||
| 269 | } | ||
| 270 | auto GetKernelCodeRegionPhysicalExtents() const { | ||
| 271 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 272 | KMemoryRegionType_DramKernelCode); | ||
| 273 | } | ||
| 274 | auto GetKernelSlabRegionPhysicalExtents() const { | ||
| 275 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 276 | KMemoryRegionType_DramKernelSlab); | ||
| 277 | } | ||
| 278 | auto GetKernelPageTableHeapRegionPhysicalExtents() const { | ||
| 279 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 280 | KMemoryRegionType_DramKernelPtHeap); | ||
| 281 | } | ||
| 282 | auto GetKernelInitPageTableRegionPhysicalExtents() const { | ||
| 283 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 284 | KMemoryRegionType_DramKernelInitPt); | ||
| 285 | } | ||
| 286 | |||
| 287 | auto GetKernelPoolManagementRegionPhysicalExtents() const { | ||
| 288 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 289 | KMemoryRegionType_DramPoolManagement); | ||
| 290 | } | ||
| 291 | auto GetKernelPoolPartitionRegionPhysicalExtents() const { | ||
| 292 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 293 | KMemoryRegionType_DramPoolPartition); | ||
| 294 | } | ||
| 295 | auto GetKernelSystemPoolRegionPhysicalExtents() const { | ||
| 296 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 297 | KMemoryRegionType_DramSystemPool); | ||
| 298 | } | ||
| 299 | auto GetKernelSystemNonSecurePoolRegionPhysicalExtents() const { | ||
| 300 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 301 | KMemoryRegionType_DramSystemNonSecurePool); | ||
| 302 | } | ||
| 303 | auto GetKernelAppletPoolRegionPhysicalExtents() const { | ||
| 304 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 305 | KMemoryRegionType_DramAppletPool); | ||
| 306 | } | ||
| 307 | auto GetKernelApplicationPoolRegionPhysicalExtents() const { | ||
| 308 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 309 | KMemoryRegionType_DramApplicationPool); | ||
| 36 | } | 310 | } |
| 37 | 311 | ||
| 38 | constexpr PAddr EndAddress() const { | 312 | auto GetKernelTraceBufferRegionPhysicalExtents() const { |
| 39 | return end_address; | 313 | return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( |
| 314 | KMemoryRegionType_KernelTraceBuffer); | ||
| 40 | } | 315 | } |
| 41 | 316 | ||
| 42 | private: | 317 | private: |
| 43 | constexpr KMemoryRegion() = default; | 318 | template <typename AddressType> |
| 44 | constexpr KMemoryRegion(PAddr start_address, PAddr end_address) | 319 | static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, |
| 45 | : start_address{start_address}, end_address{end_address} {} | 320 | const KMemoryRegionTree& tree, KMemoryRegionType type) { |
| 321 | // Check if the cached region already contains the address. | ||
| 322 | if (region != nullptr && region->Contains(address)) { | ||
| 323 | return true; | ||
| 324 | } | ||
| 46 | 325 | ||
| 47 | const PAddr start_address{}; | 326 | // Find the containing region, and update the cache. |
| 48 | const PAddr end_address{}; | 327 | if (const KMemoryRegion* found = tree.Find(address); |
| 49 | }; | 328 | found != nullptr && found->IsDerivedFrom(type)) { |
| 329 | region = found; | ||
| 330 | return true; | ||
| 331 | } else { | ||
| 332 | return false; | ||
| 333 | } | ||
| 334 | } | ||
| 50 | 335 | ||
| 51 | class KMemoryLayout final { | 336 | template <typename AddressType> |
| 52 | public: | 337 | static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, size_t size, |
| 53 | constexpr const KMemoryRegion& Application() const { | 338 | const KMemoryRegionTree& tree, KMemoryRegionType type) { |
| 54 | return application; | 339 | // Get the end of the checked region. |
| 340 | const u64 last_address = address + size - 1; | ||
| 341 | |||
| 342 | // Walk the tree to verify the region is correct. | ||
| 343 | const KMemoryRegion* cur = | ||
| 344 | (region != nullptr && region->Contains(address)) ? region : tree.Find(address); | ||
| 345 | while (cur != nullptr && cur->IsDerivedFrom(type)) { | ||
| 346 | if (last_address <= cur->GetLastAddress()) { | ||
| 347 | region = cur; | ||
| 348 | return true; | ||
| 349 | } | ||
| 350 | |||
| 351 | cur = cur->GetNext(); | ||
| 352 | } | ||
| 353 | return false; | ||
| 55 | } | 354 | } |
| 56 | 355 | ||
| 57 | constexpr const KMemoryRegion& Applet() const { | 356 | template <typename AddressType> |
| 58 | return applet; | 357 | static const KMemoryRegion* Find(AddressType address, const KMemoryRegionTree& tree) { |
| 358 | return tree.Find(address); | ||
| 59 | } | 359 | } |
| 60 | 360 | ||
| 61 | constexpr const KMemoryRegion& System() const { | 361 | static KMemoryRegion& Dereference(KMemoryRegion* region) { |
| 62 | return system; | 362 | ASSERT(region != nullptr); |
| 363 | return *region; | ||
| 63 | } | 364 | } |
| 64 | 365 | ||
| 65 | static constexpr KMemoryLayout GetDefaultLayout() { | 366 | static const KMemoryRegion& Dereference(const KMemoryRegion* region) { |
| 66 | constexpr std::size_t application_size{0xcd500000}; | 367 | ASSERT(region != nullptr); |
| 67 | constexpr std::size_t applet_size{0x1fb00000}; | 368 | return *region; |
| 68 | constexpr PAddr application_start_address{Core::DramMemoryMap::End - application_size}; | 369 | } |
| 69 | constexpr PAddr application_end_address{Core::DramMemoryMap::End}; | 370 | |
| 70 | constexpr PAddr applet_start_address{application_start_address - applet_size}; | 371 | VAddr GetStackTopAddress(s32 core_id, KMemoryRegionType type) const { |
| 71 | constexpr PAddr applet_end_address{applet_start_address + applet_size}; | 372 | const auto& region = Dereference( |
| 72 | constexpr PAddr system_start_address{Core::DramMemoryMap::SlabHeapEnd}; | 373 | GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id))); |
| 73 | constexpr PAddr system_end_address{applet_start_address}; | 374 | ASSERT(region.GetEndAddress() != 0); |
| 74 | return {application_start_address, application_end_address, applet_start_address, | 375 | return region.GetEndAddress(); |
| 75 | applet_end_address, system_start_address, system_end_address}; | ||
| 76 | } | 376 | } |
| 77 | 377 | ||
| 78 | private: | 378 | private: |
| 79 | constexpr KMemoryLayout(PAddr application_start_address, std::size_t application_size, | 379 | u64 linear_phys_to_virt_diff{}; |
| 80 | PAddr applet_start_address, std::size_t applet_size, | 380 | u64 linear_virt_to_phys_diff{}; |
| 81 | PAddr system_start_address, std::size_t system_size) | 381 | KMemoryRegionAllocator memory_region_allocator; |
| 82 | : application{application_start_address, application_size}, | 382 | KMemoryRegionTree virtual_tree; |
| 83 | applet{applet_start_address, applet_size}, system{system_start_address, system_size} {} | 383 | KMemoryRegionTree physical_tree; |
| 84 | 384 | KMemoryRegionTree virtual_linear_tree; | |
| 85 | const KMemoryRegion application; | 385 | KMemoryRegionTree physical_linear_tree; |
| 86 | const KMemoryRegion applet; | ||
| 87 | const KMemoryRegion system; | ||
| 88 | }; | 386 | }; |
| 89 | 387 | ||
| 388 | namespace Init { | ||
| 389 | |||
| 390 | // These should be generic, regardless of board. | ||
| 391 | void SetupPoolPartitionMemoryRegions(KMemoryLayout& memory_layout); | ||
| 392 | |||
| 393 | // These may be implemented in a board-specific manner. | ||
| 394 | void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout); | ||
| 395 | void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout); | ||
| 396 | |||
| 397 | } // namespace Init | ||
| 398 | |||
| 90 | } // namespace Kernel | 399 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index 9027602bf..aa71697b2 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp | |||
| @@ -173,4 +173,16 @@ ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_page | |||
| 173 | return RESULT_SUCCESS; | 173 | return RESULT_SUCCESS; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | std::size_t KMemoryManager::Impl::CalculateManagementOverheadSize(std::size_t region_size) { | ||
| 177 | const std::size_t ref_count_size = (region_size / PageSize) * sizeof(u16); | ||
| 178 | const std::size_t optimize_map_size = | ||
| 179 | (Common::AlignUp((region_size / PageSize), Common::BitSize<u64>()) / | ||
| 180 | Common::BitSize<u64>()) * | ||
| 181 | sizeof(u64); | ||
| 182 | const std::size_t manager_meta_size = | ||
| 183 | Common::AlignUp(optimize_map_size + ref_count_size, PageSize); | ||
| 184 | const std::size_t page_heap_size = KPageHeap::CalculateManagementOverheadSize(region_size); | ||
| 185 | return manager_meta_size + page_heap_size; | ||
| 186 | } | ||
| 187 | |||
| 176 | } // namespace Kernel | 188 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h index ae9f683b8..ac840b3d0 100644 --- a/src/core/hle/kernel/k_memory_manager.h +++ b/src/core/hle/kernel/k_memory_manager.h | |||
| @@ -29,6 +29,10 @@ public: | |||
| 29 | 29 | ||
| 30 | Shift = 4, | 30 | Shift = 4, |
| 31 | Mask = (0xF << Shift), | 31 | Mask = (0xF << Shift), |
| 32 | |||
| 33 | // Aliases. | ||
| 34 | Unsafe = Application, | ||
| 35 | Secure = System, | ||
| 32 | }; | 36 | }; |
| 33 | 37 | ||
| 34 | enum class Direction : u32 { | 38 | enum class Direction : u32 { |
| @@ -56,6 +60,10 @@ public: | |||
| 56 | static constexpr std::size_t MaxManagerCount = 10; | 60 | static constexpr std::size_t MaxManagerCount = 10; |
| 57 | 61 | ||
| 58 | public: | 62 | public: |
| 63 | static std::size_t CalculateManagementOverheadSize(std::size_t region_size) { | ||
| 64 | return Impl::CalculateManagementOverheadSize(region_size); | ||
| 65 | } | ||
| 66 | |||
| 59 | static constexpr u32 EncodeOption(Pool pool, Direction dir) { | 67 | static constexpr u32 EncodeOption(Pool pool, Direction dir) { |
| 60 | return (static_cast<u32>(pool) << static_cast<u32>(Pool::Shift)) | | 68 | return (static_cast<u32>(pool) << static_cast<u32>(Pool::Shift)) | |
| 61 | (static_cast<u32>(dir) << static_cast<u32>(Direction::Shift)); | 69 | (static_cast<u32>(dir) << static_cast<u32>(Direction::Shift)); |
| @@ -86,6 +94,16 @@ private: | |||
| 86 | Pool pool{}; | 94 | Pool pool{}; |
| 87 | 95 | ||
| 88 | public: | 96 | public: |
| 97 | static std::size_t CalculateManagementOverheadSize(std::size_t region_size); | ||
| 98 | |||
| 99 | static constexpr std::size_t CalculateOptimizedProcessOverheadSize( | ||
| 100 | std::size_t region_size) { | ||
| 101 | return (Common::AlignUp((region_size / PageSize), Common::BitSize<u64>()) / | ||
| 102 | Common::BitSize<u64>()) * | ||
| 103 | sizeof(u64); | ||
| 104 | } | ||
| 105 | |||
| 106 | public: | ||
| 89 | Impl() = default; | 107 | Impl() = default; |
| 90 | 108 | ||
| 91 | std::size_t Initialize(Pool new_pool, u64 start_address, u64 end_address); | 109 | std::size_t Initialize(Pool new_pool, u64 start_address, u64 end_address); |
diff --git a/src/core/hle/kernel/k_memory_region.h b/src/core/hle/kernel/k_memory_region.h new file mode 100644 index 000000000..a861c04ab --- /dev/null +++ b/src/core/hle/kernel/k_memory_region.h | |||
| @@ -0,0 +1,350 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "common/intrusive_red_black_tree.h" | ||
| 10 | #include "core/hle/kernel/k_memory_region_type.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | |||
| 14 | class KMemoryRegionAllocator; | ||
| 15 | |||
| 16 | class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>, | ||
| 17 | NonCopyable { | ||
| 18 | friend class KMemoryRegionTree; | ||
| 19 | |||
| 20 | public: | ||
| 21 | constexpr KMemoryRegion() = default; | ||
| 22 | constexpr KMemoryRegion(u64 address_, u64 last_address_) | ||
| 23 | : address{address_}, last_address{last_address_} {} | ||
| 24 | constexpr KMemoryRegion(u64 address_, u64 last_address_, u64 pair_address_, u32 attributes_, | ||
| 25 | u32 type_id_) | ||
| 26 | : address(address_), last_address(last_address_), pair_address(pair_address_), | ||
| 27 | attributes(attributes_), type_id(type_id_) {} | ||
| 28 | constexpr KMemoryRegion(u64 address_, u64 last_address_, u32 attributes_, u32 type_id_) | ||
| 29 | : KMemoryRegion(address_, last_address_, std::numeric_limits<u64>::max(), attributes_, | ||
| 30 | type_id_) {} | ||
| 31 | |||
| 32 | static constexpr int Compare(const KMemoryRegion& lhs, const KMemoryRegion& rhs) { | ||
| 33 | if (lhs.GetAddress() < rhs.GetAddress()) { | ||
| 34 | return -1; | ||
| 35 | } else if (lhs.GetAddress() <= rhs.GetLastAddress()) { | ||
| 36 | return 0; | ||
| 37 | } else { | ||
| 38 | return 1; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | private: | ||
| 43 | constexpr void Reset(u64 a, u64 la, u64 p, u32 r, u32 t) { | ||
| 44 | address = a; | ||
| 45 | pair_address = p; | ||
| 46 | last_address = la; | ||
| 47 | attributes = r; | ||
| 48 | type_id = t; | ||
| 49 | } | ||
| 50 | |||
| 51 | public: | ||
| 52 | constexpr u64 GetAddress() const { | ||
| 53 | return address; | ||
| 54 | } | ||
| 55 | |||
| 56 | constexpr u64 GetPairAddress() const { | ||
| 57 | return pair_address; | ||
| 58 | } | ||
| 59 | |||
| 60 | constexpr u64 GetLastAddress() const { | ||
| 61 | return last_address; | ||
| 62 | } | ||
| 63 | |||
| 64 | constexpr u64 GetEndAddress() const { | ||
| 65 | return this->GetLastAddress() + 1; | ||
| 66 | } | ||
| 67 | |||
| 68 | constexpr size_t GetSize() const { | ||
| 69 | return this->GetEndAddress() - this->GetAddress(); | ||
| 70 | } | ||
| 71 | |||
| 72 | constexpr u32 GetAttributes() const { | ||
| 73 | return attributes; | ||
| 74 | } | ||
| 75 | |||
| 76 | constexpr u32 GetType() const { | ||
| 77 | return type_id; | ||
| 78 | } | ||
| 79 | |||
| 80 | constexpr void SetType(u32 type) { | ||
| 81 | ASSERT(this->CanDerive(type)); | ||
| 82 | type_id = type; | ||
| 83 | } | ||
| 84 | |||
| 85 | constexpr bool Contains(u64 address) const { | ||
| 86 | ASSERT(this->GetEndAddress() != 0); | ||
| 87 | return this->GetAddress() <= address && address <= this->GetLastAddress(); | ||
| 88 | } | ||
| 89 | |||
| 90 | constexpr bool IsDerivedFrom(u32 type) const { | ||
| 91 | return (this->GetType() | type) == this->GetType(); | ||
| 92 | } | ||
| 93 | |||
| 94 | constexpr bool HasTypeAttribute(u32 attr) const { | ||
| 95 | return (this->GetType() | attr) == this->GetType(); | ||
| 96 | } | ||
| 97 | |||
| 98 | constexpr bool CanDerive(u32 type) const { | ||
| 99 | return (this->GetType() | type) == type; | ||
| 100 | } | ||
| 101 | |||
| 102 | constexpr void SetPairAddress(u64 a) { | ||
| 103 | pair_address = a; | ||
| 104 | } | ||
| 105 | |||
| 106 | constexpr void SetTypeAttribute(u32 attr) { | ||
| 107 | type_id |= attr; | ||
| 108 | } | ||
| 109 | |||
| 110 | private: | ||
| 111 | u64 address{}; | ||
| 112 | u64 last_address{}; | ||
| 113 | u64 pair_address{}; | ||
| 114 | u32 attributes{}; | ||
| 115 | u32 type_id{}; | ||
| 116 | }; | ||
| 117 | |||
| 118 | class KMemoryRegionTree final : NonCopyable { | ||
| 119 | public: | ||
| 120 | struct DerivedRegionExtents { | ||
| 121 | const KMemoryRegion* first_region{}; | ||
| 122 | const KMemoryRegion* last_region{}; | ||
| 123 | |||
| 124 | constexpr DerivedRegionExtents() = default; | ||
| 125 | |||
| 126 | constexpr u64 GetAddress() const { | ||
| 127 | return this->first_region->GetAddress(); | ||
| 128 | } | ||
| 129 | |||
| 130 | constexpr u64 GetLastAddress() const { | ||
| 131 | return this->last_region->GetLastAddress(); | ||
| 132 | } | ||
| 133 | |||
| 134 | constexpr u64 GetEndAddress() const { | ||
| 135 | return this->GetLastAddress() + 1; | ||
| 136 | } | ||
| 137 | |||
| 138 | constexpr size_t GetSize() const { | ||
| 139 | return this->GetEndAddress() - this->GetAddress(); | ||
| 140 | } | ||
| 141 | }; | ||
| 142 | |||
| 143 | private: | ||
| 144 | using TreeType = | ||
| 145 | Common::IntrusiveRedBlackTreeBaseTraits<KMemoryRegion>::TreeType<KMemoryRegion>; | ||
| 146 | |||
| 147 | public: | ||
| 148 | using value_type = TreeType::value_type; | ||
| 149 | using size_type = TreeType::size_type; | ||
| 150 | using difference_type = TreeType::difference_type; | ||
| 151 | using pointer = TreeType::pointer; | ||
| 152 | using const_pointer = TreeType::const_pointer; | ||
| 153 | using reference = TreeType::reference; | ||
| 154 | using const_reference = TreeType::const_reference; | ||
| 155 | using iterator = TreeType::iterator; | ||
| 156 | using const_iterator = TreeType::const_iterator; | ||
| 157 | |||
| 158 | private: | ||
| 159 | TreeType m_tree{}; | ||
| 160 | KMemoryRegionAllocator& memory_region_allocator; | ||
| 161 | |||
| 162 | public: | ||
| 163 | explicit KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_); | ||
| 164 | |||
| 165 | public: | ||
| 166 | KMemoryRegion* FindModifiable(u64 address) { | ||
| 167 | if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->end()) { | ||
| 168 | return std::addressof(*it); | ||
| 169 | } else { | ||
| 170 | return nullptr; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | const KMemoryRegion* Find(u64 address) const { | ||
| 175 | if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->cend()) { | ||
| 176 | return std::addressof(*it); | ||
| 177 | } else { | ||
| 178 | return nullptr; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | const KMemoryRegion* FindByType(KMemoryRegionType type_id) const { | ||
| 183 | for (auto it = this->cbegin(); it != this->cend(); ++it) { | ||
| 184 | if (it->GetType() == static_cast<u32>(type_id)) { | ||
| 185 | return std::addressof(*it); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | return nullptr; | ||
| 189 | } | ||
| 190 | |||
| 191 | const KMemoryRegion* FindByTypeAndAttribute(u32 type_id, u32 attr) const { | ||
| 192 | for (auto it = this->cbegin(); it != this->cend(); ++it) { | ||
| 193 | if (it->GetType() == type_id && it->GetAttributes() == attr) { | ||
| 194 | return std::addressof(*it); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | return nullptr; | ||
| 198 | } | ||
| 199 | |||
| 200 | const KMemoryRegion* FindFirstDerived(KMemoryRegionType type_id) const { | ||
| 201 | for (auto it = this->cbegin(); it != this->cend(); it++) { | ||
| 202 | if (it->IsDerivedFrom(type_id)) { | ||
| 203 | return std::addressof(*it); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | return nullptr; | ||
| 207 | } | ||
| 208 | |||
| 209 | const KMemoryRegion* FindLastDerived(KMemoryRegionType type_id) const { | ||
| 210 | const KMemoryRegion* region = nullptr; | ||
| 211 | for (auto it = this->begin(); it != this->end(); it++) { | ||
| 212 | if (it->IsDerivedFrom(type_id)) { | ||
| 213 | region = std::addressof(*it); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | return region; | ||
| 217 | } | ||
| 218 | |||
| 219 | DerivedRegionExtents GetDerivedRegionExtents(KMemoryRegionType type_id) const { | ||
| 220 | DerivedRegionExtents extents; | ||
| 221 | |||
| 222 | ASSERT(extents.first_region == nullptr); | ||
| 223 | ASSERT(extents.last_region == nullptr); | ||
| 224 | |||
| 225 | for (auto it = this->cbegin(); it != this->cend(); it++) { | ||
| 226 | if (it->IsDerivedFrom(type_id)) { | ||
| 227 | if (extents.first_region == nullptr) { | ||
| 228 | extents.first_region = std::addressof(*it); | ||
| 229 | } | ||
| 230 | extents.last_region = std::addressof(*it); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | ASSERT(extents.first_region != nullptr); | ||
| 235 | ASSERT(extents.last_region != nullptr); | ||
| 236 | |||
| 237 | return extents; | ||
| 238 | } | ||
| 239 | |||
| 240 | DerivedRegionExtents GetDerivedRegionExtents(u32 type_id) const { | ||
| 241 | return GetDerivedRegionExtents(static_cast<KMemoryRegionType>(type_id)); | ||
| 242 | } | ||
| 243 | |||
| 244 | public: | ||
| 245 | void InsertDirectly(u64 address, u64 last_address, u32 attr = 0, u32 type_id = 0); | ||
| 246 | bool Insert(u64 address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0); | ||
| 247 | |||
| 248 | VAddr GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id); | ||
| 249 | |||
| 250 | VAddr GetRandomAlignedRegionWithGuard(size_t size, size_t alignment, u32 type_id, | ||
| 251 | size_t guard_size) { | ||
| 252 | return this->GetRandomAlignedRegion(size + 2 * guard_size, alignment, type_id) + guard_size; | ||
| 253 | } | ||
| 254 | |||
| 255 | public: | ||
| 256 | // Iterator accessors. | ||
| 257 | iterator begin() { | ||
| 258 | return m_tree.begin(); | ||
| 259 | } | ||
| 260 | |||
| 261 | const_iterator begin() const { | ||
| 262 | return m_tree.begin(); | ||
| 263 | } | ||
| 264 | |||
| 265 | iterator end() { | ||
| 266 | return m_tree.end(); | ||
| 267 | } | ||
| 268 | |||
| 269 | const_iterator end() const { | ||
| 270 | return m_tree.end(); | ||
| 271 | } | ||
| 272 | |||
| 273 | const_iterator cbegin() const { | ||
| 274 | return this->begin(); | ||
| 275 | } | ||
| 276 | |||
| 277 | const_iterator cend() const { | ||
| 278 | return this->end(); | ||
| 279 | } | ||
| 280 | |||
| 281 | iterator iterator_to(reference ref) { | ||
| 282 | return m_tree.iterator_to(ref); | ||
| 283 | } | ||
| 284 | |||
| 285 | const_iterator iterator_to(const_reference ref) const { | ||
| 286 | return m_tree.iterator_to(ref); | ||
| 287 | } | ||
| 288 | |||
| 289 | // Content management. | ||
| 290 | bool empty() const { | ||
| 291 | return m_tree.empty(); | ||
| 292 | } | ||
| 293 | |||
| 294 | reference back() { | ||
| 295 | return m_tree.back(); | ||
| 296 | } | ||
| 297 | |||
| 298 | const_reference back() const { | ||
| 299 | return m_tree.back(); | ||
| 300 | } | ||
| 301 | |||
| 302 | reference front() { | ||
| 303 | return m_tree.front(); | ||
| 304 | } | ||
| 305 | |||
| 306 | const_reference front() const { | ||
| 307 | return m_tree.front(); | ||
| 308 | } | ||
| 309 | |||
| 310 | iterator insert(reference ref) { | ||
| 311 | return m_tree.insert(ref); | ||
| 312 | } | ||
| 313 | |||
| 314 | iterator erase(iterator it) { | ||
| 315 | return m_tree.erase(it); | ||
| 316 | } | ||
| 317 | |||
| 318 | iterator find(const_reference ref) const { | ||
| 319 | return m_tree.find(ref); | ||
| 320 | } | ||
| 321 | |||
| 322 | iterator nfind(const_reference ref) const { | ||
| 323 | return m_tree.nfind(ref); | ||
| 324 | } | ||
| 325 | }; | ||
| 326 | |||
| 327 | class KMemoryRegionAllocator final : NonCopyable { | ||
| 328 | public: | ||
| 329 | static constexpr size_t MaxMemoryRegions = 200; | ||
| 330 | |||
| 331 | constexpr KMemoryRegionAllocator() = default; | ||
| 332 | |||
| 333 | template <typename... Args> | ||
| 334 | KMemoryRegion* Allocate(Args&&... args) { | ||
| 335 | // Ensure we stay within the bounds of our heap. | ||
| 336 | ASSERT(this->num_regions < MaxMemoryRegions); | ||
| 337 | |||
| 338 | // Create the new region. | ||
| 339 | KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]); | ||
| 340 | new (region) KMemoryRegion(std::forward<Args>(args)...); | ||
| 341 | |||
| 342 | return region; | ||
| 343 | } | ||
| 344 | |||
| 345 | private: | ||
| 346 | std::array<KMemoryRegion, MaxMemoryRegions> region_heap{}; | ||
| 347 | size_t num_regions{}; | ||
| 348 | }; | ||
| 349 | |||
| 350 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_memory_region_type.h b/src/core/hle/kernel/k_memory_region_type.h new file mode 100644 index 000000000..a05e66677 --- /dev/null +++ b/src/core/hle/kernel/k_memory_region_type.h | |||
| @@ -0,0 +1,338 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/bit_util.h" | ||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | #define ARCH_ARM64 | ||
| 12 | #define BOARD_NINTENDO_NX | ||
| 13 | |||
| 14 | namespace Kernel { | ||
| 15 | |||
| 16 | enum KMemoryRegionType : u32 { | ||
| 17 | KMemoryRegionAttr_CarveoutProtected = 0x04000000, | ||
| 18 | KMemoryRegionAttr_DidKernelMap = 0x08000000, | ||
| 19 | KMemoryRegionAttr_ShouldKernelMap = 0x10000000, | ||
| 20 | KMemoryRegionAttr_UserReadOnly = 0x20000000, | ||
| 21 | KMemoryRegionAttr_NoUserMap = 0x40000000, | ||
| 22 | KMemoryRegionAttr_LinearMapped = 0x80000000, | ||
| 23 | }; | ||
| 24 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryRegionType); | ||
| 25 | |||
| 26 | namespace impl { | ||
| 27 | |||
| 28 | constexpr size_t BitsForDeriveSparse(size_t n) { | ||
| 29 | return n + 1; | ||
| 30 | } | ||
| 31 | |||
| 32 | constexpr size_t BitsForDeriveDense(size_t n) { | ||
| 33 | size_t low = 0, high = 1; | ||
| 34 | for (size_t i = 0; i < n - 1; ++i) { | ||
| 35 | if ((++low) == high) { | ||
| 36 | ++high; | ||
| 37 | low = 0; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | return high + 1; | ||
| 41 | } | ||
| 42 | |||
| 43 | class KMemoryRegionTypeValue { | ||
| 44 | public: | ||
| 45 | using ValueType = std::underlying_type_t<KMemoryRegionType>; | ||
| 46 | |||
| 47 | constexpr KMemoryRegionTypeValue() = default; | ||
| 48 | |||
| 49 | constexpr operator KMemoryRegionType() const { | ||
| 50 | return static_cast<KMemoryRegionType>(m_value); | ||
| 51 | } | ||
| 52 | |||
| 53 | constexpr ValueType GetValue() const { | ||
| 54 | return m_value; | ||
| 55 | } | ||
| 56 | |||
| 57 | constexpr const KMemoryRegionTypeValue& Finalize() { | ||
| 58 | m_finalized = true; | ||
| 59 | return *this; | ||
| 60 | } | ||
| 61 | |||
| 62 | constexpr const KMemoryRegionTypeValue& SetSparseOnly() { | ||
| 63 | m_sparse_only = true; | ||
| 64 | return *this; | ||
| 65 | } | ||
| 66 | |||
| 67 | constexpr const KMemoryRegionTypeValue& SetDenseOnly() { | ||
| 68 | m_dense_only = true; | ||
| 69 | return *this; | ||
| 70 | } | ||
| 71 | |||
| 72 | constexpr KMemoryRegionTypeValue& SetAttribute(u32 attr) { | ||
| 73 | m_value |= attr; | ||
| 74 | return *this; | ||
| 75 | } | ||
| 76 | |||
| 77 | constexpr KMemoryRegionTypeValue DeriveInitial( | ||
| 78 | size_t i, size_t next = Common::BitSize<ValueType>()) const { | ||
| 79 | KMemoryRegionTypeValue new_type = *this; | ||
| 80 | new_type.m_value = (ValueType{1} << i); | ||
| 81 | new_type.m_next_bit = next; | ||
| 82 | return new_type; | ||
| 83 | } | ||
| 84 | |||
| 85 | constexpr KMemoryRegionTypeValue DeriveAttribute(u32 attr) const { | ||
| 86 | KMemoryRegionTypeValue new_type = *this; | ||
| 87 | new_type.m_value |= attr; | ||
| 88 | return new_type; | ||
| 89 | } | ||
| 90 | |||
| 91 | constexpr KMemoryRegionTypeValue DeriveTransition(size_t ofs = 0, size_t adv = 1) const { | ||
| 92 | KMemoryRegionTypeValue new_type = *this; | ||
| 93 | new_type.m_value |= (ValueType{1} << (m_next_bit + ofs)); | ||
| 94 | new_type.m_next_bit += adv; | ||
| 95 | return new_type; | ||
| 96 | } | ||
| 97 | |||
| 98 | constexpr KMemoryRegionTypeValue DeriveSparse(size_t ofs, size_t n, size_t i) const { | ||
| 99 | KMemoryRegionTypeValue new_type = *this; | ||
| 100 | new_type.m_value |= (ValueType{1} << (m_next_bit + ofs)); | ||
| 101 | new_type.m_value |= (ValueType{1} << (m_next_bit + ofs + 1 + i)); | ||
| 102 | new_type.m_next_bit += ofs + n + 1; | ||
| 103 | return new_type; | ||
| 104 | } | ||
| 105 | |||
| 106 | constexpr KMemoryRegionTypeValue Derive(size_t n, size_t i) const { | ||
| 107 | size_t low = 0, high = 1; | ||
| 108 | for (size_t j = 0; j < i; ++j) { | ||
| 109 | if ((++low) == high) { | ||
| 110 | ++high; | ||
| 111 | low = 0; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | KMemoryRegionTypeValue new_type = *this; | ||
| 116 | new_type.m_value |= (ValueType{1} << (m_next_bit + low)); | ||
| 117 | new_type.m_value |= (ValueType{1} << (m_next_bit + high)); | ||
| 118 | new_type.m_next_bit += BitsForDeriveDense(n); | ||
| 119 | return new_type; | ||
| 120 | } | ||
| 121 | |||
| 122 | constexpr KMemoryRegionTypeValue Advance(size_t n) const { | ||
| 123 | KMemoryRegionTypeValue new_type = *this; | ||
| 124 | new_type.m_next_bit += n; | ||
| 125 | return new_type; | ||
| 126 | } | ||
| 127 | |||
| 128 | constexpr bool IsAncestorOf(ValueType v) const { | ||
| 129 | return (m_value | v) == v; | ||
| 130 | } | ||
| 131 | |||
| 132 | private: | ||
| 133 | constexpr KMemoryRegionTypeValue(ValueType v) : m_value(v) {} | ||
| 134 | |||
| 135 | private: | ||
| 136 | ValueType m_value{}; | ||
| 137 | size_t m_next_bit{}; | ||
| 138 | bool m_finalized{}; | ||
| 139 | bool m_sparse_only{}; | ||
| 140 | bool m_dense_only{}; | ||
| 141 | }; | ||
| 142 | |||
| 143 | } // namespace impl | ||
| 144 | |||
| 145 | constexpr auto KMemoryRegionType_None = impl::KMemoryRegionTypeValue(); | ||
| 146 | constexpr auto KMemoryRegionType_Kernel = KMemoryRegionType_None.DeriveInitial(0, 2); | ||
| 147 | constexpr auto KMemoryRegionType_Dram = KMemoryRegionType_None.DeriveInitial(1, 2); | ||
| 148 | static_assert(KMemoryRegionType_Kernel.GetValue() == 0x1); | ||
| 149 | static_assert(KMemoryRegionType_Dram.GetValue() == 0x2); | ||
| 150 | |||
| 151 | constexpr auto KMemoryRegionType_DramKernelBase = | ||
| 152 | KMemoryRegionType_Dram.DeriveSparse(0, 3, 0) | ||
| 153 | .SetAttribute(KMemoryRegionAttr_NoUserMap) | ||
| 154 | .SetAttribute(KMemoryRegionAttr_CarveoutProtected); | ||
| 155 | constexpr auto KMemoryRegionType_DramReservedBase = KMemoryRegionType_Dram.DeriveSparse(0, 3, 1); | ||
| 156 | constexpr auto KMemoryRegionType_DramHeapBase = | ||
| 157 | KMemoryRegionType_Dram.DeriveSparse(0, 3, 2).SetAttribute(KMemoryRegionAttr_LinearMapped); | ||
| 158 | static_assert(KMemoryRegionType_DramKernelBase.GetValue() == | ||
| 159 | (0xE | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap)); | ||
| 160 | static_assert(KMemoryRegionType_DramReservedBase.GetValue() == (0x16)); | ||
| 161 | static_assert(KMemoryRegionType_DramHeapBase.GetValue() == (0x26 | KMemoryRegionAttr_LinearMapped)); | ||
| 162 | |||
| 163 | constexpr auto KMemoryRegionType_DramKernelCode = | ||
| 164 | KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 0); | ||
| 165 | constexpr auto KMemoryRegionType_DramKernelSlab = | ||
| 166 | KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 1); | ||
| 167 | constexpr auto KMemoryRegionType_DramKernelPtHeap = | ||
| 168 | KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 2).SetAttribute( | ||
| 169 | KMemoryRegionAttr_LinearMapped); | ||
| 170 | constexpr auto KMemoryRegionType_DramKernelInitPt = | ||
| 171 | KMemoryRegionType_DramKernelBase.DeriveSparse(0, 4, 3).SetAttribute( | ||
| 172 | KMemoryRegionAttr_LinearMapped); | ||
| 173 | static_assert(KMemoryRegionType_DramKernelCode.GetValue() == | ||
| 174 | (0xCE | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap)); | ||
| 175 | static_assert(KMemoryRegionType_DramKernelSlab.GetValue() == | ||
| 176 | (0x14E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap)); | ||
| 177 | static_assert(KMemoryRegionType_DramKernelPtHeap.GetValue() == | ||
| 178 | (0x24E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | | ||
| 179 | KMemoryRegionAttr_LinearMapped)); | ||
| 180 | static_assert(KMemoryRegionType_DramKernelInitPt.GetValue() == | ||
| 181 | (0x44E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | | ||
| 182 | KMemoryRegionAttr_LinearMapped)); | ||
| 183 | |||
| 184 | constexpr auto KMemoryRegionType_DramReservedEarly = | ||
| 185 | KMemoryRegionType_DramReservedBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 186 | static_assert(KMemoryRegionType_DramReservedEarly.GetValue() == | ||
| 187 | (0x16 | KMemoryRegionAttr_NoUserMap)); | ||
| 188 | |||
| 189 | constexpr auto KMemoryRegionType_KernelTraceBuffer = | ||
| 190 | KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 0) | ||
| 191 | .SetAttribute(KMemoryRegionAttr_LinearMapped) | ||
| 192 | .SetAttribute(KMemoryRegionAttr_UserReadOnly); | ||
| 193 | constexpr auto KMemoryRegionType_OnMemoryBootImage = | ||
| 194 | KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 1); | ||
| 195 | constexpr auto KMemoryRegionType_DTB = KMemoryRegionType_DramReservedBase.DeriveSparse(0, 3, 2); | ||
| 196 | static_assert(KMemoryRegionType_KernelTraceBuffer.GetValue() == | ||
| 197 | (0xD6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_UserReadOnly)); | ||
| 198 | static_assert(KMemoryRegionType_OnMemoryBootImage.GetValue() == 0x156); | ||
| 199 | static_assert(KMemoryRegionType_DTB.GetValue() == 0x256); | ||
| 200 | |||
| 201 | constexpr auto KMemoryRegionType_DramPoolPartition = | ||
| 202 | KMemoryRegionType_DramHeapBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap); | ||
| 203 | static_assert(KMemoryRegionType_DramPoolPartition.GetValue() == | ||
| 204 | (0x26 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); | ||
| 205 | |||
| 206 | constexpr auto KMemoryRegionType_DramPoolManagement = | ||
| 207 | KMemoryRegionType_DramPoolPartition.DeriveTransition(0, 2).DeriveTransition().SetAttribute( | ||
| 208 | KMemoryRegionAttr_CarveoutProtected); | ||
| 209 | constexpr auto KMemoryRegionType_DramUserPool = | ||
| 210 | KMemoryRegionType_DramPoolPartition.DeriveTransition(1, 2).DeriveTransition(); | ||
| 211 | static_assert(KMemoryRegionType_DramPoolManagement.GetValue() == | ||
| 212 | (0x166 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | | ||
| 213 | KMemoryRegionAttr_CarveoutProtected)); | ||
| 214 | static_assert(KMemoryRegionType_DramUserPool.GetValue() == | ||
| 215 | (0x1A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); | ||
| 216 | |||
| 217 | constexpr auto KMemoryRegionType_DramApplicationPool = KMemoryRegionType_DramUserPool.Derive(4, 0); | ||
| 218 | constexpr auto KMemoryRegionType_DramAppletPool = KMemoryRegionType_DramUserPool.Derive(4, 1); | ||
| 219 | constexpr auto KMemoryRegionType_DramSystemNonSecurePool = | ||
| 220 | KMemoryRegionType_DramUserPool.Derive(4, 2); | ||
| 221 | constexpr auto KMemoryRegionType_DramSystemPool = | ||
| 222 | KMemoryRegionType_DramUserPool.Derive(4, 3).SetAttribute(KMemoryRegionAttr_CarveoutProtected); | ||
| 223 | static_assert(KMemoryRegionType_DramApplicationPool.GetValue() == | ||
| 224 | (0x7A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); | ||
| 225 | static_assert(KMemoryRegionType_DramAppletPool.GetValue() == | ||
| 226 | (0xBA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); | ||
| 227 | static_assert(KMemoryRegionType_DramSystemNonSecurePool.GetValue() == | ||
| 228 | (0xDA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); | ||
| 229 | static_assert(KMemoryRegionType_DramSystemPool.GetValue() == | ||
| 230 | (0x13A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | | ||
| 231 | KMemoryRegionAttr_CarveoutProtected)); | ||
| 232 | |||
| 233 | constexpr auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 3, 0); | ||
| 234 | constexpr auto KMemoryRegionType_VirtualDramKernelPtHeap = | ||
| 235 | KMemoryRegionType_Dram.DeriveSparse(1, 3, 1); | ||
| 236 | constexpr auto KMemoryRegionType_VirtualDramKernelTraceBuffer = | ||
| 237 | KMemoryRegionType_Dram.DeriveSparse(1, 3, 2); | ||
| 238 | static_assert(KMemoryRegionType_VirtualDramHeapBase.GetValue() == 0x1A); | ||
| 239 | static_assert(KMemoryRegionType_VirtualDramKernelPtHeap.GetValue() == 0x2A); | ||
| 240 | static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A); | ||
| 241 | |||
| 242 | constexpr auto KMemoryRegionType_VirtualDramKernelInitPt = | ||
| 243 | KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0); | ||
| 244 | constexpr auto KMemoryRegionType_VirtualDramPoolManagement = | ||
| 245 | KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1); | ||
| 246 | constexpr auto KMemoryRegionType_VirtualDramUserPool = | ||
| 247 | KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2); | ||
| 248 | static_assert(KMemoryRegionType_VirtualDramKernelInitPt.GetValue() == 0x19A); | ||
| 249 | static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x29A); | ||
| 250 | static_assert(KMemoryRegionType_VirtualDramUserPool.GetValue() == 0x31A); | ||
| 251 | |||
| 252 | // NOTE: For unknown reason, the pools are derived out-of-order here. It's worth eventually trying | ||
| 253 | // to understand why Nintendo made this choice. | ||
| 254 | // UNUSED: .Derive(6, 0); | ||
| 255 | // UNUSED: .Derive(6, 1); | ||
| 256 | constexpr auto KMemoryRegionType_VirtualDramAppletPool = | ||
| 257 | KMemoryRegionType_VirtualDramUserPool.Derive(6, 2); | ||
| 258 | constexpr auto KMemoryRegionType_VirtualDramApplicationPool = | ||
| 259 | KMemoryRegionType_VirtualDramUserPool.Derive(6, 3); | ||
| 260 | constexpr auto KMemoryRegionType_VirtualDramSystemNonSecurePool = | ||
| 261 | KMemoryRegionType_VirtualDramUserPool.Derive(6, 4); | ||
| 262 | constexpr auto KMemoryRegionType_VirtualDramSystemPool = | ||
| 263 | KMemoryRegionType_VirtualDramUserPool.Derive(6, 5); | ||
| 264 | static_assert(KMemoryRegionType_VirtualDramAppletPool.GetValue() == 0x1B1A); | ||
| 265 | static_assert(KMemoryRegionType_VirtualDramApplicationPool.GetValue() == 0x271A); | ||
| 266 | static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x2B1A); | ||
| 267 | static_assert(KMemoryRegionType_VirtualDramSystemPool.GetValue() == 0x331A); | ||
| 268 | |||
| 269 | constexpr auto KMemoryRegionType_ArchDeviceBase = | ||
| 270 | KMemoryRegionType_Kernel.DeriveTransition(0, 1).SetSparseOnly(); | ||
| 271 | constexpr auto KMemoryRegionType_BoardDeviceBase = | ||
| 272 | KMemoryRegionType_Kernel.DeriveTransition(0, 2).SetDenseOnly(); | ||
| 273 | static_assert(KMemoryRegionType_ArchDeviceBase.GetValue() == 0x5); | ||
| 274 | static_assert(KMemoryRegionType_BoardDeviceBase.GetValue() == 0x5); | ||
| 275 | |||
| 276 | #if defined(ARCH_ARM64) | ||
| 277 | #include "core/hle/kernel/arch/arm64/k_memory_region_device_types.inc" | ||
| 278 | #elif defined(ARCH_ARM) | ||
| 279 | #error "Unimplemented" | ||
| 280 | #else | ||
| 281 | // Default to no architecture devices. | ||
| 282 | constexpr auto NumArchitectureDeviceRegions = 0; | ||
| 283 | #endif | ||
| 284 | static_assert(NumArchitectureDeviceRegions >= 0); | ||
| 285 | |||
| 286 | #if defined(BOARD_NINTENDO_NX) | ||
| 287 | #include "core/hle/kernel/board/nintendo/nx/k_memory_region_device_types.inc" | ||
| 288 | #else | ||
| 289 | // Default to no board devices. | ||
| 290 | constexpr auto NumBoardDeviceRegions = 0; | ||
| 291 | #endif | ||
| 292 | static_assert(NumBoardDeviceRegions >= 0); | ||
| 293 | |||
| 294 | constexpr auto KMemoryRegionType_KernelCode = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 0); | ||
| 295 | constexpr auto KMemoryRegionType_KernelStack = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 1); | ||
| 296 | constexpr auto KMemoryRegionType_KernelMisc = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 2); | ||
| 297 | constexpr auto KMemoryRegionType_KernelSlab = KMemoryRegionType_Kernel.DeriveSparse(1, 4, 3); | ||
| 298 | static_assert(KMemoryRegionType_KernelCode.GetValue() == 0x19); | ||
| 299 | static_assert(KMemoryRegionType_KernelStack.GetValue() == 0x29); | ||
| 300 | static_assert(KMemoryRegionType_KernelMisc.GetValue() == 0x49); | ||
| 301 | static_assert(KMemoryRegionType_KernelSlab.GetValue() == 0x89); | ||
| 302 | |||
| 303 | constexpr auto KMemoryRegionType_KernelMiscDerivedBase = | ||
| 304 | KMemoryRegionType_KernelMisc.DeriveTransition(); | ||
| 305 | static_assert(KMemoryRegionType_KernelMiscDerivedBase.GetValue() == 0x149); | ||
| 306 | |||
| 307 | // UNUSED: .Derive(7, 0); | ||
| 308 | constexpr auto KMemoryRegionType_KernelMiscMainStack = | ||
| 309 | KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 1); | ||
| 310 | constexpr auto KMemoryRegionType_KernelMiscMappedDevice = | ||
| 311 | KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 2); | ||
| 312 | constexpr auto KMemoryRegionType_KernelMiscExceptionStack = | ||
| 313 | KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 3); | ||
| 314 | constexpr auto KMemoryRegionType_KernelMiscUnknownDebug = | ||
| 315 | KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 4); | ||
| 316 | // UNUSED: .Derive(7, 5); | ||
| 317 | constexpr auto KMemoryRegionType_KernelMiscIdleStack = | ||
| 318 | KMemoryRegionType_KernelMiscDerivedBase.Derive(7, 6); | ||
| 319 | static_assert(KMemoryRegionType_KernelMiscMainStack.GetValue() == 0xB49); | ||
| 320 | static_assert(KMemoryRegionType_KernelMiscMappedDevice.GetValue() == 0xD49); | ||
| 321 | static_assert(KMemoryRegionType_KernelMiscExceptionStack.GetValue() == 0x1349); | ||
| 322 | static_assert(KMemoryRegionType_KernelMiscUnknownDebug.GetValue() == 0x1549); | ||
| 323 | static_assert(KMemoryRegionType_KernelMiscIdleStack.GetValue() == 0x2349); | ||
| 324 | |||
| 325 | constexpr auto KMemoryRegionType_KernelTemp = KMemoryRegionType_Kernel.Advance(2).Derive(2, 0); | ||
| 326 | static_assert(KMemoryRegionType_KernelTemp.GetValue() == 0x31); | ||
| 327 | |||
| 328 | constexpr KMemoryRegionType GetTypeForVirtualLinearMapping(u32 type_id) { | ||
| 329 | if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) { | ||
| 330 | return KMemoryRegionType_VirtualDramKernelTraceBuffer; | ||
| 331 | } else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) { | ||
| 332 | return KMemoryRegionType_VirtualDramKernelPtHeap; | ||
| 333 | } else { | ||
| 334 | return KMemoryRegionType_Dram; | ||
| 335 | } | ||
| 336 | } | ||
| 337 | |||
| 338 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index e7de48476..d1df97305 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -62,7 +62,7 @@ void KScheduler::RescheduleCores(KernelCore& kernel, u64 cores_pending_reschedul | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) { | 64 | u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) { |
| 65 | std::scoped_lock lock{guard}; | 65 | KScopedSpinLock lk{guard}; |
| 66 | if (KThread* prev_highest_thread = state.highest_priority_thread; | 66 | if (KThread* prev_highest_thread = state.highest_priority_thread; |
| 67 | prev_highest_thread != highest_thread) { | 67 | prev_highest_thread != highest_thread) { |
| 68 | if (prev_highest_thread != nullptr) { | 68 | if (prev_highest_thread != nullptr) { |
| @@ -637,11 +637,11 @@ void KScheduler::RescheduleCurrentCore() { | |||
| 637 | if (phys_core.IsInterrupted()) { | 637 | if (phys_core.IsInterrupted()) { |
| 638 | phys_core.ClearInterrupt(); | 638 | phys_core.ClearInterrupt(); |
| 639 | } | 639 | } |
| 640 | guard.lock(); | 640 | guard.Lock(); |
| 641 | if (state.needs_scheduling.load()) { | 641 | if (state.needs_scheduling.load()) { |
| 642 | Schedule(); | 642 | Schedule(); |
| 643 | } else { | 643 | } else { |
| 644 | guard.unlock(); | 644 | guard.Unlock(); |
| 645 | } | 645 | } |
| 646 | } | 646 | } |
| 647 | 647 | ||
| @@ -669,7 +669,7 @@ void KScheduler::Unload(KThread* thread) { | |||
| 669 | } else { | 669 | } else { |
| 670 | prev_thread = nullptr; | 670 | prev_thread = nullptr; |
| 671 | } | 671 | } |
| 672 | thread->context_guard.unlock(); | 672 | thread->context_guard.Unlock(); |
| 673 | } | 673 | } |
| 674 | } | 674 | } |
| 675 | 675 | ||
| @@ -713,7 +713,7 @@ void KScheduler::ScheduleImpl() { | |||
| 713 | 713 | ||
| 714 | // If we're not actually switching thread, there's nothing to do. | 714 | // If we're not actually switching thread, there's nothing to do. |
| 715 | if (next_thread == current_thread.load()) { | 715 | if (next_thread == current_thread.load()) { |
| 716 | guard.unlock(); | 716 | guard.Unlock(); |
| 717 | return; | 717 | return; |
| 718 | } | 718 | } |
| 719 | 719 | ||
| @@ -732,7 +732,7 @@ void KScheduler::ScheduleImpl() { | |||
| 732 | } else { | 732 | } else { |
| 733 | old_context = &idle_thread->GetHostContext(); | 733 | old_context = &idle_thread->GetHostContext(); |
| 734 | } | 734 | } |
| 735 | guard.unlock(); | 735 | guard.Unlock(); |
| 736 | 736 | ||
| 737 | Common::Fiber::YieldTo(*old_context, *switch_fiber); | 737 | Common::Fiber::YieldTo(*old_context, *switch_fiber); |
| 738 | /// When a thread wakes up, the scheduler may have changed to other in another core. | 738 | /// 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) { | |||
| 748 | void KScheduler::SwitchToCurrent() { | 748 | void KScheduler::SwitchToCurrent() { |
| 749 | while (true) { | 749 | while (true) { |
| 750 | { | 750 | { |
| 751 | std::scoped_lock lock{guard}; | 751 | KScopedSpinLock lk{guard}; |
| 752 | current_thread.store(state.highest_priority_thread); | 752 | current_thread.store(state.highest_priority_thread); |
| 753 | state.needs_scheduling.store(false); | 753 | state.needs_scheduling.store(false); |
| 754 | } | 754 | } |
| 755 | const auto is_switch_pending = [this] { | 755 | const auto is_switch_pending = [this] { |
| 756 | std::scoped_lock lock{guard}; | 756 | KScopedSpinLock lk{guard}; |
| 757 | return state.needs_scheduling.load(); | 757 | return state.needs_scheduling.load(); |
| 758 | }; | 758 | }; |
| 759 | do { | 759 | do { |
| 760 | auto next_thread = current_thread.load(); | 760 | auto next_thread = current_thread.load(); |
| 761 | if (next_thread != nullptr) { | 761 | if (next_thread != nullptr) { |
| 762 | next_thread->context_guard.lock(); | 762 | next_thread->context_guard.Lock(); |
| 763 | if (next_thread->GetRawState() != ThreadState::Runnable) { | 763 | if (next_thread->GetRawState() != ThreadState::Runnable) { |
| 764 | next_thread->context_guard.unlock(); | 764 | next_thread->context_guard.Unlock(); |
| 765 | break; | 765 | break; |
| 766 | } | 766 | } |
| 767 | if (next_thread->GetActiveCore() != core_id) { | 767 | if (next_thread->GetActiveCore() != core_id) { |
| 768 | next_thread->context_guard.unlock(); | 768 | next_thread->context_guard.Unlock(); |
| 769 | break; | 769 | break; |
| 770 | } | 770 | } |
| 771 | } | 771 | } |
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index f595b9a5c..8e32865aa 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h | |||
| @@ -2,19 +2,16 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | 5 | #pragma once |
| 9 | 6 | ||
| 10 | #include <atomic> | 7 | #include <atomic> |
| 11 | 8 | ||
| 12 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 13 | #include "common/spin_lock.h" | ||
| 14 | #include "core/hle/kernel/global_scheduler_context.h" | 10 | #include "core/hle/kernel/global_scheduler_context.h" |
| 15 | #include "core/hle/kernel/k_priority_queue.h" | 11 | #include "core/hle/kernel/k_priority_queue.h" |
| 16 | #include "core/hle/kernel/k_scheduler_lock.h" | 12 | #include "core/hle/kernel/k_scheduler_lock.h" |
| 17 | #include "core/hle/kernel/k_scoped_lock.h" | 13 | #include "core/hle/kernel/k_scoped_lock.h" |
| 14 | #include "core/hle/kernel/k_spin_lock.h" | ||
| 18 | 15 | ||
| 19 | namespace Common { | 16 | namespace Common { |
| 20 | class Fiber; | 17 | class Fiber; |
| @@ -195,12 +192,12 @@ private: | |||
| 195 | u64 last_context_switch_time{}; | 192 | u64 last_context_switch_time{}; |
| 196 | const s32 core_id; | 193 | const s32 core_id; |
| 197 | 194 | ||
| 198 | Common::SpinLock guard{}; | 195 | KSpinLock guard{}; |
| 199 | }; | 196 | }; |
| 200 | 197 | ||
| 201 | class KScopedSchedulerLock : KScopedLock<GlobalSchedulerContext::LockType> { | 198 | class [[nodiscard]] KScopedSchedulerLock : KScopedLock<GlobalSchedulerContext::LockType> { |
| 202 | public: | 199 | public: |
| 203 | explicit KScopedSchedulerLock(KernelCore& kernel); | 200 | explicit KScopedSchedulerLock(KernelCore & kernel); |
| 204 | ~KScopedSchedulerLock(); | 201 | ~KScopedSchedulerLock(); |
| 205 | }; | 202 | }; |
| 206 | 203 | ||
diff --git a/src/core/hle/kernel/k_scheduler_lock.h b/src/core/hle/kernel/k_scheduler_lock.h index 169455d18..47e315555 100644 --- a/src/core/hle/kernel/k_scheduler_lock.h +++ b/src/core/hle/kernel/k_scheduler_lock.h | |||
| @@ -2,14 +2,11 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | 5 | #pragma once |
| 9 | 6 | ||
| 10 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 11 | #include "common/spin_lock.h" | ||
| 12 | #include "core/hardware_properties.h" | 8 | #include "core/hardware_properties.h" |
| 9 | #include "core/hle/kernel/k_spin_lock.h" | ||
| 13 | #include "core/hle/kernel/k_thread.h" | 10 | #include "core/hle/kernel/k_thread.h" |
| 14 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 15 | 12 | ||
| @@ -34,7 +31,7 @@ public: | |||
| 34 | } else { | 31 | } else { |
| 35 | // Otherwise, we want to disable scheduling and acquire the spinlock. | 32 | // Otherwise, we want to disable scheduling and acquire the spinlock. |
| 36 | SchedulerType::DisableScheduling(kernel); | 33 | SchedulerType::DisableScheduling(kernel); |
| 37 | spin_lock.lock(); | 34 | spin_lock.Lock(); |
| 38 | 35 | ||
| 39 | // For debug, ensure that our state is valid. | 36 | // For debug, ensure that our state is valid. |
| 40 | ASSERT(lock_count == 0); | 37 | ASSERT(lock_count == 0); |
| @@ -58,7 +55,7 @@ public: | |||
| 58 | 55 | ||
| 59 | // Note that we no longer hold the lock, and unlock the spinlock. | 56 | // Note that we no longer hold the lock, and unlock the spinlock. |
| 60 | owner_thread = nullptr; | 57 | owner_thread = nullptr; |
| 61 | spin_lock.unlock(); | 58 | spin_lock.Unlock(); |
| 62 | 59 | ||
| 63 | // Enable scheduling, and perform a rescheduling operation. | 60 | // Enable scheduling, and perform a rescheduling operation. |
| 64 | SchedulerType::EnableScheduling(kernel, cores_needing_scheduling); | 61 | SchedulerType::EnableScheduling(kernel, cores_needing_scheduling); |
| @@ -67,7 +64,7 @@ public: | |||
| 67 | 64 | ||
| 68 | private: | 65 | private: |
| 69 | KernelCore& kernel; | 66 | KernelCore& kernel; |
| 70 | Common::SpinLock spin_lock{}; | 67 | KAlignedSpinLock spin_lock{}; |
| 71 | s32 lock_count{}; | 68 | s32 lock_count{}; |
| 72 | KThread* owner_thread{}; | 69 | KThread* owner_thread{}; |
| 73 | }; | 70 | }; |
diff --git a/src/core/hle/kernel/k_scoped_lock.h b/src/core/hle/kernel/k_scoped_lock.h index d7cc557b2..72c3b0252 100644 --- a/src/core/hle/kernel/k_scoped_lock.h +++ b/src/core/hle/kernel/k_scoped_lock.h | |||
| @@ -20,19 +20,22 @@ concept KLockable = !std::is_reference_v<T> && requires(T & t) { | |||
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | template <typename T> | 22 | template <typename T> |
| 23 | requires KLockable<T> class KScopedLock { | 23 | requires KLockable<T> class [[nodiscard]] KScopedLock { |
| 24 | public: | 24 | public: |
| 25 | explicit KScopedLock(T* l) : lock_ptr(l) { | 25 | explicit KScopedLock(T * l) : lock_ptr(l) { |
| 26 | this->lock_ptr->Lock(); | 26 | this->lock_ptr->Lock(); |
| 27 | } | 27 | } |
| 28 | explicit KScopedLock(T& l) : KScopedLock(std::addressof(l)) { /* ... */ | 28 | explicit KScopedLock(T & l) : KScopedLock(std::addressof(l)) {} |
| 29 | } | 29 | |
| 30 | ~KScopedLock() { | 30 | ~KScopedLock() { |
| 31 | this->lock_ptr->Unlock(); | 31 | this->lock_ptr->Unlock(); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | KScopedLock(const KScopedLock&) = delete; | 34 | KScopedLock(const KScopedLock&) = delete; |
| 35 | KScopedLock(KScopedLock&&) = delete; | 35 | KScopedLock& operator=(const KScopedLock&) = delete; |
| 36 | |||
| 37 | KScopedLock(KScopedLock &&) = delete; | ||
| 38 | KScopedLock& operator=(KScopedLock&&) = delete; | ||
| 36 | 39 | ||
| 37 | private: | 40 | private: |
| 38 | T* lock_ptr; | 41 | T* lock_ptr; |
diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h index f8189e107..ebecf0c77 100644 --- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h +++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h | |||
| @@ -15,9 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | 17 | ||
| 18 | class KScopedSchedulerLockAndSleep { | 18 | class [[nodiscard]] KScopedSchedulerLockAndSleep { |
| 19 | public: | 19 | public: |
| 20 | explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, KThread* t, s64 timeout) | 20 | explicit KScopedSchedulerLockAndSleep(KernelCore & kernel, KThread * t, s64 timeout) |
| 21 | : kernel(kernel), thread(t), timeout_tick(timeout) { | 21 | : kernel(kernel), thread(t), timeout_tick(timeout) { |
| 22 | // Lock the scheduler. | 22 | // Lock the scheduler. |
| 23 | kernel.GlobalSchedulerContext().scheduler_lock.Lock(); | 23 | kernel.GlobalSchedulerContext().scheduler_lock.Lock(); |
diff --git a/src/core/hle/kernel/k_spin_lock.h b/src/core/hle/kernel/k_spin_lock.h index 12c4b2e88..4d87d006a 100644 --- a/src/core/hle/kernel/k_spin_lock.h +++ b/src/core/hle/kernel/k_spin_lock.h | |||
| @@ -28,6 +28,12 @@ private: | |||
| 28 | std::atomic_flag lck = ATOMIC_FLAG_INIT; | 28 | std::atomic_flag lck = ATOMIC_FLAG_INIT; |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | // TODO(bunnei): Alias for now, in case we want to implement these accurately in the future. | ||
| 32 | using KAlignedSpinLock = KSpinLock; | ||
| 33 | using KNotAlignedSpinLock = KSpinLock; | ||
| 34 | |||
| 31 | using KScopedSpinLock = KScopedLock<KSpinLock>; | 35 | using KScopedSpinLock = KScopedLock<KSpinLock>; |
| 36 | using KScopedAlignedSpinLock = KScopedLock<KAlignedSpinLock>; | ||
| 37 | using KScopedNotAlignedSpinLock = KScopedLock<KNotAlignedSpinLock>; | ||
| 32 | 38 | ||
| 33 | } // namespace Kernel | 39 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_system_control.cpp b/src/core/hle/kernel/k_system_control.cpp deleted file mode 100644 index aa1682f69..000000000 --- a/src/core/hle/kernel/k_system_control.cpp +++ /dev/null | |||
| @@ -1,42 +0,0 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <random> | ||
| 6 | |||
| 7 | #include "core/hle/kernel/k_system_control.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | |||
| 11 | namespace { | ||
| 12 | template <typename F> | ||
| 13 | u64 GenerateUniformRange(u64 min, u64 max, F f) { | ||
| 14 | // Handle the case where the difference is too large to represent. | ||
| 15 | if (max == std::numeric_limits<u64>::max() && min == std::numeric_limits<u64>::min()) { | ||
| 16 | return f(); | ||
| 17 | } | ||
| 18 | |||
| 19 | // Iterate until we get a value in range. | ||
| 20 | const u64 range_size = ((max + 1) - min); | ||
| 21 | const u64 effective_max = (std::numeric_limits<u64>::max() / range_size) * range_size; | ||
| 22 | while (true) { | ||
| 23 | if (const u64 rnd = f(); rnd < effective_max) { | ||
| 24 | return min + (rnd % range_size); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | } // Anonymous namespace | ||
| 30 | |||
| 31 | u64 KSystemControl::GenerateRandomU64() { | ||
| 32 | static std::random_device device; | ||
| 33 | static std::mt19937 gen(device()); | ||
| 34 | static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); | ||
| 35 | return distribution(gen); | ||
| 36 | } | ||
| 37 | |||
| 38 | u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) { | ||
| 39 | return GenerateUniformRange(min, max, GenerateRandomU64); | ||
| 40 | } | ||
| 41 | |||
| 42 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_system_control.h b/src/core/hle/kernel/k_system_control.h index 1d5b64ffa..d755082c2 100644 --- a/src/core/hle/kernel/k_system_control.h +++ b/src/core/hle/kernel/k_system_control.h | |||
| @@ -6,14 +6,18 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | namespace Kernel { | 9 | #define BOARD_NINTENDO_NX |
| 10 | |||
| 11 | #ifdef BOARD_NINTENDO_NX | ||
| 10 | 12 | ||
| 11 | class KSystemControl { | 13 | #include "core/hle/kernel/board/nintendo/nx/k_system_control.h" |
| 12 | public: | ||
| 13 | KSystemControl() = default; | ||
| 14 | 14 | ||
| 15 | static u64 GenerateRandomRange(u64 min, u64 max); | 15 | namespace Kernel { |
| 16 | static u64 GenerateRandomU64(); | 16 | |
| 17 | }; | 17 | using Kernel::Board::Nintendo::Nx::KSystemControl; |
| 18 | 18 | ||
| 19 | } // namespace Kernel | 19 | } // namespace Kernel |
| 20 | |||
| 21 | #else | ||
| 22 | #error "Unknown board for KSystemControl" | ||
| 23 | #endif | ||
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 1c19b23dc..1c86fdd20 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -14,10 +14,10 @@ | |||
| 14 | 14 | ||
| 15 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 16 | #include "common/intrusive_red_black_tree.h" | 16 | #include "common/intrusive_red_black_tree.h" |
| 17 | #include "common/spin_lock.h" | ||
| 18 | #include "core/arm/arm_interface.h" | 17 | #include "core/arm/arm_interface.h" |
| 19 | #include "core/hle/kernel/k_affinity_mask.h" | 18 | #include "core/hle/kernel/k_affinity_mask.h" |
| 20 | #include "core/hle/kernel/k_light_lock.h" | 19 | #include "core/hle/kernel/k_light_lock.h" |
| 20 | #include "core/hle/kernel/k_spin_lock.h" | ||
| 21 | #include "core/hle/kernel/k_synchronization_object.h" | 21 | #include "core/hle/kernel/k_synchronization_object.h" |
| 22 | #include "core/hle/kernel/object.h" | 22 | #include "core/hle/kernel/object.h" |
| 23 | #include "core/hle/kernel/svc_common.h" | 23 | #include "core/hle/kernel/svc_common.h" |
| @@ -732,7 +732,7 @@ private: | |||
| 732 | s8 priority_inheritance_count{}; | 732 | s8 priority_inheritance_count{}; |
| 733 | bool resource_limit_release_hint{}; | 733 | bool resource_limit_release_hint{}; |
| 734 | StackParameters stack_parameters{}; | 734 | StackParameters stack_parameters{}; |
| 735 | Common::SpinLock context_guard{}; | 735 | KSpinLock context_guard{}; |
| 736 | 736 | ||
| 737 | // For emulation | 737 | // For emulation |
| 738 | std::shared_ptr<Common::Fiber> host_context{}; | 738 | std::shared_ptr<Common::Fiber> host_context{}; |
diff --git a/src/core/hle/kernel/k_trace.h b/src/core/hle/kernel/k_trace.h new file mode 100644 index 000000000..91ebf9ab2 --- /dev/null +++ b/src/core/hle/kernel/k_trace.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Kernel { | ||
| 8 | |||
| 9 | constexpr bool IsKTraceEnabled = false; | ||
| 10 | constexpr std::size_t KTraceBufferSize = IsKTraceEnabled ? 16 * 1024 * 1024 : 0; | ||
| 11 | |||
| 12 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 5b6c7792e..8fd990577 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2021 yuzu Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <utility> | 12 | #include <utility> |
| 13 | 13 | ||
| 14 | #include "common/assert.h" | 14 | #include "common/assert.h" |
| 15 | #include "common/common_sizes.h" | ||
| 15 | #include "common/logging/log.h" | 16 | #include "common/logging/log.h" |
| 16 | #include "common/microprofile.h" | 17 | #include "common/microprofile.h" |
| 17 | #include "common/thread.h" | 18 | #include "common/thread.h" |
| @@ -143,10 +144,10 @@ struct KernelCore::Impl { | |||
| 143 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) | 144 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) |
| 144 | .IsSuccess()); | 145 | .IsSuccess()); |
| 145 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); | 146 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); |
| 146 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess()); | 147 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess()); |
| 147 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) | 148 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) |
| 148 | .IsSuccess()); | 149 | .IsSuccess()); |
| 149 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 933).IsSuccess()); | 150 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess()); |
| 150 | 151 | ||
| 151 | // Derived from recent software updates. The kernel reserves 27MB | 152 | // Derived from recent software updates. The kernel reserves 27MB |
| 152 | constexpr u64 kernel_size{0x1b00000}; | 153 | constexpr u64 kernel_size{0x1b00000}; |
| @@ -268,45 +269,314 @@ struct KernelCore::Impl { | |||
| 268 | return schedulers[thread_id]->GetCurrentThread(); | 269 | return schedulers[thread_id]->GetCurrentThread(); |
| 269 | } | 270 | } |
| 270 | 271 | ||
| 272 | void DeriveInitialMemoryLayout(KMemoryLayout& memory_layout) { | ||
| 273 | // Insert the root region for the virtual memory tree, from which all other regions will | ||
| 274 | // derive. | ||
| 275 | memory_layout.GetVirtualMemoryRegionTree().InsertDirectly( | ||
| 276 | KernelVirtualAddressSpaceBase, | ||
| 277 | KernelVirtualAddressSpaceBase + KernelVirtualAddressSpaceSize - 1); | ||
| 278 | |||
| 279 | // Insert the root region for the physical memory tree, from which all other regions will | ||
| 280 | // derive. | ||
| 281 | memory_layout.GetPhysicalMemoryRegionTree().InsertDirectly( | ||
| 282 | KernelPhysicalAddressSpaceBase, | ||
| 283 | KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1); | ||
| 284 | |||
| 285 | // Save start and end for ease of use. | ||
| 286 | const VAddr code_start_virt_addr = KernelVirtualAddressCodeBase; | ||
| 287 | const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd; | ||
| 288 | |||
| 289 | // Setup the containing kernel region. | ||
| 290 | constexpr size_t KernelRegionSize = Common::Size_1_GB; | ||
| 291 | constexpr size_t KernelRegionAlign = Common::Size_1_GB; | ||
| 292 | constexpr VAddr kernel_region_start = | ||
| 293 | Common::AlignDown(code_start_virt_addr, KernelRegionAlign); | ||
| 294 | size_t kernel_region_size = KernelRegionSize; | ||
| 295 | if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) { | ||
| 296 | kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start; | ||
| 297 | } | ||
| 298 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 299 | kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel)); | ||
| 300 | |||
| 301 | // Setup the code region. | ||
| 302 | constexpr size_t CodeRegionAlign = PageSize; | ||
| 303 | constexpr VAddr code_region_start = | ||
| 304 | Common::AlignDown(code_start_virt_addr, CodeRegionAlign); | ||
| 305 | constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign); | ||
| 306 | constexpr size_t code_region_size = code_region_end - code_region_start; | ||
| 307 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 308 | code_region_start, code_region_size, KMemoryRegionType_KernelCode)); | ||
| 309 | |||
| 310 | // Setup board-specific device physical regions. | ||
| 311 | Init::SetupDevicePhysicalMemoryRegions(memory_layout); | ||
| 312 | |||
| 313 | // Determine the amount of space needed for the misc region. | ||
| 314 | size_t misc_region_needed_size; | ||
| 315 | { | ||
| 316 | // Each core has a one page stack for all three stack types (Main, Idle, Exception). | ||
| 317 | misc_region_needed_size = Core::Hardware::NUM_CPU_CORES * (3 * (PageSize + PageSize)); | ||
| 318 | |||
| 319 | // Account for each auto-map device. | ||
| 320 | for (const auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { | ||
| 321 | if (region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) { | ||
| 322 | // Check that the region is valid. | ||
| 323 | ASSERT(region.GetEndAddress() != 0); | ||
| 324 | |||
| 325 | // Account for the region. | ||
| 326 | misc_region_needed_size += | ||
| 327 | PageSize + (Common::AlignUp(region.GetLastAddress(), PageSize) - | ||
| 328 | Common::AlignDown(region.GetAddress(), PageSize)); | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
| 332 | // Multiply the needed size by three, to account for the need for guard space. | ||
| 333 | misc_region_needed_size *= 3; | ||
| 334 | } | ||
| 335 | |||
| 336 | // Decide on the actual size for the misc region. | ||
| 337 | constexpr size_t MiscRegionAlign = KernelAslrAlignment; | ||
| 338 | constexpr size_t MiscRegionMinimumSize = Common::Size_32_MB; | ||
| 339 | const size_t misc_region_size = Common::AlignUp( | ||
| 340 | std::max(misc_region_needed_size, MiscRegionMinimumSize), MiscRegionAlign); | ||
| 341 | ASSERT(misc_region_size > 0); | ||
| 342 | |||
| 343 | // Setup the misc region. | ||
| 344 | const VAddr misc_region_start = | ||
| 345 | memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( | ||
| 346 | misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel); | ||
| 347 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 348 | misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc)); | ||
| 349 | |||
| 350 | // Setup the stack region. | ||
| 351 | constexpr size_t StackRegionSize = Common::Size_14_MB; | ||
| 352 | constexpr size_t StackRegionAlign = KernelAslrAlignment; | ||
| 353 | const VAddr stack_region_start = | ||
| 354 | memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( | ||
| 355 | StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel); | ||
| 356 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 357 | stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack)); | ||
| 358 | |||
| 359 | // Determine the size of the resource region. | ||
| 360 | const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); | ||
| 361 | |||
| 362 | // Determine the size of the slab region. | ||
| 363 | const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize); | ||
| 364 | ASSERT(slab_region_size <= resource_region_size); | ||
| 365 | |||
| 366 | // Setup the slab region. | ||
| 367 | const PAddr code_start_phys_addr = KernelPhysicalAddressCodeBase; | ||
| 368 | const PAddr code_end_phys_addr = code_start_phys_addr + code_region_size; | ||
| 369 | const PAddr slab_start_phys_addr = code_end_phys_addr; | ||
| 370 | const PAddr slab_end_phys_addr = slab_start_phys_addr + slab_region_size; | ||
| 371 | constexpr size_t SlabRegionAlign = KernelAslrAlignment; | ||
| 372 | const size_t slab_region_needed_size = | ||
| 373 | Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) - | ||
| 374 | Common::AlignDown(code_end_phys_addr, SlabRegionAlign); | ||
| 375 | const VAddr slab_region_start = | ||
| 376 | memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( | ||
| 377 | slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) + | ||
| 378 | (code_end_phys_addr % SlabRegionAlign); | ||
| 379 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 380 | slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab)); | ||
| 381 | |||
| 382 | // Setup the temp region. | ||
| 383 | constexpr size_t TempRegionSize = Common::Size_128_MB; | ||
| 384 | constexpr size_t TempRegionAlign = KernelAslrAlignment; | ||
| 385 | const VAddr temp_region_start = | ||
| 386 | memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( | ||
| 387 | TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel); | ||
| 388 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize, | ||
| 389 | KMemoryRegionType_KernelTemp)); | ||
| 390 | |||
| 391 | // Automatically map in devices that have auto-map attributes. | ||
| 392 | for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { | ||
| 393 | // We only care about kernel regions. | ||
| 394 | if (!region.IsDerivedFrom(KMemoryRegionType_Kernel)) { | ||
| 395 | continue; | ||
| 396 | } | ||
| 397 | |||
| 398 | // Check whether we should map the region. | ||
| 399 | if (!region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) { | ||
| 400 | continue; | ||
| 401 | } | ||
| 402 | |||
| 403 | // If this region has already been mapped, no need to consider it. | ||
| 404 | if (region.HasTypeAttribute(KMemoryRegionAttr_DidKernelMap)) { | ||
| 405 | continue; | ||
| 406 | } | ||
| 407 | |||
| 408 | // Check that the region is valid. | ||
| 409 | ASSERT(region.GetEndAddress() != 0); | ||
| 410 | |||
| 411 | // Set the attribute to note we've mapped this region. | ||
| 412 | region.SetTypeAttribute(KMemoryRegionAttr_DidKernelMap); | ||
| 413 | |||
| 414 | // Create a virtual pair region and insert it into the tree. | ||
| 415 | const PAddr map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize); | ||
| 416 | const size_t map_size = | ||
| 417 | Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr; | ||
| 418 | const VAddr map_virt_addr = | ||
| 419 | memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard( | ||
| 420 | map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize); | ||
| 421 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 422 | map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice)); | ||
| 423 | region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr); | ||
| 424 | } | ||
| 425 | |||
| 426 | Init::SetupDramPhysicalMemoryRegions(memory_layout); | ||
| 427 | |||
| 428 | // Insert a physical region for the kernel code region. | ||
| 429 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 430 | code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode)); | ||
| 431 | |||
| 432 | // Insert a physical region for the kernel slab region. | ||
| 433 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 434 | slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab)); | ||
| 435 | |||
| 436 | // Determine size available for kernel page table heaps, requiring > 8 MB. | ||
| 437 | const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size; | ||
| 438 | const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr; | ||
| 439 | ASSERT(page_table_heap_size / Common::Size_4_MB > 2); | ||
| 440 | |||
| 441 | // Insert a physical region for the kernel page table heap region | ||
| 442 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 443 | slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); | ||
| 444 | |||
| 445 | // All DRAM regions that we haven't tagged by this point will be mapped under the linear | ||
| 446 | // mapping. Tag them. | ||
| 447 | for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { | ||
| 448 | if (region.GetType() == KMemoryRegionType_Dram) { | ||
| 449 | // Check that the region is valid. | ||
| 450 | ASSERT(region.GetEndAddress() != 0); | ||
| 451 | |||
| 452 | // Set the linear map attribute. | ||
| 453 | region.SetTypeAttribute(KMemoryRegionAttr_LinearMapped); | ||
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | // Get the linear region extents. | ||
| 458 | const auto linear_extents = | ||
| 459 | memory_layout.GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( | ||
| 460 | KMemoryRegionAttr_LinearMapped); | ||
| 461 | ASSERT(linear_extents.GetEndAddress() != 0); | ||
| 462 | |||
| 463 | // Setup the linear mapping region. | ||
| 464 | constexpr size_t LinearRegionAlign = Common::Size_1_GB; | ||
| 465 | const PAddr aligned_linear_phys_start = | ||
| 466 | Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign); | ||
| 467 | const size_t linear_region_size = | ||
| 468 | Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) - | ||
| 469 | aligned_linear_phys_start; | ||
| 470 | const VAddr linear_region_start = | ||
| 471 | memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard( | ||
| 472 | linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign); | ||
| 473 | |||
| 474 | const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start; | ||
| 475 | |||
| 476 | // Map and create regions for all the linearly-mapped data. | ||
| 477 | { | ||
| 478 | PAddr cur_phys_addr = 0; | ||
| 479 | u64 cur_size = 0; | ||
| 480 | for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { | ||
| 481 | if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) { | ||
| 482 | continue; | ||
| 483 | } | ||
| 484 | |||
| 485 | ASSERT(region.GetEndAddress() != 0); | ||
| 486 | |||
| 487 | if (cur_size == 0) { | ||
| 488 | cur_phys_addr = region.GetAddress(); | ||
| 489 | cur_size = region.GetSize(); | ||
| 490 | } else if (cur_phys_addr + cur_size == region.GetAddress()) { | ||
| 491 | cur_size += region.GetSize(); | ||
| 492 | } else { | ||
| 493 | cur_phys_addr = region.GetAddress(); | ||
| 494 | cur_size = region.GetSize(); | ||
| 495 | } | ||
| 496 | |||
| 497 | const VAddr region_virt_addr = | ||
| 498 | region.GetAddress() + linear_region_phys_to_virt_diff; | ||
| 499 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 500 | region_virt_addr, region.GetSize(), | ||
| 501 | GetTypeForVirtualLinearMapping(region.GetType()))); | ||
| 502 | region.SetPairAddress(region_virt_addr); | ||
| 503 | |||
| 504 | KMemoryRegion* virt_region = | ||
| 505 | memory_layout.GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr); | ||
| 506 | ASSERT(virt_region != nullptr); | ||
| 507 | virt_region->SetPairAddress(region.GetAddress()); | ||
| 508 | } | ||
| 509 | } | ||
| 510 | |||
| 511 | // Insert regions for the initial page table region. | ||
| 512 | ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( | ||
| 513 | resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt)); | ||
| 514 | ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( | ||
| 515 | resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize, | ||
| 516 | KMemoryRegionType_VirtualDramKernelInitPt)); | ||
| 517 | |||
| 518 | // All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to | ||
| 519 | // some pool partition. Tag them. | ||
| 520 | for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { | ||
| 521 | if (region.GetType() == (KMemoryRegionType_Dram | KMemoryRegionAttr_LinearMapped)) { | ||
| 522 | region.SetType(KMemoryRegionType_DramPoolPartition); | ||
| 523 | } | ||
| 524 | } | ||
| 525 | |||
| 526 | // Setup all other memory regions needed to arrange the pool partitions. | ||
| 527 | Init::SetupPoolPartitionMemoryRegions(memory_layout); | ||
| 528 | |||
| 529 | // Cache all linear regions in their own trees for faster access, later. | ||
| 530 | memory_layout.InitializeLinearMemoryRegionTrees(aligned_linear_phys_start, | ||
| 531 | linear_region_start); | ||
| 532 | } | ||
| 533 | |||
| 271 | void InitializeMemoryLayout() { | 534 | void InitializeMemoryLayout() { |
| 272 | // Initialize memory layout | 535 | // Derive the initial memory layout from the emulated board |
| 273 | constexpr KMemoryLayout layout{KMemoryLayout::GetDefaultLayout()}; | 536 | KMemoryLayout memory_layout; |
| 537 | DeriveInitialMemoryLayout(memory_layout); | ||
| 538 | |||
| 539 | const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents(); | ||
| 540 | const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents(); | ||
| 541 | const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents(); | ||
| 542 | |||
| 543 | // Initialize memory managers | ||
| 544 | memory_manager = std::make_unique<KMemoryManager>(); | ||
| 545 | memory_manager->InitializeManager(KMemoryManager::Pool::Application, | ||
| 546 | application_pool.GetAddress(), | ||
| 547 | application_pool.GetEndAddress()); | ||
| 548 | memory_manager->InitializeManager(KMemoryManager::Pool::Applet, applet_pool.GetAddress(), | ||
| 549 | applet_pool.GetEndAddress()); | ||
| 550 | memory_manager->InitializeManager(KMemoryManager::Pool::System, system_pool.GetAddress(), | ||
| 551 | system_pool.GetEndAddress()); | ||
| 552 | |||
| 553 | // Setup memory regions for emulated processes | ||
| 554 | // TODO(bunnei): These should not be hardcoded regions initialized within the kernel | ||
| 274 | constexpr std::size_t hid_size{0x40000}; | 555 | constexpr std::size_t hid_size{0x40000}; |
| 275 | constexpr std::size_t font_size{0x1100000}; | 556 | constexpr std::size_t font_size{0x1100000}; |
| 276 | constexpr std::size_t irs_size{0x8000}; | 557 | constexpr std::size_t irs_size{0x8000}; |
| 277 | constexpr std::size_t time_size{0x1000}; | 558 | constexpr std::size_t time_size{0x1000}; |
| 278 | constexpr PAddr hid_addr{layout.System().StartAddress()}; | ||
| 279 | constexpr PAddr font_pa{layout.System().StartAddress() + hid_size}; | ||
| 280 | constexpr PAddr irs_addr{layout.System().StartAddress() + hid_size + font_size}; | ||
| 281 | constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size}; | ||
| 282 | 559 | ||
| 283 | // Initialize memory manager | 560 | const PAddr hid_phys_addr{system_pool.GetAddress()}; |
| 284 | memory_manager = std::make_unique<KMemoryManager>(); | 561 | const PAddr font_phys_addr{system_pool.GetAddress() + hid_size}; |
| 285 | memory_manager->InitializeManager(KMemoryManager::Pool::Application, | 562 | const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; |
| 286 | layout.Application().StartAddress(), | 563 | const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; |
| 287 | layout.Application().EndAddress()); | ||
| 288 | memory_manager->InitializeManager(KMemoryManager::Pool::Applet, | ||
| 289 | layout.Applet().StartAddress(), | ||
| 290 | layout.Applet().EndAddress()); | ||
| 291 | memory_manager->InitializeManager(KMemoryManager::Pool::System, | ||
| 292 | layout.System().StartAddress(), | ||
| 293 | layout.System().EndAddress()); | ||
| 294 | 564 | ||
| 295 | hid_shared_mem = Kernel::KSharedMemory::Create( | 565 | hid_shared_mem = Kernel::KSharedMemory::Create( |
| 296 | system.Kernel(), system.DeviceMemory(), nullptr, {hid_addr, hid_size / PageSize}, | 566 | system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize}, |
| 297 | KMemoryPermission::None, KMemoryPermission::Read, hid_addr, hid_size, | 567 | KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size, |
| 298 | "HID:SharedMemory"); | 568 | "HID:SharedMemory"); |
| 299 | font_shared_mem = Kernel::KSharedMemory::Create( | 569 | font_shared_mem = Kernel::KSharedMemory::Create( |
| 300 | system.Kernel(), system.DeviceMemory(), nullptr, {font_pa, font_size / PageSize}, | 570 | system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize}, |
| 301 | KMemoryPermission::None, KMemoryPermission::Read, font_pa, font_size, | 571 | KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size, |
| 302 | "Font:SharedMemory"); | 572 | "Font:SharedMemory"); |
| 303 | irs_shared_mem = Kernel::KSharedMemory::Create( | 573 | irs_shared_mem = Kernel::KSharedMemory::Create( |
| 304 | system.Kernel(), system.DeviceMemory(), nullptr, {irs_addr, irs_size / PageSize}, | 574 | system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize}, |
| 305 | KMemoryPermission::None, KMemoryPermission::Read, irs_addr, irs_size, | 575 | KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size, |
| 306 | "IRS:SharedMemory"); | 576 | "IRS:SharedMemory"); |
| 307 | time_shared_mem = Kernel::KSharedMemory::Create( | 577 | time_shared_mem = Kernel::KSharedMemory::Create( |
| 308 | system.Kernel(), system.DeviceMemory(), nullptr, {time_addr, time_size / PageSize}, | 578 | system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, |
| 309 | KMemoryPermission::None, KMemoryPermission::Read, time_addr, time_size, | 579 | KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, |
| 310 | "Time:SharedMemory"); | 580 | "Time:SharedMemory"); |
| 311 | 581 | ||
| 312 | // Allocate slab heaps | 582 | // Allocate slab heaps |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 56906f2da..a500e63bc 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project / PPSSPP Project | 1 | // Copyright 2021 yuzu Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index 3fc326eab..1006ee50c 100644 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp | |||
| @@ -281,11 +281,6 @@ ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags) | |||
| 281 | continue; | 281 | continue; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | if (svc_number >= svc_capabilities.size()) { | ||
| 285 | LOG_ERROR(Kernel, "Process svc capability is out of range! svc_number={}", svc_number); | ||
| 286 | return ResultOutOfRange; | ||
| 287 | } | ||
| 288 | |||
| 289 | svc_capabilities[svc_number] = true; | 284 | svc_capabilities[svc_number] = true; |
| 290 | } | 285 | } |
| 291 | 286 | ||
diff --git a/src/core/hle/kernel/process_capability.h b/src/core/hle/kernel/process_capability.h index 73ad197fa..b7a9b2e45 100644 --- a/src/core/hle/kernel/process_capability.h +++ b/src/core/hle/kernel/process_capability.h | |||
| @@ -68,7 +68,7 @@ enum class ProgramType { | |||
| 68 | class ProcessCapabilities { | 68 | class ProcessCapabilities { |
| 69 | public: | 69 | public: |
| 70 | using InterruptCapabilities = std::bitset<1024>; | 70 | using InterruptCapabilities = std::bitset<1024>; |
| 71 | using SyscallCapabilities = std::bitset<128>; | 71 | using SyscallCapabilities = std::bitset<192>; |
| 72 | 72 | ||
| 73 | ProcessCapabilities() = default; | 73 | ProcessCapabilities() = default; |
| 74 | ProcessCapabilities(const ProcessCapabilities&) = delete; | 74 | ProcessCapabilities(const ProcessCapabilities&) = delete; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 326d3b9ec..fcffc746d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -2455,6 +2455,74 @@ static const FunctionDef SVC_Table_32[] = { | |||
| 2455 | {0x79, nullptr, "Unknown"}, | 2455 | {0x79, nullptr, "Unknown"}, |
| 2456 | {0x7A, nullptr, "Unknown"}, | 2456 | {0x7A, nullptr, "Unknown"}, |
| 2457 | {0x7B, nullptr, "TerminateProcess32"}, | 2457 | {0x7B, nullptr, "TerminateProcess32"}, |
| 2458 | {0x7C, nullptr, "GetProcessInfo32"}, | ||
| 2459 | {0x7D, nullptr, "CreateResourceLimit32"}, | ||
| 2460 | {0x7E, nullptr, "SetResourceLimitLimitValue32"}, | ||
| 2461 | {0x7F, nullptr, "CallSecureMonitor32"}, | ||
| 2462 | {0x80, nullptr, "Unknown"}, | ||
| 2463 | {0x81, nullptr, "Unknown"}, | ||
| 2464 | {0x82, nullptr, "Unknown"}, | ||
| 2465 | {0x83, nullptr, "Unknown"}, | ||
| 2466 | {0x84, nullptr, "Unknown"}, | ||
| 2467 | {0x85, nullptr, "Unknown"}, | ||
| 2468 | {0x86, nullptr, "Unknown"}, | ||
| 2469 | {0x87, nullptr, "Unknown"}, | ||
| 2470 | {0x88, nullptr, "Unknown"}, | ||
| 2471 | {0x89, nullptr, "Unknown"}, | ||
| 2472 | {0x8A, nullptr, "Unknown"}, | ||
| 2473 | {0x8B, nullptr, "Unknown"}, | ||
| 2474 | {0x8C, nullptr, "Unknown"}, | ||
| 2475 | {0x8D, nullptr, "Unknown"}, | ||
| 2476 | {0x8E, nullptr, "Unknown"}, | ||
| 2477 | {0x8F, nullptr, "Unknown"}, | ||
| 2478 | {0x90, nullptr, "Unknown"}, | ||
| 2479 | {0x91, nullptr, "Unknown"}, | ||
| 2480 | {0x92, nullptr, "Unknown"}, | ||
| 2481 | {0x93, nullptr, "Unknown"}, | ||
| 2482 | {0x94, nullptr, "Unknown"}, | ||
| 2483 | {0x95, nullptr, "Unknown"}, | ||
| 2484 | {0x96, nullptr, "Unknown"}, | ||
| 2485 | {0x97, nullptr, "Unknown"}, | ||
| 2486 | {0x98, nullptr, "Unknown"}, | ||
| 2487 | {0x99, nullptr, "Unknown"}, | ||
| 2488 | {0x9A, nullptr, "Unknown"}, | ||
| 2489 | {0x9B, nullptr, "Unknown"}, | ||
| 2490 | {0x9C, nullptr, "Unknown"}, | ||
| 2491 | {0x9D, nullptr, "Unknown"}, | ||
| 2492 | {0x9E, nullptr, "Unknown"}, | ||
| 2493 | {0x9F, nullptr, "Unknown"}, | ||
| 2494 | {0xA0, nullptr, "Unknown"}, | ||
| 2495 | {0xA1, nullptr, "Unknown"}, | ||
| 2496 | {0xA2, nullptr, "Unknown"}, | ||
| 2497 | {0xA3, nullptr, "Unknown"}, | ||
| 2498 | {0xA4, nullptr, "Unknown"}, | ||
| 2499 | {0xA5, nullptr, "Unknown"}, | ||
| 2500 | {0xA6, nullptr, "Unknown"}, | ||
| 2501 | {0xA7, nullptr, "Unknown"}, | ||
| 2502 | {0xA8, nullptr, "Unknown"}, | ||
| 2503 | {0xA9, nullptr, "Unknown"}, | ||
| 2504 | {0xAA, nullptr, "Unknown"}, | ||
| 2505 | {0xAB, nullptr, "Unknown"}, | ||
| 2506 | {0xAC, nullptr, "Unknown"}, | ||
| 2507 | {0xAD, nullptr, "Unknown"}, | ||
| 2508 | {0xAE, nullptr, "Unknown"}, | ||
| 2509 | {0xAF, nullptr, "Unknown"}, | ||
| 2510 | {0xB0, nullptr, "Unknown"}, | ||
| 2511 | {0xB1, nullptr, "Unknown"}, | ||
| 2512 | {0xB2, nullptr, "Unknown"}, | ||
| 2513 | {0xB3, nullptr, "Unknown"}, | ||
| 2514 | {0xB4, nullptr, "Unknown"}, | ||
| 2515 | {0xB5, nullptr, "Unknown"}, | ||
| 2516 | {0xB6, nullptr, "Unknown"}, | ||
| 2517 | {0xB7, nullptr, "Unknown"}, | ||
| 2518 | {0xB8, nullptr, "Unknown"}, | ||
| 2519 | {0xB9, nullptr, "Unknown"}, | ||
| 2520 | {0xBA, nullptr, "Unknown"}, | ||
| 2521 | {0xBB, nullptr, "Unknown"}, | ||
| 2522 | {0xBC, nullptr, "Unknown"}, | ||
| 2523 | {0xBD, nullptr, "Unknown"}, | ||
| 2524 | {0xBE, nullptr, "Unknown"}, | ||
| 2525 | {0xBF, nullptr, "Unknown"}, | ||
| 2458 | }; | 2526 | }; |
| 2459 | 2527 | ||
| 2460 | static const FunctionDef SVC_Table_64[] = { | 2528 | static const FunctionDef SVC_Table_64[] = { |
| @@ -2586,6 +2654,70 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2586 | {0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"}, | 2654 | {0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"}, |
| 2587 | {0x7E, SvcWrap64<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"}, | 2655 | {0x7E, SvcWrap64<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"}, |
| 2588 | {0x7F, nullptr, "CallSecureMonitor"}, | 2656 | {0x7F, nullptr, "CallSecureMonitor"}, |
| 2657 | {0x80, nullptr, "Unknown"}, | ||
| 2658 | {0x81, nullptr, "Unknown"}, | ||
| 2659 | {0x82, nullptr, "Unknown"}, | ||
| 2660 | {0x83, nullptr, "Unknown"}, | ||
| 2661 | {0x84, nullptr, "Unknown"}, | ||
| 2662 | {0x85, nullptr, "Unknown"}, | ||
| 2663 | {0x86, nullptr, "Unknown"}, | ||
| 2664 | {0x87, nullptr, "Unknown"}, | ||
| 2665 | {0x88, nullptr, "Unknown"}, | ||
| 2666 | {0x89, nullptr, "Unknown"}, | ||
| 2667 | {0x8A, nullptr, "Unknown"}, | ||
| 2668 | {0x8B, nullptr, "Unknown"}, | ||
| 2669 | {0x8C, nullptr, "Unknown"}, | ||
| 2670 | {0x8D, nullptr, "Unknown"}, | ||
| 2671 | {0x8E, nullptr, "Unknown"}, | ||
| 2672 | {0x8F, nullptr, "Unknown"}, | ||
| 2673 | {0x90, nullptr, "Unknown"}, | ||
| 2674 | {0x91, nullptr, "Unknown"}, | ||
| 2675 | {0x92, nullptr, "Unknown"}, | ||
| 2676 | {0x93, nullptr, "Unknown"}, | ||
| 2677 | {0x94, nullptr, "Unknown"}, | ||
| 2678 | {0x95, nullptr, "Unknown"}, | ||
| 2679 | {0x96, nullptr, "Unknown"}, | ||
| 2680 | {0x97, nullptr, "Unknown"}, | ||
| 2681 | {0x98, nullptr, "Unknown"}, | ||
| 2682 | {0x99, nullptr, "Unknown"}, | ||
| 2683 | {0x9A, nullptr, "Unknown"}, | ||
| 2684 | {0x9B, nullptr, "Unknown"}, | ||
| 2685 | {0x9C, nullptr, "Unknown"}, | ||
| 2686 | {0x9D, nullptr, "Unknown"}, | ||
| 2687 | {0x9E, nullptr, "Unknown"}, | ||
| 2688 | {0x9F, nullptr, "Unknown"}, | ||
| 2689 | {0xA0, nullptr, "Unknown"}, | ||
| 2690 | {0xA1, nullptr, "Unknown"}, | ||
| 2691 | {0xA2, nullptr, "Unknown"}, | ||
| 2692 | {0xA3, nullptr, "Unknown"}, | ||
| 2693 | {0xA4, nullptr, "Unknown"}, | ||
| 2694 | {0xA5, nullptr, "Unknown"}, | ||
| 2695 | {0xA6, nullptr, "Unknown"}, | ||
| 2696 | {0xA7, nullptr, "Unknown"}, | ||
| 2697 | {0xA8, nullptr, "Unknown"}, | ||
| 2698 | {0xA9, nullptr, "Unknown"}, | ||
| 2699 | {0xAA, nullptr, "Unknown"}, | ||
| 2700 | {0xAB, nullptr, "Unknown"}, | ||
| 2701 | {0xAC, nullptr, "Unknown"}, | ||
| 2702 | {0xAD, nullptr, "Unknown"}, | ||
| 2703 | {0xAE, nullptr, "Unknown"}, | ||
| 2704 | {0xAF, nullptr, "Unknown"}, | ||
| 2705 | {0xB0, nullptr, "Unknown"}, | ||
| 2706 | {0xB1, nullptr, "Unknown"}, | ||
| 2707 | {0xB2, nullptr, "Unknown"}, | ||
| 2708 | {0xB3, nullptr, "Unknown"}, | ||
| 2709 | {0xB4, nullptr, "Unknown"}, | ||
| 2710 | {0xB5, nullptr, "Unknown"}, | ||
| 2711 | {0xB6, nullptr, "Unknown"}, | ||
| 2712 | {0xB7, nullptr, "Unknown"}, | ||
| 2713 | {0xB8, nullptr, "Unknown"}, | ||
| 2714 | {0xB9, nullptr, "Unknown"}, | ||
| 2715 | {0xBA, nullptr, "Unknown"}, | ||
| 2716 | {0xBB, nullptr, "Unknown"}, | ||
| 2717 | {0xBC, nullptr, "Unknown"}, | ||
| 2718 | {0xBD, nullptr, "Unknown"}, | ||
| 2719 | {0xBE, nullptr, "Unknown"}, | ||
| 2720 | {0xBF, nullptr, "Unknown"}, | ||
| 2589 | }; | 2721 | }; |
| 2590 | 2722 | ||
| 2591 | static const FunctionDef* GetSVCInfo32(u32 func_num) { | 2723 | static const FunctionDef* GetSVCInfo32(u32 func_num) { |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 615e20a54..52535ecc0 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -610,12 +610,17 @@ public: | |||
| 610 | explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} { | 610 | explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} { |
| 611 | // clang-format off | 611 | // clang-format off |
| 612 | static const FunctionInfo functions[] = { | 612 | static const FunctionInfo functions[] = { |
| 613 | {0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData | 613 | {0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, |
| 614 | {1, nullptr, "LoadAuthenticationTokenCache"}, // 6.0.0+ | 614 | {1, nullptr, "LoadAuthenticationTokenCache"}, |
| 615 | {2, nullptr, "InvalidateAuthenticationTokenCache"}, // 6.0.0+ | 615 | {2, nullptr, "InvalidateAuthenticationTokenCache"}, |
| 616 | {10, nullptr, "EnsureEdgeTokenCacheAsync"}, // 6.0.0+ | 616 | {10, nullptr, "EnsureEdgeTokenCacheAsync"}, |
| 617 | {11, nullptr, "LoadEdgeTokenCache"}, // 6.0.0+ | 617 | {11, nullptr, "LoadEdgeTokenCache"}, |
| 618 | {12, nullptr, "InvalidateEdgeTokenCache"}, // 6.0.0+ | 618 | {12, nullptr, "InvalidateEdgeTokenCache"}, |
| 619 | {20, nullptr, "EnsureApplicationAuthenticationCacheAsync"}, | ||
| 620 | {21, nullptr, "LoadApplicationAuthenticationTokenCache"}, | ||
| 621 | {22, nullptr, "LoadApplicationNetworkServiceClientConfigCache"}, | ||
| 622 | {23, nullptr, "IsApplicationAuthenticationCacheAvailable"}, | ||
| 623 | {24, nullptr, "InvalidateApplicationAuthenticationCache"}, | ||
| 619 | }; | 624 | }; |
| 620 | // clang-format on | 625 | // clang-format on |
| 621 | 626 | ||
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 49b22583e..bb6118abf 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp | |||
| @@ -17,28 +17,30 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 17 | {3, &ACC_SU::ListOpenUsers, "ListOpenUsers"}, | 17 | {3, &ACC_SU::ListOpenUsers, "ListOpenUsers"}, |
| 18 | {4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"}, | 18 | {4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"}, |
| 19 | {5, &ACC_SU::GetProfile, "GetProfile"}, | 19 | {5, &ACC_SU::GetProfile, "GetProfile"}, |
| 20 | {6, nullptr, "GetProfileDigest"}, // 3.0.0+ | 20 | {6, nullptr, "GetProfileDigest"}, |
| 21 | {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, | 21 | {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, |
| 22 | {51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, | 22 | {51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, |
| 23 | {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0 | 23 | {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, |
| 24 | {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+ | 24 | {99, nullptr, "DebugActivateOpenContextRetention"}, |
| 25 | {100, nullptr, "GetUserRegistrationNotifier"}, | 25 | {100, nullptr, "GetUserRegistrationNotifier"}, |
| 26 | {101, nullptr, "GetUserStateChangeNotifier"}, | 26 | {101, nullptr, "GetUserStateChangeNotifier"}, |
| 27 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, | 27 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, |
| 28 | {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, | 28 | {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, |
| 29 | {104, nullptr, "GetProfileUpdateNotifier"}, | 29 | {104, nullptr, "GetProfileUpdateNotifier"}, |
| 30 | {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+ | 30 | {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, |
| 31 | {106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+ | 31 | {106, nullptr, "GetProfileSyncNotifier"}, |
| 32 | {110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"}, | 32 | {110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"}, |
| 33 | {111, nullptr, "ClearSaveDataThumbnail"}, | 33 | {111, nullptr, "ClearSaveDataThumbnail"}, |
| 34 | {112, nullptr, "LoadSaveDataThumbnail"}, | 34 | {112, nullptr, "LoadSaveDataThumbnail"}, |
| 35 | {113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+ | 35 | {113, nullptr, "GetSaveDataThumbnailExistence"}, |
| 36 | {120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+ | 36 | {120, nullptr, "ListOpenUsersInApplication"}, |
| 37 | {130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+ | 37 | {130, nullptr, "ActivateOpenContextRetention"}, |
| 38 | {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+ | 38 | {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"}, |
| 39 | {150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+ | 39 | {150, nullptr, "AuthenticateApplicationAsync"}, |
| 40 | {190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0 | 40 | {151, nullptr, "Unknown151"}, |
| 41 | {191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+ | 41 | {152, nullptr, "Unknown152"}, |
| 42 | {190, nullptr, "GetUserLastOpenedApplication"}, | ||
| 43 | {191, nullptr, "ActivateOpenContextHolder"}, | ||
| 42 | {200, nullptr, "BeginUserRegistration"}, | 44 | {200, nullptr, "BeginUserRegistration"}, |
| 43 | {201, nullptr, "CompleteUserRegistration"}, | 45 | {201, nullptr, "CompleteUserRegistration"}, |
| 44 | {202, nullptr, "CancelUserRegistration"}, | 46 | {202, nullptr, "CancelUserRegistration"}, |
| @@ -46,15 +48,15 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 46 | {204, nullptr, "SetUserPosition"}, | 48 | {204, nullptr, "SetUserPosition"}, |
| 47 | {205, &ACC_SU::GetProfileEditor, "GetProfileEditor"}, | 49 | {205, &ACC_SU::GetProfileEditor, "GetProfileEditor"}, |
| 48 | {206, nullptr, "CompleteUserRegistrationForcibly"}, | 50 | {206, nullptr, "CompleteUserRegistrationForcibly"}, |
| 49 | {210, nullptr, "CreateFloatingRegistrationRequest"}, // 3.0.0+ | 51 | {210, nullptr, "CreateFloatingRegistrationRequest"}, |
| 50 | {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+ | 52 | {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, |
| 51 | {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+ | 53 | {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, |
| 52 | {230, nullptr, "AuthenticateServiceAsync"}, | 54 | {230, nullptr, "AuthenticateServiceAsync"}, |
| 53 | {250, nullptr, "GetBaasAccountAdministrator"}, | 55 | {250, nullptr, "GetBaasAccountAdministrator"}, |
| 54 | {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"}, | 56 | {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"}, |
| 55 | {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, // 3.0.0+ | 57 | {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, |
| 56 | {299, nullptr, "SuspendBackgroundDaemon"}, | 58 | {299, nullptr, "SuspendBackgroundDaemon"}, |
| 57 | {997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+ | 59 | {997, nullptr, "DebugInvalidateTokenCacheForUser"}, |
| 58 | {998, nullptr, "DebugSetUserStateClose"}, | 60 | {998, nullptr, "DebugSetUserStateClose"}, |
| 59 | {999, nullptr, "DebugSetUserStateOpen"}, | 61 | {999, nullptr, "DebugSetUserStateOpen"}, |
| 60 | }; | 62 | }; |
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 951081cd0..71982ad5a 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp | |||
| @@ -17,29 +17,31 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 17 | {3, &ACC_U1::ListOpenUsers, "ListOpenUsers"}, | 17 | {3, &ACC_U1::ListOpenUsers, "ListOpenUsers"}, |
| 18 | {4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"}, | 18 | {4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"}, |
| 19 | {5, &ACC_U1::GetProfile, "GetProfile"}, | 19 | {5, &ACC_U1::GetProfile, "GetProfile"}, |
| 20 | {6, nullptr, "GetProfileDigest"}, // 3.0.0+ | 20 | {6, nullptr, "GetProfileDigest"}, |
| 21 | {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, | 21 | {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, |
| 22 | {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, | 22 | {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, |
| 23 | {60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0 | 23 | {60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, |
| 24 | {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+ | 24 | {99, nullptr, "DebugActivateOpenContextRetention"}, |
| 25 | {100, nullptr, "GetUserRegistrationNotifier"}, | 25 | {100, nullptr, "GetUserRegistrationNotifier"}, |
| 26 | {101, nullptr, "GetUserStateChangeNotifier"}, | 26 | {101, nullptr, "GetUserStateChangeNotifier"}, |
| 27 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, | 27 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, |
| 28 | {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, | 28 | {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, |
| 29 | {104, nullptr, "GetProfileUpdateNotifier"}, | 29 | {104, nullptr, "GetProfileUpdateNotifier"}, |
| 30 | {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+ | 30 | {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, |
| 31 | {106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+ | 31 | {106, nullptr, "GetProfileSyncNotifier"}, |
| 32 | {110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"}, | 32 | {110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"}, |
| 33 | {111, nullptr, "ClearSaveDataThumbnail"}, | 33 | {111, nullptr, "ClearSaveDataThumbnail"}, |
| 34 | {112, nullptr, "LoadSaveDataThumbnail"}, | 34 | {112, nullptr, "LoadSaveDataThumbnail"}, |
| 35 | {113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+ | 35 | {113, nullptr, "GetSaveDataThumbnailExistence"}, |
| 36 | {120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+ | 36 | {120, nullptr, "ListOpenUsersInApplication"}, |
| 37 | {130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+ | 37 | {130, nullptr, "ActivateOpenContextRetention"}, |
| 38 | {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+ | 38 | {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"}, |
| 39 | {150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+ | 39 | {150, nullptr, "AuthenticateApplicationAsync"}, |
| 40 | {190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0 | 40 | {151, nullptr, "Unknown151"}, |
| 41 | {191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+ | 41 | {152, nullptr, "Unknown152"}, |
| 42 | {997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+ | 42 | {190, nullptr, "GetUserLastOpenedApplication"}, |
| 43 | {191, nullptr, "ActivateOpenContextHolder"}, | ||
| 44 | {997, nullptr, "DebugInvalidateTokenCacheForUser"}, | ||
| 43 | {998, nullptr, "DebugSetUserStateClose"}, | 45 | {998, nullptr, "DebugSetUserStateClose"}, |
| 44 | {999, nullptr, "DebugSetUserStateOpen"}, | 46 | {999, nullptr, "DebugSetUserStateOpen"}, |
| 45 | }; | 47 | }; |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index d91237cba..4374487a3 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -231,6 +231,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_) | |||
| 231 | {10, nullptr, "PerformSystemButtonPressing"}, | 231 | {10, nullptr, "PerformSystemButtonPressing"}, |
| 232 | {20, nullptr, "InvalidateTransitionLayer"}, | 232 | {20, nullptr, "InvalidateTransitionLayer"}, |
| 233 | {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, | 233 | {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, |
| 234 | {31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"}, | ||
| 234 | {40, nullptr, "GetAppletResourceUsageInfo"}, | 235 | {40, nullptr, "GetAppletResourceUsageInfo"}, |
| 235 | {100, nullptr, "SetCpuBoostModeForApplet"}, | 236 | {100, nullptr, "SetCpuBoostModeForApplet"}, |
| 236 | {101, nullptr, "CancelCpuBoostModeForApplet"}, | 237 | {101, nullptr, "CancelCpuBoostModeForApplet"}, |
| @@ -242,6 +243,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_) | |||
| 242 | {130, nullptr, "FriendInvitationSetApplicationParameter"}, | 243 | {130, nullptr, "FriendInvitationSetApplicationParameter"}, |
| 243 | {131, nullptr, "FriendInvitationClearApplicationParameter"}, | 244 | {131, nullptr, "FriendInvitationClearApplicationParameter"}, |
| 244 | {132, nullptr, "FriendInvitationPushApplicationParameter"}, | 245 | {132, nullptr, "FriendInvitationPushApplicationParameter"}, |
| 246 | {900, nullptr, "GetGrcProcessLaunchedSystemEvent"}, | ||
| 245 | }; | 247 | }; |
| 246 | // clang-format on | 248 | // clang-format on |
| 247 | 249 | ||
| @@ -297,6 +299,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv | |||
| 297 | {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"}, | 299 | {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"}, |
| 298 | {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"}, | 300 | {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"}, |
| 299 | {110, nullptr, "SetApplicationAlbumUserData"}, | 301 | {110, nullptr, "SetApplicationAlbumUserData"}, |
| 302 | {120, nullptr, "SaveCurrentScreenshot"}, | ||
| 300 | {1000, nullptr, "GetDebugStorageChannel"}, | 303 | {1000, nullptr, "GetDebugStorageChannel"}, |
| 301 | }; | 304 | }; |
| 302 | // clang-format on | 305 | // clang-format on |
| @@ -645,6 +648,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, | |||
| 645 | {11, nullptr, "ReleaseSleepLock"}, | 648 | {11, nullptr, "ReleaseSleepLock"}, |
| 646 | {12, nullptr, "ReleaseSleepLockTransiently"}, | 649 | {12, nullptr, "ReleaseSleepLockTransiently"}, |
| 647 | {13, nullptr, "GetAcquiredSleepLockEvent"}, | 650 | {13, nullptr, "GetAcquiredSleepLockEvent"}, |
| 651 | {14, nullptr, "GetWakeupCount"}, | ||
| 648 | {20, nullptr, "PushToGeneralChannel"}, | 652 | {20, nullptr, "PushToGeneralChannel"}, |
| 649 | {30, nullptr, "GetHomeButtonReaderLockAccessor"}, | 653 | {30, nullptr, "GetHomeButtonReaderLockAccessor"}, |
| 650 | {31, nullptr, "GetReaderLockAccessorEx"}, | 654 | {31, nullptr, "GetReaderLockAccessorEx"}, |
| @@ -656,6 +660,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, | |||
| 656 | {53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"}, | 660 | {53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"}, |
| 657 | {54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"}, | 661 | {54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"}, |
| 658 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, | 662 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, |
| 663 | {59, nullptr, "SetVrPositionForDebug"}, | ||
| 659 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, | 664 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, |
| 660 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, | 665 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, |
| 661 | {62, nullptr, "GetHdcpAuthenticationState"}, | 666 | {62, nullptr, "GetHdcpAuthenticationState"}, |
| @@ -664,14 +669,21 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, | |||
| 664 | {65, nullptr, "GetApplicationIdByContentActionName"}, | 669 | {65, nullptr, "GetApplicationIdByContentActionName"}, |
| 665 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, | 670 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, |
| 666 | {67, nullptr, "CancelCpuBoostMode"}, | 671 | {67, nullptr, "CancelCpuBoostMode"}, |
| 672 | {68, nullptr, "GetBuiltInDisplayType"}, | ||
| 667 | {80, nullptr, "PerformSystemButtonPressingIfInFocus"}, | 673 | {80, nullptr, "PerformSystemButtonPressingIfInFocus"}, |
| 668 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, | 674 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, |
| 669 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, | 675 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, |
| 670 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, | 676 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, |
| 677 | {110, nullptr, "OpenMyGpuErrorHandler"}, | ||
| 671 | {200, nullptr, "GetOperationModeSystemInfo"}, | 678 | {200, nullptr, "GetOperationModeSystemInfo"}, |
| 672 | {300, nullptr, "GetSettingsPlatformRegion"}, | 679 | {300, nullptr, "GetSettingsPlatformRegion"}, |
| 673 | {400, nullptr, "ActivateMigrationService"}, | 680 | {400, nullptr, "ActivateMigrationService"}, |
| 674 | {401, nullptr, "DeactivateMigrationService"}, | 681 | {401, nullptr, "DeactivateMigrationService"}, |
| 682 | {500, nullptr, "DisableSleepTillShutdown"}, | ||
| 683 | {501, nullptr, "SuppressDisablingSleepTemporarily"}, | ||
| 684 | {502, nullptr, "IsSleepEnabled"}, | ||
| 685 | {503, nullptr, "IsDisablingSleepSuppressed"}, | ||
| 686 | {900, nullptr, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, | ||
| 675 | }; | 687 | }; |
| 676 | // clang-format on | 688 | // clang-format on |
| 677 | 689 | ||
| @@ -1203,11 +1215,14 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1203 | {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"}, | 1215 | {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"}, |
| 1204 | {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"}, | 1216 | {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"}, |
| 1205 | {27, nullptr, "CreateCacheStorage"}, | 1217 | {27, nullptr, "CreateCacheStorage"}, |
| 1218 | {28, nullptr, "GetSaveDataSizeMax"}, | ||
| 1219 | {29, nullptr, "GetCacheStorageMax"}, | ||
| 1206 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, | 1220 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, |
| 1207 | {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"}, | 1221 | {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"}, |
| 1208 | {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"}, | 1222 | {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"}, |
| 1209 | {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"}, | 1223 | {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"}, |
| 1210 | {34, nullptr, "SelectApplicationLicense"}, | 1224 | {34, nullptr, "SelectApplicationLicense"}, |
| 1225 | {35, nullptr, "GetDeviceSaveDataSizeMax"}, | ||
| 1211 | {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, | 1226 | {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, |
| 1212 | {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"}, | 1227 | {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"}, |
| 1213 | {60, nullptr, "SetMediaPlaybackStateForApplication"}, | 1228 | {60, nullptr, "SetMediaPlaybackStateForApplication"}, |
| @@ -1231,6 +1246,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1231 | {123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"}, | 1246 | {123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"}, |
| 1232 | {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | 1247 | {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, |
| 1233 | {130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"}, | 1248 | {130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"}, |
| 1249 | {131, nullptr, "SetDelayTimeToAbortOnGpuError"}, | ||
| 1234 | {140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"}, | 1250 | {140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"}, |
| 1235 | {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"}, | 1251 | {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"}, |
| 1236 | {150, nullptr, "GetNotificationStorageChannelEvent"}, | 1252 | {150, nullptr, "GetNotificationStorageChannelEvent"}, |
| @@ -1239,6 +1255,8 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1239 | {170, nullptr, "SetHdcpAuthenticationActivated"}, | 1255 | {170, nullptr, "SetHdcpAuthenticationActivated"}, |
| 1240 | {180, nullptr, "GetLaunchRequiredVersion"}, | 1256 | {180, nullptr, "GetLaunchRequiredVersion"}, |
| 1241 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, | 1257 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, |
| 1258 | {190, nullptr, "SendServerMaintenanceOverlayNotification"}, | ||
| 1259 | {200, nullptr, "GetLastApplicationExitReason"}, | ||
| 1242 | {500, nullptr, "StartContinuousRecordingFlushForDebug"}, | 1260 | {500, nullptr, "StartContinuousRecordingFlushForDebug"}, |
| 1243 | {1000, nullptr, "CreateMovieMaker"}, | 1261 | {1000, nullptr, "CreateMovieMaker"}, |
| 1244 | {1001, nullptr, "PrepareForJit"}, | 1262 | {1001, nullptr, "PrepareForJit"}, |
| @@ -1705,9 +1723,12 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) | |||
| 1705 | {21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"}, | 1723 | {21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"}, |
| 1706 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, | 1724 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, |
| 1707 | {31, nullptr, "GetWriterLockAccessorEx"}, | 1725 | {31, nullptr, "GetWriterLockAccessorEx"}, |
| 1726 | {40, nullptr, "IsSleepEnabled"}, | ||
| 1727 | {41, nullptr, "IsRebootEnabled"}, | ||
| 1708 | {100, nullptr, "PopRequestLaunchApplicationForDebug"}, | 1728 | {100, nullptr, "PopRequestLaunchApplicationForDebug"}, |
| 1709 | {110, nullptr, "IsForceTerminateApplicationDisabledForDebug"}, | 1729 | {110, nullptr, "IsForceTerminateApplicationDisabledForDebug"}, |
| 1710 | {200, nullptr, "LaunchDevMenu"}, | 1730 | {200, nullptr, "LaunchDevMenu"}, |
| 1731 | {1000, nullptr, "SetLastApplicationExitReason"}, | ||
| 1711 | }; | 1732 | }; |
| 1712 | // clang-format on | 1733 | // clang-format on |
| 1713 | 1734 | ||
| @@ -1751,6 +1772,7 @@ IGlobalStateController::IGlobalStateController(Core::System& system_) | |||
| 1751 | {13, nullptr, "UpdateDefaultDisplayResolution"}, | 1772 | {13, nullptr, "UpdateDefaultDisplayResolution"}, |
| 1752 | {14, nullptr, "ShouldSleepOnBoot"}, | 1773 | {14, nullptr, "ShouldSleepOnBoot"}, |
| 1753 | {15, nullptr, "GetHdcpAuthenticationFailedEvent"}, | 1774 | {15, nullptr, "GetHdcpAuthenticationFailedEvent"}, |
| 1775 | {30, nullptr, "OpenCradleFirmwareUpdater"}, | ||
| 1754 | }; | 1776 | }; |
| 1755 | // clang-format on | 1777 | // clang-format on |
| 1756 | 1778 | ||
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 8d657c0bf..0f51e5871 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -118,8 +118,10 @@ AOC_U::AOC_U(Core::System& system_) | |||
| 118 | {7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"}, | 118 | {7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"}, |
| 119 | {8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"}, | 119 | {8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"}, |
| 120 | {9, nullptr, "GetAddOnContentLostErrorCode"}, | 120 | {9, nullptr, "GetAddOnContentLostErrorCode"}, |
| 121 | {10, nullptr, "GetAddOnContentListChangedEventWithProcessId"}, | ||
| 121 | {100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"}, | 122 | {100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"}, |
| 122 | {101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"}, | 123 | {101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"}, |
| 124 | {110, nullptr, "CreateContentsServiceManager"}, | ||
| 123 | }; | 125 | }; |
| 124 | // clang-format on | 126 | // clang-format on |
| 125 | 127 | ||
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp index 79c3aa920..10acaad19 100644 --- a/src/core/hle/service/audio/audin_a.cpp +++ b/src/core/hle/service/audio/audin_a.cpp | |||
| @@ -9,10 +9,10 @@ namespace Service::Audio { | |||
| 9 | AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} { | 9 | AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} { |
| 10 | // clang-format off | 10 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 12 | {0, nullptr, "RequestSuspendAudioIns"}, | 12 | {0, nullptr, "RequestSuspend"}, |
| 13 | {1, nullptr, "RequestResumeAudioIns"}, | 13 | {1, nullptr, "RequestResume"}, |
| 14 | {2, nullptr, "GetAudioInsProcessMasterVolume"}, | 14 | {2, nullptr, "GetProcessMasterVolume"}, |
| 15 | {3, nullptr, "SetAudioInsProcessMasterVolume"}, | 15 | {3, nullptr, "SetProcessMasterVolume"}, |
| 16 | }; | 16 | }; |
| 17 | // clang-format on | 17 | // clang-format on |
| 18 | 18 | ||
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 26a6deddf..ecd05e4a6 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp | |||
| @@ -15,19 +15,19 @@ public: | |||
| 15 | // clang-format off | 15 | // clang-format off |
| 16 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 17 | {0, nullptr, "GetAudioInState"}, | 17 | {0, nullptr, "GetAudioInState"}, |
| 18 | {1, nullptr, "StartAudioIn"}, | 18 | {1, nullptr, "Start"}, |
| 19 | {2, nullptr, "StopAudioIn"}, | 19 | {2, nullptr, "Stop"}, |
| 20 | {3, nullptr, "AppendAudioInBuffer"}, | 20 | {3, nullptr, "AppendAudioInBuffer"}, |
| 21 | {4, nullptr, "RegisterBufferEvent"}, | 21 | {4, nullptr, "RegisterBufferEvent"}, |
| 22 | {5, nullptr, "GetReleasedAudioInBuffer"}, | 22 | {5, nullptr, "GetReleasedAudioInBuffer"}, |
| 23 | {6, nullptr, "ContainsAudioInBuffer"}, | 23 | {6, nullptr, "ContainsAudioInBuffer"}, |
| 24 | {7, nullptr, "AppendAudioInBufferWithUserEvent"}, | 24 | {7, nullptr, "AppendUacInBuffer"}, |
| 25 | {8, nullptr, "AppendAudioInBufferAuto"}, | 25 | {8, nullptr, "AppendAudioInBufferAuto"}, |
| 26 | {9, nullptr, "GetReleasedAudioInBufferAuto"}, | 26 | {9, nullptr, "GetReleasedAudioInBuffersAuto"}, |
| 27 | {10, nullptr, "AppendAudioInBufferWithUserEventAuto"}, | 27 | {10, nullptr, "AppendUacInBufferAuto"}, |
| 28 | {11, nullptr, "GetAudioInBufferCount"}, | 28 | {11, nullptr, "GetAudioInBufferCount"}, |
| 29 | {12, nullptr, "SetAudioInDeviceGain"}, | 29 | {12, nullptr, "SetDeviceGain"}, |
| 30 | {13, nullptr, "GetAudioInDeviceGain"}, | 30 | {13, nullptr, "GetDeviceGain"}, |
| 31 | {14, nullptr, "FlushAudioInBuffers"}, | 31 | {14, nullptr, "FlushAudioInBuffers"}, |
| 32 | }; | 32 | }; |
| 33 | // clang-format on | 33 | // clang-format on |
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp index 19825fd5d..3ee522b50 100644 --- a/src/core/hle/service/audio/audout_a.cpp +++ b/src/core/hle/service/audio/audout_a.cpp | |||
| @@ -9,12 +9,12 @@ namespace Service::Audio { | |||
| 9 | AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} { | 9 | AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} { |
| 10 | // clang-format off | 10 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 12 | {0, nullptr, "RequestSuspendAudioOuts"}, | 12 | {0, nullptr, "RequestSuspend"}, |
| 13 | {1, nullptr, "RequestResumeAudioOuts"}, | 13 | {1, nullptr, "RequestResume"}, |
| 14 | {2, nullptr, "GetAudioOutsProcessMasterVolume"}, | 14 | {2, nullptr, "GetProcessMasterVolume"}, |
| 15 | {3, nullptr, "SetAudioOutsProcessMasterVolume"}, | 15 | {3, nullptr, "SetProcessMasterVolume"}, |
| 16 | {4, nullptr, "GetAudioOutsProcessRecordVolume"}, | 16 | {4, nullptr, "GetProcessRecordVolume"}, |
| 17 | {5, nullptr, "SetAudioOutsProcessRecordVolume"}, | 17 | {5, nullptr, "SetProcessRecordVolume"}, |
| 18 | }; | 18 | }; |
| 19 | // clang-format on | 19 | // clang-format on |
| 20 | 20 | ||
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 5ed9cb20e..5f51fca9a 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -49,11 +49,11 @@ public: | |||
| 49 | // clang-format off | 49 | // clang-format off |
| 50 | static const FunctionInfo functions[] = { | 50 | static const FunctionInfo functions[] = { |
| 51 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, | 51 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, |
| 52 | {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, | 52 | {1, &IAudioOut::StartAudioOut, "Start"}, |
| 53 | {2, &IAudioOut::StopAudioOut, "StopAudioOut"}, | 53 | {2, &IAudioOut::StopAudioOut, "Stop"}, |
| 54 | {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"}, | 54 | {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"}, |
| 55 | {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, | 55 | {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, |
| 56 | {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"}, | 56 | {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffers"}, |
| 57 | {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"}, | 57 | {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"}, |
| 58 | {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"}, | 58 | {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"}, |
| 59 | {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, | 59 | {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, |
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp index c5ab7cad4..70fc17ae2 100644 --- a/src/core/hle/service/audio/audrec_a.cpp +++ b/src/core/hle/service/audio/audrec_a.cpp | |||
| @@ -9,8 +9,8 @@ namespace Service::Audio { | |||
| 9 | AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} { | 9 | AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} { |
| 10 | // clang-format off | 10 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 12 | {0, nullptr, "RequestSuspendFinalOutputRecorders"}, | 12 | {0, nullptr, "RequestSuspend"}, |
| 13 | {1, nullptr, "RequestResumeFinalOutputRecorders"}, | 13 | {1, nullptr, "RequestResume"}, |
| 14 | }; | 14 | }; |
| 15 | // clang-format on | 15 | // clang-format on |
| 16 | 16 | ||
diff --git a/src/core/hle/service/audio/audrec_u.cpp b/src/core/hle/service/audio/audrec_u.cpp index eb5c63c62..74a65ccff 100644 --- a/src/core/hle/service/audio/audrec_u.cpp +++ b/src/core/hle/service/audio/audrec_u.cpp | |||
| @@ -13,16 +13,17 @@ public: | |||
| 13 | // clang-format off | 13 | // clang-format off |
| 14 | static const FunctionInfo functions[] = { | 14 | static const FunctionInfo functions[] = { |
| 15 | {0, nullptr, "GetFinalOutputRecorderState"}, | 15 | {0, nullptr, "GetFinalOutputRecorderState"}, |
| 16 | {1, nullptr, "StartFinalOutputRecorder"}, | 16 | {1, nullptr, "Start"}, |
| 17 | {2, nullptr, "StopFinalOutputRecorder"}, | 17 | {2, nullptr, "Stop"}, |
| 18 | {3, nullptr, "AppendFinalOutputRecorderBuffer"}, | 18 | {3, nullptr, "AppendFinalOutputRecorderBuffer"}, |
| 19 | {4, nullptr, "RegisterBufferEvent"}, | 19 | {4, nullptr, "RegisterBufferEvent"}, |
| 20 | {5, nullptr, "GetReleasedFinalOutputRecorderBuffer"}, | 20 | {5, nullptr, "GetReleasedFinalOutputRecorderBuffers"}, |
| 21 | {6, nullptr, "ContainsFinalOutputRecorderBuffer"}, | 21 | {6, nullptr, "ContainsFinalOutputRecorderBuffer"}, |
| 22 | {7, nullptr, "GetFinalOutputRecorderBufferEndTime"}, | 22 | {7, nullptr, "GetFinalOutputRecorderBufferEndTime"}, |
| 23 | {8, nullptr, "AppendFinalOutputRecorderBufferAuto"}, | 23 | {8, nullptr, "AppendFinalOutputRecorderBufferAuto"}, |
| 24 | {9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"}, | 24 | {9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"}, |
| 25 | {10, nullptr, "FlushFinalOutputRecorderBuffers"}, | 25 | {10, nullptr, "FlushFinalOutputRecorderBuffers"}, |
| 26 | {11, nullptr, "AttachWorkBuffer"}, | ||
| 26 | }; | 27 | }; |
| 27 | // clang-format on | 28 | // clang-format on |
| 28 | 29 | ||
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp index 5e9f866f0..cf8c34a15 100644 --- a/src/core/hle/service/audio/audren_a.cpp +++ b/src/core/hle/service/audio/audren_a.cpp | |||
| @@ -9,14 +9,14 @@ namespace Service::Audio { | |||
| 9 | AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} { | 9 | AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} { |
| 10 | // clang-format off | 10 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 12 | {0, nullptr, "RequestSuspendAudioRenderers"}, | 12 | {0, nullptr, "RequestSuspend"}, |
| 13 | {1, nullptr, "RequestResumeAudioRenderers"}, | 13 | {1, nullptr, "RequestResume"}, |
| 14 | {2, nullptr, "GetAudioRenderersProcessMasterVolume"}, | 14 | {2, nullptr, "GetProcessMasterVolume"}, |
| 15 | {3, nullptr, "SetAudioRenderersProcessMasterVolume"}, | 15 | {3, nullptr, "SetProcessMasterVolume"}, |
| 16 | {4, nullptr, "RegisterAppletResourceUserId"}, | 16 | {4, nullptr, "RegisterAppletResourceUserId"}, |
| 17 | {5, nullptr, "UnregisterAppletResourceUserId"}, | 17 | {5, nullptr, "UnregisterAppletResourceUserId"}, |
| 18 | {6, nullptr, "GetAudioRenderersProcessRecordVolume"}, | 18 | {6, nullptr, "GetProcessRecordVolume"}, |
| 19 | {7, nullptr, "SetAudioRenderersProcessRecordVolume"}, | 19 | {7, nullptr, "SetProcessRecordVolume"}, |
| 20 | }; | 20 | }; |
| 21 | // clang-format on | 21 | // clang-format on |
| 22 | 22 | ||
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index b2b2ffc5a..572be8e00 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -332,9 +332,9 @@ AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"} | |||
| 332 | // clang-format off | 332 | // clang-format off |
| 333 | static const FunctionInfo functions[] = { | 333 | static const FunctionInfo functions[] = { |
| 334 | {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, | 334 | {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, |
| 335 | {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"}, | 335 | {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetWorkBufferSize"}, |
| 336 | {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"}, | 336 | {2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"}, |
| 337 | {3, &AudRenU::OpenAudioRendererAuto, "OpenAudioRendererAuto"}, | 337 | {3, &AudRenU::OpenAudioRendererForManualExecution, "OpenAudioRendererForManualExecution"}, |
| 338 | {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, | 338 | {4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"}, |
| 339 | }; | 339 | }; |
| 340 | // clang-format on | 340 | // clang-format on |
| @@ -665,7 +665,7 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { | |||
| 665 | rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1')); | 665 | rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1')); |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) { | 668 | void AudRenU::OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx) { |
| 669 | LOG_DEBUG(Service_Audio, "called"); | 669 | LOG_DEBUG(Service_Audio, "called"); |
| 670 | 670 | ||
| 671 | OpenAudioRendererImpl(ctx); | 671 | OpenAudioRendererImpl(ctx); |
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index d693dc406..37e8b4716 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h | |||
| @@ -25,7 +25,7 @@ private: | |||
| 25 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); | 25 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); |
| 26 | void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); | 26 | void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); |
| 27 | void GetAudioDeviceService(Kernel::HLERequestContext& ctx); | 27 | void GetAudioDeviceService(Kernel::HLERequestContext& ctx); |
| 28 | void OpenAudioRendererAuto(Kernel::HLERequestContext& ctx); | 28 | void OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx); |
| 29 | void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); | 29 | void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); |
| 30 | 30 | ||
| 31 | void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); | 31 | void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/audio/codecctl.cpp b/src/core/hle/service/audio/codecctl.cpp index 94afec1b6..42961d908 100644 --- a/src/core/hle/service/audio/codecctl.cpp +++ b/src/core/hle/service/audio/codecctl.cpp | |||
| @@ -8,19 +8,19 @@ namespace Service::Audio { | |||
| 8 | 8 | ||
| 9 | CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} { | 9 | CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} { |
| 10 | static const FunctionInfo functions[] = { | 10 | static const FunctionInfo functions[] = { |
| 11 | {0, nullptr, "InitializeCodecController"}, | 11 | {0, nullptr, "Initialize"}, |
| 12 | {1, nullptr, "FinalizeCodecController"}, | 12 | {1, nullptr, "Finalize"}, |
| 13 | {2, nullptr, "SleepCodecController"}, | 13 | {2, nullptr, "Sleep"}, |
| 14 | {3, nullptr, "WakeCodecController"}, | 14 | {3, nullptr, "Wake"}, |
| 15 | {4, nullptr, "SetCodecVolume"}, | 15 | {4, nullptr, "SetVolume"}, |
| 16 | {5, nullptr, "GetCodecVolumeMax"}, | 16 | {5, nullptr, "GetVolumeMax"}, |
| 17 | {6, nullptr, "GetCodecVolumeMin"}, | 17 | {6, nullptr, "GetVolumeMin"}, |
| 18 | {7, nullptr, "SetCodecActiveTarget"}, | 18 | {7, nullptr, "SetActiveTarget"}, |
| 19 | {8, nullptr, "GetCodecActiveTarget"}, | 19 | {8, nullptr, "GetActiveTarget"}, |
| 20 | {9, nullptr, "BindCodecHeadphoneMicJackInterrupt"}, | 20 | {9, nullptr, "BindHeadphoneMicJackInterrupt"}, |
| 21 | {10, nullptr, "IsCodecHeadphoneMicJackInserted"}, | 21 | {10, nullptr, "IsHeadphoneMicJackInserted"}, |
| 22 | {11, nullptr, "ClearCodecHeadphoneMicJackInterrupt"}, | 22 | {11, nullptr, "ClearHeadphoneMicJackInterrupt"}, |
| 23 | {12, nullptr, "IsCodecDeviceRequested"}, | 23 | {12, nullptr, "IsRequested"}, |
| 24 | }; | 24 | }; |
| 25 | RegisterHandlers(functions); | 25 | RegisterHandlers(functions); |
| 26 | } | 26 | } |
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index ea3414fd2..19c578b3a 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp | |||
| @@ -297,6 +297,10 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} { | |||
| 297 | {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, | 297 | {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, |
| 298 | {2, nullptr, "OpenOpusDecoderForMultiStream"}, | 298 | {2, nullptr, "OpenOpusDecoderForMultiStream"}, |
| 299 | {3, nullptr, "GetWorkBufferSizeForMultiStream"}, | 299 | {3, nullptr, "GetWorkBufferSizeForMultiStream"}, |
| 300 | {4, nullptr, "OpenHardwareOpusDecoderEx"}, | ||
| 301 | {5, nullptr, "GetWorkBufferSizeEx"}, | ||
| 302 | {6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"}, | ||
| 303 | {7, nullptr, "GetWorkBufferSizeForMultiStreamEx"}, | ||
| 300 | }; | 304 | }; |
| 301 | RegisterHandlers(functions); | 305 | RegisterHandlers(functions); |
| 302 | } | 306 | } |
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index 503109fdd..b68e2c345 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp | |||
| @@ -155,10 +155,12 @@ public: | |||
| 155 | {30210, nullptr, "SetDeliveryTaskTimer"}, | 155 | {30210, nullptr, "SetDeliveryTaskTimer"}, |
| 156 | {30300, nullptr, "RegisterSystemApplicationDeliveryTasks"}, | 156 | {30300, nullptr, "RegisterSystemApplicationDeliveryTasks"}, |
| 157 | {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, | 157 | {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, |
| 158 | {90101, nullptr, "Unknown90101"}, | ||
| 158 | {90200, nullptr, "GetDeliveryList"}, | 159 | {90200, nullptr, "GetDeliveryList"}, |
| 159 | {90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"}, | 160 | {90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"}, |
| 160 | {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"}, | 161 | {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"}, |
| 161 | {90300, nullptr, "GetPushNotificationLog"}, | 162 | {90300, nullptr, "GetPushNotificationLog"}, |
| 163 | {90301, nullptr, "Unknown90301"}, | ||
| 162 | }; | 164 | }; |
| 163 | // clang-format on | 165 | // clang-format on |
| 164 | RegisterHandlers(functions); | 166 | RegisterHandlers(functions); |
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp index e4630320e..78e01d8d8 100644 --- a/src/core/hle/service/bpc/bpc.cpp +++ b/src/core/hle/service/bpc/bpc.cpp | |||
| @@ -29,8 +29,8 @@ public: | |||
| 29 | {11, nullptr, "CreateWakeupTimerEx"}, | 29 | {11, nullptr, "CreateWakeupTimerEx"}, |
| 30 | {12, nullptr, "GetLastEnabledWakeupTimerType"}, | 30 | {12, nullptr, "GetLastEnabledWakeupTimerType"}, |
| 31 | {13, nullptr, "CleanAllWakeupTimers"}, | 31 | {13, nullptr, "CleanAllWakeupTimers"}, |
| 32 | {14, nullptr, "Unknown"}, | 32 | {14, nullptr, "GetPowerButton"}, |
| 33 | {15, nullptr, "Unknown2"}, | 33 | {15, nullptr, "SetEnableWakeupTimer"}, |
| 34 | }; | 34 | }; |
| 35 | // clang-format on | 35 | // clang-format on |
| 36 | 36 | ||
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 17a2ac899..af3a5842d 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -156,6 +156,25 @@ public: | |||
| 156 | {97, nullptr, "RegisterBleHidEvent"}, | 156 | {97, nullptr, "RegisterBleHidEvent"}, |
| 157 | {98, nullptr, "SetBleScanParameter"}, | 157 | {98, nullptr, "SetBleScanParameter"}, |
| 158 | {99, nullptr, "MoveToSecondaryPiconet"}, | 158 | {99, nullptr, "MoveToSecondaryPiconet"}, |
| 159 | {100, nullptr, "IsBluetoothEnabled"}, | ||
| 160 | {128, nullptr, "AcquireAudioEvent"}, | ||
| 161 | {129, nullptr, "GetAudioEventInfo"}, | ||
| 162 | {130, nullptr, "OpenAudioConnection"}, | ||
| 163 | {131, nullptr, "CloseAudioConnection"}, | ||
| 164 | {132, nullptr, "OpenAudioOut"}, | ||
| 165 | {133, nullptr, "CloseAudioOut"}, | ||
| 166 | {134, nullptr, "AcquireAudioOutStateChangedEvent"}, | ||
| 167 | {135, nullptr, "StartAudioOut"}, | ||
| 168 | {136, nullptr, "StopAudioOut"}, | ||
| 169 | {137, nullptr, "GetAudioOutState"}, | ||
| 170 | {138, nullptr, "GetAudioOutFeedingCodec"}, | ||
| 171 | {139, nullptr, "GetAudioOutFeedingParameter"}, | ||
| 172 | {140, nullptr, "AcquireAudioOutBufferAvailableEvent"}, | ||
| 173 | {141, nullptr, "SendAudioData"}, | ||
| 174 | {142, nullptr, "AcquireAudioControlInputStateChangedEvent"}, | ||
| 175 | {143, nullptr, "GetAudioControlInputState"}, | ||
| 176 | {144, nullptr, "AcquireAudioConnectionStateChangedEvent"}, | ||
| 177 | {145, nullptr, "GetConnectedAudioDevice"}, | ||
| 159 | {256, nullptr, "IsManufacturingMode"}, | 178 | {256, nullptr, "IsManufacturingMode"}, |
| 160 | {257, nullptr, "EmulateBluetoothCrash"}, | 179 | {257, nullptr, "EmulateBluetoothCrash"}, |
| 161 | {258, nullptr, "GetBleChannelMap"}, | 180 | {258, nullptr, "GetBleChannelMap"}, |
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 9cf2ee92a..d1ebc2388 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -223,6 +223,7 @@ public: | |||
| 223 | {10, nullptr, "GetGattClientDisconnectionReason"}, | 223 | {10, nullptr, "GetGattClientDisconnectionReason"}, |
| 224 | {11, nullptr, "GetBleConnectionParameter"}, | 224 | {11, nullptr, "GetBleConnectionParameter"}, |
| 225 | {12, nullptr, "GetBleConnectionParameterRequest"}, | 225 | {12, nullptr, "GetBleConnectionParameterRequest"}, |
| 226 | {13, nullptr, "Unknown13"}, | ||
| 226 | }; | 227 | }; |
| 227 | // clang-format on | 228 | // clang-format on |
| 228 | 229 | ||
diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp index 1fe4f0e14..6220e9f77 100644 --- a/src/core/hle/service/caps/caps_a.cpp +++ b/src/core/hle/service/caps/caps_a.cpp | |||
| @@ -49,6 +49,7 @@ CAPS_A::CAPS_A(Core::System& system_) : ServiceFramework{system_, "caps:a"} { | |||
| 49 | {16, nullptr, "GetAlbumMountResult"}, | 49 | {16, nullptr, "GetAlbumMountResult"}, |
| 50 | {17, nullptr, "GetAlbumUsage16"}, | 50 | {17, nullptr, "GetAlbumUsage16"}, |
| 51 | {18, nullptr, "Unknown18"}, | 51 | {18, nullptr, "Unknown18"}, |
| 52 | {19, nullptr, "Unknown19"}, | ||
| 52 | {100, nullptr, "GetAlbumFileCountEx0"}, | 53 | {100, nullptr, "GetAlbumFileCountEx0"}, |
| 53 | {101, nullptr, "GetAlbumFileListEx0"}, | 54 | {101, nullptr, "GetAlbumFileListEx0"}, |
| 54 | {202, nullptr, "SaveEditedScreenShot"}, | 55 | {202, nullptr, "SaveEditedScreenShot"}, |
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp index 842316a2e..10b8d54b1 100644 --- a/src/core/hle/service/caps/caps_u.cpp +++ b/src/core/hle/service/caps/caps_u.cpp | |||
| @@ -43,6 +43,7 @@ CAPS_U::CAPS_U(Core::System& system_) : ServiceFramework{system_, "caps:u"} { | |||
| 43 | {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"}, | 43 | {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"}, |
| 44 | {142, &CAPS_U::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"}, | 44 | {142, &CAPS_U::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"}, |
| 45 | {143, nullptr, "GetAlbumFileList4AaeUidAruid"}, | 45 | {143, nullptr, "GetAlbumFileList4AaeUidAruid"}, |
| 46 | {144, nullptr, "GetAllAlbumFileList3AaeAruid"}, | ||
| 46 | {60002, nullptr, "OpenAccessorSessionForApplication"}, | 47 | {60002, nullptr, "OpenAccessorSessionForApplication"}, |
| 47 | }; | 48 | }; |
| 48 | // clang-format on | 49 | // clang-format on |
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp index 4924c61c3..c767926a4 100644 --- a/src/core/hle/service/erpt/erpt.cpp +++ b/src/core/hle/service/erpt/erpt.cpp | |||
| @@ -16,7 +16,7 @@ public: | |||
| 16 | // clang-format off | 16 | // clang-format off |
| 17 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 18 | {0, nullptr, "SubmitContext"}, | 18 | {0, nullptr, "SubmitContext"}, |
| 19 | {1, nullptr, "CreateReport"}, | 19 | {1, nullptr, "CreateReportV0"}, |
| 20 | {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, | 20 | {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, |
| 21 | {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, | 21 | {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, |
| 22 | {4, nullptr, "UpdatePowerOnTime"}, | 22 | {4, nullptr, "UpdatePowerOnTime"}, |
| @@ -26,6 +26,11 @@ public: | |||
| 26 | {8, nullptr, "ClearApplicationLaunchTime"}, | 26 | {8, nullptr, "ClearApplicationLaunchTime"}, |
| 27 | {9, nullptr, "SubmitAttachment"}, | 27 | {9, nullptr, "SubmitAttachment"}, |
| 28 | {10, nullptr, "CreateReportWithAttachments"}, | 28 | {10, nullptr, "CreateReportWithAttachments"}, |
| 29 | {11, nullptr, "CreateReport"}, | ||
| 30 | {20, nullptr, "RegisterRunningApplet"}, | ||
| 31 | {21, nullptr, "UnregisterRunningApplet"}, | ||
| 32 | {22, nullptr, "UpdateAppletSuspendedDuration"}, | ||
| 33 | {30, nullptr, "InvalidateForcedShutdownDetection"}, | ||
| 29 | }; | 34 | }; |
| 30 | // clang-format on | 35 | // clang-format on |
| 31 | 36 | ||
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 9cc260515..a0215c4d7 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -118,9 +118,13 @@ public: | |||
| 118 | explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) | 118 | explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) |
| 119 | : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) { | 119 | : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) { |
| 120 | static const FunctionInfo functions[] = { | 120 | static const FunctionInfo functions[] = { |
| 121 | {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, | 121 | {0, &IFile::Read, "Read"}, |
| 122 | {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"}, | 122 | {1, &IFile::Write, "Write"}, |
| 123 | {4, &IFile::GetSize, "GetSize"}, {5, nullptr, "OperateRange"}, | 123 | {2, &IFile::Flush, "Flush"}, |
| 124 | {3, &IFile::SetSize, "SetSize"}, | ||
| 125 | {4, &IFile::GetSize, "GetSize"}, | ||
| 126 | {5, nullptr, "OperateRange"}, | ||
| 127 | {6, nullptr, "OperateRangeWithBuffer"}, | ||
| 124 | }; | 128 | }; |
| 125 | RegisterHandlers(functions); | 129 | RegisterHandlers(functions); |
| 126 | } | 130 | } |
| @@ -708,7 +712,10 @@ FSP_SRV::FSP_SRV(Core::System& system_) | |||
| 708 | {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"}, | 712 | {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"}, |
| 709 | {85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"}, | 713 | {85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"}, |
| 710 | {86, nullptr, "OpenSaveDataMover"}, | 714 | {86, nullptr, "OpenSaveDataMover"}, |
| 715 | {87, nullptr, "OpenSaveDataTransferManagerForRepair"}, | ||
| 711 | {100, nullptr, "OpenImageDirectoryFileSystem"}, | 716 | {100, nullptr, "OpenImageDirectoryFileSystem"}, |
| 717 | {101, nullptr, "OpenBaseFileSystem"}, | ||
| 718 | {102, nullptr, "FormatBaseFileSystem"}, | ||
| 712 | {110, nullptr, "OpenContentStorageFileSystem"}, | 719 | {110, nullptr, "OpenContentStorageFileSystem"}, |
| 713 | {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, | 720 | {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, |
| 714 | {130, nullptr, "OpenCustomStorageFileSystem"}, | 721 | {130, nullptr, "OpenCustomStorageFileSystem"}, |
| @@ -764,10 +771,12 @@ FSP_SRV::FSP_SRV(Core::System& system_) | |||
| 764 | {1008, nullptr, "OpenRegisteredUpdatePartition"}, | 771 | {1008, nullptr, "OpenRegisteredUpdatePartition"}, |
| 765 | {1009, nullptr, "GetAndClearMemoryReportInfo"}, | 772 | {1009, nullptr, "GetAndClearMemoryReportInfo"}, |
| 766 | {1010, nullptr, "SetDataStorageRedirectTarget"}, | 773 | {1010, nullptr, "SetDataStorageRedirectTarget"}, |
| 767 | {1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"}, | 774 | {1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"}, |
| 768 | {1012, nullptr, "GetFsStackUsage"}, | 775 | {1012, nullptr, "GetFsStackUsage"}, |
| 769 | {1013, nullptr, "UnsetSaveDataRootPath"}, | 776 | {1013, nullptr, "UnsetSaveDataRootPath"}, |
| 770 | {1014, nullptr, "OutputMultiProgramTagAccessLog"}, | 777 | {1014, nullptr, "OutputMultiProgramTagAccessLog"}, |
| 778 | {1016, nullptr, "FlushAccessLogOnSdCard"}, | ||
| 779 | {1017, nullptr, "OutputApplicationInfoAccessLog"}, | ||
| 771 | {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, | 780 | {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, |
| 772 | {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, | 781 | {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, |
| 773 | {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"}, | 782 | {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"}, |
| @@ -1051,7 +1060,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) { | |||
| 1051 | rb.Push(RESULT_SUCCESS); | 1060 | rb.Push(RESULT_SUCCESS); |
| 1052 | } | 1061 | } |
| 1053 | 1062 | ||
| 1054 | void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) { | 1063 | void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) { |
| 1055 | LOG_DEBUG(Service_FS, "called"); | 1064 | LOG_DEBUG(Service_FS, "called"); |
| 1056 | 1065 | ||
| 1057 | IPC::ResponseBuilder rb{ctx, 4}; | 1066 | IPC::ResponseBuilder rb{ctx, 4}; |
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index 8ed933279..b01b924eb 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h | |||
| @@ -53,7 +53,7 @@ private: | |||
| 53 | void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); | 53 | void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); |
| 54 | void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); | 54 | void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); |
| 55 | void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); | 55 | void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); |
| 56 | void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx); | 56 | void GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx); |
| 57 | void OpenMultiCommitManager(Kernel::HLERequestContext& ctx); | 57 | void OpenMultiCommitManager(Kernel::HLERequestContext& ctx); |
| 58 | 58 | ||
| 59 | FileSystemController& fsc; | 59 | FileSystemController& fsc; |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 0a6621ef2..a35979053 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -38,7 +38,7 @@ public: | |||
| 38 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, | 38 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, |
| 39 | {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"}, | 39 | {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"}, |
| 40 | {10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"}, | 40 | {10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"}, |
| 41 | {10700, nullptr, "GetPlayHistoryRegistrationKey"}, | 41 | {10700, &IFriendService::GetPlayHistoryRegistrationKey, "GetPlayHistoryRegistrationKey"}, |
| 42 | {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, | 42 | {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, |
| 43 | {10702, nullptr, "AddPlayHistory"}, | 43 | {10702, nullptr, "AddPlayHistory"}, |
| 44 | {11000, nullptr, "GetProfileImageUrl"}, | 44 | {11000, nullptr, "GetProfileImageUrl"}, |
| @@ -153,6 +153,18 @@ private: | |||
| 153 | rb.Push(RESULT_SUCCESS); | 153 | rb.Push(RESULT_SUCCESS); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | void GetPlayHistoryRegistrationKey(Kernel::HLERequestContext& ctx) { | ||
| 157 | IPC::RequestParser rp{ctx}; | ||
| 158 | const auto local_play = rp.Pop<bool>(); | ||
| 159 | const auto uuid = rp.PopRaw<Common::UUID>(); | ||
| 160 | |||
| 161 | LOG_WARNING(Service_Friend, "(STUBBED) called local_play={} uuid={}", local_play, | ||
| 162 | uuid.Format()); | ||
| 163 | |||
| 164 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 165 | rb.Push(RESULT_SUCCESS); | ||
| 166 | } | ||
| 167 | |||
| 156 | void GetFriendList(Kernel::HLERequestContext& ctx) { | 168 | void GetFriendList(Kernel::HLERequestContext& ctx) { |
| 157 | IPC::RequestParser rp{ctx}; | 169 | IPC::RequestParser rp{ctx}; |
| 158 | const auto friend_offset = rp.Pop<u32>(); | 170 | const auto friend_offset = rp.Pop<u32>(); |
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp index fc77e7286..322125135 100644 --- a/src/core/hle/service/glue/arp.cpp +++ b/src/core/hle/service/glue/arp.cpp | |||
| @@ -41,6 +41,12 @@ ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_) | |||
| 41 | {1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"}, | 41 | {1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"}, |
| 42 | {2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"}, | 42 | {2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"}, |
| 43 | {3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"}, | 43 | {3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"}, |
| 44 | {4, nullptr, "GetApplicationInstanceUnregistrationNotifier"}, | ||
| 45 | {5, nullptr, "ListApplicationInstanceId"}, | ||
| 46 | {6, nullptr, "GetMicroApplicationInstanceId"}, | ||
| 47 | {7, nullptr, "GetApplicationCertificate"}, | ||
| 48 | {9998, nullptr, "GetPreomiaApplicationLaunchProperty"}, | ||
| 49 | {9999, nullptr, "GetPreomiaApplicationControlProperty"}, | ||
| 44 | }; | 50 | }; |
| 45 | // clang-format on | 51 | // clang-format on |
| 46 | 52 | ||
| @@ -243,7 +249,8 @@ ARP_W::ARP_W(Core::System& system_, ARPManager& manager_) | |||
| 243 | // clang-format off | 249 | // clang-format off |
| 244 | static const FunctionInfo functions[] = { | 250 | static const FunctionInfo functions[] = { |
| 245 | {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, | 251 | {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, |
| 246 | {1, &ARP_W::DeleteProperties, "DeleteProperties"}, | 252 | {1, &ARP_W::UnregisterApplicationInstance , "UnregisterApplicationInstance "}, |
| 253 | {2, nullptr, "AcquireUpdater"}, | ||
| 247 | }; | 254 | }; |
| 248 | // clang-format on | 255 | // clang-format on |
| 249 | 256 | ||
| @@ -270,7 +277,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { | |||
| 270 | rb.PushIpcInterface(registrar); | 277 | rb.PushIpcInterface(registrar); |
| 271 | } | 278 | } |
| 272 | 279 | ||
| 273 | void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { | 280 | void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) { |
| 274 | IPC::RequestParser rp{ctx}; | 281 | IPC::RequestParser rp{ctx}; |
| 275 | const auto process_id = rp.PopRaw<u64>(); | 282 | const auto process_id = rp.PopRaw<u64>(); |
| 276 | 283 | ||
diff --git a/src/core/hle/service/glue/arp.h b/src/core/hle/service/glue/arp.h index 34b412e26..0df3c5e1f 100644 --- a/src/core/hle/service/glue/arp.h +++ b/src/core/hle/service/glue/arp.h | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | 32 | ||
| 33 | private: | 33 | private: |
| 34 | void AcquireRegistrar(Kernel::HLERequestContext& ctx); | 34 | void AcquireRegistrar(Kernel::HLERequestContext& ctx); |
| 35 | void DeleteProperties(Kernel::HLERequestContext& ctx); | 35 | void UnregisterApplicationInstance(Kernel::HLERequestContext& ctx); |
| 36 | 36 | ||
| 37 | ARPManager& manager; | 37 | ARPManager& manager; |
| 38 | std::shared_ptr<IRegistrar> registrar; | 38 | std::shared_ptr<IRegistrar> registrar; |
diff --git a/src/core/hle/service/glue/bgtc.cpp b/src/core/hle/service/glue/bgtc.cpp index a478b68e1..daecfff15 100644 --- a/src/core/hle/service/glue/bgtc.cpp +++ b/src/core/hle/service/glue/bgtc.cpp | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/core.h" | ||
| 7 | #include "core/hle/ipc_helpers.h" | ||
| 5 | #include "core/hle/service/glue/bgtc.h" | 8 | #include "core/hle/service/glue/bgtc.h" |
| 6 | 9 | ||
| 7 | namespace Service::Glue { | 10 | namespace Service::Glue { |
| @@ -9,6 +12,26 @@ namespace Service::Glue { | |||
| 9 | BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} { | 12 | BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} { |
| 10 | // clang-format off | 13 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 14 | static const FunctionInfo functions[] = { |
| 15 | {100, &BGTC_T::OpenTaskService, "OpenTaskService"}, | ||
| 16 | }; | ||
| 17 | // clang-format on | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | BGTC_T::~BGTC_T() = default; | ||
| 23 | |||
| 24 | void BGTC_T::OpenTaskService(Kernel::HLERequestContext& ctx) { | ||
| 25 | LOG_DEBUG(Service_BGTC, "called"); | ||
| 26 | |||
| 27 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 28 | rb.Push(RESULT_SUCCESS); | ||
| 29 | rb.PushIpcInterface<ITaskService>(system); | ||
| 30 | } | ||
| 31 | |||
| 32 | ITaskService::ITaskService(Core::System& system_) : ServiceFramework{system_, "ITaskService"} { | ||
| 33 | // clang-format off | ||
| 34 | static const FunctionInfo functions[] = { | ||
| 12 | {1, nullptr, "NotifyTaskStarting"}, | 35 | {1, nullptr, "NotifyTaskStarting"}, |
| 13 | {2, nullptr, "NotifyTaskFinished"}, | 36 | {2, nullptr, "NotifyTaskFinished"}, |
| 14 | {3, nullptr, "GetTriggerEvent"}, | 37 | {3, nullptr, "GetTriggerEvent"}, |
| @@ -20,16 +43,18 @@ BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} { | |||
| 20 | {13, nullptr, "UnscheduleTask"}, | 43 | {13, nullptr, "UnscheduleTask"}, |
| 21 | {14, nullptr, "GetScheduleEvent"}, | 44 | {14, nullptr, "GetScheduleEvent"}, |
| 22 | {15, nullptr, "SchedulePeriodicTask"}, | 45 | {15, nullptr, "SchedulePeriodicTask"}, |
| 46 | {16, nullptr, "Unknown16"}, | ||
| 23 | {101, nullptr, "GetOperationMode"}, | 47 | {101, nullptr, "GetOperationMode"}, |
| 24 | {102, nullptr, "WillDisconnectNetworkWhenEnteringSleep"}, | 48 | {102, nullptr, "WillDisconnectNetworkWhenEnteringSleep"}, |
| 25 | {103, nullptr, "WillStayHalfAwakeInsteadSleep"}, | 49 | {103, nullptr, "WillStayHalfAwakeInsteadSleep"}, |
| 50 | {200, nullptr, "Unknown200"}, | ||
| 26 | }; | 51 | }; |
| 27 | // clang-format on | 52 | // clang-format on |
| 28 | 53 | ||
| 29 | RegisterHandlers(functions); | 54 | RegisterHandlers(functions); |
| 30 | } | 55 | } |
| 31 | 56 | ||
| 32 | BGTC_T::~BGTC_T() = default; | 57 | ITaskService::~ITaskService() = default; |
| 33 | 58 | ||
| 34 | BGTC_SC::BGTC_SC(Core::System& system_) : ServiceFramework{system_, "bgtc:sc"} { | 59 | BGTC_SC::BGTC_SC(Core::System& system_) : ServiceFramework{system_, "bgtc:sc"} { |
| 35 | // clang-format off | 60 | // clang-format off |
diff --git a/src/core/hle/service/glue/bgtc.h b/src/core/hle/service/glue/bgtc.h index 906116ba6..4c0142fd5 100644 --- a/src/core/hle/service/glue/bgtc.h +++ b/src/core/hle/service/glue/bgtc.h | |||
| @@ -16,6 +16,14 @@ class BGTC_T final : public ServiceFramework<BGTC_T> { | |||
| 16 | public: | 16 | public: |
| 17 | explicit BGTC_T(Core::System& system_); | 17 | explicit BGTC_T(Core::System& system_); |
| 18 | ~BGTC_T() override; | 18 | ~BGTC_T() override; |
| 19 | |||
| 20 | void OpenTaskService(Kernel::HLERequestContext& ctx); | ||
| 21 | }; | ||
| 22 | |||
| 23 | class ITaskService final : public ServiceFramework<ITaskService> { | ||
| 24 | public: | ||
| 25 | explicit ITaskService(Core::System& system_); | ||
| 26 | ~ITaskService() override; | ||
| 19 | }; | 27 | }; |
| 20 | 28 | ||
| 21 | class BGTC_SC final : public ServiceFramework<BGTC_SC> { | 29 | class BGTC_SC final : public ServiceFramework<BGTC_SC> { |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 1df62f98e..673db68c7 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -1138,6 +1138,10 @@ void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_prot | |||
| 1138 | unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled; | 1138 | unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled; |
| 1139 | } | 1139 | } |
| 1140 | 1140 | ||
| 1141 | void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { | ||
| 1142 | analog_stick_use_center_clamp = use_center_clamp; | ||
| 1143 | } | ||
| 1144 | |||
| 1141 | void Controller_NPad::ClearAllConnectedControllers() { | 1145 | void Controller_NPad::ClearAllConnectedControllers() { |
| 1142 | for (auto& controller : connected_controllers) { | 1146 | for (auto& controller : connected_controllers) { |
| 1143 | if (controller.is_connected && controller.type != NPadControllerType::None) { | 1147 | if (controller.is_connected && controller.type != NPadControllerType::None) { |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index bc2e6779d..873a0a1e2 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -219,6 +219,7 @@ public: | |||
| 219 | LedPattern GetLedPattern(u32 npad_id); | 219 | LedPattern GetLedPattern(u32 npad_id); |
| 220 | bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const; | 220 | bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const; |
| 221 | void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id); | 221 | void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id); |
| 222 | void SetAnalogStickUseCenterClamp(bool use_center_clamp); | ||
| 222 | void ClearAllConnectedControllers(); | 223 | void ClearAllConnectedControllers(); |
| 223 | void DisconnectAllConnectedControllers(); | 224 | void DisconnectAllConnectedControllers(); |
| 224 | void ConnectAllDisconnectedControllers(); | 225 | void ConnectAllDisconnectedControllers(); |
| @@ -577,6 +578,7 @@ private: | |||
| 577 | std::array<std::array<bool, 2>, 10> vibration_devices_mounted{}; | 578 | std::array<std::array<bool, 2>, 10> vibration_devices_mounted{}; |
| 578 | std::array<ControllerHolder, 10> connected_controllers{}; | 579 | std::array<ControllerHolder, 10> connected_controllers{}; |
| 579 | std::array<bool, 10> unintended_home_button_input_protection{}; | 580 | std::array<bool, 10> unintended_home_button_input_protection{}; |
| 581 | bool analog_stick_use_center_clamp{}; | ||
| 580 | GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; | 582 | GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; |
| 581 | bool sixaxis_sensors_enabled{true}; | 583 | bool sixaxis_sensors_enabled{true}; |
| 582 | f32 sixaxis_fusion_parameter1{}; | 584 | f32 sixaxis_fusion_parameter1{}; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ba27bbb05..a1a779cc0 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -263,7 +263,7 @@ Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} { | |||
| 263 | {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, | 263 | {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"}, |
| 264 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, | 264 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, |
| 265 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, | 265 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, |
| 266 | {134, nullptr, "SetNpadAnalogStickUseCenterClamp"}, | 266 | {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, |
| 267 | {135, nullptr, "SetNpadCaptureButtonAssignment"}, | 267 | {135, nullptr, "SetNpadCaptureButtonAssignment"}, |
| 268 | {136, nullptr, "ClearNpadCaptureButtonAssignment"}, | 268 | {136, nullptr, "ClearNpadCaptureButtonAssignment"}, |
| 269 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, | 269 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, |
| @@ -278,6 +278,7 @@ Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} { | |||
| 278 | {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, | 278 | {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, |
| 279 | {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"}, | 279 | {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"}, |
| 280 | {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"}, | 280 | {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"}, |
| 281 | {212, nullptr, "SendVibrationValueInBool"}, | ||
| 281 | {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, | 282 | {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, |
| 282 | {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, | 283 | {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, |
| 283 | {302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"}, | 284 | {302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"}, |
| @@ -1087,6 +1088,27 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c | |||
| 1087 | rb.Push(RESULT_SUCCESS); | 1088 | rb.Push(RESULT_SUCCESS); |
| 1088 | } | 1089 | } |
| 1089 | 1090 | ||
| 1091 | void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) { | ||
| 1092 | IPC::RequestParser rp{ctx}; | ||
| 1093 | struct Parameters { | ||
| 1094 | bool analog_stick_use_center_clamp; | ||
| 1095 | u64 applet_resource_user_id; | ||
| 1096 | }; | ||
| 1097 | static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||
| 1098 | |||
| 1099 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1100 | |||
| 1101 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | ||
| 1102 | .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp); | ||
| 1103 | |||
| 1104 | LOG_WARNING(Service_HID, | ||
| 1105 | "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}", | ||
| 1106 | parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id); | ||
| 1107 | |||
| 1108 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1109 | rb.Push(RESULT_SUCCESS); | ||
| 1110 | } | ||
| 1111 | |||
| 1090 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | 1112 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { |
| 1091 | IPC::RequestParser rp{ctx}; | 1113 | IPC::RequestParser rp{ctx}; |
| 1092 | const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()}; | 1114 | const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()}; |
| @@ -1553,6 +1575,7 @@ public: | |||
| 1553 | {11, nullptr, "SetTouchScreenAutoPilotState"}, | 1575 | {11, nullptr, "SetTouchScreenAutoPilotState"}, |
| 1554 | {12, nullptr, "UnsetTouchScreenAutoPilotState"}, | 1576 | {12, nullptr, "UnsetTouchScreenAutoPilotState"}, |
| 1555 | {13, nullptr, "GetTouchScreenConfiguration"}, | 1577 | {13, nullptr, "GetTouchScreenConfiguration"}, |
| 1578 | {14, nullptr, "ProcessTouchScreenAutoTune"}, | ||
| 1556 | {20, nullptr, "DeactivateMouse"}, | 1579 | {20, nullptr, "DeactivateMouse"}, |
| 1557 | {21, nullptr, "SetMouseAutoPilotState"}, | 1580 | {21, nullptr, "SetMouseAutoPilotState"}, |
| 1558 | {22, nullptr, "UnsetMouseAutoPilotState"}, | 1581 | {22, nullptr, "UnsetMouseAutoPilotState"}, |
| @@ -1562,6 +1585,7 @@ public: | |||
| 1562 | {50, nullptr, "DeactivateXpad"}, | 1585 | {50, nullptr, "DeactivateXpad"}, |
| 1563 | {51, nullptr, "SetXpadAutoPilotState"}, | 1586 | {51, nullptr, "SetXpadAutoPilotState"}, |
| 1564 | {52, nullptr, "UnsetXpadAutoPilotState"}, | 1587 | {52, nullptr, "UnsetXpadAutoPilotState"}, |
| 1588 | {53, nullptr, "DeactivateJoyXpad"}, | ||
| 1565 | {60, nullptr, "ClearNpadSystemCommonPolicy"}, | 1589 | {60, nullptr, "ClearNpadSystemCommonPolicy"}, |
| 1566 | {61, nullptr, "DeactivateNpad"}, | 1590 | {61, nullptr, "DeactivateNpad"}, |
| 1567 | {62, nullptr, "ForceDisconnectNpad"}, | 1591 | {62, nullptr, "ForceDisconnectNpad"}, |
| @@ -1632,6 +1656,11 @@ public: | |||
| 1632 | {244, nullptr, "RequestKuinaFirmwareVersion"}, | 1656 | {244, nullptr, "RequestKuinaFirmwareVersion"}, |
| 1633 | {245, nullptr, "GetKuinaFirmwareVersion"}, | 1657 | {245, nullptr, "GetKuinaFirmwareVersion"}, |
| 1634 | {246, nullptr, "GetVidPid"}, | 1658 | {246, nullptr, "GetVidPid"}, |
| 1659 | {247, nullptr, "GetAnalogStickCalibrationValue"}, | ||
| 1660 | {248, nullptr, "GetUniquePadIdsFull"}, | ||
| 1661 | {249, nullptr, "ConnectUniquePad"}, | ||
| 1662 | {250, nullptr, "IsVirtual"}, | ||
| 1663 | {251, nullptr, "GetAnalogStickModuleParam"}, | ||
| 1635 | {301, nullptr, "GetAbstractedPadHandles"}, | 1664 | {301, nullptr, "GetAbstractedPadHandles"}, |
| 1636 | {302, nullptr, "GetAbstractedPadState"}, | 1665 | {302, nullptr, "GetAbstractedPadState"}, |
| 1637 | {303, nullptr, "GetAbstractedPadsState"}, | 1666 | {303, nullptr, "GetAbstractedPadsState"}, |
| @@ -1652,12 +1681,16 @@ public: | |||
| 1652 | {401, nullptr, "DisableRailDeviceFiltering"}, | 1681 | {401, nullptr, "DisableRailDeviceFiltering"}, |
| 1653 | {402, nullptr, "EnableWiredPairing"}, | 1682 | {402, nullptr, "EnableWiredPairing"}, |
| 1654 | {403, nullptr, "EnableShipmentModeAutoClear"}, | 1683 | {403, nullptr, "EnableShipmentModeAutoClear"}, |
| 1684 | {404, nullptr, "SetRailEnabled"}, | ||
| 1655 | {500, nullptr, "SetFactoryInt"}, | 1685 | {500, nullptr, "SetFactoryInt"}, |
| 1656 | {501, nullptr, "IsFactoryBootEnabled"}, | 1686 | {501, nullptr, "IsFactoryBootEnabled"}, |
| 1657 | {550, nullptr, "SetAnalogStickModelDataTemporarily"}, | 1687 | {550, nullptr, "SetAnalogStickModelDataTemporarily"}, |
| 1658 | {551, nullptr, "GetAnalogStickModelData"}, | 1688 | {551, nullptr, "GetAnalogStickModelData"}, |
| 1659 | {552, nullptr, "ResetAnalogStickModelData"}, | 1689 | {552, nullptr, "ResetAnalogStickModelData"}, |
| 1660 | {600, nullptr, "ConvertPadState"}, | 1690 | {600, nullptr, "ConvertPadState"}, |
| 1691 | {650, nullptr, "AddButtonPlayData"}, | ||
| 1692 | {651, nullptr, "StartButtonPlayData"}, | ||
| 1693 | {652, nullptr, "StopButtonPlayData"}, | ||
| 1661 | {2000, nullptr, "DeactivateDigitizer"}, | 1694 | {2000, nullptr, "DeactivateDigitizer"}, |
| 1662 | {2001, nullptr, "SetDigitizerAutoPilotState"}, | 1695 | {2001, nullptr, "SetDigitizerAutoPilotState"}, |
| 1663 | {2002, nullptr, "UnsetDigitizerAutoPilotState"}, | 1696 | {2002, nullptr, "UnsetDigitizerAutoPilotState"}, |
| @@ -1689,6 +1722,8 @@ public: | |||
| 1689 | {215, nullptr, "IsNfcActivated"}, | 1722 | {215, nullptr, "IsNfcActivated"}, |
| 1690 | {230, nullptr, "AcquireIrSensorEventHandle"}, | 1723 | {230, nullptr, "AcquireIrSensorEventHandle"}, |
| 1691 | {231, nullptr, "ActivateIrSensor"}, | 1724 | {231, nullptr, "ActivateIrSensor"}, |
| 1725 | {232, nullptr, "GetIrSensorState"}, | ||
| 1726 | {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | ||
| 1692 | {301, nullptr, "ActivateNpadSystem"}, | 1727 | {301, nullptr, "ActivateNpadSystem"}, |
| 1693 | {303, nullptr, "ApplyNpadSystemCommonPolicy"}, | 1728 | {303, nullptr, "ApplyNpadSystemCommonPolicy"}, |
| 1694 | {304, nullptr, "EnableAssigningSingleOnSlSrPress"}, | 1729 | {304, nullptr, "EnableAssigningSingleOnSlSrPress"}, |
| @@ -1703,9 +1738,16 @@ public: | |||
| 1703 | {313, nullptr, "GetNpadCaptureButtonAssignment"}, | 1738 | {313, nullptr, "GetNpadCaptureButtonAssignment"}, |
| 1704 | {314, nullptr, "GetAppletFooterUiType"}, | 1739 | {314, nullptr, "GetAppletFooterUiType"}, |
| 1705 | {315, nullptr, "GetAppletDetailedUiType"}, | 1740 | {315, nullptr, "GetAppletDetailedUiType"}, |
| 1741 | {316, nullptr, "GetNpadInterfaceType"}, | ||
| 1742 | {317, nullptr, "GetNpadLeftRightInterfaceType"}, | ||
| 1743 | {318, nullptr, "HasBattery"}, | ||
| 1744 | {319, nullptr, "HasLeftRightBattery"}, | ||
| 1706 | {321, nullptr, "GetUniquePadsFromNpad"}, | 1745 | {321, nullptr, "GetUniquePadsFromNpad"}, |
| 1707 | {322, nullptr, "GetIrSensorState"}, | 1746 | {322, nullptr, "GetIrSensorState"}, |
| 1708 | {323, nullptr, "GetXcdHandleForNpadWithIrSensor"}, | 1747 | {323, nullptr, "GetXcdHandleForNpadWithIrSensor"}, |
| 1748 | {324, nullptr, "GetUniquePadButtonSet"}, | ||
| 1749 | {325, nullptr, "GetUniquePadColor"}, | ||
| 1750 | {326, nullptr, "GetUniquePadAppletDetailedUiType"}, | ||
| 1709 | {500, nullptr, "SetAppletResourceUserId"}, | 1751 | {500, nullptr, "SetAppletResourceUserId"}, |
| 1710 | {501, nullptr, "RegisterAppletResourceUserId"}, | 1752 | {501, nullptr, "RegisterAppletResourceUserId"}, |
| 1711 | {502, nullptr, "UnregisterAppletResourceUserId"}, | 1753 | {502, nullptr, "UnregisterAppletResourceUserId"}, |
| @@ -1716,10 +1758,13 @@ public: | |||
| 1716 | {511, nullptr, "GetVibrationMasterVolume"}, | 1758 | {511, nullptr, "GetVibrationMasterVolume"}, |
| 1717 | {512, nullptr, "BeginPermitVibrationSession"}, | 1759 | {512, nullptr, "BeginPermitVibrationSession"}, |
| 1718 | {513, nullptr, "EndPermitVibrationSession"}, | 1760 | {513, nullptr, "EndPermitVibrationSession"}, |
| 1761 | {514, nullptr, "Unknown514"}, | ||
| 1719 | {520, nullptr, "EnableHandheldHids"}, | 1762 | {520, nullptr, "EnableHandheldHids"}, |
| 1720 | {521, nullptr, "DisableHandheldHids"}, | 1763 | {521, nullptr, "DisableHandheldHids"}, |
| 1721 | {522, nullptr, "SetJoyConRailEnabled"}, | 1764 | {522, nullptr, "SetJoyConRailEnabled"}, |
| 1722 | {523, nullptr, "IsJoyConRailEnabled"}, | 1765 | {523, nullptr, "IsJoyConRailEnabled"}, |
| 1766 | {524, nullptr, "IsHandheldHidsEnabled"}, | ||
| 1767 | {525, nullptr, "IsJoyConAttachedOnAllRail"}, | ||
| 1723 | {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"}, | 1768 | {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"}, |
| 1724 | {541, nullptr, "GetPlayReportControllerUsages"}, | 1769 | {541, nullptr, "GetPlayReportControllerUsages"}, |
| 1725 | {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, | 1770 | {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, |
| @@ -1795,6 +1840,65 @@ public: | |||
| 1795 | {1154, nullptr, "IsFirmwareAvailableForNotification"}, | 1840 | {1154, nullptr, "IsFirmwareAvailableForNotification"}, |
| 1796 | {1155, nullptr, "SetForceHandheldStyleVibration"}, | 1841 | {1155, nullptr, "SetForceHandheldStyleVibration"}, |
| 1797 | {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"}, | 1842 | {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"}, |
| 1843 | {1157, nullptr, "CancelConnectionTrigger"}, | ||
| 1844 | {1200, nullptr, "IsButtonConfigSupported"}, | ||
| 1845 | {1201, nullptr, "IsButtonConfigEmbeddedSupported"}, | ||
| 1846 | {1202, nullptr, "DeleteButtonConfig"}, | ||
| 1847 | {1203, nullptr, "DeleteButtonConfigEmbedded"}, | ||
| 1848 | {1204, nullptr, "SetButtonConfigEnabled"}, | ||
| 1849 | {1205, nullptr, "SetButtonConfigEmbeddedEnabled"}, | ||
| 1850 | {1206, nullptr, "IsButtonConfigEnabled"}, | ||
| 1851 | {1207, nullptr, "IsButtonConfigEmbeddedEnabled"}, | ||
| 1852 | {1208, nullptr, "SetButtonConfigEmbedded"}, | ||
| 1853 | {1209, nullptr, "SetButtonConfigFull"}, | ||
| 1854 | {1210, nullptr, "SetButtonConfigLeft"}, | ||
| 1855 | {1211, nullptr, "SetButtonConfigRight"}, | ||
| 1856 | {1212, nullptr, "GetButtonConfigEmbedded"}, | ||
| 1857 | {1213, nullptr, "GetButtonConfigFull"}, | ||
| 1858 | {1214, nullptr, "GetButtonConfigLeft"}, | ||
| 1859 | {1215, nullptr, "GetButtonConfigRight"}, | ||
| 1860 | {1250, nullptr, "IsCustomButtonConfigSupported"}, | ||
| 1861 | {1251, nullptr, "IsDefaultButtonConfigEmbedded"}, | ||
| 1862 | {1252, nullptr, "IsDefaultButtonConfigFull"}, | ||
| 1863 | {1253, nullptr, "IsDefaultButtonConfigLeft"}, | ||
| 1864 | {1254, nullptr, "IsDefaultButtonConfigRight"}, | ||
| 1865 | {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"}, | ||
| 1866 | {1256, nullptr, "IsButtonConfigStorageFullEmpty"}, | ||
| 1867 | {1257, nullptr, "IsButtonConfigStorageLeftEmpty"}, | ||
| 1868 | {1258, nullptr, "IsButtonConfigStorageRightEmpty"}, | ||
| 1869 | {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"}, | ||
| 1870 | {1260, nullptr, "GetButtonConfigStorageFullDeprecated"}, | ||
| 1871 | {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"}, | ||
| 1872 | {1262, nullptr, "GetButtonConfigStorageRightDeprecated"}, | ||
| 1873 | {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"}, | ||
| 1874 | {1264, nullptr, "SetButtonConfigStorageFullDeprecated"}, | ||
| 1875 | {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"}, | ||
| 1876 | {1266, nullptr, "SetButtonConfigStorageRightDeprecated"}, | ||
| 1877 | {1267, nullptr, "DeleteButtonConfigStorageEmbedded"}, | ||
| 1878 | {1268, nullptr, "DeleteButtonConfigStorageFull"}, | ||
| 1879 | {1269, nullptr, "DeleteButtonConfigStorageLeft"}, | ||
| 1880 | {1270, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 1881 | {1271, nullptr, "IsUsingCustomButtonConfig"}, | ||
| 1882 | {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, | ||
| 1883 | {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, | ||
| 1884 | {1274, nullptr, "SetDefaultButtonConfig"}, | ||
| 1885 | {1275, nullptr, "SetAllDefaultButtonConfig"}, | ||
| 1886 | {1276, nullptr, "SetHidButtonConfigEmbedded"}, | ||
| 1887 | {1277, nullptr, "SetHidButtonConfigFull"}, | ||
| 1888 | {1278, nullptr, "SetHidButtonConfigLeft"}, | ||
| 1889 | {1279, nullptr, "SetHidButtonConfigRight"}, | ||
| 1890 | {1280, nullptr, "GetHidButtonConfigEmbedded"}, | ||
| 1891 | {1281, nullptr, "GetHidButtonConfigFull"}, | ||
| 1892 | {1282, nullptr, "GetHidButtonConfigLeft"}, | ||
| 1893 | {1283, nullptr, "GetHidButtonConfigRight"}, | ||
| 1894 | {1284, nullptr, "GetButtonConfigStorageEmbedded"}, | ||
| 1895 | {1285, nullptr, "GetButtonConfigStorageFull"}, | ||
| 1896 | {1286, nullptr, "GetButtonConfigStorageLeft"}, | ||
| 1897 | {1287, nullptr, "GetButtonConfigStorageRight"}, | ||
| 1898 | {1288, nullptr, "SetButtonConfigStorageEmbedded"}, | ||
| 1899 | {1289, nullptr, "SetButtonConfigStorageFull"}, | ||
| 1900 | {1290, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 1901 | {1291, nullptr, "DeleteButtonConfigStorageRight"}, | ||
| 1798 | }; | 1902 | }; |
| 1799 | // clang-format on | 1903 | // clang-format on |
| 1800 | 1904 | ||
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 36ed228c8..c2bdd39a3 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -129,6 +129,7 @@ private: | |||
| 129 | void SwapNpadAssignment(Kernel::HLERequestContext& ctx); | 129 | void SwapNpadAssignment(Kernel::HLERequestContext& ctx); |
| 130 | void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx); | 130 | void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx); |
| 131 | void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx); | 131 | void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx); |
| 132 | void SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx); | ||
| 132 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); | 133 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); |
| 133 | void SendVibrationValue(Kernel::HLERequestContext& ctx); | 134 | void SendVibrationValue(Kernel::HLERequestContext& ctx); |
| 134 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); | 135 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/hid/xcd.cpp b/src/core/hle/service/hid/xcd.cpp index 43a8840d0..b1efa3d05 100644 --- a/src/core/hle/service/hid/xcd.cpp +++ b/src/core/hle/service/hid/xcd.cpp | |||
| @@ -28,6 +28,8 @@ XCD_SYS::XCD_SYS(Core::System& system_) : ServiceFramework{system_, "xcd:sys"} { | |||
| 28 | {20, nullptr, "StartMifareWrite"}, | 28 | {20, nullptr, "StartMifareWrite"}, |
| 29 | {101, nullptr, "GetAwakeTriggerReasonForLeftRail"}, | 29 | {101, nullptr, "GetAwakeTriggerReasonForLeftRail"}, |
| 30 | {102, nullptr, "GetAwakeTriggerReasonForRightRail"}, | 30 | {102, nullptr, "GetAwakeTriggerReasonForRightRail"}, |
| 31 | {103, nullptr, "GetAwakeTriggerBatteryLevelTransitionForLeftRail"}, | ||
| 32 | {104, nullptr, "GetAwakeTriggerBatteryLevelTransitionForRightRail"}, | ||
| 31 | }; | 33 | }; |
| 32 | // clang-format on | 34 | // clang-format on |
| 33 | 35 | ||
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index d111c1357..c8bc60ad1 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -118,9 +118,9 @@ public: | |||
| 118 | explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "ldr:dmnt"} { | 118 | explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "ldr:dmnt"} { |
| 119 | // clang-format off | 119 | // clang-format off |
| 120 | static const FunctionInfo functions[] = { | 120 | static const FunctionInfo functions[] = { |
| 121 | {0, nullptr, "AddProcessToDebugLaunchQueue"}, | 121 | {0, nullptr, "SetProgramArgument"}, |
| 122 | {1, nullptr, "ClearDebugLaunchQueue"}, | 122 | {1, nullptr, "FlushArguments"}, |
| 123 | {2, nullptr, "GetNsoInfos"}, | 123 | {2, nullptr, "GetProcessModuleInfo"}, |
| 124 | }; | 124 | }; |
| 125 | // clang-format on | 125 | // clang-format on |
| 126 | 126 | ||
| @@ -135,8 +135,8 @@ public: | |||
| 135 | static const FunctionInfo functions[] = { | 135 | static const FunctionInfo functions[] = { |
| 136 | {0, nullptr, "CreateProcess"}, | 136 | {0, nullptr, "CreateProcess"}, |
| 137 | {1, nullptr, "GetProgramInfo"}, | 137 | {1, nullptr, "GetProgramInfo"}, |
| 138 | {2, nullptr, "RegisterTitle"}, | 138 | {2, nullptr, "PinProgram"}, |
| 139 | {3, nullptr, "UnregisterTitle"}, | 139 | {3, nullptr, "UnpinProgram"}, |
| 140 | {4, nullptr, "SetEnabledProgramVerification"}, | 140 | {4, nullptr, "SetEnabledProgramVerification"}, |
| 141 | }; | 141 | }; |
| 142 | // clang-format on | 142 | // clang-format on |
| @@ -150,8 +150,8 @@ public: | |||
| 150 | explicit Shell(Core::System& system_) : ServiceFramework{system_, "ldr:shel"} { | 150 | explicit Shell(Core::System& system_) : ServiceFramework{system_, "ldr:shel"} { |
| 151 | // clang-format off | 151 | // clang-format off |
| 152 | static const FunctionInfo functions[] = { | 152 | static const FunctionInfo functions[] = { |
| 153 | {0, nullptr, "AddProcessToLaunchQueue"}, | 153 | {0, nullptr, "SetProgramArgument"}, |
| 154 | {1, nullptr, "ClearLaunchQueue"}, | 154 | {1, nullptr, "FlushArguments"}, |
| 155 | }; | 155 | }; |
| 156 | // clang-format on | 156 | // clang-format on |
| 157 | 157 | ||
| @@ -164,19 +164,19 @@ public: | |||
| 164 | explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} { | 164 | explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} { |
| 165 | // clang-format off | 165 | // clang-format off |
| 166 | static const FunctionInfo functions[] = { | 166 | static const FunctionInfo functions[] = { |
| 167 | {0, &RelocatableObject::LoadNro, "LoadNro"}, | 167 | {0, &RelocatableObject::LoadModule, "LoadModule"}, |
| 168 | {1, &RelocatableObject::UnloadNro, "UnloadNro"}, | 168 | {1, &RelocatableObject::UnloadModule, "UnloadModule"}, |
| 169 | {2, &RelocatableObject::LoadNrr, "LoadNrr"}, | 169 | {2, &RelocatableObject::RegisterModuleInfo, "RegisterModuleInfo"}, |
| 170 | {3, &RelocatableObject::UnloadNrr, "UnloadNrr"}, | 170 | {3, &RelocatableObject::UnregisterModuleInfo, "UnregisterModuleInfo"}, |
| 171 | {4, &RelocatableObject::Initialize, "Initialize"}, | 171 | {4, &RelocatableObject::Initialize, "Initialize"}, |
| 172 | {10, nullptr, "LoadNrrEx"}, | 172 | {10, nullptr, "RegisterModuleInfo2"}, |
| 173 | }; | 173 | }; |
| 174 | // clang-format on | 174 | // clang-format on |
| 175 | 175 | ||
| 176 | RegisterHandlers(functions); | 176 | RegisterHandlers(functions); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | void LoadNrr(Kernel::HLERequestContext& ctx) { | 179 | void RegisterModuleInfo(Kernel::HLERequestContext& ctx) { |
| 180 | struct Parameters { | 180 | struct Parameters { |
| 181 | u64_le process_id; | 181 | u64_le process_id; |
| 182 | u64_le nrr_address; | 182 | u64_le nrr_address; |
| @@ -273,7 +273,7 @@ public: | |||
| 273 | rb.Push(RESULT_SUCCESS); | 273 | rb.Push(RESULT_SUCCESS); |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | void UnloadNrr(Kernel::HLERequestContext& ctx) { | 276 | void UnregisterModuleInfo(Kernel::HLERequestContext& ctx) { |
| 277 | IPC::RequestParser rp{ctx}; | 277 | IPC::RequestParser rp{ctx}; |
| 278 | const auto pid = rp.Pop<u64>(); | 278 | const auto pid = rp.Pop<u64>(); |
| 279 | const auto nrr_address = rp.Pop<VAddr>(); | 279 | const auto nrr_address = rp.Pop<VAddr>(); |
| @@ -408,7 +408,7 @@ public: | |||
| 408 | data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); | 408 | data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite); |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | void LoadNro(Kernel::HLERequestContext& ctx) { | 411 | void LoadModule(Kernel::HLERequestContext& ctx) { |
| 412 | struct Parameters { | 412 | struct Parameters { |
| 413 | u64_le process_id; | 413 | u64_le process_id; |
| 414 | u64_le image_address; | 414 | u64_le image_address; |
| @@ -546,7 +546,7 @@ public: | |||
| 546 | return RESULT_SUCCESS; | 546 | return RESULT_SUCCESS; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | void UnloadNro(Kernel::HLERequestContext& ctx) { | 549 | void UnloadModule(Kernel::HLERequestContext& ctx) { |
| 550 | if (!initialized) { | 550 | if (!initialized) { |
| 551 | LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!"); | 551 | LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!"); |
| 552 | IPC::ResponseBuilder rb{ctx, 2}; | 552 | IPC::ResponseBuilder rb{ctx, 2}; |
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index f3be0b878..fee360ab9 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp | |||
| @@ -125,51 +125,51 @@ public: | |||
| 125 | {39, nullptr, "PrepareShutdown"}, | 125 | {39, nullptr, "PrepareShutdown"}, |
| 126 | {40, nullptr, "ListApplyDeltaTask"}, | 126 | {40, nullptr, "ListApplyDeltaTask"}, |
| 127 | {41, nullptr, "ClearNotEnoughSpaceStateOfApplyDeltaTask"}, | 127 | {41, nullptr, "ClearNotEnoughSpaceStateOfApplyDeltaTask"}, |
| 128 | {42, nullptr, "Unknown42"}, | 128 | {42, nullptr, "CreateApplyDeltaTaskFromDownloadTask"}, |
| 129 | {43, nullptr, "Unknown43"}, | 129 | {43, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, |
| 130 | {44, nullptr, "Unknown44"}, | 130 | {44, nullptr, "GetApplyDeltaTaskRequiredStorage"}, |
| 131 | {45, nullptr, "Unknown45"}, | 131 | {45, nullptr, "CalculateNetworkInstallTaskContentsSize"}, |
| 132 | {46, nullptr, "Unknown46"}, | 132 | {46, nullptr, "PrepareShutdownForSystemUpdate"}, |
| 133 | {47, nullptr, "Unknown47"}, | 133 | {47, nullptr, "FindMaxRequiredApplicationVersionOfTask"}, |
| 134 | {48, nullptr, "Unknown48"}, | 134 | {48, nullptr, "CommitNetworkInstallTaskPartially"}, |
| 135 | {49, nullptr, "Unknown49"}, | 135 | {49, nullptr, "ListNetworkInstallTaskCommittedContentMeta"}, |
| 136 | {50, nullptr, "Unknown50"}, | 136 | {50, nullptr, "ListNetworkInstallTaskNotCommittedContentMeta"}, |
| 137 | {51, nullptr, "Unknown51"}, | 137 | {51, nullptr, "FindMaxRequiredSystemVersionOfTask"}, |
| 138 | {52, nullptr, "Unknown52"}, | 138 | {52, nullptr, "GetNetworkInstallTaskErrorContext"}, |
| 139 | {53, nullptr, "Unknown53"}, | 139 | {53, nullptr, "CreateLocalCommunicationReceiveApplicationTask"}, |
| 140 | {54, nullptr, "Unknown54"}, | 140 | {54, nullptr, "DestroyLocalCommunicationReceiveApplicationTask"}, |
| 141 | {55, nullptr, "Unknown55"}, | 141 | {55, nullptr, "ListLocalCommunicationReceiveApplicationTask"}, |
| 142 | {56, nullptr, "Unknown56"}, | 142 | {56, nullptr, "RequestLocalCommunicationReceiveApplicationTaskRun"}, |
| 143 | {57, nullptr, "Unknown57"}, | 143 | {57, nullptr, "GetLocalCommunicationReceiveApplicationTaskInfo"}, |
| 144 | {58, nullptr, "Unknown58"}, | 144 | {58, nullptr, "CommitLocalCommunicationReceiveApplicationTask"}, |
| 145 | {59, nullptr, "Unknown59"}, | 145 | {59, nullptr, "ListLocalCommunicationReceiveApplicationTaskContentMeta"}, |
| 146 | {60, nullptr, "Unknown60"}, | 146 | {60, nullptr, "CreateLocalCommunicationSendApplicationTask"}, |
| 147 | {61, nullptr, "Unknown61"}, | 147 | {61, nullptr, "RequestLocalCommunicationSendApplicationTaskRun"}, |
| 148 | {62, nullptr, "Unknown62"}, | 148 | {62, nullptr, "GetLocalCommunicationReceiveApplicationTaskErrorContext"}, |
| 149 | {63, nullptr, "Unknown63"}, | 149 | {63, nullptr, "GetLocalCommunicationSendApplicationTaskInfo"}, |
| 150 | {64, nullptr, "Unknown64"}, | 150 | {64, nullptr, "DestroyLocalCommunicationSendApplicationTask"}, |
| 151 | {65, nullptr, "Unknown65"}, | 151 | {65, nullptr, "GetLocalCommunicationSendApplicationTaskErrorContext"}, |
| 152 | {66, nullptr, "Unknown66"}, | 152 | {66, nullptr, "CalculateLocalCommunicationReceiveApplicationTaskRequiredSize"}, |
| 153 | {67, nullptr, "Unknown67"}, | 153 | {67, nullptr, "ListApplicationLocalCommunicationReceiveApplicationTask"}, |
| 154 | {68, nullptr, "Unknown68"}, | 154 | {68, nullptr, "ListApplicationLocalCommunicationSendApplicationTask"}, |
| 155 | {69, nullptr, "Unknown69"}, | 155 | {69, nullptr, "CreateLocalCommunicationReceiveSystemUpdateTask"}, |
| 156 | {70, nullptr, "Unknown70"}, | 156 | {70, nullptr, "DestroyLocalCommunicationReceiveSystemUpdateTask"}, |
| 157 | {71, nullptr, "Unknown71"}, | 157 | {71, nullptr, "ListLocalCommunicationReceiveSystemUpdateTask"}, |
| 158 | {72, nullptr, "Unknown72"}, | 158 | {72, nullptr, "RequestLocalCommunicationReceiveSystemUpdateTaskRun"}, |
| 159 | {73, nullptr, "Unknown73"}, | 159 | {73, nullptr, "GetLocalCommunicationReceiveSystemUpdateTaskInfo"}, |
| 160 | {74, nullptr, "Unknown74"}, | 160 | {74, nullptr, "CommitLocalCommunicationReceiveSystemUpdateTask"}, |
| 161 | {75, nullptr, "Unknown75"}, | 161 | {75, nullptr, "GetLocalCommunicationReceiveSystemUpdateTaskErrorContext"}, |
| 162 | {76, nullptr, "Unknown76"}, | 162 | {76, nullptr, "CreateLocalCommunicationSendSystemUpdateTask"}, |
| 163 | {77, nullptr, "Unknown77"}, | 163 | {77, nullptr, "RequestLocalCommunicationSendSystemUpdateTaskRun"}, |
| 164 | {78, nullptr, "Unknown78"}, | 164 | {78, nullptr, "GetLocalCommunicationSendSystemUpdateTaskInfo"}, |
| 165 | {79, nullptr, "Unknown79"}, | 165 | {79, nullptr, "DestroyLocalCommunicationSendSystemUpdateTask"}, |
| 166 | {80, nullptr, "Unknown80"}, | 166 | {80, nullptr, "GetLocalCommunicationSendSystemUpdateTaskErrorContext"}, |
| 167 | {81, nullptr, "Unknown81"}, | 167 | {81, nullptr, "ListLocalCommunicationSendSystemUpdateTask"}, |
| 168 | {82, nullptr, "Unknown82"}, | 168 | {82, nullptr, "GetReceivedSystemDataPath"}, |
| 169 | {83, nullptr, "Unknown83"}, | 169 | {83, nullptr, "CalculateApplyDeltaTaskOccupiedSize"}, |
| 170 | {84, nullptr, "Unknown84"}, | 170 | {84, nullptr, "Unknown84"}, |
| 171 | {85, nullptr, "Unknown85"}, | 171 | {85, nullptr, "ListNetworkInstallTaskContentMetaFromInstallMeta"}, |
| 172 | {86, nullptr, "Unknown86"}, | 172 | {86, nullptr, "ListNetworkInstallTaskOccupiedSize"}, |
| 173 | {87, nullptr, "Unknown87"}, | 173 | {87, nullptr, "Unknown87"}, |
| 174 | {88, nullptr, "Unknown88"}, | 174 | {88, nullptr, "Unknown88"}, |
| 175 | {89, nullptr, "Unknown89"}, | 175 | {89, nullptr, "Unknown89"}, |
| @@ -202,6 +202,17 @@ public: | |||
| 202 | {116, nullptr, "Unknown116"}, | 202 | {116, nullptr, "Unknown116"}, |
| 203 | {117, nullptr, "Unknown117"}, | 203 | {117, nullptr, "Unknown117"}, |
| 204 | {118, nullptr, "Unknown118"}, | 204 | {118, nullptr, "Unknown118"}, |
| 205 | {119, nullptr, "Unknown119"}, | ||
| 206 | {120, nullptr, "Unknown120"}, | ||
| 207 | {121, nullptr, "Unknown121"}, | ||
| 208 | {122, nullptr, "Unknown122"}, | ||
| 209 | {123, nullptr, "Unknown123"}, | ||
| 210 | {124, nullptr, "Unknown124"}, | ||
| 211 | {125, nullptr, "Unknown125"}, | ||
| 212 | {126, nullptr, "Unknown126"}, | ||
| 213 | {127, nullptr, "Unknown127"}, | ||
| 214 | {128, nullptr, "Unknown128"}, | ||
| 215 | {129, nullptr, "Unknown129"}, | ||
| 205 | }; | 216 | }; |
| 206 | // clang-format on | 217 | // clang-format on |
| 207 | 218 | ||
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp index f7a58f659..e4c703da4 100644 --- a/src/core/hle/service/npns/npns.cpp +++ b/src/core/hle/service/npns/npns.cpp | |||
| @@ -49,6 +49,8 @@ public: | |||
| 49 | {151, nullptr, "GetStateWithHandover"}, | 49 | {151, nullptr, "GetStateWithHandover"}, |
| 50 | {152, nullptr, "GetStateChangeEventWithHandover"}, | 50 | {152, nullptr, "GetStateChangeEventWithHandover"}, |
| 51 | {153, nullptr, "GetDropEventWithHandover"}, | 51 | {153, nullptr, "GetDropEventWithHandover"}, |
| 52 | {154, nullptr, "CreateTokenAsync"}, | ||
| 53 | {155, nullptr, "CreateTokenAsyncWithApplicationId"}, | ||
| 52 | {161, nullptr, "GetRequestChangeStateCancelEvent"}, | 54 | {161, nullptr, "GetRequestChangeStateCancelEvent"}, |
| 53 | {162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"}, | 55 | {162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"}, |
| 54 | {201, nullptr, "RequestChangeStateForceTimed"}, | 56 | {201, nullptr, "RequestChangeStateForceTimed"}, |
| @@ -84,6 +86,7 @@ public: | |||
| 84 | {151, nullptr, "GetStateWithHandover"}, | 86 | {151, nullptr, "GetStateWithHandover"}, |
| 85 | {152, nullptr, "GetStateChangeEventWithHandover"}, | 87 | {152, nullptr, "GetStateChangeEventWithHandover"}, |
| 86 | {153, nullptr, "GetDropEventWithHandover"}, | 88 | {153, nullptr, "GetDropEventWithHandover"}, |
| 89 | {154, nullptr, "CreateTokenAsync"}, | ||
| 87 | }; | 90 | }; |
| 88 | // clang-format on | 91 | // clang-format on |
| 89 | 92 | ||
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 6ccf8995c..5fe7a9189 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -55,6 +55,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ | |||
| 55 | {26, nullptr, "BeginInstallApplication"}, | 55 | {26, nullptr, "BeginInstallApplication"}, |
| 56 | {27, nullptr, "DeleteApplicationRecord"}, | 56 | {27, nullptr, "DeleteApplicationRecord"}, |
| 57 | {30, nullptr, "RequestApplicationUpdateInfo"}, | 57 | {30, nullptr, "RequestApplicationUpdateInfo"}, |
| 58 | {31, nullptr, "Unknown31"}, | ||
| 58 | {32, nullptr, "CancelApplicationDownload"}, | 59 | {32, nullptr, "CancelApplicationDownload"}, |
| 59 | {33, nullptr, "ResumeApplicationDownload"}, | 60 | {33, nullptr, "ResumeApplicationDownload"}, |
| 60 | {35, nullptr, "UpdateVersionList"}, | 61 | {35, nullptr, "UpdateVersionList"}, |
| @@ -182,6 +183,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ | |||
| 182 | {913, nullptr, "ListAllApplicationRecord"}, | 183 | {913, nullptr, "ListAllApplicationRecord"}, |
| 183 | {914, nullptr, "HideApplicationRecord"}, | 184 | {914, nullptr, "HideApplicationRecord"}, |
| 184 | {915, nullptr, "ShowApplicationRecord"}, | 185 | {915, nullptr, "ShowApplicationRecord"}, |
| 186 | {916, nullptr, "IsApplicationAutoDeleteDisabled"}, | ||
| 185 | {1000, nullptr, "RequestVerifyApplicationDeprecated"}, | 187 | {1000, nullptr, "RequestVerifyApplicationDeprecated"}, |
| 186 | {1001, nullptr, "CorruptApplicationForDebug"}, | 188 | {1001, nullptr, "CorruptApplicationForDebug"}, |
| 187 | {1002, nullptr, "RequestVerifyAddOnContentsRights"}, | 189 | {1002, nullptr, "RequestVerifyAddOnContentsRights"}, |
| @@ -201,6 +203,8 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ | |||
| 201 | {1310, nullptr, "RequestMoveApplicationEntity"}, | 203 | {1310, nullptr, "RequestMoveApplicationEntity"}, |
| 202 | {1311, nullptr, "EstimateSizeToMove"}, | 204 | {1311, nullptr, "EstimateSizeToMove"}, |
| 203 | {1312, nullptr, "HasMovableEntity"}, | 205 | {1312, nullptr, "HasMovableEntity"}, |
| 206 | {1313, nullptr, "CleanupOrphanContents"}, | ||
| 207 | {1314, nullptr, "CheckPreconditionSatisfiedToMove"}, | ||
| 204 | {1400, nullptr, "PrepareShutdown"}, | 208 | {1400, nullptr, "PrepareShutdown"}, |
| 205 | {1500, nullptr, "FormatSdCard"}, | 209 | {1500, nullptr, "FormatSdCard"}, |
| 206 | {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, | 210 | {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, |
| @@ -215,6 +219,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ | |||
| 215 | {1702, nullptr, "GetApplicationDownloadTaskStatus"}, | 219 | {1702, nullptr, "GetApplicationDownloadTaskStatus"}, |
| 216 | {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, | 220 | {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, |
| 217 | {1704, nullptr, "GetApplicationViewWithPromotionInfo"}, | 221 | {1704, nullptr, "GetApplicationViewWithPromotionInfo"}, |
| 222 | {1705, nullptr, "IsPatchAutoDeletableApplication"}, | ||
| 218 | {1800, nullptr, "IsNotificationSetupCompleted"}, | 223 | {1800, nullptr, "IsNotificationSetupCompleted"}, |
| 219 | {1801, nullptr, "GetLastNotificationInfoCount"}, | 224 | {1801, nullptr, "GetLastNotificationInfoCount"}, |
| 220 | {1802, nullptr, "ListLastNotificationInfo"}, | 225 | {1802, nullptr, "ListLastNotificationInfo"}, |
| @@ -269,6 +274,9 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ | |||
| 269 | {2351, nullptr, "RequestNoDownloadRightsErrorResolution"}, | 274 | {2351, nullptr, "RequestNoDownloadRightsErrorResolution"}, |
| 270 | {2352, nullptr, "RequestResolveNoDownloadRightsError"}, | 275 | {2352, nullptr, "RequestResolveNoDownloadRightsError"}, |
| 271 | {2353, nullptr, "GetApplicationDownloadTaskInfo"}, | 276 | {2353, nullptr, "GetApplicationDownloadTaskInfo"}, |
| 277 | {2354, nullptr, "PrioritizeApplicationBackgroundTask"}, | ||
| 278 | {2355, nullptr, "Unknown2355"}, | ||
| 279 | {2356, nullptr, "Unknown2356"}, | ||
| 272 | {2400, nullptr, "GetPromotionInfo"}, | 280 | {2400, nullptr, "GetPromotionInfo"}, |
| 273 | {2401, nullptr, "CountPromotionInfo"}, | 281 | {2401, nullptr, "CountPromotionInfo"}, |
| 274 | {2402, nullptr, "ListPromotionInfo"}, | 282 | {2402, nullptr, "ListPromotionInfo"}, |
| @@ -282,6 +290,21 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ | |||
| 282 | {2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"}, | 290 | {2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"}, |
| 283 | {2516, nullptr, "EnsureApplicationCertificate"}, | 291 | {2516, nullptr, "EnsureApplicationCertificate"}, |
| 284 | {2800, nullptr, "GetApplicationIdOfPreomia"}, | 292 | {2800, nullptr, "GetApplicationIdOfPreomia"}, |
| 293 | {3000, nullptr, "RegisterDeviceLockKey"}, | ||
| 294 | {3001, nullptr, "UnregisterDeviceLockKey"}, | ||
| 295 | {3002, nullptr, "VerifyDeviceLockKey"}, | ||
| 296 | {3003, nullptr, "HideApplicationIcon"}, | ||
| 297 | {3004, nullptr, "ShowApplicationIcon"}, | ||
| 298 | {3005, nullptr, "HideApplicationTitle"}, | ||
| 299 | {3006, nullptr, "ShowApplicationTitle"}, | ||
| 300 | {3007, nullptr, "EnableGameCard"}, | ||
| 301 | {3008, nullptr, "DisableGameCard"}, | ||
| 302 | {3009, nullptr, "EnableLocalContentShare"}, | ||
| 303 | {3010, nullptr, "DisableLocalContentShare"}, | ||
| 304 | {3011, nullptr, "IsApplicationIconHidden"}, | ||
| 305 | {3012, nullptr, "IsApplicationTitleHidden"}, | ||
| 306 | {3013, nullptr, "IsGameCardEnabled"}, | ||
| 307 | {3014, nullptr, "IsLocalContentShareEnabled"}, | ||
| 285 | {9999, nullptr, "GetApplicationCertificate"}, | 308 | {9999, nullptr, "GetApplicationCertificate"}, |
| 286 | }; | 309 | }; |
| 287 | // clang-format on | 310 | // clang-format on |
| @@ -441,7 +464,11 @@ IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_ | |||
| 441 | {800, nullptr, "RequestVersionList"}, | 464 | {800, nullptr, "RequestVersionList"}, |
| 442 | {801, nullptr, "ListVersionList"}, | 465 | {801, nullptr, "ListVersionList"}, |
| 443 | {802, nullptr, "RequestVersionListData"}, | 466 | {802, nullptr, "RequestVersionListData"}, |
| 467 | {900, nullptr, "ImportAutoUpdatePolicyJsonForDebug"}, | ||
| 468 | {901, nullptr, "ListDefaultAutoUpdatePolicy"}, | ||
| 469 | {902, nullptr, "ListAutoUpdatePolicyForSpecificApplication"}, | ||
| 444 | {1000, nullptr, "PerformAutoUpdate"}, | 470 | {1000, nullptr, "PerformAutoUpdate"}, |
| 471 | {1001, nullptr, "ListAutoUpdateSchedule"}, | ||
| 445 | }; | 472 | }; |
| 446 | // clang-format on | 473 | // clang-format on |
| 447 | 474 | ||
| @@ -547,6 +574,9 @@ IFactoryResetInterface::~IFactoryResetInterface() = default; | |||
| 547 | NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { | 574 | NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { |
| 548 | // clang-format off | 575 | // clang-format off |
| 549 | static const FunctionInfo functions[] = { | 576 | static const FunctionInfo functions[] = { |
| 577 | {7988, nullptr, "GetDynamicRightsInterface"}, | ||
| 578 | {7989, nullptr, "GetReadOnlyApplicationControlDataInterface"}, | ||
| 579 | {7991, nullptr, "GetReadOnlyApplicationRecordInterface"}, | ||
| 550 | {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, | 580 | {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, |
| 551 | {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, | 581 | {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, |
| 552 | {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, | 582 | {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, |
| @@ -575,18 +605,22 @@ public: | |||
| 575 | {0, nullptr, "LaunchProgram"}, | 605 | {0, nullptr, "LaunchProgram"}, |
| 576 | {1, nullptr, "TerminateProcess"}, | 606 | {1, nullptr, "TerminateProcess"}, |
| 577 | {2, nullptr, "TerminateProgram"}, | 607 | {2, nullptr, "TerminateProgram"}, |
| 578 | {4, nullptr, "GetShellEventHandle"}, | 608 | {4, nullptr, "GetShellEvent"}, |
| 579 | {5, nullptr, "GetShellEventInfo"}, | 609 | {5, nullptr, "GetShellEventInfo"}, |
| 580 | {6, nullptr, "TerminateApplication"}, | 610 | {6, nullptr, "TerminateApplication"}, |
| 581 | {7, nullptr, "PrepareLaunchProgramFromHost"}, | 611 | {7, nullptr, "PrepareLaunchProgramFromHost"}, |
| 582 | {8, nullptr, "LaunchApplication"}, | 612 | {8, nullptr, "LaunchApplicationFromHost"}, |
| 583 | {9, nullptr, "LaunchApplicationWithStorageIdForDevelop"}, | 613 | {9, nullptr, "LaunchApplicationWithStorageIdForDevelop"}, |
| 584 | {10, nullptr, "IsSystemMemoryResourceLimitBoosted"}, | 614 | {10, nullptr, "IsSystemMemoryResourceLimitBoosted"}, |
| 585 | {11, nullptr, "GetRunningApplicationProcessIdForDevelop"}, | 615 | {11, nullptr, "GetRunningApplicationProcessIdForDevelop"}, |
| 586 | {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"}, | 616 | {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"}, |
| 587 | {13, nullptr, "CreateApplicationResourceForDevelop"}, | 617 | {13, nullptr, "CreateApplicationResourceForDevelop"}, |
| 588 | {14, nullptr, "IsPreomiaForDevelop"}, | 618 | {14, nullptr, "IsPreomiaForDevelop"}, |
| 589 | {15, nullptr, "GetApplicationProgramIdFromHost"}, | 619 | {15, nullptr, "GetApplicationProgramIdFromHost"}, |
| 620 | {16, nullptr, "RefreshCachedDebugValues"}, | ||
| 621 | {17, nullptr, "PrepareLaunchApplicationFromHost"}, | ||
| 622 | {18, nullptr, "GetLaunchEvent"}, | ||
| 623 | {19, nullptr, "GetLaunchResult"}, | ||
| 590 | }; | 624 | }; |
| 591 | // clang-format on | 625 | // clang-format on |
| 592 | 626 | ||
| @@ -699,6 +733,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system | |||
| 699 | std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager); | 733 | std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager); |
| 700 | std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); | 734 | std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); |
| 701 | std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); | 735 | std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); |
| 736 | std::make_shared<NS>("ns:ro", system)->InstallAsService(service_manager); | ||
| 702 | 737 | ||
| 703 | std::make_shared<NS_DEV>(system)->InstallAsService(service_manager); | 738 | std::make_shared<NS_DEV>(system)->InstallAsService(service_manager); |
| 704 | std::make_shared<NS_SU>(system)->InstallAsService(service_manager); | 739 | std::make_shared<NS_SU>(system)->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index fcd15d81f..da139fdc4 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp | |||
| @@ -154,6 +154,10 @@ PL_U::PL_U(Core::System& system_) | |||
| 154 | {100, nullptr, "RequestApplicationFunctionAuthorization"}, | 154 | {100, nullptr, "RequestApplicationFunctionAuthorization"}, |
| 155 | {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, | 155 | {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, |
| 156 | {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, | 156 | {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, |
| 157 | {103, nullptr, "RefreshApplicationFunctionBlackListDebugRecord"}, | ||
| 158 | {104, nullptr, "RequestApplicationFunctionAuthorizationByProgramId"}, | ||
| 159 | {105, nullptr, "GetFunctionBlackListSystemVersionToAuthorize"}, | ||
| 160 | {106, nullptr, "GetFunctionBlackListVersion"}, | ||
| 157 | {1000, nullptr, "LoadNgWordDataForPlatformRegionChina"}, | 161 | {1000, nullptr, "LoadNgWordDataForPlatformRegionChina"}, |
| 158 | {1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"}, | 162 | {1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"}, |
| 159 | }; | 163 | }; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 933d42f3f..2edd803f3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -248,7 +248,13 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector< | |||
| 248 | IoctlZbcSetTable params{}; | 248 | IoctlZbcSetTable params{}; |
| 249 | std::memcpy(¶ms, input.data(), input.size()); | 249 | std::memcpy(¶ms, input.data(), input.size()); |
| 250 | // TODO(ogniK): What does this even actually do? | 250 | // TODO(ogniK): What does this even actually do? |
| 251 | std::memcpy(output.data(), ¶ms, output.size()); | 251 | |
| 252 | // Prevent null pointer being passed as arg 1 | ||
| 253 | if (output.empty()) { | ||
| 254 | LOG_WARNING(Service_NVDRV, "Avoiding passing null pointer to memcpy"); | ||
| 255 | } else { | ||
| 256 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 257 | } | ||
| 252 | return NvResult::Success; | 258 | return NvResult::Success; |
| 253 | } | 259 | } |
| 254 | 260 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 4898dc27a..c2f152190 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -23,17 +23,22 @@ namespace { | |||
| 23 | template <typename T> | 23 | template <typename T> |
| 24 | std::size_t SpliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count, | 24 | std::size_t SpliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count, |
| 25 | std::size_t offset) { | 25 | std::size_t offset) { |
| 26 | std::memcpy(dst.data(), input.data() + offset, count * sizeof(T)); | 26 | if (!dst.empty()) { |
| 27 | offset += count * sizeof(T); | 27 | std::memcpy(dst.data(), input.data() + offset, count * sizeof(T)); |
| 28 | return offset; | 28 | } |
| 29 | return 0; | ||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | // Write vectors will write data to the output buffer | 32 | // Write vectors will write data to the output buffer |
| 32 | template <typename T> | 33 | template <typename T> |
| 33 | std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) { | 34 | std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) { |
| 34 | std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T)); | 35 | if (src.empty()) { |
| 35 | offset += src.size() * sizeof(T); | 36 | return 0; |
| 36 | return offset; | 37 | } else { |
| 38 | std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T)); | ||
| 39 | offset += src.size() * sizeof(T); | ||
| 40 | return offset; | ||
| 41 | } | ||
| 37 | } | 42 | } |
| 38 | } // Anonymous namespace | 43 | } // Anonymous namespace |
| 39 | 44 | ||
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp index e2ac71fa1..b066c3417 100644 --- a/src/core/hle/service/olsc/olsc.cpp +++ b/src/core/hle/service/olsc/olsc.cpp | |||
| @@ -26,6 +26,7 @@ public: | |||
| 26 | {22, nullptr, "DeleteSaveDataBackupAsync"}, | 26 | {22, nullptr, "DeleteSaveDataBackupAsync"}, |
| 27 | {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"}, | 27 | {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"}, |
| 28 | {26, nullptr, "DownloadSaveDataBackupAsync"}, | 28 | {26, nullptr, "DownloadSaveDataBackupAsync"}, |
| 29 | {27, nullptr, "UploadSaveDataBackupAsync"}, | ||
| 29 | {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"}, | 30 | {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"}, |
| 30 | {9013, nullptr, "GetSaveDataBackupSettingForDebug"}, | 31 | {9013, nullptr, "GetSaveDataBackupSettingForDebug"}, |
| 31 | {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"}, | 32 | {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"}, |
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp index f6686fc4d..9bc851591 100644 --- a/src/core/hle/service/pcie/pcie.cpp +++ b/src/core/hle/service/pcie/pcie.cpp | |||
| @@ -37,7 +37,7 @@ public: | |||
| 37 | {19, nullptr, "SetIrqEnable"}, | 37 | {19, nullptr, "SetIrqEnable"}, |
| 38 | {20, nullptr, "SetAspmEnable"}, | 38 | {20, nullptr, "SetAspmEnable"}, |
| 39 | {21, nullptr, "SetResetUponResumeEnable"}, | 39 | {21, nullptr, "SetResetUponResumeEnable"}, |
| 40 | {22, nullptr, "Unknown22"}, | 40 | {22, nullptr, "ResetFunction"}, |
| 41 | {23, nullptr, "Unknown23"}, | 41 | {23, nullptr, "Unknown23"}, |
| 42 | }; | 42 | }; |
| 43 | // clang-format on | 43 | // clang-format on |
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp index f9089bf2f..dc59702f1 100644 --- a/src/core/hle/service/pctl/module.cpp +++ b/src/core/hle/service/pctl/module.cpp | |||
| @@ -3,16 +3,30 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/core.h" | ||
| 7 | #include "core/file_sys/control_metadata.h" | ||
| 8 | #include "core/file_sys/patch_manager.h" | ||
| 6 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/process.h" | ||
| 7 | #include "core/hle/service/pctl/module.h" | 11 | #include "core/hle/service/pctl/module.h" |
| 8 | #include "core/hle/service/pctl/pctl.h" | 12 | #include "core/hle/service/pctl/pctl.h" |
| 9 | 13 | ||
| 10 | namespace Service::PCTL { | 14 | namespace Service::PCTL { |
| 11 | 15 | ||
| 16 | namespace Error { | ||
| 17 | |||
| 18 | constexpr ResultCode ResultNoFreeCommunication{ErrorModule::PCTL, 101}; | ||
| 19 | constexpr ResultCode ResultStereoVisionRestricted{ErrorModule::PCTL, 104}; | ||
| 20 | constexpr ResultCode ResultNoCapability{ErrorModule::PCTL, 131}; | ||
| 21 | constexpr ResultCode ResultNoRestrictionEnabled{ErrorModule::PCTL, 181}; | ||
| 22 | |||
| 23 | } // namespace Error | ||
| 24 | |||
| 12 | class IParentalControlService final : public ServiceFramework<IParentalControlService> { | 25 | class IParentalControlService final : public ServiceFramework<IParentalControlService> { |
| 13 | public: | 26 | public: |
| 14 | explicit IParentalControlService(Core::System& system_) | 27 | explicit IParentalControlService(Core::System& system_, Capability capability) |
| 15 | : ServiceFramework{system_, "IParentalControlService"} { | 28 | : ServiceFramework{system_, "IParentalControlService"}, system(system_), |
| 29 | capability(capability) { | ||
| 16 | // clang-format off | 30 | // clang-format off |
| 17 | static const FunctionInfo functions[] = { | 31 | static const FunctionInfo functions[] = { |
| 18 | {1, &IParentalControlService::Initialize, "Initialize"}, | 32 | {1, &IParentalControlService::Initialize, "Initialize"}, |
| @@ -28,13 +42,13 @@ public: | |||
| 28 | {1010, nullptr, "IsRestrictedSystemSettingsEntered"}, | 42 | {1010, nullptr, "IsRestrictedSystemSettingsEntered"}, |
| 29 | {1011, nullptr, "RevertRestrictedSystemSettingsEntered"}, | 43 | {1011, nullptr, "RevertRestrictedSystemSettingsEntered"}, |
| 30 | {1012, nullptr, "GetRestrictedFeatures"}, | 44 | {1012, nullptr, "GetRestrictedFeatures"}, |
| 31 | {1013, nullptr, "ConfirmStereoVisionPermission"}, | 45 | {1013, &IParentalControlService::ConfirmStereoVisionPermission, "ConfirmStereoVisionPermission"}, |
| 32 | {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, | 46 | {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, |
| 33 | {1015, nullptr, "ConfirmPlayableApplicationVideo"}, | 47 | {1015, nullptr, "ConfirmPlayableApplicationVideo"}, |
| 34 | {1016, nullptr, "ConfirmShowNewsPermission"}, | 48 | {1016, nullptr, "ConfirmShowNewsPermission"}, |
| 35 | {1017, nullptr, "EndFreeCommunication"}, | 49 | {1017, nullptr, "EndFreeCommunication"}, |
| 36 | {1018, nullptr, "IsFreeCommunicationAvailable"}, | 50 | {1018, &IParentalControlService::IsFreeCommunicationAvailable, "IsFreeCommunicationAvailable"}, |
| 37 | {1031, nullptr, "IsRestrictionEnabled"}, | 51 | {1031, &IParentalControlService::IsRestrictionEnabled, "IsRestrictionEnabled"}, |
| 38 | {1032, nullptr, "GetSafetyLevel"}, | 52 | {1032, nullptr, "GetSafetyLevel"}, |
| 39 | {1033, nullptr, "SetSafetyLevel"}, | 53 | {1033, nullptr, "SetSafetyLevel"}, |
| 40 | {1034, nullptr, "GetSafetyLevelSettings"}, | 54 | {1034, nullptr, "GetSafetyLevelSettings"}, |
| @@ -50,6 +64,7 @@ public: | |||
| 50 | {1046, nullptr, "DisableFeaturesForReset"}, | 64 | {1046, nullptr, "DisableFeaturesForReset"}, |
| 51 | {1047, nullptr, "NotifyApplicationDownloadStarted"}, | 65 | {1047, nullptr, "NotifyApplicationDownloadStarted"}, |
| 52 | {1048, nullptr, "NotifyNetworkProfileCreated"}, | 66 | {1048, nullptr, "NotifyNetworkProfileCreated"}, |
| 67 | {1049, nullptr, "ResetFreeCommunicationApplicationList"}, | ||
| 53 | {1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"}, | 68 | {1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"}, |
| 54 | {1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"}, | 69 | {1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"}, |
| 55 | {1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"}, | 70 | {1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"}, |
| @@ -69,6 +84,8 @@ public: | |||
| 69 | {1421, nullptr, "GetAccountNickname"}, | 84 | {1421, nullptr, "GetAccountNickname"}, |
| 70 | {1424, nullptr, "GetAccountState"}, | 85 | {1424, nullptr, "GetAccountState"}, |
| 71 | {1425, nullptr, "RequestPostEvents"}, | 86 | {1425, nullptr, "RequestPostEvents"}, |
| 87 | {1426, nullptr, "GetPostEventInterval"}, | ||
| 88 | {1427, nullptr, "SetPostEventInterval"}, | ||
| 72 | {1432, nullptr, "GetSynchronizationEvent"}, | 89 | {1432, nullptr, "GetSynchronizationEvent"}, |
| 73 | {1451, nullptr, "StartPlayTimer"}, | 90 | {1451, nullptr, "StartPlayTimer"}, |
| 74 | {1452, nullptr, "StopPlayTimer"}, | 91 | {1452, nullptr, "StopPlayTimer"}, |
| @@ -119,62 +136,235 @@ public: | |||
| 119 | } | 136 | } |
| 120 | 137 | ||
| 121 | private: | 138 | private: |
| 139 | bool CheckFreeCommunicationPermissionImpl() const { | ||
| 140 | if (states.temporary_unlocked) { | ||
| 141 | return true; | ||
| 142 | } | ||
| 143 | if ((states.application_info.parental_control_flag & 1) == 0) { | ||
| 144 | return true; | ||
| 145 | } | ||
| 146 | if (pin_code[0] == '\0') { | ||
| 147 | return true; | ||
| 148 | } | ||
| 149 | if (!settings.is_free_communication_default_on) { | ||
| 150 | return true; | ||
| 151 | } | ||
| 152 | // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here | ||
| 153 | // but as we don't have multiproceses support yet, we can just assume our application is | ||
| 154 | // valid for the time being | ||
| 155 | return true; | ||
| 156 | } | ||
| 157 | |||
| 158 | bool ConfirmStereoVisionPermissionImpl() const { | ||
| 159 | if (states.temporary_unlocked) { | ||
| 160 | return true; | ||
| 161 | } | ||
| 162 | if (pin_code[0] == '\0') { | ||
| 163 | return true; | ||
| 164 | } | ||
| 165 | if (!settings.is_stero_vision_restricted) { | ||
| 166 | return false; | ||
| 167 | } | ||
| 168 | return true; | ||
| 169 | } | ||
| 170 | |||
| 171 | void SetStereoVisionRestrictionImpl(bool is_restricted) { | ||
| 172 | if (settings.disabled) { | ||
| 173 | return; | ||
| 174 | } | ||
| 175 | |||
| 176 | if (pin_code[0] == '\0') { | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | settings.is_stero_vision_restricted = is_restricted; | ||
| 180 | } | ||
| 181 | |||
| 122 | void Initialize(Kernel::HLERequestContext& ctx) { | 182 | void Initialize(Kernel::HLERequestContext& ctx) { |
| 123 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); | 183 | LOG_DEBUG(Service_PCTL, "called"); |
| 184 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 185 | |||
| 186 | if (False(capability & (Capability::Application | Capability::System))) { | ||
| 187 | LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability); | ||
| 188 | return; | ||
| 189 | } | ||
| 190 | |||
| 191 | // TODO(ogniK): Recovery flag initialization for pctl:r | ||
| 192 | |||
| 193 | const auto tid = system.CurrentProcess()->GetTitleID(); | ||
| 194 | if (tid != 0) { | ||
| 195 | const FileSys::PatchManager pm{tid, system.GetFileSystemController(), | ||
| 196 | system.GetContentProvider()}; | ||
| 197 | const auto control = pm.GetControlMetadata(); | ||
| 198 | if (control.first) { | ||
| 199 | states.tid_from_event = 0; | ||
| 200 | states.launch_time_valid = false; | ||
| 201 | states.is_suspended = false; | ||
| 202 | states.free_communication = false; | ||
| 203 | states.stereo_vision = false; | ||
| 204 | states.application_info = ApplicationInfo{ | ||
| 205 | .tid = tid, | ||
| 206 | .age_rating = control.first->GetRatingAge(), | ||
| 207 | .parental_control_flag = control.first->GetParentalControlFlag(), | ||
| 208 | .capability = capability, | ||
| 209 | }; | ||
| 210 | |||
| 211 | if (False(capability & (Capability::System | Capability::Recovery))) { | ||
| 212 | // TODO(ogniK): Signal application launch event | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } | ||
| 124 | 216 | ||
| 125 | IPC::ResponseBuilder rb{ctx, 2, 0, 0}; | ||
| 126 | rb.Push(RESULT_SUCCESS); | 217 | rb.Push(RESULT_SUCCESS); |
| 127 | } | 218 | } |
| 128 | 219 | ||
| 129 | void CheckFreeCommunicationPermission(Kernel::HLERequestContext& ctx) { | 220 | void CheckFreeCommunicationPermission(Kernel::HLERequestContext& ctx) { |
| 130 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); | 221 | LOG_DEBUG(Service_PCTL, "called"); |
| 222 | |||
| 223 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 224 | if (!CheckFreeCommunicationPermissionImpl()) { | ||
| 225 | rb.Push(Error::ResultNoFreeCommunication); | ||
| 226 | } else { | ||
| 227 | rb.Push(RESULT_SUCCESS); | ||
| 228 | } | ||
| 229 | |||
| 230 | states.free_communication = true; | ||
| 231 | } | ||
| 232 | |||
| 233 | void ConfirmStereoVisionPermission(Kernel::HLERequestContext& ctx) { | ||
| 234 | LOG_DEBUG(Service_PCTL, "called"); | ||
| 235 | states.stereo_vision = true; | ||
| 131 | 236 | ||
| 132 | IPC::ResponseBuilder rb{ctx, 2}; | 237 | IPC::ResponseBuilder rb{ctx, 2}; |
| 133 | rb.Push(RESULT_SUCCESS); | 238 | rb.Push(RESULT_SUCCESS); |
| 134 | } | 239 | } |
| 135 | 240 | ||
| 136 | void ConfirmStereoVisionRestrictionConfigurable(Kernel::HLERequestContext& ctx) { | 241 | void IsFreeCommunicationAvailable(Kernel::HLERequestContext& ctx) { |
| 137 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); | 242 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); |
| 138 | 243 | ||
| 139 | IPC::ResponseBuilder rb{ctx, 2}; | 244 | IPC::ResponseBuilder rb{ctx, 2}; |
| 245 | if (!CheckFreeCommunicationPermissionImpl()) { | ||
| 246 | rb.Push(Error::ResultNoFreeCommunication); | ||
| 247 | } else { | ||
| 248 | rb.Push(RESULT_SUCCESS); | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | void IsRestrictionEnabled(Kernel::HLERequestContext& ctx) { | ||
| 253 | LOG_DEBUG(Service_PCTL, "called"); | ||
| 254 | |||
| 255 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 256 | if (False(capability & (Capability::Status | Capability::Recovery))) { | ||
| 257 | LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!"); | ||
| 258 | rb.Push(Error::ResultNoCapability); | ||
| 259 | rb.Push(false); | ||
| 260 | return; | ||
| 261 | } | ||
| 262 | |||
| 263 | rb.Push(pin_code[0] != '\0'); | ||
| 264 | } | ||
| 265 | |||
| 266 | void ConfirmStereoVisionRestrictionConfigurable(Kernel::HLERequestContext& ctx) { | ||
| 267 | LOG_DEBUG(Service_PCTL, "called"); | ||
| 268 | |||
| 269 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 270 | |||
| 271 | if (False(capability & Capability::StereoVision)) { | ||
| 272 | LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); | ||
| 273 | rb.Push(Error::ResultNoCapability); | ||
| 274 | return; | ||
| 275 | } | ||
| 276 | |||
| 277 | if (pin_code[0] == '\0') { | ||
| 278 | rb.Push(Error::ResultNoRestrictionEnabled); | ||
| 279 | return; | ||
| 280 | } | ||
| 281 | |||
| 140 | rb.Push(RESULT_SUCCESS); | 282 | rb.Push(RESULT_SUCCESS); |
| 141 | } | 283 | } |
| 142 | 284 | ||
| 143 | void IsStereoVisionPermitted(Kernel::HLERequestContext& ctx) { | 285 | void IsStereoVisionPermitted(Kernel::HLERequestContext& ctx) { |
| 144 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); | 286 | LOG_DEBUG(Service_PCTL, "called"); |
| 145 | 287 | ||
| 146 | IPC::ResponseBuilder rb{ctx, 3}; | 288 | IPC::ResponseBuilder rb{ctx, 3}; |
| 147 | rb.Push(RESULT_SUCCESS); | 289 | if (!ConfirmStereoVisionPermissionImpl()) { |
| 148 | rb.Push(true); | 290 | rb.Push(Error::ResultStereoVisionRestricted); |
| 291 | rb.Push(false); | ||
| 292 | } else { | ||
| 293 | rb.Push(RESULT_SUCCESS); | ||
| 294 | rb.Push(true); | ||
| 295 | } | ||
| 149 | } | 296 | } |
| 150 | 297 | ||
| 151 | void SetStereoVisionRestriction(Kernel::HLERequestContext& ctx) { | 298 | void SetStereoVisionRestriction(Kernel::HLERequestContext& ctx) { |
| 152 | IPC::RequestParser rp{ctx}; | 299 | IPC::RequestParser rp{ctx}; |
| 153 | const auto can_use = rp.Pop<bool>(); | 300 | const auto can_use = rp.Pop<bool>(); |
| 154 | LOG_WARNING(Service_PCTL, "(STUBBED) called, can_use={}", can_use); | 301 | LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use); |
| 155 | |||
| 156 | can_use_stereo_vision = can_use; | ||
| 157 | 302 | ||
| 158 | IPC::ResponseBuilder rb{ctx, 2}; | 303 | IPC::ResponseBuilder rb{ctx, 2}; |
| 304 | if (False(capability & Capability::StereoVision)) { | ||
| 305 | LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); | ||
| 306 | rb.Push(Error::ResultNoCapability); | ||
| 307 | return; | ||
| 308 | } | ||
| 309 | |||
| 310 | SetStereoVisionRestrictionImpl(can_use); | ||
| 159 | rb.Push(RESULT_SUCCESS); | 311 | rb.Push(RESULT_SUCCESS); |
| 160 | } | 312 | } |
| 161 | 313 | ||
| 162 | void GetStereoVisionRestriction(Kernel::HLERequestContext& ctx) { | 314 | void GetStereoVisionRestriction(Kernel::HLERequestContext& ctx) { |
| 163 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); | 315 | LOG_DEBUG(Service_PCTL, "called"); |
| 164 | 316 | ||
| 165 | IPC::ResponseBuilder rb{ctx, 3}; | 317 | IPC::ResponseBuilder rb{ctx, 3}; |
| 318 | if (False(capability & Capability::StereoVision)) { | ||
| 319 | LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); | ||
| 320 | rb.Push(Error::ResultNoCapability); | ||
| 321 | rb.Push(false); | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | |||
| 166 | rb.Push(RESULT_SUCCESS); | 325 | rb.Push(RESULT_SUCCESS); |
| 167 | rb.Push(can_use_stereo_vision); | 326 | rb.Push(settings.is_stero_vision_restricted); |
| 168 | } | 327 | } |
| 169 | 328 | ||
| 170 | void ResetConfirmedStereoVisionPermission(Kernel::HLERequestContext& ctx) { | 329 | void ResetConfirmedStereoVisionPermission(Kernel::HLERequestContext& ctx) { |
| 171 | LOG_WARNING(Service_PCTL, "(STUBBED) called"); | 330 | LOG_DEBUG(Service_PCTL, "called"); |
| 331 | |||
| 332 | states.stereo_vision = false; | ||
| 172 | 333 | ||
| 173 | IPC::ResponseBuilder rb{ctx, 2}; | 334 | IPC::ResponseBuilder rb{ctx, 2}; |
| 174 | rb.Push(RESULT_SUCCESS); | 335 | rb.Push(RESULT_SUCCESS); |
| 175 | } | 336 | } |
| 176 | 337 | ||
| 338 | struct ApplicationInfo { | ||
| 339 | u64 tid{}; | ||
| 340 | std::array<u8, 32> age_rating{}; | ||
| 341 | u32 parental_control_flag{}; | ||
| 342 | Capability capability{}; | ||
| 343 | }; | ||
| 344 | |||
| 345 | struct States { | ||
| 346 | u64 current_tid{}; | ||
| 347 | ApplicationInfo application_info{}; | ||
| 348 | u64 tid_from_event{}; | ||
| 349 | bool launch_time_valid{}; | ||
| 350 | bool is_suspended{}; | ||
| 351 | bool temporary_unlocked{}; | ||
| 352 | bool free_communication{}; | ||
| 353 | bool stereo_vision{}; | ||
| 354 | }; | ||
| 355 | |||
| 356 | struct ParentalControlSettings { | ||
| 357 | bool is_stero_vision_restricted{}; | ||
| 358 | bool is_free_communication_default_on{}; | ||
| 359 | bool disabled{}; | ||
| 360 | }; | ||
| 361 | |||
| 362 | States states{}; | ||
| 363 | ParentalControlSettings settings{}; | ||
| 364 | std::array<char, 8> pin_code{}; | ||
| 177 | bool can_use_stereo_vision = true; | 365 | bool can_use_stereo_vision = true; |
| 366 | Core::System& system; | ||
| 367 | Capability capability{}; | ||
| 178 | }; | 368 | }; |
| 179 | 369 | ||
| 180 | void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) { | 370 | void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) { |
| @@ -182,7 +372,9 @@ void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) { | |||
| 182 | 372 | ||
| 183 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 373 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 184 | rb.Push(RESULT_SUCCESS); | 374 | rb.Push(RESULT_SUCCESS); |
| 185 | rb.PushIpcInterface<IParentalControlService>(system); | 375 | // TODO(ogniK): Get TID from process |
| 376 | |||
| 377 | rb.PushIpcInterface<IParentalControlService>(system, capability); | ||
| 186 | } | 378 | } |
| 187 | 379 | ||
| 188 | void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { | 380 | void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { |
| @@ -190,21 +382,28 @@ void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext | |||
| 190 | 382 | ||
| 191 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 383 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 192 | rb.Push(RESULT_SUCCESS); | 384 | rb.Push(RESULT_SUCCESS); |
| 193 | rb.PushIpcInterface<IParentalControlService>(system); | 385 | rb.PushIpcInterface<IParentalControlService>(system, capability); |
| 194 | } | 386 | } |
| 195 | 387 | ||
| 196 | Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_, | 388 | Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_, |
| 197 | const char* name) | 389 | const char* name, Capability capability) |
| 198 | : ServiceFramework{system_, name}, module{std::move(module_)} {} | 390 | : ServiceFramework{system_, name}, module{std::move(module_)}, capability(capability) {} |
| 199 | 391 | ||
| 200 | Module::Interface::~Interface() = default; | 392 | Module::Interface::~Interface() = default; |
| 201 | 393 | ||
| 202 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { | 394 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { |
| 203 | auto module = std::make_shared<Module>(); | 395 | auto module = std::make_shared<Module>(); |
| 204 | std::make_shared<PCTL>(system, module, "pctl")->InstallAsService(service_manager); | 396 | std::make_shared<PCTL>(system, module, "pctl", |
| 205 | std::make_shared<PCTL>(system, module, "pctl:a")->InstallAsService(service_manager); | 397 | Capability::Application | Capability::SnsPost | Capability::Status | |
| 206 | std::make_shared<PCTL>(system, module, "pctl:r")->InstallAsService(service_manager); | 398 | Capability::StereoVision) |
| 207 | std::make_shared<PCTL>(system, module, "pctl:s")->InstallAsService(service_manager); | 399 | ->InstallAsService(service_manager); |
| 400 | // TODO(ogniK): Implement remaining capabilities | ||
| 401 | std::make_shared<PCTL>(system, module, "pctl:a", Capability::None) | ||
| 402 | ->InstallAsService(service_manager); | ||
| 403 | std::make_shared<PCTL>(system, module, "pctl:r", Capability::None) | ||
| 404 | ->InstallAsService(service_manager); | ||
| 405 | std::make_shared<PCTL>(system, module, "pctl:s", Capability::None) | ||
| 406 | ->InstallAsService(service_manager); | ||
| 208 | } | 407 | } |
| 209 | 408 | ||
| 210 | } // namespace Service::PCTL | 409 | } // namespace Service::PCTL |
diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/module.h index 4c7e09a3b..032481b00 100644 --- a/src/core/hle/service/pctl/module.h +++ b/src/core/hle/service/pctl/module.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_funcs.h" | ||
| 7 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 8 | 9 | ||
| 9 | namespace Core { | 10 | namespace Core { |
| @@ -12,12 +13,23 @@ class System; | |||
| 12 | 13 | ||
| 13 | namespace Service::PCTL { | 14 | namespace Service::PCTL { |
| 14 | 15 | ||
| 16 | enum class Capability : u32 { | ||
| 17 | None = 0, | ||
| 18 | Application = 1 << 0, | ||
| 19 | SnsPost = 1 << 1, | ||
| 20 | Recovery = 1 << 6, | ||
| 21 | Status = 1 << 8, | ||
| 22 | StereoVision = 1 << 9, | ||
| 23 | System = 1 << 15, | ||
| 24 | }; | ||
| 25 | DECLARE_ENUM_FLAG_OPERATORS(Capability); | ||
| 26 | |||
| 15 | class Module final { | 27 | class Module final { |
| 16 | public: | 28 | public: |
| 17 | class Interface : public ServiceFramework<Interface> { | 29 | class Interface : public ServiceFramework<Interface> { |
| 18 | public: | 30 | public: |
| 19 | explicit Interface(Core::System& system_, std::shared_ptr<Module> module_, | 31 | explicit Interface(Core::System& system_, std::shared_ptr<Module> module_, const char* name, |
| 20 | const char* name); | 32 | Capability capability); |
| 21 | ~Interface() override; | 33 | ~Interface() override; |
| 22 | 34 | ||
| 23 | void CreateService(Kernel::HLERequestContext& ctx); | 35 | void CreateService(Kernel::HLERequestContext& ctx); |
| @@ -25,6 +37,9 @@ public: | |||
| 25 | 37 | ||
| 26 | protected: | 38 | protected: |
| 27 | std::shared_ptr<Module> module; | 39 | std::shared_ptr<Module> module; |
| 40 | |||
| 41 | private: | ||
| 42 | Capability capability{}; | ||
| 28 | }; | 43 | }; |
| 29 | }; | 44 | }; |
| 30 | 45 | ||
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp index 16dd34f90..e4d155c86 100644 --- a/src/core/hle/service/pctl/pctl.cpp +++ b/src/core/hle/service/pctl/pctl.cpp | |||
| @@ -6,8 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | namespace Service::PCTL { | 7 | namespace Service::PCTL { |
| 8 | 8 | ||
| 9 | PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name) | 9 | PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name, |
| 10 | : Interface{system_, std::move(module_), name} { | 10 | Capability capability) |
| 11 | : Interface{system_, std::move(module_), name, capability} { | ||
| 11 | static const FunctionInfo functions[] = { | 12 | static const FunctionInfo functions[] = { |
| 12 | {0, &PCTL::CreateService, "CreateService"}, | 13 | {0, &PCTL::CreateService, "CreateService"}, |
| 13 | {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, | 14 | {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, |
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h index 275d23007..fd0a1e486 100644 --- a/src/core/hle/service/pctl/pctl.h +++ b/src/core/hle/service/pctl/pctl.h | |||
| @@ -14,7 +14,8 @@ namespace Service::PCTL { | |||
| 14 | 14 | ||
| 15 | class PCTL final : public Module::Interface { | 15 | class PCTL final : public Module::Interface { |
| 16 | public: | 16 | public: |
| 17 | explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name); | 17 | explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name, |
| 18 | Capability capability); | ||
| 18 | ~PCTL() override; | 19 | ~PCTL() override; |
| 19 | }; | 20 | }; |
| 20 | 21 | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 1da56bc27..aec399076 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -70,6 +70,7 @@ | |||
| 70 | #include "core/hle/service/vi/vi.h" | 70 | #include "core/hle/service/vi/vi.h" |
| 71 | #include "core/hle/service/wlan/wlan.h" | 71 | #include "core/hle/service/wlan/wlan.h" |
| 72 | #include "core/reporter.h" | 72 | #include "core/reporter.h" |
| 73 | #include "core/settings.h" | ||
| 73 | 74 | ||
| 74 | namespace Service { | 75 | namespace Service { |
| 75 | 76 | ||
| @@ -146,6 +147,11 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext | |||
| 146 | system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name, | 147 | system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name, |
| 147 | service_name); | 148 | service_name); |
| 148 | UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf)); | 149 | UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf)); |
| 150 | if (Settings::values.use_auto_stub) { | ||
| 151 | LOG_WARNING(Service, "Using auto stub fallback!"); | ||
| 152 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 153 | rb.Push(RESULT_SUCCESS); | ||
| 154 | } | ||
| 149 | } | 155 | } |
| 150 | 156 | ||
| 151 | void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { | 157 | void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index b58b2c8c5..5909fdd85 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp | |||
| @@ -261,6 +261,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||
| 261 | {155, nullptr, "SetAccountOnlineStorageSettings"}, | 261 | {155, nullptr, "SetAccountOnlineStorageSettings"}, |
| 262 | {156, nullptr, "GetPctlReadyFlag"}, | 262 | {156, nullptr, "GetPctlReadyFlag"}, |
| 263 | {157, nullptr, "SetPctlReadyFlag"}, | 263 | {157, nullptr, "SetPctlReadyFlag"}, |
| 264 | {158, nullptr, "GetAnalogStickUserCalibrationL"}, | ||
| 265 | {159, nullptr, "SetAnalogStickUserCalibrationL"}, | ||
| 266 | {160, nullptr, "GetAnalogStickUserCalibrationR"}, | ||
| 267 | {161, nullptr, "SetAnalogStickUserCalibrationR"}, | ||
| 264 | {162, nullptr, "GetPtmBatteryVersion"}, | 268 | {162, nullptr, "GetPtmBatteryVersion"}, |
| 265 | {163, nullptr, "SetPtmBatteryVersion"}, | 269 | {163, nullptr, "SetPtmBatteryVersion"}, |
| 266 | {164, nullptr, "GetUsb30HostEnableFlag"}, | 270 | {164, nullptr, "GetUsb30HostEnableFlag"}, |
| @@ -302,6 +306,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||
| 302 | {200, nullptr, "SetButtonConfigRegisteredSettings"}, | 306 | {200, nullptr, "SetButtonConfigRegisteredSettings"}, |
| 303 | {201, nullptr, "GetFieldTestingFlag"}, | 307 | {201, nullptr, "GetFieldTestingFlag"}, |
| 304 | {202, nullptr, "SetFieldTestingFlag"}, | 308 | {202, nullptr, "SetFieldTestingFlag"}, |
| 309 | {203, nullptr, "GetPanelCrcMode"}, | ||
| 310 | {204, nullptr, "SetPanelCrcMode"}, | ||
| 305 | }; | 311 | }; |
| 306 | // clang-format on | 312 | // clang-format on |
| 307 | 313 | ||
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 2b91a89d1..94608d529 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -190,10 +190,11 @@ SM::SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_) | |||
| 190 | : ServiceFramework{system_, "sm:", 4}, | 190 | : ServiceFramework{system_, "sm:", 4}, |
| 191 | service_manager{std::move(service_manager_)}, kernel{system_.Kernel()} { | 191 | service_manager{std::move(service_manager_)}, kernel{system_.Kernel()} { |
| 192 | static const FunctionInfo functions[] = { | 192 | static const FunctionInfo functions[] = { |
| 193 | {0x00000000, &SM::Initialize, "Initialize"}, | 193 | {0, &SM::Initialize, "Initialize"}, |
| 194 | {0x00000001, &SM::GetService, "GetService"}, | 194 | {1, &SM::GetService, "GetService"}, |
| 195 | {0x00000002, &SM::RegisterService, "RegisterService"}, | 195 | {2, &SM::RegisterService, "RegisterService"}, |
| 196 | {0x00000003, &SM::UnregisterService, "UnregisterService"}, | 196 | {3, &SM::UnregisterService, "UnregisterService"}, |
| 197 | {4, nullptr, "DetachClient"}, | ||
| 197 | }; | 198 | }; |
| 198 | RegisterHandlers(functions); | 199 | RegisterHandlers(functions); |
| 199 | } | 200 | } |
diff --git a/src/core/hle/service/sockets/ethc.cpp b/src/core/hle/service/sockets/ethc.cpp index 05681ca2d..899a64c2f 100644 --- a/src/core/hle/service/sockets/ethc.cpp +++ b/src/core/hle/service/sockets/ethc.cpp | |||
| @@ -15,6 +15,7 @@ ETHC_C::ETHC_C(Core::System& system_) : ServiceFramework{system_, "ethc:c"} { | |||
| 15 | {3, nullptr, "GetMediaList"}, | 15 | {3, nullptr, "GetMediaList"}, |
| 16 | {4, nullptr, "SetMediaType"}, | 16 | {4, nullptr, "SetMediaType"}, |
| 17 | {5, nullptr, "GetMediaType"}, | 17 | {5, nullptr, "GetMediaType"}, |
| 18 | {6, nullptr, "Unknown6"}, | ||
| 18 | }; | 19 | }; |
| 19 | // clang-format on | 20 | // clang-format on |
| 20 | 21 | ||
diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp index 51c3739bb..1159debc5 100644 --- a/src/core/hle/service/sockets/nsd.cpp +++ b/src/core/hle/service/sockets/nsd.cpp | |||
| @@ -9,6 +9,7 @@ namespace Service::Sockets { | |||
| 9 | NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { | 9 | NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} { |
| 10 | // clang-format off | 10 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 12 | {5, nullptr, "GetSettingUrl"}, | ||
| 12 | {10, nullptr, "GetSettingName"}, | 13 | {10, nullptr, "GetSettingName"}, |
| 13 | {11, nullptr, "GetEnvironmentIdentifier"}, | 14 | {11, nullptr, "GetEnvironmentIdentifier"}, |
| 14 | {12, nullptr, "GetDeviceId"}, | 15 | {12, nullptr, "GetDeviceId"}, |
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 3a6329f56..5c71f423c 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp | |||
| @@ -9,8 +9,8 @@ namespace Service::Sockets { | |||
| 9 | 9 | ||
| 10 | SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"} { | 10 | SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"} { |
| 11 | static const FunctionInfo functions[] = { | 11 | static const FunctionInfo functions[] = { |
| 12 | {0, nullptr, "SetDnsAddressesPrivate"}, | 12 | {0, nullptr, "SetDnsAddressesPrivateRequest"}, |
| 13 | {1, nullptr, "GetDnsAddressPrivate"}, | 13 | {1, nullptr, "GetDnsAddressPrivateRequest"}, |
| 14 | {2, nullptr, "GetHostByNameRequest"}, | 14 | {2, nullptr, "GetHostByNameRequest"}, |
| 15 | {3, nullptr, "GetHostByAddrRequest"}, | 15 | {3, nullptr, "GetHostByAddrRequest"}, |
| 16 | {4, nullptr, "GetHostStringErrorRequest"}, | 16 | {4, nullptr, "GetHostStringErrorRequest"}, |
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp index 4e212610f..fff3f3c42 100644 --- a/src/core/hle/service/spl/spl.cpp +++ b/src/core/hle/service/spl/spl.cpp | |||
| @@ -60,6 +60,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_) | |||
| 60 | {4, nullptr, "GenerateAesKey"}, | 60 | {4, nullptr, "GenerateAesKey"}, |
| 61 | {5, nullptr, "SetConfig"}, | 61 | {5, nullptr, "SetConfig"}, |
| 62 | {7, &SPL::GetRandomBytes, "GenerateRandomBytes"}, | 62 | {7, &SPL::GetRandomBytes, "GenerateRandomBytes"}, |
| 63 | {9, nullptr, "ImportLotusKey"}, | ||
| 64 | {10, nullptr, "DecryptLotusMessage"}, | ||
| 63 | {11, nullptr, "IsDevelopment"}, | 65 | {11, nullptr, "IsDevelopment"}, |
| 64 | {12, nullptr, "GenerateSpecificAesKey"}, | 66 | {12, nullptr, "GenerateSpecificAesKey"}, |
| 65 | {14, nullptr, "DecryptAesKey"}, | 67 | {14, nullptr, "DecryptAesKey"}, |
| @@ -123,6 +125,7 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_) | |||
| 123 | {14, nullptr, "DecryptAesKey"}, | 125 | {14, nullptr, "DecryptAesKey"}, |
| 124 | {15, nullptr, "CryptAesCtr"}, | 126 | {15, nullptr, "CryptAesCtr"}, |
| 125 | {16, nullptr, "ComputeCmac"}, | 127 | {16, nullptr, "ComputeCmac"}, |
| 128 | {17, nullptr, "ImportEsKey"}, | ||
| 126 | {18, nullptr, "UnwrapTitleKey"}, | 129 | {18, nullptr, "UnwrapTitleKey"}, |
| 127 | {20, nullptr, "PrepareEsCommonKey"}, | 130 | {20, nullptr, "PrepareEsCommonKey"}, |
| 128 | {21, nullptr, "AllocateAesKeyslot"}, | 131 | {21, nullptr, "AllocateAesKeyslot"}, |
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h index b78892223..a9cfe3eb0 100644 --- a/src/core/hle/service/time/clock_types.h +++ b/src/core/hle/service/time/clock_types.h | |||
| @@ -12,6 +12,12 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::Time::Clock { | 13 | namespace Service::Time::Clock { |
| 14 | 14 | ||
| 15 | enum class TimeType : u8 { | ||
| 16 | UserSystemClock, | ||
| 17 | NetworkSystemClock, | ||
| 18 | LocalSystemClock, | ||
| 19 | }; | ||
| 20 | |||
| 15 | /// https://switchbrew.org/wiki/Glue_services#SteadyClockTimePoint | 21 | /// https://switchbrew.org/wiki/Glue_services#SteadyClockTimePoint |
| 16 | struct SteadyClockTimePoint { | 22 | struct SteadyClockTimePoint { |
| 17 | s64 time_point; | 23 | s64 time_point; |
| @@ -84,7 +90,7 @@ struct ClockSnapshot { | |||
| 84 | SteadyClockTimePoint steady_clock_time_point; | 90 | SteadyClockTimePoint steady_clock_time_point; |
| 85 | TimeZone::LocationName location_name; | 91 | TimeZone::LocationName location_name; |
| 86 | u8 is_automatic_correction_enabled; | 92 | u8 is_automatic_correction_enabled; |
| 87 | u8 type; | 93 | TimeType type; |
| 88 | INSERT_PADDING_BYTES_NOINIT(0x2); | 94 | INSERT_PADDING_BYTES_NOINIT(0x2); |
| 89 | 95 | ||
| 90 | static ResultCode GetCurrentTime(s64& current_time, | 96 | static ResultCode GetCurrentTime(s64& current_time, |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 78543688f..63e0247de 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -122,14 +122,16 @@ private: | |||
| 122 | 122 | ||
| 123 | ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | 123 | ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( |
| 124 | Kernel::KThread* thread, Clock::SystemClockContext user_context, | 124 | Kernel::KThread* thread, Clock::SystemClockContext user_context, |
| 125 | Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) { | 125 | Clock::SystemClockContext network_context, Clock::TimeType type, |
| 126 | Clock::ClockSnapshot& clock_snapshot) { | ||
| 126 | 127 | ||
| 127 | auto& time_manager{system.GetTimeManager()}; | 128 | auto& time_manager{system.GetTimeManager()}; |
| 128 | 129 | ||
| 130 | clock_snapshot.steady_clock_time_point = | ||
| 131 | time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system); | ||
| 129 | clock_snapshot.is_automatic_correction_enabled = | 132 | clock_snapshot.is_automatic_correction_enabled = |
| 130 | time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); | 133 | time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); |
| 131 | clock_snapshot.user_context = user_context; | 134 | clock_snapshot.type = type; |
| 132 | clock_snapshot.network_context = network_context; | ||
| 133 | 135 | ||
| 134 | if (const ResultCode result{ | 136 | if (const ResultCode result{ |
| 135 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().GetDeviceLocationName( | 137 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().GetDeviceLocationName( |
| @@ -138,12 +140,11 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 138 | return result; | 140 | return result; |
| 139 | } | 141 | } |
| 140 | 142 | ||
| 141 | const auto current_time_point{ | 143 | clock_snapshot.user_context = user_context; |
| 142 | time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)}; | ||
| 143 | clock_snapshot.steady_clock_time_point = current_time_point; | ||
| 144 | 144 | ||
| 145 | if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime( | 145 | if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime( |
| 146 | clock_snapshot.user_time, current_time_point, clock_snapshot.user_context)}; | 146 | clock_snapshot.user_time, clock_snapshot.steady_clock_time_point, |
| 147 | clock_snapshot.user_context)}; | ||
| 147 | result != RESULT_SUCCESS) { | 148 | result != RESULT_SUCCESS) { |
| 148 | return result; | 149 | return result; |
| 149 | } | 150 | } |
| @@ -157,9 +158,12 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | clock_snapshot.user_calendar_time = userCalendarInfo.time; | 160 | clock_snapshot.user_calendar_time = userCalendarInfo.time; |
| 160 | clock_snapshot.user_calendar_additional_time = userCalendarInfo.additiona_info; | 161 | clock_snapshot.user_calendar_additional_time = userCalendarInfo.additional_info; |
| 162 | |||
| 163 | clock_snapshot.network_context = network_context; | ||
| 161 | 164 | ||
| 162 | if (Clock::ClockSnapshot::GetCurrentTime(clock_snapshot.network_time, current_time_point, | 165 | if (Clock::ClockSnapshot::GetCurrentTime(clock_snapshot.network_time, |
| 166 | clock_snapshot.steady_clock_time_point, | ||
| 163 | clock_snapshot.network_context) != RESULT_SUCCESS) { | 167 | clock_snapshot.network_context) != RESULT_SUCCESS) { |
| 164 | clock_snapshot.network_time = 0; | 168 | clock_snapshot.network_time = 0; |
| 165 | } | 169 | } |
| @@ -173,8 +177,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 173 | } | 177 | } |
| 174 | 178 | ||
| 175 | clock_snapshot.network_calendar_time = networkCalendarInfo.time; | 179 | clock_snapshot.network_calendar_time = networkCalendarInfo.time; |
| 176 | clock_snapshot.network_calendar_additional_time = networkCalendarInfo.additiona_info; | 180 | clock_snapshot.network_calendar_additional_time = networkCalendarInfo.additional_info; |
| 177 | clock_snapshot.type = type; | ||
| 178 | 181 | ||
| 179 | return RESULT_SUCCESS; | 182 | return RESULT_SUCCESS; |
| 180 | } | 183 | } |
| @@ -257,9 +260,10 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERe | |||
| 257 | } | 260 | } |
| 258 | 261 | ||
| 259 | void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | 262 | void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { |
| 260 | LOG_DEBUG(Service_Time, "called"); | ||
| 261 | IPC::RequestParser rp{ctx}; | 263 | IPC::RequestParser rp{ctx}; |
| 262 | const auto type{rp.PopRaw<u8>()}; | 264 | const auto type{rp.PopEnum<Clock::TimeType>()}; |
| 265 | |||
| 266 | LOG_DEBUG(Service_Time, "called, type={}", type); | ||
| 263 | 267 | ||
| 264 | Clock::SystemClockContext user_context{}; | 268 | Clock::SystemClockContext user_context{}; |
| 265 | if (const ResultCode result{ | 269 | if (const ResultCode result{ |
| @@ -270,6 +274,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | |||
| 270 | rb.Push(result); | 274 | rb.Push(result); |
| 271 | return; | 275 | return; |
| 272 | } | 276 | } |
| 277 | |||
| 273 | Clock::SystemClockContext network_context{}; | 278 | Clock::SystemClockContext network_context{}; |
| 274 | if (const ResultCode result{ | 279 | if (const ResultCode result{ |
| 275 | system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( | 280 | system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( |
| @@ -295,14 +300,16 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | |||
| 295 | } | 300 | } |
| 296 | 301 | ||
| 297 | void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) { | 302 | void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) { |
| 298 | LOG_DEBUG(Service_Time, "called"); | ||
| 299 | IPC::RequestParser rp{ctx}; | 303 | IPC::RequestParser rp{ctx}; |
| 300 | const auto type{rp.PopRaw<u8>()}; | 304 | const auto type{rp.PopEnum<Clock::TimeType>()}; |
| 305 | |||
| 301 | rp.AlignWithPadding(); | 306 | rp.AlignWithPadding(); |
| 302 | 307 | ||
| 303 | const Clock::SystemClockContext user_context{rp.PopRaw<Clock::SystemClockContext>()}; | 308 | const Clock::SystemClockContext user_context{rp.PopRaw<Clock::SystemClockContext>()}; |
| 304 | const Clock::SystemClockContext network_context{rp.PopRaw<Clock::SystemClockContext>()}; | 309 | const Clock::SystemClockContext network_context{rp.PopRaw<Clock::SystemClockContext>()}; |
| 305 | 310 | ||
| 311 | LOG_DEBUG(Service_Time, "called, type={}", type); | ||
| 312 | |||
| 306 | Clock::ClockSnapshot clock_snapshot{}; | 313 | Clock::ClockSnapshot clock_snapshot{}; |
| 307 | if (const ResultCode result{GetClockSnapshotFromSystemClockContextInternal( | 314 | if (const ResultCode result{GetClockSnapshotFromSystemClockContextInternal( |
| 308 | &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; | 315 | &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; |
| @@ -321,9 +328,14 @@ void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( | |||
| 321 | Kernel::HLERequestContext& ctx) { | 328 | Kernel::HLERequestContext& ctx) { |
| 322 | LOG_DEBUG(Service_Time, "called"); | 329 | LOG_DEBUG(Service_Time, "called"); |
| 323 | 330 | ||
| 324 | IPC::RequestParser rp{ctx}; | 331 | Clock::ClockSnapshot snapshot_a; |
| 325 | const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>(); | 332 | Clock::ClockSnapshot snapshot_b; |
| 326 | const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>(); | 333 | |
| 334 | const auto snapshot_a_data = ctx.ReadBuffer(0); | ||
| 335 | const auto snapshot_b_data = ctx.ReadBuffer(1); | ||
| 336 | |||
| 337 | std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(Clock::ClockSnapshot)); | ||
| 338 | std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(Clock::ClockSnapshot)); | ||
| 327 | 339 | ||
| 328 | auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset - | 340 | auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset - |
| 329 | snapshot_a.user_context.offset)}; | 341 | snapshot_a.user_context.offset)}; |
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 4154c7ee9..ce9c479c6 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h | |||
| @@ -40,7 +40,7 @@ public: | |||
| 40 | private: | 40 | private: |
| 41 | ResultCode GetClockSnapshotFromSystemClockContextInternal( | 41 | ResultCode GetClockSnapshotFromSystemClockContextInternal( |
| 42 | Kernel::KThread* thread, Clock::SystemClockContext user_context, | 42 | Kernel::KThread* thread, Clock::SystemClockContext user_context, |
| 43 | Clock::SystemClockContext network_context, u8 type, | 43 | Clock::SystemClockContext network_context, Clock::TimeType type, |
| 44 | Clock::ClockSnapshot& cloc_snapshot); | 44 | Clock::ClockSnapshot& cloc_snapshot); |
| 45 | 45 | ||
| 46 | protected: | 46 | protected: |
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index 1f7309f6b..51becd074 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp | |||
| @@ -44,7 +44,11 @@ struct TimeManager::Impl final { | |||
| 44 | const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())}; | 44 | const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())}; |
| 45 | SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {}); | 45 | SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {}); |
| 46 | SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds()); | 46 | SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds()); |
| 47 | SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy); | 47 | |
| 48 | Clock::SystemClockContext clock_context{}; | ||
| 49 | standard_local_system_clock_core.GetClockContext(system, clock_context); | ||
| 50 | |||
| 51 | SetupStandardNetworkSystemClock(clock_context, standard_network_clock_accuracy); | ||
| 48 | SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom()); | 52 | SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom()); |
| 49 | SetupEphemeralNetworkSystemClock(); | 53 | SetupEphemeralNetworkSystemClock(); |
| 50 | } | 54 | } |
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index bdf0439f2..3032ca193 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -818,7 +818,7 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | |||
| 818 | static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) { | 818 | static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) { |
| 819 | CalendarTimeInternal calendar_time{}; | 819 | CalendarTimeInternal calendar_time{}; |
| 820 | const ResultCode result{ | 820 | const ResultCode result{ |
| 821 | ToCalendarTimeInternal(rules, time, calendar_time, calendar.additiona_info)}; | 821 | ToCalendarTimeInternal(rules, time, calendar_time, calendar.additional_info)}; |
| 822 | calendar.time.year = static_cast<s16>(calendar_time.year); | 822 | calendar.time.year = static_cast<s16>(calendar_time.year); |
| 823 | 823 | ||
| 824 | // Internal impl. uses 0-indexed month | 824 | // Internal impl. uses 0-indexed month |
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp index 25cecbc83..3117627cf 100644 --- a/src/core/hle/service/time/time_zone_service.cpp +++ b/src/core/hle/service/time/time_zone_service.cpp | |||
| @@ -20,6 +20,7 @@ ITimeZoneService ::ITimeZoneService(Core::System& system_, | |||
| 20 | {3, nullptr, "LoadLocationNameList"}, | 20 | {3, nullptr, "LoadLocationNameList"}, |
| 21 | {4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"}, | 21 | {4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"}, |
| 22 | {5, nullptr, "GetTimeZoneRuleVersion"}, | 22 | {5, nullptr, "GetTimeZoneRuleVersion"}, |
| 23 | {6, nullptr, "GetDeviceLocationNameAndUpdatedTime"}, | ||
| 23 | {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, | 24 | {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, |
| 24 | {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, | 25 | {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, |
| 25 | {201, &ITimeZoneService::ToPosixTime, "ToPosixTime"}, | 26 | {201, &ITimeZoneService::ToPosixTime, "ToPosixTime"}, |
diff --git a/src/core/hle/service/time/time_zone_types.h b/src/core/hle/service/time/time_zone_types.h index 4a57e036d..d39103253 100644 --- a/src/core/hle/service/time/time_zone_types.h +++ b/src/core/hle/service/time/time_zone_types.h | |||
| @@ -66,8 +66,8 @@ struct CalendarTime { | |||
| 66 | static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime is incorrect size"); | 66 | static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime is incorrect size"); |
| 67 | 67 | ||
| 68 | struct CalendarInfo { | 68 | struct CalendarInfo { |
| 69 | CalendarTime time{}; | 69 | CalendarTime time; |
| 70 | CalendarAdditionalInfo additiona_info{}; | 70 | CalendarAdditionalInfo additional_info; |
| 71 | }; | 71 | }; |
| 72 | static_assert(sizeof(CalendarInfo) == 0x20, "CalendarInfo is incorrect size"); | 72 | static_assert(sizeof(CalendarInfo) == 0x20, "CalendarInfo is incorrect size"); |
| 73 | 73 | ||
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp index 579de83e4..b3b230a8c 100644 --- a/src/core/hle/service/usb/usb.cpp +++ b/src/core/hle/service/usb/usb.cpp | |||
| @@ -69,15 +69,15 @@ public: | |||
| 69 | : ServiceFramework{system_, "IClientEpSession"} { | 69 | : ServiceFramework{system_, "IClientEpSession"} { |
| 70 | // clang-format off | 70 | // clang-format off |
| 71 | static const FunctionInfo functions[] = { | 71 | static const FunctionInfo functions[] = { |
| 72 | {0, nullptr, "Open"}, | 72 | {0, nullptr, "ReOpen"}, |
| 73 | {1, nullptr, "Close"}, | 73 | {1, nullptr, "Close"}, |
| 74 | {2, nullptr, "Unknown2"}, | 74 | {2, nullptr, "GetCompletionEvent"}, |
| 75 | {3, nullptr, "Populate"}, | 75 | {3, nullptr, "PopulateRing"}, |
| 76 | {4, nullptr, "PostBufferAsync"}, | 76 | {4, nullptr, "PostBufferAsync"}, |
| 77 | {5, nullptr, "GetXferReport"}, | 77 | {5, nullptr, "GetXferReport"}, |
| 78 | {6, nullptr, "PostBufferMultiAsync"}, | 78 | {6, nullptr, "PostBufferMultiAsync"}, |
| 79 | {7, nullptr, "Unknown7"}, | 79 | {7, nullptr, "CreateSmmuSpace"}, |
| 80 | {8, nullptr, "Unknown8"}, | 80 | {8, nullptr, "ShareReportRing"}, |
| 81 | }; | 81 | }; |
| 82 | // clang-format on | 82 | // clang-format on |
| 83 | 83 | ||
| @@ -91,7 +91,7 @@ public: | |||
| 91 | : ServiceFramework{system_, "IClientIfSession"} { | 91 | : ServiceFramework{system_, "IClientIfSession"} { |
| 92 | // clang-format off | 92 | // clang-format off |
| 93 | static const FunctionInfo functions[] = { | 93 | static const FunctionInfo functions[] = { |
| 94 | {0, nullptr, "Unknown0"}, | 94 | {0, nullptr, "GetStateChangeEvent"}, |
| 95 | {1, nullptr, "SetInterface"}, | 95 | {1, nullptr, "SetInterface"}, |
| 96 | {2, nullptr, "GetInterface"}, | 96 | {2, nullptr, "GetInterface"}, |
| 97 | {3, nullptr, "GetAlternateInterface"}, | 97 | {3, nullptr, "GetAlternateInterface"}, |
| @@ -176,15 +176,15 @@ public: | |||
| 176 | : ServiceFramework{system_, "IPdCradleSession"} { | 176 | : ServiceFramework{system_, "IPdCradleSession"} { |
| 177 | // clang-format off | 177 | // clang-format off |
| 178 | static const FunctionInfo functions[] = { | 178 | static const FunctionInfo functions[] = { |
| 179 | {0, nullptr, "VdmUserWrite"}, | 179 | {0, nullptr, "SetCradleVdo"}, |
| 180 | {1, nullptr, "VdmUserRead"}, | 180 | {1, nullptr, "GetCradleVdo"}, |
| 181 | {2, nullptr, "Vdm20Init"}, | 181 | {2, nullptr, "ResetCradleUsbHub"}, |
| 182 | {3, nullptr, "GetFwType"}, | 182 | {3, nullptr, "GetHostPdcFirmwareType"}, |
| 183 | {4, nullptr, "GetFwRevision"}, | 183 | {4, nullptr, "GetHostPdcFirmwareRevision"}, |
| 184 | {5, nullptr, "GetManufacturerId"}, | 184 | {5, nullptr, "GetHostPdcManufactureId"}, |
| 185 | {6, nullptr, "GetDeviceId"}, | 185 | {6, nullptr, "GetHostPdcDeviceId"}, |
| 186 | {7, nullptr, "Unknown7"}, | 186 | {7, nullptr, "AwakeCradle"}, |
| 187 | {8, nullptr, "Unknown8"}, | 187 | {8, nullptr, "SleepCradle"}, |
| 188 | }; | 188 | }; |
| 189 | // clang-format on | 189 | // clang-format on |
| 190 | 190 | ||
| @@ -219,12 +219,12 @@ public: | |||
| 219 | explicit USB_PM(Core::System& system_) : ServiceFramework{system_, "usb:pm"} { | 219 | explicit USB_PM(Core::System& system_) : ServiceFramework{system_, "usb:pm"} { |
| 220 | // clang-format off | 220 | // clang-format off |
| 221 | static const FunctionInfo functions[] = { | 221 | static const FunctionInfo functions[] = { |
| 222 | {0, nullptr, "Unknown0"}, | 222 | {0, nullptr, "GetPowerEvent"}, |
| 223 | {1, nullptr, "Unknown1"}, | 223 | {1, nullptr, "GetPowerState"}, |
| 224 | {2, nullptr, "Unknown2"}, | 224 | {2, nullptr, "GetDataEvent"}, |
| 225 | {3, nullptr, "Unknown3"}, | 225 | {3, nullptr, "GetDataRole"}, |
| 226 | {4, nullptr, "Unknown4"}, | 226 | {4, nullptr, "SetDiagData"}, |
| 227 | {5, nullptr, "Unknown5"}, | 227 | {5, nullptr, "GetDiagData"}, |
| 228 | }; | 228 | }; |
| 229 | // clang-format on | 229 | // clang-format on |
| 230 | 230 | ||
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 7423287ea..a1a7ac987 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -695,6 +695,7 @@ public: | |||
| 695 | {2205, &ISystemDisplayService::SetLayerZ, "SetLayerZ"}, | 695 | {2205, &ISystemDisplayService::SetLayerZ, "SetLayerZ"}, |
| 696 | {2207, &ISystemDisplayService::SetLayerVisibility, "SetLayerVisibility"}, | 696 | {2207, &ISystemDisplayService::SetLayerVisibility, "SetLayerVisibility"}, |
| 697 | {2209, nullptr, "SetLayerAlpha"}, | 697 | {2209, nullptr, "SetLayerAlpha"}, |
| 698 | {2210, nullptr, "SetLayerPositionAndSize"}, | ||
| 698 | {2312, nullptr, "CreateStrayLayer"}, | 699 | {2312, nullptr, "CreateStrayLayer"}, |
| 699 | {2400, nullptr, "OpenIndirectLayer"}, | 700 | {2400, nullptr, "OpenIndirectLayer"}, |
| 700 | {2401, nullptr, "CloseIndirectLayer"}, | 701 | {2401, nullptr, "CloseIndirectLayer"}, |
| @@ -718,6 +719,7 @@ public: | |||
| 718 | {3215, nullptr, "SetDisplayGamma"}, | 719 | {3215, nullptr, "SetDisplayGamma"}, |
| 719 | {3216, nullptr, "GetDisplayCmuLuma"}, | 720 | {3216, nullptr, "GetDisplayCmuLuma"}, |
| 720 | {3217, nullptr, "SetDisplayCmuLuma"}, | 721 | {3217, nullptr, "SetDisplayCmuLuma"}, |
| 722 | {3218, nullptr, "SetDisplayCrcMode"}, | ||
| 721 | {6013, nullptr, "GetLayerPresentationSubmissionTimestamps"}, | 723 | {6013, nullptr, "GetLayerPresentationSubmissionTimestamps"}, |
| 722 | {8225, nullptr, "GetSharedBufferMemoryHandleId"}, | 724 | {8225, nullptr, "GetSharedBufferMemoryHandleId"}, |
| 723 | {8250, nullptr, "OpenSharedLayer"}, | 725 | {8250, nullptr, "OpenSharedLayer"}, |
| @@ -729,6 +731,7 @@ public: | |||
| 729 | {8256, nullptr, "GetSharedFrameBufferAcquirableEvent"}, | 731 | {8256, nullptr, "GetSharedFrameBufferAcquirableEvent"}, |
| 730 | {8257, nullptr, "FillSharedFrameBufferColor"}, | 732 | {8257, nullptr, "FillSharedFrameBufferColor"}, |
| 731 | {8258, nullptr, "CancelSharedFrameBuffer"}, | 733 | {8258, nullptr, "CancelSharedFrameBuffer"}, |
| 734 | {9000, nullptr, "GetDp2hdmiController"}, | ||
| 732 | }; | 735 | }; |
| 733 | RegisterHandlers(functions); | 736 | RegisterHandlers(functions); |
| 734 | } | 737 | } |
| @@ -808,10 +811,15 @@ public: | |||
| 808 | {2402, nullptr, "GetDisplayHotplugState"}, | 811 | {2402, nullptr, "GetDisplayHotplugState"}, |
| 809 | {2501, nullptr, "GetCompositorErrorInfo"}, | 812 | {2501, nullptr, "GetCompositorErrorInfo"}, |
| 810 | {2601, nullptr, "GetDisplayErrorEvent"}, | 813 | {2601, nullptr, "GetDisplayErrorEvent"}, |
| 814 | {2701, nullptr, "GetDisplayFatalErrorEvent"}, | ||
| 811 | {4201, nullptr, "SetDisplayAlpha"}, | 815 | {4201, nullptr, "SetDisplayAlpha"}, |
| 812 | {4203, nullptr, "SetDisplayLayerStack"}, | 816 | {4203, nullptr, "SetDisplayLayerStack"}, |
| 813 | {4205, nullptr, "SetDisplayPowerState"}, | 817 | {4205, nullptr, "SetDisplayPowerState"}, |
| 814 | {4206, nullptr, "SetDefaultDisplay"}, | 818 | {4206, nullptr, "SetDefaultDisplay"}, |
| 819 | {4207, nullptr, "ResetDisplayPanel"}, | ||
| 820 | {4208, nullptr, "SetDisplayFatalErrorEnabled"}, | ||
| 821 | {4209, nullptr, "IsDisplayPanelOn"}, | ||
| 822 | {4300, nullptr, "GetInternalPanelId"}, | ||
| 815 | {6000, &IManagerDisplayService::AddToLayerStack, "AddToLayerStack"}, | 823 | {6000, &IManagerDisplayService::AddToLayerStack, "AddToLayerStack"}, |
| 816 | {6001, nullptr, "RemoveFromLayerStack"}, | 824 | {6001, nullptr, "RemoveFromLayerStack"}, |
| 817 | {6002, &IManagerDisplayService::SetLayerVisibility, "SetLayerVisibility"}, | 825 | {6002, &IManagerDisplayService::SetLayerVisibility, "SetLayerVisibility"}, |
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp index ddbf04069..44957e01d 100644 --- a/src/core/hle/service/wlan/wlan.cpp +++ b/src/core/hle/service/wlan/wlan.cpp | |||
| @@ -46,6 +46,13 @@ public: | |||
| 46 | {28, nullptr, "Unknown28"}, | 46 | {28, nullptr, "Unknown28"}, |
| 47 | {29, nullptr, "Unknown29"}, | 47 | {29, nullptr, "Unknown29"}, |
| 48 | {30, nullptr, "Unknown30"}, | 48 | {30, nullptr, "Unknown30"}, |
| 49 | {31, nullptr, "Unknown31"}, | ||
| 50 | {32, nullptr, "Unknown32"}, | ||
| 51 | {33, nullptr, "Unknown33"}, | ||
| 52 | {34, nullptr, "Unknown34"}, | ||
| 53 | {35, nullptr, "Unknown35"}, | ||
| 54 | {36, nullptr, "Unknown36"}, | ||
| 55 | {37, nullptr, "Unknown37"}, | ||
| 49 | }; | 56 | }; |
| 50 | // clang-format on | 57 | // clang-format on |
| 51 | 58 | ||
diff --git a/src/core/settings.h b/src/core/settings.h index 0501bf0db..6c03a6ea9 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -223,6 +223,7 @@ struct Values { | |||
| 223 | bool quest_flag; | 223 | bool quest_flag; |
| 224 | bool disable_macro_jit; | 224 | bool disable_macro_jit; |
| 225 | bool extended_logging; | 225 | bool extended_logging; |
| 226 | bool use_auto_stub; | ||
| 226 | 227 | ||
| 227 | // Miscellaneous | 228 | // Miscellaneous |
| 228 | std::string log_filter; | 229 | std::string log_filter; |
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp index 59e586695..29bb31418 100644 --- a/src/video_core/command_classes/codecs/vp9.cpp +++ b/src/video_core/command_classes/codecs/vp9.cpp | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> // for std::memcpy | 5 | #include <algorithm> // for std::copy |
| 6 | #include <numeric> | 6 | #include <numeric> |
| 7 | #include "common/assert.h" | ||
| 7 | #include "video_core/command_classes/codecs/vp9.h" | 8 | #include "video_core/command_classes/codecs/vp9.h" |
| 8 | #include "video_core/gpu.h" | 9 | #include "video_core/gpu.h" |
| 9 | #include "video_core/memory_manager.h" | 10 | #include "video_core/memory_manager.h" |
| @@ -362,7 +363,8 @@ Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) | |||
| 362 | // surface_luma_offset[0:3] contains the address of the reference frame offsets in the following | 363 | // surface_luma_offset[0:3] contains the address of the reference frame offsets in the following |
| 363 | // order: last, golden, altref, current. It may be worthwhile to track the updates done here | 364 | // order: last, golden, altref, current. It may be worthwhile to track the updates done here |
| 364 | // to avoid buffering frame data needed for reference frame updating in the header composition. | 365 | // to avoid buffering frame data needed for reference frame updating in the header composition. |
| 365 | std::memcpy(vp9_info.frame_offsets.data(), state.surface_luma_offset.data(), 4 * sizeof(u64)); | 366 | std::copy(state.surface_luma_offset.begin(), state.surface_luma_offset.begin() + 4, |
| 367 | vp9_info.frame_offsets.begin()); | ||
| 366 | 368 | ||
| 367 | return vp9_info; | 369 | return vp9_info; |
| 368 | } | 370 | } |
| @@ -821,11 +823,11 @@ const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters | |||
| 821 | 823 | ||
| 822 | // Write headers and frame to buffer | 824 | // Write headers and frame to buffer |
| 823 | frame.resize(uncompressed_header.size() + compressed_header.size() + bitstream.size()); | 825 | frame.resize(uncompressed_header.size() + compressed_header.size() + bitstream.size()); |
| 824 | std::memcpy(frame.data(), uncompressed_header.data(), uncompressed_header.size()); | 826 | std::copy(uncompressed_header.begin(), uncompressed_header.end(), frame.begin()); |
| 825 | std::memcpy(frame.data() + uncompressed_header.size(), compressed_header.data(), | 827 | std::copy(compressed_header.begin(), compressed_header.end(), |
| 826 | compressed_header.size()); | 828 | frame.begin() + uncompressed_header.size()); |
| 827 | std::memcpy(frame.data() + uncompressed_header.size() + compressed_header.size(), | 829 | std::copy(bitstream.begin(), bitstream.end(), |
| 828 | bitstream.data(), bitstream.size()); | 830 | frame.begin() + uncompressed_header.size() + compressed_header.size()); |
| 829 | 831 | ||
| 830 | // keep track of frame number | 832 | // keep track of frame number |
| 831 | current_frame_number++; | 833 | current_frame_number++; |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index c61f44619..009c6f574 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -517,8 +517,8 @@ void GPU::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const { | |||
| 517 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); | 517 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | void GPU::WaitIdle() const { | 520 | void GPU::ShutDown() { |
| 521 | gpu_thread.WaitIdle(); | 521 | gpu_thread.ShutDown(); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | void GPU::OnCommandListEnd() { | 524 | void GPU::OnCommandListEnd() { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index b2ee45496..ecab35d3b 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -219,8 +219,8 @@ public: | |||
| 219 | return *shader_notify; | 219 | return *shader_notify; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | // Waits for the GPU to finish working | 222 | // Stops the GPU execution and waits for the GPU to finish working |
| 223 | void WaitIdle() const; | 223 | void ShutDown(); |
| 224 | 224 | ||
| 225 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 225 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. |
| 226 | void WaitFence(u32 syncpoint_id, u32 value); | 226 | void WaitFence(u32 syncpoint_id, u32 value); |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 99353f15f..7addfbc7b 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -29,8 +29,7 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer, | |||
| 29 | system.RegisterHostThread(); | 29 | system.RegisterHostThread(); |
| 30 | 30 | ||
| 31 | // Wait for first GPU command before acquiring the window context | 31 | // Wait for first GPU command before acquiring the window context |
| 32 | while (state.queue.Empty()) | 32 | state.queue.Wait(); |
| 33 | ; | ||
| 34 | 33 | ||
| 35 | // If emulation was stopped during disk shader loading, abort before trying to acquire context | 34 | // If emulation was stopped during disk shader loading, abort before trying to acquire context |
| 36 | if (!state.is_running) { | 35 | if (!state.is_running) { |
| @@ -57,11 +56,17 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer, | |||
| 57 | } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) { | 56 | } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) { |
| 58 | rasterizer->OnCPUWrite(invalidate->addr, invalidate->size); | 57 | rasterizer->OnCPUWrite(invalidate->addr, invalidate->size); |
| 59 | } else if (std::holds_alternative<EndProcessingCommand>(next.data)) { | 58 | } else if (std::holds_alternative<EndProcessingCommand>(next.data)) { |
| 60 | return; | 59 | ASSERT(state.is_running == false); |
| 61 | } else { | 60 | } else { |
| 62 | UNREACHABLE(); | 61 | UNREACHABLE(); |
| 63 | } | 62 | } |
| 64 | state.signaled_fence.store(next.fence); | 63 | state.signaled_fence.store(next.fence); |
| 64 | if (next.block) { | ||
| 65 | // We have to lock the write_lock to ensure that the condition_variable wait not get a | ||
| 66 | // race between the check and the lock itself. | ||
| 67 | std::lock_guard lk(state.write_lock); | ||
| 68 | state.cv.notify_all(); | ||
| 69 | } | ||
| 65 | } | 70 | } |
| 66 | } | 71 | } |
| 67 | 72 | ||
| @@ -69,13 +74,7 @@ ThreadManager::ThreadManager(Core::System& system_, bool is_async_) | |||
| 69 | : system{system_}, is_async{is_async_} {} | 74 | : system{system_}, is_async{is_async_} {} |
| 70 | 75 | ||
| 71 | ThreadManager::~ThreadManager() { | 76 | ThreadManager::~ThreadManager() { |
| 72 | if (!thread.joinable()) { | 77 | ShutDown(); |
| 73 | return; | ||
| 74 | } | ||
| 75 | |||
| 76 | // Notify GPU thread that a shutdown is pending | ||
| 77 | PushCommand(EndProcessingCommand()); | ||
| 78 | thread.join(); | ||
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | void ThreadManager::StartThread(VideoCore::RendererBase& renderer, | 80 | void ThreadManager::StartThread(VideoCore::RendererBase& renderer, |
| @@ -112,9 +111,8 @@ void ThreadManager::FlushRegion(VAddr addr, u64 size) { | |||
| 112 | case Settings::GPUAccuracy::Extreme: { | 111 | case Settings::GPUAccuracy::Extreme: { |
| 113 | auto& gpu = system.GPU(); | 112 | auto& gpu = system.GPU(); |
| 114 | u64 fence = gpu.RequestFlush(addr, size); | 113 | u64 fence = gpu.RequestFlush(addr, size); |
| 115 | PushCommand(GPUTickCommand()); | 114 | PushCommand(GPUTickCommand(), true); |
| 116 | while (fence > gpu.CurrentFlushRequestFence()) { | 115 | ASSERT(fence <= gpu.CurrentFlushRequestFence()); |
| 117 | } | ||
| 118 | break; | 116 | break; |
| 119 | } | 117 | } |
| 120 | default: | 118 | default: |
| @@ -131,23 +129,45 @@ void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { | |||
| 131 | rasterizer->OnCPUWrite(addr, size); | 129 | rasterizer->OnCPUWrite(addr, size); |
| 132 | } | 130 | } |
| 133 | 131 | ||
| 134 | void ThreadManager::WaitIdle() const { | 132 | void ThreadManager::ShutDown() { |
| 135 | while (state.last_fence > state.signaled_fence.load(std::memory_order_relaxed) && | 133 | if (!state.is_running) { |
| 136 | system.IsPoweredOn()) { | 134 | return; |
| 137 | } | 135 | } |
| 136 | |||
| 137 | { | ||
| 138 | std::lock_guard lk(state.write_lock); | ||
| 139 | state.is_running = false; | ||
| 140 | state.cv.notify_all(); | ||
| 141 | } | ||
| 142 | |||
| 143 | if (!thread.joinable()) { | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | |||
| 147 | // Notify GPU thread that a shutdown is pending | ||
| 148 | PushCommand(EndProcessingCommand()); | ||
| 149 | thread.join(); | ||
| 138 | } | 150 | } |
| 139 | 151 | ||
| 140 | void ThreadManager::OnCommandListEnd() { | 152 | void ThreadManager::OnCommandListEnd() { |
| 141 | PushCommand(OnCommandListEndCommand()); | 153 | PushCommand(OnCommandListEndCommand()); |
| 142 | } | 154 | } |
| 143 | 155 | ||
| 144 | u64 ThreadManager::PushCommand(CommandData&& command_data) { | 156 | u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) { |
| 145 | const u64 fence{++state.last_fence}; | ||
| 146 | state.queue.Push(CommandDataContainer(std::move(command_data), fence)); | ||
| 147 | |||
| 148 | if (!is_async) { | 157 | if (!is_async) { |
| 149 | // In synchronous GPU mode, block the caller until the command has executed | 158 | // In synchronous GPU mode, block the caller until the command has executed |
| 150 | WaitIdle(); | 159 | block = true; |
| 160 | } | ||
| 161 | |||
| 162 | std::unique_lock lk(state.write_lock); | ||
| 163 | const u64 fence{++state.last_fence}; | ||
| 164 | state.queue.Push(CommandDataContainer(std::move(command_data), fence, block)); | ||
| 165 | |||
| 166 | if (block) { | ||
| 167 | state.cv.wait(lk, [this, fence] { | ||
| 168 | return fence <= state.signaled_fence.load(std::memory_order_relaxed) || | ||
| 169 | !state.is_running; | ||
| 170 | }); | ||
| 151 | } | 171 | } |
| 152 | 172 | ||
| 153 | return fence; | 173 | return fence; |
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index 18269e51c..11a648f38 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h | |||
| @@ -90,21 +90,24 @@ using CommandData = | |||
| 90 | struct CommandDataContainer { | 90 | struct CommandDataContainer { |
| 91 | CommandDataContainer() = default; | 91 | CommandDataContainer() = default; |
| 92 | 92 | ||
| 93 | explicit CommandDataContainer(CommandData&& data_, u64 next_fence_) | 93 | explicit CommandDataContainer(CommandData&& data_, u64 next_fence_, bool block_) |
| 94 | : data{std::move(data_)}, fence{next_fence_} {} | 94 | : data{std::move(data_)}, fence{next_fence_}, block(block_) {} |
| 95 | 95 | ||
| 96 | CommandData data; | 96 | CommandData data; |
| 97 | u64 fence{}; | 97 | u64 fence{}; |
| 98 | bool block{}; | ||
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | /// Struct used to synchronize the GPU thread | 101 | /// Struct used to synchronize the GPU thread |
| 101 | struct SynchState final { | 102 | struct SynchState final { |
| 102 | std::atomic_bool is_running{true}; | 103 | std::atomic_bool is_running{true}; |
| 103 | 104 | ||
| 104 | using CommandQueue = Common::MPSCQueue<CommandDataContainer>; | 105 | using CommandQueue = Common::SPSCQueue<CommandDataContainer>; |
| 106 | std::mutex write_lock; | ||
| 105 | CommandQueue queue; | 107 | CommandQueue queue; |
| 106 | u64 last_fence{}; | 108 | u64 last_fence{}; |
| 107 | std::atomic<u64> signaled_fence{}; | 109 | std::atomic<u64> signaled_fence{}; |
| 110 | std::condition_variable cv; | ||
| 108 | }; | 111 | }; |
| 109 | 112 | ||
| 110 | /// Class used to manage the GPU thread | 113 | /// Class used to manage the GPU thread |
| @@ -132,14 +135,14 @@ public: | |||
| 132 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated | 135 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated |
| 133 | void FlushAndInvalidateRegion(VAddr addr, u64 size); | 136 | void FlushAndInvalidateRegion(VAddr addr, u64 size); |
| 134 | 137 | ||
| 135 | // Wait until the gpu thread is idle. | 138 | // Stops the GPU execution and waits for the GPU to finish working |
| 136 | void WaitIdle() const; | 139 | void ShutDown(); |
| 137 | 140 | ||
| 138 | void OnCommandListEnd(); | 141 | void OnCommandListEnd(); |
| 139 | 142 | ||
| 140 | private: | 143 | private: |
| 141 | /// Pushes a command to be executed by the GPU thread | 144 | /// Pushes a command to be executed by the GPU thread |
| 142 | u64 PushCommand(CommandData&& command_data); | 145 | u64 PushCommand(CommandData&& command_data, bool block = false); |
| 143 | 146 | ||
| 144 | Core::System& system; | 147 | Core::System& system; |
| 145 | const bool is_async; | 148 | const bool is_async; |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 1cc720ddd..14e5f36e2 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -143,7 +143,10 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 143 | 143 | ||
| 144 | scheduler.WaitWorker(); | 144 | scheduler.WaitWorker(); |
| 145 | 145 | ||
| 146 | swapchain.AcquireNextImage(); | 146 | while (!swapchain.AcquireNextImage()) { |
| 147 | swapchain.Create(layout.width, layout.height, is_srgb); | ||
| 148 | blit_screen.Recreate(); | ||
| 149 | } | ||
| 147 | const VkSemaphore render_semaphore = blit_screen.Draw(*framebuffer, use_accelerated); | 150 | const VkSemaphore render_semaphore = blit_screen.Draw(*framebuffer, use_accelerated); |
| 148 | 151 | ||
| 149 | scheduler.Flush(render_semaphore); | 152 | scheduler.Flush(render_semaphore); |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 668633e7b..8cb65e588 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -176,7 +176,7 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset | |||
| 176 | u32 stride) { | 176 | u32 stride) { |
| 177 | if (device.IsExtExtendedDynamicStateSupported()) { | 177 | if (device.IsExtExtendedDynamicStateSupported()) { |
| 178 | scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) { | 178 | scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) { |
| 179 | const VkDeviceSize vk_offset = offset; | 179 | const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0; |
| 180 | const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE; | 180 | const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE; |
| 181 | const VkDeviceSize vk_stride = stride; | 181 | const VkDeviceSize vk_stride = stride; |
| 182 | cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, &vk_stride); | 182 | cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, &vk_stride); |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 0b63bd6c8..dfd5c65ba 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp | |||
| @@ -82,11 +82,13 @@ void VKSwapchain::Create(u32 width, u32 height, bool srgb) { | |||
| 82 | resource_ticks.resize(image_count); | 82 | resource_ticks.resize(image_count); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void VKSwapchain::AcquireNextImage() { | 85 | bool VKSwapchain::AcquireNextImage() { |
| 86 | device.GetLogical().AcquireNextImageKHR(*swapchain, std::numeric_limits<u64>::max(), | 86 | const VkResult result = |
| 87 | *present_semaphores[frame_index], {}, &image_index); | 87 | device.GetLogical().AcquireNextImageKHR(*swapchain, std::numeric_limits<u64>::max(), |
| 88 | *present_semaphores[frame_index], {}, &image_index); | ||
| 88 | 89 | ||
| 89 | scheduler.Wait(resource_ticks[image_index]); | 90 | scheduler.Wait(resource_ticks[image_index]); |
| 91 | return result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR; | ||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | bool VKSwapchain::Present(VkSemaphore render_semaphore) { | 94 | bool VKSwapchain::Present(VkSemaphore render_semaphore) { |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index a728511e0..adc8d27cf 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 28 | void Create(u32 width, u32 height, bool srgb); | 28 | void Create(u32 width, u32 height, bool srgb); |
| 29 | 29 | ||
| 30 | /// Acquires the next image in the swapchain, waits as needed. | 30 | /// Acquires the next image in the swapchain, waits as needed. |
| 31 | void AcquireNextImage(); | 31 | bool AcquireNextImage(); |
| 32 | 32 | ||
| 33 | /// Presents the rendered image to the swapchain. Returns true when the swapchains had to be | 33 | /// Presents the rendered image to the swapchain. Returns true when the swapchains had to be |
| 34 | /// recreated. Takes responsability for the ownership of fence. | 34 | /// recreated. Takes responsability for the ownership of fence. |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 697cb16b9..230b8717b 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -294,6 +294,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 294 | }; | 294 | }; |
| 295 | SetNext(next, bit8_storage); | 295 | SetNext(next, bit8_storage); |
| 296 | 296 | ||
| 297 | VkPhysicalDeviceRobustness2FeaturesEXT robustness2{ | ||
| 298 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT, | ||
| 299 | .pNext = nullptr, | ||
| 300 | .robustBufferAccess2 = true, | ||
| 301 | .robustImageAccess2 = true, | ||
| 302 | .nullDescriptor = true, | ||
| 303 | }; | ||
| 304 | SetNext(next, robustness2); | ||
| 305 | |||
| 297 | VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset{ | 306 | VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset{ |
| 298 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, | 307 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, |
| 299 | .pNext = nullptr, | 308 | .pNext = nullptr, |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 2dfe271f0..50ea15e2a 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -641,6 +641,7 @@ void Config::ReadDebuggingValues() { | |||
| 641 | ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); | 641 | ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); |
| 642 | Settings::values.extended_logging = | 642 | Settings::values.extended_logging = |
| 643 | ReadSetting(QStringLiteral("extended_logging"), false).toBool(); | 643 | ReadSetting(QStringLiteral("extended_logging"), false).toBool(); |
| 644 | Settings::values.use_auto_stub = ReadSetting(QStringLiteral("use_auto_stub"), false).toBool(); | ||
| 644 | 645 | ||
| 645 | qt_config->endGroup(); | 646 | qt_config->endGroup(); |
| 646 | } | 647 | } |
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 121873f95..2a5b3f5e7 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp | |||
| @@ -34,6 +34,7 @@ void ConfigureDebug::SetConfiguration() { | |||
| 34 | ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); | 34 | ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); |
| 35 | ui->reporting_services->setChecked(Settings::values.reporting_services); | 35 | ui->reporting_services->setChecked(Settings::values.reporting_services); |
| 36 | ui->quest_flag->setChecked(Settings::values.quest_flag); | 36 | ui->quest_flag->setChecked(Settings::values.quest_flag); |
| 37 | ui->use_auto_stub->setChecked(Settings::values.use_auto_stub); | ||
| 37 | ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 38 | ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 38 | ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); | 39 | ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); |
| 39 | ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 40 | ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| @@ -47,6 +48,7 @@ void ConfigureDebug::ApplyConfiguration() { | |||
| 47 | Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); | 48 | Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); |
| 48 | Settings::values.reporting_services = ui->reporting_services->isChecked(); | 49 | Settings::values.reporting_services = ui->reporting_services->isChecked(); |
| 49 | Settings::values.quest_flag = ui->quest_flag->isChecked(); | 50 | Settings::values.quest_flag = ui->quest_flag->isChecked(); |
| 51 | Settings::values.use_auto_stub = ui->use_auto_stub->isChecked(); | ||
| 50 | Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); | 52 | Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); |
| 51 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); | 53 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); |
| 52 | Settings::values.extended_logging = ui->extended_logging->isChecked(); | 54 | Settings::values.extended_logging = ui->extended_logging->isChecked(); |
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 9186aa732..ae48b728c 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui | |||
| @@ -185,6 +185,28 @@ | |||
| 185 | </property> | 185 | </property> |
| 186 | </widget> | 186 | </widget> |
| 187 | </item> | 187 | </item> |
| 188 | <item> | ||
| 189 | <widget class="QCheckBox" name="use_auto_stub"> | ||
| 190 | <property name="text"> | ||
| 191 | <string>Enable Auto-Stub</string> | ||
| 192 | </property> | ||
| 193 | </widget> | ||
| 194 | </item> | ||
| 195 | <item> | ||
| 196 | <widget class="QLabel" name="label_3"> | ||
| 197 | <property name="font"> | ||
| 198 | <font> | ||
| 199 | <italic>true</italic> | ||
| 200 | </font> | ||
| 201 | </property> | ||
| 202 | <property name="text"> | ||
| 203 | <string>This will be reset automatically when yuzu closes.</string> | ||
| 204 | </property> | ||
| 205 | <property name="indent"> | ||
| 206 | <number>20</number> | ||
| 207 | </property> | ||
| 208 | </widget> | ||
| 209 | </item> | ||
| 188 | </layout> | 210 | </layout> |
| 189 | </widget> | 211 | </widget> |
| 190 | </item> | 212 | </item> |