diff options
Diffstat (limited to 'src')
310 files changed, 3343 insertions, 2484 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9182dbfd4..39d038493 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -65,6 +65,10 @@ if (MSVC) | |||
| 65 | /we4305 # 'context': truncation from 'type1' to 'type2' | 65 | /we4305 # 'context': truncation from 'type1' to 'type2' |
| 66 | /we4388 # 'expression': signed/unsigned mismatch | 66 | /we4388 # 'expression': signed/unsigned mismatch |
| 67 | /we4389 # 'operator': signed/unsigned mismatch | 67 | /we4389 # 'operator': signed/unsigned mismatch |
| 68 | /we4456 # Declaration of 'identifier' hides previous local declaration | ||
| 69 | /we4457 # Declaration of 'identifier' hides function parameter | ||
| 70 | /we4458 # Declaration of 'identifier' hides class member | ||
| 71 | /we4459 # Declaration of 'identifier' hides global declaration | ||
| 68 | /we4505 # 'function': unreferenced local function has been removed | 72 | /we4505 # 'function': unreferenced local function has been removed |
| 69 | /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect | 73 | /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect |
| 70 | /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? | 74 | /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? |
| @@ -92,6 +96,7 @@ else() | |||
| 92 | -Werror=missing-declarations | 96 | -Werror=missing-declarations |
| 93 | -Werror=missing-field-initializers | 97 | -Werror=missing-field-initializers |
| 94 | -Werror=reorder | 98 | -Werror=reorder |
| 99 | -Werror=shadow | ||
| 95 | -Werror=sign-compare | 100 | -Werror=sign-compare |
| 96 | -Werror=switch | 101 | -Werror=switch |
| 97 | -Werror=uninitialized | 102 | -Werror=uninitialized |
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index e553b8203..89575a53e 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt | |||
| @@ -49,9 +49,6 @@ if (NOT MSVC) | |||
| 49 | target_compile_options(audio_core PRIVATE | 49 | target_compile_options(audio_core PRIVATE |
| 50 | -Werror=conversion | 50 | -Werror=conversion |
| 51 | -Werror=ignored-qualifiers | 51 | -Werror=ignored-qualifiers |
| 52 | -Werror=shadow | ||
| 53 | -Werror=unused-parameter | ||
| 54 | -Werror=unused-variable | ||
| 55 | 52 | ||
| 56 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 53 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
| 57 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> | 54 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> |
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index e40ab16d2..2ee0a96ed 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -98,13 +98,13 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing_, Core::Memor | |||
| 98 | 98 | ||
| 99 | AudioRenderer::~AudioRenderer() = default; | 99 | AudioRenderer::~AudioRenderer() = default; |
| 100 | 100 | ||
| 101 | ResultCode AudioRenderer::Start() { | 101 | Result AudioRenderer::Start() { |
| 102 | audio_out->StartStream(stream); | 102 | audio_out->StartStream(stream); |
| 103 | ReleaseAndQueueBuffers(); | 103 | ReleaseAndQueueBuffers(); |
| 104 | return ResultSuccess; | 104 | return ResultSuccess; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | ResultCode AudioRenderer::Stop() { | 107 | Result AudioRenderer::Stop() { |
| 108 | audio_out->StopStream(stream); | 108 | audio_out->StopStream(stream); |
| 109 | return ResultSuccess; | 109 | return ResultSuccess; |
| 110 | } | 110 | } |
| @@ -125,8 +125,8 @@ Stream::State AudioRenderer::GetStreamState() const { | |||
| 125 | return stream->GetState(); | 125 | return stream->GetState(); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params, | 128 | Result AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params, |
| 129 | std::vector<u8>& output_params) { | 129 | std::vector<u8>& output_params) { |
| 130 | std::scoped_lock lock{mutex}; | 130 | std::scoped_lock lock{mutex}; |
| 131 | InfoUpdater info_updater{input_params, output_params, behavior_info}; | 131 | InfoUpdater info_updater{input_params, output_params, behavior_info}; |
| 132 | 132 | ||
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 1f9f55ae2..a67ffd592 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h | |||
| @@ -43,10 +43,10 @@ public: | |||
| 43 | Stream::ReleaseCallback&& release_callback, std::size_t instance_number); | 43 | Stream::ReleaseCallback&& release_callback, std::size_t instance_number); |
| 44 | ~AudioRenderer(); | 44 | ~AudioRenderer(); |
| 45 | 45 | ||
| 46 | [[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params, | 46 | [[nodiscard]] Result UpdateAudioRenderer(const std::vector<u8>& input_params, |
| 47 | std::vector<u8>& output_params); | 47 | std::vector<u8>& output_params); |
| 48 | [[nodiscard]] ResultCode Start(); | 48 | [[nodiscard]] Result Start(); |
| 49 | [[nodiscard]] ResultCode Stop(); | 49 | [[nodiscard]] Result Stop(); |
| 50 | void QueueMixedBuffer(Buffer::Tag tag); | 50 | void QueueMixedBuffer(Buffer::Tag tag); |
| 51 | void ReleaseAndQueueBuffers(); | 51 | void ReleaseAndQueueBuffers(); |
| 52 | [[nodiscard]] u32 GetSampleRate() const; | 52 | [[nodiscard]] u32 GetSampleRate() const; |
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index ff20ed00f..f97520820 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp | |||
| @@ -429,7 +429,7 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo | |||
| 429 | in_params.node_id); | 429 | in_params.node_id); |
| 430 | break; | 430 | break; |
| 431 | default: | 431 | default: |
| 432 | UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); | 432 | ASSERT_MSG(false, "Unimplemented sample format={}", in_params.sample_format); |
| 433 | } | 433 | } |
| 434 | } | 434 | } |
| 435 | } | 435 | } |
| @@ -1312,7 +1312,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, std::s | |||
| 1312 | samples_to_read - samples_read, channel, temp_mix_offset); | 1312 | samples_to_read - samples_read, channel, temp_mix_offset); |
| 1313 | break; | 1313 | break; |
| 1314 | default: | 1314 | default: |
| 1315 | UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); | 1315 | ASSERT_MSG(false, "Unimplemented sample format={}", in_params.sample_format); |
| 1316 | } | 1316 | } |
| 1317 | 1317 | ||
| 1318 | temp_mix_offset += samples_decoded; | 1318 | temp_mix_offset += samples_decoded; |
diff --git a/src/audio_core/common.h b/src/audio_core/common.h index 46ef83113..056a0ac70 100644 --- a/src/audio_core/common.h +++ b/src/audio_core/common.h | |||
| @@ -10,8 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | namespace AudioCommon { | 11 | namespace AudioCommon { |
| 12 | namespace Audren { | 12 | namespace Audren { |
| 13 | constexpr ResultCode ERR_INVALID_PARAMETERS{ErrorModule::Audio, 41}; | 13 | constexpr Result ERR_INVALID_PARAMETERS{ErrorModule::Audio, 41}; |
| 14 | constexpr ResultCode ERR_SPLITTER_SORT_FAILED{ErrorModule::Audio, 43}; | 14 | constexpr Result ERR_SPLITTER_SORT_FAILED{ErrorModule::Audio, 43}; |
| 15 | } // namespace Audren | 15 | } // namespace Audren |
| 16 | 16 | ||
| 17 | constexpr u8 BASE_REVISION = '0'; | 17 | constexpr u8 BASE_REVISION = '0'; |
diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index 51059580e..79bcd1192 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp | |||
| @@ -50,7 +50,7 @@ EffectBase* EffectContext::RetargetEffect(std::size_t i, EffectType effect) { | |||
| 50 | effects[i] = std::make_unique<EffectBiquadFilter>(); | 50 | effects[i] = std::make_unique<EffectBiquadFilter>(); |
| 51 | break; | 51 | break; |
| 52 | default: | 52 | default: |
| 53 | UNREACHABLE_MSG("Unimplemented effect {}", effect); | 53 | ASSERT_MSG(false, "Unimplemented effect {}", effect); |
| 54 | effects[i] = std::make_unique<EffectStubbed>(); | 54 | effects[i] = std::make_unique<EffectStubbed>(); |
| 55 | } | 55 | } |
| 56 | return GetInfo(i); | 56 | return GetInfo(i); |
| @@ -104,7 +104,7 @@ void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) { | |||
| 104 | auto& params = GetParams(); | 104 | auto& params = GetParams(); |
| 105 | const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data()); | 105 | const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data()); |
| 106 | if (!ValidChannelCountForEffect(reverb_params->max_channels)) { | 106 | if (!ValidChannelCountForEffect(reverb_params->max_channels)) { |
| 107 | UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels); | 107 | ASSERT_MSG(false, "Invalid reverb max channel count {}", reverb_params->max_channels); |
| 108 | return; | 108 | return; |
| 109 | } | 109 | } |
| 110 | 110 | ||
diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp index 313a2eb6d..0065e6e53 100644 --- a/src/audio_core/info_updater.cpp +++ b/src/audio_core/info_updater.cpp | |||
| @@ -285,9 +285,8 @@ bool InfoUpdater::UpdateSplitterInfo(SplitterContext& splitter_context) { | |||
| 285 | return true; | 285 | return true; |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buffer_count, | 288 | Result InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buffer_count, |
| 289 | SplitterContext& splitter_context, | 289 | SplitterContext& splitter_context, EffectContext& effect_context) { |
| 290 | EffectContext& effect_context) { | ||
| 291 | std::vector<MixInfo::InParams> mix_in_params; | 290 | std::vector<MixInfo::InParams> mix_in_params; |
| 292 | 291 | ||
| 293 | if (!behavior_info.IsMixInParameterDirtyOnlyUpdateSupported()) { | 292 | if (!behavior_info.IsMixInParameterDirtyOnlyUpdateSupported()) { |
diff --git a/src/audio_core/info_updater.h b/src/audio_core/info_updater.h index 6aab5beaf..17e66b036 100644 --- a/src/audio_core/info_updater.h +++ b/src/audio_core/info_updater.h | |||
| @@ -32,8 +32,8 @@ public: | |||
| 32 | VAddr audio_codec_dsp_addr); | 32 | VAddr audio_codec_dsp_addr); |
| 33 | bool UpdateEffects(EffectContext& effect_context, bool is_active); | 33 | bool UpdateEffects(EffectContext& effect_context, bool is_active); |
| 34 | bool UpdateSplitterInfo(SplitterContext& splitter_context); | 34 | bool UpdateSplitterInfo(SplitterContext& splitter_context); |
| 35 | ResultCode UpdateMixes(MixContext& mix_context, std::size_t mix_buffer_count, | 35 | Result UpdateMixes(MixContext& mix_context, std::size_t mix_buffer_count, |
| 36 | SplitterContext& splitter_context, EffectContext& effect_context); | 36 | SplitterContext& splitter_context, EffectContext& effect_context); |
| 37 | bool UpdateSinks(SinkContext& sink_context); | 37 | bool UpdateSinks(SinkContext& sink_context); |
| 38 | bool UpdatePerformanceBuffer(); | 38 | bool UpdatePerformanceBuffer(); |
| 39 | bool UpdateErrorInfo(BehaviorInfo& in_behavior_info); | 39 | bool UpdateErrorInfo(BehaviorInfo& in_behavior_info); |
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index 1751d0212..10646dc05 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp | |||
| @@ -483,7 +483,7 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) { | |||
| 483 | // Add more work | 483 | // Add more work |
| 484 | index_stack.push(j); | 484 | index_stack.push(j); |
| 485 | } else if (node_state == NodeStates::State::InFound) { | 485 | } else if (node_state == NodeStates::State::InFound) { |
| 486 | UNREACHABLE_MSG("Node start marked as found"); | 486 | ASSERT_MSG(false, "Node start marked as found"); |
| 487 | ResetState(); | 487 | ResetState(); |
| 488 | return false; | 488 | return false; |
| 489 | } | 489 | } |
diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index c8e4a6caf..f58a5c754 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp | |||
| @@ -114,7 +114,7 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in, | |||
| 114 | in_params.current_playstate = ServerPlayState::Play; | 114 | in_params.current_playstate = ServerPlayState::Play; |
| 115 | break; | 115 | break; |
| 116 | default: | 116 | default: |
| 117 | UNREACHABLE_MSG("Unknown playstate {}", voice_in.play_state); | 117 | ASSERT_MSG(false, "Unknown playstate {}", voice_in.play_state); |
| 118 | break; | 118 | break; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| @@ -410,7 +410,7 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration( | |||
| 410 | return in_params.should_depop; | 410 | return in_params.should_depop; |
| 411 | } | 411 | } |
| 412 | default: | 412 | default: |
| 413 | UNREACHABLE_MSG("Invalid playstate {}", in_params.current_playstate); | 413 | ASSERT_MSG(false, "Invalid playstate {}", in_params.current_playstate); |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | return false; | 416 | return false; |
diff --git a/src/common/assert.cpp b/src/common/assert.cpp index b44570528..6026b7dc2 100644 --- a/src/common/assert.cpp +++ b/src/common/assert.cpp | |||
| @@ -6,8 +6,13 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/settings.h" | 7 | #include "common/settings.h" |
| 8 | 8 | ||
| 9 | void assert_handle_failure() { | 9 | void assert_fail_impl() { |
| 10 | if (Settings::values.use_debug_asserts) { | 10 | if (Settings::values.use_debug_asserts) { |
| 11 | Crash(); | 11 | Crash(); |
| 12 | } | 12 | } |
| 13 | } | 13 | } |
| 14 | |||
| 15 | [[noreturn]] void unreachable_impl() { | ||
| 16 | Crash(); | ||
| 17 | throw std::runtime_error("Unreachable code"); | ||
| 18 | } | ||
diff --git a/src/common/assert.h b/src/common/assert.h index dbfd8abaf..8c927fcc0 100644 --- a/src/common/assert.h +++ b/src/common/assert.h | |||
| @@ -9,44 +9,43 @@ | |||
| 9 | // Sometimes we want to try to continue even after hitting an assert. | 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 | 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. | 11 | // everywhere. So let's just move the handling of the failed assert to a single cpp file. |
| 12 | void assert_handle_failure(); | ||
| 13 | 12 | ||
| 14 | // For asserts we'd like to keep all the junk executed when an assert happens away from the | 13 | void assert_fail_impl(); |
| 15 | // important code in the function. One way of doing this is to put all the relevant code inside a | 14 | [[noreturn]] void unreachable_impl(); |
| 16 | // lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to | 15 | |
| 17 | // specify __declspec on lambda functions, so what we do instead is define a noinline wrapper | 16 | #ifdef _MSC_VER |
| 18 | // template that calls the lambda. This seems to generate an extra instruction at the call-site | 17 | #define YUZU_NO_INLINE __declspec(noinline) |
| 19 | // compared to the ideal implementation (which wouldn't support ASSERT_MSG parameters), but is good | 18 | #else |
| 20 | // enough for our purposes. | 19 | #define YUZU_NO_INLINE __attribute__((noinline)) |
| 21 | template <typename Fn> | ||
| 22 | #if defined(_MSC_VER) | ||
| 23 | [[msvc::noinline]] | ||
| 24 | #elif defined(__GNUC__) | ||
| 25 | [[gnu::cold, gnu::noinline]] | ||
| 26 | #endif | 20 | #endif |
| 27 | static void | ||
| 28 | assert_noinline_call(const Fn& fn) { | ||
| 29 | fn(); | ||
| 30 | assert_handle_failure(); | ||
| 31 | } | ||
| 32 | 21 | ||
| 33 | #define ASSERT(_a_) \ | 22 | #define ASSERT(_a_) \ |
| 34 | do \ | 23 | ([&]() YUZU_NO_INLINE { \ |
| 35 | if (!(_a_)) { \ | 24 | if (!(_a_)) [[unlikely]] { \ |
| 36 | assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \ | 25 | LOG_CRITICAL(Debug, "Assertion Failed!"); \ |
| 26 | assert_fail_impl(); \ | ||
| 37 | } \ | 27 | } \ |
| 38 | while (0) | 28 | }()) |
| 39 | 29 | ||
| 40 | #define ASSERT_MSG(_a_, ...) \ | 30 | #define ASSERT_MSG(_a_, ...) \ |
| 41 | do \ | 31 | ([&]() YUZU_NO_INLINE { \ |
| 42 | if (!(_a_)) { \ | 32 | if (!(_a_)) [[unlikely]] { \ |
| 43 | assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \ | 33 | LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \ |
| 34 | assert_fail_impl(); \ | ||
| 44 | } \ | 35 | } \ |
| 45 | while (0) | 36 | }()) |
| 37 | |||
| 38 | #define UNREACHABLE() \ | ||
| 39 | do { \ | ||
| 40 | LOG_CRITICAL(Debug, "Unreachable code!"); \ | ||
| 41 | unreachable_impl(); \ | ||
| 42 | } while (0) | ||
| 46 | 43 | ||
| 47 | #define UNREACHABLE() assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); }) | ||
| 48 | #define UNREACHABLE_MSG(...) \ | 44 | #define UNREACHABLE_MSG(...) \ |
| 49 | assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); }) | 45 | do { \ |
| 46 | LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \ | ||
| 47 | unreachable_impl(); \ | ||
| 48 | } while (0) | ||
| 50 | 49 | ||
| 51 | #ifdef _DEBUG | 50 | #ifdef _DEBUG |
| 52 | #define DEBUG_ASSERT(_a_) ASSERT(_a_) | 51 | #define DEBUG_ASSERT(_a_) ASSERT(_a_) |
diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h index e83064c7f..7e465549b 100644 --- a/src/common/bounded_threadsafe_queue.h +++ b/src/common/bounded_threadsafe_queue.h | |||
| @@ -1,10 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se> | 1 | // SPDX-FileCopyrightText: Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se> |
| 2 | // SPDX-License-Identifier: MIT | 2 | // SPDX-License-Identifier: MIT |
| 3 | |||
| 3 | #pragma once | 4 | #pragma once |
| 4 | #ifdef _MSC_VER | ||
| 5 | #pragma warning(push) | ||
| 6 | #pragma warning(disable : 4324) | ||
| 7 | #endif | ||
| 8 | 5 | ||
| 9 | #include <atomic> | 6 | #include <atomic> |
| 10 | #include <bit> | 7 | #include <bit> |
| @@ -12,105 +9,63 @@ | |||
| 12 | #include <memory> | 9 | #include <memory> |
| 13 | #include <mutex> | 10 | #include <mutex> |
| 14 | #include <new> | 11 | #include <new> |
| 15 | #include <stdexcept> | ||
| 16 | #include <stop_token> | 12 | #include <stop_token> |
| 17 | #include <type_traits> | 13 | #include <type_traits> |
| 18 | #include <utility> | 14 | #include <utility> |
| 19 | 15 | ||
| 20 | namespace Common { | 16 | namespace Common { |
| 21 | namespace mpsc { | 17 | |
| 22 | #if defined(__cpp_lib_hardware_interference_size) | 18 | #if defined(__cpp_lib_hardware_interference_size) |
| 23 | constexpr size_t hardware_interference_size = std::hardware_destructive_interference_size; | 19 | constexpr size_t hardware_interference_size = std::hardware_destructive_interference_size; |
| 24 | #else | 20 | #else |
| 25 | constexpr size_t hardware_interference_size = 64; | 21 | constexpr size_t hardware_interference_size = 64; |
| 26 | #endif | 22 | #endif |
| 27 | 23 | ||
| 28 | template <typename T> | 24 | #ifdef _MSC_VER |
| 29 | using AlignedAllocator = std::allocator<T>; | 25 | #pragma warning(push) |
| 30 | 26 | #pragma warning(disable : 4324) | |
| 31 | template <typename T> | 27 | #endif |
| 32 | struct Slot { | ||
| 33 | ~Slot() noexcept { | ||
| 34 | if (turn.test()) { | ||
| 35 | destroy(); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | template <typename... Args> | ||
| 40 | void construct(Args&&... args) noexcept { | ||
| 41 | static_assert(std::is_nothrow_constructible_v<T, Args&&...>, | ||
| 42 | "T must be nothrow constructible with Args&&..."); | ||
| 43 | std::construct_at(reinterpret_cast<T*>(&storage), std::forward<Args>(args)...); | ||
| 44 | } | ||
| 45 | |||
| 46 | void destroy() noexcept { | ||
| 47 | static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); | ||
| 48 | std::destroy_at(reinterpret_cast<T*>(&storage)); | ||
| 49 | } | ||
| 50 | |||
| 51 | T&& move() noexcept { | ||
| 52 | return reinterpret_cast<T&&>(storage); | ||
| 53 | } | ||
| 54 | |||
| 55 | // Align to avoid false sharing between adjacent slots | ||
| 56 | alignas(hardware_interference_size) std::atomic_flag turn{}; | ||
| 57 | struct aligned_store { | ||
| 58 | struct type { | ||
| 59 | alignas(T) unsigned char data[sizeof(T)]; | ||
| 60 | }; | ||
| 61 | }; | ||
| 62 | typename aligned_store::type storage; | ||
| 63 | }; | ||
| 64 | 28 | ||
| 65 | template <typename T, typename Allocator = AlignedAllocator<Slot<T>>> | 29 | template <typename T, size_t capacity = 0x400> |
| 66 | class Queue { | 30 | class MPSCQueue { |
| 67 | public: | 31 | public: |
| 68 | explicit Queue(const size_t capacity, const Allocator& allocator = Allocator()) | 32 | explicit MPSCQueue() : allocator{std::allocator<Slot<T>>()} { |
| 69 | : allocator_(allocator) { | ||
| 70 | if (capacity < 1) { | ||
| 71 | throw std::invalid_argument("capacity < 1"); | ||
| 72 | } | ||
| 73 | // Ensure that the queue length is an integer power of 2 | ||
| 74 | // This is so that idx(i) can be a simple i & mask_ insted of i % capacity | ||
| 75 | // https://github.com/rigtorp/MPMCQueue/pull/36 | ||
| 76 | if (!std::has_single_bit(capacity)) { | ||
| 77 | throw std::invalid_argument("capacity must be an integer power of 2"); | ||
| 78 | } | ||
| 79 | |||
| 80 | mask_ = capacity - 1; | ||
| 81 | |||
| 82 | // Allocate one extra slot to prevent false sharing on the last slot | 33 | // Allocate one extra slot to prevent false sharing on the last slot |
| 83 | slots_ = allocator_.allocate(mask_ + 2); | 34 | slots = allocator.allocate(capacity + 1); |
| 84 | // Allocators are not required to honor alignment for over-aligned types | 35 | // Allocators are not required to honor alignment for over-aligned types |
| 85 | // (see http://eel.is/c++draft/allocator.requirements#10) so we verify | 36 | // (see http://eel.is/c++draft/allocator.requirements#10) so we verify |
| 86 | // alignment here | 37 | // alignment here |
| 87 | if (reinterpret_cast<uintptr_t>(slots_) % alignof(Slot<T>) != 0) { | 38 | if (reinterpret_cast<uintptr_t>(slots) % alignof(Slot<T>) != 0) { |
| 88 | allocator_.deallocate(slots_, mask_ + 2); | 39 | allocator.deallocate(slots, capacity + 1); |
| 89 | throw std::bad_alloc(); | 40 | throw std::bad_alloc(); |
| 90 | } | 41 | } |
| 91 | for (size_t i = 0; i < mask_ + 1; ++i) { | 42 | for (size_t i = 0; i < capacity; ++i) { |
| 92 | std::construct_at(&slots_[i]); | 43 | std::construct_at(&slots[i]); |
| 93 | } | 44 | } |
| 45 | static_assert(std::has_single_bit(capacity), "capacity must be an integer power of 2"); | ||
| 94 | static_assert(alignof(Slot<T>) == hardware_interference_size, | 46 | static_assert(alignof(Slot<T>) == hardware_interference_size, |
| 95 | "Slot must be aligned to cache line boundary to prevent false sharing"); | 47 | "Slot must be aligned to cache line boundary to prevent false sharing"); |
| 96 | static_assert(sizeof(Slot<T>) % hardware_interference_size == 0, | 48 | static_assert(sizeof(Slot<T>) % hardware_interference_size == 0, |
| 97 | "Slot size must be a multiple of cache line size to prevent " | 49 | "Slot size must be a multiple of cache line size to prevent " |
| 98 | "false sharing between adjacent slots"); | 50 | "false sharing between adjacent slots"); |
| 99 | static_assert(sizeof(Queue) % hardware_interference_size == 0, | 51 | static_assert(sizeof(MPSCQueue) % hardware_interference_size == 0, |
| 100 | "Queue size must be a multiple of cache line size to " | 52 | "Queue size must be a multiple of cache line size to " |
| 101 | "prevent false sharing between adjacent queues"); | 53 | "prevent false sharing between adjacent queues"); |
| 102 | } | 54 | } |
| 103 | 55 | ||
| 104 | ~Queue() noexcept { | 56 | ~MPSCQueue() noexcept { |
| 105 | for (size_t i = 0; i < mask_ + 1; ++i) { | 57 | for (size_t i = 0; i < capacity; ++i) { |
| 106 | slots_[i].~Slot(); | 58 | std::destroy_at(&slots[i]); |
| 107 | } | 59 | } |
| 108 | allocator_.deallocate(slots_, mask_ + 2); | 60 | allocator.deallocate(slots, capacity + 1); |
| 109 | } | 61 | } |
| 110 | 62 | ||
| 111 | // non-copyable and non-movable | 63 | // The queue must be both non-copyable and non-movable |
| 112 | Queue(const Queue&) = delete; | 64 | MPSCQueue(const MPSCQueue&) = delete; |
| 113 | Queue& operator=(const Queue&) = delete; | 65 | MPSCQueue& operator=(const MPSCQueue&) = delete; |
| 66 | |||
| 67 | MPSCQueue(MPSCQueue&&) = delete; | ||
| 68 | MPSCQueue& operator=(MPSCQueue&&) = delete; | ||
| 114 | 69 | ||
| 115 | void Push(const T& v) noexcept { | 70 | void Push(const T& v) noexcept { |
| 116 | static_assert(std::is_nothrow_copy_constructible_v<T>, | 71 | static_assert(std::is_nothrow_copy_constructible_v<T>, |
| @@ -125,8 +80,8 @@ public: | |||
| 125 | 80 | ||
| 126 | void Pop(T& v, std::stop_token stop) noexcept { | 81 | void Pop(T& v, std::stop_token stop) noexcept { |
| 127 | auto const tail = tail_.fetch_add(1); | 82 | auto const tail = tail_.fetch_add(1); |
| 128 | auto& slot = slots_[idx(tail)]; | 83 | auto& slot = slots[idx(tail)]; |
| 129 | if (false == slot.turn.test()) { | 84 | if (!slot.turn.test()) { |
| 130 | std::unique_lock lock{cv_mutex}; | 85 | std::unique_lock lock{cv_mutex}; |
| 131 | cv.wait(lock, stop, [&slot] { return slot.turn.test(); }); | 86 | cv.wait(lock, stop, [&slot] { return slot.turn.test(); }); |
| 132 | } | 87 | } |
| @@ -137,12 +92,46 @@ public: | |||
| 137 | } | 92 | } |
| 138 | 93 | ||
| 139 | private: | 94 | private: |
| 95 | template <typename U = T> | ||
| 96 | struct Slot { | ||
| 97 | ~Slot() noexcept { | ||
| 98 | if (turn.test()) { | ||
| 99 | destroy(); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | template <typename... Args> | ||
| 104 | void construct(Args&&... args) noexcept { | ||
| 105 | static_assert(std::is_nothrow_constructible_v<U, Args&&...>, | ||
| 106 | "T must be nothrow constructible with Args&&..."); | ||
| 107 | std::construct_at(reinterpret_cast<U*>(&storage), std::forward<Args>(args)...); | ||
| 108 | } | ||
| 109 | |||
| 110 | void destroy() noexcept { | ||
| 111 | static_assert(std::is_nothrow_destructible_v<U>, "T must be nothrow destructible"); | ||
| 112 | std::destroy_at(reinterpret_cast<U*>(&storage)); | ||
| 113 | } | ||
| 114 | |||
| 115 | U&& move() noexcept { | ||
| 116 | return reinterpret_cast<U&&>(storage); | ||
| 117 | } | ||
| 118 | |||
| 119 | // Align to avoid false sharing between adjacent slots | ||
| 120 | alignas(hardware_interference_size) std::atomic_flag turn{}; | ||
| 121 | struct aligned_store { | ||
| 122 | struct type { | ||
| 123 | alignas(U) unsigned char data[sizeof(U)]; | ||
| 124 | }; | ||
| 125 | }; | ||
| 126 | typename aligned_store::type storage; | ||
| 127 | }; | ||
| 128 | |||
| 140 | template <typename... Args> | 129 | template <typename... Args> |
| 141 | void emplace(Args&&... args) noexcept { | 130 | void emplace(Args&&... args) noexcept { |
| 142 | static_assert(std::is_nothrow_constructible_v<T, Args&&...>, | 131 | static_assert(std::is_nothrow_constructible_v<T, Args&&...>, |
| 143 | "T must be nothrow constructible with Args&&..."); | 132 | "T must be nothrow constructible with Args&&..."); |
| 144 | auto const head = head_.fetch_add(1); | 133 | auto const head = head_.fetch_add(1); |
| 145 | auto& slot = slots_[idx(head)]; | 134 | auto& slot = slots[idx(head)]; |
| 146 | slot.turn.wait(true); | 135 | slot.turn.wait(true); |
| 147 | slot.construct(std::forward<Args>(args)...); | 136 | slot.construct(std::forward<Args>(args)...); |
| 148 | slot.turn.test_and_set(); | 137 | slot.turn.test_and_set(); |
| @@ -150,31 +139,29 @@ private: | |||
| 150 | } | 139 | } |
| 151 | 140 | ||
| 152 | constexpr size_t idx(size_t i) const noexcept { | 141 | constexpr size_t idx(size_t i) const noexcept { |
| 153 | return i & mask_; | 142 | return i & mask; |
| 154 | } | 143 | } |
| 155 | 144 | ||
| 156 | std::conditional_t<true, std::condition_variable_any, std::condition_variable> cv; | 145 | static constexpr size_t mask = capacity - 1; |
| 157 | std::mutex cv_mutex; | ||
| 158 | size_t mask_; | ||
| 159 | Slot<T>* slots_; | ||
| 160 | [[no_unique_address]] Allocator allocator_; | ||
| 161 | 146 | ||
| 162 | // Align to avoid false sharing between head_ and tail_ | 147 | // Align to avoid false sharing between head_ and tail_ |
| 163 | alignas(hardware_interference_size) std::atomic<size_t> head_{0}; | 148 | alignas(hardware_interference_size) std::atomic<size_t> head_{0}; |
| 164 | alignas(hardware_interference_size) std::atomic<size_t> tail_{0}; | 149 | alignas(hardware_interference_size) std::atomic<size_t> tail_{0}; |
| 165 | 150 | ||
| 151 | std::mutex cv_mutex; | ||
| 152 | std::condition_variable_any cv; | ||
| 153 | |||
| 154 | Slot<T>* slots; | ||
| 155 | [[no_unique_address]] std::allocator<Slot<T>> allocator; | ||
| 156 | |||
| 166 | static_assert(std::is_nothrow_copy_assignable_v<T> || std::is_nothrow_move_assignable_v<T>, | 157 | static_assert(std::is_nothrow_copy_assignable_v<T> || std::is_nothrow_move_assignable_v<T>, |
| 167 | "T must be nothrow copy or move assignable"); | 158 | "T must be nothrow copy or move assignable"); |
| 168 | 159 | ||
| 169 | static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); | 160 | static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); |
| 170 | }; | 161 | }; |
| 171 | } // namespace mpsc | ||
| 172 | |||
| 173 | template <typename T, typename Allocator = mpsc::AlignedAllocator<mpsc::Slot<T>>> | ||
| 174 | using MPSCQueue = mpsc::Queue<T, Allocator>; | ||
| 175 | |||
| 176 | } // namespace Common | ||
| 177 | 162 | ||
| 178 | #ifdef _MSC_VER | 163 | #ifdef _MSC_VER |
| 179 | #pragma warning(pop) | 164 | #pragma warning(pop) |
| 180 | #endif | 165 | #endif |
| 166 | |||
| 167 | } // namespace Common | ||
diff --git a/src/common/detached_tasks.cpp b/src/common/detached_tasks.cpp index c1362631e..ec31d0b88 100644 --- a/src/common/detached_tasks.cpp +++ b/src/common/detached_tasks.cpp | |||
| @@ -33,9 +33,9 @@ void DetachedTasks::AddTask(std::function<void()> task) { | |||
| 33 | ++instance->count; | 33 | ++instance->count; |
| 34 | std::thread([task{std::move(task)}]() { | 34 | std::thread([task{std::move(task)}]() { |
| 35 | task(); | 35 | task(); |
| 36 | std::unique_lock lock{instance->mutex}; | 36 | std::unique_lock thread_lock{instance->mutex}; |
| 37 | --instance->count; | 37 | --instance->count; |
| 38 | std::notify_all_at_thread_exit(instance->cv, std::move(lock)); | 38 | std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock)); |
| 39 | }).detach(); | 39 | }).detach(); |
| 40 | } | 40 | } |
| 41 | 41 | ||
diff --git a/src/common/page_table.h b/src/common/page_table.h index fcbd12a43..1ad3a9f8b 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h | |||
| @@ -15,6 +15,9 @@ enum class PageType : u8 { | |||
| 15 | Unmapped, | 15 | Unmapped, |
| 16 | /// Page is mapped to regular memory. This is the only type you can get pointers to. | 16 | /// Page is mapped to regular memory. This is the only type you can get pointers to. |
| 17 | Memory, | 17 | Memory, |
| 18 | /// Page is mapped to regular memory, but inaccessible from CPU fastmem and must use | ||
| 19 | /// the callbacks. | ||
| 20 | DebugMemory, | ||
| 18 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and | 21 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and |
| 19 | /// invalidation | 22 | /// invalidation |
| 20 | RasterizerCachedMemory, | 23 | RasterizerCachedMemory, |
diff --git a/src/common/param_package.cpp b/src/common/param_package.cpp index bbf20f5eb..462502e34 100644 --- a/src/common/param_package.cpp +++ b/src/common/param_package.cpp | |||
| @@ -76,7 +76,7 @@ std::string ParamPackage::Serialize() const { | |||
| 76 | std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const { | 76 | std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const { |
| 77 | auto pair = data.find(key); | 77 | auto pair = data.find(key); |
| 78 | if (pair == data.end()) { | 78 | if (pair == data.end()) { |
| 79 | LOG_DEBUG(Common, "key '{}' not found", key); | 79 | LOG_TRACE(Common, "key '{}' not found", key); |
| 80 | return default_value; | 80 | return default_value; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| @@ -86,7 +86,7 @@ std::string ParamPackage::Get(const std::string& key, const std::string& default | |||
| 86 | int ParamPackage::Get(const std::string& key, int default_value) const { | 86 | int ParamPackage::Get(const std::string& key, int default_value) const { |
| 87 | auto pair = data.find(key); | 87 | auto pair = data.find(key); |
| 88 | if (pair == data.end()) { | 88 | if (pair == data.end()) { |
| 89 | LOG_DEBUG(Common, "key '{}' not found", key); | 89 | LOG_TRACE(Common, "key '{}' not found", key); |
| 90 | return default_value; | 90 | return default_value; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| @@ -101,7 +101,7 @@ int ParamPackage::Get(const std::string& key, int default_value) const { | |||
| 101 | float ParamPackage::Get(const std::string& key, float default_value) const { | 101 | float ParamPackage::Get(const std::string& key, float default_value) const { |
| 102 | auto pair = data.find(key); | 102 | auto pair = data.find(key); |
| 103 | if (pair == data.end()) { | 103 | if (pair == data.end()) { |
| 104 | LOG_DEBUG(Common, "key {} not found", key); | 104 | LOG_TRACE(Common, "key {} not found", key); |
| 105 | return default_value; | 105 | return default_value; |
| 106 | } | 106 | } |
| 107 | 107 | ||
diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 6ffab63af..751549583 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp | |||
| @@ -147,7 +147,7 @@ void UpdateRescalingInfo() { | |||
| 147 | info.down_shift = 0; | 147 | info.down_shift = 0; |
| 148 | break; | 148 | break; |
| 149 | default: | 149 | default: |
| 150 | UNREACHABLE(); | 150 | ASSERT(false); |
| 151 | info.up_scale = 1; | 151 | info.up_scale = 1; |
| 152 | info.down_shift = 0; | 152 | info.down_shift = 0; |
| 153 | } | 153 | } |
diff --git a/src/common/thread.cpp b/src/common/thread.cpp index f932a7290..919e33af9 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp | |||
| @@ -47,6 +47,9 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { | |||
| 47 | case ThreadPriority::VeryHigh: | 47 | case ThreadPriority::VeryHigh: |
| 48 | windows_priority = THREAD_PRIORITY_HIGHEST; | 48 | windows_priority = THREAD_PRIORITY_HIGHEST; |
| 49 | break; | 49 | break; |
| 50 | case ThreadPriority::Critical: | ||
| 51 | windows_priority = THREAD_PRIORITY_TIME_CRITICAL; | ||
| 52 | break; | ||
| 50 | default: | 53 | default: |
| 51 | windows_priority = THREAD_PRIORITY_NORMAL; | 54 | windows_priority = THREAD_PRIORITY_NORMAL; |
| 52 | break; | 55 | break; |
| @@ -59,9 +62,10 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { | |||
| 59 | void SetCurrentThreadPriority(ThreadPriority new_priority) { | 62 | void SetCurrentThreadPriority(ThreadPriority new_priority) { |
| 60 | pthread_t this_thread = pthread_self(); | 63 | pthread_t this_thread = pthread_self(); |
| 61 | 64 | ||
| 62 | s32 max_prio = sched_get_priority_max(SCHED_OTHER); | 65 | const auto scheduling_type = SCHED_OTHER; |
| 63 | s32 min_prio = sched_get_priority_min(SCHED_OTHER); | 66 | s32 max_prio = sched_get_priority_max(scheduling_type); |
| 64 | u32 level = static_cast<u32>(new_priority) + 1; | 67 | s32 min_prio = sched_get_priority_min(scheduling_type); |
| 68 | u32 level = std::max(static_cast<u32>(new_priority) + 1, 4U); | ||
| 65 | 69 | ||
| 66 | struct sched_param params; | 70 | struct sched_param params; |
| 67 | if (max_prio > min_prio) { | 71 | if (max_prio > min_prio) { |
| @@ -70,7 +74,7 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { | |||
| 70 | params.sched_priority = min_prio - ((min_prio - max_prio) * level) / 4; | 74 | params.sched_priority = min_prio - ((min_prio - max_prio) * level) / 4; |
| 71 | } | 75 | } |
| 72 | 76 | ||
| 73 | pthread_setschedparam(this_thread, SCHED_OTHER, ¶ms); | 77 | pthread_setschedparam(this_thread, scheduling_type, ¶ms); |
| 74 | } | 78 | } |
| 75 | 79 | ||
| 76 | #endif | 80 | #endif |
diff --git a/src/common/thread.h b/src/common/thread.h index a63122516..1552f58e0 100644 --- a/src/common/thread.h +++ b/src/common/thread.h | |||
| @@ -92,6 +92,7 @@ enum class ThreadPriority : u32 { | |||
| 92 | Normal = 1, | 92 | Normal = 1, |
| 93 | High = 2, | 93 | High = 2, |
| 94 | VeryHigh = 3, | 94 | VeryHigh = 3, |
| 95 | Critical = 4, | ||
| 95 | }; | 96 | }; |
| 96 | 97 | ||
| 97 | void SetCurrentThreadPriority(ThreadPriority new_priority); | 98 | void SetCurrentThreadPriority(ThreadPriority new_priority); |
diff --git a/src/common/uint128.h b/src/common/uint128.h index f890ffec2..199d0f55e 100644 --- a/src/common/uint128.h +++ b/src/common/uint128.h | |||
| @@ -31,12 +31,17 @@ namespace Common { | |||
| 31 | return _udiv128(r[1], r[0], d, &remainder); | 31 | return _udiv128(r[1], r[0], d, &remainder); |
| 32 | #endif | 32 | #endif |
| 33 | #else | 33 | #else |
| 34 | #ifdef __SIZEOF_INT128__ | ||
| 35 | const auto product = static_cast<unsigned __int128>(a) * static_cast<unsigned __int128>(b); | ||
| 36 | return static_cast<u64>(product / d); | ||
| 37 | #else | ||
| 34 | const u64 diva = a / d; | 38 | const u64 diva = a / d; |
| 35 | const u64 moda = a % d; | 39 | const u64 moda = a % d; |
| 36 | const u64 divb = b / d; | 40 | const u64 divb = b / d; |
| 37 | const u64 modb = b % d; | 41 | const u64 modb = b % d; |
| 38 | return diva * b + moda * divb + moda * modb / d; | 42 | return diva * b + moda * divb + moda * modb / d; |
| 39 | #endif | 43 | #endif |
| 44 | #endif | ||
| 40 | } | 45 | } |
| 41 | 46 | ||
| 42 | // This function multiplies 2 u64 values and produces a u128 value; | 47 | // This function multiplies 2 u64 values and produces a u128 value; |
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 1b7194503..6aaa8cdf9 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -75,8 +75,8 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen | |||
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | u64 NativeClock::GetRTSC() { | 77 | u64 NativeClock::GetRTSC() { |
| 78 | TimePoint new_time_point{}; | ||
| 79 | TimePoint current_time_point{}; | 78 | TimePoint current_time_point{}; |
| 79 | TimePoint new_time_point{}; | ||
| 80 | 80 | ||
| 81 | current_time_point.pack = Common::AtomicLoad128(time_point.pack.data()); | 81 | current_time_point.pack = Common::AtomicLoad128(time_point.pack.data()); |
| 82 | do { | 82 | do { |
| @@ -89,8 +89,7 @@ u64 NativeClock::GetRTSC() { | |||
| 89 | new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff; | 89 | new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff; |
| 90 | } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, | 90 | } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, |
| 91 | current_time_point.pack, current_time_point.pack)); | 91 | current_time_point.pack, current_time_point.pack)); |
| 92 | /// The clock cannot be more precise than the guest timer, remove the lower bits | 92 | return new_time_point.inner.accumulated_ticks; |
| 93 | return new_time_point.inner.accumulated_ticks & inaccuracy_mask; | ||
| 94 | } | 93 | } |
| 95 | 94 | ||
| 96 | void NativeClock::Pause(bool is_paused) { | 95 | void NativeClock::Pause(bool is_paused) { |
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 30d2ba2e9..38ae7a462 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h | |||
| @@ -37,12 +37,8 @@ private: | |||
| 37 | } inner; | 37 | } inner; |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | /// value used to reduce the native clocks accuracy as some apss rely on | ||
| 41 | /// undefined behavior where the level of accuracy in the clock shouldn't | ||
| 42 | /// be higher. | ||
| 43 | static constexpr u64 inaccuracy_mask = ~(UINT64_C(0x400) - 1); | ||
| 44 | |||
| 45 | TimePoint time_point; | 40 | TimePoint time_point; |
| 41 | |||
| 46 | // factors | 42 | // factors |
| 47 | u64 clock_rtsc_factor{}; | 43 | u64 clock_rtsc_factor{}; |
| 48 | u64 cpu_rtsc_factor{}; | 44 | u64 cpu_rtsc_factor{}; |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2bd720f08..d9357138f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -222,7 +222,7 @@ add_library(core STATIC | |||
| 222 | hle/kernel/k_page_buffer.h | 222 | hle/kernel/k_page_buffer.h |
| 223 | hle/kernel/k_page_heap.cpp | 223 | hle/kernel/k_page_heap.cpp |
| 224 | hle/kernel/k_page_heap.h | 224 | hle/kernel/k_page_heap.h |
| 225 | hle/kernel/k_page_linked_list.h | 225 | hle/kernel/k_page_group.h |
| 226 | hle/kernel/k_page_table.cpp | 226 | hle/kernel/k_page_table.cpp |
| 227 | hle/kernel/k_page_table.h | 227 | hle/kernel/k_page_table.h |
| 228 | hle/kernel/k_port.cpp | 228 | hle/kernel/k_port.cpp |
| @@ -743,16 +743,11 @@ if (MSVC) | |||
| 743 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data | 743 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data |
| 744 | /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch | 744 | /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch |
| 745 | /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data | 745 | /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data |
| 746 | /we4456 # Declaration of 'identifier' hides previous local declaration | ||
| 747 | /we4457 # Declaration of 'identifier' hides function parameter | ||
| 748 | /we4458 # Declaration of 'identifier' hides class member | ||
| 749 | /we4459 # Declaration of 'identifier' hides global declaration | ||
| 750 | ) | 746 | ) |
| 751 | else() | 747 | else() |
| 752 | target_compile_options(core PRIVATE | 748 | target_compile_options(core PRIVATE |
| 753 | -Werror=conversion | 749 | -Werror=conversion |
| 754 | -Werror=ignored-qualifiers | 750 | -Werror=ignored-qualifiers |
| 755 | -Werror=shadow | ||
| 756 | 751 | ||
| 757 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> | 752 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> |
| 758 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 753 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 9b5a5ca57..0efc3732f 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -95,7 +95,7 @@ void ARM_Interface::Run() { | |||
| 95 | using Kernel::SuspendType; | 95 | using Kernel::SuspendType; |
| 96 | 96 | ||
| 97 | while (true) { | 97 | while (true) { |
| 98 | Kernel::KThread* current_thread{system.Kernel().CurrentScheduler()->GetCurrentThread()}; | 98 | Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; |
| 99 | Dynarmic::HaltReason hr{}; | 99 | Dynarmic::HaltReason hr{}; |
| 100 | 100 | ||
| 101 | // Notify the debugger and go to sleep if a step was performed | 101 | // Notify the debugger and go to sleep if a step was performed |
| @@ -107,6 +107,7 @@ void ARM_Interface::Run() { | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | // Otherwise, run the thread. | 109 | // Otherwise, run the thread. |
| 110 | system.EnterDynarmicProfile(); | ||
| 110 | if (current_thread->GetStepState() == StepState::StepPending) { | 111 | if (current_thread->GetStepState() == StepState::StepPending) { |
| 111 | hr = StepJit(); | 112 | hr = StepJit(); |
| 112 | 113 | ||
| @@ -116,14 +117,29 @@ void ARM_Interface::Run() { | |||
| 116 | } else { | 117 | } else { |
| 117 | hr = RunJit(); | 118 | hr = RunJit(); |
| 118 | } | 119 | } |
| 119 | 120 | system.ExitDynarmicProfile(); | |
| 120 | // Notify the debugger and go to sleep if a breakpoint was hit. | 121 | |
| 121 | if (Has(hr, breakpoint)) { | 122 | // Notify the debugger and go to sleep if a breakpoint was hit, |
| 122 | system.GetDebugger().NotifyThreadStopped(current_thread); | 123 | // or if the thread is unable to continue for any reason. |
| 124 | if (Has(hr, breakpoint) || Has(hr, no_execute)) { | ||
| 125 | RewindBreakpointInstruction(); | ||
| 126 | if (system.DebuggerEnabled()) { | ||
| 127 | system.GetDebugger().NotifyThreadStopped(current_thread); | ||
| 128 | } | ||
| 123 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); | 129 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); |
| 124 | break; | 130 | break; |
| 125 | } | 131 | } |
| 126 | 132 | ||
| 133 | // Notify the debugger and go to sleep if a watchpoint was hit. | ||
| 134 | if (Has(hr, watchpoint)) { | ||
| 135 | RewindBreakpointInstruction(); | ||
| 136 | if (system.DebuggerEnabled()) { | ||
| 137 | system.GetDebugger().NotifyThreadWatchpoint(current_thread, *HaltedWatchpoint()); | ||
| 138 | } | ||
| 139 | current_thread->RequestSuspend(SuspendType::Debug); | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | |||
| 127 | // Handle syscalls and scheduling (this may change the current thread) | 143 | // Handle syscalls and scheduling (this may change the current thread) |
| 128 | if (Has(hr, svc_call)) { | 144 | if (Has(hr, svc_call)) { |
| 129 | Kernel::Svc::Call(system, GetSvcNumber()); | 145 | Kernel::Svc::Call(system, GetSvcNumber()); |
| @@ -134,4 +150,36 @@ void ARM_Interface::Run() { | |||
| 134 | } | 150 | } |
| 135 | } | 151 | } |
| 136 | 152 | ||
| 153 | void ARM_Interface::LoadWatchpointArray(const WatchpointArray& wp) { | ||
| 154 | watchpoints = ℘ | ||
| 155 | } | ||
| 156 | |||
| 157 | const Kernel::DebugWatchpoint* ARM_Interface::MatchingWatchpoint( | ||
| 158 | VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const { | ||
| 159 | if (!watchpoints) { | ||
| 160 | return nullptr; | ||
| 161 | } | ||
| 162 | |||
| 163 | const VAddr start_address{addr}; | ||
| 164 | const VAddr end_address{addr + size}; | ||
| 165 | |||
| 166 | for (size_t i = 0; i < Core::Hardware::NUM_WATCHPOINTS; i++) { | ||
| 167 | const auto& watch{(*watchpoints)[i]}; | ||
| 168 | |||
| 169 | if (end_address <= watch.start_address) { | ||
| 170 | continue; | ||
| 171 | } | ||
| 172 | if (start_address >= watch.end_address) { | ||
| 173 | continue; | ||
| 174 | } | ||
| 175 | if ((access_type & watch.type) == Kernel::DebugWatchpointType::None) { | ||
| 176 | continue; | ||
| 177 | } | ||
| 178 | |||
| 179 | return &watch; | ||
| 180 | } | ||
| 181 | |||
| 182 | return nullptr; | ||
| 183 | } | ||
| 184 | |||
| 137 | } // namespace Core | 185 | } // namespace Core |
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 66f6107e9..8a066ed91 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <span> | ||
| 8 | #include <vector> | 9 | #include <vector> |
| 9 | 10 | ||
| 10 | #include <dynarmic/interface/halt_reason.h> | 11 | #include <dynarmic/interface/halt_reason.h> |
| @@ -19,13 +20,16 @@ struct PageTable; | |||
| 19 | 20 | ||
| 20 | namespace Kernel { | 21 | namespace Kernel { |
| 21 | enum class VMAPermission : u8; | 22 | enum class VMAPermission : u8; |
| 22 | } | 23 | enum class DebugWatchpointType : u8; |
| 24 | struct DebugWatchpoint; | ||
| 25 | } // namespace Kernel | ||
| 23 | 26 | ||
| 24 | namespace Core { | 27 | namespace Core { |
| 25 | class System; | 28 | class System; |
| 26 | class CPUInterruptHandler; | 29 | class CPUInterruptHandler; |
| 27 | 30 | ||
| 28 | using CPUInterrupts = std::array<CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>; | 31 | using CPUInterrupts = std::array<CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>; |
| 32 | using WatchpointArray = std::array<Kernel::DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>; | ||
| 29 | 33 | ||
| 30 | /// Generic ARMv8 CPU interface | 34 | /// Generic ARMv8 CPU interface |
| 31 | class ARM_Interface { | 35 | class ARM_Interface { |
| @@ -170,6 +174,7 @@ public: | |||
| 170 | virtual void SaveContext(ThreadContext64& ctx) = 0; | 174 | virtual void SaveContext(ThreadContext64& ctx) = 0; |
| 171 | virtual void LoadContext(const ThreadContext32& ctx) = 0; | 175 | virtual void LoadContext(const ThreadContext32& ctx) = 0; |
| 172 | virtual void LoadContext(const ThreadContext64& ctx) = 0; | 176 | virtual void LoadContext(const ThreadContext64& ctx) = 0; |
| 177 | void LoadWatchpointArray(const WatchpointArray& wp); | ||
| 173 | 178 | ||
| 174 | /// Clears the exclusive monitor's state. | 179 | /// Clears the exclusive monitor's state. |
| 175 | virtual void ClearExclusiveState() = 0; | 180 | virtual void ClearExclusiveState() = 0; |
| @@ -198,18 +203,25 @@ public: | |||
| 198 | static constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2; | 203 | static constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2; |
| 199 | static constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3; | 204 | static constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3; |
| 200 | static constexpr Dynarmic::HaltReason breakpoint = Dynarmic::HaltReason::UserDefined4; | 205 | static constexpr Dynarmic::HaltReason breakpoint = Dynarmic::HaltReason::UserDefined4; |
| 206 | static constexpr Dynarmic::HaltReason watchpoint = Dynarmic::HaltReason::UserDefined5; | ||
| 207 | static constexpr Dynarmic::HaltReason no_execute = Dynarmic::HaltReason::UserDefined6; | ||
| 201 | 208 | ||
| 202 | protected: | 209 | protected: |
| 203 | /// System context that this ARM interface is running under. | 210 | /// System context that this ARM interface is running under. |
| 204 | System& system; | 211 | System& system; |
| 205 | CPUInterrupts& interrupt_handlers; | 212 | CPUInterrupts& interrupt_handlers; |
| 213 | const WatchpointArray* watchpoints; | ||
| 206 | bool uses_wall_clock; | 214 | bool uses_wall_clock; |
| 207 | 215 | ||
| 208 | static void SymbolicateBacktrace(Core::System& system, std::vector<BacktraceEntry>& out); | 216 | static void SymbolicateBacktrace(Core::System& system, std::vector<BacktraceEntry>& out); |
| 217 | const Kernel::DebugWatchpoint* MatchingWatchpoint( | ||
| 218 | VAddr addr, u64 size, Kernel::DebugWatchpointType access_type) const; | ||
| 209 | 219 | ||
| 210 | virtual Dynarmic::HaltReason RunJit() = 0; | 220 | virtual Dynarmic::HaltReason RunJit() = 0; |
| 211 | virtual Dynarmic::HaltReason StepJit() = 0; | 221 | virtual Dynarmic::HaltReason StepJit() = 0; |
| 212 | virtual u32 GetSvcNumber() const = 0; | 222 | virtual u32 GetSvcNumber() const = 0; |
| 223 | virtual const Kernel::DebugWatchpoint* HaltedWatchpoint() const = 0; | ||
| 224 | virtual void RewindBreakpointInstruction() = 0; | ||
| 213 | }; | 225 | }; |
| 214 | 226 | ||
| 215 | } // namespace Core | 227 | } // namespace Core |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 7c82d0b96..10cf72a45 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -29,64 +29,94 @@ using namespace Common::Literals; | |||
| 29 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { | 29 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { |
| 30 | public: | 30 | public: |
| 31 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) | 31 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) |
| 32 | : parent{parent_}, memory(parent.system.Memory()) {} | 32 | : parent{parent_}, |
| 33 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} | ||
| 33 | 34 | ||
| 34 | u8 MemoryRead8(u32 vaddr) override { | 35 | u8 MemoryRead8(u32 vaddr) override { |
| 36 | CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); | ||
| 35 | return memory.Read8(vaddr); | 37 | return memory.Read8(vaddr); |
| 36 | } | 38 | } |
| 37 | u16 MemoryRead16(u32 vaddr) override { | 39 | u16 MemoryRead16(u32 vaddr) override { |
| 40 | CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Read); | ||
| 38 | return memory.Read16(vaddr); | 41 | return memory.Read16(vaddr); |
| 39 | } | 42 | } |
| 40 | u32 MemoryRead32(u32 vaddr) override { | 43 | u32 MemoryRead32(u32 vaddr) override { |
| 44 | CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Read); | ||
| 41 | return memory.Read32(vaddr); | 45 | return memory.Read32(vaddr); |
| 42 | } | 46 | } |
| 43 | u64 MemoryRead64(u32 vaddr) override { | 47 | u64 MemoryRead64(u32 vaddr) override { |
| 48 | CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Read); | ||
| 44 | return memory.Read64(vaddr); | 49 | return memory.Read64(vaddr); |
| 45 | } | 50 | } |
| 51 | std::optional<u32> MemoryReadCode(u32 vaddr) override { | ||
| 52 | if (!memory.IsValidVirtualAddressRange(vaddr, sizeof(u32))) { | ||
| 53 | return std::nullopt; | ||
| 54 | } | ||
| 55 | return MemoryRead32(vaddr); | ||
| 56 | } | ||
| 46 | 57 | ||
| 47 | void MemoryWrite8(u32 vaddr, u8 value) override { | 58 | void MemoryWrite8(u32 vaddr, u8 value) override { |
| 48 | memory.Write8(vaddr, value); | 59 | if (CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write)) { |
| 60 | memory.Write8(vaddr, value); | ||
| 61 | } | ||
| 49 | } | 62 | } |
| 50 | void MemoryWrite16(u32 vaddr, u16 value) override { | 63 | void MemoryWrite16(u32 vaddr, u16 value) override { |
| 51 | memory.Write16(vaddr, value); | 64 | if (CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Write)) { |
| 65 | memory.Write16(vaddr, value); | ||
| 66 | } | ||
| 52 | } | 67 | } |
| 53 | void MemoryWrite32(u32 vaddr, u32 value) override { | 68 | void MemoryWrite32(u32 vaddr, u32 value) override { |
| 54 | memory.Write32(vaddr, value); | 69 | if (CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Write)) { |
| 70 | memory.Write32(vaddr, value); | ||
| 71 | } | ||
| 55 | } | 72 | } |
| 56 | void MemoryWrite64(u32 vaddr, u64 value) override { | 73 | void MemoryWrite64(u32 vaddr, u64 value) override { |
| 57 | memory.Write64(vaddr, value); | 74 | if (CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Write)) { |
| 75 | memory.Write64(vaddr, value); | ||
| 76 | } | ||
| 58 | } | 77 | } |
| 59 | 78 | ||
| 60 | bool MemoryWriteExclusive8(u32 vaddr, u8 value, u8 expected) override { | 79 | bool MemoryWriteExclusive8(u32 vaddr, u8 value, u8 expected) override { |
| 61 | return memory.WriteExclusive8(vaddr, value, expected); | 80 | return CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write) && |
| 81 | memory.WriteExclusive8(vaddr, value, expected); | ||
| 62 | } | 82 | } |
| 63 | bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override { | 83 | bool MemoryWriteExclusive16(u32 vaddr, u16 value, u16 expected) override { |
| 64 | return memory.WriteExclusive16(vaddr, value, expected); | 84 | return CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Write) && |
| 85 | memory.WriteExclusive16(vaddr, value, expected); | ||
| 65 | } | 86 | } |
| 66 | bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override { | 87 | bool MemoryWriteExclusive32(u32 vaddr, u32 value, u32 expected) override { |
| 67 | return memory.WriteExclusive32(vaddr, value, expected); | 88 | return CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Write) && |
| 89 | memory.WriteExclusive32(vaddr, value, expected); | ||
| 68 | } | 90 | } |
| 69 | bool MemoryWriteExclusive64(u32 vaddr, u64 value, u64 expected) override { | 91 | bool MemoryWriteExclusive64(u32 vaddr, u64 value, u64 expected) override { |
| 70 | return memory.WriteExclusive64(vaddr, value, expected); | 92 | return CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Write) && |
| 93 | memory.WriteExclusive64(vaddr, value, expected); | ||
| 71 | } | 94 | } |
| 72 | 95 | ||
| 73 | void InterpreterFallback(u32 pc, std::size_t num_instructions) override { | 96 | void InterpreterFallback(u32 pc, std::size_t num_instructions) override { |
| 74 | parent.LogBacktrace(); | 97 | parent.LogBacktrace(); |
| 75 | UNIMPLEMENTED_MSG("This should never happen, pc = {:08X}, code = {:08X}", pc, | 98 | LOG_ERROR(Core_ARM, |
| 76 | MemoryReadCode(pc)); | 99 | "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, |
| 100 | num_instructions, MemoryRead32(pc)); | ||
| 77 | } | 101 | } |
| 78 | 102 | ||
| 79 | void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { | 103 | void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { |
| 80 | if (parent.system.DebuggerEnabled()) { | 104 | switch (exception) { |
| 81 | parent.jit.load()->Regs()[15] = pc; | 105 | case Dynarmic::A32::Exception::NoExecuteFault: |
| 82 | parent.jit.load()->HaltExecution(ARM_Interface::breakpoint); | 106 | LOG_CRITICAL(Core_ARM, "Cannot execute instruction at unmapped address {:#08x}", pc); |
| 107 | ReturnException(pc, ARM_Interface::no_execute); | ||
| 83 | return; | 108 | return; |
| 84 | } | 109 | default: |
| 110 | if (debugger_enabled) { | ||
| 111 | ReturnException(pc, ARM_Interface::breakpoint); | ||
| 112 | return; | ||
| 113 | } | ||
| 85 | 114 | ||
| 86 | parent.LogBacktrace(); | 115 | parent.LogBacktrace(); |
| 87 | LOG_CRITICAL(Core_ARM, | 116 | LOG_CRITICAL(Core_ARM, |
| 88 | "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X}, thumb = {})", | 117 | "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X}, thumb = {})", |
| 89 | exception, pc, MemoryReadCode(pc), parent.IsInThumbMode()); | 118 | exception, pc, MemoryRead32(pc), parent.IsInThumbMode()); |
| 119 | } | ||
| 90 | } | 120 | } |
| 91 | 121 | ||
| 92 | void CallSVC(u32 swi) override { | 122 | void CallSVC(u32 swi) override { |
| @@ -117,9 +147,31 @@ public: | |||
| 117 | return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); | 147 | return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); |
| 118 | } | 148 | } |
| 119 | 149 | ||
| 150 | bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { | ||
| 151 | if (!debugger_enabled) { | ||
| 152 | return true; | ||
| 153 | } | ||
| 154 | |||
| 155 | const auto match{parent.MatchingWatchpoint(addr, size, type)}; | ||
| 156 | if (match) { | ||
| 157 | parent.halted_watchpoint = match; | ||
| 158 | ReturnException(parent.jit.load()->Regs()[15], ARM_Interface::watchpoint); | ||
| 159 | return false; | ||
| 160 | } | ||
| 161 | |||
| 162 | return true; | ||
| 163 | } | ||
| 164 | |||
| 165 | void ReturnException(u32 pc, Dynarmic::HaltReason hr) { | ||
| 166 | parent.SaveContext(parent.breakpoint_context); | ||
| 167 | parent.breakpoint_context.cpu_registers[15] = pc; | ||
| 168 | parent.jit.load()->HaltExecution(hr); | ||
| 169 | } | ||
| 170 | |||
| 120 | ARM_Dynarmic_32& parent; | 171 | ARM_Dynarmic_32& parent; |
| 121 | Core::Memory::Memory& memory; | 172 | Core::Memory::Memory& memory; |
| 122 | std::size_t num_interpreted_instructions{}; | 173 | std::size_t num_interpreted_instructions{}; |
| 174 | bool debugger_enabled{}; | ||
| 123 | static constexpr u64 minimum_run_cycles = 1000U; | 175 | static constexpr u64 minimum_run_cycles = 1000U; |
| 124 | }; | 176 | }; |
| 125 | 177 | ||
| @@ -154,6 +206,11 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* | |||
| 154 | config.code_cache_size = 512_MiB; | 206 | config.code_cache_size = 512_MiB; |
| 155 | config.far_code_offset = 400_MiB; | 207 | config.far_code_offset = 400_MiB; |
| 156 | 208 | ||
| 209 | // Allow memory fault handling to work | ||
| 210 | if (system.DebuggerEnabled()) { | ||
| 211 | config.check_halt_on_memory_access = true; | ||
| 212 | } | ||
| 213 | |||
| 157 | // null_jit | 214 | // null_jit |
| 158 | if (!page_table) { | 215 | if (!page_table) { |
| 159 | // Don't waste too much memory on null_jit | 216 | // Don't waste too much memory on null_jit |
| @@ -248,6 +305,14 @@ u32 ARM_Dynarmic_32::GetSvcNumber() const { | |||
| 248 | return svc_swi; | 305 | return svc_swi; |
| 249 | } | 306 | } |
| 250 | 307 | ||
| 308 | const Kernel::DebugWatchpoint* ARM_Dynarmic_32::HaltedWatchpoint() const { | ||
| 309 | return halted_watchpoint; | ||
| 310 | } | ||
| 311 | |||
| 312 | void ARM_Dynarmic_32::RewindBreakpointInstruction() { | ||
| 313 | LoadContext(breakpoint_context); | ||
| 314 | } | ||
| 315 | |||
| 251 | ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, | 316 | ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, |
| 252 | bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, | 317 | bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, |
| 253 | std::size_t core_index_) | 318 | std::size_t core_index_) |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 5b1d60005..fcbe24f0c 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h | |||
| @@ -72,6 +72,8 @@ protected: | |||
| 72 | Dynarmic::HaltReason RunJit() override; | 72 | Dynarmic::HaltReason RunJit() override; |
| 73 | Dynarmic::HaltReason StepJit() override; | 73 | Dynarmic::HaltReason StepJit() override; |
| 74 | u32 GetSvcNumber() const override; | 74 | u32 GetSvcNumber() const override; |
| 75 | const Kernel::DebugWatchpoint* HaltedWatchpoint() const override; | ||
| 76 | void RewindBreakpointInstruction() override; | ||
| 75 | 77 | ||
| 76 | private: | 78 | private: |
| 77 | std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; | 79 | std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; |
| @@ -98,6 +100,10 @@ private: | |||
| 98 | 100 | ||
| 99 | // SVC callback | 101 | // SVC callback |
| 100 | u32 svc_swi{}; | 102 | u32 svc_swi{}; |
| 103 | |||
| 104 | // Watchpoint info | ||
| 105 | const Kernel::DebugWatchpoint* halted_watchpoint; | ||
| 106 | ThreadContext32 breakpoint_context; | ||
| 101 | }; | 107 | }; |
| 102 | 108 | ||
| 103 | } // namespace Core | 109 | } // namespace Core |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index d4c67eafd..92266aa9e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -29,62 +29,89 @@ using namespace Common::Literals; | |||
| 29 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { | 29 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { |
| 30 | public: | 30 | public: |
| 31 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) | 31 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) |
| 32 | : parent{parent_}, memory(parent.system.Memory()) {} | 32 | : parent{parent_}, |
| 33 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} | ||
| 33 | 34 | ||
| 34 | u8 MemoryRead8(u64 vaddr) override { | 35 | u8 MemoryRead8(u64 vaddr) override { |
| 36 | CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); | ||
| 35 | return memory.Read8(vaddr); | 37 | return memory.Read8(vaddr); |
| 36 | } | 38 | } |
| 37 | u16 MemoryRead16(u64 vaddr) override { | 39 | u16 MemoryRead16(u64 vaddr) override { |
| 40 | CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Read); | ||
| 38 | return memory.Read16(vaddr); | 41 | return memory.Read16(vaddr); |
| 39 | } | 42 | } |
| 40 | u32 MemoryRead32(u64 vaddr) override { | 43 | u32 MemoryRead32(u64 vaddr) override { |
| 44 | CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Read); | ||
| 41 | return memory.Read32(vaddr); | 45 | return memory.Read32(vaddr); |
| 42 | } | 46 | } |
| 43 | u64 MemoryRead64(u64 vaddr) override { | 47 | u64 MemoryRead64(u64 vaddr) override { |
| 48 | CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Read); | ||
| 44 | return memory.Read64(vaddr); | 49 | return memory.Read64(vaddr); |
| 45 | } | 50 | } |
| 46 | Vector MemoryRead128(u64 vaddr) override { | 51 | Vector MemoryRead128(u64 vaddr) override { |
| 52 | CheckMemoryAccess(vaddr, 16, Kernel::DebugWatchpointType::Read); | ||
| 47 | return {memory.Read64(vaddr), memory.Read64(vaddr + 8)}; | 53 | return {memory.Read64(vaddr), memory.Read64(vaddr + 8)}; |
| 48 | } | 54 | } |
| 55 | std::optional<u32> MemoryReadCode(u64 vaddr) override { | ||
| 56 | if (!memory.IsValidVirtualAddressRange(vaddr, sizeof(u32))) { | ||
| 57 | return std::nullopt; | ||
| 58 | } | ||
| 59 | return MemoryRead32(vaddr); | ||
| 60 | } | ||
| 49 | 61 | ||
| 50 | void MemoryWrite8(u64 vaddr, u8 value) override { | 62 | void MemoryWrite8(u64 vaddr, u8 value) override { |
| 51 | memory.Write8(vaddr, value); | 63 | if (CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write)) { |
| 64 | memory.Write8(vaddr, value); | ||
| 65 | } | ||
| 52 | } | 66 | } |
| 53 | void MemoryWrite16(u64 vaddr, u16 value) override { | 67 | void MemoryWrite16(u64 vaddr, u16 value) override { |
| 54 | memory.Write16(vaddr, value); | 68 | if (CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Write)) { |
| 69 | memory.Write16(vaddr, value); | ||
| 70 | } | ||
| 55 | } | 71 | } |
| 56 | void MemoryWrite32(u64 vaddr, u32 value) override { | 72 | void MemoryWrite32(u64 vaddr, u32 value) override { |
| 57 | memory.Write32(vaddr, value); | 73 | if (CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Write)) { |
| 74 | memory.Write32(vaddr, value); | ||
| 75 | } | ||
| 58 | } | 76 | } |
| 59 | void MemoryWrite64(u64 vaddr, u64 value) override { | 77 | void MemoryWrite64(u64 vaddr, u64 value) override { |
| 60 | memory.Write64(vaddr, value); | 78 | if (CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Write)) { |
| 79 | memory.Write64(vaddr, value); | ||
| 80 | } | ||
| 61 | } | 81 | } |
| 62 | void MemoryWrite128(u64 vaddr, Vector value) override { | 82 | void MemoryWrite128(u64 vaddr, Vector value) override { |
| 63 | memory.Write64(vaddr, value[0]); | 83 | if (CheckMemoryAccess(vaddr, 16, Kernel::DebugWatchpointType::Write)) { |
| 64 | memory.Write64(vaddr + 8, value[1]); | 84 | memory.Write64(vaddr, value[0]); |
| 85 | memory.Write64(vaddr + 8, value[1]); | ||
| 86 | } | ||
| 65 | } | 87 | } |
| 66 | 88 | ||
| 67 | bool MemoryWriteExclusive8(u64 vaddr, std::uint8_t value, std::uint8_t expected) override { | 89 | bool MemoryWriteExclusive8(u64 vaddr, std::uint8_t value, std::uint8_t expected) override { |
| 68 | return memory.WriteExclusive8(vaddr, value, expected); | 90 | return CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Write) && |
| 91 | memory.WriteExclusive8(vaddr, value, expected); | ||
| 69 | } | 92 | } |
| 70 | bool MemoryWriteExclusive16(u64 vaddr, std::uint16_t value, std::uint16_t expected) override { | 93 | bool MemoryWriteExclusive16(u64 vaddr, std::uint16_t value, std::uint16_t expected) override { |
| 71 | return memory.WriteExclusive16(vaddr, value, expected); | 94 | return CheckMemoryAccess(vaddr, 2, Kernel::DebugWatchpointType::Write) && |
| 95 | memory.WriteExclusive16(vaddr, value, expected); | ||
| 72 | } | 96 | } |
| 73 | bool MemoryWriteExclusive32(u64 vaddr, std::uint32_t value, std::uint32_t expected) override { | 97 | bool MemoryWriteExclusive32(u64 vaddr, std::uint32_t value, std::uint32_t expected) override { |
| 74 | return memory.WriteExclusive32(vaddr, value, expected); | 98 | return CheckMemoryAccess(vaddr, 4, Kernel::DebugWatchpointType::Write) && |
| 99 | memory.WriteExclusive32(vaddr, value, expected); | ||
| 75 | } | 100 | } |
| 76 | bool MemoryWriteExclusive64(u64 vaddr, std::uint64_t value, std::uint64_t expected) override { | 101 | bool MemoryWriteExclusive64(u64 vaddr, std::uint64_t value, std::uint64_t expected) override { |
| 77 | return memory.WriteExclusive64(vaddr, value, expected); | 102 | return CheckMemoryAccess(vaddr, 8, Kernel::DebugWatchpointType::Write) && |
| 103 | memory.WriteExclusive64(vaddr, value, expected); | ||
| 78 | } | 104 | } |
| 79 | bool MemoryWriteExclusive128(u64 vaddr, Vector value, Vector expected) override { | 105 | bool MemoryWriteExclusive128(u64 vaddr, Vector value, Vector expected) override { |
| 80 | return memory.WriteExclusive128(vaddr, value, expected); | 106 | return CheckMemoryAccess(vaddr, 16, Kernel::DebugWatchpointType::Write) && |
| 107 | memory.WriteExclusive128(vaddr, value, expected); | ||
| 81 | } | 108 | } |
| 82 | 109 | ||
| 83 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { | 110 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { |
| 84 | parent.LogBacktrace(); | 111 | parent.LogBacktrace(); |
| 85 | LOG_ERROR(Core_ARM, | 112 | LOG_ERROR(Core_ARM, |
| 86 | "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, | 113 | "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, |
| 87 | num_instructions, MemoryReadCode(pc)); | 114 | num_instructions, MemoryRead32(pc)); |
| 88 | } | 115 | } |
| 89 | 116 | ||
| 90 | void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, | 117 | void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, |
| @@ -117,16 +144,19 @@ public: | |||
| 117 | case Dynarmic::A64::Exception::SendEventLocal: | 144 | case Dynarmic::A64::Exception::SendEventLocal: |
| 118 | case Dynarmic::A64::Exception::Yield: | 145 | case Dynarmic::A64::Exception::Yield: |
| 119 | return; | 146 | return; |
| 147 | case Dynarmic::A64::Exception::NoExecuteFault: | ||
| 148 | LOG_CRITICAL(Core_ARM, "Cannot execute instruction at unmapped address {:#016x}", pc); | ||
| 149 | ReturnException(pc, ARM_Interface::no_execute); | ||
| 150 | return; | ||
| 120 | default: | 151 | default: |
| 121 | if (parent.system.DebuggerEnabled()) { | 152 | if (debugger_enabled) { |
| 122 | parent.jit.load()->SetPC(pc); | 153 | ReturnException(pc, ARM_Interface::breakpoint); |
| 123 | parent.jit.load()->HaltExecution(ARM_Interface::breakpoint); | ||
| 124 | return; | 154 | return; |
| 125 | } | 155 | } |
| 126 | 156 | ||
| 127 | parent.LogBacktrace(); | 157 | parent.LogBacktrace(); |
| 128 | ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", | 158 | LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", |
| 129 | static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); | 159 | static_cast<std::size_t>(exception), pc, MemoryRead32(pc)); |
| 130 | } | 160 | } |
| 131 | } | 161 | } |
| 132 | 162 | ||
| @@ -160,10 +190,32 @@ public: | |||
| 160 | return parent.system.CoreTiming().GetClockTicks(); | 190 | return parent.system.CoreTiming().GetClockTicks(); |
| 161 | } | 191 | } |
| 162 | 192 | ||
| 193 | bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { | ||
| 194 | if (!debugger_enabled) { | ||
| 195 | return true; | ||
| 196 | } | ||
| 197 | |||
| 198 | const auto match{parent.MatchingWatchpoint(addr, size, type)}; | ||
| 199 | if (match) { | ||
| 200 | parent.halted_watchpoint = match; | ||
| 201 | ReturnException(parent.jit.load()->GetPC(), ARM_Interface::watchpoint); | ||
| 202 | return false; | ||
| 203 | } | ||
| 204 | |||
| 205 | return true; | ||
| 206 | } | ||
| 207 | |||
| 208 | void ReturnException(u64 pc, Dynarmic::HaltReason hr) { | ||
| 209 | parent.SaveContext(parent.breakpoint_context); | ||
| 210 | parent.breakpoint_context.pc = pc; | ||
| 211 | parent.jit.load()->HaltExecution(hr); | ||
| 212 | } | ||
| 213 | |||
| 163 | ARM_Dynarmic_64& parent; | 214 | ARM_Dynarmic_64& parent; |
| 164 | Core::Memory::Memory& memory; | 215 | Core::Memory::Memory& memory; |
| 165 | u64 tpidrro_el0 = 0; | 216 | u64 tpidrro_el0 = 0; |
| 166 | u64 tpidr_el0 = 0; | 217 | u64 tpidr_el0 = 0; |
| 218 | bool debugger_enabled{}; | ||
| 167 | static constexpr u64 minimum_run_cycles = 1000U; | 219 | static constexpr u64 minimum_run_cycles = 1000U; |
| 168 | }; | 220 | }; |
| 169 | 221 | ||
| @@ -214,6 +266,11 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* | |||
| 214 | config.code_cache_size = 512_MiB; | 266 | config.code_cache_size = 512_MiB; |
| 215 | config.far_code_offset = 400_MiB; | 267 | config.far_code_offset = 400_MiB; |
| 216 | 268 | ||
| 269 | // Allow memory fault handling to work | ||
| 270 | if (system.DebuggerEnabled()) { | ||
| 271 | config.check_halt_on_memory_access = true; | ||
| 272 | } | ||
| 273 | |||
| 217 | // null_jit | 274 | // null_jit |
| 218 | if (!page_table) { | 275 | if (!page_table) { |
| 219 | // Don't waste too much memory on null_jit | 276 | // Don't waste too much memory on null_jit |
| @@ -308,6 +365,14 @@ u32 ARM_Dynarmic_64::GetSvcNumber() const { | |||
| 308 | return svc_swi; | 365 | return svc_swi; |
| 309 | } | 366 | } |
| 310 | 367 | ||
| 368 | const Kernel::DebugWatchpoint* ARM_Dynarmic_64::HaltedWatchpoint() const { | ||
| 369 | return halted_watchpoint; | ||
| 370 | } | ||
| 371 | |||
| 372 | void ARM_Dynarmic_64::RewindBreakpointInstruction() { | ||
| 373 | LoadContext(breakpoint_context); | ||
| 374 | } | ||
| 375 | |||
| 311 | ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, | 376 | ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, |
| 312 | bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, | 377 | bool uses_wall_clock_, ExclusiveMonitor& exclusive_monitor_, |
| 313 | std::size_t core_index_) | 378 | std::size_t core_index_) |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index abfbc3c3f..71dbaac5e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h | |||
| @@ -66,6 +66,8 @@ protected: | |||
| 66 | Dynarmic::HaltReason RunJit() override; | 66 | Dynarmic::HaltReason RunJit() override; |
| 67 | Dynarmic::HaltReason StepJit() override; | 67 | Dynarmic::HaltReason StepJit() override; |
| 68 | u32 GetSvcNumber() const override; | 68 | u32 GetSvcNumber() const override; |
| 69 | const Kernel::DebugWatchpoint* HaltedWatchpoint() const override; | ||
| 70 | void RewindBreakpointInstruction() override; | ||
| 69 | 71 | ||
| 70 | private: | 72 | private: |
| 71 | std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, | 73 | std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, |
| @@ -91,6 +93,10 @@ private: | |||
| 91 | 93 | ||
| 92 | // SVC callback | 94 | // SVC callback |
| 93 | u32 svc_swi{}; | 95 | u32 svc_swi{}; |
| 96 | |||
| 97 | // Breakpoint info | ||
| 98 | const Kernel::DebugWatchpoint* halted_watchpoint; | ||
| 99 | ThreadContext64 breakpoint_context; | ||
| 94 | }; | 100 | }; |
| 95 | 101 | ||
| 96 | } // namespace Core | 102 | } // namespace Core |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 7d974ba65..7723d9782 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -138,7 +138,6 @@ struct System::Impl { | |||
| 138 | 138 | ||
| 139 | kernel.Suspend(false); | 139 | kernel.Suspend(false); |
| 140 | core_timing.SyncPause(false); | 140 | core_timing.SyncPause(false); |
| 141 | cpu_manager.Pause(false); | ||
| 142 | is_paused = false; | 141 | is_paused = false; |
| 143 | 142 | ||
| 144 | return status; | 143 | return status; |
| @@ -150,25 +149,22 @@ struct System::Impl { | |||
| 150 | 149 | ||
| 151 | core_timing.SyncPause(true); | 150 | core_timing.SyncPause(true); |
| 152 | kernel.Suspend(true); | 151 | kernel.Suspend(true); |
| 153 | cpu_manager.Pause(true); | ||
| 154 | is_paused = true; | 152 | is_paused = true; |
| 155 | 153 | ||
| 156 | return status; | 154 | return status; |
| 157 | } | 155 | } |
| 158 | 156 | ||
| 159 | std::unique_lock<std::mutex> StallCPU() { | 157 | std::unique_lock<std::mutex> StallProcesses() { |
| 160 | std::unique_lock<std::mutex> lk(suspend_guard); | 158 | std::unique_lock<std::mutex> lk(suspend_guard); |
| 161 | kernel.Suspend(true); | 159 | kernel.Suspend(true); |
| 162 | core_timing.SyncPause(true); | 160 | core_timing.SyncPause(true); |
| 163 | cpu_manager.Pause(true); | ||
| 164 | return lk; | 161 | return lk; |
| 165 | } | 162 | } |
| 166 | 163 | ||
| 167 | void UnstallCPU() { | 164 | void UnstallProcesses() { |
| 168 | if (!is_paused) { | 165 | if (!is_paused) { |
| 169 | core_timing.SyncPause(false); | 166 | core_timing.SyncPause(false); |
| 170 | kernel.Suspend(false); | 167 | kernel.Suspend(false); |
| 171 | cpu_manager.Pause(false); | ||
| 172 | } | 168 | } |
| 173 | } | 169 | } |
| 174 | 170 | ||
| @@ -334,6 +330,8 @@ struct System::Impl { | |||
| 334 | gpu_core->NotifyShutdown(); | 330 | gpu_core->NotifyShutdown(); |
| 335 | } | 331 | } |
| 336 | 332 | ||
| 333 | kernel.ShutdownCores(); | ||
| 334 | cpu_manager.Shutdown(); | ||
| 337 | debugger.reset(); | 335 | debugger.reset(); |
| 338 | services.reset(); | 336 | services.reset(); |
| 339 | service_manager.reset(); | 337 | service_manager.reset(); |
| @@ -493,12 +491,18 @@ void System::Shutdown() { | |||
| 493 | impl->Shutdown(); | 491 | impl->Shutdown(); |
| 494 | } | 492 | } |
| 495 | 493 | ||
| 496 | std::unique_lock<std::mutex> System::StallCPU() { | 494 | void System::DetachDebugger() { |
| 497 | return impl->StallCPU(); | 495 | if (impl->debugger) { |
| 496 | impl->debugger->NotifyShutdown(); | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | std::unique_lock<std::mutex> System::StallProcesses() { | ||
| 501 | return impl->StallProcesses(); | ||
| 498 | } | 502 | } |
| 499 | 503 | ||
| 500 | void System::UnstallCPU() { | 504 | void System::UnstallProcesses() { |
| 501 | impl->UnstallCPU(); | 505 | impl->UnstallProcesses(); |
| 502 | } | 506 | } |
| 503 | 507 | ||
| 504 | void System::InitializeDebugger() { | 508 | void System::InitializeDebugger() { |
diff --git a/src/core/core.h b/src/core/core.h index 94477206e..60efe4410 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -160,8 +160,11 @@ public: | |||
| 160 | /// Shutdown the emulated system. | 160 | /// Shutdown the emulated system. |
| 161 | void Shutdown(); | 161 | void Shutdown(); |
| 162 | 162 | ||
| 163 | std::unique_lock<std::mutex> StallCPU(); | 163 | /// Forcibly detach the debugger if it is running. |
| 164 | void UnstallCPU(); | 164 | void DetachDebugger(); |
| 165 | |||
| 166 | std::unique_lock<std::mutex> StallProcesses(); | ||
| 167 | void UnstallProcesses(); | ||
| 165 | 168 | ||
| 166 | /** | 169 | /** |
| 167 | * Initialize the debugger. | 170 | * Initialize the debugger. |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 29e7dba9b..140578069 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -6,7 +6,9 @@ | |||
| 6 | #include <string> | 6 | #include <string> |
| 7 | #include <tuple> | 7 | #include <tuple> |
| 8 | 8 | ||
| 9 | #include "common/logging/log.h" | ||
| 9 | #include "common/microprofile.h" | 10 | #include "common/microprofile.h" |
| 11 | #include "common/thread.h" | ||
| 10 | #include "core/core_timing.h" | 12 | #include "core/core_timing.h" |
| 11 | #include "core/core_timing_util.h" | 13 | #include "core/core_timing_util.h" |
| 12 | #include "core/hardware_properties.h" | 14 | #include "core/hardware_properties.h" |
| @@ -41,11 +43,11 @@ CoreTiming::CoreTiming() | |||
| 41 | 43 | ||
| 42 | CoreTiming::~CoreTiming() = default; | 44 | CoreTiming::~CoreTiming() = default; |
| 43 | 45 | ||
| 44 | void CoreTiming::ThreadEntry(CoreTiming& instance) { | 46 | void CoreTiming::ThreadEntry(CoreTiming& instance, size_t id) { |
| 45 | constexpr char name[] = "yuzu:HostTiming"; | 47 | const std::string name = "yuzu:HostTiming_" + std::to_string(id); |
| 46 | MicroProfileOnThreadCreate(name); | 48 | MicroProfileOnThreadCreate(name.c_str()); |
| 47 | Common::SetCurrentThreadName(name); | 49 | Common::SetCurrentThreadName(name.c_str()); |
| 48 | Common::SetCurrentThreadPriority(Common::ThreadPriority::VeryHigh); | 50 | Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); |
| 49 | instance.on_thread_init(); | 51 | instance.on_thread_init(); |
| 50 | instance.ThreadLoop(); | 52 | instance.ThreadLoop(); |
| 51 | MicroProfileOnThreadExit(); | 53 | MicroProfileOnThreadExit(); |
| @@ -59,68 +61,97 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { | |||
| 59 | const auto empty_timed_callback = [](std::uintptr_t, std::chrono::nanoseconds) {}; | 61 | const auto empty_timed_callback = [](std::uintptr_t, std::chrono::nanoseconds) {}; |
| 60 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); | 62 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); |
| 61 | if (is_multicore) { | 63 | if (is_multicore) { |
| 62 | timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); | 64 | const auto hardware_concurrency = std::thread::hardware_concurrency(); |
| 65 | size_t id = 0; | ||
| 66 | worker_threads.emplace_back(ThreadEntry, std::ref(*this), id++); | ||
| 67 | if (hardware_concurrency > 8) { | ||
| 68 | worker_threads.emplace_back(ThreadEntry, std::ref(*this), id++); | ||
| 69 | } | ||
| 63 | } | 70 | } |
| 64 | } | 71 | } |
| 65 | 72 | ||
| 66 | void CoreTiming::Shutdown() { | 73 | void CoreTiming::Shutdown() { |
| 67 | paused = true; | 74 | is_paused = true; |
| 68 | shutting_down = true; | 75 | shutting_down = true; |
| 69 | pause_event.Set(); | 76 | std::atomic_thread_fence(std::memory_order_release); |
| 70 | event.Set(); | 77 | |
| 71 | if (timer_thread) { | 78 | event_cv.notify_all(); |
| 72 | timer_thread->join(); | 79 | wait_pause_cv.notify_all(); |
| 80 | for (auto& thread : worker_threads) { | ||
| 81 | thread.join(); | ||
| 73 | } | 82 | } |
| 83 | worker_threads.clear(); | ||
| 74 | ClearPendingEvents(); | 84 | ClearPendingEvents(); |
| 75 | timer_thread.reset(); | ||
| 76 | has_started = false; | 85 | has_started = false; |
| 77 | } | 86 | } |
| 78 | 87 | ||
| 79 | void CoreTiming::Pause(bool is_paused) { | 88 | void CoreTiming::Pause(bool is_paused_) { |
| 80 | paused = is_paused; | 89 | std::unique_lock main_lock(event_mutex); |
| 81 | pause_event.Set(); | 90 | if (is_paused_ == paused_state.load(std::memory_order_relaxed)) { |
| 91 | return; | ||
| 92 | } | ||
| 93 | if (is_multicore) { | ||
| 94 | is_paused = is_paused_; | ||
| 95 | event_cv.notify_all(); | ||
| 96 | if (!is_paused_) { | ||
| 97 | wait_pause_cv.notify_all(); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | paused_state.store(is_paused_, std::memory_order_relaxed); | ||
| 82 | } | 101 | } |
| 83 | 102 | ||
| 84 | void CoreTiming::SyncPause(bool is_paused) { | 103 | void CoreTiming::SyncPause(bool is_paused_) { |
| 85 | if (is_paused == paused && paused_set == paused) { | 104 | std::unique_lock main_lock(event_mutex); |
| 105 | if (is_paused_ == paused_state.load(std::memory_order_relaxed)) { | ||
| 86 | return; | 106 | return; |
| 87 | } | 107 | } |
| 88 | Pause(is_paused); | 108 | |
| 89 | if (timer_thread) { | 109 | if (is_multicore) { |
| 90 | if (!is_paused) { | 110 | is_paused = is_paused_; |
| 91 | pause_event.Set(); | 111 | event_cv.notify_all(); |
| 112 | if (!is_paused_) { | ||
| 113 | wait_pause_cv.notify_all(); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | paused_state.store(is_paused_, std::memory_order_relaxed); | ||
| 117 | if (is_multicore) { | ||
| 118 | if (is_paused_) { | ||
| 119 | wait_signal_cv.wait(main_lock, [this] { return pause_count == worker_threads.size(); }); | ||
| 120 | } else { | ||
| 121 | wait_signal_cv.wait(main_lock, [this] { return pause_count == 0; }); | ||
| 92 | } | 122 | } |
| 93 | event.Set(); | ||
| 94 | while (paused_set != is_paused) | ||
| 95 | ; | ||
| 96 | } | 123 | } |
| 97 | } | 124 | } |
| 98 | 125 | ||
| 99 | bool CoreTiming::IsRunning() const { | 126 | bool CoreTiming::IsRunning() const { |
| 100 | return !paused_set; | 127 | return !paused_state.load(std::memory_order_acquire); |
| 101 | } | 128 | } |
| 102 | 129 | ||
| 103 | bool CoreTiming::HasPendingEvents() const { | 130 | bool CoreTiming::HasPendingEvents() const { |
| 104 | return !(wait_set && event_queue.empty()); | 131 | std::unique_lock main_lock(event_mutex); |
| 132 | return !event_queue.empty() || pending_events.load(std::memory_order_relaxed) != 0; | ||
| 105 | } | 133 | } |
| 106 | 134 | ||
| 107 | void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, | 135 | void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, |
| 108 | const std::shared_ptr<EventType>& event_type, | 136 | const std::shared_ptr<EventType>& event_type, |
| 109 | std::uintptr_t user_data) { | 137 | std::uintptr_t user_data) { |
| 110 | { | ||
| 111 | std::scoped_lock scope{basic_lock}; | ||
| 112 | const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count()); | ||
| 113 | 138 | ||
| 114 | event_queue.emplace_back(Event{timeout, event_fifo_id++, user_data, event_type}); | 139 | std::unique_lock main_lock(event_mutex); |
| 140 | const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count()); | ||
| 141 | |||
| 142 | event_queue.emplace_back(Event{timeout, event_fifo_id++, user_data, event_type}); | ||
| 143 | pending_events.fetch_add(1, std::memory_order_relaxed); | ||
| 115 | 144 | ||
| 116 | std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); | 145 | std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 146 | |||
| 147 | if (is_multicore) { | ||
| 148 | event_cv.notify_one(); | ||
| 117 | } | 149 | } |
| 118 | event.Set(); | ||
| 119 | } | 150 | } |
| 120 | 151 | ||
| 121 | void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | 152 | void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, |
| 122 | std::uintptr_t user_data) { | 153 | std::uintptr_t user_data) { |
| 123 | std::scoped_lock scope{basic_lock}; | 154 | std::unique_lock main_lock(event_mutex); |
| 124 | const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { | 155 | const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { |
| 125 | return e.type.lock().get() == event_type.get() && e.user_data == user_data; | 156 | return e.type.lock().get() == event_type.get() && e.user_data == user_data; |
| 126 | }); | 157 | }); |
| @@ -129,6 +160,7 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | |||
| 129 | if (itr != event_queue.end()) { | 160 | if (itr != event_queue.end()) { |
| 130 | event_queue.erase(itr, event_queue.end()); | 161 | event_queue.erase(itr, event_queue.end()); |
| 131 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); | 162 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 163 | pending_events.fetch_sub(1, std::memory_order_relaxed); | ||
| 132 | } | 164 | } |
| 133 | } | 165 | } |
| 134 | 166 | ||
| @@ -168,11 +200,12 @@ u64 CoreTiming::GetClockTicks() const { | |||
| 168 | } | 200 | } |
| 169 | 201 | ||
| 170 | void CoreTiming::ClearPendingEvents() { | 202 | void CoreTiming::ClearPendingEvents() { |
| 203 | std::unique_lock main_lock(event_mutex); | ||
| 171 | event_queue.clear(); | 204 | event_queue.clear(); |
| 172 | } | 205 | } |
| 173 | 206 | ||
| 174 | void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { | 207 | void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { |
| 175 | std::scoped_lock lock{basic_lock}; | 208 | std::unique_lock main_lock(event_mutex); |
| 176 | 209 | ||
| 177 | const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { | 210 | const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { |
| 178 | return e.type.lock().get() == event_type.get(); | 211 | return e.type.lock().get() == event_type.get(); |
| @@ -186,21 +219,28 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { | |||
| 186 | } | 219 | } |
| 187 | 220 | ||
| 188 | std::optional<s64> CoreTiming::Advance() { | 221 | std::optional<s64> CoreTiming::Advance() { |
| 189 | std::scoped_lock lock{advance_lock, basic_lock}; | ||
| 190 | global_timer = GetGlobalTimeNs().count(); | 222 | global_timer = GetGlobalTimeNs().count(); |
| 191 | 223 | ||
| 224 | std::unique_lock main_lock(event_mutex); | ||
| 192 | while (!event_queue.empty() && event_queue.front().time <= global_timer) { | 225 | while (!event_queue.empty() && event_queue.front().time <= global_timer) { |
| 193 | Event evt = std::move(event_queue.front()); | 226 | Event evt = std::move(event_queue.front()); |
| 194 | std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); | 227 | std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 195 | event_queue.pop_back(); | 228 | event_queue.pop_back(); |
| 196 | basic_lock.unlock(); | ||
| 197 | 229 | ||
| 198 | if (const auto event_type{evt.type.lock()}) { | 230 | if (const auto event_type{evt.type.lock()}) { |
| 199 | event_type->callback( | 231 | sequence_mutex.lock(); |
| 200 | evt.user_data, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)}); | 232 | event_mutex.unlock(); |
| 233 | |||
| 234 | event_type->guard.lock(); | ||
| 235 | sequence_mutex.unlock(); | ||
| 236 | const s64 delay = static_cast<s64>(GetGlobalTimeNs().count() - evt.time); | ||
| 237 | event_type->callback(evt.user_data, std::chrono::nanoseconds{delay}); | ||
| 238 | event_type->guard.unlock(); | ||
| 239 | |||
| 240 | event_mutex.lock(); | ||
| 241 | pending_events.fetch_sub(1, std::memory_order_relaxed); | ||
| 201 | } | 242 | } |
| 202 | 243 | ||
| 203 | basic_lock.lock(); | ||
| 204 | global_timer = GetGlobalTimeNs().count(); | 244 | global_timer = GetGlobalTimeNs().count(); |
| 205 | } | 245 | } |
| 206 | 246 | ||
| @@ -213,26 +253,34 @@ std::optional<s64> CoreTiming::Advance() { | |||
| 213 | } | 253 | } |
| 214 | 254 | ||
| 215 | void CoreTiming::ThreadLoop() { | 255 | void CoreTiming::ThreadLoop() { |
| 256 | const auto predicate = [this] { return !event_queue.empty() || is_paused; }; | ||
| 216 | has_started = true; | 257 | has_started = true; |
| 217 | while (!shutting_down) { | 258 | while (!shutting_down) { |
| 218 | while (!paused) { | 259 | while (!is_paused && !shutting_down) { |
| 219 | paused_set = false; | ||
| 220 | const auto next_time = Advance(); | 260 | const auto next_time = Advance(); |
| 221 | if (next_time) { | 261 | if (next_time) { |
| 222 | if (*next_time > 0) { | 262 | if (*next_time > 0) { |
| 223 | std::chrono::nanoseconds next_time_ns = std::chrono::nanoseconds(*next_time); | 263 | std::chrono::nanoseconds next_time_ns = std::chrono::nanoseconds(*next_time); |
| 224 | event.WaitFor(next_time_ns); | 264 | std::unique_lock main_lock(event_mutex); |
| 265 | event_cv.wait_for(main_lock, next_time_ns, predicate); | ||
| 225 | } | 266 | } |
| 226 | } else { | 267 | } else { |
| 227 | wait_set = true; | 268 | std::unique_lock main_lock(event_mutex); |
| 228 | event.Wait(); | 269 | event_cv.wait(main_lock, predicate); |
| 229 | } | 270 | } |
| 230 | wait_set = false; | ||
| 231 | } | 271 | } |
| 232 | paused_set = true; | 272 | std::unique_lock main_lock(event_mutex); |
| 233 | clock->Pause(true); | 273 | pause_count++; |
| 234 | pause_event.Wait(); | 274 | if (pause_count == worker_threads.size()) { |
| 235 | clock->Pause(false); | 275 | clock->Pause(true); |
| 276 | wait_signal_cv.notify_all(); | ||
| 277 | } | ||
| 278 | wait_pause_cv.wait(main_lock, [this] { return !is_paused || shutting_down; }); | ||
| 279 | pause_count--; | ||
| 280 | if (pause_count == 0) { | ||
| 281 | clock->Pause(false); | ||
| 282 | wait_signal_cv.notify_all(); | ||
| 283 | } | ||
| 236 | } | 284 | } |
| 237 | } | 285 | } |
| 238 | 286 | ||
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index d27773009..a86553e08 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <atomic> | 6 | #include <atomic> |
| 7 | #include <chrono> | 7 | #include <chrono> |
| 8 | #include <condition_variable> | ||
| 8 | #include <functional> | 9 | #include <functional> |
| 9 | #include <memory> | 10 | #include <memory> |
| 10 | #include <mutex> | 11 | #include <mutex> |
| @@ -14,7 +15,6 @@ | |||
| 14 | #include <vector> | 15 | #include <vector> |
| 15 | 16 | ||
| 16 | #include "common/common_types.h" | 17 | #include "common/common_types.h" |
| 17 | #include "common/thread.h" | ||
| 18 | #include "common/wall_clock.h" | 18 | #include "common/wall_clock.h" |
| 19 | 19 | ||
| 20 | namespace Core::Timing { | 20 | namespace Core::Timing { |
| @@ -32,6 +32,7 @@ struct EventType { | |||
| 32 | TimedCallback callback; | 32 | TimedCallback callback; |
| 33 | /// A pointer to the name of the event. | 33 | /// A pointer to the name of the event. |
| 34 | const std::string name; | 34 | const std::string name; |
| 35 | mutable std::mutex guard; | ||
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | /** | 38 | /** |
| @@ -131,7 +132,7 @@ private: | |||
| 131 | /// Clear all pending events. This should ONLY be done on exit. | 132 | /// Clear all pending events. This should ONLY be done on exit. |
| 132 | void ClearPendingEvents(); | 133 | void ClearPendingEvents(); |
| 133 | 134 | ||
| 134 | static void ThreadEntry(CoreTiming& instance); | 135 | static void ThreadEntry(CoreTiming& instance, size_t id); |
| 135 | void ThreadLoop(); | 136 | void ThreadLoop(); |
| 136 | 137 | ||
| 137 | std::unique_ptr<Common::WallClock> clock; | 138 | std::unique_ptr<Common::WallClock> clock; |
| @@ -144,21 +145,25 @@ private: | |||
| 144 | // accomodated by the standard adaptor class. | 145 | // accomodated by the standard adaptor class. |
| 145 | std::vector<Event> event_queue; | 146 | std::vector<Event> event_queue; |
| 146 | u64 event_fifo_id = 0; | 147 | u64 event_fifo_id = 0; |
| 148 | std::atomic<size_t> pending_events{}; | ||
| 147 | 149 | ||
| 148 | std::shared_ptr<EventType> ev_lost; | 150 | std::shared_ptr<EventType> ev_lost; |
| 149 | Common::Event event{}; | ||
| 150 | Common::Event pause_event{}; | ||
| 151 | std::mutex basic_lock; | ||
| 152 | std::mutex advance_lock; | ||
| 153 | std::unique_ptr<std::thread> timer_thread; | ||
| 154 | std::atomic<bool> paused{}; | ||
| 155 | std::atomic<bool> paused_set{}; | ||
| 156 | std::atomic<bool> wait_set{}; | ||
| 157 | std::atomic<bool> shutting_down{}; | ||
| 158 | std::atomic<bool> has_started{}; | 151 | std::atomic<bool> has_started{}; |
| 159 | std::function<void()> on_thread_init{}; | 152 | std::function<void()> on_thread_init{}; |
| 160 | 153 | ||
| 154 | std::vector<std::thread> worker_threads; | ||
| 155 | |||
| 156 | std::condition_variable event_cv; | ||
| 157 | std::condition_variable wait_pause_cv; | ||
| 158 | std::condition_variable wait_signal_cv; | ||
| 159 | mutable std::mutex event_mutex; | ||
| 160 | mutable std::mutex sequence_mutex; | ||
| 161 | |||
| 162 | std::atomic<bool> paused_state{}; | ||
| 163 | bool is_paused{}; | ||
| 164 | bool shutting_down{}; | ||
| 161 | bool is_multicore{}; | 165 | bool is_multicore{}; |
| 166 | size_t pause_count{}; | ||
| 162 | 167 | ||
| 163 | /// Cycle timing | 168 | /// Cycle timing |
| 164 | u64 ticks{}; | 169 | u64 ticks{}; |
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 09d9c5163..9fc78f033 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -21,23 +21,24 @@ CpuManager::~CpuManager() = default; | |||
| 21 | 21 | ||
| 22 | void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, | 22 | void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, |
| 23 | std::size_t core) { | 23 | std::size_t core) { |
| 24 | cpu_manager.RunThread(stop_token, core); | 24 | cpu_manager.RunThread(core); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void CpuManager::Initialize() { | 27 | void CpuManager::Initialize() { |
| 28 | running_mode = true; | 28 | num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; |
| 29 | if (is_multicore) { | 29 | gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1); |
| 30 | for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { | 30 | |
| 31 | core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); | 31 | for (std::size_t core = 0; core < num_cores; core++) { |
| 32 | } | 32 | core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); |
| 33 | } else { | ||
| 34 | core_data[0].host_thread = std::jthread(ThreadStart, std::ref(*this), 0); | ||
| 35 | } | 33 | } |
| 36 | } | 34 | } |
| 37 | 35 | ||
| 38 | void CpuManager::Shutdown() { | 36 | void CpuManager::Shutdown() { |
| 39 | running_mode = false; | 37 | for (std::size_t core = 0; core < num_cores; core++) { |
| 40 | Pause(false); | 38 | if (core_data[core].host_thread.joinable()) { |
| 39 | core_data[core].host_thread.join(); | ||
| 40 | } | ||
| 41 | } | ||
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() { | 44 | std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() { |
| @@ -48,8 +49,8 @@ std::function<void(void*)> CpuManager::GetIdleThreadStartFunc() { | |||
| 48 | return IdleThreadFunction; | 49 | return IdleThreadFunction; |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | std::function<void(void*)> CpuManager::GetSuspendThreadStartFunc() { | 52 | std::function<void(void*)> CpuManager::GetShutdownThreadStartFunc() { |
| 52 | return SuspendThreadFunction; | 53 | return ShutdownThreadFunction; |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | void CpuManager::GuestThreadFunction(void* cpu_manager_) { | 56 | void CpuManager::GuestThreadFunction(void* cpu_manager_) { |
| @@ -79,17 +80,12 @@ void CpuManager::IdleThreadFunction(void* cpu_manager_) { | |||
| 79 | } | 80 | } |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | void CpuManager::SuspendThreadFunction(void* cpu_manager_) { | 83 | void CpuManager::ShutdownThreadFunction(void* cpu_manager) { |
| 83 | CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_); | 84 | static_cast<CpuManager*>(cpu_manager)->ShutdownThread(); |
| 84 | if (cpu_manager->is_multicore) { | ||
| 85 | cpu_manager->MultiCoreRunSuspendThread(); | ||
| 86 | } else { | ||
| 87 | cpu_manager->SingleCoreRunSuspendThread(); | ||
| 88 | } | ||
| 89 | } | 85 | } |
| 90 | 86 | ||
| 91 | void* CpuManager::GetStartFuncParamater() { | 87 | void* CpuManager::GetStartFuncParameter() { |
| 92 | return static_cast<void*>(this); | 88 | return this; |
| 93 | } | 89 | } |
| 94 | 90 | ||
| 95 | /////////////////////////////////////////////////////////////////////////////// | 91 | /////////////////////////////////////////////////////////////////////////////// |
| @@ -99,7 +95,7 @@ void* CpuManager::GetStartFuncParamater() { | |||
| 99 | void CpuManager::MultiCoreRunGuestThread() { | 95 | void CpuManager::MultiCoreRunGuestThread() { |
| 100 | auto& kernel = system.Kernel(); | 96 | auto& kernel = system.Kernel(); |
| 101 | kernel.CurrentScheduler()->OnThreadStart(); | 97 | kernel.CurrentScheduler()->OnThreadStart(); |
| 102 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | 98 | auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread(); |
| 103 | auto& host_context = thread->GetHostContext(); | 99 | auto& host_context = thread->GetHostContext(); |
| 104 | host_context->SetRewindPoint(GuestRewindFunction, this); | 100 | host_context->SetRewindPoint(GuestRewindFunction, this); |
| 105 | MultiCoreRunGuestLoop(); | 101 | MultiCoreRunGuestLoop(); |
| @@ -110,12 +106,10 @@ void CpuManager::MultiCoreRunGuestLoop() { | |||
| 110 | 106 | ||
| 111 | while (true) { | 107 | while (true) { |
| 112 | auto* physical_core = &kernel.CurrentPhysicalCore(); | 108 | auto* physical_core = &kernel.CurrentPhysicalCore(); |
| 113 | system.EnterDynarmicProfile(); | ||
| 114 | while (!physical_core->IsInterrupted()) { | 109 | while (!physical_core->IsInterrupted()) { |
| 115 | physical_core->Run(); | 110 | physical_core->Run(); |
| 116 | physical_core = &kernel.CurrentPhysicalCore(); | 111 | physical_core = &kernel.CurrentPhysicalCore(); |
| 117 | } | 112 | } |
| 118 | system.ExitDynarmicProfile(); | ||
| 119 | { | 113 | { |
| 120 | Kernel::KScopedDisableDispatch dd(kernel); | 114 | Kernel::KScopedDisableDispatch dd(kernel); |
| 121 | physical_core->ArmInterface().ClearExclusiveState(); | 115 | physical_core->ArmInterface().ClearExclusiveState(); |
| @@ -131,58 +125,6 @@ void CpuManager::MultiCoreRunIdleThread() { | |||
| 131 | } | 125 | } |
| 132 | } | 126 | } |
| 133 | 127 | ||
| 134 | void CpuManager::MultiCoreRunSuspendThread() { | ||
| 135 | auto& kernel = system.Kernel(); | ||
| 136 | kernel.CurrentScheduler()->OnThreadStart(); | ||
| 137 | while (true) { | ||
| 138 | auto core = kernel.CurrentPhysicalCoreIndex(); | ||
| 139 | auto& scheduler = *kernel.CurrentScheduler(); | ||
| 140 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | ||
| 141 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); | ||
| 142 | ASSERT(scheduler.ContextSwitchPending()); | ||
| 143 | ASSERT(core == kernel.CurrentPhysicalCoreIndex()); | ||
| 144 | scheduler.RescheduleCurrentCore(); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | void CpuManager::MultiCorePause(bool paused) { | ||
| 149 | if (!paused) { | ||
| 150 | bool all_not_barrier = false; | ||
| 151 | while (!all_not_barrier) { | ||
| 152 | all_not_barrier = true; | ||
| 153 | for (const auto& data : core_data) { | ||
| 154 | all_not_barrier &= !data.is_running.load() && data.initialized.load(); | ||
| 155 | } | ||
| 156 | } | ||
| 157 | for (auto& data : core_data) { | ||
| 158 | data.enter_barrier->Set(); | ||
| 159 | } | ||
| 160 | if (paused_state.load()) { | ||
| 161 | bool all_barrier = false; | ||
| 162 | while (!all_barrier) { | ||
| 163 | all_barrier = true; | ||
| 164 | for (const auto& data : core_data) { | ||
| 165 | all_barrier &= data.is_paused.load() && data.initialized.load(); | ||
| 166 | } | ||
| 167 | } | ||
| 168 | for (auto& data : core_data) { | ||
| 169 | data.exit_barrier->Set(); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | } else { | ||
| 173 | /// Wait until all cores are paused. | ||
| 174 | bool all_barrier = false; | ||
| 175 | while (!all_barrier) { | ||
| 176 | all_barrier = true; | ||
| 177 | for (const auto& data : core_data) { | ||
| 178 | all_barrier &= data.is_paused.load() && data.initialized.load(); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | /// Don't release the barrier | ||
| 182 | } | ||
| 183 | paused_state = paused; | ||
| 184 | } | ||
| 185 | |||
| 186 | /////////////////////////////////////////////////////////////////////////////// | 128 | /////////////////////////////////////////////////////////////////////////////// |
| 187 | /// SingleCore /// | 129 | /// SingleCore /// |
| 188 | /////////////////////////////////////////////////////////////////////////////// | 130 | /////////////////////////////////////////////////////////////////////////////// |
| @@ -190,7 +132,7 @@ void CpuManager::MultiCorePause(bool paused) { | |||
| 190 | void CpuManager::SingleCoreRunGuestThread() { | 132 | void CpuManager::SingleCoreRunGuestThread() { |
| 191 | auto& kernel = system.Kernel(); | 133 | auto& kernel = system.Kernel(); |
| 192 | kernel.CurrentScheduler()->OnThreadStart(); | 134 | kernel.CurrentScheduler()->OnThreadStart(); |
| 193 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | 135 | auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread(); |
| 194 | auto& host_context = thread->GetHostContext(); | 136 | auto& host_context = thread->GetHostContext(); |
| 195 | host_context->SetRewindPoint(GuestRewindFunction, this); | 137 | host_context->SetRewindPoint(GuestRewindFunction, this); |
| 196 | SingleCoreRunGuestLoop(); | 138 | SingleCoreRunGuestLoop(); |
| @@ -200,12 +142,10 @@ void CpuManager::SingleCoreRunGuestLoop() { | |||
| 200 | auto& kernel = system.Kernel(); | 142 | auto& kernel = system.Kernel(); |
| 201 | while (true) { | 143 | while (true) { |
| 202 | auto* physical_core = &kernel.CurrentPhysicalCore(); | 144 | auto* physical_core = &kernel.CurrentPhysicalCore(); |
| 203 | system.EnterDynarmicProfile(); | ||
| 204 | if (!physical_core->IsInterrupted()) { | 145 | if (!physical_core->IsInterrupted()) { |
| 205 | physical_core->Run(); | 146 | physical_core->Run(); |
| 206 | physical_core = &kernel.CurrentPhysicalCore(); | 147 | physical_core = &kernel.CurrentPhysicalCore(); |
| 207 | } | 148 | } |
| 208 | system.ExitDynarmicProfile(); | ||
| 209 | kernel.SetIsPhantomModeForSingleCore(true); | 149 | kernel.SetIsPhantomModeForSingleCore(true); |
| 210 | system.CoreTiming().Advance(); | 150 | system.CoreTiming().Advance(); |
| 211 | kernel.SetIsPhantomModeForSingleCore(false); | 151 | kernel.SetIsPhantomModeForSingleCore(false); |
| @@ -228,25 +168,11 @@ void CpuManager::SingleCoreRunIdleThread() { | |||
| 228 | } | 168 | } |
| 229 | } | 169 | } |
| 230 | 170 | ||
| 231 | void CpuManager::SingleCoreRunSuspendThread() { | ||
| 232 | auto& kernel = system.Kernel(); | ||
| 233 | kernel.CurrentScheduler()->OnThreadStart(); | ||
| 234 | while (true) { | ||
| 235 | auto core = kernel.GetCurrentHostThreadID(); | ||
| 236 | auto& scheduler = *kernel.CurrentScheduler(); | ||
| 237 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | ||
| 238 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[0].host_context); | ||
| 239 | ASSERT(scheduler.ContextSwitchPending()); | ||
| 240 | ASSERT(core == kernel.GetCurrentHostThreadID()); | ||
| 241 | scheduler.RescheduleCurrentCore(); | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 245 | void CpuManager::PreemptSingleCore(bool from_running_enviroment) { | 171 | void CpuManager::PreemptSingleCore(bool from_running_enviroment) { |
| 246 | { | 172 | { |
| 247 | auto& kernel = system.Kernel(); | 173 | auto& kernel = system.Kernel(); |
| 248 | auto& scheduler = kernel.Scheduler(current_core); | 174 | auto& scheduler = kernel.Scheduler(current_core); |
| 249 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | 175 | Kernel::KThread* current_thread = scheduler.GetSchedulerCurrentThread(); |
| 250 | if (idle_count >= 4 || from_running_enviroment) { | 176 | if (idle_count >= 4 || from_running_enviroment) { |
| 251 | if (!from_running_enviroment) { | 177 | if (!from_running_enviroment) { |
| 252 | system.CoreTiming().Idle(); | 178 | system.CoreTiming().Idle(); |
| @@ -258,7 +184,7 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) { | |||
| 258 | } | 184 | } |
| 259 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | 185 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); |
| 260 | system.CoreTiming().ResetTicks(); | 186 | system.CoreTiming().ResetTicks(); |
| 261 | scheduler.Unload(scheduler.GetCurrentThread()); | 187 | scheduler.Unload(scheduler.GetSchedulerCurrentThread()); |
| 262 | 188 | ||
| 263 | auto& next_scheduler = kernel.Scheduler(current_core); | 189 | auto& next_scheduler = kernel.Scheduler(current_core); |
| 264 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.ControlContext()); | 190 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.ControlContext()); |
| @@ -267,47 +193,23 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) { | |||
| 267 | // May have changed scheduler | 193 | // May have changed scheduler |
| 268 | { | 194 | { |
| 269 | auto& scheduler = system.Kernel().Scheduler(current_core); | 195 | auto& scheduler = system.Kernel().Scheduler(current_core); |
| 270 | scheduler.Reload(scheduler.GetCurrentThread()); | 196 | scheduler.Reload(scheduler.GetSchedulerCurrentThread()); |
| 271 | if (!scheduler.IsIdle()) { | 197 | if (!scheduler.IsIdle()) { |
| 272 | idle_count = 0; | 198 | idle_count = 0; |
| 273 | } | 199 | } |
| 274 | } | 200 | } |
| 275 | } | 201 | } |
| 276 | 202 | ||
| 277 | void CpuManager::SingleCorePause(bool paused) { | 203 | void CpuManager::ShutdownThread() { |
| 278 | if (!paused) { | 204 | auto& kernel = system.Kernel(); |
| 279 | bool all_not_barrier = false; | 205 | auto core = is_multicore ? kernel.CurrentPhysicalCoreIndex() : 0; |
| 280 | while (!all_not_barrier) { | 206 | auto* current_thread = kernel.GetCurrentEmuThread(); |
| 281 | all_not_barrier = !core_data[0].is_running.load() && core_data[0].initialized.load(); | ||
| 282 | } | ||
| 283 | core_data[0].enter_barrier->Set(); | ||
| 284 | if (paused_state.load()) { | ||
| 285 | bool all_barrier = false; | ||
| 286 | while (!all_barrier) { | ||
| 287 | all_barrier = core_data[0].is_paused.load() && core_data[0].initialized.load(); | ||
| 288 | } | ||
| 289 | core_data[0].exit_barrier->Set(); | ||
| 290 | } | ||
| 291 | } else { | ||
| 292 | /// Wait until all cores are paused. | ||
| 293 | bool all_barrier = false; | ||
| 294 | while (!all_barrier) { | ||
| 295 | all_barrier = core_data[0].is_paused.load() && core_data[0].initialized.load(); | ||
| 296 | } | ||
| 297 | /// Don't release the barrier | ||
| 298 | } | ||
| 299 | paused_state = paused; | ||
| 300 | } | ||
| 301 | 207 | ||
| 302 | void CpuManager::Pause(bool paused) { | 208 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); |
| 303 | if (is_multicore) { | 209 | UNREACHABLE(); |
| 304 | MultiCorePause(paused); | ||
| 305 | } else { | ||
| 306 | SingleCorePause(paused); | ||
| 307 | } | ||
| 308 | } | 210 | } |
| 309 | 211 | ||
| 310 | void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { | 212 | void CpuManager::RunThread(std::size_t core) { |
| 311 | /// Initialization | 213 | /// Initialization |
| 312 | system.RegisterCoreThread(core); | 214 | system.RegisterCoreThread(core); |
| 313 | std::string name; | 215 | std::string name; |
| @@ -320,45 +222,24 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { | |||
| 320 | Common::SetCurrentThreadName(name.c_str()); | 222 | Common::SetCurrentThreadName(name.c_str()); |
| 321 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | 223 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); |
| 322 | auto& data = core_data[core]; | 224 | auto& data = core_data[core]; |
| 323 | data.enter_barrier = std::make_unique<Common::Event>(); | ||
| 324 | data.exit_barrier = std::make_unique<Common::Event>(); | ||
| 325 | data.host_context = Common::Fiber::ThreadToFiber(); | 225 | data.host_context = Common::Fiber::ThreadToFiber(); |
| 326 | data.is_running = false; | ||
| 327 | data.initialized = true; | ||
| 328 | const bool sc_sync = !is_async_gpu && !is_multicore; | ||
| 329 | bool sc_sync_first_use = sc_sync; | ||
| 330 | 226 | ||
| 331 | // Cleanup | 227 | // Cleanup |
| 332 | SCOPE_EXIT({ | 228 | SCOPE_EXIT({ |
| 333 | data.host_context->Exit(); | 229 | data.host_context->Exit(); |
| 334 | data.enter_barrier.reset(); | ||
| 335 | data.exit_barrier.reset(); | ||
| 336 | data.initialized = false; | ||
| 337 | MicroProfileOnThreadExit(); | 230 | MicroProfileOnThreadExit(); |
| 338 | }); | 231 | }); |
| 339 | 232 | ||
| 340 | /// Running | 233 | // Running |
| 341 | while (running_mode) { | 234 | gpu_barrier->Sync(); |
| 342 | data.is_running = false; | ||
| 343 | data.enter_barrier->Wait(); | ||
| 344 | if (sc_sync_first_use) { | ||
| 345 | system.GPU().ObtainContext(); | ||
| 346 | sc_sync_first_use = false; | ||
| 347 | } | ||
| 348 | |||
| 349 | // Emulation was stopped | ||
| 350 | if (stop_token.stop_requested()) { | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | 235 | ||
| 354 | auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | 236 | if (!is_async_gpu && !is_multicore) { |
| 355 | data.is_running = true; | 237 | system.GPU().ObtainContext(); |
| 356 | Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); | ||
| 357 | data.is_running = false; | ||
| 358 | data.is_paused = true; | ||
| 359 | data.exit_barrier->Wait(); | ||
| 360 | data.is_paused = false; | ||
| 361 | } | 238 | } |
| 239 | |||
| 240 | auto* current_thread = system.Kernel().CurrentScheduler()->GetIdleThread(); | ||
| 241 | Kernel::SetCurrentThread(system.Kernel(), current_thread); | ||
| 242 | Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); | ||
| 362 | } | 243 | } |
| 363 | 244 | ||
| 364 | } // namespace Core | 245 | } // namespace Core |
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index aee352245..f0751fc58 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h | |||
| @@ -43,15 +43,17 @@ public: | |||
| 43 | is_async_gpu = is_async; | 43 | is_async_gpu = is_async; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void OnGpuReady() { | ||
| 47 | gpu_barrier->Sync(); | ||
| 48 | } | ||
| 49 | |||
| 46 | void Initialize(); | 50 | void Initialize(); |
| 47 | void Shutdown(); | 51 | void Shutdown(); |
| 48 | 52 | ||
| 49 | void Pause(bool paused); | ||
| 50 | |||
| 51 | static std::function<void(void*)> GetGuestThreadStartFunc(); | 53 | static std::function<void(void*)> GetGuestThreadStartFunc(); |
| 52 | static std::function<void(void*)> GetIdleThreadStartFunc(); | 54 | static std::function<void(void*)> GetIdleThreadStartFunc(); |
| 53 | static std::function<void(void*)> GetSuspendThreadStartFunc(); | 55 | static std::function<void(void*)> GetShutdownThreadStartFunc(); |
| 54 | void* GetStartFuncParamater(); | 56 | void* GetStartFuncParameter(); |
| 55 | 57 | ||
| 56 | void PreemptSingleCore(bool from_running_enviroment = true); | 58 | void PreemptSingleCore(bool from_running_enviroment = true); |
| 57 | 59 | ||
| @@ -63,43 +65,34 @@ private: | |||
| 63 | static void GuestThreadFunction(void* cpu_manager); | 65 | static void GuestThreadFunction(void* cpu_manager); |
| 64 | static void GuestRewindFunction(void* cpu_manager); | 66 | static void GuestRewindFunction(void* cpu_manager); |
| 65 | static void IdleThreadFunction(void* cpu_manager); | 67 | static void IdleThreadFunction(void* cpu_manager); |
| 66 | static void SuspendThreadFunction(void* cpu_manager); | 68 | static void ShutdownThreadFunction(void* cpu_manager); |
| 67 | 69 | ||
| 68 | void MultiCoreRunGuestThread(); | 70 | void MultiCoreRunGuestThread(); |
| 69 | void MultiCoreRunGuestLoop(); | 71 | void MultiCoreRunGuestLoop(); |
| 70 | void MultiCoreRunIdleThread(); | 72 | void MultiCoreRunIdleThread(); |
| 71 | void MultiCoreRunSuspendThread(); | ||
| 72 | void MultiCorePause(bool paused); | ||
| 73 | 73 | ||
| 74 | void SingleCoreRunGuestThread(); | 74 | void SingleCoreRunGuestThread(); |
| 75 | void SingleCoreRunGuestLoop(); | 75 | void SingleCoreRunGuestLoop(); |
| 76 | void SingleCoreRunIdleThread(); | 76 | void SingleCoreRunIdleThread(); |
| 77 | void SingleCoreRunSuspendThread(); | ||
| 78 | void SingleCorePause(bool paused); | ||
| 79 | 77 | ||
| 80 | static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); | 78 | static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); |
| 81 | 79 | ||
| 82 | void RunThread(std::stop_token stop_token, std::size_t core); | 80 | void ShutdownThread(); |
| 81 | void RunThread(std::size_t core); | ||
| 83 | 82 | ||
| 84 | struct CoreData { | 83 | struct CoreData { |
| 85 | std::shared_ptr<Common::Fiber> host_context; | 84 | std::shared_ptr<Common::Fiber> host_context; |
| 86 | std::unique_ptr<Common::Event> enter_barrier; | ||
| 87 | std::unique_ptr<Common::Event> exit_barrier; | ||
| 88 | std::atomic<bool> is_running; | ||
| 89 | std::atomic<bool> is_paused; | ||
| 90 | std::atomic<bool> initialized; | ||
| 91 | std::jthread host_thread; | 85 | std::jthread host_thread; |
| 92 | }; | 86 | }; |
| 93 | 87 | ||
| 94 | std::atomic<bool> running_mode{}; | 88 | std::unique_ptr<Common::Barrier> gpu_barrier{}; |
| 95 | std::atomic<bool> paused_state{}; | ||
| 96 | |||
| 97 | std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; | 89 | std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; |
| 98 | 90 | ||
| 99 | bool is_async_gpu{}; | 91 | bool is_async_gpu{}; |
| 100 | bool is_multicore{}; | 92 | bool is_multicore{}; |
| 101 | std::atomic<std::size_t> current_core{}; | 93 | std::atomic<std::size_t> current_core{}; |
| 102 | std::size_t idle_count{}; | 94 | std::size_t idle_count{}; |
| 95 | std::size_t num_cores{}; | ||
| 103 | static constexpr std::size_t max_cycle_runs = 5; | 96 | static constexpr std::size_t max_cycle_runs = 5; |
| 104 | 97 | ||
| 105 | System& system; | 98 | System& system; |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index e3c4f80eb..443323390 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -140,7 +140,6 @@ u64 GetSignatureTypeDataSize(SignatureType type) { | |||
| 140 | return 0x3C; | 140 | return 0x3C; |
| 141 | } | 141 | } |
| 142 | UNREACHABLE(); | 142 | UNREACHABLE(); |
| 143 | return 0; | ||
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | u64 GetSignatureTypePaddingSize(SignatureType type) { | 145 | u64 GetSignatureTypePaddingSize(SignatureType type) { |
| @@ -155,7 +154,6 @@ u64 GetSignatureTypePaddingSize(SignatureType type) { | |||
| 155 | return 0x40; | 154 | return 0x40; |
| 156 | } | 155 | } |
| 157 | UNREACHABLE(); | 156 | UNREACHABLE(); |
| 158 | return 0; | ||
| 159 | } | 157 | } |
| 160 | 158 | ||
| 161 | SignatureType Ticket::GetSignatureType() const { | 159 | SignatureType Ticket::GetSignatureType() const { |
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index 8d64990ed..ac64d2f9d 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp | |||
| @@ -42,6 +42,18 @@ static std::span<const u8> ReceiveInto(Readable& r, Buffer& buffer) { | |||
| 42 | return received_data; | 42 | return received_data; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | enum class SignalType { | ||
| 46 | Stopped, | ||
| 47 | Watchpoint, | ||
| 48 | ShuttingDown, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct SignalInfo { | ||
| 52 | SignalType type; | ||
| 53 | Kernel::KThread* thread; | ||
| 54 | const Kernel::DebugWatchpoint* watchpoint; | ||
| 55 | }; | ||
| 56 | |||
| 45 | namespace Core { | 57 | namespace Core { |
| 46 | 58 | ||
| 47 | class DebuggerImpl : public DebuggerBackend { | 59 | class DebuggerImpl : public DebuggerBackend { |
| @@ -56,17 +68,23 @@ public: | |||
| 56 | ShutdownServer(); | 68 | ShutdownServer(); |
| 57 | } | 69 | } |
| 58 | 70 | ||
| 59 | bool NotifyThreadStopped(Kernel::KThread* thread) { | 71 | bool SignalDebugger(SignalInfo signal_info) { |
| 60 | std::scoped_lock lk{connection_lock}; | 72 | { |
| 73 | std::scoped_lock lk{connection_lock}; | ||
| 74 | |||
| 75 | if (stopped) { | ||
| 76 | // Do not notify the debugger about another event. | ||
| 77 | // It should be ignored. | ||
| 78 | return false; | ||
| 79 | } | ||
| 61 | 80 | ||
| 62 | if (stopped) { | 81 | // Set up the state. |
| 63 | // Do not notify the debugger about another event. | 82 | stopped = true; |
| 64 | // It should be ignored. | 83 | info = signal_info; |
| 65 | return false; | ||
| 66 | } | 84 | } |
| 67 | stopped = true; | ||
| 68 | 85 | ||
| 69 | boost::asio::write(signal_pipe, boost::asio::buffer(&thread, sizeof(thread))); | 86 | // Write a single byte into the pipe to wake up the debug interface. |
| 87 | boost::asio::write(signal_pipe, boost::asio::buffer(&stopped, sizeof(stopped))); | ||
| 70 | return true; | 88 | return true; |
| 71 | } | 89 | } |
| 72 | 90 | ||
| @@ -96,7 +114,7 @@ private: | |||
| 96 | connection_thread = std::jthread([&, port](std::stop_token stop_token) { | 114 | connection_thread = std::jthread([&, port](std::stop_token stop_token) { |
| 97 | try { | 115 | try { |
| 98 | // Initialize the listening socket and accept a new client. | 116 | // Initialize the listening socket and accept a new client. |
| 99 | tcp::endpoint endpoint{boost::asio::ip::address_v4::loopback(), port}; | 117 | tcp::endpoint endpoint{boost::asio::ip::address_v4::any(), port}; |
| 100 | tcp::acceptor acceptor{io_context, endpoint}; | 118 | tcp::acceptor acceptor{io_context, endpoint}; |
| 101 | 119 | ||
| 102 | acceptor.async_accept(client_socket, [](const auto&) {}); | 120 | acceptor.async_accept(client_socket, [](const auto&) {}); |
| @@ -124,12 +142,9 @@ private: | |||
| 124 | Common::SetCurrentThreadName("yuzu:Debugger"); | 142 | Common::SetCurrentThreadName("yuzu:Debugger"); |
| 125 | 143 | ||
| 126 | // Set up the client signals for new data. | 144 | // Set up the client signals for new data. |
| 127 | AsyncReceiveInto(signal_pipe, active_thread, [&](auto d) { PipeData(d); }); | 145 | AsyncReceiveInto(signal_pipe, pipe_data, [&](auto d) { PipeData(d); }); |
| 128 | AsyncReceiveInto(client_socket, client_data, [&](auto d) { ClientData(d); }); | 146 | AsyncReceiveInto(client_socket, client_data, [&](auto d) { ClientData(d); }); |
| 129 | 147 | ||
| 130 | // Stop the emulated CPU. | ||
| 131 | AllCoreStop(); | ||
| 132 | |||
| 133 | // Set the active thread. | 148 | // Set the active thread. |
| 134 | UpdateActiveThread(); | 149 | UpdateActiveThread(); |
| 135 | 150 | ||
| @@ -142,9 +157,33 @@ private: | |||
| 142 | } | 157 | } |
| 143 | 158 | ||
| 144 | void PipeData(std::span<const u8> data) { | 159 | void PipeData(std::span<const u8> data) { |
| 145 | AllCoreStop(); | 160 | switch (info.type) { |
| 146 | UpdateActiveThread(); | 161 | case SignalType::Stopped: |
| 147 | frontend->Stopped(active_thread); | 162 | case SignalType::Watchpoint: |
| 163 | // Stop emulation. | ||
| 164 | PauseEmulation(); | ||
| 165 | |||
| 166 | // Notify the client. | ||
| 167 | active_thread = info.thread; | ||
| 168 | UpdateActiveThread(); | ||
| 169 | |||
| 170 | if (info.type == SignalType::Watchpoint) { | ||
| 171 | frontend->Watchpoint(active_thread, *info.watchpoint); | ||
| 172 | } else { | ||
| 173 | frontend->Stopped(active_thread); | ||
| 174 | } | ||
| 175 | |||
| 176 | break; | ||
| 177 | case SignalType::ShuttingDown: | ||
| 178 | frontend->ShuttingDown(); | ||
| 179 | |||
| 180 | // Wait for emulation to shut down gracefully now. | ||
| 181 | signal_pipe.close(); | ||
| 182 | client_socket.shutdown(boost::asio::socket_base::shutdown_both); | ||
| 183 | LOG_INFO(Debug_GDBStub, "Shut down server"); | ||
| 184 | |||
| 185 | break; | ||
| 186 | } | ||
| 148 | } | 187 | } |
| 149 | 188 | ||
| 150 | void ClientData(std::span<const u8> data) { | 189 | void ClientData(std::span<const u8> data) { |
| @@ -156,32 +195,29 @@ private: | |||
| 156 | std::scoped_lock lk{connection_lock}; | 195 | std::scoped_lock lk{connection_lock}; |
| 157 | stopped = true; | 196 | stopped = true; |
| 158 | } | 197 | } |
| 159 | AllCoreStop(); | 198 | PauseEmulation(); |
| 160 | UpdateActiveThread(); | 199 | UpdateActiveThread(); |
| 161 | frontend->Stopped(active_thread); | 200 | frontend->Stopped(active_thread); |
| 162 | break; | 201 | break; |
| 163 | } | 202 | } |
| 164 | case DebuggerAction::Continue: | 203 | case DebuggerAction::Continue: |
| 165 | active_thread->SetStepState(Kernel::StepState::NotStepping); | 204 | MarkResumed([&] { ResumeEmulation(); }); |
| 166 | ResumeInactiveThreads(); | ||
| 167 | AllCoreResume(); | ||
| 168 | break; | 205 | break; |
| 169 | case DebuggerAction::StepThreadUnlocked: | 206 | case DebuggerAction::StepThreadUnlocked: |
| 170 | active_thread->SetStepState(Kernel::StepState::StepPending); | 207 | MarkResumed([&] { |
| 171 | ResumeInactiveThreads(); | 208 | active_thread->SetStepState(Kernel::StepState::StepPending); |
| 172 | AllCoreResume(); | 209 | active_thread->Resume(Kernel::SuspendType::Debug); |
| 210 | ResumeEmulation(active_thread); | ||
| 211 | }); | ||
| 173 | break; | 212 | break; |
| 174 | case DebuggerAction::StepThreadLocked: | 213 | case DebuggerAction::StepThreadLocked: { |
| 175 | active_thread->SetStepState(Kernel::StepState::StepPending); | 214 | MarkResumed([&] { |
| 176 | SuspendInactiveThreads(); | 215 | active_thread->SetStepState(Kernel::StepState::StepPending); |
| 177 | AllCoreResume(); | 216 | active_thread->Resume(Kernel::SuspendType::Debug); |
| 217 | }); | ||
| 178 | break; | 218 | break; |
| 219 | } | ||
| 179 | case DebuggerAction::ShutdownEmulation: { | 220 | case DebuggerAction::ShutdownEmulation: { |
| 180 | // Suspend all threads and release any locks held | ||
| 181 | active_thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 182 | SuspendInactiveThreads(); | ||
| 183 | AllCoreResume(); | ||
| 184 | |||
| 185 | // Spawn another thread that will exit after shutdown, | 221 | // Spawn another thread that will exit after shutdown, |
| 186 | // to avoid a deadlock | 222 | // to avoid a deadlock |
| 187 | Core::System* system_ref{&system}; | 223 | Core::System* system_ref{&system}; |
| @@ -193,33 +229,33 @@ private: | |||
| 193 | } | 229 | } |
| 194 | } | 230 | } |
| 195 | 231 | ||
| 196 | void AllCoreStop() { | 232 | void PauseEmulation() { |
| 197 | if (!suspend) { | 233 | // Put all threads to sleep on next scheduler round. |
| 198 | suspend = system.StallCPU(); | 234 | for (auto* thread : ThreadList()) { |
| 235 | thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 199 | } | 236 | } |
| 200 | } | ||
| 201 | 237 | ||
| 202 | void AllCoreResume() { | 238 | // Signal an interrupt so that scheduler will fire. |
| 203 | stopped = false; | 239 | system.Kernel().InterruptAllPhysicalCores(); |
| 204 | system.UnstallCPU(); | ||
| 205 | suspend.reset(); | ||
| 206 | } | 240 | } |
| 207 | 241 | ||
| 208 | void SuspendInactiveThreads() { | 242 | void ResumeEmulation(Kernel::KThread* except = nullptr) { |
| 243 | // Wake up all threads. | ||
| 209 | for (auto* thread : ThreadList()) { | 244 | for (auto* thread : ThreadList()) { |
| 210 | if (thread != active_thread) { | 245 | if (thread == except) { |
| 211 | thread->RequestSuspend(Kernel::SuspendType::Debug); | 246 | continue; |
| 212 | } | 247 | } |
| 248 | |||
| 249 | thread->SetStepState(Kernel::StepState::NotStepping); | ||
| 250 | thread->Resume(Kernel::SuspendType::Debug); | ||
| 213 | } | 251 | } |
| 214 | } | 252 | } |
| 215 | 253 | ||
| 216 | void ResumeInactiveThreads() { | 254 | template <typename Callback> |
| 217 | for (auto* thread : ThreadList()) { | 255 | void MarkResumed(Callback&& cb) { |
| 218 | if (thread != active_thread) { | 256 | std::scoped_lock lk{connection_lock}; |
| 219 | thread->Resume(Kernel::SuspendType::Debug); | 257 | stopped = false; |
| 220 | thread->SetStepState(Kernel::StepState::NotStepping); | 258 | cb(); |
| 221 | } | ||
| 222 | } | ||
| 223 | } | 259 | } |
| 224 | 260 | ||
| 225 | void UpdateActiveThread() { | 261 | void UpdateActiveThread() { |
| @@ -227,8 +263,6 @@ private: | |||
| 227 | if (std::find(threads.begin(), threads.end(), active_thread) == threads.end()) { | 263 | if (std::find(threads.begin(), threads.end(), active_thread) == threads.end()) { |
| 228 | active_thread = threads[0]; | 264 | active_thread = threads[0]; |
| 229 | } | 265 | } |
| 230 | active_thread->Resume(Kernel::SuspendType::Debug); | ||
| 231 | active_thread->SetStepState(Kernel::StepState::NotStepping); | ||
| 232 | } | 266 | } |
| 233 | 267 | ||
| 234 | const std::vector<Kernel::KThread*>& ThreadList() { | 268 | const std::vector<Kernel::KThread*>& ThreadList() { |
| @@ -244,9 +278,10 @@ private: | |||
| 244 | boost::asio::io_context io_context; | 278 | boost::asio::io_context io_context; |
| 245 | boost::process::async_pipe signal_pipe; | 279 | boost::process::async_pipe signal_pipe; |
| 246 | boost::asio::ip::tcp::socket client_socket; | 280 | boost::asio::ip::tcp::socket client_socket; |
| 247 | std::optional<std::unique_lock<std::mutex>> suspend; | ||
| 248 | 281 | ||
| 282 | SignalInfo info; | ||
| 249 | Kernel::KThread* active_thread; | 283 | Kernel::KThread* active_thread; |
| 284 | bool pipe_data; | ||
| 250 | bool stopped; | 285 | bool stopped; |
| 251 | 286 | ||
| 252 | std::array<u8, 4096> client_data; | 287 | std::array<u8, 4096> client_data; |
| @@ -263,7 +298,18 @@ Debugger::Debugger(Core::System& system, u16 port) { | |||
| 263 | Debugger::~Debugger() = default; | 298 | Debugger::~Debugger() = default; |
| 264 | 299 | ||
| 265 | bool Debugger::NotifyThreadStopped(Kernel::KThread* thread) { | 300 | bool Debugger::NotifyThreadStopped(Kernel::KThread* thread) { |
| 266 | return impl && impl->NotifyThreadStopped(thread); | 301 | return impl && impl->SignalDebugger(SignalInfo{SignalType::Stopped, thread, nullptr}); |
| 302 | } | ||
| 303 | |||
| 304 | bool Debugger::NotifyThreadWatchpoint(Kernel::KThread* thread, | ||
| 305 | const Kernel::DebugWatchpoint& watch) { | ||
| 306 | return impl && impl->SignalDebugger(SignalInfo{SignalType::Watchpoint, thread, &watch}); | ||
| 307 | } | ||
| 308 | |||
| 309 | void Debugger::NotifyShutdown() { | ||
| 310 | if (impl) { | ||
| 311 | impl->SignalDebugger(SignalInfo{SignalType::ShuttingDown, nullptr, nullptr}); | ||
| 312 | } | ||
| 267 | } | 313 | } |
| 268 | 314 | ||
| 269 | } // namespace Core | 315 | } // namespace Core |
diff --git a/src/core/debugger/debugger.h b/src/core/debugger/debugger.h index ea36c6ab2..b2f503376 100644 --- a/src/core/debugger/debugger.h +++ b/src/core/debugger/debugger.h | |||
| @@ -9,7 +9,8 @@ | |||
| 9 | 9 | ||
| 10 | namespace Kernel { | 10 | namespace Kernel { |
| 11 | class KThread; | 11 | class KThread; |
| 12 | } | 12 | struct DebugWatchpoint; |
| 13 | } // namespace Kernel | ||
| 13 | 14 | ||
| 14 | namespace Core { | 15 | namespace Core { |
| 15 | class System; | 16 | class System; |
| @@ -35,6 +36,16 @@ public: | |||
| 35 | */ | 36 | */ |
| 36 | bool NotifyThreadStopped(Kernel::KThread* thread); | 37 | bool NotifyThreadStopped(Kernel::KThread* thread); |
| 37 | 38 | ||
| 39 | /** | ||
| 40 | * Notify the debugger that a shutdown is being performed now and disconnect. | ||
| 41 | */ | ||
| 42 | void NotifyShutdown(); | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Notify the debugger that the given thread has stopped due to hitting a watchpoint. | ||
| 46 | */ | ||
| 47 | bool NotifyThreadWatchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch); | ||
| 48 | |||
| 38 | private: | 49 | private: |
| 39 | std::unique_ptr<DebuggerImpl> impl; | 50 | std::unique_ptr<DebuggerImpl> impl; |
| 40 | }; | 51 | }; |
diff --git a/src/core/debugger/debugger_interface.h b/src/core/debugger/debugger_interface.h index 35ba0bc61..5b31edc43 100644 --- a/src/core/debugger/debugger_interface.h +++ b/src/core/debugger/debugger_interface.h | |||
| @@ -11,7 +11,8 @@ | |||
| 11 | 11 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | class KThread; | 13 | class KThread; |
| 14 | } | 14 | struct DebugWatchpoint; |
| 15 | } // namespace Kernel | ||
| 15 | 16 | ||
| 16 | namespace Core { | 17 | namespace Core { |
| 17 | 18 | ||
| @@ -67,6 +68,16 @@ public: | |||
| 67 | virtual void Stopped(Kernel::KThread* thread) = 0; | 68 | virtual void Stopped(Kernel::KThread* thread) = 0; |
| 68 | 69 | ||
| 69 | /** | 70 | /** |
| 71 | * Called when emulation is shutting down. | ||
| 72 | */ | ||
| 73 | virtual void ShuttingDown() = 0; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * Called when emulation has stopped on a watchpoint. | ||
| 77 | */ | ||
| 78 | virtual void Watchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch) = 0; | ||
| 79 | |||
| 80 | /** | ||
| 70 | * Called when new data is asynchronously received on the client socket. | 81 | * Called when new data is asynchronously received on the client socket. |
| 71 | * A list of actions to perform is returned. | 82 | * A list of actions to perform is returned. |
| 72 | */ | 83 | */ |
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index f52d78829..884229c77 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp | |||
| @@ -106,10 +106,29 @@ GDBStub::~GDBStub() = default; | |||
| 106 | 106 | ||
| 107 | void GDBStub::Connected() {} | 107 | void GDBStub::Connected() {} |
| 108 | 108 | ||
| 109 | void GDBStub::ShuttingDown() {} | ||
| 110 | |||
| 109 | void GDBStub::Stopped(Kernel::KThread* thread) { | 111 | void GDBStub::Stopped(Kernel::KThread* thread) { |
| 110 | SendReply(arch->ThreadStatus(thread, GDB_STUB_SIGTRAP)); | 112 | SendReply(arch->ThreadStatus(thread, GDB_STUB_SIGTRAP)); |
| 111 | } | 113 | } |
| 112 | 114 | ||
| 115 | void GDBStub::Watchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch) { | ||
| 116 | const auto status{arch->ThreadStatus(thread, GDB_STUB_SIGTRAP)}; | ||
| 117 | |||
| 118 | switch (watch.type) { | ||
| 119 | case Kernel::DebugWatchpointType::Read: | ||
| 120 | SendReply(fmt::format("{}rwatch:{:x};", status, watch.start_address)); | ||
| 121 | break; | ||
| 122 | case Kernel::DebugWatchpointType::Write: | ||
| 123 | SendReply(fmt::format("{}watch:{:x};", status, watch.start_address)); | ||
| 124 | break; | ||
| 125 | case Kernel::DebugWatchpointType::ReadOrWrite: | ||
| 126 | default: | ||
| 127 | SendReply(fmt::format("{}awatch:{:x};", status, watch.start_address)); | ||
| 128 | break; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 113 | std::vector<DebuggerAction> GDBStub::ClientData(std::span<const u8> data) { | 132 | std::vector<DebuggerAction> GDBStub::ClientData(std::span<const u8> data) { |
| 114 | std::vector<DebuggerAction> actions; | 133 | std::vector<DebuggerAction> actions; |
| 115 | current_command.insert(current_command.end(), data.begin(), data.end()); | 134 | current_command.insert(current_command.end(), data.begin(), data.end()); |
| @@ -233,6 +252,7 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction | |||
| 233 | const auto sep{std::find(command.begin(), command.end(), '=') - command.begin() + 1}; | 252 | const auto sep{std::find(command.begin(), command.end(), '=') - command.begin() + 1}; |
| 234 | const size_t reg{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; | 253 | const size_t reg{static_cast<size_t>(strtoll(command.data(), nullptr, 16))}; |
| 235 | arch->RegWrite(backend.GetActiveThread(), reg, std::string_view(command).substr(sep)); | 254 | arch->RegWrite(backend.GetActiveThread(), reg, std::string_view(command).substr(sep)); |
| 255 | SendReply(GDB_STUB_REPLY_OK); | ||
| 236 | break; | 256 | break; |
| 237 | } | 257 | } |
| 238 | case 'm': { | 258 | case 'm': { |
| @@ -276,41 +296,121 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction | |||
| 276 | case 'c': | 296 | case 'c': |
| 277 | actions.push_back(DebuggerAction::Continue); | 297 | actions.push_back(DebuggerAction::Continue); |
| 278 | break; | 298 | break; |
| 279 | case 'Z': { | 299 | case 'Z': |
| 280 | const auto addr_sep{std::find(command.begin(), command.end(), ',') - command.begin() + 1}; | 300 | HandleBreakpointInsert(command); |
| 281 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | 301 | break; |
| 302 | case 'z': | ||
| 303 | HandleBreakpointRemove(command); | ||
| 304 | break; | ||
| 305 | default: | ||
| 306 | SendReply(GDB_STUB_REPLY_EMPTY); | ||
| 307 | break; | ||
| 308 | } | ||
| 309 | } | ||
| 282 | 310 | ||
| 283 | if (system.Memory().IsValidVirtualAddress(addr)) { | 311 | enum class BreakpointType { |
| 284 | replaced_instructions[addr] = system.Memory().Read32(addr); | 312 | Software = 0, |
| 285 | system.Memory().Write32(addr, arch->BreakpointInstruction()); | 313 | Hardware = 1, |
| 286 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | 314 | WriteWatch = 2, |
| 315 | ReadWatch = 3, | ||
| 316 | AccessWatch = 4, | ||
| 317 | }; | ||
| 318 | |||
| 319 | void GDBStub::HandleBreakpointInsert(std::string_view command) { | ||
| 320 | const auto type{static_cast<BreakpointType>(strtoll(command.data(), nullptr, 16))}; | ||
| 321 | const auto addr_sep{std::find(command.begin(), command.end(), ',') - command.begin() + 1}; | ||
| 322 | const auto size_sep{std::find(command.begin() + addr_sep, command.end(), ',') - | ||
| 323 | command.begin() + 1}; | ||
| 324 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | ||
| 325 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; | ||
| 326 | |||
| 327 | if (!system.Memory().IsValidVirtualAddressRange(addr, size)) { | ||
| 328 | SendReply(GDB_STUB_REPLY_ERR); | ||
| 329 | return; | ||
| 330 | } | ||
| 287 | 331 | ||
| 288 | SendReply(GDB_STUB_REPLY_OK); | 332 | bool success{}; |
| 289 | } else { | 333 | |
| 290 | SendReply(GDB_STUB_REPLY_ERR); | 334 | switch (type) { |
| 291 | } | 335 | case BreakpointType::Software: |
| 336 | replaced_instructions[addr] = system.Memory().Read32(addr); | ||
| 337 | system.Memory().Write32(addr, arch->BreakpointInstruction()); | ||
| 338 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | ||
| 339 | success = true; | ||
| 340 | break; | ||
| 341 | case BreakpointType::WriteWatch: | ||
| 342 | success = system.CurrentProcess()->InsertWatchpoint(system, addr, size, | ||
| 343 | Kernel::DebugWatchpointType::Write); | ||
| 344 | break; | ||
| 345 | case BreakpointType::ReadWatch: | ||
| 346 | success = system.CurrentProcess()->InsertWatchpoint(system, addr, size, | ||
| 347 | Kernel::DebugWatchpointType::Read); | ||
| 348 | break; | ||
| 349 | case BreakpointType::AccessWatch: | ||
| 350 | success = system.CurrentProcess()->InsertWatchpoint( | ||
| 351 | system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); | ||
| 292 | break; | 352 | break; |
| 353 | case BreakpointType::Hardware: | ||
| 354 | default: | ||
| 355 | SendReply(GDB_STUB_REPLY_EMPTY); | ||
| 356 | return; | ||
| 357 | } | ||
| 358 | |||
| 359 | if (success) { | ||
| 360 | SendReply(GDB_STUB_REPLY_OK); | ||
| 361 | } else { | ||
| 362 | SendReply(GDB_STUB_REPLY_ERR); | ||
| 293 | } | 363 | } |
| 294 | case 'z': { | 364 | } |
| 295 | const auto addr_sep{std::find(command.begin(), command.end(), ',') - command.begin() + 1}; | 365 | |
| 296 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | 366 | void GDBStub::HandleBreakpointRemove(std::string_view command) { |
| 367 | const auto type{static_cast<BreakpointType>(strtoll(command.data(), nullptr, 16))}; | ||
| 368 | const auto addr_sep{std::find(command.begin(), command.end(), ',') - command.begin() + 1}; | ||
| 369 | const auto size_sep{std::find(command.begin() + addr_sep, command.end(), ',') - | ||
| 370 | command.begin() + 1}; | ||
| 371 | const size_t addr{static_cast<size_t>(strtoll(command.data() + addr_sep, nullptr, 16))}; | ||
| 372 | const size_t size{static_cast<size_t>(strtoll(command.data() + size_sep, nullptr, 16))}; | ||
| 373 | |||
| 374 | if (!system.Memory().IsValidVirtualAddressRange(addr, size)) { | ||
| 375 | SendReply(GDB_STUB_REPLY_ERR); | ||
| 376 | return; | ||
| 377 | } | ||
| 378 | |||
| 379 | bool success{}; | ||
| 297 | 380 | ||
| 381 | switch (type) { | ||
| 382 | case BreakpointType::Software: { | ||
| 298 | const auto orig_insn{replaced_instructions.find(addr)}; | 383 | const auto orig_insn{replaced_instructions.find(addr)}; |
| 299 | if (system.Memory().IsValidVirtualAddress(addr) && | 384 | if (orig_insn != replaced_instructions.end()) { |
| 300 | orig_insn != replaced_instructions.end()) { | ||
| 301 | system.Memory().Write32(addr, orig_insn->second); | 385 | system.Memory().Write32(addr, orig_insn->second); |
| 302 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); | 386 | system.InvalidateCpuInstructionCacheRange(addr, sizeof(u32)); |
| 303 | replaced_instructions.erase(addr); | 387 | replaced_instructions.erase(addr); |
| 304 | 388 | success = true; | |
| 305 | SendReply(GDB_STUB_REPLY_OK); | ||
| 306 | } else { | ||
| 307 | SendReply(GDB_STUB_REPLY_ERR); | ||
| 308 | } | 389 | } |
| 309 | break; | 390 | break; |
| 310 | } | 391 | } |
| 392 | case BreakpointType::WriteWatch: | ||
| 393 | success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size, | ||
| 394 | Kernel::DebugWatchpointType::Write); | ||
| 395 | break; | ||
| 396 | case BreakpointType::ReadWatch: | ||
| 397 | success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size, | ||
| 398 | Kernel::DebugWatchpointType::Read); | ||
| 399 | break; | ||
| 400 | case BreakpointType::AccessWatch: | ||
| 401 | success = system.CurrentProcess()->RemoveWatchpoint( | ||
| 402 | system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite); | ||
| 403 | break; | ||
| 404 | case BreakpointType::Hardware: | ||
| 311 | default: | 405 | default: |
| 312 | SendReply(GDB_STUB_REPLY_EMPTY); | 406 | SendReply(GDB_STUB_REPLY_EMPTY); |
| 313 | break; | 407 | return; |
| 408 | } | ||
| 409 | |||
| 410 | if (success) { | ||
| 411 | SendReply(GDB_STUB_REPLY_OK); | ||
| 412 | } else { | ||
| 413 | SendReply(GDB_STUB_REPLY_ERR); | ||
| 314 | } | 414 | } |
| 315 | } | 415 | } |
| 316 | 416 | ||
diff --git a/src/core/debugger/gdbstub.h b/src/core/debugger/gdbstub.h index 1bb638187..0b0f56e4b 100644 --- a/src/core/debugger/gdbstub.h +++ b/src/core/debugger/gdbstub.h | |||
| @@ -23,6 +23,8 @@ public: | |||
| 23 | 23 | ||
| 24 | void Connected() override; | 24 | void Connected() override; |
| 25 | void Stopped(Kernel::KThread* thread) override; | 25 | void Stopped(Kernel::KThread* thread) override; |
| 26 | void ShuttingDown() override; | ||
| 27 | void Watchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch) override; | ||
| 26 | std::vector<DebuggerAction> ClientData(std::span<const u8> data) override; | 28 | std::vector<DebuggerAction> ClientData(std::span<const u8> data) override; |
| 27 | 29 | ||
| 28 | private: | 30 | private: |
| @@ -30,6 +32,8 @@ private: | |||
| 30 | void ExecuteCommand(std::string_view packet, std::vector<DebuggerAction>& actions); | 32 | void ExecuteCommand(std::string_view packet, std::vector<DebuggerAction>& actions); |
| 31 | void HandleVCont(std::string_view command, std::vector<DebuggerAction>& actions); | 33 | void HandleVCont(std::string_view command, std::vector<DebuggerAction>& actions); |
| 32 | void HandleQuery(std::string_view command); | 34 | void HandleQuery(std::string_view command); |
| 35 | void HandleBreakpointInsert(std::string_view command); | ||
| 36 | void HandleBreakpointRemove(std::string_view command); | ||
| 33 | std::vector<char>::const_iterator CommandEnd() const; | 37 | std::vector<char>::const_iterator CommandEnd() const; |
| 34 | std::optional<std::string> DetachCommand(); | 38 | std::optional<std::string> DetachCommand(); |
| 35 | Kernel::KThread* GetThreadByID(u64 thread_id); | 39 | Kernel::KThread* GetThreadByID(u64 thread_id); |
diff --git a/src/core/debugger/gdbstub_arch.cpp b/src/core/debugger/gdbstub_arch.cpp index 750c353b9..4bef09bd7 100644 --- a/src/core/debugger/gdbstub_arch.cpp +++ b/src/core/debugger/gdbstub_arch.cpp | |||
| @@ -191,8 +191,10 @@ std::string GDBStubA64::RegRead(const Kernel::KThread* thread, size_t id) const | |||
| 191 | const auto& gprs{context.cpu_registers}; | 191 | const auto& gprs{context.cpu_registers}; |
| 192 | const auto& fprs{context.vector_registers}; | 192 | const auto& fprs{context.vector_registers}; |
| 193 | 193 | ||
| 194 | if (id <= SP_REGISTER) { | 194 | if (id < SP_REGISTER) { |
| 195 | return ValueToHex(gprs[id]); | 195 | return ValueToHex(gprs[id]); |
| 196 | } else if (id == SP_REGISTER) { | ||
| 197 | return ValueToHex(context.sp); | ||
| 196 | } else if (id == PC_REGISTER) { | 198 | } else if (id == PC_REGISTER) { |
| 197 | return ValueToHex(context.pc); | 199 | return ValueToHex(context.pc); |
| 198 | } else if (id == PSTATE_REGISTER) { | 200 | } else if (id == PSTATE_REGISTER) { |
| @@ -215,8 +217,10 @@ void GDBStubA64::RegWrite(Kernel::KThread* thread, size_t id, std::string_view v | |||
| 215 | 217 | ||
| 216 | auto& context{thread->GetContext64()}; | 218 | auto& context{thread->GetContext64()}; |
| 217 | 219 | ||
| 218 | if (id <= SP_REGISTER) { | 220 | if (id < SP_REGISTER) { |
| 219 | context.cpu_registers[id] = HexToValue<u64>(value); | 221 | context.cpu_registers[id] = HexToValue<u64>(value); |
| 222 | } else if (id == SP_REGISTER) { | ||
| 223 | context.sp = HexToValue<u64>(value); | ||
| 220 | } else if (id == PC_REGISTER) { | 224 | } else if (id == PC_REGISTER) { |
| 221 | context.pc = HexToValue<u64>(value); | 225 | context.pc = HexToValue<u64>(value); |
| 222 | } else if (id == PSTATE_REGISTER) { | 226 | } else if (id == PSTATE_REGISTER) { |
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 93f784418..78e56bbbd 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -419,7 +419,7 @@ std::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type | |||
| 419 | Core::Crypto::Mode::ECB); | 419 | Core::Crypto::Mode::ECB); |
| 420 | cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt); | 420 | cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt); |
| 421 | 421 | ||
| 422 | Core::Crypto::Key128 out; | 422 | Core::Crypto::Key128 out{}; |
| 423 | if (type == NCASectionCryptoType::XTS) { | 423 | if (type == NCASectionCryptoType::XTS) { |
| 424 | std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin()); | 424 | std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin()); |
| 425 | } else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR) { | 425 | } else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR) { |
diff --git a/src/core/file_sys/errors.h b/src/core/file_sys/errors.h index 1a920b45d..ff15b3e23 100644 --- a/src/core/file_sys/errors.h +++ b/src/core/file_sys/errors.h | |||
| @@ -8,14 +8,14 @@ | |||
| 8 | 8 | ||
| 9 | namespace FileSys { | 9 | namespace FileSys { |
| 10 | 10 | ||
| 11 | constexpr ResultCode ERROR_PATH_NOT_FOUND{ErrorModule::FS, 1}; | 11 | constexpr Result ERROR_PATH_NOT_FOUND{ErrorModule::FS, 1}; |
| 12 | constexpr ResultCode ERROR_PATH_ALREADY_EXISTS{ErrorModule::FS, 2}; | 12 | constexpr Result ERROR_PATH_ALREADY_EXISTS{ErrorModule::FS, 2}; |
| 13 | constexpr ResultCode ERROR_ENTITY_NOT_FOUND{ErrorModule::FS, 1002}; | 13 | constexpr Result ERROR_ENTITY_NOT_FOUND{ErrorModule::FS, 1002}; |
| 14 | constexpr ResultCode ERROR_SD_CARD_NOT_FOUND{ErrorModule::FS, 2001}; | 14 | constexpr Result ERROR_SD_CARD_NOT_FOUND{ErrorModule::FS, 2001}; |
| 15 | constexpr ResultCode ERROR_OUT_OF_BOUNDS{ErrorModule::FS, 3005}; | 15 | constexpr Result ERROR_OUT_OF_BOUNDS{ErrorModule::FS, 3005}; |
| 16 | constexpr ResultCode ERROR_FAILED_MOUNT_ARCHIVE{ErrorModule::FS, 3223}; | 16 | constexpr Result ERROR_FAILED_MOUNT_ARCHIVE{ErrorModule::FS, 3223}; |
| 17 | constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::FS, 6001}; | 17 | constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::FS, 6001}; |
| 18 | constexpr ResultCode ERROR_INVALID_OFFSET{ErrorModule::FS, 6061}; | 18 | constexpr Result ERROR_INVALID_OFFSET{ErrorModule::FS, 6061}; |
| 19 | constexpr ResultCode ERROR_INVALID_SIZE{ErrorModule::FS, 6062}; | 19 | constexpr Result ERROR_INVALID_SIZE{ErrorModule::FS, 6062}; |
| 20 | 20 | ||
| 21 | } // namespace FileSys | 21 | } // namespace FileSys |
diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp index d4c0a974a..2735d053b 100644 --- a/src/core/file_sys/nca_patch.cpp +++ b/src/core/file_sys/nca_patch.cpp | |||
| @@ -50,7 +50,7 @@ std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, const BlockTyp | |||
| 50 | low = mid + 1; | 50 | low = mid + 1; |
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| 53 | UNREACHABLE_MSG("Offset could not be found in BKTR block."); | 53 | ASSERT_MSG(false, "Offset could not be found in BKTR block."); |
| 54 | return {0, 0}; | 54 | return {0, 0}; |
| 55 | } | 55 | } |
| 56 | } // Anonymous namespace | 56 | } // Anonymous namespace |
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 2eaac73ef..878d832c2 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp | |||
| @@ -108,7 +108,7 @@ ContentRecordType GetCRTypeFromNCAType(NCAContentType type) { | |||
| 108 | // TODO(DarkLordZach): Peek at NCA contents to differentiate Manual and Legal. | 108 | // TODO(DarkLordZach): Peek at NCA contents to differentiate Manual and Legal. |
| 109 | return ContentRecordType::HtmlDocument; | 109 | return ContentRecordType::HtmlDocument; |
| 110 | default: | 110 | default: |
| 111 | UNREACHABLE_MSG("Invalid NCAContentType={:02X}", type); | 111 | ASSERT_MSG(false, "Invalid NCAContentType={:02X}", type); |
| 112 | return ContentRecordType{}; | 112 | return ContentRecordType{}; |
| 113 | } | 113 | } |
| 114 | } | 114 | } |
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index e42d7c9f6..cc0076238 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -144,7 +144,7 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ | |||
| 144 | LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", new_path); | 144 | LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", new_path); |
| 145 | } | 145 | } |
| 146 | } else { | 146 | } else { |
| 147 | UNREACHABLE(); | 147 | ASSERT(false); |
| 148 | return nullptr; | 148 | return nullptr; |
| 149 | } | 149 | } |
| 150 | 150 | ||
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp index 0ff2a338e..6c230f619 100644 --- a/src/core/frontend/applets/controller.cpp +++ b/src/core/frontend/applets/controller.cpp | |||
| @@ -65,7 +65,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb | |||
| 65 | controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); | 65 | controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); |
| 66 | controller->Connect(true); | 66 | controller->Connect(true); |
| 67 | } else { | 67 | } else { |
| 68 | UNREACHABLE_MSG("Unable to add a new controller based on the given parameters!"); | 68 | ASSERT_MSG(false, "Unable to add a new controller based on the given parameters!"); |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | 71 | ||
diff --git a/src/core/frontend/applets/error.cpp b/src/core/frontend/applets/error.cpp index f2ec4b10e..f8b961098 100644 --- a/src/core/frontend/applets/error.cpp +++ b/src/core/frontend/applets/error.cpp | |||
| @@ -8,12 +8,12 @@ namespace Core::Frontend { | |||
| 8 | 8 | ||
| 9 | ErrorApplet::~ErrorApplet() = default; | 9 | ErrorApplet::~ErrorApplet() = default; |
| 10 | 10 | ||
| 11 | void DefaultErrorApplet::ShowError(ResultCode error, std::function<void()> finished) const { | 11 | void DefaultErrorApplet::ShowError(Result error, std::function<void()> finished) const { |
| 12 | LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", | 12 | LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", |
| 13 | error.module.Value(), error.description.Value(), error.raw); | 13 | error.module.Value(), error.description.Value(), error.raw); |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | 16 | void DefaultErrorApplet::ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 17 | std::function<void()> finished) const { | 17 | std::function<void()> finished) const { |
| 18 | LOG_CRITICAL( | 18 | LOG_CRITICAL( |
| 19 | Service_Fatal, | 19 | Service_Fatal, |
| @@ -21,7 +21,7 @@ void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::s | |||
| 21 | error.module.Value(), error.description.Value(), error.raw, time.count()); | 21 | error.module.Value(), error.description.Value(), error.raw, time.count()); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_text, | 24 | void DefaultErrorApplet::ShowCustomErrorText(Result error, std::string main_text, |
| 25 | std::string detail_text, | 25 | std::string detail_text, |
| 26 | std::function<void()> finished) const { | 26 | std::function<void()> finished) const { |
| 27 | LOG_CRITICAL(Service_Fatal, | 27 | LOG_CRITICAL(Service_Fatal, |
diff --git a/src/core/frontend/applets/error.h b/src/core/frontend/applets/error.h index 8a1134561..f378f8805 100644 --- a/src/core/frontend/applets/error.h +++ b/src/core/frontend/applets/error.h | |||
| @@ -14,22 +14,22 @@ class ErrorApplet { | |||
| 14 | public: | 14 | public: |
| 15 | virtual ~ErrorApplet(); | 15 | virtual ~ErrorApplet(); |
| 16 | 16 | ||
| 17 | virtual void ShowError(ResultCode error, std::function<void()> finished) const = 0; | 17 | virtual void ShowError(Result error, std::function<void()> finished) const = 0; |
| 18 | 18 | ||
| 19 | virtual void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | 19 | virtual void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 20 | std::function<void()> finished) const = 0; | 20 | std::function<void()> finished) const = 0; |
| 21 | 21 | ||
| 22 | virtual void ShowCustomErrorText(ResultCode error, std::string dialog_text, | 22 | virtual void ShowCustomErrorText(Result error, std::string dialog_text, |
| 23 | std::string fullscreen_text, | 23 | std::string fullscreen_text, |
| 24 | std::function<void()> finished) const = 0; | 24 | std::function<void()> finished) const = 0; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | class DefaultErrorApplet final : public ErrorApplet { | 27 | class DefaultErrorApplet final : public ErrorApplet { |
| 28 | public: | 28 | public: |
| 29 | void ShowError(ResultCode error, std::function<void()> finished) const override; | 29 | void ShowError(Result error, std::function<void()> finished) const override; |
| 30 | void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | 30 | void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 31 | std::function<void()> finished) const override; | 31 | std::function<void()> finished) const override; |
| 32 | void ShowCustomErrorText(ResultCode error, std::string main_text, std::string detail_text, | 32 | void ShowCustomErrorText(Result error, std::string main_text, std::string detail_text, |
| 33 | std::function<void()> finished) const override; | 33 | std::function<void()> finished) const override; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h index aac362c51..13cbdb734 100644 --- a/src/core/hardware_properties.h +++ b/src/core/hardware_properties.h | |||
| @@ -25,6 +25,9 @@ constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{ | |||
| 25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, | 25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | // Cortex-A57 supports 4 memory watchpoints | ||
| 29 | constexpr u64 NUM_WATCHPOINTS = 4; | ||
| 30 | |||
| 28 | } // namespace Hardware | 31 | } // namespace Hardware |
| 29 | 32 | ||
| 30 | } // namespace Core | 33 | } // namespace Core |
diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp index 7eed52593..7d6373414 100644 --- a/src/core/hid/hid_core.cpp +++ b/src/core/hid/hid_core.cpp | |||
| @@ -48,7 +48,7 @@ EmulatedController* HIDCore::GetEmulatedController(NpadIdType npad_id_type) { | |||
| 48 | return handheld.get(); | 48 | return handheld.get(); |
| 49 | case NpadIdType::Invalid: | 49 | case NpadIdType::Invalid: |
| 50 | default: | 50 | default: |
| 51 | UNREACHABLE_MSG("Invalid NpadIdType={}", npad_id_type); | 51 | ASSERT_MSG(false, "Invalid NpadIdType={}", npad_id_type); |
| 52 | return nullptr; | 52 | return nullptr; |
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| @@ -77,7 +77,7 @@ const EmulatedController* HIDCore::GetEmulatedController(NpadIdType npad_id_type | |||
| 77 | return handheld.get(); | 77 | return handheld.get(); |
| 78 | case NpadIdType::Invalid: | 78 | case NpadIdType::Invalid: |
| 79 | default: | 79 | default: |
| 80 | UNREACHABLE_MSG("Invalid NpadIdType={}", npad_id_type); | 80 | ASSERT_MSG(false, "Invalid NpadIdType={}", npad_id_type); |
| 81 | return nullptr; | 81 | return nullptr; |
| 82 | } | 82 | } |
| 83 | } | 83 | } |
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 3c4e45fcd..004bb2005 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | namespace IPC { | 20 | namespace IPC { |
| 21 | 21 | ||
| 22 | constexpr ResultCode ERR_REMOTE_PROCESS_DEAD{ErrorModule::HIPC, 301}; | 22 | constexpr Result ERR_REMOTE_PROCESS_DEAD{ErrorModule::HIPC, 301}; |
| 23 | 23 | ||
| 24 | class RequestHelperBase { | 24 | class RequestHelperBase { |
| 25 | protected: | 25 | protected: |
| @@ -176,7 +176,7 @@ public: | |||
| 176 | void PushImpl(float value); | 176 | void PushImpl(float value); |
| 177 | void PushImpl(double value); | 177 | void PushImpl(double value); |
| 178 | void PushImpl(bool value); | 178 | void PushImpl(bool value); |
| 179 | void PushImpl(ResultCode value); | 179 | void PushImpl(Result value); |
| 180 | 180 | ||
| 181 | template <typename T> | 181 | template <typename T> |
| 182 | void Push(T value) { | 182 | void Push(T value) { |
| @@ -251,7 +251,7 @@ void ResponseBuilder::PushRaw(const T& value) { | |||
| 251 | index += (sizeof(T) + 3) / 4; // round up to word length | 251 | index += (sizeof(T) + 3) / 4; // round up to word length |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | inline void ResponseBuilder::PushImpl(ResultCode value) { | 254 | inline void ResponseBuilder::PushImpl(Result value) { |
| 255 | // Result codes are actually 64-bit in the IPC buffer, but only the high part is discarded. | 255 | // Result codes are actually 64-bit in the IPC buffer, but only the high part is discarded. |
| 256 | Push(value.raw); | 256 | Push(value.raw); |
| 257 | Push<u32>(0); | 257 | Push<u32>(0); |
| @@ -481,8 +481,8 @@ inline bool RequestParser::Pop() { | |||
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | template <> | 483 | template <> |
| 484 | inline ResultCode RequestParser::Pop() { | 484 | inline Result RequestParser::Pop() { |
| 485 | return ResultCode{Pop<u32>()}; | 485 | return Result{Pop<u32>()}; |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | template <typename T> | 488 | template <typename T> |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 4650d25b0..45135a07f 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -188,8 +188,8 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32 | |||
| 188 | rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. | 188 | rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, | 191 | Result HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, |
| 192 | u32_le* src_cmdbuf) { | 192 | u32_le* src_cmdbuf) { |
| 193 | ParseCommandBuffer(handle_table, src_cmdbuf, true); | 193 | ParseCommandBuffer(handle_table, src_cmdbuf, true); |
| 194 | 194 | ||
| 195 | if (command_header->IsCloseCommand()) { | 195 | if (command_header->IsCloseCommand()) { |
| @@ -202,7 +202,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTab | |||
| 202 | return ResultSuccess; | 202 | return ResultSuccess; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_thread) { | 205 | Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_thread) { |
| 206 | auto current_offset = handles_offset; | 206 | auto current_offset = handles_offset; |
| 207 | auto& owner_process = *requesting_thread.GetOwnerProcess(); | 207 | auto& owner_process = *requesting_thread.GetOwnerProcess(); |
| 208 | auto& handle_table = owner_process.GetHandleTable(); | 208 | auto& handle_table = owner_process.GetHandleTable(); |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index a427cbc93..d3abeee85 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include "core/hle/ipc.h" | 18 | #include "core/hle/ipc.h" |
| 19 | #include "core/hle/kernel/svc_common.h" | 19 | #include "core/hle/kernel/svc_common.h" |
| 20 | 20 | ||
| 21 | union ResultCode; | 21 | union Result; |
| 22 | 22 | ||
| 23 | namespace Core::Memory { | 23 | namespace Core::Memory { |
| 24 | class Memory; | 24 | class Memory; |
| @@ -71,10 +71,10 @@ public: | |||
| 71 | * it should be used to differentiate which client (As in ClientSession) we're answering to. | 71 | * it should be used to differentiate which client (As in ClientSession) we're answering to. |
| 72 | * TODO(Subv): Use a wrapper structure to hold all the information relevant to | 72 | * TODO(Subv): Use a wrapper structure to hold all the information relevant to |
| 73 | * this request (ServerSession, Originator thread, Translated command buffer, etc). | 73 | * this request (ServerSession, Originator thread, Translated command buffer, etc). |
| 74 | * @returns ResultCode the result code of the translate operation. | 74 | * @returns Result the result code of the translate operation. |
| 75 | */ | 75 | */ |
| 76 | virtual ResultCode HandleSyncRequest(Kernel::KServerSession& session, | 76 | virtual Result HandleSyncRequest(Kernel::KServerSession& session, |
| 77 | Kernel::HLERequestContext& context) = 0; | 77 | Kernel::HLERequestContext& context) = 0; |
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | * Signals that a client has just connected to this HLE handler and keeps the | 80 | * Signals that a client has just connected to this HLE handler and keeps the |
| @@ -141,7 +141,7 @@ public: | |||
| 141 | if (index < DomainHandlerCount()) { | 141 | if (index < DomainHandlerCount()) { |
| 142 | domain_handlers[index] = nullptr; | 142 | domain_handlers[index] = nullptr; |
| 143 | } else { | 143 | } else { |
| 144 | UNREACHABLE_MSG("Unexpected handler index {}", index); | 144 | ASSERT_MSG(false, "Unexpected handler index {}", index); |
| 145 | } | 145 | } |
| 146 | } | 146 | } |
| 147 | 147 | ||
| @@ -212,11 +212,10 @@ public: | |||
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | /// Populates this context with data from the requesting process/thread. | 214 | /// Populates this context with data from the requesting process/thread. |
| 215 | ResultCode PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, | 215 | Result PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf); |
| 216 | u32_le* src_cmdbuf); | ||
| 217 | 216 | ||
| 218 | /// Writes data from this context back to the requesting process/thread. | 217 | /// Writes data from this context back to the requesting process/thread. |
| 219 | ResultCode WriteToOutgoingCommandBuffer(KThread& requesting_thread); | 218 | Result WriteToOutgoingCommandBuffer(KThread& requesting_thread); |
| 220 | 219 | ||
| 221 | u32_le GetHipcCommand() const { | 220 | u32_le GetHipcCommand() const { |
| 222 | return command; | 221 | return command; |
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index 34a8be052..9b6b284d0 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -244,7 +244,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { | |||
| 244 | FOREACH_SLAB_TYPE(INITIALIZE_SLAB_HEAP) | 244 | FOREACH_SLAB_TYPE(INITIALIZE_SLAB_HEAP) |
| 245 | // If we somehow get an invalid type, abort. | 245 | // If we somehow get an invalid type, abort. |
| 246 | default: | 246 | default: |
| 247 | UNREACHABLE_MSG("Unknown slab type: {}", slab_types[i]); | 247 | ASSERT_MSG(false, "Unknown slab type: {}", slab_types[i]); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | // If we've hit the end of a gap, free it. | 250 | // If we've hit the end of a gap, free it. |
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 04cf86d52..f85b11557 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp | |||
| @@ -90,8 +90,7 @@ public: | |||
| 90 | explicit ThreadQueueImplForKAddressArbiter(KernelCore& kernel_, KAddressArbiter::ThreadTree* t) | 90 | explicit ThreadQueueImplForKAddressArbiter(KernelCore& kernel_, KAddressArbiter::ThreadTree* t) |
| 91 | : KThreadQueue(kernel_), m_tree(t) {} | 91 | : KThreadQueue(kernel_), m_tree(t) {} |
| 92 | 92 | ||
| 93 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 93 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 94 | bool cancel_timer_task) override { | ||
| 95 | // If the thread is waiting on an address arbiter, remove it from the tree. | 94 | // If the thread is waiting on an address arbiter, remove it from the tree. |
| 96 | if (waiting_thread->IsWaitingForAddressArbiter()) { | 95 | if (waiting_thread->IsWaitingForAddressArbiter()) { |
| 97 | m_tree->erase(m_tree->iterator_to(*waiting_thread)); | 96 | m_tree->erase(m_tree->iterator_to(*waiting_thread)); |
| @@ -108,7 +107,7 @@ private: | |||
| 108 | 107 | ||
| 109 | } // namespace | 108 | } // namespace |
| 110 | 109 | ||
| 111 | ResultCode KAddressArbiter::Signal(VAddr addr, s32 count) { | 110 | Result KAddressArbiter::Signal(VAddr addr, s32 count) { |
| 112 | // Perform signaling. | 111 | // Perform signaling. |
| 113 | s32 num_waiters{}; | 112 | s32 num_waiters{}; |
| 114 | { | 113 | { |
| @@ -131,7 +130,7 @@ ResultCode KAddressArbiter::Signal(VAddr addr, s32 count) { | |||
| 131 | return ResultSuccess; | 130 | return ResultSuccess; |
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | ResultCode KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count) { | 133 | Result KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count) { |
| 135 | // Perform signaling. | 134 | // Perform signaling. |
| 136 | s32 num_waiters{}; | 135 | s32 num_waiters{}; |
| 137 | { | 136 | { |
| @@ -164,7 +163,7 @@ ResultCode KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 | |||
| 164 | return ResultSuccess; | 163 | return ResultSuccess; |
| 165 | } | 164 | } |
| 166 | 165 | ||
| 167 | ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count) { | 166 | Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count) { |
| 168 | // Perform signaling. | 167 | // Perform signaling. |
| 169 | s32 num_waiters{}; | 168 | s32 num_waiters{}; |
| 170 | { | 169 | { |
| @@ -232,9 +231,9 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 | |||
| 232 | return ResultSuccess; | 231 | return ResultSuccess; |
| 233 | } | 232 | } |
| 234 | 233 | ||
| 235 | ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { | 234 | Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { |
| 236 | // Prepare to wait. | 235 | // Prepare to wait. |
| 237 | KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); | 236 | KThread* cur_thread = GetCurrentThreadPointer(kernel); |
| 238 | ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); | 237 | ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); |
| 239 | 238 | ||
| 240 | { | 239 | { |
| @@ -285,9 +284,9 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement | |||
| 285 | return cur_thread->GetWaitResult(); | 284 | return cur_thread->GetWaitResult(); |
| 286 | } | 285 | } |
| 287 | 286 | ||
| 288 | ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | 287 | Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { |
| 289 | // Prepare to wait. | 288 | // Prepare to wait. |
| 290 | KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); | 289 | KThread* cur_thread = GetCurrentThreadPointer(kernel); |
| 291 | ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); | 290 | ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); |
| 292 | 291 | ||
| 293 | { | 292 | { |
diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h index e46e0d848..e4085ae22 100644 --- a/src/core/hle/kernel/k_address_arbiter.h +++ b/src/core/hle/kernel/k_address_arbiter.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include "core/hle/kernel/k_condition_variable.h" | 8 | #include "core/hle/kernel/k_condition_variable.h" |
| 9 | #include "core/hle/kernel/svc_types.h" | 9 | #include "core/hle/kernel/svc_types.h" |
| 10 | 10 | ||
| 11 | union ResultCode; | 11 | union Result; |
| 12 | 12 | ||
| 13 | namespace Core { | 13 | namespace Core { |
| 14 | class System; | 14 | class System; |
| @@ -25,8 +25,7 @@ public: | |||
| 25 | explicit KAddressArbiter(Core::System& system_); | 25 | explicit KAddressArbiter(Core::System& system_); |
| 26 | ~KAddressArbiter(); | 26 | ~KAddressArbiter(); |
| 27 | 27 | ||
| 28 | [[nodiscard]] ResultCode SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, | 28 | [[nodiscard]] Result SignalToAddress(VAddr addr, Svc::SignalType type, s32 value, s32 count) { |
| 29 | s32 count) { | ||
| 30 | switch (type) { | 29 | switch (type) { |
| 31 | case Svc::SignalType::Signal: | 30 | case Svc::SignalType::Signal: |
| 32 | return Signal(addr, count); | 31 | return Signal(addr, count); |
| @@ -35,12 +34,12 @@ public: | |||
| 35 | case Svc::SignalType::SignalAndModifyByWaitingCountIfEqual: | 34 | case Svc::SignalType::SignalAndModifyByWaitingCountIfEqual: |
| 36 | return SignalAndModifyByWaitingCountIfEqual(addr, value, count); | 35 | return SignalAndModifyByWaitingCountIfEqual(addr, value, count); |
| 37 | } | 36 | } |
| 38 | UNREACHABLE(); | 37 | ASSERT(false); |
| 39 | return ResultUnknown; | 38 | return ResultUnknown; |
| 40 | } | 39 | } |
| 41 | 40 | ||
| 42 | [[nodiscard]] ResultCode WaitForAddress(VAddr addr, Svc::ArbitrationType type, s32 value, | 41 | [[nodiscard]] Result WaitForAddress(VAddr addr, Svc::ArbitrationType type, s32 value, |
| 43 | s64 timeout) { | 42 | s64 timeout) { |
| 44 | switch (type) { | 43 | switch (type) { |
| 45 | case Svc::ArbitrationType::WaitIfLessThan: | 44 | case Svc::ArbitrationType::WaitIfLessThan: |
| 46 | return WaitIfLessThan(addr, value, false, timeout); | 45 | return WaitIfLessThan(addr, value, false, timeout); |
| @@ -49,16 +48,16 @@ public: | |||
| 49 | case Svc::ArbitrationType::WaitIfEqual: | 48 | case Svc::ArbitrationType::WaitIfEqual: |
| 50 | return WaitIfEqual(addr, value, timeout); | 49 | return WaitIfEqual(addr, value, timeout); |
| 51 | } | 50 | } |
| 52 | UNREACHABLE(); | 51 | ASSERT(false); |
| 53 | return ResultUnknown; | 52 | return ResultUnknown; |
| 54 | } | 53 | } |
| 55 | 54 | ||
| 56 | private: | 55 | private: |
| 57 | [[nodiscard]] ResultCode Signal(VAddr addr, s32 count); | 56 | [[nodiscard]] Result Signal(VAddr addr, s32 count); |
| 58 | [[nodiscard]] ResultCode SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count); | 57 | [[nodiscard]] Result SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count); |
| 59 | [[nodiscard]] ResultCode SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count); | 58 | [[nodiscard]] Result SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count); |
| 60 | [[nodiscard]] ResultCode WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout); | 59 | [[nodiscard]] Result WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout); |
| 61 | [[nodiscard]] ResultCode WaitIfEqual(VAddr addr, s32 value, s64 timeout); | 60 | [[nodiscard]] Result WaitIfEqual(VAddr addr, s32 value, s64 timeout); |
| 62 | 61 | ||
| 63 | ThreadTree thread_tree; | 62 | ThreadTree thread_tree; |
| 64 | 63 | ||
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp index bc37cadda..3e612a207 100644 --- a/src/core/hle/kernel/k_address_space_info.cpp +++ b/src/core/hle/kernel/k_address_space_info.cpp | |||
| @@ -84,7 +84,7 @@ u64 KAddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) { | |||
| 84 | ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index])); | 84 | ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index])); |
| 85 | return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].address; | 85 | return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].address; |
| 86 | } | 86 | } |
| 87 | UNREACHABLE(); | 87 | ASSERT(false); |
| 88 | return 0; | 88 | return 0; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| @@ -101,7 +101,7 @@ std::size_t KAddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) | |||
| 101 | ASSERT(IsAllowed39BitType(type)); | 101 | ASSERT(IsAllowed39BitType(type)); |
| 102 | return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].size; | 102 | return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].size; |
| 103 | } | 103 | } |
| 104 | UNREACHABLE(); | 104 | ASSERT(false); |
| 105 | return 0; | 105 | return 0; |
| 106 | } | 106 | } |
| 107 | 107 | ||
diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index ea47fc600..2827763d5 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h | |||
| @@ -18,7 +18,7 @@ namespace Kernel { | |||
| 18 | class KernelCore; | 18 | class KernelCore; |
| 19 | class KProcess; | 19 | class KProcess; |
| 20 | 20 | ||
| 21 | #define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \ | 21 | #define KERNEL_AUTOOBJECT_TRAITS_IMPL(CLASS, BASE_CLASS, ATTRIBUTE) \ |
| 22 | \ | 22 | \ |
| 23 | private: \ | 23 | private: \ |
| 24 | friend class ::Kernel::KClassTokenGenerator; \ | 24 | friend class ::Kernel::KClassTokenGenerator; \ |
| @@ -40,16 +40,19 @@ public: | |||
| 40 | static constexpr const char* GetStaticTypeName() { \ | 40 | static constexpr const char* GetStaticTypeName() { \ |
| 41 | return TypeName; \ | 41 | return TypeName; \ |
| 42 | } \ | 42 | } \ |
| 43 | virtual TypeObj GetTypeObj() const { \ | 43 | virtual TypeObj GetTypeObj() ATTRIBUTE { \ |
| 44 | return GetStaticTypeObj(); \ | 44 | return GetStaticTypeObj(); \ |
| 45 | } \ | 45 | } \ |
| 46 | virtual const char* GetTypeName() const { \ | 46 | virtual const char* GetTypeName() ATTRIBUTE { \ |
| 47 | return GetStaticTypeName(); \ | 47 | return GetStaticTypeName(); \ |
| 48 | } \ | 48 | } \ |
| 49 | \ | 49 | \ |
| 50 | private: \ | 50 | private: \ |
| 51 | constexpr bool operator!=(const TypeObj& rhs) | 51 | constexpr bool operator!=(const TypeObj& rhs) |
| 52 | 52 | ||
| 53 | #define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \ | ||
| 54 | KERNEL_AUTOOBJECT_TRAITS_IMPL(CLASS, BASE_CLASS, const override) | ||
| 55 | |||
| 53 | class KAutoObject { | 56 | class KAutoObject { |
| 54 | protected: | 57 | protected: |
| 55 | class TypeObj { | 58 | class TypeObj { |
| @@ -82,7 +85,7 @@ protected: | |||
| 82 | }; | 85 | }; |
| 83 | 86 | ||
| 84 | private: | 87 | private: |
| 85 | KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject); | 88 | KERNEL_AUTOOBJECT_TRAITS_IMPL(KAutoObject, KAutoObject, const); |
| 86 | 89 | ||
| 87 | public: | 90 | public: |
| 88 | explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) { | 91 | explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) { |
diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h index be9e3c357..c9001ae3d 100644 --- a/src/core/hle/kernel/k_class_token.h +++ b/src/core/hle/kernel/k_class_token.h | |||
| @@ -49,6 +49,7 @@ private: | |||
| 49 | } | 49 | } |
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | UNREACHABLE(); | ||
| 52 | }(); | 53 | }(); |
| 53 | 54 | ||
| 54 | template <typename T> | 55 | template <typename T> |
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp index ef168fe87..d63e77d15 100644 --- a/src/core/hle/kernel/k_client_port.cpp +++ b/src/core/hle/kernel/k_client_port.cpp | |||
| @@ -59,8 +59,8 @@ bool KClientPort::IsSignaled() const { | |||
| 59 | return num_sessions < max_sessions; | 59 | return num_sessions < max_sessions; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | ResultCode KClientPort::CreateSession(KClientSession** out, | 62 | Result KClientPort::CreateSession(KClientSession** out, |
| 63 | std::shared_ptr<SessionRequestManager> session_manager) { | 63 | std::shared_ptr<SessionRequestManager> session_manager) { |
| 64 | // Reserve a new session from the resource limit. | 64 | // Reserve a new session from the resource limit. |
| 65 | KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(), | 65 | KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(), |
| 66 | LimitableResource::Sessions); | 66 | LimitableResource::Sessions); |
diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h index 54bb05e20..ef8583efc 100644 --- a/src/core/hle/kernel/k_client_port.h +++ b/src/core/hle/kernel/k_client_port.h | |||
| @@ -53,8 +53,8 @@ public: | |||
| 53 | void Destroy() override; | 53 | void Destroy() override; |
| 54 | bool IsSignaled() const override; | 54 | bool IsSignaled() const override; |
| 55 | 55 | ||
| 56 | ResultCode CreateSession(KClientSession** out, | 56 | Result CreateSession(KClientSession** out, |
| 57 | std::shared_ptr<SessionRequestManager> session_manager = nullptr); | 57 | std::shared_ptr<SessionRequestManager> session_manager = nullptr); |
| 58 | 58 | ||
| 59 | private: | 59 | private: |
| 60 | std::atomic<s32> num_sessions{}; | 60 | std::atomic<s32> num_sessions{}; |
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp index 731af079c..b2a887b14 100644 --- a/src/core/hle/kernel/k_client_session.cpp +++ b/src/core/hle/kernel/k_client_session.cpp | |||
| @@ -21,8 +21,8 @@ void KClientSession::Destroy() { | |||
| 21 | 21 | ||
| 22 | void KClientSession::OnServerClosed() {} | 22 | void KClientSession::OnServerClosed() {} |
| 23 | 23 | ||
| 24 | ResultCode KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 24 | Result KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, |
| 25 | Core::Timing::CoreTiming& core_timing) { | 25 | Core::Timing::CoreTiming& core_timing) { |
| 26 | // Signal the server session that new data is available | 26 | // Signal the server session that new data is available |
| 27 | return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing); | 27 | return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing); |
| 28 | } | 28 | } |
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h index 7a7ec8450..0c750d756 100644 --- a/src/core/hle/kernel/k_client_session.h +++ b/src/core/hle/kernel/k_client_session.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/kernel/slab_helpers.h" | 9 | #include "core/hle/kernel/slab_helpers.h" |
| 10 | #include "core/hle/result.h" | 10 | #include "core/hle/result.h" |
| 11 | 11 | ||
| 12 | union ResultCode; | 12 | union Result; |
| 13 | 13 | ||
| 14 | namespace Core::Memory { | 14 | namespace Core::Memory { |
| 15 | class Memory; | 15 | class Memory; |
| @@ -46,8 +46,8 @@ public: | |||
| 46 | return parent; | 46 | return parent; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | ResultCode SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 49 | Result SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, |
| 50 | Core::Timing::CoreTiming& core_timing); | 50 | Core::Timing::CoreTiming& core_timing); |
| 51 | 51 | ||
| 52 | void OnServerClosed(); | 52 | void OnServerClosed(); |
| 53 | 53 | ||
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp index fd3cbfd94..da57ceb21 100644 --- a/src/core/hle/kernel/k_code_memory.cpp +++ b/src/core/hle/kernel/k_code_memory.cpp | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "core/hle/kernel/k_code_memory.h" | 7 | #include "core/hle/kernel/k_code_memory.h" |
| 8 | #include "core/hle/kernel/k_light_lock.h" | 8 | #include "core/hle/kernel/k_light_lock.h" |
| 9 | #include "core/hle/kernel/k_memory_block.h" | 9 | #include "core/hle/kernel/k_memory_block.h" |
| 10 | #include "core/hle/kernel/k_page_linked_list.h" | 10 | #include "core/hle/kernel/k_page_group.h" |
| 11 | #include "core/hle/kernel/k_page_table.h" | 11 | #include "core/hle/kernel/k_page_table.h" |
| 12 | #include "core/hle/kernel/k_process.h" | 12 | #include "core/hle/kernel/k_process.h" |
| 13 | #include "core/hle/kernel/slab_helpers.h" | 13 | #include "core/hle/kernel/slab_helpers.h" |
| @@ -19,7 +19,7 @@ namespace Kernel { | |||
| 19 | KCodeMemory::KCodeMemory(KernelCore& kernel_) | 19 | KCodeMemory::KCodeMemory(KernelCore& kernel_) |
| 20 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_lock(kernel_) {} | 20 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_lock(kernel_) {} |
| 21 | 21 | ||
| 22 | ResultCode KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) { | 22 | Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) { |
| 23 | // Set members. | 23 | // Set members. |
| 24 | m_owner = kernel.CurrentProcess(); | 24 | m_owner = kernel.CurrentProcess(); |
| 25 | 25 | ||
| @@ -27,23 +27,18 @@ ResultCode KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr | |||
| 27 | auto& page_table = m_owner->PageTable(); | 27 | auto& page_table = m_owner->PageTable(); |
| 28 | 28 | ||
| 29 | // Construct the page group. | 29 | // Construct the page group. |
| 30 | m_page_group = | 30 | m_page_group = {}; |
| 31 | KPageLinkedList(page_table.GetPhysicalAddr(addr), Common::DivideUp(size, PageSize)); | ||
| 32 | 31 | ||
| 33 | // Lock the memory. | 32 | // Lock the memory. |
| 34 | R_TRY(page_table.LockForCodeMemory(addr, size)) | 33 | R_TRY(page_table.LockForCodeMemory(&m_page_group, addr, size)) |
| 35 | 34 | ||
| 36 | // Clear the memory. | 35 | // Clear the memory. |
| 37 | // | 36 | for (const auto& block : m_page_group.Nodes()) { |
| 38 | // FIXME: this ends up clobbering address ranges outside the scope of the mapping within | 37 | std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize()); |
| 39 | // guest memory, and is not specifically required if the guest program is correctly | 38 | } |
| 40 | // written, so disable until this is further investigated. | ||
| 41 | // | ||
| 42 | // for (const auto& block : m_page_group.Nodes()) { | ||
| 43 | // std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize()); | ||
| 44 | // } | ||
| 45 | 39 | ||
| 46 | // Set remaining tracking members. | 40 | // Set remaining tracking members. |
| 41 | m_owner->Open(); | ||
| 47 | m_address = addr; | 42 | m_address = addr; |
| 48 | m_is_initialized = true; | 43 | m_is_initialized = true; |
| 49 | m_is_owner_mapped = false; | 44 | m_is_owner_mapped = false; |
| @@ -57,11 +52,17 @@ void KCodeMemory::Finalize() { | |||
| 57 | // Unlock. | 52 | // Unlock. |
| 58 | if (!m_is_mapped && !m_is_owner_mapped) { | 53 | if (!m_is_mapped && !m_is_owner_mapped) { |
| 59 | const size_t size = m_page_group.GetNumPages() * PageSize; | 54 | const size_t size = m_page_group.GetNumPages() * PageSize; |
| 60 | m_owner->PageTable().UnlockForCodeMemory(m_address, size); | 55 | m_owner->PageTable().UnlockForCodeMemory(m_address, size, m_page_group); |
| 61 | } | 56 | } |
| 57 | |||
| 58 | // Close the page group. | ||
| 59 | m_page_group = {}; | ||
| 60 | |||
| 61 | // Close our reference to our owner. | ||
| 62 | m_owner->Close(); | ||
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | ResultCode KCodeMemory::Map(VAddr address, size_t size) { | 65 | Result KCodeMemory::Map(VAddr address, size_t size) { |
| 65 | // Validate the size. | 66 | // Validate the size. |
| 66 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | 67 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); |
| 67 | 68 | ||
| @@ -81,7 +82,7 @@ ResultCode KCodeMemory::Map(VAddr address, size_t size) { | |||
| 81 | return ResultSuccess; | 82 | return ResultSuccess; |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | ResultCode KCodeMemory::Unmap(VAddr address, size_t size) { | 85 | Result KCodeMemory::Unmap(VAddr address, size_t size) { |
| 85 | // Validate the size. | 86 | // Validate the size. |
| 86 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | 87 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); |
| 87 | 88 | ||
| @@ -98,7 +99,7 @@ ResultCode KCodeMemory::Unmap(VAddr address, size_t size) { | |||
| 98 | return ResultSuccess; | 99 | return ResultSuccess; |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | ResultCode KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) { | 102 | Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) { |
| 102 | // Validate the size. | 103 | // Validate the size. |
| 103 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | 104 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); |
| 104 | 105 | ||
| @@ -118,7 +119,8 @@ ResultCode KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermis | |||
| 118 | k_perm = KMemoryPermission::UserReadExecute; | 119 | k_perm = KMemoryPermission::UserReadExecute; |
| 119 | break; | 120 | break; |
| 120 | default: | 121 | default: |
| 121 | break; | 122 | // Already validated by ControlCodeMemory svc |
| 123 | UNREACHABLE(); | ||
| 122 | } | 124 | } |
| 123 | 125 | ||
| 124 | // Map the memory. | 126 | // Map the memory. |
| @@ -131,7 +133,7 @@ ResultCode KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermis | |||
| 131 | return ResultSuccess; | 133 | return ResultSuccess; |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | ResultCode KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { | 136 | Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { |
| 135 | // Validate the size. | 137 | // Validate the size. |
| 136 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | 138 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); |
| 137 | 139 | ||
diff --git a/src/core/hle/kernel/k_code_memory.h b/src/core/hle/kernel/k_code_memory.h index ab06b6f29..2410f74a3 100644 --- a/src/core/hle/kernel/k_code_memory.h +++ b/src/core/hle/kernel/k_code_memory.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "core/device_memory.h" | 7 | #include "core/device_memory.h" |
| 8 | #include "core/hle/kernel/k_auto_object.h" | 8 | #include "core/hle/kernel/k_auto_object.h" |
| 9 | #include "core/hle/kernel/k_light_lock.h" | 9 | #include "core/hle/kernel/k_light_lock.h" |
| 10 | #include "core/hle/kernel/k_page_linked_list.h" | 10 | #include "core/hle/kernel/k_page_group.h" |
| 11 | #include "core/hle/kernel/k_process.h" | 11 | #include "core/hle/kernel/k_process.h" |
| 12 | #include "core/hle/kernel/slab_helpers.h" | 12 | #include "core/hle/kernel/slab_helpers.h" |
| 13 | #include "core/hle/kernel/svc_types.h" | 13 | #include "core/hle/kernel/svc_types.h" |
| @@ -29,13 +29,13 @@ class KCodeMemory final | |||
| 29 | public: | 29 | public: |
| 30 | explicit KCodeMemory(KernelCore& kernel_); | 30 | explicit KCodeMemory(KernelCore& kernel_); |
| 31 | 31 | ||
| 32 | ResultCode Initialize(Core::DeviceMemory& device_memory, VAddr address, size_t size); | 32 | Result Initialize(Core::DeviceMemory& device_memory, VAddr address, size_t size); |
| 33 | void Finalize(); | 33 | void Finalize(); |
| 34 | 34 | ||
| 35 | ResultCode Map(VAddr address, size_t size); | 35 | Result Map(VAddr address, size_t size); |
| 36 | ResultCode Unmap(VAddr address, size_t size); | 36 | Result Unmap(VAddr address, size_t size); |
| 37 | ResultCode MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm); | 37 | Result MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm); |
| 38 | ResultCode UnmapFromOwner(VAddr address, size_t size); | 38 | Result UnmapFromOwner(VAddr address, size_t size); |
| 39 | 39 | ||
| 40 | bool IsInitialized() const { | 40 | bool IsInitialized() const { |
| 41 | return m_is_initialized; | 41 | return m_is_initialized; |
| @@ -53,7 +53,7 @@ public: | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | private: | 55 | private: |
| 56 | KPageLinkedList m_page_group{}; | 56 | KPageGroup m_page_group{}; |
| 57 | KProcess* m_owner{}; | 57 | KProcess* m_owner{}; |
| 58 | VAddr m_address{}; | 58 | VAddr m_address{}; |
| 59 | KLightLock m_lock; | 59 | KLightLock m_lock; |
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 43bcd253d..124149697 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp | |||
| @@ -61,8 +61,7 @@ public: | |||
| 61 | explicit ThreadQueueImplForKConditionVariableWaitForAddress(KernelCore& kernel_) | 61 | explicit ThreadQueueImplForKConditionVariableWaitForAddress(KernelCore& kernel_) |
| 62 | : KThreadQueue(kernel_) {} | 62 | : KThreadQueue(kernel_) {} |
| 63 | 63 | ||
| 64 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 64 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 65 | bool cancel_timer_task) override { | ||
| 66 | // Remove the thread as a waiter from its owner. | 65 | // Remove the thread as a waiter from its owner. |
| 67 | waiting_thread->GetLockOwner()->RemoveWaiter(waiting_thread); | 66 | waiting_thread->GetLockOwner()->RemoveWaiter(waiting_thread); |
| 68 | 67 | ||
| @@ -80,8 +79,7 @@ public: | |||
| 80 | KernelCore& kernel_, KConditionVariable::ThreadTree* t) | 79 | KernelCore& kernel_, KConditionVariable::ThreadTree* t) |
| 81 | : KThreadQueue(kernel_), m_tree(t) {} | 80 | : KThreadQueue(kernel_), m_tree(t) {} |
| 82 | 81 | ||
| 83 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 82 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 84 | bool cancel_timer_task) override { | ||
| 85 | // Remove the thread as a waiter from its owner. | 83 | // Remove the thread as a waiter from its owner. |
| 86 | if (KThread* owner = waiting_thread->GetLockOwner(); owner != nullptr) { | 84 | if (KThread* owner = waiting_thread->GetLockOwner(); owner != nullptr) { |
| 87 | owner->RemoveWaiter(waiting_thread); | 85 | owner->RemoveWaiter(waiting_thread); |
| @@ -105,8 +103,8 @@ KConditionVariable::KConditionVariable(Core::System& system_) | |||
| 105 | 103 | ||
| 106 | KConditionVariable::~KConditionVariable() = default; | 104 | KConditionVariable::~KConditionVariable() = default; |
| 107 | 105 | ||
| 108 | ResultCode KConditionVariable::SignalToAddress(VAddr addr) { | 106 | Result KConditionVariable::SignalToAddress(VAddr addr) { |
| 109 | KThread* owner_thread = kernel.CurrentScheduler()->GetCurrentThread(); | 107 | KThread* owner_thread = GetCurrentThreadPointer(kernel); |
| 110 | 108 | ||
| 111 | // Signal the address. | 109 | // Signal the address. |
| 112 | { | 110 | { |
| @@ -126,7 +124,7 @@ ResultCode KConditionVariable::SignalToAddress(VAddr addr) { | |||
| 126 | } | 124 | } |
| 127 | 125 | ||
| 128 | // Write the value to userspace. | 126 | // Write the value to userspace. |
| 129 | ResultCode result{ResultSuccess}; | 127 | Result result{ResultSuccess}; |
| 130 | if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] { | 128 | if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] { |
| 131 | result = ResultSuccess; | 129 | result = ResultSuccess; |
| 132 | } else { | 130 | } else { |
| @@ -146,8 +144,8 @@ ResultCode KConditionVariable::SignalToAddress(VAddr addr) { | |||
| 146 | } | 144 | } |
| 147 | } | 145 | } |
| 148 | 146 | ||
| 149 | ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { | 147 | Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { |
| 150 | KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); | 148 | KThread* cur_thread = GetCurrentThreadPointer(kernel); |
| 151 | ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel); | 149 | ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel); |
| 152 | 150 | ||
| 153 | // Wait for the address. | 151 | // Wait for the address. |
| @@ -261,7 +259,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { | |||
| 261 | } | 259 | } |
| 262 | } | 260 | } |
| 263 | 261 | ||
| 264 | ResultCode KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { | 262 | Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { |
| 265 | // Prepare to wait. | 263 | // Prepare to wait. |
| 266 | KThread* cur_thread = GetCurrentThreadPointer(kernel); | 264 | KThread* cur_thread = GetCurrentThreadPointer(kernel); |
| 267 | ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue( | 265 | ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue( |
diff --git a/src/core/hle/kernel/k_condition_variable.h b/src/core/hle/kernel/k_condition_variable.h index 7bc749d98..fad4ed011 100644 --- a/src/core/hle/kernel/k_condition_variable.h +++ b/src/core/hle/kernel/k_condition_variable.h | |||
| @@ -25,12 +25,12 @@ public: | |||
| 25 | ~KConditionVariable(); | 25 | ~KConditionVariable(); |
| 26 | 26 | ||
| 27 | // Arbitration | 27 | // Arbitration |
| 28 | [[nodiscard]] ResultCode SignalToAddress(VAddr addr); | 28 | [[nodiscard]] Result SignalToAddress(VAddr addr); |
| 29 | [[nodiscard]] ResultCode WaitForAddress(Handle handle, VAddr addr, u32 value); | 29 | [[nodiscard]] Result WaitForAddress(Handle handle, VAddr addr, u32 value); |
| 30 | 30 | ||
| 31 | // Condition variable | 31 | // Condition variable |
| 32 | void Signal(u64 cv_key, s32 count); | 32 | void Signal(u64 cv_key, s32 count); |
| 33 | [[nodiscard]] ResultCode Wait(VAddr addr, u64 key, u32 value, s64 timeout); | 33 | [[nodiscard]] Result Wait(VAddr addr, u64 key, u32 value, s64 timeout); |
| 34 | 34 | ||
| 35 | private: | 35 | private: |
| 36 | void SignalImpl(KThread* thread); | 36 | void SignalImpl(KThread* thread); |
diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp index c453927ad..e830ca46e 100644 --- a/src/core/hle/kernel/k_handle_table.cpp +++ b/src/core/hle/kernel/k_handle_table.cpp | |||
| @@ -8,7 +8,7 @@ namespace Kernel { | |||
| 8 | KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {} | 8 | KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {} |
| 9 | KHandleTable::~KHandleTable() = default; | 9 | KHandleTable::~KHandleTable() = default; |
| 10 | 10 | ||
| 11 | ResultCode KHandleTable::Finalize() { | 11 | Result KHandleTable::Finalize() { |
| 12 | // Get the table and clear our record of it. | 12 | // Get the table and clear our record of it. |
| 13 | u16 saved_table_size = 0; | 13 | u16 saved_table_size = 0; |
| 14 | { | 14 | { |
| @@ -62,7 +62,7 @@ bool KHandleTable::Remove(Handle handle) { | |||
| 62 | return true; | 62 | return true; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | ResultCode KHandleTable::Add(Handle* out_handle, KAutoObject* obj) { | 65 | Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) { |
| 66 | KScopedDisableDispatch dd(kernel); | 66 | KScopedDisableDispatch dd(kernel); |
| 67 | KScopedSpinLock lk(m_lock); | 67 | KScopedSpinLock lk(m_lock); |
| 68 | 68 | ||
| @@ -85,7 +85,7 @@ ResultCode KHandleTable::Add(Handle* out_handle, KAutoObject* obj) { | |||
| 85 | return ResultSuccess; | 85 | return ResultSuccess; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | ResultCode KHandleTable::Reserve(Handle* out_handle) { | 88 | Result KHandleTable::Reserve(Handle* out_handle) { |
| 89 | KScopedDisableDispatch dd(kernel); | 89 | KScopedDisableDispatch dd(kernel); |
| 90 | KScopedSpinLock lk(m_lock); | 90 | KScopedSpinLock lk(m_lock); |
| 91 | 91 | ||
diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h index befdb2ec9..0864a737c 100644 --- a/src/core/hle/kernel/k_handle_table.h +++ b/src/core/hle/kernel/k_handle_table.h | |||
| @@ -30,7 +30,7 @@ public: | |||
| 30 | explicit KHandleTable(KernelCore& kernel_); | 30 | explicit KHandleTable(KernelCore& kernel_); |
| 31 | ~KHandleTable(); | 31 | ~KHandleTable(); |
| 32 | 32 | ||
| 33 | ResultCode Initialize(s32 size) { | 33 | Result Initialize(s32 size) { |
| 34 | R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); | 34 | R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); |
| 35 | 35 | ||
| 36 | // Initialize all fields. | 36 | // Initialize all fields. |
| @@ -60,7 +60,7 @@ public: | |||
| 60 | return m_max_count; | 60 | return m_max_count; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | ResultCode Finalize(); | 63 | Result Finalize(); |
| 64 | bool Remove(Handle handle); | 64 | bool Remove(Handle handle); |
| 65 | 65 | ||
| 66 | template <typename T = KAutoObject> | 66 | template <typename T = KAutoObject> |
| @@ -100,10 +100,10 @@ public: | |||
| 100 | return this->template GetObjectWithoutPseudoHandle<T>(handle); | 100 | return this->template GetObjectWithoutPseudoHandle<T>(handle); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | ResultCode Reserve(Handle* out_handle); | 103 | Result Reserve(Handle* out_handle); |
| 104 | void Unreserve(Handle handle); | 104 | void Unreserve(Handle handle); |
| 105 | 105 | ||
| 106 | ResultCode Add(Handle* out_handle, KAutoObject* obj); | 106 | Result Add(Handle* out_handle, KAutoObject* obj); |
| 107 | void Register(Handle handle, KAutoObject* obj); | 107 | void Register(Handle handle, KAutoObject* obj); |
| 108 | 108 | ||
| 109 | template <typename T> | 109 | template <typename T> |
diff --git a/src/core/hle/kernel/k_interrupt_manager.cpp b/src/core/hle/kernel/k_interrupt_manager.cpp index cf9ed80d0..d606a7f86 100644 --- a/src/core/hle/kernel/k_interrupt_manager.cpp +++ b/src/core/hle/kernel/k_interrupt_manager.cpp | |||
| @@ -15,8 +15,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) { | |||
| 15 | return; | 15 | return; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | auto& scheduler = kernel.Scheduler(core_id); | 18 | auto& current_thread = GetCurrentThread(kernel); |
| 19 | auto& current_thread = *scheduler.GetCurrentThread(); | ||
| 20 | 19 | ||
| 21 | // If the user disable count is set, we may need to pin the current thread. | 20 | // If the user disable count is set, we may need to pin the current thread. |
| 22 | if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) { | 21 | if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) { |
| @@ -26,7 +25,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) { | |||
| 26 | process->PinCurrentThread(core_id); | 25 | process->PinCurrentThread(core_id); |
| 27 | 26 | ||
| 28 | // Set the interrupt flag for the thread. | 27 | // Set the interrupt flag for the thread. |
| 29 | scheduler.GetCurrentThread()->SetInterruptFlag(); | 28 | GetCurrentThread(kernel).SetInterruptFlag(); |
| 30 | } | 29 | } |
| 31 | } | 30 | } |
| 32 | 31 | ||
diff --git a/src/core/hle/kernel/k_light_condition_variable.cpp b/src/core/hle/kernel/k_light_condition_variable.cpp index a40f35f45..cade99cfd 100644 --- a/src/core/hle/kernel/k_light_condition_variable.cpp +++ b/src/core/hle/kernel/k_light_condition_variable.cpp | |||
| @@ -17,8 +17,7 @@ public: | |||
| 17 | bool term) | 17 | bool term) |
| 18 | : KThreadQueue(kernel_), m_wait_list(wl), m_allow_terminating_thread(term) {} | 18 | : KThreadQueue(kernel_), m_wait_list(wl), m_allow_terminating_thread(term) {} |
| 19 | 19 | ||
| 20 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 20 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 21 | bool cancel_timer_task) override { | ||
| 22 | // Only process waits if we're allowed to. | 21 | // Only process waits if we're allowed to. |
| 23 | if (ResultTerminationRequested == wait_result && m_allow_terminating_thread) { | 22 | if (ResultTerminationRequested == wait_result && m_allow_terminating_thread) { |
| 24 | return; | 23 | return; |
diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp index 0225734b4..43185320d 100644 --- a/src/core/hle/kernel/k_light_lock.cpp +++ b/src/core/hle/kernel/k_light_lock.cpp | |||
| @@ -15,8 +15,7 @@ class ThreadQueueImplForKLightLock final : public KThreadQueue { | |||
| 15 | public: | 15 | public: |
| 16 | explicit ThreadQueueImplForKLightLock(KernelCore& kernel_) : KThreadQueue(kernel_) {} | 16 | explicit ThreadQueueImplForKLightLock(KernelCore& kernel_) : KThreadQueue(kernel_) {} |
| 17 | 17 | ||
| 18 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 18 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 19 | bool cancel_timer_task) override { | ||
| 20 | // Remove the thread as a waiter from its owner. | 19 | // Remove the thread as a waiter from its owner. |
| 21 | if (KThread* owner = waiting_thread->GetLockOwner(); owner != nullptr) { | 20 | if (KThread* owner = waiting_thread->GetLockOwner(); owner != nullptr) { |
| 22 | owner->RemoveWaiter(waiting_thread); | 21 | owner->RemoveWaiter(waiting_thread); |
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index a55db3088..5b0a9963a 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #include "core/device_memory.h" | 11 | #include "core/device_memory.h" |
| 12 | #include "core/hle/kernel/initial_process.h" | 12 | #include "core/hle/kernel/initial_process.h" |
| 13 | #include "core/hle/kernel/k_memory_manager.h" | 13 | #include "core/hle/kernel/k_memory_manager.h" |
| 14 | #include "core/hle/kernel/k_page_linked_list.h" | 14 | #include "core/hle/kernel/k_page_group.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 16 | #include "core/hle/kernel/svc_results.h" | 16 | #include "core/hle/kernel/svc_results.h" |
| 17 | 17 | ||
| @@ -29,7 +29,7 @@ constexpr KMemoryManager::Pool GetPoolFromMemoryRegionType(u32 type) { | |||
| 29 | } else if ((type | KMemoryRegionType_DramSystemNonSecurePool) == type) { | 29 | } else if ((type | KMemoryRegionType_DramSystemNonSecurePool) == type) { |
| 30 | return KMemoryManager::Pool::SystemNonSecure; | 30 | return KMemoryManager::Pool::SystemNonSecure; |
| 31 | } else { | 31 | } else { |
| 32 | UNREACHABLE_MSG("InvalidMemoryRegionType for conversion to Pool"); | 32 | ASSERT_MSG(false, "InvalidMemoryRegionType for conversion to Pool"); |
| 33 | return {}; | 33 | return {}; |
| 34 | } | 34 | } |
| 35 | } | 35 | } |
| @@ -208,8 +208,8 @@ PAddr KMemoryManager::AllocateAndOpenContinuous(size_t num_pages, size_t align_p | |||
| 208 | return allocated_block; | 208 | return allocated_block; |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | ResultCode KMemoryManager::AllocatePageGroupImpl(KPageLinkedList* out, size_t num_pages, Pool pool, | 211 | Result KMemoryManager::AllocatePageGroupImpl(KPageGroup* out, size_t num_pages, Pool pool, |
| 212 | Direction dir, bool random) { | 212 | Direction dir, bool random) { |
| 213 | // Choose a heap based on our page size request. | 213 | // Choose a heap based on our page size request. |
| 214 | const s32 heap_index = KPageHeap::GetBlockIndex(num_pages); | 214 | const s32 heap_index = KPageHeap::GetBlockIndex(num_pages); |
| 215 | R_UNLESS(0 <= heap_index, ResultOutOfMemory); | 215 | R_UNLESS(0 <= heap_index, ResultOutOfMemory); |
| @@ -257,7 +257,7 @@ ResultCode KMemoryManager::AllocatePageGroupImpl(KPageLinkedList* out, size_t nu | |||
| 257 | return ResultSuccess; | 257 | return ResultSuccess; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | ResultCode KMemoryManager::AllocateAndOpen(KPageLinkedList* out, size_t num_pages, u32 option) { | 260 | Result KMemoryManager::AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 option) { |
| 261 | ASSERT(out != nullptr); | 261 | ASSERT(out != nullptr); |
| 262 | ASSERT(out->GetNumPages() == 0); | 262 | ASSERT(out->GetNumPages() == 0); |
| 263 | 263 | ||
| @@ -293,8 +293,8 @@ ResultCode KMemoryManager::AllocateAndOpen(KPageLinkedList* out, size_t num_page | |||
| 293 | return ResultSuccess; | 293 | return ResultSuccess; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | ResultCode KMemoryManager::AllocateAndOpenForProcess(KPageLinkedList* out, size_t num_pages, | 296 | Result KMemoryManager::AllocateAndOpenForProcess(KPageGroup* out, size_t num_pages, u32 option, |
| 297 | u32 option, u64 process_id, u8 fill_pattern) { | 297 | u64 process_id, u8 fill_pattern) { |
| 298 | ASSERT(out != nullptr); | 298 | ASSERT(out != nullptr); |
| 299 | ASSERT(out->GetNumPages() == 0); | 299 | ASSERT(out->GetNumPages() == 0); |
| 300 | 300 | ||
| @@ -370,12 +370,12 @@ void KMemoryManager::Close(PAddr address, size_t num_pages) { | |||
| 370 | } | 370 | } |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | void KMemoryManager::Close(const KPageLinkedList& pg) { | 373 | void KMemoryManager::Close(const KPageGroup& pg) { |
| 374 | for (const auto& node : pg.Nodes()) { | 374 | for (const auto& node : pg.Nodes()) { |
| 375 | Close(node.GetAddress(), node.GetNumPages()); | 375 | Close(node.GetAddress(), node.GetNumPages()); |
| 376 | } | 376 | } |
| 377 | } | 377 | } |
| 378 | void KMemoryManager::Open(const KPageLinkedList& pg) { | 378 | void KMemoryManager::Open(const KPageGroup& pg) { |
| 379 | for (const auto& node : pg.Nodes()) { | 379 | for (const auto& node : pg.Nodes()) { |
| 380 | Open(node.GetAddress(), node.GetNumPages()); | 380 | Open(node.GetAddress(), node.GetNumPages()); |
| 381 | } | 381 | } |
diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h index c7923cb82..dcb9b6348 100644 --- a/src/core/hle/kernel/k_memory_manager.h +++ b/src/core/hle/kernel/k_memory_manager.h | |||
| @@ -19,7 +19,7 @@ class System; | |||
| 19 | 19 | ||
| 20 | namespace Kernel { | 20 | namespace Kernel { |
| 21 | 21 | ||
| 22 | class KPageLinkedList; | 22 | class KPageGroup; |
| 23 | 23 | ||
| 24 | class KMemoryManager final { | 24 | class KMemoryManager final { |
| 25 | public: | 25 | public: |
| @@ -65,17 +65,17 @@ public: | |||
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | PAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); | 67 | PAddr AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); |
| 68 | ResultCode AllocateAndOpen(KPageLinkedList* out, size_t num_pages, u32 option); | 68 | Result AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 option); |
| 69 | ResultCode AllocateAndOpenForProcess(KPageLinkedList* out, size_t num_pages, u32 option, | 69 | Result AllocateAndOpenForProcess(KPageGroup* out, size_t num_pages, u32 option, u64 process_id, |
| 70 | u64 process_id, u8 fill_pattern); | 70 | u8 fill_pattern); |
| 71 | 71 | ||
| 72 | static constexpr size_t MaxManagerCount = 10; | 72 | static constexpr size_t MaxManagerCount = 10; |
| 73 | 73 | ||
| 74 | void Close(PAddr address, size_t num_pages); | 74 | void Close(PAddr address, size_t num_pages); |
| 75 | void Close(const KPageLinkedList& pg); | 75 | void Close(const KPageGroup& pg); |
| 76 | 76 | ||
| 77 | void Open(PAddr address, size_t num_pages); | 77 | void Open(PAddr address, size_t num_pages); |
| 78 | void Open(const KPageLinkedList& pg); | 78 | void Open(const KPageGroup& pg); |
| 79 | 79 | ||
| 80 | public: | 80 | public: |
| 81 | static size_t CalculateManagementOverheadSize(size_t region_size) { | 81 | static size_t CalculateManagementOverheadSize(size_t region_size) { |
| @@ -262,8 +262,8 @@ private: | |||
| 262 | } | 262 | } |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | ResultCode AllocatePageGroupImpl(KPageLinkedList* out, size_t num_pages, Pool pool, | 265 | Result AllocatePageGroupImpl(KPageGroup* out, size_t num_pages, Pool pool, Direction dir, |
| 266 | Direction dir, bool random); | 266 | bool random); |
| 267 | 267 | ||
| 268 | private: | 268 | private: |
| 269 | Core::System& system; | 269 | Core::System& system; |
diff --git a/src/core/hle/kernel/k_page_linked_list.h b/src/core/hle/kernel/k_page_group.h index 1f79c8330..968753992 100644 --- a/src/core/hle/kernel/k_page_linked_list.h +++ b/src/core/hle/kernel/k_page_group.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
| 14 | 14 | ||
| 15 | class KPageLinkedList final { | 15 | class KPageGroup final { |
| 16 | public: | 16 | public: |
| 17 | class Node final { | 17 | class Node final { |
| 18 | public: | 18 | public: |
| @@ -36,8 +36,8 @@ public: | |||
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | public: | 38 | public: |
| 39 | KPageLinkedList() = default; | 39 | KPageGroup() = default; |
| 40 | KPageLinkedList(u64 address, u64 num_pages) { | 40 | KPageGroup(u64 address, u64 num_pages) { |
| 41 | ASSERT(AddBlock(address, num_pages).IsSuccess()); | 41 | ASSERT(AddBlock(address, num_pages).IsSuccess()); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| @@ -57,7 +57,7 @@ public: | |||
| 57 | return num_pages; | 57 | return num_pages; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | bool IsEqual(KPageLinkedList& other) const { | 60 | bool IsEqual(KPageGroup& other) const { |
| 61 | auto this_node = nodes.begin(); | 61 | auto this_node = nodes.begin(); |
| 62 | auto other_node = other.nodes.begin(); | 62 | auto other_node = other.nodes.begin(); |
| 63 | while (this_node != nodes.end() && other_node != other.nodes.end()) { | 63 | while (this_node != nodes.end() && other_node != other.nodes.end()) { |
| @@ -72,7 +72,7 @@ public: | |||
| 72 | return this_node == nodes.end() && other_node == other.nodes.end(); | 72 | return this_node == nodes.end() && other_node == other.nodes.end(); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | ResultCode AddBlock(u64 address, u64 num_pages) { | 75 | Result AddBlock(u64 address, u64 num_pages) { |
| 76 | if (!num_pages) { | 76 | if (!num_pages) { |
| 77 | return ResultSuccess; | 77 | return ResultSuccess; |
| 78 | } | 78 | } |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index b38ef333b..d975de844 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/kernel/k_address_space_info.h" | 9 | #include "core/hle/kernel/k_address_space_info.h" |
| 10 | #include "core/hle/kernel/k_memory_block.h" | 10 | #include "core/hle/kernel/k_memory_block.h" |
| 11 | #include "core/hle/kernel/k_memory_block_manager.h" | 11 | #include "core/hle/kernel/k_memory_block_manager.h" |
| 12 | #include "core/hle/kernel/k_page_linked_list.h" | 12 | #include "core/hle/kernel/k_page_group.h" |
| 13 | #include "core/hle/kernel/k_page_table.h" | 13 | #include "core/hle/kernel/k_page_table.h" |
| 14 | #include "core/hle/kernel/k_process.h" | 14 | #include "core/hle/kernel/k_process.h" |
| 15 | #include "core/hle/kernel/k_resource_limit.h" | 15 | #include "core/hle/kernel/k_resource_limit.h" |
| @@ -35,7 +35,7 @@ constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceT | |||
| 35 | case FileSys::ProgramAddressSpaceType::Is39Bit: | 35 | case FileSys::ProgramAddressSpaceType::Is39Bit: |
| 36 | return 39; | 36 | return 39; |
| 37 | default: | 37 | default: |
| 38 | UNREACHABLE(); | 38 | ASSERT(false); |
| 39 | return {}; | 39 | return {}; |
| 40 | } | 40 | } |
| 41 | } | 41 | } |
| @@ -47,9 +47,9 @@ KPageTable::KPageTable(Core::System& system_) | |||
| 47 | 47 | ||
| 48 | KPageTable::~KPageTable() = default; | 48 | KPageTable::~KPageTable() = default; |
| 49 | 49 | ||
| 50 | ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, | 50 | Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, |
| 51 | bool enable_aslr, VAddr code_addr, | 51 | VAddr code_addr, std::size_t code_size, |
| 52 | std::size_t code_size, KMemoryManager::Pool pool) { | 52 | KMemoryManager::Pool pool) { |
| 53 | 53 | ||
| 54 | const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { | 54 | const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) { |
| 55 | return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); | 55 | return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); |
| @@ -65,7 +65,6 @@ ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_ | |||
| 65 | std::size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)}; | 65 | std::size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)}; |
| 66 | std::size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)}; | 66 | std::size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)}; |
| 67 | 67 | ||
| 68 | ASSERT(start <= code_addr); | ||
| 69 | ASSERT(code_addr < code_addr + code_size); | 68 | ASSERT(code_addr < code_addr + code_size); |
| 70 | ASSERT(code_addr + code_size - 1 <= end - 1); | 69 | ASSERT(code_addr + code_size - 1 <= end - 1); |
| 71 | 70 | ||
| @@ -128,7 +127,7 @@ ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_ | |||
| 128 | const std::size_t needed_size{ | 127 | const std::size_t needed_size{ |
| 129 | (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size)}; | 128 | (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size)}; |
| 130 | if (alloc_size < needed_size) { | 129 | if (alloc_size < needed_size) { |
| 131 | UNREACHABLE(); | 130 | ASSERT(false); |
| 132 | return ResultOutOfMemory; | 131 | return ResultOutOfMemory; |
| 133 | } | 132 | } |
| 134 | 133 | ||
| @@ -258,8 +257,8 @@ ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_ | |||
| 258 | return InitializeMemoryLayout(start, end); | 257 | return InitializeMemoryLayout(start, end); |
| 259 | } | 258 | } |
| 260 | 259 | ||
| 261 | ResultCode KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryState state, | 260 | Result KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryState state, |
| 262 | KMemoryPermission perm) { | 261 | KMemoryPermission perm) { |
| 263 | const u64 size{num_pages * PageSize}; | 262 | const u64 size{num_pages * PageSize}; |
| 264 | 263 | ||
| 265 | // Validate the mapping request. | 264 | // Validate the mapping request. |
| @@ -272,7 +271,7 @@ ResultCode KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemory | |||
| 272 | R_TRY(this->CheckMemoryState(addr, size, KMemoryState::All, KMemoryState::Free, | 271 | R_TRY(this->CheckMemoryState(addr, size, KMemoryState::All, KMemoryState::Free, |
| 273 | KMemoryPermission::None, KMemoryPermission::None, | 272 | KMemoryPermission::None, KMemoryPermission::None, |
| 274 | KMemoryAttribute::None, KMemoryAttribute::None)); | 273 | KMemoryAttribute::None, KMemoryAttribute::None)); |
| 275 | KPageLinkedList pg; | 274 | KPageGroup pg; |
| 276 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpen( | 275 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpen( |
| 277 | &pg, num_pages, | 276 | &pg, num_pages, |
| 278 | KMemoryManager::EncodeOption(KMemoryManager::Pool::Application, allocation_option))); | 277 | KMemoryManager::EncodeOption(KMemoryManager::Pool::Application, allocation_option))); |
| @@ -284,7 +283,7 @@ ResultCode KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemory | |||
| 284 | return ResultSuccess; | 283 | return ResultSuccess; |
| 285 | } | 284 | } |
| 286 | 285 | ||
| 287 | ResultCode KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size) { | 286 | Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size) { |
| 288 | // Validate the mapping request. | 287 | // Validate the mapping request. |
| 289 | R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), | 288 | R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), |
| 290 | ResultInvalidMemoryRegion); | 289 | ResultInvalidMemoryRegion); |
| @@ -314,7 +313,7 @@ ResultCode KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std:: | |||
| 314 | const std::size_t num_pages = size / PageSize; | 313 | const std::size_t num_pages = size / PageSize; |
| 315 | 314 | ||
| 316 | // Create page groups for the memory being mapped. | 315 | // Create page groups for the memory being mapped. |
| 317 | KPageLinkedList pg; | 316 | KPageGroup pg; |
| 318 | AddRegionToPages(src_address, num_pages, pg); | 317 | AddRegionToPages(src_address, num_pages, pg); |
| 319 | 318 | ||
| 320 | // Reprotect the source as kernel-read/not mapped. | 319 | // Reprotect the source as kernel-read/not mapped. |
| @@ -345,8 +344,8 @@ ResultCode KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std:: | |||
| 345 | return ResultSuccess; | 344 | return ResultSuccess; |
| 346 | } | 345 | } |
| 347 | 346 | ||
| 348 | ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size, | 347 | Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size, |
| 349 | ICacheInvalidationStrategy icache_invalidation_strategy) { | 348 | ICacheInvalidationStrategy icache_invalidation_strategy) { |
| 350 | // Validate the mapping request. | 349 | // Validate the mapping request. |
| 351 | R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), | 350 | R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), |
| 352 | ResultInvalidMemoryRegion); | 351 | ResultInvalidMemoryRegion); |
| @@ -490,7 +489,7 @@ VAddr KPageTable::FindFreeArea(VAddr region_start, std::size_t region_num_pages, | |||
| 490 | return address; | 489 | return address; |
| 491 | } | 490 | } |
| 492 | 491 | ||
| 493 | ResultCode KPageTable::MakePageGroup(KPageLinkedList& pg, VAddr addr, size_t num_pages) { | 492 | Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) { |
| 494 | ASSERT(this->IsLockedByCurrentThread()); | 493 | ASSERT(this->IsLockedByCurrentThread()); |
| 495 | 494 | ||
| 496 | const size_t size = num_pages * PageSize; | 495 | const size_t size = num_pages * PageSize; |
| @@ -542,8 +541,97 @@ ResultCode KPageTable::MakePageGroup(KPageLinkedList& pg, VAddr addr, size_t num | |||
| 542 | return ResultSuccess; | 541 | return ResultSuccess; |
| 543 | } | 542 | } |
| 544 | 543 | ||
| 545 | ResultCode KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, | 544 | bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t num_pages) { |
| 546 | KPageTable& src_page_table, VAddr src_addr) { | 545 | ASSERT(this->IsLockedByCurrentThread()); |
| 546 | |||
| 547 | const size_t size = num_pages * PageSize; | ||
| 548 | const auto& pg = pg_ll.Nodes(); | ||
| 549 | const auto& memory_layout = system.Kernel().MemoryLayout(); | ||
| 550 | |||
| 551 | // Empty groups are necessarily invalid. | ||
| 552 | if (pg.empty()) { | ||
| 553 | return false; | ||
| 554 | } | ||
| 555 | |||
| 556 | // We're going to validate that the group we'd expect is the group we see. | ||
| 557 | auto cur_it = pg.begin(); | ||
| 558 | PAddr cur_block_address = cur_it->GetAddress(); | ||
| 559 | size_t cur_block_pages = cur_it->GetNumPages(); | ||
| 560 | |||
| 561 | auto UpdateCurrentIterator = [&]() { | ||
| 562 | if (cur_block_pages == 0) { | ||
| 563 | if ((++cur_it) == pg.end()) { | ||
| 564 | return false; | ||
| 565 | } | ||
| 566 | |||
| 567 | cur_block_address = cur_it->GetAddress(); | ||
| 568 | cur_block_pages = cur_it->GetNumPages(); | ||
| 569 | } | ||
| 570 | return true; | ||
| 571 | }; | ||
| 572 | |||
| 573 | // Begin traversal. | ||
| 574 | Common::PageTable::TraversalContext context; | ||
| 575 | Common::PageTable::TraversalEntry next_entry; | ||
| 576 | if (!page_table_impl.BeginTraversal(next_entry, context, addr)) { | ||
| 577 | return false; | ||
| 578 | } | ||
| 579 | |||
| 580 | // Prepare tracking variables. | ||
| 581 | PAddr cur_addr = next_entry.phys_addr; | ||
| 582 | size_t cur_size = next_entry.block_size - (cur_addr & (next_entry.block_size - 1)); | ||
| 583 | size_t tot_size = cur_size; | ||
| 584 | |||
| 585 | // Iterate, comparing expected to actual. | ||
| 586 | while (tot_size < size) { | ||
| 587 | if (!page_table_impl.ContinueTraversal(next_entry, context)) { | ||
| 588 | return false; | ||
| 589 | } | ||
| 590 | |||
| 591 | if (next_entry.phys_addr != (cur_addr + cur_size)) { | ||
| 592 | const size_t cur_pages = cur_size / PageSize; | ||
| 593 | |||
| 594 | if (!IsHeapPhysicalAddress(memory_layout, cur_addr)) { | ||
| 595 | return false; | ||
| 596 | } | ||
| 597 | |||
| 598 | if (!UpdateCurrentIterator()) { | ||
| 599 | return false; | ||
| 600 | } | ||
| 601 | |||
| 602 | if (cur_block_address != cur_addr || cur_block_pages < cur_pages) { | ||
| 603 | return false; | ||
| 604 | } | ||
| 605 | |||
| 606 | cur_block_address += cur_size; | ||
| 607 | cur_block_pages -= cur_pages; | ||
| 608 | cur_addr = next_entry.phys_addr; | ||
| 609 | cur_size = next_entry.block_size; | ||
| 610 | } else { | ||
| 611 | cur_size += next_entry.block_size; | ||
| 612 | } | ||
| 613 | |||
| 614 | tot_size += next_entry.block_size; | ||
| 615 | } | ||
| 616 | |||
| 617 | // Ensure we compare the right amount for the last block. | ||
| 618 | if (tot_size > size) { | ||
| 619 | cur_size -= (tot_size - size); | ||
| 620 | } | ||
| 621 | |||
| 622 | if (!IsHeapPhysicalAddress(memory_layout, cur_addr)) { | ||
| 623 | return false; | ||
| 624 | } | ||
| 625 | |||
| 626 | if (!UpdateCurrentIterator()) { | ||
| 627 | return false; | ||
| 628 | } | ||
| 629 | |||
| 630 | return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize); | ||
| 631 | } | ||
| 632 | |||
| 633 | Result KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, | ||
| 634 | VAddr src_addr) { | ||
| 547 | KScopedLightLock lk(general_lock); | 635 | KScopedLightLock lk(general_lock); |
| 548 | 636 | ||
| 549 | const std::size_t num_pages{size / PageSize}; | 637 | const std::size_t num_pages{size / PageSize}; |
| @@ -572,7 +660,7 @@ ResultCode KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, | |||
| 572 | return ResultSuccess; | 660 | return ResultSuccess; |
| 573 | } | 661 | } |
| 574 | 662 | ||
| 575 | ResultCode KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) { | 663 | Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) { |
| 576 | // Lock the physical memory lock. | 664 | // Lock the physical memory lock. |
| 577 | KScopedLightLock map_phys_mem_lk(map_physical_memory_lock); | 665 | KScopedLightLock map_phys_mem_lk(map_physical_memory_lock); |
| 578 | 666 | ||
| @@ -633,7 +721,7 @@ ResultCode KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) { | |||
| 633 | R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); | 721 | R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); |
| 634 | 722 | ||
| 635 | // Allocate pages for the new memory. | 723 | // Allocate pages for the new memory. |
| 636 | KPageLinkedList pg; | 724 | KPageGroup pg; |
| 637 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpenForProcess( | 725 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpenForProcess( |
| 638 | &pg, (size - mapped_size) / PageSize, | 726 | &pg, (size - mapped_size) / PageSize, |
| 639 | KMemoryManager::EncodeOption(memory_pool, allocation_option), 0, 0)); | 727 | KMemoryManager::EncodeOption(memory_pool, allocation_option), 0, 0)); |
| @@ -815,7 +903,7 @@ ResultCode KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) { | |||
| 815 | } | 903 | } |
| 816 | } | 904 | } |
| 817 | 905 | ||
| 818 | ResultCode KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) { | 906 | Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) { |
| 819 | // Lock the physical memory lock. | 907 | // Lock the physical memory lock. |
| 820 | KScopedLightLock map_phys_mem_lk(map_physical_memory_lock); | 908 | KScopedLightLock map_phys_mem_lk(map_physical_memory_lock); |
| 821 | 909 | ||
| @@ -884,7 +972,7 @@ ResultCode KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) { | |||
| 884 | } | 972 | } |
| 885 | 973 | ||
| 886 | // Make a page group for the unmap region. | 974 | // Make a page group for the unmap region. |
| 887 | KPageLinkedList pg; | 975 | KPageGroup pg; |
| 888 | { | 976 | { |
| 889 | auto& impl = this->PageTableImpl(); | 977 | auto& impl = this->PageTableImpl(); |
| 890 | 978 | ||
| @@ -1046,7 +1134,7 @@ ResultCode KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) { | |||
| 1046 | return ResultSuccess; | 1134 | return ResultSuccess; |
| 1047 | } | 1135 | } |
| 1048 | 1136 | ||
| 1049 | ResultCode KPageTable::MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) { | 1137 | Result KPageTable::MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) { |
| 1050 | KScopedLightLock lk(general_lock); | 1138 | KScopedLightLock lk(general_lock); |
| 1051 | 1139 | ||
| 1052 | KMemoryState src_state{}; | 1140 | KMemoryState src_state{}; |
| @@ -1059,7 +1147,7 @@ ResultCode KPageTable::MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t siz | |||
| 1059 | return ResultInvalidCurrentMemory; | 1147 | return ResultInvalidCurrentMemory; |
| 1060 | } | 1148 | } |
| 1061 | 1149 | ||
| 1062 | KPageLinkedList page_linked_list; | 1150 | KPageGroup page_linked_list; |
| 1063 | const std::size_t num_pages{size / PageSize}; | 1151 | const std::size_t num_pages{size / PageSize}; |
| 1064 | 1152 | ||
| 1065 | AddRegionToPages(src_addr, num_pages, page_linked_list); | 1153 | AddRegionToPages(src_addr, num_pages, page_linked_list); |
| @@ -1085,7 +1173,7 @@ ResultCode KPageTable::MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t siz | |||
| 1085 | return ResultSuccess; | 1173 | return ResultSuccess; |
| 1086 | } | 1174 | } |
| 1087 | 1175 | ||
| 1088 | ResultCode KPageTable::UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) { | 1176 | Result KPageTable::UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) { |
| 1089 | KScopedLightLock lk(general_lock); | 1177 | KScopedLightLock lk(general_lock); |
| 1090 | 1178 | ||
| 1091 | KMemoryState src_state{}; | 1179 | KMemoryState src_state{}; |
| @@ -1100,8 +1188,8 @@ ResultCode KPageTable::UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t s | |||
| 1100 | KMemoryPermission::None, KMemoryAttribute::Mask, | 1188 | KMemoryPermission::None, KMemoryAttribute::Mask, |
| 1101 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); | 1189 | KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); |
| 1102 | 1190 | ||
| 1103 | KPageLinkedList src_pages; | 1191 | KPageGroup src_pages; |
| 1104 | KPageLinkedList dst_pages; | 1192 | KPageGroup dst_pages; |
| 1105 | const std::size_t num_pages{size / PageSize}; | 1193 | const std::size_t num_pages{size / PageSize}; |
| 1106 | 1194 | ||
| 1107 | AddRegionToPages(src_addr, num_pages, src_pages); | 1195 | AddRegionToPages(src_addr, num_pages, src_pages); |
| @@ -1127,8 +1215,8 @@ ResultCode KPageTable::UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t s | |||
| 1127 | return ResultSuccess; | 1215 | return ResultSuccess; |
| 1128 | } | 1216 | } |
| 1129 | 1217 | ||
| 1130 | ResultCode KPageTable::MapPages(VAddr addr, const KPageLinkedList& page_linked_list, | 1218 | Result KPageTable::MapPages(VAddr addr, const KPageGroup& page_linked_list, |
| 1131 | KMemoryPermission perm) { | 1219 | KMemoryPermission perm) { |
| 1132 | ASSERT(this->IsLockedByCurrentThread()); | 1220 | ASSERT(this->IsLockedByCurrentThread()); |
| 1133 | 1221 | ||
| 1134 | VAddr cur_addr{addr}; | 1222 | VAddr cur_addr{addr}; |
| @@ -1151,8 +1239,8 @@ ResultCode KPageTable::MapPages(VAddr addr, const KPageLinkedList& page_linked_l | |||
| 1151 | return ResultSuccess; | 1239 | return ResultSuccess; |
| 1152 | } | 1240 | } |
| 1153 | 1241 | ||
| 1154 | ResultCode KPageTable::MapPages(VAddr address, KPageLinkedList& page_linked_list, | 1242 | Result KPageTable::MapPages(VAddr address, KPageGroup& page_linked_list, KMemoryState state, |
| 1155 | KMemoryState state, KMemoryPermission perm) { | 1243 | KMemoryPermission perm) { |
| 1156 | // Check that the map is in range. | 1244 | // Check that the map is in range. |
| 1157 | const std::size_t num_pages{page_linked_list.GetNumPages()}; | 1245 | const std::size_t num_pages{page_linked_list.GetNumPages()}; |
| 1158 | const std::size_t size{num_pages * PageSize}; | 1246 | const std::size_t size{num_pages * PageSize}; |
| @@ -1175,10 +1263,10 @@ ResultCode KPageTable::MapPages(VAddr address, KPageLinkedList& page_linked_list | |||
| 1175 | return ResultSuccess; | 1263 | return ResultSuccess; |
| 1176 | } | 1264 | } |
| 1177 | 1265 | ||
| 1178 | ResultCode KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, | 1266 | Result KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, |
| 1179 | PAddr phys_addr, bool is_pa_valid, VAddr region_start, | 1267 | PAddr phys_addr, bool is_pa_valid, VAddr region_start, |
| 1180 | std::size_t region_num_pages, KMemoryState state, | 1268 | std::size_t region_num_pages, KMemoryState state, |
| 1181 | KMemoryPermission perm) { | 1269 | KMemoryPermission perm) { |
| 1182 | ASSERT(Common::IsAligned(alignment, PageSize) && alignment >= PageSize); | 1270 | ASSERT(Common::IsAligned(alignment, PageSize) && alignment >= PageSize); |
| 1183 | 1271 | ||
| 1184 | // Ensure this is a valid map request. | 1272 | // Ensure this is a valid map request. |
| @@ -1215,7 +1303,7 @@ ResultCode KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::siz | |||
| 1215 | return ResultSuccess; | 1303 | return ResultSuccess; |
| 1216 | } | 1304 | } |
| 1217 | 1305 | ||
| 1218 | ResultCode KPageTable::UnmapPages(VAddr addr, const KPageLinkedList& page_linked_list) { | 1306 | Result KPageTable::UnmapPages(VAddr addr, const KPageGroup& page_linked_list) { |
| 1219 | ASSERT(this->IsLockedByCurrentThread()); | 1307 | ASSERT(this->IsLockedByCurrentThread()); |
| 1220 | 1308 | ||
| 1221 | VAddr cur_addr{addr}; | 1309 | VAddr cur_addr{addr}; |
| @@ -1233,8 +1321,7 @@ ResultCode KPageTable::UnmapPages(VAddr addr, const KPageLinkedList& page_linked | |||
| 1233 | return ResultSuccess; | 1321 | return ResultSuccess; |
| 1234 | } | 1322 | } |
| 1235 | 1323 | ||
| 1236 | ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, | 1324 | Result KPageTable::UnmapPages(VAddr addr, KPageGroup& page_linked_list, KMemoryState state) { |
| 1237 | KMemoryState state) { | ||
| 1238 | // Check that the unmap is in range. | 1325 | // Check that the unmap is in range. |
| 1239 | const std::size_t num_pages{page_linked_list.GetNumPages()}; | 1326 | const std::size_t num_pages{page_linked_list.GetNumPages()}; |
| 1240 | const std::size_t size{num_pages * PageSize}; | 1327 | const std::size_t size{num_pages * PageSize}; |
| @@ -1257,7 +1344,7 @@ ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, | |||
| 1257 | return ResultSuccess; | 1344 | return ResultSuccess; |
| 1258 | } | 1345 | } |
| 1259 | 1346 | ||
| 1260 | ResultCode KPageTable::UnmapPages(VAddr address, std::size_t num_pages, KMemoryState state) { | 1347 | Result KPageTable::UnmapPages(VAddr address, std::size_t num_pages, KMemoryState state) { |
| 1261 | // Check that the unmap is in range. | 1348 | // Check that the unmap is in range. |
| 1262 | const std::size_t size = num_pages * PageSize; | 1349 | const std::size_t size = num_pages * PageSize; |
| 1263 | R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); | 1350 | R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory); |
| @@ -1281,10 +1368,10 @@ ResultCode KPageTable::UnmapPages(VAddr address, std::size_t num_pages, KMemoryS | |||
| 1281 | return ResultSuccess; | 1368 | return ResultSuccess; |
| 1282 | } | 1369 | } |
| 1283 | 1370 | ||
| 1284 | ResultCode KPageTable::MakeAndOpenPageGroup(KPageLinkedList* out, VAddr address, size_t num_pages, | 1371 | Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages, |
| 1285 | KMemoryState state_mask, KMemoryState state, | 1372 | KMemoryState state_mask, KMemoryState state, |
| 1286 | KMemoryPermission perm_mask, KMemoryPermission perm, | 1373 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 1287 | KMemoryAttribute attr_mask, KMemoryAttribute attr) { | 1374 | KMemoryAttribute attr_mask, KMemoryAttribute attr) { |
| 1288 | // Ensure that the page group isn't null. | 1375 | // Ensure that the page group isn't null. |
| 1289 | ASSERT(out != nullptr); | 1376 | ASSERT(out != nullptr); |
| 1290 | 1377 | ||
| @@ -1306,8 +1393,8 @@ ResultCode KPageTable::MakeAndOpenPageGroup(KPageLinkedList* out, VAddr address, | |||
| 1306 | return ResultSuccess; | 1393 | return ResultSuccess; |
| 1307 | } | 1394 | } |
| 1308 | 1395 | ||
| 1309 | ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, | 1396 | Result KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, |
| 1310 | Svc::MemoryPermission svc_perm) { | 1397 | Svc::MemoryPermission svc_perm) { |
| 1311 | const size_t num_pages = size / PageSize; | 1398 | const size_t num_pages = size / PageSize; |
| 1312 | 1399 | ||
| 1313 | // Lock the table. | 1400 | // Lock the table. |
| @@ -1341,7 +1428,7 @@ ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, | |||
| 1341 | new_state = KMemoryState::AliasCodeData; | 1428 | new_state = KMemoryState::AliasCodeData; |
| 1342 | break; | 1429 | break; |
| 1343 | default: | 1430 | default: |
| 1344 | UNREACHABLE(); | 1431 | ASSERT(false); |
| 1345 | } | 1432 | } |
| 1346 | } | 1433 | } |
| 1347 | 1434 | ||
| @@ -1379,7 +1466,7 @@ KMemoryInfo KPageTable::QueryInfo(VAddr addr) { | |||
| 1379 | return QueryInfoImpl(addr); | 1466 | return QueryInfoImpl(addr); |
| 1380 | } | 1467 | } |
| 1381 | 1468 | ||
| 1382 | ResultCode KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm) { | 1469 | Result KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm) { |
| 1383 | KScopedLightLock lk(general_lock); | 1470 | KScopedLightLock lk(general_lock); |
| 1384 | 1471 | ||
| 1385 | KMemoryState state{}; | 1472 | KMemoryState state{}; |
| @@ -1397,7 +1484,7 @@ ResultCode KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemo | |||
| 1397 | return ResultSuccess; | 1484 | return ResultSuccess; |
| 1398 | } | 1485 | } |
| 1399 | 1486 | ||
| 1400 | ResultCode KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | 1487 | Result KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) { |
| 1401 | KScopedLightLock lk(general_lock); | 1488 | KScopedLightLock lk(general_lock); |
| 1402 | 1489 | ||
| 1403 | KMemoryState state{}; | 1490 | KMemoryState state{}; |
| @@ -1412,8 +1499,8 @@ ResultCode KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | |||
| 1412 | return ResultSuccess; | 1499 | return ResultSuccess; |
| 1413 | } | 1500 | } |
| 1414 | 1501 | ||
| 1415 | ResultCode KPageTable::SetMemoryPermission(VAddr addr, std::size_t size, | 1502 | Result KPageTable::SetMemoryPermission(VAddr addr, std::size_t size, |
| 1416 | Svc::MemoryPermission svc_perm) { | 1503 | Svc::MemoryPermission svc_perm) { |
| 1417 | const size_t num_pages = size / PageSize; | 1504 | const size_t num_pages = size / PageSize; |
| 1418 | 1505 | ||
| 1419 | // Lock the table. | 1506 | // Lock the table. |
| @@ -1440,7 +1527,7 @@ ResultCode KPageTable::SetMemoryPermission(VAddr addr, std::size_t size, | |||
| 1440 | return ResultSuccess; | 1527 | return ResultSuccess; |
| 1441 | } | 1528 | } |
| 1442 | 1529 | ||
| 1443 | ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr) { | 1530 | Result KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr) { |
| 1444 | const size_t num_pages = size / PageSize; | 1531 | const size_t num_pages = size / PageSize; |
| 1445 | ASSERT((static_cast<KMemoryAttribute>(mask) | KMemoryAttribute::SetMask) == | 1532 | ASSERT((static_cast<KMemoryAttribute>(mask) | KMemoryAttribute::SetMask) == |
| 1446 | KMemoryAttribute::SetMask); | 1533 | KMemoryAttribute::SetMask); |
| @@ -1475,7 +1562,7 @@ ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask | |||
| 1475 | return ResultSuccess; | 1562 | return ResultSuccess; |
| 1476 | } | 1563 | } |
| 1477 | 1564 | ||
| 1478 | ResultCode KPageTable::SetMaxHeapSize(std::size_t size) { | 1565 | Result KPageTable::SetMaxHeapSize(std::size_t size) { |
| 1479 | // Lock the table. | 1566 | // Lock the table. |
| 1480 | KScopedLightLock lk(general_lock); | 1567 | KScopedLightLock lk(general_lock); |
| 1481 | 1568 | ||
| @@ -1487,7 +1574,7 @@ ResultCode KPageTable::SetMaxHeapSize(std::size_t size) { | |||
| 1487 | return ResultSuccess; | 1574 | return ResultSuccess; |
| 1488 | } | 1575 | } |
| 1489 | 1576 | ||
| 1490 | ResultCode KPageTable::SetHeapSize(VAddr* out, std::size_t size) { | 1577 | Result KPageTable::SetHeapSize(VAddr* out, std::size_t size) { |
| 1491 | // Lock the physical memory mutex. | 1578 | // Lock the physical memory mutex. |
| 1492 | KScopedLightLock map_phys_mem_lk(map_physical_memory_lock); | 1579 | KScopedLightLock map_phys_mem_lk(map_physical_memory_lock); |
| 1493 | 1580 | ||
| @@ -1554,7 +1641,7 @@ ResultCode KPageTable::SetHeapSize(VAddr* out, std::size_t size) { | |||
| 1554 | R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); | 1641 | R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); |
| 1555 | 1642 | ||
| 1556 | // Allocate pages for the heap extension. | 1643 | // Allocate pages for the heap extension. |
| 1557 | KPageLinkedList pg; | 1644 | KPageGroup pg; |
| 1558 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpen( | 1645 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpen( |
| 1559 | &pg, allocation_size / PageSize, | 1646 | &pg, allocation_size / PageSize, |
| 1560 | KMemoryManager::EncodeOption(memory_pool, allocation_option))); | 1647 | KMemoryManager::EncodeOption(memory_pool, allocation_option))); |
| @@ -1629,7 +1716,7 @@ ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, | |||
| 1629 | if (is_map_only) { | 1716 | if (is_map_only) { |
| 1630 | R_TRY(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); | 1717 | R_TRY(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); |
| 1631 | } else { | 1718 | } else { |
| 1632 | KPageLinkedList page_group; | 1719 | KPageGroup page_group; |
| 1633 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpenForProcess( | 1720 | R_TRY(system.Kernel().MemoryManager().AllocateAndOpenForProcess( |
| 1634 | &page_group, needed_num_pages, | 1721 | &page_group, needed_num_pages, |
| 1635 | KMemoryManager::EncodeOption(memory_pool, allocation_option), 0, 0)); | 1722 | KMemoryManager::EncodeOption(memory_pool, allocation_option), 0, 0)); |
| @@ -1641,11 +1728,11 @@ ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, | |||
| 1641 | return addr; | 1728 | return addr; |
| 1642 | } | 1729 | } |
| 1643 | 1730 | ||
| 1644 | ResultCode KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { | 1731 | Result KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { |
| 1645 | KScopedLightLock lk(general_lock); | 1732 | KScopedLightLock lk(general_lock); |
| 1646 | 1733 | ||
| 1647 | KMemoryPermission perm{}; | 1734 | KMemoryPermission perm{}; |
| 1648 | if (const ResultCode result{CheckMemoryState( | 1735 | if (const Result result{CheckMemoryState( |
| 1649 | nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, | 1736 | nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 1650 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, | 1737 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 1651 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, | 1738 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| @@ -1664,11 +1751,11 @@ ResultCode KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) { | |||
| 1664 | return ResultSuccess; | 1751 | return ResultSuccess; |
| 1665 | } | 1752 | } |
| 1666 | 1753 | ||
| 1667 | ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) { | 1754 | Result KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) { |
| 1668 | KScopedLightLock lk(general_lock); | 1755 | KScopedLightLock lk(general_lock); |
| 1669 | 1756 | ||
| 1670 | KMemoryPermission perm{}; | 1757 | KMemoryPermission perm{}; |
| 1671 | if (const ResultCode result{CheckMemoryState( | 1758 | if (const Result result{CheckMemoryState( |
| 1672 | nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, | 1759 | nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute, |
| 1673 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, | 1760 | KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None, |
| 1674 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, | 1761 | KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None, |
| @@ -1687,25 +1774,24 @@ ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) | |||
| 1687 | return ResultSuccess; | 1774 | return ResultSuccess; |
| 1688 | } | 1775 | } |
| 1689 | 1776 | ||
| 1690 | ResultCode KPageTable::LockForCodeMemory(VAddr addr, std::size_t size) { | 1777 | Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, std::size_t size) { |
| 1691 | return this->LockMemoryAndOpen( | 1778 | return this->LockMemoryAndOpen( |
| 1692 | nullptr, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, | 1779 | out, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory, |
| 1693 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::All, KMemoryPermission::UserReadWrite, | 1780 | KMemoryPermission::All, KMemoryPermission::UserReadWrite, KMemoryAttribute::All, |
| 1694 | KMemoryAttribute::All, KMemoryAttribute::None, | 1781 | KMemoryAttribute::None, |
| 1695 | static_cast<KMemoryPermission>(KMemoryPermission::NotMapped | | 1782 | static_cast<KMemoryPermission>(KMemoryPermission::NotMapped | |
| 1696 | KMemoryPermission::KernelReadWrite), | 1783 | KMemoryPermission::KernelReadWrite), |
| 1697 | KMemoryAttribute::Locked); | 1784 | KMemoryAttribute::Locked); |
| 1698 | } | 1785 | } |
| 1699 | 1786 | ||
| 1700 | ResultCode KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size) { | 1787 | Result KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size, const KPageGroup& pg) { |
| 1701 | return this->UnlockMemory(addr, size, KMemoryState::FlagCanCodeMemory, | 1788 | return this->UnlockMemory( |
| 1702 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::None, | 1789 | addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory, |
| 1703 | KMemoryPermission::None, KMemoryAttribute::All, | 1790 | KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All, |
| 1704 | KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, | 1791 | KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg); |
| 1705 | KMemoryAttribute::Locked, nullptr); | ||
| 1706 | } | 1792 | } |
| 1707 | 1793 | ||
| 1708 | ResultCode KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) { | 1794 | Result KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) { |
| 1709 | block_manager = std::make_unique<KMemoryBlockManager>(start, end); | 1795 | block_manager = std::make_unique<KMemoryBlockManager>(start, end); |
| 1710 | 1796 | ||
| 1711 | return ResultSuccess; | 1797 | return ResultSuccess; |
| @@ -1730,13 +1816,11 @@ bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const { | |||
| 1730 | } | 1816 | } |
| 1731 | 1817 | ||
| 1732 | void KPageTable::AddRegionToPages(VAddr start, std::size_t num_pages, | 1818 | void KPageTable::AddRegionToPages(VAddr start, std::size_t num_pages, |
| 1733 | KPageLinkedList& page_linked_list) { | 1819 | KPageGroup& page_linked_list) { |
| 1734 | VAddr addr{start}; | 1820 | VAddr addr{start}; |
| 1735 | while (addr < start + (num_pages * PageSize)) { | 1821 | while (addr < start + (num_pages * PageSize)) { |
| 1736 | const PAddr paddr{GetPhysicalAddr(addr)}; | 1822 | const PAddr paddr{GetPhysicalAddr(addr)}; |
| 1737 | if (!paddr) { | 1823 | ASSERT(paddr != 0); |
| 1738 | UNREACHABLE(); | ||
| 1739 | } | ||
| 1740 | page_linked_list.AddBlock(paddr, 1); | 1824 | page_linked_list.AddBlock(paddr, 1); |
| 1741 | addr += PageSize; | 1825 | addr += PageSize; |
| 1742 | } | 1826 | } |
| @@ -1751,8 +1835,8 @@ VAddr KPageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_page | |||
| 1751 | IsKernel() ? 1 : 4); | 1835 | IsKernel() ? 1 : 4); |
| 1752 | } | 1836 | } |
| 1753 | 1837 | ||
| 1754 | ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageLinkedList& page_group, | 1838 | Result KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageGroup& page_group, |
| 1755 | OperationType operation) { | 1839 | OperationType operation) { |
| 1756 | ASSERT(this->IsLockedByCurrentThread()); | 1840 | ASSERT(this->IsLockedByCurrentThread()); |
| 1757 | 1841 | ||
| 1758 | ASSERT(Common::IsAligned(addr, PageSize)); | 1842 | ASSERT(Common::IsAligned(addr, PageSize)); |
| @@ -1767,7 +1851,7 @@ ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageLin | |||
| 1767 | system.Memory().MapMemoryRegion(page_table_impl, addr, size, node.GetAddress()); | 1851 | system.Memory().MapMemoryRegion(page_table_impl, addr, size, node.GetAddress()); |
| 1768 | break; | 1852 | break; |
| 1769 | default: | 1853 | default: |
| 1770 | UNREACHABLE(); | 1854 | ASSERT(false); |
| 1771 | } | 1855 | } |
| 1772 | 1856 | ||
| 1773 | addr += size; | 1857 | addr += size; |
| @@ -1776,8 +1860,8 @@ ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageLin | |||
| 1776 | return ResultSuccess; | 1860 | return ResultSuccess; |
| 1777 | } | 1861 | } |
| 1778 | 1862 | ||
| 1779 | ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, | 1863 | Result KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, |
| 1780 | OperationType operation, PAddr map_addr) { | 1864 | OperationType operation, PAddr map_addr) { |
| 1781 | ASSERT(this->IsLockedByCurrentThread()); | 1865 | ASSERT(this->IsLockedByCurrentThread()); |
| 1782 | 1866 | ||
| 1783 | ASSERT(num_pages > 0); | 1867 | ASSERT(num_pages > 0); |
| @@ -1798,7 +1882,7 @@ ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermiss | |||
| 1798 | case OperationType::ChangePermissionsAndRefresh: | 1882 | case OperationType::ChangePermissionsAndRefresh: |
| 1799 | break; | 1883 | break; |
| 1800 | default: | 1884 | default: |
| 1801 | UNREACHABLE(); | 1885 | ASSERT(false); |
| 1802 | } | 1886 | } |
| 1803 | return ResultSuccess; | 1887 | return ResultSuccess; |
| 1804 | } | 1888 | } |
| @@ -1835,7 +1919,6 @@ VAddr KPageTable::GetRegionAddress(KMemoryState state) const { | |||
| 1835 | return code_region_start; | 1919 | return code_region_start; |
| 1836 | default: | 1920 | default: |
| 1837 | UNREACHABLE(); | 1921 | UNREACHABLE(); |
| 1838 | return {}; | ||
| 1839 | } | 1922 | } |
| 1840 | } | 1923 | } |
| 1841 | 1924 | ||
| @@ -1871,7 +1954,6 @@ std::size_t KPageTable::GetRegionSize(KMemoryState state) const { | |||
| 1871 | return code_region_end - code_region_start; | 1954 | return code_region_end - code_region_start; |
| 1872 | default: | 1955 | default: |
| 1873 | UNREACHABLE(); | 1956 | UNREACHABLE(); |
| 1874 | return {}; | ||
| 1875 | } | 1957 | } |
| 1876 | } | 1958 | } |
| 1877 | 1959 | ||
| @@ -1921,10 +2003,10 @@ bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) co | |||
| 1921 | } | 2003 | } |
| 1922 | } | 2004 | } |
| 1923 | 2005 | ||
| 1924 | ResultCode KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, | 2006 | Result KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, |
| 1925 | KMemoryState state, KMemoryPermission perm_mask, | 2007 | KMemoryState state, KMemoryPermission perm_mask, |
| 1926 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 2008 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 1927 | KMemoryAttribute attr) const { | 2009 | KMemoryAttribute attr) const { |
| 1928 | // Validate the states match expectation. | 2010 | // Validate the states match expectation. |
| 1929 | R_UNLESS((info.state & state_mask) == state, ResultInvalidCurrentMemory); | 2011 | R_UNLESS((info.state & state_mask) == state, ResultInvalidCurrentMemory); |
| 1930 | R_UNLESS((info.perm & perm_mask) == perm, ResultInvalidCurrentMemory); | 2012 | R_UNLESS((info.perm & perm_mask) == perm, ResultInvalidCurrentMemory); |
| @@ -1933,12 +2015,11 @@ ResultCode KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState st | |||
| 1933 | return ResultSuccess; | 2015 | return ResultSuccess; |
| 1934 | } | 2016 | } |
| 1935 | 2017 | ||
| 1936 | ResultCode KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, | 2018 | Result KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, |
| 1937 | std::size_t size, KMemoryState state_mask, | 2019 | std::size_t size, KMemoryState state_mask, |
| 1938 | KMemoryState state, KMemoryPermission perm_mask, | 2020 | KMemoryState state, KMemoryPermission perm_mask, |
| 1939 | KMemoryPermission perm, | 2021 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 1940 | KMemoryAttribute attr_mask, | 2022 | KMemoryAttribute attr) const { |
| 1941 | KMemoryAttribute attr) const { | ||
| 1942 | ASSERT(this->IsLockedByCurrentThread()); | 2023 | ASSERT(this->IsLockedByCurrentThread()); |
| 1943 | 2024 | ||
| 1944 | // Get information about the first block. | 2025 | // Get information about the first block. |
| @@ -1976,12 +2057,12 @@ ResultCode KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed | |||
| 1976 | return ResultSuccess; | 2057 | return ResultSuccess; |
| 1977 | } | 2058 | } |
| 1978 | 2059 | ||
| 1979 | ResultCode KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | 2060 | Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 1980 | KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, | 2061 | KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, |
| 1981 | VAddr addr, std::size_t size, KMemoryState state_mask, | 2062 | VAddr addr, std::size_t size, KMemoryState state_mask, |
| 1982 | KMemoryState state, KMemoryPermission perm_mask, | 2063 | KMemoryState state, KMemoryPermission perm_mask, |
| 1983 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 2064 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 1984 | KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { | 2065 | KMemoryAttribute attr, KMemoryAttribute ignore_attr) const { |
| 1985 | ASSERT(this->IsLockedByCurrentThread()); | 2066 | ASSERT(this->IsLockedByCurrentThread()); |
| 1986 | 2067 | ||
| 1987 | // Get information about the first block. | 2068 | // Get information about the first block. |
| @@ -2038,11 +2119,11 @@ ResultCode KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermissi | |||
| 2038 | return ResultSuccess; | 2119 | return ResultSuccess; |
| 2039 | } | 2120 | } |
| 2040 | 2121 | ||
| 2041 | ResultCode KPageTable::LockMemoryAndOpen(KPageLinkedList* out_pg, PAddr* out_paddr, VAddr addr, | 2122 | Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size, |
| 2042 | size_t size, KMemoryState state_mask, KMemoryState state, | 2123 | KMemoryState state_mask, KMemoryState state, |
| 2043 | KMemoryPermission perm_mask, KMemoryPermission perm, | 2124 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 2044 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | 2125 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 2045 | KMemoryPermission new_perm, KMemoryAttribute lock_attr) { | 2126 | KMemoryPermission new_perm, KMemoryAttribute lock_attr) { |
| 2046 | // Validate basic preconditions. | 2127 | // Validate basic preconditions. |
| 2047 | ASSERT((lock_attr & attr) == KMemoryAttribute::None); | 2128 | ASSERT((lock_attr & attr) == KMemoryAttribute::None); |
| 2048 | ASSERT((lock_attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) == | 2129 | ASSERT((lock_attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) == |
| @@ -2096,11 +2177,11 @@ ResultCode KPageTable::LockMemoryAndOpen(KPageLinkedList* out_pg, PAddr* out_pad | |||
| 2096 | return ResultSuccess; | 2177 | return ResultSuccess; |
| 2097 | } | 2178 | } |
| 2098 | 2179 | ||
| 2099 | ResultCode KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, | 2180 | Result KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, |
| 2100 | KMemoryState state, KMemoryPermission perm_mask, | 2181 | KMemoryState state, KMemoryPermission perm_mask, |
| 2101 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 2182 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 2102 | KMemoryAttribute attr, KMemoryPermission new_perm, | 2183 | KMemoryAttribute attr, KMemoryPermission new_perm, |
| 2103 | KMemoryAttribute lock_attr, const KPageLinkedList* pg) { | 2184 | KMemoryAttribute lock_attr, const KPageGroup* pg) { |
| 2104 | // Validate basic preconditions. | 2185 | // Validate basic preconditions. |
| 2105 | ASSERT((attr_mask & lock_attr) == lock_attr); | 2186 | ASSERT((attr_mask & lock_attr) == lock_attr); |
| 2106 | ASSERT((attr & lock_attr) == lock_attr); | 2187 | ASSERT((attr & lock_attr) == lock_attr); |
| @@ -2125,7 +2206,7 @@ ResultCode KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_ | |||
| 2125 | 2206 | ||
| 2126 | // Check the page group. | 2207 | // Check the page group. |
| 2127 | if (pg != nullptr) { | 2208 | if (pg != nullptr) { |
| 2128 | UNIMPLEMENTED_MSG("PageGroup support is unimplemented!"); | 2209 | R_UNLESS(this->IsValidPageGroup(*pg, addr, num_pages), ResultInvalidMemoryRegion); |
| 2129 | } | 2210 | } |
| 2130 | 2211 | ||
| 2131 | // Decide on new perm and attr. | 2212 | // Decide on new perm and attr. |
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 52a93ce86..25774f232 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -33,51 +33,49 @@ public: | |||
| 33 | explicit KPageTable(Core::System& system_); | 33 | explicit KPageTable(Core::System& system_); |
| 34 | ~KPageTable(); | 34 | ~KPageTable(); |
| 35 | 35 | ||
| 36 | ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, | 36 | Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr, |
| 37 | VAddr code_addr, std::size_t code_size, | 37 | VAddr code_addr, std::size_t code_size, KMemoryManager::Pool pool); |
| 38 | KMemoryManager::Pool pool); | 38 | Result MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, |
| 39 | ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, | 39 | KMemoryPermission perm); |
| 40 | KMemoryPermission perm); | 40 | Result MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); |
| 41 | ResultCode MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); | 41 | Result UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size, |
| 42 | ResultCode UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size, | 42 | ICacheInvalidationStrategy icache_invalidation_strategy); |
| 43 | ICacheInvalidationStrategy icache_invalidation_strategy); | 43 | Result UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, |
| 44 | ResultCode UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, | 44 | VAddr src_addr); |
| 45 | VAddr src_addr); | 45 | Result MapPhysicalMemory(VAddr addr, std::size_t size); |
| 46 | ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); | 46 | Result UnmapPhysicalMemory(VAddr addr, std::size_t size); |
| 47 | ResultCode UnmapPhysicalMemory(VAddr addr, std::size_t size); | 47 | Result MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 48 | ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); | 48 | Result UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 49 | ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); | 49 | Result MapPages(VAddr addr, KPageGroup& page_linked_list, KMemoryState state, |
| 50 | ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, | 50 | KMemoryPermission perm); |
| 51 | KMemoryPermission perm); | 51 | Result MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, PAddr phys_addr, |
| 52 | ResultCode MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, | 52 | KMemoryState state, KMemoryPermission perm) { |
| 53 | PAddr phys_addr, KMemoryState state, KMemoryPermission perm) { | ||
| 54 | return this->MapPages(out_addr, num_pages, alignment, phys_addr, true, | 53 | return this->MapPages(out_addr, num_pages, alignment, phys_addr, true, |
| 55 | this->GetRegionAddress(state), this->GetRegionSize(state) / PageSize, | 54 | this->GetRegionAddress(state), this->GetRegionSize(state) / PageSize, |
| 56 | state, perm); | 55 | state, perm); |
| 57 | } | 56 | } |
| 58 | ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state); | 57 | Result UnmapPages(VAddr addr, KPageGroup& page_linked_list, KMemoryState state); |
| 59 | ResultCode UnmapPages(VAddr address, std::size_t num_pages, KMemoryState state); | 58 | Result UnmapPages(VAddr address, std::size_t num_pages, KMemoryState state); |
| 60 | ResultCode SetProcessMemoryPermission(VAddr addr, std::size_t size, | 59 | Result SetProcessMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission svc_perm); |
| 61 | Svc::MemoryPermission svc_perm); | ||
| 62 | KMemoryInfo QueryInfo(VAddr addr); | 60 | KMemoryInfo QueryInfo(VAddr addr); |
| 63 | ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); | 61 | Result ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); |
| 64 | ResultCode ResetTransferMemory(VAddr addr, std::size_t size); | 62 | Result ResetTransferMemory(VAddr addr, std::size_t size); |
| 65 | ResultCode SetMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission perm); | 63 | Result SetMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission perm); |
| 66 | ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr); | 64 | Result SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr); |
| 67 | ResultCode SetMaxHeapSize(std::size_t size); | 65 | Result SetMaxHeapSize(std::size_t size); |
| 68 | ResultCode SetHeapSize(VAddr* out, std::size_t size); | 66 | Result SetHeapSize(VAddr* out, std::size_t size); |
| 69 | ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, | 67 | ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, |
| 70 | bool is_map_only, VAddr region_start, | 68 | bool is_map_only, VAddr region_start, |
| 71 | std::size_t region_num_pages, KMemoryState state, | 69 | std::size_t region_num_pages, KMemoryState state, |
| 72 | KMemoryPermission perm, PAddr map_addr = 0); | 70 | KMemoryPermission perm, PAddr map_addr = 0); |
| 73 | ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); | 71 | Result LockForDeviceAddressSpace(VAddr addr, std::size_t size); |
| 74 | ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); | 72 | Result UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); |
| 75 | ResultCode LockForCodeMemory(VAddr addr, std::size_t size); | 73 | Result LockForCodeMemory(KPageGroup* out, VAddr addr, std::size_t size); |
| 76 | ResultCode UnlockForCodeMemory(VAddr addr, std::size_t size); | 74 | Result UnlockForCodeMemory(VAddr addr, std::size_t size, const KPageGroup& pg); |
| 77 | ResultCode MakeAndOpenPageGroup(KPageLinkedList* out, VAddr address, size_t num_pages, | 75 | Result MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages, |
| 78 | KMemoryState state_mask, KMemoryState state, | 76 | KMemoryState state_mask, KMemoryState state, |
| 79 | KMemoryPermission perm_mask, KMemoryPermission perm, | 77 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 80 | KMemoryAttribute attr_mask, KMemoryAttribute attr); | 78 | KMemoryAttribute attr_mask, KMemoryAttribute attr); |
| 81 | 79 | ||
| 82 | Common::PageTable& PageTableImpl() { | 80 | Common::PageTable& PageTableImpl() { |
| 83 | return page_table_impl; | 81 | return page_table_impl; |
| @@ -102,82 +100,78 @@ private: | |||
| 102 | KMemoryAttribute::IpcLocked | | 100 | KMemoryAttribute::IpcLocked | |
| 103 | KMemoryAttribute::DeviceShared; | 101 | KMemoryAttribute::DeviceShared; |
| 104 | 102 | ||
| 105 | ResultCode InitializeMemoryLayout(VAddr start, VAddr end); | 103 | Result InitializeMemoryLayout(VAddr start, VAddr end); |
| 106 | ResultCode MapPages(VAddr addr, const KPageLinkedList& page_linked_list, | 104 | Result MapPages(VAddr addr, const KPageGroup& page_linked_list, KMemoryPermission perm); |
| 107 | KMemoryPermission perm); | 105 | Result MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, PAddr phys_addr, |
| 108 | ResultCode MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, | 106 | bool is_pa_valid, VAddr region_start, std::size_t region_num_pages, |
| 109 | PAddr phys_addr, bool is_pa_valid, VAddr region_start, | 107 | KMemoryState state, KMemoryPermission perm); |
| 110 | std::size_t region_num_pages, KMemoryState state, KMemoryPermission perm); | 108 | Result UnmapPages(VAddr addr, const KPageGroup& page_linked_list); |
| 111 | ResultCode UnmapPages(VAddr addr, const KPageLinkedList& page_linked_list); | ||
| 112 | bool IsRegionMapped(VAddr address, u64 size); | 109 | bool IsRegionMapped(VAddr address, u64 size); |
| 113 | bool IsRegionContiguous(VAddr addr, u64 size) const; | 110 | bool IsRegionContiguous(VAddr addr, u64 size) const; |
| 114 | void AddRegionToPages(VAddr start, std::size_t num_pages, KPageLinkedList& page_linked_list); | 111 | void AddRegionToPages(VAddr start, std::size_t num_pages, KPageGroup& page_linked_list); |
| 115 | KMemoryInfo QueryInfoImpl(VAddr addr); | 112 | KMemoryInfo QueryInfoImpl(VAddr addr); |
| 116 | VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages, | 113 | VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages, |
| 117 | std::size_t align); | 114 | std::size_t align); |
| 118 | ResultCode Operate(VAddr addr, std::size_t num_pages, const KPageLinkedList& page_group, | 115 | Result Operate(VAddr addr, std::size_t num_pages, const KPageGroup& page_group, |
| 119 | OperationType operation); | 116 | OperationType operation); |
| 120 | ResultCode Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, | 117 | Result Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm, |
| 121 | OperationType operation, PAddr map_addr = 0); | 118 | OperationType operation, PAddr map_addr = 0); |
| 122 | VAddr GetRegionAddress(KMemoryState state) const; | 119 | VAddr GetRegionAddress(KMemoryState state) const; |
| 123 | std::size_t GetRegionSize(KMemoryState state) const; | 120 | std::size_t GetRegionSize(KMemoryState state) const; |
| 124 | 121 | ||
| 125 | VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages, | 122 | VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages, |
| 126 | std::size_t alignment, std::size_t offset, std::size_t guard_pages); | 123 | std::size_t alignment, std::size_t offset, std::size_t guard_pages); |
| 127 | 124 | ||
| 128 | ResultCode CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, | 125 | Result CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, std::size_t size, |
| 129 | std::size_t size, KMemoryState state_mask, | 126 | KMemoryState state_mask, KMemoryState state, |
| 130 | KMemoryState state, KMemoryPermission perm_mask, | 127 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 131 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 128 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const; |
| 132 | KMemoryAttribute attr) const; | 129 | Result CheckMemoryStateContiguous(VAddr addr, std::size_t size, KMemoryState state_mask, |
| 133 | ResultCode CheckMemoryStateContiguous(VAddr addr, std::size_t size, KMemoryState state_mask, | 130 | KMemoryState state, KMemoryPermission perm_mask, |
| 134 | KMemoryState state, KMemoryPermission perm_mask, | 131 | KMemoryPermission perm, KMemoryAttribute attr_mask, |
| 135 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 132 | KMemoryAttribute attr) const { |
| 136 | KMemoryAttribute attr) const { | ||
| 137 | return this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, | 133 | return this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, |
| 138 | perm, attr_mask, attr); | 134 | perm, attr_mask, attr); |
| 139 | } | 135 | } |
| 140 | 136 | ||
| 141 | ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, | 137 | Result CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state, |
| 142 | KMemoryState state, KMemoryPermission perm_mask, | 138 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 143 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 139 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const; |
| 144 | KMemoryAttribute attr) const; | 140 | Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, |
| 145 | ResultCode CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm, | 141 | KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, VAddr addr, |
| 146 | KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, | 142 | std::size_t size, KMemoryState state_mask, KMemoryState state, |
| 147 | VAddr addr, std::size_t size, KMemoryState state_mask, | 143 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 148 | KMemoryState state, KMemoryPermission perm_mask, | 144 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 149 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 145 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const; |
| 150 | KMemoryAttribute attr, | 146 | Result CheckMemoryState(std::size_t* out_blocks_needed, VAddr addr, std::size_t size, |
| 151 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const; | 147 | KMemoryState state_mask, KMemoryState state, |
| 152 | ResultCode CheckMemoryState(std::size_t* out_blocks_needed, VAddr addr, std::size_t size, | 148 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 153 | KMemoryState state_mask, KMemoryState state, | 149 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 154 | KMemoryPermission perm_mask, KMemoryPermission perm, | 150 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { |
| 155 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | ||
| 156 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { | ||
| 157 | return CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size, | 151 | return CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size, |
| 158 | state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr); | 152 | state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr); |
| 159 | } | 153 | } |
| 160 | ResultCode CheckMemoryState(VAddr addr, std::size_t size, KMemoryState state_mask, | 154 | Result CheckMemoryState(VAddr addr, std::size_t size, KMemoryState state_mask, |
| 161 | KMemoryState state, KMemoryPermission perm_mask, | 155 | KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm, |
| 162 | KMemoryPermission perm, KMemoryAttribute attr_mask, | 156 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 163 | KMemoryAttribute attr, | 157 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { |
| 164 | KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const { | ||
| 165 | return this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, | 158 | return this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, |
| 166 | attr_mask, attr, ignore_attr); | 159 | attr_mask, attr, ignore_attr); |
| 167 | } | 160 | } |
| 168 | 161 | ||
| 169 | ResultCode LockMemoryAndOpen(KPageLinkedList* out_pg, PAddr* out_paddr, VAddr addr, size_t size, | 162 | Result LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size, |
| 170 | KMemoryState state_mask, KMemoryState state, | 163 | KMemoryState state_mask, KMemoryState state, |
| 171 | KMemoryPermission perm_mask, KMemoryPermission perm, | 164 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 172 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | 165 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 173 | KMemoryPermission new_perm, KMemoryAttribute lock_attr); | 166 | KMemoryPermission new_perm, KMemoryAttribute lock_attr); |
| 174 | ResultCode UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state, | 167 | Result UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state, |
| 175 | KMemoryPermission perm_mask, KMemoryPermission perm, | 168 | KMemoryPermission perm_mask, KMemoryPermission perm, |
| 176 | KMemoryAttribute attr_mask, KMemoryAttribute attr, | 169 | KMemoryAttribute attr_mask, KMemoryAttribute attr, |
| 177 | KMemoryPermission new_perm, KMemoryAttribute lock_attr, | 170 | KMemoryPermission new_perm, KMemoryAttribute lock_attr, |
| 178 | const KPageLinkedList* pg); | 171 | const KPageGroup* pg); |
| 179 | 172 | ||
| 180 | ResultCode MakePageGroup(KPageLinkedList& pg, VAddr addr, size_t num_pages); | 173 | Result MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages); |
| 174 | bool IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages); | ||
| 181 | 175 | ||
| 182 | bool IsLockedByCurrentThread() const { | 176 | bool IsLockedByCurrentThread() const { |
| 183 | return general_lock.IsLockedByCurrentThread(); | 177 | return general_lock.IsLockedByCurrentThread(); |
diff --git a/src/core/hle/kernel/k_port.cpp b/src/core/hle/kernel/k_port.cpp index a31861cdb..7a5a9dc2a 100644 --- a/src/core/hle/kernel/k_port.cpp +++ b/src/core/hle/kernel/k_port.cpp | |||
| @@ -50,7 +50,7 @@ bool KPort::IsServerClosed() const { | |||
| 50 | return state == State::ServerClosed; | 50 | return state == State::ServerClosed; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | ResultCode KPort::EnqueueSession(KServerSession* session) { | 53 | Result KPort::EnqueueSession(KServerSession* session) { |
| 54 | KScopedSchedulerLock sl{kernel}; | 54 | KScopedSchedulerLock sl{kernel}; |
| 55 | 55 | ||
| 56 | R_UNLESS(state == State::Normal, ResultPortClosed); | 56 | R_UNLESS(state == State::Normal, ResultPortClosed); |
| @@ -60,7 +60,7 @@ ResultCode KPort::EnqueueSession(KServerSession* session) { | |||
| 60 | if (auto session_ptr = server.GetSessionRequestHandler().lock()) { | 60 | if (auto session_ptr = server.GetSessionRequestHandler().lock()) { |
| 61 | session_ptr->ClientConnected(server.AcceptSession()); | 61 | session_ptr->ClientConnected(server.AcceptSession()); |
| 62 | } else { | 62 | } else { |
| 63 | UNREACHABLE(); | 63 | ASSERT(false); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | return ResultSuccess; | 66 | return ResultSuccess; |
diff --git a/src/core/hle/kernel/k_port.h b/src/core/hle/kernel/k_port.h index 1bfecf8c3..0cfc16dab 100644 --- a/src/core/hle/kernel/k_port.h +++ b/src/core/hle/kernel/k_port.h | |||
| @@ -34,7 +34,7 @@ public: | |||
| 34 | 34 | ||
| 35 | bool IsServerClosed() const; | 35 | bool IsServerClosed() const; |
| 36 | 36 | ||
| 37 | ResultCode EnqueueSession(KServerSession* session); | 37 | Result EnqueueSession(KServerSession* session); |
| 38 | 38 | ||
| 39 | KClientPort& GetClientPort() { | 39 | KClientPort& GetClientPort() { |
| 40 | return client; | 40 | return client; |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index dcfeacccd..183c693e3 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -57,23 +57,18 @@ void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority | |||
| 57 | thread->GetContext64().cpu_registers[0] = 0; | 57 | thread->GetContext64().cpu_registers[0] = 0; |
| 58 | thread->GetContext32().cpu_registers[1] = thread_handle; | 58 | thread->GetContext32().cpu_registers[1] = thread_handle; |
| 59 | thread->GetContext64().cpu_registers[1] = thread_handle; | 59 | thread->GetContext64().cpu_registers[1] = thread_handle; |
| 60 | thread->DisableDispatch(); | ||
| 61 | 60 | ||
| 62 | auto& kernel = system.Kernel(); | 61 | if (system.DebuggerEnabled()) { |
| 63 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires | 62 | thread->RequestSuspend(SuspendType::Debug); |
| 64 | { | ||
| 65 | KScopedSchedulerLock lock{kernel}; | ||
| 66 | thread->SetState(ThreadState::Runnable); | ||
| 67 | |||
| 68 | if (system.DebuggerEnabled()) { | ||
| 69 | thread->RequestSuspend(SuspendType::Debug); | ||
| 70 | } | ||
| 71 | } | 63 | } |
| 64 | |||
| 65 | // Run our thread. | ||
| 66 | void(thread->Run()); | ||
| 72 | } | 67 | } |
| 73 | } // Anonymous namespace | 68 | } // Anonymous namespace |
| 74 | 69 | ||
| 75 | ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name, | 70 | Result KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name, |
| 76 | ProcessType type, KResourceLimit* res_limit) { | 71 | ProcessType type, KResourceLimit* res_limit) { |
| 77 | auto& kernel = system.Kernel(); | 72 | auto& kernel = system.Kernel(); |
| 78 | 73 | ||
| 79 | process->name = std::move(process_name); | 74 | process->name = std::move(process_name); |
| @@ -181,7 +176,8 @@ void KProcess::PinCurrentThread(s32 core_id) { | |||
| 181 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | 176 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); |
| 182 | 177 | ||
| 183 | // Get the current thread. | 178 | // Get the current thread. |
| 184 | KThread* cur_thread = kernel.Scheduler(static_cast<std::size_t>(core_id)).GetCurrentThread(); | 179 | KThread* cur_thread = |
| 180 | kernel.Scheduler(static_cast<std::size_t>(core_id)).GetSchedulerCurrentThread(); | ||
| 185 | 181 | ||
| 186 | // If the thread isn't terminated, pin it. | 182 | // If the thread isn't terminated, pin it. |
| 187 | if (!cur_thread->IsTerminationRequested()) { | 183 | if (!cur_thread->IsTerminationRequested()) { |
| @@ -198,7 +194,8 @@ void KProcess::UnpinCurrentThread(s32 core_id) { | |||
| 198 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | 194 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); |
| 199 | 195 | ||
| 200 | // Get the current thread. | 196 | // Get the current thread. |
| 201 | KThread* cur_thread = kernel.Scheduler(static_cast<std::size_t>(core_id)).GetCurrentThread(); | 197 | KThread* cur_thread = |
| 198 | kernel.Scheduler(static_cast<std::size_t>(core_id)).GetSchedulerCurrentThread(); | ||
| 202 | 199 | ||
| 203 | // Unpin it. | 200 | // Unpin it. |
| 204 | cur_thread->Unpin(); | 201 | cur_thread->Unpin(); |
| @@ -222,8 +219,8 @@ void KProcess::UnpinThread(KThread* thread) { | |||
| 222 | KScheduler::SetSchedulerUpdateNeeded(kernel); | 219 | KScheduler::SetSchedulerUpdateNeeded(kernel); |
| 223 | } | 220 | } |
| 224 | 221 | ||
| 225 | ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address, | 222 | Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address, |
| 226 | [[maybe_unused]] size_t size) { | 223 | [[maybe_unused]] size_t size) { |
| 227 | // Lock ourselves, to prevent concurrent access. | 224 | // Lock ourselves, to prevent concurrent access. |
| 228 | KScopedLightLock lk(state_lock); | 225 | KScopedLightLock lk(state_lock); |
| 229 | 226 | ||
| @@ -275,15 +272,19 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a | |||
| 275 | shmem->Close(); | 272 | shmem->Close(); |
| 276 | } | 273 | } |
| 277 | 274 | ||
| 278 | void KProcess::RegisterThread(const KThread* thread) { | 275 | void KProcess::RegisterThread(KThread* thread) { |
| 276 | KScopedLightLock lk{list_lock}; | ||
| 277 | |||
| 279 | thread_list.push_back(thread); | 278 | thread_list.push_back(thread); |
| 280 | } | 279 | } |
| 281 | 280 | ||
| 282 | void KProcess::UnregisterThread(const KThread* thread) { | 281 | void KProcess::UnregisterThread(KThread* thread) { |
| 282 | KScopedLightLock lk{list_lock}; | ||
| 283 | |||
| 283 | thread_list.remove(thread); | 284 | thread_list.remove(thread); |
| 284 | } | 285 | } |
| 285 | 286 | ||
| 286 | ResultCode KProcess::Reset() { | 287 | Result KProcess::Reset() { |
| 287 | // Lock the process and the scheduler. | 288 | // Lock the process and the scheduler. |
| 288 | KScopedLightLock lk(state_lock); | 289 | KScopedLightLock lk(state_lock); |
| 289 | KScopedSchedulerLock sl{kernel}; | 290 | KScopedSchedulerLock sl{kernel}; |
| @@ -297,8 +298,51 @@ ResultCode KProcess::Reset() { | |||
| 297 | return ResultSuccess; | 298 | return ResultSuccess; |
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | 301 | Result KProcess::SetActivity(ProcessActivity activity) { |
| 301 | std::size_t code_size) { | 302 | // Lock ourselves and the scheduler. |
| 303 | KScopedLightLock lk{state_lock}; | ||
| 304 | KScopedLightLock list_lk{list_lock}; | ||
| 305 | KScopedSchedulerLock sl{kernel}; | ||
| 306 | |||
| 307 | // Validate our state. | ||
| 308 | R_UNLESS(status != ProcessStatus::Exiting, ResultInvalidState); | ||
| 309 | R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState); | ||
| 310 | |||
| 311 | // Either pause or resume. | ||
| 312 | if (activity == ProcessActivity::Paused) { | ||
| 313 | // Verify that we're not suspended. | ||
| 314 | if (is_suspended) { | ||
| 315 | return ResultInvalidState; | ||
| 316 | } | ||
| 317 | |||
| 318 | // Suspend all threads. | ||
| 319 | for (auto* thread : GetThreadList()) { | ||
| 320 | thread->RequestSuspend(SuspendType::Process); | ||
| 321 | } | ||
| 322 | |||
| 323 | // Set ourselves as suspended. | ||
| 324 | SetSuspended(true); | ||
| 325 | } else { | ||
| 326 | ASSERT(activity == ProcessActivity::Runnable); | ||
| 327 | |||
| 328 | // Verify that we're suspended. | ||
| 329 | if (!is_suspended) { | ||
| 330 | return ResultInvalidState; | ||
| 331 | } | ||
| 332 | |||
| 333 | // Resume all threads. | ||
| 334 | for (auto* thread : GetThreadList()) { | ||
| 335 | thread->Resume(SuspendType::Process); | ||
| 336 | } | ||
| 337 | |||
| 338 | // Set ourselves as resumed. | ||
| 339 | SetSuspended(false); | ||
| 340 | } | ||
| 341 | |||
| 342 | return ResultSuccess; | ||
| 343 | } | ||
| 344 | |||
| 345 | Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size) { | ||
| 302 | program_id = metadata.GetTitleID(); | 346 | program_id = metadata.GetTitleID(); |
| 303 | ideal_core = metadata.GetMainThreadCore(); | 347 | ideal_core = metadata.GetMainThreadCore(); |
| 304 | is_64bit_process = metadata.Is64BitProgram(); | 348 | is_64bit_process = metadata.Is64BitProgram(); |
| @@ -313,24 +357,24 @@ ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 313 | return ResultLimitReached; | 357 | return ResultLimitReached; |
| 314 | } | 358 | } |
| 315 | // Initialize proces address space | 359 | // Initialize proces address space |
| 316 | if (const ResultCode result{ | 360 | if (const Result result{page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, |
| 317 | page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, | 361 | 0x8000000, code_size, |
| 318 | code_size, KMemoryManager::Pool::Application)}; | 362 | KMemoryManager::Pool::Application)}; |
| 319 | result.IsError()) { | 363 | result.IsError()) { |
| 320 | return result; | 364 | return result; |
| 321 | } | 365 | } |
| 322 | 366 | ||
| 323 | // Map process code region | 367 | // Map process code region |
| 324 | if (const ResultCode result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), | 368 | if (const Result result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), |
| 325 | code_size / PageSize, KMemoryState::Code, | 369 | code_size / PageSize, KMemoryState::Code, |
| 326 | KMemoryPermission::None)}; | 370 | KMemoryPermission::None)}; |
| 327 | result.IsError()) { | 371 | result.IsError()) { |
| 328 | return result; | 372 | return result; |
| 329 | } | 373 | } |
| 330 | 374 | ||
| 331 | // Initialize process capabilities | 375 | // Initialize process capabilities |
| 332 | const auto& caps{metadata.GetKernelCapabilities()}; | 376 | const auto& caps{metadata.GetKernelCapabilities()}; |
| 333 | if (const ResultCode result{ | 377 | if (const Result result{ |
| 334 | capabilities.InitializeForUserProcess(caps.data(), caps.size(), *page_table)}; | 378 | capabilities.InitializeForUserProcess(caps.data(), caps.size(), *page_table)}; |
| 335 | result.IsError()) { | 379 | result.IsError()) { |
| 336 | return result; | 380 | return result; |
| @@ -350,7 +394,7 @@ ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 350 | break; | 394 | break; |
| 351 | 395 | ||
| 352 | default: | 396 | default: |
| 353 | UNREACHABLE(); | 397 | ASSERT(false); |
| 354 | } | 398 | } |
| 355 | 399 | ||
| 356 | // Create TLS region | 400 | // Create TLS region |
| @@ -377,11 +421,11 @@ void KProcess::PrepareForTermination() { | |||
| 377 | ChangeStatus(ProcessStatus::Exiting); | 421 | ChangeStatus(ProcessStatus::Exiting); |
| 378 | 422 | ||
| 379 | const auto stop_threads = [this](const std::vector<KThread*>& in_thread_list) { | 423 | const auto stop_threads = [this](const std::vector<KThread*>& in_thread_list) { |
| 380 | for (auto& thread : in_thread_list) { | 424 | for (auto* thread : in_thread_list) { |
| 381 | if (thread->GetOwnerProcess() != this) | 425 | if (thread->GetOwnerProcess() != this) |
| 382 | continue; | 426 | continue; |
| 383 | 427 | ||
| 384 | if (thread == kernel.CurrentScheduler()->GetCurrentThread()) | 428 | if (thread == GetCurrentThreadPointer(kernel)) |
| 385 | continue; | 429 | continue; |
| 386 | 430 | ||
| 387 | // TODO(Subv): When are the other running/ready threads terminated? | 431 | // TODO(Subv): When are the other running/ready threads terminated? |
| @@ -437,7 +481,7 @@ void KProcess::Finalize() { | |||
| 437 | KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask>::Finalize(); | 481 | KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask>::Finalize(); |
| 438 | } | 482 | } |
| 439 | 483 | ||
| 440 | ResultCode KProcess::CreateThreadLocalRegion(VAddr* out) { | 484 | Result KProcess::CreateThreadLocalRegion(VAddr* out) { |
| 441 | KThreadLocalPage* tlp = nullptr; | 485 | KThreadLocalPage* tlp = nullptr; |
| 442 | VAddr tlr = 0; | 486 | VAddr tlr = 0; |
| 443 | 487 | ||
| @@ -488,7 +532,7 @@ ResultCode KProcess::CreateThreadLocalRegion(VAddr* out) { | |||
| 488 | return ResultSuccess; | 532 | return ResultSuccess; |
| 489 | } | 533 | } |
| 490 | 534 | ||
| 491 | ResultCode KProcess::DeleteThreadLocalRegion(VAddr addr) { | 535 | Result KProcess::DeleteThreadLocalRegion(VAddr addr) { |
| 492 | KThreadLocalPage* page_to_free = nullptr; | 536 | KThreadLocalPage* page_to_free = nullptr; |
| 493 | 537 | ||
| 494 | // Release the region. | 538 | // Release the region. |
| @@ -536,6 +580,52 @@ ResultCode KProcess::DeleteThreadLocalRegion(VAddr addr) { | |||
| 536 | return ResultSuccess; | 580 | return ResultSuccess; |
| 537 | } | 581 | } |
| 538 | 582 | ||
| 583 | bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size, | ||
| 584 | DebugWatchpointType type) { | ||
| 585 | const auto watch{std::find_if(watchpoints.begin(), watchpoints.end(), [&](const auto& wp) { | ||
| 586 | return wp.type == DebugWatchpointType::None; | ||
| 587 | })}; | ||
| 588 | |||
| 589 | if (watch == watchpoints.end()) { | ||
| 590 | return false; | ||
| 591 | } | ||
| 592 | |||
| 593 | watch->start_address = addr; | ||
| 594 | watch->end_address = addr + size; | ||
| 595 | watch->type = type; | ||
| 596 | |||
| 597 | for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) { | ||
| 598 | debug_page_refcounts[page]++; | ||
| 599 | system.Memory().MarkRegionDebug(page, PageSize, true); | ||
| 600 | } | ||
| 601 | |||
| 602 | return true; | ||
| 603 | } | ||
| 604 | |||
| 605 | bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, | ||
| 606 | DebugWatchpointType type) { | ||
| 607 | const auto watch{std::find_if(watchpoints.begin(), watchpoints.end(), [&](const auto& wp) { | ||
| 608 | return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; | ||
| 609 | })}; | ||
| 610 | |||
| 611 | if (watch == watchpoints.end()) { | ||
| 612 | return false; | ||
| 613 | } | ||
| 614 | |||
| 615 | watch->start_address = 0; | ||
| 616 | watch->end_address = 0; | ||
| 617 | watch->type = DebugWatchpointType::None; | ||
| 618 | |||
| 619 | for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) { | ||
| 620 | debug_page_refcounts[page]--; | ||
| 621 | if (!debug_page_refcounts[page]) { | ||
| 622 | system.Memory().MarkRegionDebug(page, PageSize, false); | ||
| 623 | } | ||
| 624 | } | ||
| 625 | |||
| 626 | return true; | ||
| 627 | } | ||
| 628 | |||
| 539 | void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { | 629 | void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { |
| 540 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 630 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 541 | Svc::MemoryPermission permission) { | 631 | Svc::MemoryPermission permission) { |
| @@ -556,9 +646,10 @@ bool KProcess::IsSignaled() const { | |||
| 556 | } | 646 | } |
| 557 | 647 | ||
| 558 | KProcess::KProcess(KernelCore& kernel_) | 648 | KProcess::KProcess(KernelCore& kernel_) |
| 559 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, | 649 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{std::make_unique<KPageTable>( |
| 560 | page_table{std::make_unique<KPageTable>(kernel_.System())}, handle_table{kernel_}, | 650 | kernel_.System())}, |
| 561 | address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, state_lock{kernel_} {} | 651 | handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, |
| 652 | state_lock{kernel_}, list_lock{kernel_} {} | ||
| 562 | 653 | ||
| 563 | KProcess::~KProcess() = default; | 654 | KProcess::~KProcess() = default; |
| 564 | 655 | ||
| @@ -572,7 +663,7 @@ void KProcess::ChangeStatus(ProcessStatus new_status) { | |||
| 572 | NotifyAvailable(); | 663 | NotifyAvailable(); |
| 573 | } | 664 | } |
| 574 | 665 | ||
| 575 | ResultCode KProcess::AllocateMainThreadStack(std::size_t stack_size) { | 666 | Result KProcess::AllocateMainThreadStack(std::size_t stack_size) { |
| 576 | ASSERT(stack_size); | 667 | ASSERT(stack_size); |
| 577 | 668 | ||
| 578 | // The kernel always ensures that the given stack size is page aligned. | 669 | // The kernel always ensures that the given stack size is page aligned. |
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 9f171e3da..5e3e22ad8 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <list> | 9 | #include <list> |
| 10 | #include <map> | ||
| 10 | #include <string> | 11 | #include <string> |
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 12 | #include "core/hle/kernel/k_address_arbiter.h" | 13 | #include "core/hle/kernel/k_address_arbiter.h" |
| @@ -63,6 +64,25 @@ enum class ProcessStatus { | |||
| 63 | DebugBreak, | 64 | DebugBreak, |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 67 | enum class ProcessActivity : u32 { | ||
| 68 | Runnable, | ||
| 69 | Paused, | ||
| 70 | }; | ||
| 71 | |||
| 72 | enum class DebugWatchpointType : u8 { | ||
| 73 | None = 0, | ||
| 74 | Read = 1 << 0, | ||
| 75 | Write = 1 << 1, | ||
| 76 | ReadOrWrite = Read | Write, | ||
| 77 | }; | ||
| 78 | DECLARE_ENUM_FLAG_OPERATORS(DebugWatchpointType); | ||
| 79 | |||
| 80 | struct DebugWatchpoint { | ||
| 81 | VAddr start_address; | ||
| 82 | VAddr end_address; | ||
| 83 | DebugWatchpointType type; | ||
| 84 | }; | ||
| 85 | |||
| 66 | class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> { | 86 | class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> { |
| 67 | KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); | 87 | KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); |
| 68 | 88 | ||
| @@ -90,8 +110,8 @@ public: | |||
| 90 | 110 | ||
| 91 | static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; | 111 | static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; |
| 92 | 112 | ||
| 93 | static ResultCode Initialize(KProcess* process, Core::System& system, std::string process_name, | 113 | static Result Initialize(KProcess* process, Core::System& system, std::string process_name, |
| 94 | ProcessType type, KResourceLimit* res_limit); | 114 | ProcessType type, KResourceLimit* res_limit); |
| 95 | 115 | ||
| 96 | /// Gets a reference to the process' page table. | 116 | /// Gets a reference to the process' page table. |
| 97 | KPageTable& PageTable() { | 117 | KPageTable& PageTable() { |
| @@ -113,11 +133,11 @@ public: | |||
| 113 | return handle_table; | 133 | return handle_table; |
| 114 | } | 134 | } |
| 115 | 135 | ||
| 116 | ResultCode SignalToAddress(VAddr address) { | 136 | Result SignalToAddress(VAddr address) { |
| 117 | return condition_var.SignalToAddress(address); | 137 | return condition_var.SignalToAddress(address); |
| 118 | } | 138 | } |
| 119 | 139 | ||
| 120 | ResultCode WaitForAddress(Handle handle, VAddr address, u32 tag) { | 140 | Result WaitForAddress(Handle handle, VAddr address, u32 tag) { |
| 121 | return condition_var.WaitForAddress(handle, address, tag); | 141 | return condition_var.WaitForAddress(handle, address, tag); |
| 122 | } | 142 | } |
| 123 | 143 | ||
| @@ -125,17 +145,16 @@ public: | |||
| 125 | return condition_var.Signal(cv_key, count); | 145 | return condition_var.Signal(cv_key, count); |
| 126 | } | 146 | } |
| 127 | 147 | ||
| 128 | ResultCode WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) { | 148 | Result WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) { |
| 129 | return condition_var.Wait(address, cv_key, tag, ns); | 149 | return condition_var.Wait(address, cv_key, tag, ns); |
| 130 | } | 150 | } |
| 131 | 151 | ||
| 132 | ResultCode SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, | 152 | Result SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, s32 count) { |
| 133 | s32 count) { | ||
| 134 | return address_arbiter.SignalToAddress(address, signal_type, value, count); | 153 | return address_arbiter.SignalToAddress(address, signal_type, value, count); |
| 135 | } | 154 | } |
| 136 | 155 | ||
| 137 | ResultCode WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value, | 156 | Result WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value, |
| 138 | s64 timeout) { | 157 | s64 timeout) { |
| 139 | return address_arbiter.WaitForAddress(address, arb_type, value, timeout); | 158 | return address_arbiter.WaitForAddress(address, arb_type, value, timeout); |
| 140 | } | 159 | } |
| 141 | 160 | ||
| @@ -282,17 +301,17 @@ public: | |||
| 282 | u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; | 301 | u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; |
| 283 | 302 | ||
| 284 | /// Gets the list of all threads created with this process as their owner. | 303 | /// Gets the list of all threads created with this process as their owner. |
| 285 | const std::list<const KThread*>& GetThreadList() const { | 304 | std::list<KThread*>& GetThreadList() { |
| 286 | return thread_list; | 305 | return thread_list; |
| 287 | } | 306 | } |
| 288 | 307 | ||
| 289 | /// Registers a thread as being created under this process, | 308 | /// Registers a thread as being created under this process, |
| 290 | /// adding it to this process' thread list. | 309 | /// adding it to this process' thread list. |
| 291 | void RegisterThread(const KThread* thread); | 310 | void RegisterThread(KThread* thread); |
| 292 | 311 | ||
| 293 | /// Unregisters a thread from this process, removing it | 312 | /// Unregisters a thread from this process, removing it |
| 294 | /// from this process' thread list. | 313 | /// from this process' thread list. |
| 295 | void UnregisterThread(const KThread* thread); | 314 | void UnregisterThread(KThread* thread); |
| 296 | 315 | ||
| 297 | /// Clears the signaled state of the process if and only if it's signaled. | 316 | /// Clears the signaled state of the process if and only if it's signaled. |
| 298 | /// | 317 | /// |
| @@ -302,7 +321,7 @@ public: | |||
| 302 | /// @pre The process must be in a signaled state. If this is called on a | 321 | /// @pre The process must be in a signaled state. If this is called on a |
| 303 | /// process instance that is not signaled, ERR_INVALID_STATE will be | 322 | /// process instance that is not signaled, ERR_INVALID_STATE will be |
| 304 | /// returned. | 323 | /// returned. |
| 305 | ResultCode Reset(); | 324 | Result Reset(); |
| 306 | 325 | ||
| 307 | /** | 326 | /** |
| 308 | * Loads process-specifics configuration info with metadata provided | 327 | * Loads process-specifics configuration info with metadata provided |
| @@ -313,7 +332,7 @@ public: | |||
| 313 | * @returns ResultSuccess if all relevant metadata was able to be | 332 | * @returns ResultSuccess if all relevant metadata was able to be |
| 314 | * loaded and parsed. Otherwise, an error code is returned. | 333 | * loaded and parsed. Otherwise, an error code is returned. |
| 315 | */ | 334 | */ |
| 316 | ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size); | 335 | Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size); |
| 317 | 336 | ||
| 318 | /** | 337 | /** |
| 319 | * Starts the main application thread for this process. | 338 | * Starts the main application thread for this process. |
| @@ -347,6 +366,8 @@ public: | |||
| 347 | 366 | ||
| 348 | void DoWorkerTaskImpl(); | 367 | void DoWorkerTaskImpl(); |
| 349 | 368 | ||
| 369 | Result SetActivity(ProcessActivity activity); | ||
| 370 | |||
| 350 | void PinCurrentThread(s32 core_id); | 371 | void PinCurrentThread(s32 core_id); |
| 351 | void UnpinCurrentThread(s32 core_id); | 372 | void UnpinCurrentThread(s32 core_id); |
| 352 | void UnpinThread(KThread* thread); | 373 | void UnpinThread(KThread* thread); |
| @@ -355,17 +376,30 @@ public: | |||
| 355 | return state_lock; | 376 | return state_lock; |
| 356 | } | 377 | } |
| 357 | 378 | ||
| 358 | ResultCode AddSharedMemory(KSharedMemory* shmem, VAddr address, size_t size); | 379 | Result AddSharedMemory(KSharedMemory* shmem, VAddr address, size_t size); |
| 359 | void RemoveSharedMemory(KSharedMemory* shmem, VAddr address, size_t size); | 380 | void RemoveSharedMemory(KSharedMemory* shmem, VAddr address, size_t size); |
| 360 | 381 | ||
| 361 | /////////////////////////////////////////////////////////////////////////////////////////////// | 382 | /////////////////////////////////////////////////////////////////////////////////////////////// |
| 362 | // Thread-local storage management | 383 | // Thread-local storage management |
| 363 | 384 | ||
| 364 | // Marks the next available region as used and returns the address of the slot. | 385 | // Marks the next available region as used and returns the address of the slot. |
| 365 | [[nodiscard]] ResultCode CreateThreadLocalRegion(VAddr* out); | 386 | [[nodiscard]] Result CreateThreadLocalRegion(VAddr* out); |
| 366 | 387 | ||
| 367 | // Frees a used TLS slot identified by the given address | 388 | // Frees a used TLS slot identified by the given address |
| 368 | ResultCode DeleteThreadLocalRegion(VAddr addr); | 389 | Result DeleteThreadLocalRegion(VAddr addr); |
| 390 | |||
| 391 | /////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 392 | // Debug watchpoint management | ||
| 393 | |||
| 394 | // Attempts to insert a watchpoint into a free slot. Returns false if none are available. | ||
| 395 | bool InsertWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type); | ||
| 396 | |||
| 397 | // Attempts to remove the watchpoint specified by the given parameters. | ||
| 398 | bool RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, DebugWatchpointType type); | ||
| 399 | |||
| 400 | const std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS>& GetWatchpoints() const { | ||
| 401 | return watchpoints; | ||
| 402 | } | ||
| 369 | 403 | ||
| 370 | private: | 404 | private: |
| 371 | void PinThread(s32 core_id, KThread* thread) { | 405 | void PinThread(s32 core_id, KThread* thread) { |
| @@ -388,7 +422,7 @@ private: | |||
| 388 | void ChangeStatus(ProcessStatus new_status); | 422 | void ChangeStatus(ProcessStatus new_status); |
| 389 | 423 | ||
| 390 | /// Allocates the main thread stack for the process, given the stack size in bytes. | 424 | /// Allocates the main thread stack for the process, given the stack size in bytes. |
| 391 | ResultCode AllocateMainThreadStack(std::size_t stack_size); | 425 | Result AllocateMainThreadStack(std::size_t stack_size); |
| 392 | 426 | ||
| 393 | /// Memory manager for this process | 427 | /// Memory manager for this process |
| 394 | std::unique_ptr<KPageTable> page_table; | 428 | std::unique_ptr<KPageTable> page_table; |
| @@ -442,7 +476,7 @@ private: | |||
| 442 | std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; | 476 | std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; |
| 443 | 477 | ||
| 444 | /// List of threads that are running with this process as their owner. | 478 | /// List of threads that are running with this process as their owner. |
| 445 | std::list<const KThread*> thread_list; | 479 | std::list<KThread*> thread_list; |
| 446 | 480 | ||
| 447 | /// List of shared memory that are running with this process as their owner. | 481 | /// List of shared memory that are running with this process as their owner. |
| 448 | std::list<KSharedMemoryInfo*> shared_memory_list; | 482 | std::list<KSharedMemoryInfo*> shared_memory_list; |
| @@ -471,10 +505,13 @@ private: | |||
| 471 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> running_threads{}; | 505 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> running_threads{}; |
| 472 | std::array<u64, Core::Hardware::NUM_CPU_CORES> running_thread_idle_counts{}; | 506 | std::array<u64, Core::Hardware::NUM_CPU_CORES> running_thread_idle_counts{}; |
| 473 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> pinned_threads{}; | 507 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> pinned_threads{}; |
| 508 | std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> watchpoints{}; | ||
| 509 | std::map<VAddr, u64> debug_page_refcounts; | ||
| 474 | 510 | ||
| 475 | KThread* exception_thread{}; | 511 | KThread* exception_thread{}; |
| 476 | 512 | ||
| 477 | KLightLock state_lock; | 513 | KLightLock state_lock; |
| 514 | KLightLock list_lock; | ||
| 478 | 515 | ||
| 479 | using TLPTree = | 516 | using TLPTree = |
| 480 | Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>; | 517 | Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>; |
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp index dddba554d..94c5464fe 100644 --- a/src/core/hle/kernel/k_readable_event.cpp +++ b/src/core/hle/kernel/k_readable_event.cpp | |||
| @@ -27,7 +27,7 @@ void KReadableEvent::Destroy() { | |||
| 27 | } | 27 | } |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | ResultCode KReadableEvent::Signal() { | 30 | Result KReadableEvent::Signal() { |
| 31 | KScopedSchedulerLock lk{kernel}; | 31 | KScopedSchedulerLock lk{kernel}; |
| 32 | 32 | ||
| 33 | if (!is_signaled) { | 33 | if (!is_signaled) { |
| @@ -38,13 +38,13 @@ ResultCode KReadableEvent::Signal() { | |||
| 38 | return ResultSuccess; | 38 | return ResultSuccess; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | ResultCode KReadableEvent::Clear() { | 41 | Result KReadableEvent::Clear() { |
| 42 | Reset(); | 42 | Reset(); |
| 43 | 43 | ||
| 44 | return ResultSuccess; | 44 | return ResultSuccess; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | ResultCode KReadableEvent::Reset() { | 47 | Result KReadableEvent::Reset() { |
| 48 | KScopedSchedulerLock lk{kernel}; | 48 | KScopedSchedulerLock lk{kernel}; |
| 49 | 49 | ||
| 50 | if (!is_signaled) { | 50 | if (!is_signaled) { |
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index 5065c7cc0..18dcad289 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h | |||
| @@ -33,9 +33,9 @@ public: | |||
| 33 | bool IsSignaled() const override; | 33 | bool IsSignaled() const override; |
| 34 | void Destroy() override; | 34 | void Destroy() override; |
| 35 | 35 | ||
| 36 | ResultCode Signal(); | 36 | Result Signal(); |
| 37 | ResultCode Clear(); | 37 | Result Clear(); |
| 38 | ResultCode Reset(); | 38 | Result Reset(); |
| 39 | 39 | ||
| 40 | private: | 40 | private: |
| 41 | bool is_signaled{}; | 41 | bool is_signaled{}; |
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index 3e0ecffdb..010dcf99e 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp | |||
| @@ -73,7 +73,7 @@ s64 KResourceLimit::GetFreeValue(LimitableResource which) const { | |||
| 73 | return value; | 73 | return value; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { | 76 | Result KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { |
| 77 | const auto index = static_cast<std::size_t>(which); | 77 | const auto index = static_cast<std::size_t>(which); |
| 78 | KScopedLightLock lk(lock); | 78 | KScopedLightLock lk(lock); |
| 79 | R_UNLESS(current_values[index] <= value, ResultInvalidState); | 79 | R_UNLESS(current_values[index] <= value, ResultInvalidState); |
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 43bf74b8d..65c98c979 100644 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include "core/hle/kernel/k_light_condition_variable.h" | 8 | #include "core/hle/kernel/k_light_condition_variable.h" |
| 9 | #include "core/hle/kernel/k_light_lock.h" | 9 | #include "core/hle/kernel/k_light_lock.h" |
| 10 | 10 | ||
| 11 | union ResultCode; | 11 | union Result; |
| 12 | 12 | ||
| 13 | namespace Core::Timing { | 13 | namespace Core::Timing { |
| 14 | class CoreTiming; | 14 | class CoreTiming; |
| @@ -46,7 +46,7 @@ public: | |||
| 46 | s64 GetPeakValue(LimitableResource which) const; | 46 | s64 GetPeakValue(LimitableResource which) const; |
| 47 | s64 GetFreeValue(LimitableResource which) const; | 47 | s64 GetFreeValue(LimitableResource which) const; |
| 48 | 48 | ||
| 49 | ResultCode SetLimitValue(LimitableResource which, s64 value); | 49 | Result SetLimitValue(LimitableResource which, s64 value); |
| 50 | 50 | ||
| 51 | bool Reserve(LimitableResource which, s64 value); | 51 | bool Reserve(LimitableResource which, s64 value); |
| 52 | bool Reserve(LimitableResource which, s64 value, s64 timeout); | 52 | bool Reserve(LimitableResource which, s64 value, s64 timeout); |
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 2d4e8637b..d586b3f5c 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -317,7 +317,7 @@ void KScheduler::RotateScheduledQueue(s32 cpu_core_id, s32 priority) { | |||
| 317 | 317 | ||
| 318 | { | 318 | { |
| 319 | KThread* best_thread = priority_queue.GetScheduledFront(cpu_core_id); | 319 | KThread* best_thread = priority_queue.GetScheduledFront(cpu_core_id); |
| 320 | if (best_thread == GetCurrentThread()) { | 320 | if (best_thread == GetCurrentThreadPointer(kernel)) { |
| 321 | best_thread = priority_queue.GetScheduledNext(cpu_core_id, best_thread); | 321 | best_thread = priority_queue.GetScheduledNext(cpu_core_id, best_thread); |
| 322 | } | 322 | } |
| 323 | 323 | ||
| @@ -424,7 +424,7 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) { | |||
| 424 | ASSERT(kernel.CurrentProcess() != nullptr); | 424 | ASSERT(kernel.CurrentProcess() != nullptr); |
| 425 | 425 | ||
| 426 | // Get the current thread and process. | 426 | // Get the current thread and process. |
| 427 | KThread& cur_thread = Kernel::GetCurrentThread(kernel); | 427 | KThread& cur_thread = GetCurrentThread(kernel); |
| 428 | KProcess& cur_process = *kernel.CurrentProcess(); | 428 | KProcess& cur_process = *kernel.CurrentProcess(); |
| 429 | 429 | ||
| 430 | // If the thread's yield count matches, there's nothing for us to do. | 430 | // If the thread's yield count matches, there's nothing for us to do. |
| @@ -463,7 +463,7 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) { | |||
| 463 | ASSERT(kernel.CurrentProcess() != nullptr); | 463 | ASSERT(kernel.CurrentProcess() != nullptr); |
| 464 | 464 | ||
| 465 | // Get the current thread and process. | 465 | // Get the current thread and process. |
| 466 | KThread& cur_thread = Kernel::GetCurrentThread(kernel); | 466 | KThread& cur_thread = GetCurrentThread(kernel); |
| 467 | KProcess& cur_process = *kernel.CurrentProcess(); | 467 | KProcess& cur_process = *kernel.CurrentProcess(); |
| 468 | 468 | ||
| 469 | // If the thread's yield count matches, there's nothing for us to do. | 469 | // If the thread's yield count matches, there's nothing for us to do. |
| @@ -551,7 +551,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) { | |||
| 551 | ASSERT(kernel.CurrentProcess() != nullptr); | 551 | ASSERT(kernel.CurrentProcess() != nullptr); |
| 552 | 552 | ||
| 553 | // Get the current thread and process. | 553 | // Get the current thread and process. |
| 554 | KThread& cur_thread = Kernel::GetCurrentThread(kernel); | 554 | KThread& cur_thread = GetCurrentThread(kernel); |
| 555 | KProcess& cur_process = *kernel.CurrentProcess(); | 555 | KProcess& cur_process = *kernel.CurrentProcess(); |
| 556 | 556 | ||
| 557 | // If the thread's yield count matches, there's nothing for us to do. | 557 | // If the thread's yield count matches, there's nothing for us to do. |
| @@ -642,7 +642,7 @@ KScheduler::~KScheduler() { | |||
| 642 | ASSERT(!idle_thread); | 642 | ASSERT(!idle_thread); |
| 643 | } | 643 | } |
| 644 | 644 | ||
| 645 | KThread* KScheduler::GetCurrentThread() const { | 645 | KThread* KScheduler::GetSchedulerCurrentThread() const { |
| 646 | if (auto result = current_thread.load(); result) { | 646 | if (auto result = current_thread.load(); result) { |
| 647 | return result; | 647 | return result; |
| 648 | } | 648 | } |
| @@ -654,7 +654,7 @@ u64 KScheduler::GetLastContextSwitchTicks() const { | |||
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | void KScheduler::RescheduleCurrentCore() { | 656 | void KScheduler::RescheduleCurrentCore() { |
| 657 | ASSERT(GetCurrentThread()->GetDisableDispatchCount() == 1); | 657 | ASSERT(GetCurrentThread(system.Kernel()).GetDisableDispatchCount() == 1); |
| 658 | 658 | ||
| 659 | auto& phys_core = system.Kernel().PhysicalCore(core_id); | 659 | auto& phys_core = system.Kernel().PhysicalCore(core_id); |
| 660 | if (phys_core.IsInterrupted()) { | 660 | if (phys_core.IsInterrupted()) { |
| @@ -665,7 +665,7 @@ void KScheduler::RescheduleCurrentCore() { | |||
| 665 | if (state.needs_scheduling.load()) { | 665 | if (state.needs_scheduling.load()) { |
| 666 | Schedule(); | 666 | Schedule(); |
| 667 | } else { | 667 | } else { |
| 668 | GetCurrentThread()->EnableDispatch(); | 668 | GetCurrentThread(system.Kernel()).EnableDispatch(); |
| 669 | guard.Unlock(); | 669 | guard.Unlock(); |
| 670 | } | 670 | } |
| 671 | } | 671 | } |
| @@ -710,6 +710,7 @@ void KScheduler::Reload(KThread* thread) { | |||
| 710 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); | 710 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); |
| 711 | cpu_core.LoadContext(thread->GetContext32()); | 711 | cpu_core.LoadContext(thread->GetContext32()); |
| 712 | cpu_core.LoadContext(thread->GetContext64()); | 712 | cpu_core.LoadContext(thread->GetContext64()); |
| 713 | cpu_core.LoadWatchpointArray(thread->GetOwnerProcess()->GetWatchpoints()); | ||
| 713 | cpu_core.SetTlsAddress(thread->GetTLSAddress()); | 714 | cpu_core.SetTlsAddress(thread->GetTLSAddress()); |
| 714 | cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); | 715 | cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); |
| 715 | cpu_core.ClearExclusiveState(); | 716 | cpu_core.ClearExclusiveState(); |
| @@ -717,13 +718,18 @@ void KScheduler::Reload(KThread* thread) { | |||
| 717 | 718 | ||
| 718 | void KScheduler::SwitchContextStep2() { | 719 | void KScheduler::SwitchContextStep2() { |
| 719 | // Load context of new thread | 720 | // Load context of new thread |
| 720 | Reload(GetCurrentThread()); | 721 | Reload(GetCurrentThreadPointer(system.Kernel())); |
| 721 | 722 | ||
| 722 | RescheduleCurrentCore(); | 723 | RescheduleCurrentCore(); |
| 723 | } | 724 | } |
| 724 | 725 | ||
| 726 | void KScheduler::Schedule() { | ||
| 727 | ASSERT(GetCurrentThread(system.Kernel()).GetDisableDispatchCount() == 1); | ||
| 728 | this->ScheduleImpl(); | ||
| 729 | } | ||
| 730 | |||
| 725 | void KScheduler::ScheduleImpl() { | 731 | void KScheduler::ScheduleImpl() { |
| 726 | KThread* previous_thread = GetCurrentThread(); | 732 | KThread* previous_thread = GetCurrentThreadPointer(system.Kernel()); |
| 727 | KThread* next_thread = state.highest_priority_thread; | 733 | KThread* next_thread = state.highest_priority_thread; |
| 728 | 734 | ||
| 729 | state.needs_scheduling.store(false); | 735 | state.needs_scheduling.store(false); |
| @@ -761,6 +767,7 @@ void KScheduler::ScheduleImpl() { | |||
| 761 | old_context = &previous_thread->GetHostContext(); | 767 | old_context = &previous_thread->GetHostContext(); |
| 762 | 768 | ||
| 763 | // Set the new thread. | 769 | // Set the new thread. |
| 770 | SetCurrentThread(system.Kernel(), next_thread); | ||
| 764 | current_thread.store(next_thread); | 771 | current_thread.store(next_thread); |
| 765 | 772 | ||
| 766 | guard.Unlock(); | 773 | guard.Unlock(); |
| @@ -804,6 +811,7 @@ void KScheduler::SwitchToCurrent() { | |||
| 804 | } | 811 | } |
| 805 | } | 812 | } |
| 806 | auto thread = next_thread ? next_thread : idle_thread; | 813 | auto thread = next_thread ? next_thread : idle_thread; |
| 814 | SetCurrentThread(system.Kernel(), thread); | ||
| 807 | Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext()); | 815 | Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext()); |
| 808 | } while (!is_switch_pending()); | 816 | } while (!is_switch_pending()); |
| 809 | } | 817 | } |
| @@ -829,6 +837,7 @@ void KScheduler::Initialize() { | |||
| 829 | idle_thread = KThread::Create(system.Kernel()); | 837 | idle_thread = KThread::Create(system.Kernel()); |
| 830 | ASSERT(KThread::InitializeIdleThread(system, idle_thread, core_id).IsSuccess()); | 838 | ASSERT(KThread::InitializeIdleThread(system, idle_thread, core_id).IsSuccess()); |
| 831 | idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); | 839 | idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); |
| 840 | idle_thread->EnableDispatch(); | ||
| 832 | } | 841 | } |
| 833 | 842 | ||
| 834 | KScopedSchedulerLock::KScopedSchedulerLock(KernelCore& kernel) | 843 | KScopedSchedulerLock::KScopedSchedulerLock(KernelCore& kernel) |
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 729e006f2..cc3da33f5 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h | |||
| @@ -48,7 +48,7 @@ public: | |||
| 48 | void Reload(KThread* thread); | 48 | void Reload(KThread* thread); |
| 49 | 49 | ||
| 50 | /// Gets the current running thread | 50 | /// Gets the current running thread |
| 51 | [[nodiscard]] KThread* GetCurrentThread() const; | 51 | [[nodiscard]] KThread* GetSchedulerCurrentThread() const; |
| 52 | 52 | ||
| 53 | /// Gets the idle thread | 53 | /// Gets the idle thread |
| 54 | [[nodiscard]] KThread* GetIdleThread() const { | 54 | [[nodiscard]] KThread* GetIdleThread() const { |
| @@ -57,7 +57,7 @@ public: | |||
| 57 | 57 | ||
| 58 | /// Returns true if the scheduler is idle | 58 | /// Returns true if the scheduler is idle |
| 59 | [[nodiscard]] bool IsIdle() const { | 59 | [[nodiscard]] bool IsIdle() const { |
| 60 | return GetCurrentThread() == idle_thread; | 60 | return GetSchedulerCurrentThread() == idle_thread; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | /// Gets the timestamp for the last context switch in ticks. | 63 | /// Gets the timestamp for the last context switch in ticks. |
| @@ -149,10 +149,7 @@ private: | |||
| 149 | 149 | ||
| 150 | void RotateScheduledQueue(s32 cpu_core_id, s32 priority); | 150 | void RotateScheduledQueue(s32 cpu_core_id, s32 priority); |
| 151 | 151 | ||
| 152 | void Schedule() { | 152 | void Schedule(); |
| 153 | ASSERT(GetCurrentThread()->GetDisableDispatchCount() == 1); | ||
| 154 | this->ScheduleImpl(); | ||
| 155 | } | ||
| 156 | 153 | ||
| 157 | /// Switches the CPU's active thread context to that of the specified thread | 154 | /// Switches the CPU's active thread context to that of the specified thread |
| 158 | void ScheduleImpl(); | 155 | void ScheduleImpl(); |
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 7e39f6d50..802c646a6 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -79,7 +79,7 @@ std::size_t KServerSession::NumDomainRequestHandlers() const { | |||
| 79 | return manager->DomainHandlerCount(); | 79 | return manager->DomainHandlerCount(); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) { | 82 | Result KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) { |
| 83 | if (!context.HasDomainMessageHeader()) { | 83 | if (!context.HasDomainMessageHeader()) { |
| 84 | return ResultSuccess; | 84 | return ResultSuccess; |
| 85 | } | 85 | } |
| @@ -97,13 +97,13 @@ ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& co | |||
| 97 | "object_id {} is too big! This probably means a recent service call " | 97 | "object_id {} is too big! This probably means a recent service call " |
| 98 | "to {} needed to return a new interface!", | 98 | "to {} needed to return a new interface!", |
| 99 | object_id, name); | 99 | object_id, name); |
| 100 | UNREACHABLE(); | 100 | ASSERT(false); |
| 101 | return ResultSuccess; // Ignore error if asserts are off | 101 | return ResultSuccess; // Ignore error if asserts are off |
| 102 | } | 102 | } |
| 103 | if (auto strong_ptr = manager->DomainHandler(object_id - 1).lock()) { | 103 | if (auto strong_ptr = manager->DomainHandler(object_id - 1).lock()) { |
| 104 | return strong_ptr->HandleSyncRequest(*this, context); | 104 | return strong_ptr->HandleSyncRequest(*this, context); |
| 105 | } else { | 105 | } else { |
| 106 | UNREACHABLE(); | 106 | ASSERT(false); |
| 107 | return ResultSuccess; | 107 | return ResultSuccess; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| @@ -123,7 +123,7 @@ ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& co | |||
| 123 | return ResultSuccess; | 123 | return ResultSuccess; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) { | 126 | Result KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) { |
| 127 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))}; | 127 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))}; |
| 128 | auto context = std::make_shared<HLERequestContext>(kernel, memory, this, thread); | 128 | auto context = std::make_shared<HLERequestContext>(kernel, memory, this, thread); |
| 129 | 129 | ||
| @@ -143,8 +143,8 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor | |||
| 143 | return ResultSuccess; | 143 | return ResultSuccess; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) { | 146 | Result KServerSession::CompleteSyncRequest(HLERequestContext& context) { |
| 147 | ResultCode result = ResultSuccess; | 147 | Result result = ResultSuccess; |
| 148 | 148 | ||
| 149 | // If the session has been converted to a domain, handle the domain request | 149 | // If the session has been converted to a domain, handle the domain request |
| 150 | if (manager->HasSessionRequestHandler(context)) { | 150 | if (manager->HasSessionRequestHandler(context)) { |
| @@ -173,8 +173,8 @@ ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) { | |||
| 173 | return result; | 173 | return result; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | ResultCode KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 176 | Result KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, |
| 177 | Core::Timing::CoreTiming& core_timing) { | 177 | Core::Timing::CoreTiming& core_timing) { |
| 178 | return QueueSyncRequest(thread, memory); | 178 | return QueueSyncRequest(thread, memory); |
| 179 | } | 179 | } |
| 180 | 180 | ||
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index b628a843f..6d0821945 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h | |||
| @@ -73,10 +73,10 @@ public: | |||
| 73 | * @param memory Memory context to handle the sync request under. | 73 | * @param memory Memory context to handle the sync request under. |
| 74 | * @param core_timing Core timing context to schedule the request event under. | 74 | * @param core_timing Core timing context to schedule the request event under. |
| 75 | * | 75 | * |
| 76 | * @returns ResultCode from the operation. | 76 | * @returns Result from the operation. |
| 77 | */ | 77 | */ |
| 78 | ResultCode HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 78 | Result HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, |
| 79 | Core::Timing::CoreTiming& core_timing); | 79 | Core::Timing::CoreTiming& core_timing); |
| 80 | 80 | ||
| 81 | /// Adds a new domain request handler to the collection of request handlers within | 81 | /// Adds a new domain request handler to the collection of request handlers within |
| 82 | /// this ServerSession instance. | 82 | /// this ServerSession instance. |
| @@ -103,14 +103,14 @@ public: | |||
| 103 | 103 | ||
| 104 | private: | 104 | private: |
| 105 | /// Queues a sync request from the emulated application. | 105 | /// Queues a sync request from the emulated application. |
| 106 | ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); | 106 | Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); |
| 107 | 107 | ||
| 108 | /// Completes a sync request from the emulated application. | 108 | /// Completes a sync request from the emulated application. |
| 109 | ResultCode CompleteSyncRequest(HLERequestContext& context); | 109 | Result CompleteSyncRequest(HLERequestContext& context); |
| 110 | 110 | ||
| 111 | /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an | 111 | /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an |
| 112 | /// object handle. | 112 | /// object handle. |
| 113 | ResultCode HandleDomainSyncRequest(Kernel::HLERequestContext& context); | 113 | Result HandleDomainSyncRequest(Kernel::HLERequestContext& context); |
| 114 | 114 | ||
| 115 | /// This session's HLE request handlers | 115 | /// This session's HLE request handlers |
| 116 | std::shared_ptr<SessionRequestManager> manager; | 116 | std::shared_ptr<SessionRequestManager> manager; |
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index 51d7538ca..b77735736 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp | |||
| @@ -18,12 +18,10 @@ KSharedMemory::~KSharedMemory() { | |||
| 18 | kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size); | 18 | kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | ResultCode KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, | 21 | Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, |
| 22 | KPageLinkedList&& page_list_, | 22 | KPageGroup&& page_list_, Svc::MemoryPermission owner_permission_, |
| 23 | Svc::MemoryPermission owner_permission_, | 23 | Svc::MemoryPermission user_permission_, PAddr physical_address_, |
| 24 | Svc::MemoryPermission user_permission_, | 24 | std::size_t size_, std::string name_) { |
| 25 | PAddr physical_address_, std::size_t size_, | ||
| 26 | std::string name_) { | ||
| 27 | // Set members. | 25 | // Set members. |
| 28 | owner_process = owner_process_; | 26 | owner_process = owner_process_; |
| 29 | device_memory = &device_memory_; | 27 | device_memory = &device_memory_; |
| @@ -67,8 +65,8 @@ void KSharedMemory::Finalize() { | |||
| 67 | KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList>::Finalize(); | 65 | KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList>::Finalize(); |
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size, | 68 | Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size, |
| 71 | Svc::MemoryPermission permissions) { | 69 | Svc::MemoryPermission permissions) { |
| 72 | const u64 page_count{(map_size + PageSize - 1) / PageSize}; | 70 | const u64 page_count{(map_size + PageSize - 1) / PageSize}; |
| 73 | 71 | ||
| 74 | if (page_list.GetNumPages() != page_count) { | 72 | if (page_list.GetNumPages() != page_count) { |
| @@ -86,7 +84,7 @@ ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size | |||
| 86 | ConvertToKMemoryPermission(permissions)); | 84 | ConvertToKMemoryPermission(permissions)); |
| 87 | } | 85 | } |
| 88 | 86 | ||
| 89 | ResultCode KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { | 87 | Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { |
| 90 | const u64 page_count{(unmap_size + PageSize - 1) / PageSize}; | 88 | const u64 page_count{(unmap_size + PageSize - 1) / PageSize}; |
| 91 | 89 | ||
| 92 | if (page_list.GetNumPages() != page_count) { | 90 | if (page_list.GetNumPages() != page_count) { |
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 81de36136..2c1db0e70 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/device_memory.h" | 10 | #include "core/device_memory.h" |
| 11 | #include "core/hle/kernel/k_memory_block.h" | 11 | #include "core/hle/kernel/k_memory_block.h" |
| 12 | #include "core/hle/kernel/k_page_linked_list.h" | 12 | #include "core/hle/kernel/k_page_group.h" |
| 13 | #include "core/hle/kernel/k_process.h" | 13 | #include "core/hle/kernel/k_process.h" |
| 14 | #include "core/hle/kernel/slab_helpers.h" | 14 | #include "core/hle/kernel/slab_helpers.h" |
| 15 | #include "core/hle/result.h" | 15 | #include "core/hle/result.h" |
| @@ -26,10 +26,10 @@ public: | |||
| 26 | explicit KSharedMemory(KernelCore& kernel_); | 26 | explicit KSharedMemory(KernelCore& kernel_); |
| 27 | ~KSharedMemory() override; | 27 | ~KSharedMemory() override; |
| 28 | 28 | ||
| 29 | ResultCode Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, | 29 | Result Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, |
| 30 | KPageLinkedList&& page_list_, Svc::MemoryPermission owner_permission_, | 30 | KPageGroup&& page_list_, Svc::MemoryPermission owner_permission_, |
| 31 | Svc::MemoryPermission user_permission_, PAddr physical_address_, | 31 | Svc::MemoryPermission user_permission_, PAddr physical_address_, |
| 32 | std::size_t size_, std::string name_); | 32 | std::size_t size_, std::string name_); |
| 33 | 33 | ||
| 34 | /** | 34 | /** |
| 35 | * Maps a shared memory block to an address in the target process' address space | 35 | * Maps a shared memory block to an address in the target process' address space |
| @@ -38,8 +38,8 @@ public: | |||
| 38 | * @param map_size Size of the shared memory block to map | 38 | * @param map_size Size of the shared memory block to map |
| 39 | * @param permissions Memory block map permissions (specified by SVC field) | 39 | * @param permissions Memory block map permissions (specified by SVC field) |
| 40 | */ | 40 | */ |
| 41 | ResultCode Map(KProcess& target_process, VAddr address, std::size_t map_size, | 41 | Result Map(KProcess& target_process, VAddr address, std::size_t map_size, |
| 42 | Svc::MemoryPermission permissions); | 42 | Svc::MemoryPermission permissions); |
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | * Unmaps a shared memory block from an address in the target process' address space | 45 | * Unmaps a shared memory block from an address in the target process' address space |
| @@ -47,7 +47,7 @@ public: | |||
| 47 | * @param address Address in system memory to unmap shared memory block | 47 | * @param address Address in system memory to unmap shared memory block |
| 48 | * @param unmap_size Size of the shared memory block to unmap | 48 | * @param unmap_size Size of the shared memory block to unmap |
| 49 | */ | 49 | */ |
| 50 | ResultCode Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size); | 50 | Result Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size); |
| 51 | 51 | ||
| 52 | /** | 52 | /** |
| 53 | * Gets a pointer to the shared memory block | 53 | * Gets a pointer to the shared memory block |
| @@ -77,7 +77,7 @@ public: | |||
| 77 | private: | 77 | private: |
| 78 | Core::DeviceMemory* device_memory; | 78 | Core::DeviceMemory* device_memory; |
| 79 | KProcess* owner_process{}; | 79 | KProcess* owner_process{}; |
| 80 | KPageLinkedList page_list; | 80 | KPageGroup page_list; |
| 81 | Svc::MemoryPermission owner_permission{}; | 81 | Svc::MemoryPermission owner_permission{}; |
| 82 | Svc::MemoryPermission user_permission{}; | 82 | Svc::MemoryPermission user_permission{}; |
| 83 | PAddr physical_address{}; | 83 | PAddr physical_address{}; |
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index 8554144d5..802dca046 100644 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp | |||
| @@ -22,7 +22,7 @@ public: | |||
| 22 | : KThreadQueueWithoutEndWait(kernel_), m_objects(o), m_nodes(n), m_count(c) {} | 22 | : KThreadQueueWithoutEndWait(kernel_), m_objects(o), m_nodes(n), m_count(c) {} |
| 23 | 23 | ||
| 24 | void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, | 24 | void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, |
| 25 | ResultCode wait_result) override { | 25 | Result wait_result) override { |
| 26 | // Determine the sync index, and unlink all nodes. | 26 | // Determine the sync index, and unlink all nodes. |
| 27 | s32 sync_index = -1; | 27 | s32 sync_index = -1; |
| 28 | for (auto i = 0; i < m_count; ++i) { | 28 | for (auto i = 0; i < m_count; ++i) { |
| @@ -45,8 +45,7 @@ public: | |||
| 45 | KThreadQueue::EndWait(waiting_thread, wait_result); | 45 | KThreadQueue::EndWait(waiting_thread, wait_result); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 48 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 49 | bool cancel_timer_task) override { | ||
| 50 | // Remove all nodes from our list. | 49 | // Remove all nodes from our list. |
| 51 | for (auto i = 0; i < m_count; ++i) { | 50 | for (auto i = 0; i < m_count; ++i) { |
| 52 | m_objects[i]->UnlinkNode(std::addressof(m_nodes[i])); | 51 | m_objects[i]->UnlinkNode(std::addressof(m_nodes[i])); |
| @@ -72,9 +71,9 @@ void KSynchronizationObject::Finalize() { | |||
| 72 | KAutoObject::Finalize(); | 71 | KAutoObject::Finalize(); |
| 73 | } | 72 | } |
| 74 | 73 | ||
| 75 | ResultCode KSynchronizationObject::Wait(KernelCore& kernel_ctx, s32* out_index, | 74 | Result KSynchronizationObject::Wait(KernelCore& kernel_ctx, s32* out_index, |
| 76 | KSynchronizationObject** objects, const s32 num_objects, | 75 | KSynchronizationObject** objects, const s32 num_objects, |
| 77 | s64 timeout) { | 76 | s64 timeout) { |
| 78 | // Allocate space on stack for thread nodes. | 77 | // Allocate space on stack for thread nodes. |
| 79 | std::vector<ThreadListNode> thread_nodes(num_objects); | 78 | std::vector<ThreadListNode> thread_nodes(num_objects); |
| 80 | 79 | ||
| @@ -148,7 +147,7 @@ KSynchronizationObject::KSynchronizationObject(KernelCore& kernel_) | |||
| 148 | 147 | ||
| 149 | KSynchronizationObject::~KSynchronizationObject() = default; | 148 | KSynchronizationObject::~KSynchronizationObject() = default; |
| 150 | 149 | ||
| 151 | void KSynchronizationObject::NotifyAvailable(ResultCode result) { | 150 | void KSynchronizationObject::NotifyAvailable(Result result) { |
| 152 | KScopedSchedulerLock sl(kernel); | 151 | KScopedSchedulerLock sl(kernel); |
| 153 | 152 | ||
| 154 | // If we're not signaled, we've nothing to notify. | 153 | // If we're not signaled, we've nothing to notify. |
diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index d7540d6c7..8d8122ab7 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h | |||
| @@ -24,9 +24,9 @@ public: | |||
| 24 | KThread* thread{}; | 24 | KThread* thread{}; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | [[nodiscard]] static ResultCode Wait(KernelCore& kernel, s32* out_index, | 27 | [[nodiscard]] static Result Wait(KernelCore& kernel, s32* out_index, |
| 28 | KSynchronizationObject** objects, const s32 num_objects, | 28 | KSynchronizationObject** objects, const s32 num_objects, |
| 29 | s64 timeout); | 29 | s64 timeout); |
| 30 | 30 | ||
| 31 | void Finalize() override; | 31 | void Finalize() override; |
| 32 | 32 | ||
| @@ -72,7 +72,7 @@ protected: | |||
| 72 | 72 | ||
| 73 | virtual void OnFinalizeSynchronizationObject() {} | 73 | virtual void OnFinalizeSynchronizationObject() {} |
| 74 | 74 | ||
| 75 | void NotifyAvailable(ResultCode result); | 75 | void NotifyAvailable(Result result); |
| 76 | void NotifyAvailable() { | 76 | void NotifyAvailable() { |
| 77 | return this->NotifyAvailable(ResultSuccess); | 77 | return this->NotifyAvailable(ResultSuccess); |
| 78 | } | 78 | } |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 940334f59..8d7faa662 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -80,8 +80,7 @@ public: | |||
| 80 | explicit ThreadQueueImplForKThreadSetProperty(KernelCore& kernel_, KThread::WaiterList* wl) | 80 | explicit ThreadQueueImplForKThreadSetProperty(KernelCore& kernel_, KThread::WaiterList* wl) |
| 81 | : KThreadQueue(kernel_), m_wait_list(wl) {} | 81 | : KThreadQueue(kernel_), m_wait_list(wl) {} |
| 82 | 82 | ||
| 83 | void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 83 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 84 | bool cancel_timer_task) override { | ||
| 85 | // Remove the thread from the wait list. | 84 | // Remove the thread from the wait list. |
| 86 | m_wait_list->erase(m_wait_list->iterator_to(*waiting_thread)); | 85 | m_wait_list->erase(m_wait_list->iterator_to(*waiting_thread)); |
| 87 | 86 | ||
| @@ -99,8 +98,8 @@ KThread::KThread(KernelCore& kernel_) | |||
| 99 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, activity_pause_lock{kernel_} {} | 98 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, activity_pause_lock{kernel_} {} |
| 100 | KThread::~KThread() = default; | 99 | KThread::~KThread() = default; |
| 101 | 100 | ||
| 102 | ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, | 101 | Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, |
| 103 | s32 virt_core, KProcess* owner, ThreadType type) { | 102 | s32 virt_core, KProcess* owner, ThreadType type) { |
| 104 | // Assert parameters are valid. | 103 | // Assert parameters are valid. |
| 105 | ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) || | 104 | ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) || |
| 106 | (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority)); | 105 | (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority)); |
| @@ -133,7 +132,7 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s | |||
| 133 | UNIMPLEMENTED(); | 132 | UNIMPLEMENTED(); |
| 134 | break; | 133 | break; |
| 135 | default: | 134 | default: |
| 136 | UNREACHABLE_MSG("KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type)); | 135 | ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type)); |
| 137 | break; | 136 | break; |
| 138 | } | 137 | } |
| 139 | thread_type = type; | 138 | thread_type = type; |
| @@ -225,7 +224,7 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s | |||
| 225 | // Setup the stack parameters. | 224 | // Setup the stack parameters. |
| 226 | StackParameters& sp = GetStackParameters(); | 225 | StackParameters& sp = GetStackParameters(); |
| 227 | sp.cur_thread = this; | 226 | sp.cur_thread = this; |
| 228 | sp.disable_count = 0; | 227 | sp.disable_count = 1; |
| 229 | SetInExceptionHandler(); | 228 | SetInExceptionHandler(); |
| 230 | 229 | ||
| 231 | // Set thread ID. | 230 | // Set thread ID. |
| @@ -245,10 +244,10 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s | |||
| 245 | return ResultSuccess; | 244 | return ResultSuccess; |
| 246 | } | 245 | } |
| 247 | 246 | ||
| 248 | ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, | 247 | Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, |
| 249 | VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, | 248 | VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, |
| 250 | ThreadType type, std::function<void(void*)>&& init_func, | 249 | ThreadType type, std::function<void(void*)>&& init_func, |
| 251 | void* init_func_parameter) { | 250 | void* init_func_parameter) { |
| 252 | // Initialize the thread. | 251 | // Initialize the thread. |
| 253 | R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); | 252 | R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); |
| 254 | 253 | ||
| @@ -260,31 +259,30 @@ ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uint | |||
| 260 | return ResultSuccess; | 259 | return ResultSuccess; |
| 261 | } | 260 | } |
| 262 | 261 | ||
| 263 | ResultCode KThread::InitializeDummyThread(KThread* thread) { | 262 | Result KThread::InitializeDummyThread(KThread* thread) { |
| 264 | return thread->Initialize({}, {}, {}, DummyThreadPriority, 3, {}, ThreadType::Dummy); | 263 | return thread->Initialize({}, {}, {}, DummyThreadPriority, 3, {}, ThreadType::Dummy); |
| 265 | } | 264 | } |
| 266 | 265 | ||
| 267 | ResultCode KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { | 266 | Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { |
| 268 | return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, | 267 | return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, |
| 269 | Core::CpuManager::GetIdleThreadStartFunc(), | 268 | Core::CpuManager::GetIdleThreadStartFunc(), |
| 270 | system.GetCpuManager().GetStartFuncParamater()); | 269 | system.GetCpuManager().GetStartFuncParameter()); |
| 271 | } | 270 | } |
| 272 | 271 | ||
| 273 | ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, | 272 | Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, |
| 274 | KThreadFunction func, uintptr_t arg, | 273 | KThreadFunction func, uintptr_t arg, s32 virt_core) { |
| 275 | s32 virt_core) { | ||
| 276 | return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, | 274 | return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, |
| 277 | Core::CpuManager::GetSuspendThreadStartFunc(), | 275 | Core::CpuManager::GetShutdownThreadStartFunc(), |
| 278 | system.GetCpuManager().GetStartFuncParamater()); | 276 | system.GetCpuManager().GetStartFuncParameter()); |
| 279 | } | 277 | } |
| 280 | 278 | ||
| 281 | ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, | 279 | Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func, |
| 282 | KThreadFunction func, uintptr_t arg, VAddr user_stack_top, | 280 | uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core, |
| 283 | s32 prio, s32 virt_core, KProcess* owner) { | 281 | KProcess* owner) { |
| 284 | system.Kernel().GlobalSchedulerContext().AddThread(thread); | 282 | system.Kernel().GlobalSchedulerContext().AddThread(thread); |
| 285 | return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, | 283 | return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, |
| 286 | ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), | 284 | ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), |
| 287 | system.GetCpuManager().GetStartFuncParamater()); | 285 | system.GetCpuManager().GetStartFuncParameter()); |
| 288 | } | 286 | } |
| 289 | 287 | ||
| 290 | void KThread::PostDestroy(uintptr_t arg) { | 288 | void KThread::PostDestroy(uintptr_t arg) { |
| @@ -382,7 +380,7 @@ void KThread::FinishTermination() { | |||
| 382 | for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { | 380 | for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { |
| 383 | KThread* core_thread{}; | 381 | KThread* core_thread{}; |
| 384 | do { | 382 | do { |
| 385 | core_thread = kernel.Scheduler(i).GetCurrentThread(); | 383 | core_thread = kernel.Scheduler(i).GetSchedulerCurrentThread(); |
| 386 | } while (core_thread == this); | 384 | } while (core_thread == this); |
| 387 | } | 385 | } |
| 388 | } | 386 | } |
| @@ -523,7 +521,7 @@ void KThread::ClearInterruptFlag() { | |||
| 523 | memory.Write16(tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); | 521 | memory.Write16(tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); |
| 524 | } | 522 | } |
| 525 | 523 | ||
| 526 | ResultCode KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { | 524 | Result KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { |
| 527 | KScopedSchedulerLock sl{kernel}; | 525 | KScopedSchedulerLock sl{kernel}; |
| 528 | 526 | ||
| 529 | // Get the virtual mask. | 527 | // Get the virtual mask. |
| @@ -533,7 +531,7 @@ ResultCode KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { | |||
| 533 | return ResultSuccess; | 531 | return ResultSuccess; |
| 534 | } | 532 | } |
| 535 | 533 | ||
| 536 | ResultCode KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { | 534 | Result KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { |
| 537 | KScopedSchedulerLock sl{kernel}; | 535 | KScopedSchedulerLock sl{kernel}; |
| 538 | ASSERT(num_core_migration_disables >= 0); | 536 | ASSERT(num_core_migration_disables >= 0); |
| 539 | 537 | ||
| @@ -549,7 +547,7 @@ ResultCode KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_m | |||
| 549 | return ResultSuccess; | 547 | return ResultSuccess; |
| 550 | } | 548 | } |
| 551 | 549 | ||
| 552 | ResultCode KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) { | 550 | Result KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) { |
| 553 | ASSERT(parent != nullptr); | 551 | ASSERT(parent != nullptr); |
| 554 | ASSERT(v_affinity_mask != 0); | 552 | ASSERT(v_affinity_mask != 0); |
| 555 | KScopedLightLock lk(activity_pause_lock); | 553 | KScopedLightLock lk(activity_pause_lock); |
| @@ -631,7 +629,7 @@ ResultCode KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) { | |||
| 631 | s32 thread_core; | 629 | s32 thread_core; |
| 632 | for (thread_core = 0; thread_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); | 630 | for (thread_core = 0; thread_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); |
| 633 | ++thread_core) { | 631 | ++thread_core) { |
| 634 | if (kernel.Scheduler(thread_core).GetCurrentThread() == this) { | 632 | if (kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) { |
| 635 | thread_is_current = true; | 633 | thread_is_current = true; |
| 636 | break; | 634 | break; |
| 637 | } | 635 | } |
| @@ -748,7 +746,20 @@ void KThread::Continue() { | |||
| 748 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 746 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 749 | } | 747 | } |
| 750 | 748 | ||
| 751 | ResultCode KThread::SetActivity(Svc::ThreadActivity activity) { | 749 | void KThread::WaitUntilSuspended() { |
| 750 | // Make sure we have a suspend requested. | ||
| 751 | ASSERT(IsSuspendRequested()); | ||
| 752 | |||
| 753 | // Loop until the thread is not executing on any core. | ||
| 754 | for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||
| 755 | KThread* core_thread{}; | ||
| 756 | do { | ||
| 757 | core_thread = kernel.Scheduler(i).GetSchedulerCurrentThread(); | ||
| 758 | } while (core_thread == this); | ||
| 759 | } | ||
| 760 | } | ||
| 761 | |||
| 762 | Result KThread::SetActivity(Svc::ThreadActivity activity) { | ||
| 752 | // Lock ourselves. | 763 | // Lock ourselves. |
| 753 | KScopedLightLock lk(activity_pause_lock); | 764 | KScopedLightLock lk(activity_pause_lock); |
| 754 | 765 | ||
| @@ -809,7 +820,7 @@ ResultCode KThread::SetActivity(Svc::ThreadActivity activity) { | |||
| 809 | // Check if the thread is currently running. | 820 | // Check if the thread is currently running. |
| 810 | // If it is, we'll need to retry. | 821 | // If it is, we'll need to retry. |
| 811 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | 822 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { |
| 812 | if (kernel.Scheduler(i).GetCurrentThread() == this) { | 823 | if (kernel.Scheduler(i).GetSchedulerCurrentThread() == this) { |
| 813 | thread_is_current = true; | 824 | thread_is_current = true; |
| 814 | break; | 825 | break; |
| 815 | } | 826 | } |
| @@ -821,7 +832,7 @@ ResultCode KThread::SetActivity(Svc::ThreadActivity activity) { | |||
| 821 | return ResultSuccess; | 832 | return ResultSuccess; |
| 822 | } | 833 | } |
| 823 | 834 | ||
| 824 | ResultCode KThread::GetThreadContext3(std::vector<u8>& out) { | 835 | Result KThread::GetThreadContext3(std::vector<u8>& out) { |
| 825 | // Lock ourselves. | 836 | // Lock ourselves. |
| 826 | KScopedLightLock lk{activity_pause_lock}; | 837 | KScopedLightLock lk{activity_pause_lock}; |
| 827 | 838 | ||
| @@ -986,7 +997,7 @@ KThread* KThread::RemoveWaiterByKey(s32* out_num_waiters, VAddr key) { | |||
| 986 | return next_lock_owner; | 997 | return next_lock_owner; |
| 987 | } | 998 | } |
| 988 | 999 | ||
| 989 | ResultCode KThread::Run() { | 1000 | Result KThread::Run() { |
| 990 | while (true) { | 1001 | while (true) { |
| 991 | KScopedSchedulerLock lk{kernel}; | 1002 | KScopedSchedulerLock lk{kernel}; |
| 992 | 1003 | ||
| @@ -1014,8 +1025,6 @@ ResultCode KThread::Run() { | |||
| 1014 | // Set our state and finish. | 1025 | // Set our state and finish. |
| 1015 | SetState(ThreadState::Runnable); | 1026 | SetState(ThreadState::Runnable); |
| 1016 | 1027 | ||
| 1017 | DisableDispatch(); | ||
| 1018 | |||
| 1019 | return ResultSuccess; | 1028 | return ResultSuccess; |
| 1020 | } | 1029 | } |
| 1021 | } | 1030 | } |
| @@ -1049,7 +1058,7 @@ void KThread::Exit() { | |||
| 1049 | } | 1058 | } |
| 1050 | } | 1059 | } |
| 1051 | 1060 | ||
| 1052 | ResultCode KThread::Sleep(s64 timeout) { | 1061 | Result KThread::Sleep(s64 timeout) { |
| 1053 | ASSERT(!kernel.GlobalSchedulerContext().IsLocked()); | 1062 | ASSERT(!kernel.GlobalSchedulerContext().IsLocked()); |
| 1054 | ASSERT(this == GetCurrentThreadPointer(kernel)); | 1063 | ASSERT(this == GetCurrentThreadPointer(kernel)); |
| 1055 | ASSERT(timeout > 0); | 1064 | ASSERT(timeout > 0); |
| @@ -1105,7 +1114,7 @@ void KThread::BeginWait(KThreadQueue* queue) { | |||
| 1105 | wait_queue = queue; | 1114 | wait_queue = queue; |
| 1106 | } | 1115 | } |
| 1107 | 1116 | ||
| 1108 | void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, ResultCode wait_result_) { | 1117 | void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, Result wait_result_) { |
| 1109 | // Lock the scheduler. | 1118 | // Lock the scheduler. |
| 1110 | KScopedSchedulerLock sl(kernel); | 1119 | KScopedSchedulerLock sl(kernel); |
| 1111 | 1120 | ||
| @@ -1115,7 +1124,7 @@ void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, ResultCod | |||
| 1115 | } | 1124 | } |
| 1116 | } | 1125 | } |
| 1117 | 1126 | ||
| 1118 | void KThread::EndWait(ResultCode wait_result_) { | 1127 | void KThread::EndWait(Result wait_result_) { |
| 1119 | // Lock the scheduler. | 1128 | // Lock the scheduler. |
| 1120 | KScopedSchedulerLock sl(kernel); | 1129 | KScopedSchedulerLock sl(kernel); |
| 1121 | 1130 | ||
| @@ -1134,7 +1143,7 @@ void KThread::EndWait(ResultCode wait_result_) { | |||
| 1134 | } | 1143 | } |
| 1135 | } | 1144 | } |
| 1136 | 1145 | ||
| 1137 | void KThread::CancelWait(ResultCode wait_result_, bool cancel_timer_task) { | 1146 | void KThread::CancelWait(Result wait_result_, bool cancel_timer_task) { |
| 1138 | // Lock the scheduler. | 1147 | // Lock the scheduler. |
| 1139 | KScopedSchedulerLock sl(kernel); | 1148 | KScopedSchedulerLock sl(kernel); |
| 1140 | 1149 | ||
| @@ -1164,6 +1173,10 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() { | |||
| 1164 | return host_context; | 1173 | return host_context; |
| 1165 | } | 1174 | } |
| 1166 | 1175 | ||
| 1176 | void SetCurrentThread(KernelCore& kernel, KThread* thread) { | ||
| 1177 | kernel.SetCurrentEmuThread(thread); | ||
| 1178 | } | ||
| 1179 | |||
| 1167 | KThread* GetCurrentThreadPointer(KernelCore& kernel) { | 1180 | KThread* GetCurrentThreadPointer(KernelCore& kernel) { |
| 1168 | return kernel.GetCurrentEmuThread(); | 1181 | return kernel.GetCurrentEmuThread(); |
| 1169 | } | 1182 | } |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index f4d83f99a..94c4cd1c8 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -106,6 +106,7 @@ enum class StepState : u32 { | |||
| 106 | StepPerformed, ///< Thread has stepped, waiting to be scheduled again | 106 | StepPerformed, ///< Thread has stepped, waiting to be scheduled again |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | void SetCurrentThread(KernelCore& kernel, KThread* thread); | ||
| 109 | [[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); | 110 | [[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); |
| 110 | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); | 111 | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); |
| 111 | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); | 112 | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); |
| @@ -175,7 +176,7 @@ public: | |||
| 175 | 176 | ||
| 176 | void SetBasePriority(s32 value); | 177 | void SetBasePriority(s32 value); |
| 177 | 178 | ||
| 178 | [[nodiscard]] ResultCode Run(); | 179 | [[nodiscard]] Result Run(); |
| 179 | 180 | ||
| 180 | void Exit(); | 181 | void Exit(); |
| 181 | 182 | ||
| @@ -207,6 +208,8 @@ public: | |||
| 207 | 208 | ||
| 208 | void Continue(); | 209 | void Continue(); |
| 209 | 210 | ||
| 211 | void WaitUntilSuspended(); | ||
| 212 | |||
| 210 | constexpr void SetSyncedIndex(s32 index) { | 213 | constexpr void SetSyncedIndex(s32 index) { |
| 211 | synced_index = index; | 214 | synced_index = index; |
| 212 | } | 215 | } |
| @@ -215,11 +218,11 @@ public: | |||
| 215 | return synced_index; | 218 | return synced_index; |
| 216 | } | 219 | } |
| 217 | 220 | ||
| 218 | constexpr void SetWaitResult(ResultCode wait_res) { | 221 | constexpr void SetWaitResult(Result wait_res) { |
| 219 | wait_result = wait_res; | 222 | wait_result = wait_res; |
| 220 | } | 223 | } |
| 221 | 224 | ||
| 222 | [[nodiscard]] constexpr ResultCode GetWaitResult() const { | 225 | [[nodiscard]] constexpr Result GetWaitResult() const { |
| 223 | return wait_result; | 226 | return wait_result; |
| 224 | } | 227 | } |
| 225 | 228 | ||
| @@ -342,15 +345,15 @@ public: | |||
| 342 | return physical_affinity_mask; | 345 | return physical_affinity_mask; |
| 343 | } | 346 | } |
| 344 | 347 | ||
| 345 | [[nodiscard]] ResultCode GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask); | 348 | [[nodiscard]] Result GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask); |
| 346 | 349 | ||
| 347 | [[nodiscard]] ResultCode GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask); | 350 | [[nodiscard]] Result GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask); |
| 348 | 351 | ||
| 349 | [[nodiscard]] ResultCode SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask); | 352 | [[nodiscard]] Result SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask); |
| 350 | 353 | ||
| 351 | [[nodiscard]] ResultCode SetActivity(Svc::ThreadActivity activity); | 354 | [[nodiscard]] Result SetActivity(Svc::ThreadActivity activity); |
| 352 | 355 | ||
| 353 | [[nodiscard]] ResultCode Sleep(s64 timeout); | 356 | [[nodiscard]] Result Sleep(s64 timeout); |
| 354 | 357 | ||
| 355 | [[nodiscard]] s64 GetYieldScheduleCount() const { | 358 | [[nodiscard]] s64 GetYieldScheduleCount() const { |
| 356 | return schedule_count; | 359 | return schedule_count; |
| @@ -408,20 +411,19 @@ public: | |||
| 408 | 411 | ||
| 409 | static void PostDestroy(uintptr_t arg); | 412 | static void PostDestroy(uintptr_t arg); |
| 410 | 413 | ||
| 411 | [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread); | 414 | [[nodiscard]] static Result InitializeDummyThread(KThread* thread); |
| 412 | 415 | ||
| 413 | [[nodiscard]] static ResultCode InitializeIdleThread(Core::System& system, KThread* thread, | 416 | [[nodiscard]] static Result InitializeIdleThread(Core::System& system, KThread* thread, |
| 414 | s32 virt_core); | 417 | s32 virt_core); |
| 415 | 418 | ||
| 416 | [[nodiscard]] static ResultCode InitializeHighPriorityThread(Core::System& system, | 419 | [[nodiscard]] static Result InitializeHighPriorityThread(Core::System& system, KThread* thread, |
| 417 | KThread* thread, | 420 | KThreadFunction func, uintptr_t arg, |
| 418 | KThreadFunction func, | 421 | s32 virt_core); |
| 419 | uintptr_t arg, s32 virt_core); | ||
| 420 | 422 | ||
| 421 | [[nodiscard]] static ResultCode InitializeUserThread(Core::System& system, KThread* thread, | 423 | [[nodiscard]] static Result InitializeUserThread(Core::System& system, KThread* thread, |
| 422 | KThreadFunction func, uintptr_t arg, | 424 | KThreadFunction func, uintptr_t arg, |
| 423 | VAddr user_stack_top, s32 prio, | 425 | VAddr user_stack_top, s32 prio, s32 virt_core, |
| 424 | s32 virt_core, KProcess* owner); | 426 | KProcess* owner); |
| 425 | 427 | ||
| 426 | public: | 428 | public: |
| 427 | struct StackParameters { | 429 | struct StackParameters { |
| @@ -607,7 +609,7 @@ public: | |||
| 607 | 609 | ||
| 608 | void RemoveWaiter(KThread* thread); | 610 | void RemoveWaiter(KThread* thread); |
| 609 | 611 | ||
| 610 | [[nodiscard]] ResultCode GetThreadContext3(std::vector<u8>& out); | 612 | [[nodiscard]] Result GetThreadContext3(std::vector<u8>& out); |
| 611 | 613 | ||
| 612 | [[nodiscard]] KThread* RemoveWaiterByKey(s32* out_num_waiters, VAddr key); | 614 | [[nodiscard]] KThread* RemoveWaiterByKey(s32* out_num_waiters, VAddr key); |
| 613 | 615 | ||
| @@ -633,9 +635,9 @@ public: | |||
| 633 | } | 635 | } |
| 634 | 636 | ||
| 635 | void BeginWait(KThreadQueue* queue); | 637 | void BeginWait(KThreadQueue* queue); |
| 636 | void NotifyAvailable(KSynchronizationObject* signaled_object, ResultCode wait_result_); | 638 | void NotifyAvailable(KSynchronizationObject* signaled_object, Result wait_result_); |
| 637 | void EndWait(ResultCode wait_result_); | 639 | void EndWait(Result wait_result_); |
| 638 | void CancelWait(ResultCode wait_result_, bool cancel_timer_task); | 640 | void CancelWait(Result wait_result_, bool cancel_timer_task); |
| 639 | 641 | ||
| 640 | [[nodiscard]] bool HasWaiters() const { | 642 | [[nodiscard]] bool HasWaiters() const { |
| 641 | return !waiter_list.empty(); | 643 | return !waiter_list.empty(); |
| @@ -721,14 +723,14 @@ private: | |||
| 721 | 723 | ||
| 722 | void FinishTermination(); | 724 | void FinishTermination(); |
| 723 | 725 | ||
| 724 | [[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, | 726 | [[nodiscard]] Result Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, |
| 725 | s32 prio, s32 virt_core, KProcess* owner, ThreadType type); | 727 | s32 prio, s32 virt_core, KProcess* owner, ThreadType type); |
| 726 | 728 | ||
| 727 | [[nodiscard]] static ResultCode InitializeThread(KThread* thread, KThreadFunction func, | 729 | [[nodiscard]] static Result InitializeThread(KThread* thread, KThreadFunction func, |
| 728 | uintptr_t arg, VAddr user_stack_top, s32 prio, | 730 | uintptr_t arg, VAddr user_stack_top, s32 prio, |
| 729 | s32 core, KProcess* owner, ThreadType type, | 731 | s32 core, KProcess* owner, ThreadType type, |
| 730 | std::function<void(void*)>&& init_func, | 732 | std::function<void(void*)>&& init_func, |
| 731 | void* init_func_parameter); | 733 | void* init_func_parameter); |
| 732 | 734 | ||
| 733 | static void RestorePriority(KernelCore& kernel_ctx, KThread* thread); | 735 | static void RestorePriority(KernelCore& kernel_ctx, KThread* thread); |
| 734 | 736 | ||
| @@ -765,7 +767,7 @@ private: | |||
| 765 | u32 suspend_request_flags{}; | 767 | u32 suspend_request_flags{}; |
| 766 | u32 suspend_allowed_flags{}; | 768 | u32 suspend_allowed_flags{}; |
| 767 | s32 synced_index{}; | 769 | s32 synced_index{}; |
| 768 | ResultCode wait_result{ResultSuccess}; | 770 | Result wait_result{ResultSuccess}; |
| 769 | s32 base_priority{}; | 771 | s32 base_priority{}; |
| 770 | s32 physical_ideal_core_id{}; | 772 | s32 physical_ideal_core_id{}; |
| 771 | s32 virtual_ideal_core_id{}; | 773 | s32 virtual_ideal_core_id{}; |
diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp index fbdc40b3a..563560114 100644 --- a/src/core/hle/kernel/k_thread_local_page.cpp +++ b/src/core/hle/kernel/k_thread_local_page.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | ResultCode KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { | 16 | Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { |
| 17 | // Set that this process owns us. | 17 | // Set that this process owns us. |
| 18 | m_owner = process; | 18 | m_owner = process; |
| 19 | m_kernel = &kernel; | 19 | m_kernel = &kernel; |
| @@ -35,7 +35,7 @@ ResultCode KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { | |||
| 35 | return ResultSuccess; | 35 | return ResultSuccess; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | ResultCode KThreadLocalPage::Finalize() { | 38 | Result KThreadLocalPage::Finalize() { |
| 39 | // Get the physical address of the page. | 39 | // Get the physical address of the page. |
| 40 | const PAddr phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr); | 40 | const PAddr phys_addr = m_owner->PageTable().GetPhysicalAddr(m_virt_addr); |
| 41 | ASSERT(phys_addr); | 41 | ASSERT(phys_addr); |
diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h index a4fe43ee5..0a7f22680 100644 --- a/src/core/hle/kernel/k_thread_local_page.h +++ b/src/core/hle/kernel/k_thread_local_page.h | |||
| @@ -34,8 +34,8 @@ public: | |||
| 34 | return m_virt_addr; | 34 | return m_virt_addr; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | ResultCode Initialize(KernelCore& kernel, KProcess* process); | 37 | Result Initialize(KernelCore& kernel, KProcess* process); |
| 38 | ResultCode Finalize(); | 38 | Result Finalize(); |
| 39 | 39 | ||
| 40 | VAddr Reserve(); | 40 | VAddr Reserve(); |
| 41 | void Release(VAddr addr); | 41 | void Release(VAddr addr); |
diff --git a/src/core/hle/kernel/k_thread_queue.cpp b/src/core/hle/kernel/k_thread_queue.cpp index 1c338904a..9f4e081ba 100644 --- a/src/core/hle/kernel/k_thread_queue.cpp +++ b/src/core/hle/kernel/k_thread_queue.cpp | |||
| @@ -9,9 +9,9 @@ namespace Kernel { | |||
| 9 | 9 | ||
| 10 | void KThreadQueue::NotifyAvailable([[maybe_unused]] KThread* waiting_thread, | 10 | void KThreadQueue::NotifyAvailable([[maybe_unused]] KThread* waiting_thread, |
| 11 | [[maybe_unused]] KSynchronizationObject* signaled_object, | 11 | [[maybe_unused]] KSynchronizationObject* signaled_object, |
| 12 | [[maybe_unused]] ResultCode wait_result) {} | 12 | [[maybe_unused]] Result wait_result) {} |
| 13 | 13 | ||
| 14 | void KThreadQueue::EndWait(KThread* waiting_thread, ResultCode wait_result) { | 14 | void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) { |
| 15 | // Set the thread's wait result. | 15 | // Set the thread's wait result. |
| 16 | waiting_thread->SetWaitResult(wait_result); | 16 | waiting_thread->SetWaitResult(wait_result); |
| 17 | 17 | ||
| @@ -25,8 +25,7 @@ void KThreadQueue::EndWait(KThread* waiting_thread, ResultCode wait_result) { | |||
| 25 | kernel.TimeManager().UnscheduleTimeEvent(waiting_thread); | 25 | kernel.TimeManager().UnscheduleTimeEvent(waiting_thread); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | void KThreadQueue::CancelWait(KThread* waiting_thread, ResultCode wait_result, | 28 | void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) { |
| 29 | bool cancel_timer_task) { | ||
| 30 | // Set the thread's wait result. | 29 | // Set the thread's wait result. |
| 31 | waiting_thread->SetWaitResult(wait_result); | 30 | waiting_thread->SetWaitResult(wait_result); |
| 32 | 31 | ||
| @@ -43,6 +42,6 @@ void KThreadQueue::CancelWait(KThread* waiting_thread, ResultCode wait_result, | |||
| 43 | } | 42 | } |
| 44 | 43 | ||
| 45 | void KThreadQueueWithoutEndWait::EndWait([[maybe_unused]] KThread* waiting_thread, | 44 | void KThreadQueueWithoutEndWait::EndWait([[maybe_unused]] KThread* waiting_thread, |
| 46 | [[maybe_unused]] ResultCode wait_result) {} | 45 | [[maybe_unused]] Result wait_result) {} |
| 47 | 46 | ||
| 48 | } // namespace Kernel | 47 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_thread_queue.h b/src/core/hle/kernel/k_thread_queue.h index 4a7dbdd47..8d76ece81 100644 --- a/src/core/hle/kernel/k_thread_queue.h +++ b/src/core/hle/kernel/k_thread_queue.h | |||
| @@ -14,10 +14,9 @@ public: | |||
| 14 | virtual ~KThreadQueue() = default; | 14 | virtual ~KThreadQueue() = default; |
| 15 | 15 | ||
| 16 | virtual void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, | 16 | virtual void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, |
| 17 | ResultCode wait_result); | 17 | Result wait_result); |
| 18 | virtual void EndWait(KThread* waiting_thread, ResultCode wait_result); | 18 | virtual void EndWait(KThread* waiting_thread, Result wait_result); |
| 19 | virtual void CancelWait(KThread* waiting_thread, ResultCode wait_result, | 19 | virtual void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task); |
| 20 | bool cancel_timer_task); | ||
| 21 | 20 | ||
| 22 | private: | 21 | private: |
| 23 | KernelCore& kernel; | 22 | KernelCore& kernel; |
| @@ -28,7 +27,7 @@ class KThreadQueueWithoutEndWait : public KThreadQueue { | |||
| 28 | public: | 27 | public: |
| 29 | explicit KThreadQueueWithoutEndWait(KernelCore& kernel_) : KThreadQueue(kernel_) {} | 28 | explicit KThreadQueueWithoutEndWait(KernelCore& kernel_) : KThreadQueue(kernel_) {} |
| 30 | 29 | ||
| 31 | void EndWait(KThread* waiting_thread, ResultCode wait_result) override final; | 30 | void EndWait(KThread* waiting_thread, Result wait_result) override final; |
| 32 | }; | 31 | }; |
| 33 | 32 | ||
| 34 | } // namespace Kernel | 33 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp index 1ed4b0f6f..b0320eb73 100644 --- a/src/core/hle/kernel/k_transfer_memory.cpp +++ b/src/core/hle/kernel/k_transfer_memory.cpp | |||
| @@ -13,8 +13,8 @@ KTransferMemory::KTransferMemory(KernelCore& kernel_) | |||
| 13 | 13 | ||
| 14 | KTransferMemory::~KTransferMemory() = default; | 14 | KTransferMemory::~KTransferMemory() = default; |
| 15 | 15 | ||
| 16 | ResultCode KTransferMemory::Initialize(VAddr address_, std::size_t size_, | 16 | Result KTransferMemory::Initialize(VAddr address_, std::size_t size_, |
| 17 | Svc::MemoryPermission owner_perm_) { | 17 | Svc::MemoryPermission owner_perm_) { |
| 18 | // Set members. | 18 | // Set members. |
| 19 | owner = kernel.CurrentProcess(); | 19 | owner = kernel.CurrentProcess(); |
| 20 | 20 | ||
diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index 9ad80ba30..85d508ee7 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "core/hle/kernel/svc_types.h" | 7 | #include "core/hle/kernel/svc_types.h" |
| 8 | #include "core/hle/result.h" | 8 | #include "core/hle/result.h" |
| 9 | 9 | ||
| 10 | union ResultCode; | 10 | union Result; |
| 11 | 11 | ||
| 12 | namespace Core::Memory { | 12 | namespace Core::Memory { |
| 13 | class Memory; | 13 | class Memory; |
| @@ -26,7 +26,7 @@ public: | |||
| 26 | explicit KTransferMemory(KernelCore& kernel_); | 26 | explicit KTransferMemory(KernelCore& kernel_); |
| 27 | ~KTransferMemory() override; | 27 | ~KTransferMemory() override; |
| 28 | 28 | ||
| 29 | ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); | 29 | Result Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); |
| 30 | 30 | ||
| 31 | void Finalize() override; | 31 | void Finalize() override; |
| 32 | 32 | ||
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp index 26c8489ad..ff88c5acd 100644 --- a/src/core/hle/kernel/k_writable_event.cpp +++ b/src/core/hle/kernel/k_writable_event.cpp | |||
| @@ -18,11 +18,11 @@ void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) { | |||
| 18 | parent->GetReadableEvent().Open(); | 18 | parent->GetReadableEvent().Open(); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | ResultCode KWritableEvent::Signal() { | 21 | Result KWritableEvent::Signal() { |
| 22 | return parent->GetReadableEvent().Signal(); | 22 | return parent->GetReadableEvent().Signal(); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | ResultCode KWritableEvent::Clear() { | 25 | Result KWritableEvent::Clear() { |
| 26 | return parent->GetReadableEvent().Clear(); | 26 | return parent->GetReadableEvent().Clear(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h index e289e80c4..3fd0c7d0a 100644 --- a/src/core/hle/kernel/k_writable_event.h +++ b/src/core/hle/kernel/k_writable_event.h | |||
| @@ -25,8 +25,8 @@ public: | |||
| 25 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} | 25 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} |
| 26 | 26 | ||
| 27 | void Initialize(KEvent* parent_, std::string&& name_); | 27 | void Initialize(KEvent* parent_, std::string&& name_); |
| 28 | ResultCode Signal(); | 28 | Result Signal(); |
| 29 | ResultCode Clear(); | 29 | Result Clear(); |
| 30 | 30 | ||
| 31 | KEvent* GetParent() const { | 31 | KEvent* GetParent() const { |
| 32 | return parent; | 32 | return parent; |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 92f6d8c49..0009193be 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -76,7 +76,7 @@ struct KernelCore::Impl { | |||
| 76 | InitializeMemoryLayout(); | 76 | InitializeMemoryLayout(); |
| 77 | Init::InitializeKPageBufferSlabHeap(system); | 77 | Init::InitializeKPageBufferSlabHeap(system); |
| 78 | InitializeSchedulers(); | 78 | InitializeSchedulers(); |
| 79 | InitializeSuspendThreads(); | 79 | InitializeShutdownThreads(); |
| 80 | InitializePreemption(kernel); | 80 | InitializePreemption(kernel); |
| 81 | 81 | ||
| 82 | RegisterHostThread(); | 82 | RegisterHostThread(); |
| @@ -143,9 +143,9 @@ struct KernelCore::Impl { | |||
| 143 | CleanupObject(system_resource_limit); | 143 | CleanupObject(system_resource_limit); |
| 144 | 144 | ||
| 145 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 145 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 146 | if (suspend_threads[core_id]) { | 146 | if (shutdown_threads[core_id]) { |
| 147 | suspend_threads[core_id]->Close(); | 147 | shutdown_threads[core_id]->Close(); |
| 148 | suspend_threads[core_id] = nullptr; | 148 | shutdown_threads[core_id] = nullptr; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | schedulers[core_id]->Finalize(); | 151 | schedulers[core_id]->Finalize(); |
| @@ -212,7 +212,9 @@ struct KernelCore::Impl { | |||
| 212 | system_resource_limit = KResourceLimit::Create(system.Kernel()); | 212 | system_resource_limit = KResourceLimit::Create(system.Kernel()); |
| 213 | system_resource_limit->Initialize(&core_timing); | 213 | system_resource_limit->Initialize(&core_timing); |
| 214 | 214 | ||
| 215 | const auto [total_size, kernel_size] = memory_layout->GetTotalAndKernelMemorySizes(); | 215 | const auto sizes{memory_layout->GetTotalAndKernelMemorySizes()}; |
| 216 | const auto total_size{sizes.first}; | ||
| 217 | const auto kernel_size{sizes.second}; | ||
| 216 | 218 | ||
| 217 | // If setting the default system values fails, then something seriously wrong has occurred. | 219 | // If setting the default system values fails, then something seriously wrong has occurred. |
| 218 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size) | 220 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size) |
| @@ -245,13 +247,13 @@ struct KernelCore::Impl { | |||
| 245 | system.CoreTiming().ScheduleEvent(time_interval, preemption_event); | 247 | system.CoreTiming().ScheduleEvent(time_interval, preemption_event); |
| 246 | } | 248 | } |
| 247 | 249 | ||
| 248 | void InitializeSuspendThreads() { | 250 | void InitializeShutdownThreads() { |
| 249 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 251 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 250 | suspend_threads[core_id] = KThread::Create(system.Kernel()); | 252 | shutdown_threads[core_id] = KThread::Create(system.Kernel()); |
| 251 | ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, | 253 | ASSERT(KThread::InitializeHighPriorityThread(system, shutdown_threads[core_id], {}, {}, |
| 252 | core_id) | 254 | core_id) |
| 253 | .IsSuccess()); | 255 | .IsSuccess()); |
| 254 | suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); | 256 | shutdown_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); |
| 255 | } | 257 | } |
| 256 | } | 258 | } |
| 257 | 259 | ||
| @@ -329,6 +331,8 @@ struct KernelCore::Impl { | |||
| 329 | return is_shutting_down.load(std::memory_order_relaxed); | 331 | return is_shutting_down.load(std::memory_order_relaxed); |
| 330 | } | 332 | } |
| 331 | 333 | ||
| 334 | static inline thread_local KThread* current_thread{nullptr}; | ||
| 335 | |||
| 332 | KThread* GetCurrentEmuThread() { | 336 | KThread* GetCurrentEmuThread() { |
| 333 | // If we are shutting down the kernel, none of this is relevant anymore. | 337 | // If we are shutting down the kernel, none of this is relevant anymore. |
| 334 | if (IsShuttingDown()) { | 338 | if (IsShuttingDown()) { |
| @@ -339,7 +343,12 @@ struct KernelCore::Impl { | |||
| 339 | if (thread_id >= Core::Hardware::NUM_CPU_CORES) { | 343 | if (thread_id >= Core::Hardware::NUM_CPU_CORES) { |
| 340 | return GetHostDummyThread(); | 344 | return GetHostDummyThread(); |
| 341 | } | 345 | } |
| 342 | return schedulers[thread_id]->GetCurrentThread(); | 346 | |
| 347 | return current_thread; | ||
| 348 | } | ||
| 349 | |||
| 350 | void SetCurrentEmuThread(KThread* thread) { | ||
| 351 | current_thread = thread; | ||
| 343 | } | 352 | } |
| 344 | 353 | ||
| 345 | void DeriveInitialMemoryLayout() { | 354 | void DeriveInitialMemoryLayout() { |
| @@ -766,7 +775,7 @@ struct KernelCore::Impl { | |||
| 766 | std::weak_ptr<ServiceThread> default_service_thread; | 775 | std::weak_ptr<ServiceThread> default_service_thread; |
| 767 | Common::ThreadWorker service_threads_manager; | 776 | Common::ThreadWorker service_threads_manager; |
| 768 | 777 | ||
| 769 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; | 778 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; |
| 770 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | 779 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; |
| 771 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 780 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| 772 | 781 | ||
| @@ -917,6 +926,12 @@ const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { | |||
| 917 | return *impl->global_object_list_container; | 926 | return *impl->global_object_list_container; |
| 918 | } | 927 | } |
| 919 | 928 | ||
| 929 | void KernelCore::InterruptAllPhysicalCores() { | ||
| 930 | for (auto& physical_core : impl->cores) { | ||
| 931 | physical_core.Interrupt(); | ||
| 932 | } | ||
| 933 | } | ||
| 934 | |||
| 920 | void KernelCore::InvalidateAllInstructionCaches() { | 935 | void KernelCore::InvalidateAllInstructionCaches() { |
| 921 | for (auto& physical_core : impl->cores) { | 936 | for (auto& physical_core : impl->cores) { |
| 922 | physical_core.ArmInterface().ClearInstructionCache(); | 937 | physical_core.ArmInterface().ClearInstructionCache(); |
| @@ -1016,6 +1031,10 @@ KThread* KernelCore::GetCurrentEmuThread() const { | |||
| 1016 | return impl->GetCurrentEmuThread(); | 1031 | return impl->GetCurrentEmuThread(); |
| 1017 | } | 1032 | } |
| 1018 | 1033 | ||
| 1034 | void KernelCore::SetCurrentEmuThread(KThread* thread) { | ||
| 1035 | impl->SetCurrentEmuThread(thread); | ||
| 1036 | } | ||
| 1037 | |||
| 1019 | KMemoryManager& KernelCore::MemoryManager() { | 1038 | KMemoryManager& KernelCore::MemoryManager() { |
| 1020 | return *impl->memory_manager; | 1039 | return *impl->memory_manager; |
| 1021 | } | 1040 | } |
| @@ -1064,22 +1083,29 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const { | |||
| 1064 | return *impl->hidbus_shared_mem; | 1083 | return *impl->hidbus_shared_mem; |
| 1065 | } | 1084 | } |
| 1066 | 1085 | ||
| 1067 | void KernelCore::Suspend(bool in_suspention) { | 1086 | void KernelCore::Suspend(bool suspended) { |
| 1068 | const bool should_suspend = exception_exited || in_suspention; | 1087 | const bool should_suspend{exception_exited || suspended}; |
| 1069 | { | 1088 | const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; |
| 1070 | KScopedSchedulerLock lock(*this); | 1089 | |
| 1071 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; | 1090 | for (auto* process : GetProcessList()) { |
| 1072 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 1091 | process->SetActivity(activity); |
| 1073 | impl->suspend_threads[core_id]->SetState(state); | 1092 | |
| 1074 | impl->suspend_threads[core_id]->SetWaitReasonForDebugging( | 1093 | if (should_suspend) { |
| 1075 | ThreadWaitReasonForDebugging::Suspended); | 1094 | // Wait for execution to stop |
| 1076 | if (!should_suspend) { | 1095 | for (auto* thread : process->GetThreadList()) { |
| 1077 | impl->suspend_threads[core_id]->DisableDispatch(); | 1096 | thread->WaitUntilSuspended(); |
| 1078 | } | 1097 | } |
| 1079 | } | 1098 | } |
| 1080 | } | 1099 | } |
| 1081 | } | 1100 | } |
| 1082 | 1101 | ||
| 1102 | void KernelCore::ShutdownCores() { | ||
| 1103 | for (auto* thread : impl->shutdown_threads) { | ||
| 1104 | void(thread->Run()); | ||
| 1105 | } | ||
| 1106 | InterruptAllPhysicalCores(); | ||
| 1107 | } | ||
| 1108 | |||
| 1083 | bool KernelCore::IsMulticore() const { | 1109 | bool KernelCore::IsMulticore() const { |
| 1084 | return impl->is_multicore; | 1110 | return impl->is_multicore; |
| 1085 | } | 1111 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 926e14c6f..aa0ebaa02 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -184,6 +184,8 @@ public: | |||
| 184 | 184 | ||
| 185 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; | 185 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; |
| 186 | 186 | ||
| 187 | void InterruptAllPhysicalCores(); | ||
| 188 | |||
| 187 | void InvalidateAllInstructionCaches(); | 189 | void InvalidateAllInstructionCaches(); |
| 188 | 190 | ||
| 189 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | 191 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); |
| @@ -224,6 +226,9 @@ public: | |||
| 224 | /// Gets the current host_thread/guest_thread pointer. | 226 | /// Gets the current host_thread/guest_thread pointer. |
| 225 | KThread* GetCurrentEmuThread() const; | 227 | KThread* GetCurrentEmuThread() const; |
| 226 | 228 | ||
| 229 | /// Sets the current guest_thread pointer. | ||
| 230 | void SetCurrentEmuThread(KThread* thread); | ||
| 231 | |||
| 227 | /// Gets the current host_thread handle. | 232 | /// Gets the current host_thread handle. |
| 228 | u32 GetCurrentHostThreadID() const; | 233 | u32 GetCurrentHostThreadID() const; |
| 229 | 234 | ||
| @@ -269,12 +274,15 @@ public: | |||
| 269 | /// Gets the shared memory object for HIDBus services. | 274 | /// Gets the shared memory object for HIDBus services. |
| 270 | const Kernel::KSharedMemory& GetHidBusSharedMem() const; | 275 | const Kernel::KSharedMemory& GetHidBusSharedMem() const; |
| 271 | 276 | ||
| 272 | /// Suspend/unsuspend the OS. | 277 | /// Suspend/unsuspend all processes. |
| 273 | void Suspend(bool in_suspention); | 278 | void Suspend(bool suspend); |
| 274 | 279 | ||
| 275 | /// Exceptional exit the OS. | 280 | /// Exceptional exit all processes. |
| 276 | void ExceptionalExit(); | 281 | void ExceptionalExit(); |
| 277 | 282 | ||
| 283 | /// Notify emulated CPU cores to shut down. | ||
| 284 | void ShutdownCores(); | ||
| 285 | |||
| 278 | bool IsMulticore() const; | 286 | bool IsMulticore() const; |
| 279 | 287 | ||
| 280 | bool IsShuttingDown() const; | 288 | bool IsShuttingDown() const; |
diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index 54872626e..773319ad8 100644 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp | |||
| @@ -68,9 +68,9 @@ u32 GetFlagBitOffset(CapabilityType type) { | |||
| 68 | 68 | ||
| 69 | } // Anonymous namespace | 69 | } // Anonymous namespace |
| 70 | 70 | ||
| 71 | ResultCode ProcessCapabilities::InitializeForKernelProcess(const u32* capabilities, | 71 | Result ProcessCapabilities::InitializeForKernelProcess(const u32* capabilities, |
| 72 | std::size_t num_capabilities, | 72 | std::size_t num_capabilities, |
| 73 | KPageTable& page_table) { | 73 | KPageTable& page_table) { |
| 74 | Clear(); | 74 | Clear(); |
| 75 | 75 | ||
| 76 | // Allow all cores and priorities. | 76 | // Allow all cores and priorities. |
| @@ -81,9 +81,9 @@ ResultCode ProcessCapabilities::InitializeForKernelProcess(const u32* capabiliti | |||
| 81 | return ParseCapabilities(capabilities, num_capabilities, page_table); | 81 | return ParseCapabilities(capabilities, num_capabilities, page_table); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | ResultCode ProcessCapabilities::InitializeForUserProcess(const u32* capabilities, | 84 | Result ProcessCapabilities::InitializeForUserProcess(const u32* capabilities, |
| 85 | std::size_t num_capabilities, | 85 | std::size_t num_capabilities, |
| 86 | KPageTable& page_table) { | 86 | KPageTable& page_table) { |
| 87 | Clear(); | 87 | Clear(); |
| 88 | 88 | ||
| 89 | return ParseCapabilities(capabilities, num_capabilities, page_table); | 89 | return ParseCapabilities(capabilities, num_capabilities, page_table); |
| @@ -107,9 +107,8 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() { | |||
| 107 | can_force_debug = true; | 107 | can_force_debug = true; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities, | 110 | Result ProcessCapabilities::ParseCapabilities(const u32* capabilities, std::size_t num_capabilities, |
| 111 | std::size_t num_capabilities, | 111 | KPageTable& page_table) { |
| 112 | KPageTable& page_table) { | ||
| 113 | u32 set_flags = 0; | 112 | u32 set_flags = 0; |
| 114 | u32 set_svc_bits = 0; | 113 | u32 set_svc_bits = 0; |
| 115 | 114 | ||
| @@ -155,8 +154,8 @@ ResultCode ProcessCapabilities::ParseCapabilities(const u32* capabilities, | |||
| 155 | return ResultSuccess; | 154 | return ResultSuccess; |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, | 157 | Result ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag, |
| 159 | u32 flag, KPageTable& page_table) { | 158 | KPageTable& page_table) { |
| 160 | const auto type = GetCapabilityType(flag); | 159 | const auto type = GetCapabilityType(flag); |
| 161 | 160 | ||
| 162 | if (type == CapabilityType::Unset) { | 161 | if (type == CapabilityType::Unset) { |
| @@ -224,7 +223,7 @@ void ProcessCapabilities::Clear() { | |||
| 224 | can_force_debug = false; | 223 | can_force_debug = false; |
| 225 | } | 224 | } |
| 226 | 225 | ||
| 227 | ResultCode ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) { | 226 | Result ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) { |
| 228 | if (priority_mask != 0 || core_mask != 0) { | 227 | if (priority_mask != 0 || core_mask != 0) { |
| 229 | LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}", | 228 | LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}", |
| 230 | priority_mask, core_mask); | 229 | priority_mask, core_mask); |
| @@ -266,7 +265,7 @@ ResultCode ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) { | |||
| 266 | return ResultSuccess; | 265 | return ResultSuccess; |
| 267 | } | 266 | } |
| 268 | 267 | ||
| 269 | ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags) { | 268 | Result ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags) { |
| 270 | const u32 index = flags >> 29; | 269 | const u32 index = flags >> 29; |
| 271 | const u32 svc_bit = 1U << index; | 270 | const u32 svc_bit = 1U << index; |
| 272 | 271 | ||
| @@ -290,23 +289,23 @@ ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags) | |||
| 290 | return ResultSuccess; | 289 | return ResultSuccess; |
| 291 | } | 290 | } |
| 292 | 291 | ||
| 293 | ResultCode ProcessCapabilities::HandleMapPhysicalFlags(u32 flags, u32 size_flags, | 292 | Result ProcessCapabilities::HandleMapPhysicalFlags(u32 flags, u32 size_flags, |
| 294 | KPageTable& page_table) { | 293 | KPageTable& page_table) { |
| 295 | // TODO(Lioncache): Implement once the memory manager can handle this. | 294 | // TODO(Lioncache): Implement once the memory manager can handle this. |
| 296 | return ResultSuccess; | 295 | return ResultSuccess; |
| 297 | } | 296 | } |
| 298 | 297 | ||
| 299 | ResultCode ProcessCapabilities::HandleMapIOFlags(u32 flags, KPageTable& page_table) { | 298 | Result ProcessCapabilities::HandleMapIOFlags(u32 flags, KPageTable& page_table) { |
| 300 | // TODO(Lioncache): Implement once the memory manager can handle this. | 299 | // TODO(Lioncache): Implement once the memory manager can handle this. |
| 301 | return ResultSuccess; | 300 | return ResultSuccess; |
| 302 | } | 301 | } |
| 303 | 302 | ||
| 304 | ResultCode ProcessCapabilities::HandleMapRegionFlags(u32 flags, KPageTable& page_table) { | 303 | Result ProcessCapabilities::HandleMapRegionFlags(u32 flags, KPageTable& page_table) { |
| 305 | // TODO(Lioncache): Implement once the memory manager can handle this. | 304 | // TODO(Lioncache): Implement once the memory manager can handle this. |
| 306 | return ResultSuccess; | 305 | return ResultSuccess; |
| 307 | } | 306 | } |
| 308 | 307 | ||
| 309 | ResultCode ProcessCapabilities::HandleInterruptFlags(u32 flags) { | 308 | Result ProcessCapabilities::HandleInterruptFlags(u32 flags) { |
| 310 | constexpr u32 interrupt_ignore_value = 0x3FF; | 309 | constexpr u32 interrupt_ignore_value = 0x3FF; |
| 311 | const u32 interrupt0 = (flags >> 12) & 0x3FF; | 310 | const u32 interrupt0 = (flags >> 12) & 0x3FF; |
| 312 | const u32 interrupt1 = (flags >> 22) & 0x3FF; | 311 | const u32 interrupt1 = (flags >> 22) & 0x3FF; |
| @@ -333,7 +332,7 @@ ResultCode ProcessCapabilities::HandleInterruptFlags(u32 flags) { | |||
| 333 | return ResultSuccess; | 332 | return ResultSuccess; |
| 334 | } | 333 | } |
| 335 | 334 | ||
| 336 | ResultCode ProcessCapabilities::HandleProgramTypeFlags(u32 flags) { | 335 | Result ProcessCapabilities::HandleProgramTypeFlags(u32 flags) { |
| 337 | const u32 reserved = flags >> 17; | 336 | const u32 reserved = flags >> 17; |
| 338 | if (reserved != 0) { | 337 | if (reserved != 0) { |
| 339 | LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); | 338 | LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); |
| @@ -344,7 +343,7 @@ ResultCode ProcessCapabilities::HandleProgramTypeFlags(u32 flags) { | |||
| 344 | return ResultSuccess; | 343 | return ResultSuccess; |
| 345 | } | 344 | } |
| 346 | 345 | ||
| 347 | ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) { | 346 | Result ProcessCapabilities::HandleKernelVersionFlags(u32 flags) { |
| 348 | // Yes, the internal member variable is checked in the actual kernel here. | 347 | // Yes, the internal member variable is checked in the actual kernel here. |
| 349 | // This might look odd for options that are only allowed to be initialized | 348 | // This might look odd for options that are only allowed to be initialized |
| 350 | // just once, however the kernel has a separate initialization function for | 349 | // just once, however the kernel has a separate initialization function for |
| @@ -364,7 +363,7 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) { | |||
| 364 | return ResultSuccess; | 363 | return ResultSuccess; |
| 365 | } | 364 | } |
| 366 | 365 | ||
| 367 | ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) { | 366 | Result ProcessCapabilities::HandleHandleTableFlags(u32 flags) { |
| 368 | const u32 reserved = flags >> 26; | 367 | const u32 reserved = flags >> 26; |
| 369 | if (reserved != 0) { | 368 | if (reserved != 0) { |
| 370 | LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); | 369 | LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); |
| @@ -375,7 +374,7 @@ ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) { | |||
| 375 | return ResultSuccess; | 374 | return ResultSuccess; |
| 376 | } | 375 | } |
| 377 | 376 | ||
| 378 | ResultCode ProcessCapabilities::HandleDebugFlags(u32 flags) { | 377 | Result ProcessCapabilities::HandleDebugFlags(u32 flags) { |
| 379 | const u32 reserved = flags >> 19; | 378 | const u32 reserved = flags >> 19; |
| 380 | if (reserved != 0) { | 379 | if (reserved != 0) { |
| 381 | LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); | 380 | LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); |
diff --git a/src/core/hle/kernel/process_capability.h b/src/core/hle/kernel/process_capability.h index 7f3a2339d..ff05dc5ff 100644 --- a/src/core/hle/kernel/process_capability.h +++ b/src/core/hle/kernel/process_capability.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | union ResultCode; | 10 | union Result; |
| 11 | 11 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| @@ -86,8 +86,8 @@ public: | |||
| 86 | /// @returns ResultSuccess if this capabilities instance was able to be initialized, | 86 | /// @returns ResultSuccess if this capabilities instance was able to be initialized, |
| 87 | /// otherwise, an error code upon failure. | 87 | /// otherwise, an error code upon failure. |
| 88 | /// | 88 | /// |
| 89 | ResultCode InitializeForKernelProcess(const u32* capabilities, std::size_t num_capabilities, | 89 | Result InitializeForKernelProcess(const u32* capabilities, std::size_t num_capabilities, |
| 90 | KPageTable& page_table); | 90 | KPageTable& page_table); |
| 91 | 91 | ||
| 92 | /// Initializes this process capabilities instance for a userland process. | 92 | /// Initializes this process capabilities instance for a userland process. |
| 93 | /// | 93 | /// |
| @@ -99,8 +99,8 @@ public: | |||
| 99 | /// @returns ResultSuccess if this capabilities instance was able to be initialized, | 99 | /// @returns ResultSuccess if this capabilities instance was able to be initialized, |
| 100 | /// otherwise, an error code upon failure. | 100 | /// otherwise, an error code upon failure. |
| 101 | /// | 101 | /// |
| 102 | ResultCode InitializeForUserProcess(const u32* capabilities, std::size_t num_capabilities, | 102 | Result InitializeForUserProcess(const u32* capabilities, std::size_t num_capabilities, |
| 103 | KPageTable& page_table); | 103 | KPageTable& page_table); |
| 104 | 104 | ||
| 105 | /// Initializes this process capabilities instance for a process that does not | 105 | /// Initializes this process capabilities instance for a process that does not |
| 106 | /// have any metadata to parse. | 106 | /// have any metadata to parse. |
| @@ -185,8 +185,8 @@ private: | |||
| 185 | /// | 185 | /// |
| 186 | /// @return ResultSuccess if no errors occur, otherwise an error code. | 186 | /// @return ResultSuccess if no errors occur, otherwise an error code. |
| 187 | /// | 187 | /// |
| 188 | ResultCode ParseCapabilities(const u32* capabilities, std::size_t num_capabilities, | 188 | Result ParseCapabilities(const u32* capabilities, std::size_t num_capabilities, |
| 189 | KPageTable& page_table); | 189 | KPageTable& page_table); |
| 190 | 190 | ||
| 191 | /// Attempts to parse a capability descriptor that is only represented by a | 191 | /// Attempts to parse a capability descriptor that is only represented by a |
| 192 | /// single flag set. | 192 | /// single flag set. |
| @@ -200,8 +200,8 @@ private: | |||
| 200 | /// | 200 | /// |
| 201 | /// @return ResultSuccess if no errors occurred, otherwise an error code. | 201 | /// @return ResultSuccess if no errors occurred, otherwise an error code. |
| 202 | /// | 202 | /// |
| 203 | ResultCode ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag, | 203 | Result ParseSingleFlagCapability(u32& set_flags, u32& set_svc_bits, u32 flag, |
| 204 | KPageTable& page_table); | 204 | KPageTable& page_table); |
| 205 | 205 | ||
| 206 | /// Clears the internal state of this process capability instance. Necessary, | 206 | /// Clears the internal state of this process capability instance. Necessary, |
| 207 | /// to have a sane starting point due to us allowing running executables without | 207 | /// to have a sane starting point due to us allowing running executables without |
| @@ -219,34 +219,34 @@ private: | |||
| 219 | void Clear(); | 219 | void Clear(); |
| 220 | 220 | ||
| 221 | /// Handles flags related to the priority and core number capability flags. | 221 | /// Handles flags related to the priority and core number capability flags. |
| 222 | ResultCode HandlePriorityCoreNumFlags(u32 flags); | 222 | Result HandlePriorityCoreNumFlags(u32 flags); |
| 223 | 223 | ||
| 224 | /// Handles flags related to determining the allowable SVC mask. | 224 | /// Handles flags related to determining the allowable SVC mask. |
| 225 | ResultCode HandleSyscallFlags(u32& set_svc_bits, u32 flags); | 225 | Result HandleSyscallFlags(u32& set_svc_bits, u32 flags); |
| 226 | 226 | ||
| 227 | /// Handles flags related to mapping physical memory pages. | 227 | /// Handles flags related to mapping physical memory pages. |
| 228 | ResultCode HandleMapPhysicalFlags(u32 flags, u32 size_flags, KPageTable& page_table); | 228 | Result HandleMapPhysicalFlags(u32 flags, u32 size_flags, KPageTable& page_table); |
| 229 | 229 | ||
| 230 | /// Handles flags related to mapping IO pages. | 230 | /// Handles flags related to mapping IO pages. |
| 231 | ResultCode HandleMapIOFlags(u32 flags, KPageTable& page_table); | 231 | Result HandleMapIOFlags(u32 flags, KPageTable& page_table); |
| 232 | 232 | ||
| 233 | /// Handles flags related to mapping physical memory regions. | 233 | /// Handles flags related to mapping physical memory regions. |
| 234 | ResultCode HandleMapRegionFlags(u32 flags, KPageTable& page_table); | 234 | Result HandleMapRegionFlags(u32 flags, KPageTable& page_table); |
| 235 | 235 | ||
| 236 | /// Handles flags related to the interrupt capability flags. | 236 | /// Handles flags related to the interrupt capability flags. |
| 237 | ResultCode HandleInterruptFlags(u32 flags); | 237 | Result HandleInterruptFlags(u32 flags); |
| 238 | 238 | ||
| 239 | /// Handles flags related to the program type. | 239 | /// Handles flags related to the program type. |
| 240 | ResultCode HandleProgramTypeFlags(u32 flags); | 240 | Result HandleProgramTypeFlags(u32 flags); |
| 241 | 241 | ||
| 242 | /// Handles flags related to the handle table size. | 242 | /// Handles flags related to the handle table size. |
| 243 | ResultCode HandleHandleTableFlags(u32 flags); | 243 | Result HandleHandleTableFlags(u32 flags); |
| 244 | 244 | ||
| 245 | /// Handles flags related to the kernel version capability flags. | 245 | /// Handles flags related to the kernel version capability flags. |
| 246 | ResultCode HandleKernelVersionFlags(u32 flags); | 246 | Result HandleKernelVersionFlags(u32 flags); |
| 247 | 247 | ||
| 248 | /// Handles flags related to debug-specific capabilities. | 248 | /// Handles flags related to debug-specific capabilities. |
| 249 | ResultCode HandleDebugFlags(u32 flags); | 249 | Result HandleDebugFlags(u32 flags); |
| 250 | 250 | ||
| 251 | SyscallCapabilities svc_capabilities; | 251 | SyscallCapabilities svc_capabilities; |
| 252 | InterruptCapabilities interrupt_capabilities; | 252 | InterruptCapabilities interrupt_capabilities; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 66e0ce2d0..8655506b0 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "common/scope_exit.h" | 15 | #include "common/scope_exit.h" |
| 16 | #include "core/core.h" | 16 | #include "core/core.h" |
| 17 | #include "core/core_timing.h" | 17 | #include "core/core_timing.h" |
| 18 | #include "core/debugger/debugger.h" | ||
| 18 | #include "core/hle/kernel/k_client_port.h" | 19 | #include "core/hle/kernel/k_client_port.h" |
| 19 | #include "core/hle/kernel/k_client_session.h" | 20 | #include "core/hle/kernel/k_client_session.h" |
| 20 | #include "core/hle/kernel/k_code_memory.h" | 21 | #include "core/hle/kernel/k_code_memory.h" |
| @@ -57,8 +58,8 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) { | |||
| 57 | // Helper function that performs the common sanity checks for svcMapMemory | 58 | // Helper function that performs the common sanity checks for svcMapMemory |
| 58 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing | 59 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing |
| 59 | // in the same order. | 60 | // in the same order. |
| 60 | ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr, | 61 | Result MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr, |
| 61 | u64 size) { | 62 | u64 size) { |
| 62 | if (!Common::Is4KBAligned(dst_addr)) { | 63 | if (!Common::Is4KBAligned(dst_addr)) { |
| 63 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); | 64 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); |
| 64 | return ResultInvalidAddress; | 65 | return ResultInvalidAddress; |
| @@ -134,7 +135,7 @@ enum class ResourceLimitValueType { | |||
| 134 | } // Anonymous namespace | 135 | } // Anonymous namespace |
| 135 | 136 | ||
| 136 | /// Set the process heap to a given Size. It can both extend and shrink the heap. | 137 | /// Set the process heap to a given Size. It can both extend and shrink the heap. |
| 137 | static ResultCode SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { | 138 | static Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) { |
| 138 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size); | 139 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size); |
| 139 | 140 | ||
| 140 | // Validate size. | 141 | // Validate size. |
| @@ -147,9 +148,9 @@ static ResultCode SetHeapSize(Core::System& system, VAddr* out_address, u64 size | |||
| 147 | return ResultSuccess; | 148 | return ResultSuccess; |
| 148 | } | 149 | } |
| 149 | 150 | ||
| 150 | static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) { | 151 | static Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) { |
| 151 | VAddr temp_heap_addr{}; | 152 | VAddr temp_heap_addr{}; |
| 152 | const ResultCode result{SetHeapSize(system, &temp_heap_addr, heap_size)}; | 153 | const Result result{SetHeapSize(system, &temp_heap_addr, heap_size)}; |
| 153 | *heap_addr = static_cast<u32>(temp_heap_addr); | 154 | *heap_addr = static_cast<u32>(temp_heap_addr); |
| 154 | return result; | 155 | return result; |
| 155 | } | 156 | } |
| @@ -165,8 +166,8 @@ constexpr bool IsValidSetMemoryPermission(MemoryPermission perm) { | |||
| 165 | } | 166 | } |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 size, | 169 | static Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, |
| 169 | MemoryPermission perm) { | 170 | MemoryPermission perm) { |
| 170 | LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size, | 171 | LOG_DEBUG(Kernel_SVC, "called, address=0x{:016X}, size=0x{:X}, perm=0x{:08X", address, size, |
| 171 | perm); | 172 | perm); |
| 172 | 173 | ||
| @@ -187,8 +188,8 @@ static ResultCode SetMemoryPermission(Core::System& system, VAddr address, u64 s | |||
| 187 | return page_table.SetMemoryPermission(address, size, perm); | 188 | return page_table.SetMemoryPermission(address, size, perm); |
| 188 | } | 189 | } |
| 189 | 190 | ||
| 190 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, | 191 | static Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, |
| 191 | u32 attr) { | 192 | u32 attr) { |
| 192 | LOG_DEBUG(Kernel_SVC, | 193 | LOG_DEBUG(Kernel_SVC, |
| 193 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, | 194 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, |
| 194 | size, mask, attr); | 195 | size, mask, attr); |
| @@ -212,19 +213,19 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 212 | return page_table.SetMemoryAttribute(address, size, mask, attr); | 213 | return page_table.SetMemoryAttribute(address, size, mask, attr); |
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, | 216 | static Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, |
| 216 | u32 attr) { | 217 | u32 attr) { |
| 217 | return SetMemoryAttribute(system, address, size, mask, attr); | 218 | return SetMemoryAttribute(system, address, size, mask, attr); |
| 218 | } | 219 | } |
| 219 | 220 | ||
| 220 | /// Maps a memory range into a different range. | 221 | /// Maps a memory range into a different range. |
| 221 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 222 | static Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 222 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 223 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 223 | src_addr, size); | 224 | src_addr, size); |
| 224 | 225 | ||
| 225 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; | 226 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 226 | 227 | ||
| 227 | if (const ResultCode result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; | 228 | if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; |
| 228 | result.IsError()) { | 229 | result.IsError()) { |
| 229 | return result; | 230 | return result; |
| 230 | } | 231 | } |
| @@ -232,18 +233,18 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr | |||
| 232 | return page_table.MapMemory(dst_addr, src_addr, size); | 233 | return page_table.MapMemory(dst_addr, src_addr, size); |
| 233 | } | 234 | } |
| 234 | 235 | ||
| 235 | static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { | 236 | static Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { |
| 236 | return MapMemory(system, dst_addr, src_addr, size); | 237 | return MapMemory(system, dst_addr, src_addr, size); |
| 237 | } | 238 | } |
| 238 | 239 | ||
| 239 | /// Unmaps a region that was previously mapped with svcMapMemory | 240 | /// Unmaps a region that was previously mapped with svcMapMemory |
| 240 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 241 | static Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 241 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 242 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 242 | src_addr, size); | 243 | src_addr, size); |
| 243 | 244 | ||
| 244 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; | 245 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 245 | 246 | ||
| 246 | if (const ResultCode result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; | 247 | if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; |
| 247 | result.IsError()) { | 248 | result.IsError()) { |
| 248 | return result; | 249 | return result; |
| 249 | } | 250 | } |
| @@ -251,12 +252,12 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | |||
| 251 | return page_table.UnmapMemory(dst_addr, src_addr, size); | 252 | return page_table.UnmapMemory(dst_addr, src_addr, size); |
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | static ResultCode UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { | 255 | static Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) { |
| 255 | return UnmapMemory(system, dst_addr, src_addr, size); | 256 | return UnmapMemory(system, dst_addr, src_addr, size); |
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | /// Connect to an OS service given the port name, returns the handle to the port to out | 259 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 259 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { | 260 | static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { |
| 260 | auto& memory = system.Memory(); | 261 | auto& memory = system.Memory(); |
| 261 | if (!memory.IsValidVirtualAddress(port_name_address)) { | 262 | if (!memory.IsValidVirtualAddress(port_name_address)) { |
| 262 | LOG_ERROR(Kernel_SVC, | 263 | LOG_ERROR(Kernel_SVC, |
| @@ -306,14 +307,14 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr po | |||
| 306 | return ResultSuccess; | 307 | return ResultSuccess; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, | 310 | static Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, |
| 310 | u32 port_name_address) { | 311 | u32 port_name_address) { |
| 311 | 312 | ||
| 312 | return ConnectToNamedPort(system, out_handle, port_name_address); | 313 | return ConnectToNamedPort(system, out_handle, port_name_address); |
| 313 | } | 314 | } |
| 314 | 315 | ||
| 315 | /// Makes a blocking IPC call to an OS service. | 316 | /// Makes a blocking IPC call to an OS service. |
| 316 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | 317 | static Result SendSyncRequest(Core::System& system, Handle handle) { |
| 317 | auto& kernel = system.Kernel(); | 318 | auto& kernel = system.Kernel(); |
| 318 | 319 | ||
| 319 | // Create the wait queue. | 320 | // Create the wait queue. |
| @@ -326,7 +327,6 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 326 | 327 | ||
| 327 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | 328 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); |
| 328 | 329 | ||
| 329 | auto thread = kernel.CurrentScheduler()->GetCurrentThread(); | ||
| 330 | { | 330 | { |
| 331 | KScopedSchedulerLock lock(kernel); | 331 | KScopedSchedulerLock lock(kernel); |
| 332 | 332 | ||
| @@ -336,15 +336,15 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 336 | session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming()); | 336 | session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming()); |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | return thread->GetWaitResult(); | 339 | return GetCurrentThread(kernel).GetWaitResult(); |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { | 342 | static Result SendSyncRequest32(Core::System& system, Handle handle) { |
| 343 | return SendSyncRequest(system, handle); | 343 | return SendSyncRequest(system, handle); |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | /// Get the ID for the specified thread. | 346 | /// Get the ID for the specified thread. |
| 347 | static ResultCode GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { | 347 | static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { |
| 348 | // Get the thread from its handle. | 348 | // Get the thread from its handle. |
| 349 | KScopedAutoObject thread = | 349 | KScopedAutoObject thread = |
| 350 | system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); | 350 | system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); |
| @@ -355,10 +355,10 @@ static ResultCode GetThreadId(Core::System& system, u64* out_thread_id, Handle t | |||
| 355 | return ResultSuccess; | 355 | return ResultSuccess; |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | static ResultCode GetThreadId32(Core::System& system, u32* out_thread_id_low, | 358 | static Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high, |
| 359 | u32* out_thread_id_high, Handle thread_handle) { | 359 | Handle thread_handle) { |
| 360 | u64 out_thread_id{}; | 360 | u64 out_thread_id{}; |
| 361 | const ResultCode result{GetThreadId(system, &out_thread_id, thread_handle)}; | 361 | const Result result{GetThreadId(system, &out_thread_id, thread_handle)}; |
| 362 | 362 | ||
| 363 | *out_thread_id_low = static_cast<u32>(out_thread_id >> 32); | 363 | *out_thread_id_low = static_cast<u32>(out_thread_id >> 32); |
| 364 | *out_thread_id_high = static_cast<u32>(out_thread_id & std::numeric_limits<u32>::max()); | 364 | *out_thread_id_high = static_cast<u32>(out_thread_id & std::numeric_limits<u32>::max()); |
| @@ -367,7 +367,7 @@ static ResultCode GetThreadId32(Core::System& system, u32* out_thread_id_low, | |||
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | /// Gets the ID of the specified process or a specified thread's owning process. | 369 | /// Gets the ID of the specified process or a specified thread's owning process. |
| 370 | static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { | 370 | static Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { |
| 371 | LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); | 371 | LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); |
| 372 | 372 | ||
| 373 | // Get the object from the handle table. | 373 | // Get the object from the handle table. |
| @@ -398,8 +398,8 @@ static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle | |||
| 398 | return ResultSuccess; | 398 | return ResultSuccess; |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low, | 401 | static Result GetProcessId32(Core::System& system, u32* out_process_id_low, |
| 402 | u32* out_process_id_high, Handle handle) { | 402 | u32* out_process_id_high, Handle handle) { |
| 403 | u64 out_process_id{}; | 403 | u64 out_process_id{}; |
| 404 | const auto result = GetProcessId(system, &out_process_id, handle); | 404 | const auto result = GetProcessId(system, &out_process_id, handle); |
| 405 | *out_process_id_low = static_cast<u32>(out_process_id); | 405 | *out_process_id_low = static_cast<u32>(out_process_id); |
| @@ -408,8 +408,8 @@ static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low, | |||
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 410 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 411 | static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, | 411 | static Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, |
| 412 | s32 num_handles, s64 nano_seconds) { | 412 | s32 num_handles, s64 nano_seconds) { |
| 413 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}", | 413 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}", |
| 414 | handles_address, num_handles, nano_seconds); | 414 | handles_address, num_handles, nano_seconds); |
| 415 | 415 | ||
| @@ -444,14 +444,14 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha | |||
| 444 | nano_seconds); | 444 | nano_seconds); |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, | 447 | static Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, |
| 448 | s32 num_handles, u32 timeout_high, s32* index) { | 448 | s32 num_handles, u32 timeout_high, s32* index) { |
| 449 | const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; | 449 | const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; |
| 450 | return WaitSynchronization(system, index, handles_address, num_handles, nano_seconds); | 450 | return WaitSynchronization(system, index, handles_address, num_handles, nano_seconds); |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | /// Resumes a thread waiting on WaitSynchronization | 453 | /// Resumes a thread waiting on WaitSynchronization |
| 454 | static ResultCode CancelSynchronization(Core::System& system, Handle handle) { | 454 | static Result CancelSynchronization(Core::System& system, Handle handle) { |
| 455 | LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); | 455 | LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); |
| 456 | 456 | ||
| 457 | // Get the thread from its handle. | 457 | // Get the thread from its handle. |
| @@ -464,13 +464,12 @@ static ResultCode CancelSynchronization(Core::System& system, Handle handle) { | |||
| 464 | return ResultSuccess; | 464 | return ResultSuccess; |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | static ResultCode CancelSynchronization32(Core::System& system, Handle handle) { | 467 | static Result CancelSynchronization32(Core::System& system, Handle handle) { |
| 468 | return CancelSynchronization(system, handle); | 468 | return CancelSynchronization(system, handle); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | /// Attempts to locks a mutex | 471 | /// Attempts to locks a mutex |
| 472 | static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, | 472 | static Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag) { |
| 473 | u32 tag) { | ||
| 474 | LOG_TRACE(Kernel_SVC, "called thread_handle=0x{:08X}, address=0x{:X}, tag=0x{:08X}", | 473 | LOG_TRACE(Kernel_SVC, "called thread_handle=0x{:08X}, address=0x{:X}, tag=0x{:08X}", |
| 475 | thread_handle, address, tag); | 474 | thread_handle, address, tag); |
| 476 | 475 | ||
| @@ -488,13 +487,12 @@ static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAdd | |||
| 488 | return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag); | 487 | return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag); |
| 489 | } | 488 | } |
| 490 | 489 | ||
| 491 | static ResultCode ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, | 490 | static Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag) { |
| 492 | u32 tag) { | ||
| 493 | return ArbitrateLock(system, thread_handle, address, tag); | 491 | return ArbitrateLock(system, thread_handle, address, tag); |
| 494 | } | 492 | } |
| 495 | 493 | ||
| 496 | /// Unlock a mutex | 494 | /// Unlock a mutex |
| 497 | static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) { | 495 | static Result ArbitrateUnlock(Core::System& system, VAddr address) { |
| 498 | LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); | 496 | LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); |
| 499 | 497 | ||
| 500 | // Validate the input address. | 498 | // Validate the input address. |
| @@ -512,7 +510,7 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) { | |||
| 512 | return system.Kernel().CurrentProcess()->SignalToAddress(address); | 510 | return system.Kernel().CurrentProcess()->SignalToAddress(address); |
| 513 | } | 511 | } |
| 514 | 512 | ||
| 515 | static ResultCode ArbitrateUnlock32(Core::System& system, u32 address) { | 513 | static Result ArbitrateUnlock32(Core::System& system, u32 address) { |
| 516 | return ArbitrateUnlock(system, address); | 514 | return ArbitrateUnlock(system, address); |
| 517 | } | 515 | } |
| 518 | 516 | ||
| @@ -623,10 +621,16 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 623 | 621 | ||
| 624 | handle_debug_buffer(info1, info2); | 622 | handle_debug_buffer(info1, info2); |
| 625 | 623 | ||
| 626 | auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | 624 | auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); |
| 627 | const auto thread_processor_id = current_thread->GetActiveCore(); | 625 | const auto thread_processor_id = current_thread->GetActiveCore(); |
| 628 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); | 626 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); |
| 629 | } | 627 | } |
| 628 | |||
| 629 | if (system.DebuggerEnabled()) { | ||
| 630 | auto* thread = system.Kernel().GetCurrentEmuThread(); | ||
| 631 | system.GetDebugger().NotifyThreadStopped(thread); | ||
| 632 | thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 633 | } | ||
| 630 | } | 634 | } |
| 631 | 635 | ||
| 632 | static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { | 636 | static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { |
| @@ -649,8 +653,8 @@ static void OutputDebugString32(Core::System& system, u32 address, u32 len) { | |||
| 649 | } | 653 | } |
| 650 | 654 | ||
| 651 | /// Gets system/memory information for the current process | 655 | /// Gets system/memory information for the current process |
| 652 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, | 656 | static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, |
| 653 | u64 info_sub_id) { | 657 | u64 info_sub_id) { |
| 654 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, | 658 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, |
| 655 | info_sub_id, handle); | 659 | info_sub_id, handle); |
| 656 | 660 | ||
| @@ -685,6 +689,9 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle | |||
| 685 | // 6.0.0+ | 689 | // 6.0.0+ |
| 686 | TotalPhysicalMemoryAvailableWithoutSystemResource = 21, | 690 | TotalPhysicalMemoryAvailableWithoutSystemResource = 21, |
| 687 | TotalPhysicalMemoryUsedWithoutSystemResource = 22, | 691 | TotalPhysicalMemoryUsedWithoutSystemResource = 22, |
| 692 | |||
| 693 | // Homebrew only | ||
| 694 | MesosphereCurrentProcess = 65001, | ||
| 688 | }; | 695 | }; |
| 689 | 696 | ||
| 690 | const auto info_id_type = static_cast<GetInfoType>(info_id); | 697 | const auto info_id_type = static_cast<GetInfoType>(info_id); |
| @@ -877,7 +884,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle | |||
| 877 | 884 | ||
| 878 | const auto& core_timing = system.CoreTiming(); | 885 | const auto& core_timing = system.CoreTiming(); |
| 879 | const auto& scheduler = *system.Kernel().CurrentScheduler(); | 886 | const auto& scheduler = *system.Kernel().CurrentScheduler(); |
| 880 | const auto* const current_thread = scheduler.GetCurrentThread(); | 887 | const auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); |
| 881 | const bool same_thread = current_thread == thread.GetPointerUnsafe(); | 888 | const bool same_thread = current_thread == thread.GetPointerUnsafe(); |
| 882 | 889 | ||
| 883 | const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks(); | 890 | const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks(); |
| @@ -907,18 +914,39 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle | |||
| 907 | *result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime(); | 914 | *result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime(); |
| 908 | return ResultSuccess; | 915 | return ResultSuccess; |
| 909 | } | 916 | } |
| 917 | case GetInfoType::MesosphereCurrentProcess: { | ||
| 918 | // Verify the input handle is invalid. | ||
| 919 | R_UNLESS(handle == InvalidHandle, ResultInvalidHandle); | ||
| 920 | |||
| 921 | // Verify the sub-type is valid. | ||
| 922 | R_UNLESS(info_sub_id == 0, ResultInvalidCombination); | ||
| 923 | |||
| 924 | // Get the handle table. | ||
| 925 | KProcess* current_process = system.Kernel().CurrentProcess(); | ||
| 926 | KHandleTable& handle_table = current_process->GetHandleTable(); | ||
| 927 | |||
| 928 | // Get a new handle for the current process. | ||
| 929 | Handle tmp; | ||
| 930 | R_TRY(handle_table.Add(&tmp, current_process)); | ||
| 931 | |||
| 932 | // Set the output. | ||
| 933 | *result = tmp; | ||
| 934 | |||
| 935 | // We succeeded. | ||
| 936 | return ResultSuccess; | ||
| 937 | } | ||
| 910 | default: | 938 | default: |
| 911 | LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); | 939 | LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); |
| 912 | return ResultInvalidEnumValue; | 940 | return ResultInvalidEnumValue; |
| 913 | } | 941 | } |
| 914 | } | 942 | } |
| 915 | 943 | ||
| 916 | static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, | 944 | static Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low, |
| 917 | u32 info_id, u32 handle, u32 sub_id_high) { | 945 | u32 info_id, u32 handle, u32 sub_id_high) { |
| 918 | const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)}; | 946 | const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)}; |
| 919 | u64 res_value{}; | 947 | u64 res_value{}; |
| 920 | 948 | ||
| 921 | const ResultCode result{GetInfo(system, &res_value, info_id, handle, sub_id)}; | 949 | const Result result{GetInfo(system, &res_value, info_id, handle, sub_id)}; |
| 922 | *result_high = static_cast<u32>(res_value >> 32); | 950 | *result_high = static_cast<u32>(res_value >> 32); |
| 923 | *result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max()); | 951 | *result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max()); |
| 924 | 952 | ||
| @@ -926,7 +954,7 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h | |||
| 926 | } | 954 | } |
| 927 | 955 | ||
| 928 | /// Maps memory at a desired address | 956 | /// Maps memory at a desired address |
| 929 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 957 | static Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 930 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 958 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 931 | 959 | ||
| 932 | if (!Common::Is4KBAligned(addr)) { | 960 | if (!Common::Is4KBAligned(addr)) { |
| @@ -974,12 +1002,12 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) | |||
| 974 | return page_table.MapPhysicalMemory(addr, size); | 1002 | return page_table.MapPhysicalMemory(addr, size); |
| 975 | } | 1003 | } |
| 976 | 1004 | ||
| 977 | static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { | 1005 | static Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { |
| 978 | return MapPhysicalMemory(system, addr, size); | 1006 | return MapPhysicalMemory(system, addr, size); |
| 979 | } | 1007 | } |
| 980 | 1008 | ||
| 981 | /// Unmaps memory previously mapped via MapPhysicalMemory | 1009 | /// Unmaps memory previously mapped via MapPhysicalMemory |
| 982 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 1010 | static Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 983 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 1011 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 984 | 1012 | ||
| 985 | if (!Common::Is4KBAligned(addr)) { | 1013 | if (!Common::Is4KBAligned(addr)) { |
| @@ -1027,13 +1055,13 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size | |||
| 1027 | return page_table.UnmapPhysicalMemory(addr, size); | 1055 | return page_table.UnmapPhysicalMemory(addr, size); |
| 1028 | } | 1056 | } |
| 1029 | 1057 | ||
| 1030 | static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { | 1058 | static Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) { |
| 1031 | return UnmapPhysicalMemory(system, addr, size); | 1059 | return UnmapPhysicalMemory(system, addr, size); |
| 1032 | } | 1060 | } |
| 1033 | 1061 | ||
| 1034 | /// Sets the thread activity | 1062 | /// Sets the thread activity |
| 1035 | static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, | 1063 | static Result SetThreadActivity(Core::System& system, Handle thread_handle, |
| 1036 | ThreadActivity thread_activity) { | 1064 | ThreadActivity thread_activity) { |
| 1037 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", thread_handle, | 1065 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", thread_handle, |
| 1038 | thread_activity); | 1066 | thread_activity); |
| 1039 | 1067 | ||
| @@ -1058,13 +1086,13 @@ static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, | |||
| 1058 | return ResultSuccess; | 1086 | return ResultSuccess; |
| 1059 | } | 1087 | } |
| 1060 | 1088 | ||
| 1061 | static ResultCode SetThreadActivity32(Core::System& system, Handle thread_handle, | 1089 | static Result SetThreadActivity32(Core::System& system, Handle thread_handle, |
| 1062 | Svc::ThreadActivity thread_activity) { | 1090 | Svc::ThreadActivity thread_activity) { |
| 1063 | return SetThreadActivity(system, thread_handle, thread_activity); | 1091 | return SetThreadActivity(system, thread_handle, thread_activity); |
| 1064 | } | 1092 | } |
| 1065 | 1093 | ||
| 1066 | /// Gets the thread context | 1094 | /// Gets the thread context |
| 1067 | static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle) { | 1095 | static Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle) { |
| 1068 | LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, | 1096 | LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, |
| 1069 | thread_handle); | 1097 | thread_handle); |
| 1070 | 1098 | ||
| @@ -1096,7 +1124,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand | |||
| 1096 | if (thread->GetRawState() != ThreadState::Runnable) { | 1124 | if (thread->GetRawState() != ThreadState::Runnable) { |
| 1097 | bool current = false; | 1125 | bool current = false; |
| 1098 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | 1126 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { |
| 1099 | if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) { | 1127 | if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetSchedulerCurrentThread()) { |
| 1100 | current = true; | 1128 | current = true; |
| 1101 | break; | 1129 | break; |
| 1102 | } | 1130 | } |
| @@ -1121,12 +1149,12 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand | |||
| 1121 | return ResultSuccess; | 1149 | return ResultSuccess; |
| 1122 | } | 1150 | } |
| 1123 | 1151 | ||
| 1124 | static ResultCode GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle) { | 1152 | static Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle) { |
| 1125 | return GetThreadContext(system, out_context, thread_handle); | 1153 | return GetThreadContext(system, out_context, thread_handle); |
| 1126 | } | 1154 | } |
| 1127 | 1155 | ||
| 1128 | /// Gets the priority for the specified thread | 1156 | /// Gets the priority for the specified thread |
| 1129 | static ResultCode GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) { | 1157 | static Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle) { |
| 1130 | LOG_TRACE(Kernel_SVC, "called"); | 1158 | LOG_TRACE(Kernel_SVC, "called"); |
| 1131 | 1159 | ||
| 1132 | // Get the thread from its handle. | 1160 | // Get the thread from its handle. |
| @@ -1139,12 +1167,12 @@ static ResultCode GetThreadPriority(Core::System& system, u32* out_priority, Han | |||
| 1139 | return ResultSuccess; | 1167 | return ResultSuccess; |
| 1140 | } | 1168 | } |
| 1141 | 1169 | ||
| 1142 | static ResultCode GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle) { | 1170 | static Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle) { |
| 1143 | return GetThreadPriority(system, out_priority, handle); | 1171 | return GetThreadPriority(system, out_priority, handle); |
| 1144 | } | 1172 | } |
| 1145 | 1173 | ||
| 1146 | /// Sets the priority for the specified thread | 1174 | /// Sets the priority for the specified thread |
| 1147 | static ResultCode SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { | 1175 | static Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { |
| 1148 | // Get the current process. | 1176 | // Get the current process. |
| 1149 | KProcess& process = *system.Kernel().CurrentProcess(); | 1177 | KProcess& process = *system.Kernel().CurrentProcess(); |
| 1150 | 1178 | ||
| @@ -1162,7 +1190,7 @@ static ResultCode SetThreadPriority(Core::System& system, Handle thread_handle, | |||
| 1162 | return ResultSuccess; | 1190 | return ResultSuccess; |
| 1163 | } | 1191 | } |
| 1164 | 1192 | ||
| 1165 | static ResultCode SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { | 1193 | static Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { |
| 1166 | return SetThreadPriority(system, thread_handle, priority); | 1194 | return SetThreadPriority(system, thread_handle, priority); |
| 1167 | } | 1195 | } |
| 1168 | 1196 | ||
| @@ -1222,8 +1250,8 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(Svc::MemoryPermission p | |||
| 1222 | 1250 | ||
| 1223 | } // Anonymous namespace | 1251 | } // Anonymous namespace |
| 1224 | 1252 | ||
| 1225 | static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, | 1253 | static Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size, |
| 1226 | u64 size, Svc::MemoryPermission map_perm) { | 1254 | Svc::MemoryPermission map_perm) { |
| 1227 | LOG_TRACE(Kernel_SVC, | 1255 | LOG_TRACE(Kernel_SVC, |
| 1228 | "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", | 1256 | "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", |
| 1229 | shmem_handle, address, size, map_perm); | 1257 | shmem_handle, address, size, map_perm); |
| @@ -1263,13 +1291,13 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAd | |||
| 1263 | return ResultSuccess; | 1291 | return ResultSuccess; |
| 1264 | } | 1292 | } |
| 1265 | 1293 | ||
| 1266 | static ResultCode MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, | 1294 | static Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size, |
| 1267 | u32 size, Svc::MemoryPermission map_perm) { | 1295 | Svc::MemoryPermission map_perm) { |
| 1268 | return MapSharedMemory(system, shmem_handle, address, size, map_perm); | 1296 | return MapSharedMemory(system, shmem_handle, address, size, map_perm); |
| 1269 | } | 1297 | } |
| 1270 | 1298 | ||
| 1271 | static ResultCode UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, | 1299 | static Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, |
| 1272 | u64 size) { | 1300 | u64 size) { |
| 1273 | // Validate the address/size. | 1301 | // Validate the address/size. |
| 1274 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); | 1302 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); |
| 1275 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | 1303 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); |
| @@ -1296,13 +1324,13 @@ static ResultCode UnmapSharedMemory(Core::System& system, Handle shmem_handle, V | |||
| 1296 | return ResultSuccess; | 1324 | return ResultSuccess; |
| 1297 | } | 1325 | } |
| 1298 | 1326 | ||
| 1299 | static ResultCode UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, | 1327 | static Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, |
| 1300 | u32 size) { | 1328 | u32 size) { |
| 1301 | return UnmapSharedMemory(system, shmem_handle, address, size); | 1329 | return UnmapSharedMemory(system, shmem_handle, address, size); |
| 1302 | } | 1330 | } |
| 1303 | 1331 | ||
| 1304 | static ResultCode SetProcessMemoryPermission(Core::System& system, Handle process_handle, | 1332 | static Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address, |
| 1305 | VAddr address, u64 size, Svc::MemoryPermission perm) { | 1333 | u64 size, Svc::MemoryPermission perm) { |
| 1306 | LOG_TRACE(Kernel_SVC, | 1334 | LOG_TRACE(Kernel_SVC, |
| 1307 | "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", | 1335 | "called, process_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", |
| 1308 | process_handle, address, size, perm); | 1336 | process_handle, address, size, perm); |
| @@ -1331,8 +1359,8 @@ static ResultCode SetProcessMemoryPermission(Core::System& system, Handle proces | |||
| 1331 | return page_table.SetProcessMemoryPermission(address, size, perm); | 1359 | return page_table.SetProcessMemoryPermission(address, size, perm); |
| 1332 | } | 1360 | } |
| 1333 | 1361 | ||
| 1334 | static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, | 1362 | static Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, |
| 1335 | VAddr src_address, u64 size) { | 1363 | VAddr src_address, u64 size) { |
| 1336 | LOG_TRACE(Kernel_SVC, | 1364 | LOG_TRACE(Kernel_SVC, |
| 1337 | "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", | 1365 | "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", |
| 1338 | dst_address, process_handle, src_address, size); | 1366 | dst_address, process_handle, src_address, size); |
| @@ -1361,7 +1389,7 @@ static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Hand | |||
| 1361 | ResultInvalidMemoryRegion); | 1389 | ResultInvalidMemoryRegion); |
| 1362 | 1390 | ||
| 1363 | // Create a new page group. | 1391 | // Create a new page group. |
| 1364 | KPageLinkedList pg; | 1392 | KPageGroup pg; |
| 1365 | R_TRY(src_pt.MakeAndOpenPageGroup( | 1393 | R_TRY(src_pt.MakeAndOpenPageGroup( |
| 1366 | std::addressof(pg), src_address, size / PageSize, KMemoryState::FlagCanMapProcess, | 1394 | std::addressof(pg), src_address, size / PageSize, KMemoryState::FlagCanMapProcess, |
| 1367 | KMemoryState::FlagCanMapProcess, KMemoryPermission::None, KMemoryPermission::None, | 1395 | KMemoryState::FlagCanMapProcess, KMemoryPermission::None, KMemoryPermission::None, |
| @@ -1374,8 +1402,8 @@ static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Hand | |||
| 1374 | return ResultSuccess; | 1402 | return ResultSuccess; |
| 1375 | } | 1403 | } |
| 1376 | 1404 | ||
| 1377 | static ResultCode UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, | 1405 | static Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, |
| 1378 | VAddr src_address, u64 size) { | 1406 | VAddr src_address, u64 size) { |
| 1379 | LOG_TRACE(Kernel_SVC, | 1407 | LOG_TRACE(Kernel_SVC, |
| 1380 | "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", | 1408 | "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", |
| 1381 | dst_address, process_handle, src_address, size); | 1409 | dst_address, process_handle, src_address, size); |
| @@ -1409,7 +1437,7 @@ static ResultCode UnmapProcessMemory(Core::System& system, VAddr dst_address, Ha | |||
| 1409 | return ResultSuccess; | 1437 | return ResultSuccess; |
| 1410 | } | 1438 | } |
| 1411 | 1439 | ||
| 1412 | static ResultCode CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) { | 1440 | static Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) { |
| 1413 | LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size); | 1441 | LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size); |
| 1414 | 1442 | ||
| 1415 | // Get kernel instance. | 1443 | // Get kernel instance. |
| @@ -1444,12 +1472,12 @@ static ResultCode CreateCodeMemory(Core::System& system, Handle* out, VAddr addr | |||
| 1444 | return ResultSuccess; | 1472 | return ResultSuccess; |
| 1445 | } | 1473 | } |
| 1446 | 1474 | ||
| 1447 | static ResultCode CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) { | 1475 | static Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) { |
| 1448 | return CreateCodeMemory(system, out, address, size); | 1476 | return CreateCodeMemory(system, out, address, size); |
| 1449 | } | 1477 | } |
| 1450 | 1478 | ||
| 1451 | static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, | 1479 | static Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, |
| 1452 | VAddr address, size_t size, Svc::MemoryPermission perm) { | 1480 | VAddr address, size_t size, Svc::MemoryPermission perm) { |
| 1453 | 1481 | ||
| 1454 | LOG_TRACE(Kernel_SVC, | 1482 | LOG_TRACE(Kernel_SVC, |
| 1455 | "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, " | 1483 | "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, " |
| @@ -1527,15 +1555,13 @@ static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_han | |||
| 1527 | return ResultSuccess; | 1555 | return ResultSuccess; |
| 1528 | } | 1556 | } |
| 1529 | 1557 | ||
| 1530 | static ResultCode ControlCodeMemory32(Core::System& system, Handle code_memory_handle, | 1558 | static Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation, |
| 1531 | u32 operation, u64 address, u64 size, | 1559 | u64 address, u64 size, Svc::MemoryPermission perm) { |
| 1532 | Svc::MemoryPermission perm) { | ||
| 1533 | return ControlCodeMemory(system, code_memory_handle, operation, address, size, perm); | 1560 | return ControlCodeMemory(system, code_memory_handle, operation, address, size, perm); |
| 1534 | } | 1561 | } |
| 1535 | 1562 | ||
| 1536 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1563 | static Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1537 | VAddr page_info_address, Handle process_handle, | 1564 | VAddr page_info_address, Handle process_handle, VAddr address) { |
| 1538 | VAddr address) { | ||
| 1539 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); | 1565 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); |
| 1540 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1566 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1541 | KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); | 1567 | KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); |
| @@ -1563,8 +1589,8 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | |||
| 1563 | return ResultSuccess; | 1589 | return ResultSuccess; |
| 1564 | } | 1590 | } |
| 1565 | 1591 | ||
| 1566 | static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address, | 1592 | static Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address, |
| 1567 | VAddr page_info_address, VAddr query_address) { | 1593 | VAddr query_address) { |
| 1568 | LOG_TRACE(Kernel_SVC, | 1594 | LOG_TRACE(Kernel_SVC, |
| 1569 | "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " | 1595 | "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " |
| 1570 | "query_address=0x{:016X}", | 1596 | "query_address=0x{:016X}", |
| @@ -1574,13 +1600,13 @@ static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address, | |||
| 1574 | query_address); | 1600 | query_address); |
| 1575 | } | 1601 | } |
| 1576 | 1602 | ||
| 1577 | static ResultCode QueryMemory32(Core::System& system, u32 memory_info_address, | 1603 | static Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address, |
| 1578 | u32 page_info_address, u32 query_address) { | 1604 | u32 query_address) { |
| 1579 | return QueryMemory(system, memory_info_address, page_info_address, query_address); | 1605 | return QueryMemory(system, memory_info_address, page_info_address, query_address); |
| 1580 | } | 1606 | } |
| 1581 | 1607 | ||
| 1582 | static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, | 1608 | static Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, |
| 1583 | u64 src_address, u64 size) { | 1609 | u64 src_address, u64 size) { |
| 1584 | LOG_DEBUG(Kernel_SVC, | 1610 | LOG_DEBUG(Kernel_SVC, |
| 1585 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, " | 1611 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, " |
| 1586 | "src_address=0x{:016X}, size=0x{:016X}", | 1612 | "src_address=0x{:016X}, size=0x{:016X}", |
| @@ -1647,8 +1673,8 @@ static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_hand | |||
| 1647 | return page_table.MapCodeMemory(dst_address, src_address, size); | 1673 | return page_table.MapCodeMemory(dst_address, src_address, size); |
| 1648 | } | 1674 | } |
| 1649 | 1675 | ||
| 1650 | static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle, | 1676 | static Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, |
| 1651 | u64 dst_address, u64 src_address, u64 size) { | 1677 | u64 src_address, u64 size) { |
| 1652 | LOG_DEBUG(Kernel_SVC, | 1678 | LOG_DEBUG(Kernel_SVC, |
| 1653 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " | 1679 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " |
| 1654 | "size=0x{:016X}", | 1680 | "size=0x{:016X}", |
| @@ -1719,11 +1745,12 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha | |||
| 1719 | /// Exits the current process | 1745 | /// Exits the current process |
| 1720 | static void ExitProcess(Core::System& system) { | 1746 | static void ExitProcess(Core::System& system) { |
| 1721 | auto* current_process = system.Kernel().CurrentProcess(); | 1747 | auto* current_process = system.Kernel().CurrentProcess(); |
| 1722 | UNIMPLEMENTED(); | ||
| 1723 | 1748 | ||
| 1724 | LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); | 1749 | LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); |
| 1725 | ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, | 1750 | ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, |
| 1726 | "Process has already exited"); | 1751 | "Process has already exited"); |
| 1752 | |||
| 1753 | system.Exit(); | ||
| 1727 | } | 1754 | } |
| 1728 | 1755 | ||
| 1729 | static void ExitProcess32(Core::System& system) { | 1756 | static void ExitProcess32(Core::System& system) { |
| @@ -1739,8 +1766,8 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) { | |||
| 1739 | } // Anonymous namespace | 1766 | } // Anonymous namespace |
| 1740 | 1767 | ||
| 1741 | /// Creates a new thread | 1768 | /// Creates a new thread |
| 1742 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, | 1769 | static Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, |
| 1743 | VAddr stack_bottom, u32 priority, s32 core_id) { | 1770 | VAddr stack_bottom, u32 priority, s32 core_id) { |
| 1744 | LOG_DEBUG(Kernel_SVC, | 1771 | LOG_DEBUG(Kernel_SVC, |
| 1745 | "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, " | 1772 | "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, " |
| 1746 | "priority=0x{:08X}, core_id=0x{:08X}", | 1773 | "priority=0x{:08X}, core_id=0x{:08X}", |
| @@ -1811,13 +1838,13 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1811 | return ResultSuccess; | 1838 | return ResultSuccess; |
| 1812 | } | 1839 | } |
| 1813 | 1840 | ||
| 1814 | static ResultCode CreateThread32(Core::System& system, Handle* out_handle, u32 priority, | 1841 | static Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, |
| 1815 | u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { | 1842 | u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { |
| 1816 | return CreateThread(system, out_handle, entry_point, arg, stack_top, priority, processor_id); | 1843 | return CreateThread(system, out_handle, entry_point, arg, stack_top, priority, processor_id); |
| 1817 | } | 1844 | } |
| 1818 | 1845 | ||
| 1819 | /// Starts the thread for the provided handle | 1846 | /// Starts the thread for the provided handle |
| 1820 | static ResultCode StartThread(Core::System& system, Handle thread_handle) { | 1847 | static Result StartThread(Core::System& system, Handle thread_handle) { |
| 1821 | LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | 1848 | LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); |
| 1822 | 1849 | ||
| 1823 | // Get the thread from its handle. | 1850 | // Get the thread from its handle. |
| @@ -1835,7 +1862,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | |||
| 1835 | return ResultSuccess; | 1862 | return ResultSuccess; |
| 1836 | } | 1863 | } |
| 1837 | 1864 | ||
| 1838 | static ResultCode StartThread32(Core::System& system, Handle thread_handle) { | 1865 | static Result StartThread32(Core::System& system, Handle thread_handle) { |
| 1839 | return StartThread(system, thread_handle); | 1866 | return StartThread(system, thread_handle); |
| 1840 | } | 1867 | } |
| 1841 | 1868 | ||
| @@ -1843,7 +1870,7 @@ static ResultCode StartThread32(Core::System& system, Handle thread_handle) { | |||
| 1843 | static void ExitThread(Core::System& system) { | 1870 | static void ExitThread(Core::System& system) { |
| 1844 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | 1871 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); |
| 1845 | 1872 | ||
| 1846 | auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | 1873 | auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); |
| 1847 | system.GlobalSchedulerContext().RemoveThread(current_thread); | 1874 | system.GlobalSchedulerContext().RemoveThread(current_thread); |
| 1848 | current_thread->Exit(); | 1875 | current_thread->Exit(); |
| 1849 | system.Kernel().UnregisterInUseObject(current_thread); | 1876 | system.Kernel().UnregisterInUseObject(current_thread); |
| @@ -1876,7 +1903,7 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
| 1876 | KScheduler::YieldToAnyThread(kernel); | 1903 | KScheduler::YieldToAnyThread(kernel); |
| 1877 | } else { | 1904 | } else { |
| 1878 | // Nintendo does nothing at all if an otherwise invalid value is passed. | 1905 | // Nintendo does nothing at all if an otherwise invalid value is passed. |
| 1879 | UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); | 1906 | ASSERT_MSG(false, "Unimplemented sleep yield type '{:016X}'!", nanoseconds); |
| 1880 | } | 1907 | } |
| 1881 | } | 1908 | } |
| 1882 | 1909 | ||
| @@ -1886,8 +1913,8 @@ static void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanosec | |||
| 1886 | } | 1913 | } |
| 1887 | 1914 | ||
| 1888 | /// Wait process wide key atomic | 1915 | /// Wait process wide key atomic |
| 1889 | static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, | 1916 | static Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag, |
| 1890 | u32 tag, s64 timeout_ns) { | 1917 | s64 timeout_ns) { |
| 1891 | LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address, | 1918 | LOG_TRACE(Kernel_SVC, "called address={:X}, cv_key={:X}, tag=0x{:08X}, timeout_ns={}", address, |
| 1892 | cv_key, tag, timeout_ns); | 1919 | cv_key, tag, timeout_ns); |
| 1893 | 1920 | ||
| @@ -1922,8 +1949,8 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address, | |||
| 1922 | address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout); | 1949 | address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout); |
| 1923 | } | 1950 | } |
| 1924 | 1951 | ||
| 1925 | static ResultCode WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, | 1952 | static Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag, |
| 1926 | u32 timeout_ns_low, u32 timeout_ns_high) { | 1953 | u32 timeout_ns_low, u32 timeout_ns_high) { |
| 1927 | const auto timeout_ns = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); | 1954 | const auto timeout_ns = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); |
| 1928 | return WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns); | 1955 | return WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns); |
| 1929 | } | 1956 | } |
| @@ -1968,8 +1995,8 @@ constexpr bool IsValidArbitrationType(Svc::ArbitrationType type) { | |||
| 1968 | } // namespace | 1995 | } // namespace |
| 1969 | 1996 | ||
| 1970 | // Wait for an address (via Address Arbiter) | 1997 | // Wait for an address (via Address Arbiter) |
| 1971 | static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::ArbitrationType arb_type, | 1998 | static Result WaitForAddress(Core::System& system, VAddr address, Svc::ArbitrationType arb_type, |
| 1972 | s32 value, s64 timeout_ns) { | 1999 | s32 value, s64 timeout_ns) { |
| 1973 | LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}", | 2000 | LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, arb_type=0x{:X}, value=0x{:X}, timeout_ns={}", |
| 1974 | address, arb_type, value, timeout_ns); | 2001 | address, arb_type, value, timeout_ns); |
| 1975 | 2002 | ||
| @@ -2006,15 +2033,15 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::Arbit | |||
| 2006 | return system.Kernel().CurrentProcess()->WaitAddressArbiter(address, arb_type, value, timeout); | 2033 | return system.Kernel().CurrentProcess()->WaitAddressArbiter(address, arb_type, value, timeout); |
| 2007 | } | 2034 | } |
| 2008 | 2035 | ||
| 2009 | static ResultCode WaitForAddress32(Core::System& system, u32 address, Svc::ArbitrationType arb_type, | 2036 | static Result WaitForAddress32(Core::System& system, u32 address, Svc::ArbitrationType arb_type, |
| 2010 | s32 value, u32 timeout_ns_low, u32 timeout_ns_high) { | 2037 | s32 value, u32 timeout_ns_low, u32 timeout_ns_high) { |
| 2011 | const auto timeout = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); | 2038 | const auto timeout = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32)); |
| 2012 | return WaitForAddress(system, address, arb_type, value, timeout); | 2039 | return WaitForAddress(system, address, arb_type, value, timeout); |
| 2013 | } | 2040 | } |
| 2014 | 2041 | ||
| 2015 | // Signals to an address (via Address Arbiter) | 2042 | // Signals to an address (via Address Arbiter) |
| 2016 | static ResultCode SignalToAddress(Core::System& system, VAddr address, Svc::SignalType signal_type, | 2043 | static Result SignalToAddress(Core::System& system, VAddr address, Svc::SignalType signal_type, |
| 2017 | s32 value, s32 count) { | 2044 | s32 value, s32 count) { |
| 2018 | LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}", | 2045 | LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, signal_type=0x{:X}, value=0x{:X}, count=0x{:X}", |
| 2019 | address, signal_type, value, count); | 2046 | address, signal_type, value, count); |
| 2020 | 2047 | ||
| @@ -2055,8 +2082,8 @@ static void SynchronizePreemptionState(Core::System& system) { | |||
| 2055 | } | 2082 | } |
| 2056 | } | 2083 | } |
| 2057 | 2084 | ||
| 2058 | static ResultCode SignalToAddress32(Core::System& system, u32 address, Svc::SignalType signal_type, | 2085 | static Result SignalToAddress32(Core::System& system, u32 address, Svc::SignalType signal_type, |
| 2059 | s32 value, s32 count) { | 2086 | s32 value, s32 count) { |
| 2060 | return SignalToAddress(system, address, signal_type, value, count); | 2087 | return SignalToAddress(system, address, signal_type, value, count); |
| 2061 | } | 2088 | } |
| 2062 | 2089 | ||
| @@ -2094,7 +2121,7 @@ static void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) | |||
| 2094 | } | 2121 | } |
| 2095 | 2122 | ||
| 2096 | /// Close a handle | 2123 | /// Close a handle |
| 2097 | static ResultCode CloseHandle(Core::System& system, Handle handle) { | 2124 | static Result CloseHandle(Core::System& system, Handle handle) { |
| 2098 | LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); | 2125 | LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); |
| 2099 | 2126 | ||
| 2100 | // Remove the handle. | 2127 | // Remove the handle. |
| @@ -2104,12 +2131,12 @@ static ResultCode CloseHandle(Core::System& system, Handle handle) { | |||
| 2104 | return ResultSuccess; | 2131 | return ResultSuccess; |
| 2105 | } | 2132 | } |
| 2106 | 2133 | ||
| 2107 | static ResultCode CloseHandle32(Core::System& system, Handle handle) { | 2134 | static Result CloseHandle32(Core::System& system, Handle handle) { |
| 2108 | return CloseHandle(system, handle); | 2135 | return CloseHandle(system, handle); |
| 2109 | } | 2136 | } |
| 2110 | 2137 | ||
| 2111 | /// Clears the signaled state of an event or process. | 2138 | /// Clears the signaled state of an event or process. |
| 2112 | static ResultCode ResetSignal(Core::System& system, Handle handle) { | 2139 | static Result ResetSignal(Core::System& system, Handle handle) { |
| 2113 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); | 2140 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); |
| 2114 | 2141 | ||
| 2115 | // Get the current handle table. | 2142 | // Get the current handle table. |
| @@ -2136,7 +2163,7 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { | |||
| 2136 | return ResultInvalidHandle; | 2163 | return ResultInvalidHandle; |
| 2137 | } | 2164 | } |
| 2138 | 2165 | ||
| 2139 | static ResultCode ResetSignal32(Core::System& system, Handle handle) { | 2166 | static Result ResetSignal32(Core::System& system, Handle handle) { |
| 2140 | return ResetSignal(system, handle); | 2167 | return ResetSignal(system, handle); |
| 2141 | } | 2168 | } |
| 2142 | 2169 | ||
| @@ -2156,8 +2183,8 @@ constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { | |||
| 2156 | } // Anonymous namespace | 2183 | } // Anonymous namespace |
| 2157 | 2184 | ||
| 2158 | /// Creates a TransferMemory object | 2185 | /// Creates a TransferMemory object |
| 2159 | static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, | 2186 | static Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, |
| 2160 | MemoryPermission map_perm) { | 2187 | MemoryPermission map_perm) { |
| 2161 | auto& kernel = system.Kernel(); | 2188 | auto& kernel = system.Kernel(); |
| 2162 | 2189 | ||
| 2163 | // Validate the size. | 2190 | // Validate the size. |
| @@ -2203,13 +2230,13 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr | |||
| 2203 | return ResultSuccess; | 2230 | return ResultSuccess; |
| 2204 | } | 2231 | } |
| 2205 | 2232 | ||
| 2206 | static ResultCode CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, | 2233 | static Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, |
| 2207 | MemoryPermission map_perm) { | 2234 | MemoryPermission map_perm) { |
| 2208 | return CreateTransferMemory(system, out, address, size, map_perm); | 2235 | return CreateTransferMemory(system, out, address, size, map_perm); |
| 2209 | } | 2236 | } |
| 2210 | 2237 | ||
| 2211 | static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, | 2238 | static Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, |
| 2212 | u64* out_affinity_mask) { | 2239 | u64* out_affinity_mask) { |
| 2213 | LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); | 2240 | LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); |
| 2214 | 2241 | ||
| 2215 | // Get the thread from its handle. | 2242 | // Get the thread from its handle. |
| @@ -2223,8 +2250,8 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, | |||
| 2223 | return ResultSuccess; | 2250 | return ResultSuccess; |
| 2224 | } | 2251 | } |
| 2225 | 2252 | ||
| 2226 | static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, | 2253 | static Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id, |
| 2227 | u32* out_affinity_mask_low, u32* out_affinity_mask_high) { | 2254 | u32* out_affinity_mask_low, u32* out_affinity_mask_high) { |
| 2228 | u64 out_affinity_mask{}; | 2255 | u64 out_affinity_mask{}; |
| 2229 | const auto result = GetThreadCoreMask(system, thread_handle, out_core_id, &out_affinity_mask); | 2256 | const auto result = GetThreadCoreMask(system, thread_handle, out_core_id, &out_affinity_mask); |
| 2230 | *out_affinity_mask_high = static_cast<u32>(out_affinity_mask >> 32); | 2257 | *out_affinity_mask_high = static_cast<u32>(out_affinity_mask >> 32); |
| @@ -2232,8 +2259,8 @@ static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle | |||
| 2232 | return result; | 2259 | return result; |
| 2233 | } | 2260 | } |
| 2234 | 2261 | ||
| 2235 | static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, | 2262 | static Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, |
| 2236 | u64 affinity_mask) { | 2263 | u64 affinity_mask) { |
| 2237 | // Determine the core id/affinity mask. | 2264 | // Determine the core id/affinity mask. |
| 2238 | if (core_id == IdealCoreUseProcessValue) { | 2265 | if (core_id == IdealCoreUseProcessValue) { |
| 2239 | core_id = system.Kernel().CurrentProcess()->GetIdealCoreId(); | 2266 | core_id = system.Kernel().CurrentProcess()->GetIdealCoreId(); |
| @@ -2264,13 +2291,13 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, | |||
| 2264 | return ResultSuccess; | 2291 | return ResultSuccess; |
| 2265 | } | 2292 | } |
| 2266 | 2293 | ||
| 2267 | static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, | 2294 | static Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id, |
| 2268 | u32 affinity_mask_low, u32 affinity_mask_high) { | 2295 | u32 affinity_mask_low, u32 affinity_mask_high) { |
| 2269 | const auto affinity_mask = u64{affinity_mask_low} | (u64{affinity_mask_high} << 32); | 2296 | const auto affinity_mask = u64{affinity_mask_low} | (u64{affinity_mask_high} << 32); |
| 2270 | return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); | 2297 | return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); |
| 2271 | } | 2298 | } |
| 2272 | 2299 | ||
| 2273 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { | 2300 | static Result SignalEvent(Core::System& system, Handle event_handle) { |
| 2274 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); | 2301 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 2275 | 2302 | ||
| 2276 | // Get the current handle table. | 2303 | // Get the current handle table. |
| @@ -2283,11 +2310,11 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) { | |||
| 2283 | return writable_event->Signal(); | 2310 | return writable_event->Signal(); |
| 2284 | } | 2311 | } |
| 2285 | 2312 | ||
| 2286 | static ResultCode SignalEvent32(Core::System& system, Handle event_handle) { | 2313 | static Result SignalEvent32(Core::System& system, Handle event_handle) { |
| 2287 | return SignalEvent(system, event_handle); | 2314 | return SignalEvent(system, event_handle); |
| 2288 | } | 2315 | } |
| 2289 | 2316 | ||
| 2290 | static ResultCode ClearEvent(Core::System& system, Handle event_handle) { | 2317 | static Result ClearEvent(Core::System& system, Handle event_handle) { |
| 2291 | LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); | 2318 | LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 2292 | 2319 | ||
| 2293 | // Get the current handle table. | 2320 | // Get the current handle table. |
| @@ -2314,11 +2341,11 @@ static ResultCode ClearEvent(Core::System& system, Handle event_handle) { | |||
| 2314 | return ResultInvalidHandle; | 2341 | return ResultInvalidHandle; |
| 2315 | } | 2342 | } |
| 2316 | 2343 | ||
| 2317 | static ResultCode ClearEvent32(Core::System& system, Handle event_handle) { | 2344 | static Result ClearEvent32(Core::System& system, Handle event_handle) { |
| 2318 | return ClearEvent(system, event_handle); | 2345 | return ClearEvent(system, event_handle); |
| 2319 | } | 2346 | } |
| 2320 | 2347 | ||
| 2321 | static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { | 2348 | static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { |
| 2322 | LOG_DEBUG(Kernel_SVC, "called"); | 2349 | LOG_DEBUG(Kernel_SVC, "called"); |
| 2323 | 2350 | ||
| 2324 | // Get the kernel reference and handle table. | 2351 | // Get the kernel reference and handle table. |
| @@ -2363,11 +2390,11 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o | |||
| 2363 | return ResultSuccess; | 2390 | return ResultSuccess; |
| 2364 | } | 2391 | } |
| 2365 | 2392 | ||
| 2366 | static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { | 2393 | static Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { |
| 2367 | return CreateEvent(system, out_write, out_read); | 2394 | return CreateEvent(system, out_write, out_read); |
| 2368 | } | 2395 | } |
| 2369 | 2396 | ||
| 2370 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { | 2397 | static Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { |
| 2371 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); | 2398 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); |
| 2372 | 2399 | ||
| 2373 | // This function currently only allows retrieving a process' status. | 2400 | // This function currently only allows retrieving a process' status. |
| @@ -2393,7 +2420,7 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ | |||
| 2393 | return ResultSuccess; | 2420 | return ResultSuccess; |
| 2394 | } | 2421 | } |
| 2395 | 2422 | ||
| 2396 | static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { | 2423 | static Result CreateResourceLimit(Core::System& system, Handle* out_handle) { |
| 2397 | LOG_DEBUG(Kernel_SVC, "called"); | 2424 | LOG_DEBUG(Kernel_SVC, "called"); |
| 2398 | 2425 | ||
| 2399 | // Create a new resource limit. | 2426 | // Create a new resource limit. |
| @@ -2416,9 +2443,8 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) | |||
| 2416 | return ResultSuccess; | 2443 | return ResultSuccess; |
| 2417 | } | 2444 | } |
| 2418 | 2445 | ||
| 2419 | static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, | 2446 | static Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, |
| 2420 | Handle resource_limit_handle, | 2447 | Handle resource_limit_handle, LimitableResource which) { |
| 2421 | LimitableResource which) { | ||
| 2422 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, | 2448 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, |
| 2423 | which); | 2449 | which); |
| 2424 | 2450 | ||
| @@ -2437,9 +2463,8 @@ static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limi | |||
| 2437 | return ResultSuccess; | 2463 | return ResultSuccess; |
| 2438 | } | 2464 | } |
| 2439 | 2465 | ||
| 2440 | static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, | 2466 | static Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, |
| 2441 | Handle resource_limit_handle, | 2467 | Handle resource_limit_handle, LimitableResource which) { |
| 2442 | LimitableResource which) { | ||
| 2443 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, | 2468 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, |
| 2444 | which); | 2469 | which); |
| 2445 | 2470 | ||
| @@ -2458,8 +2483,8 @@ static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_cu | |||
| 2458 | return ResultSuccess; | 2483 | return ResultSuccess; |
| 2459 | } | 2484 | } |
| 2460 | 2485 | ||
| 2461 | static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, | 2486 | static Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, |
| 2462 | LimitableResource which, u64 limit_value) { | 2487 | LimitableResource which, u64 limit_value) { |
| 2463 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", | 2488 | LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", |
| 2464 | resource_limit_handle, which, limit_value); | 2489 | resource_limit_handle, which, limit_value); |
| 2465 | 2490 | ||
| @@ -2478,8 +2503,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2478 | return ResultSuccess; | 2503 | return ResultSuccess; |
| 2479 | } | 2504 | } |
| 2480 | 2505 | ||
| 2481 | static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, | 2506 | static Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids, |
| 2482 | VAddr out_process_ids, u32 out_process_ids_size) { | 2507 | u32 out_process_ids_size) { |
| 2483 | LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", | 2508 | LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", |
| 2484 | out_process_ids, out_process_ids_size); | 2509 | out_process_ids, out_process_ids_size); |
| 2485 | 2510 | ||
| @@ -2515,8 +2540,8 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, | |||
| 2515 | return ResultSuccess; | 2540 | return ResultSuccess; |
| 2516 | } | 2541 | } |
| 2517 | 2542 | ||
| 2518 | static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, | 2543 | static Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, |
| 2519 | u32 out_thread_ids_size, Handle debug_handle) { | 2544 | u32 out_thread_ids_size, Handle debug_handle) { |
| 2520 | // TODO: Handle this case when debug events are supported. | 2545 | // TODO: Handle this case when debug events are supported. |
| 2521 | UNIMPLEMENTED_IF(debug_handle != InvalidHandle); | 2546 | UNIMPLEMENTED_IF(debug_handle != InvalidHandle); |
| 2522 | 2547 | ||
| @@ -2530,7 +2555,7 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2530 | return ResultOutOfRange; | 2555 | return ResultOutOfRange; |
| 2531 | } | 2556 | } |
| 2532 | 2557 | ||
| 2533 | const auto* const current_process = system.Kernel().CurrentProcess(); | 2558 | auto* const current_process = system.Kernel().CurrentProcess(); |
| 2534 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); | 2559 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); |
| 2535 | 2560 | ||
| 2536 | if (out_thread_ids_size > 0 && | 2561 | if (out_thread_ids_size > 0 && |
| @@ -2555,9 +2580,9 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2555 | return ResultSuccess; | 2580 | return ResultSuccess; |
| 2556 | } | 2581 | } |
| 2557 | 2582 | ||
| 2558 | static ResultCode FlushProcessDataCache32([[maybe_unused]] Core::System& system, | 2583 | static Result FlushProcessDataCache32([[maybe_unused]] Core::System& system, |
| 2559 | [[maybe_unused]] Handle handle, | 2584 | [[maybe_unused]] Handle handle, [[maybe_unused]] u32 address, |
| 2560 | [[maybe_unused]] u32 address, [[maybe_unused]] u32 size) { | 2585 | [[maybe_unused]] u32 size) { |
| 2561 | // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a no-op, | 2586 | // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a no-op, |
| 2562 | // as all emulation is done in the same cache level in host architecture, thus data cache | 2587 | // as all emulation is done in the same cache level in host architecture, thus data cache |
| 2563 | // does not need flushing. | 2588 | // does not need flushing. |
| @@ -2982,11 +3007,10 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) { | |||
| 2982 | } | 3007 | } |
| 2983 | 3008 | ||
| 2984 | void Call(Core::System& system, u32 immediate) { | 3009 | void Call(Core::System& system, u32 immediate) { |
| 2985 | system.ExitDynarmicProfile(); | ||
| 2986 | auto& kernel = system.Kernel(); | 3010 | auto& kernel = system.Kernel(); |
| 2987 | kernel.EnterSVCProfile(); | 3011 | kernel.EnterSVCProfile(); |
| 2988 | 3012 | ||
| 2989 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | 3013 | auto* thread = GetCurrentThreadPointer(kernel); |
| 2990 | thread->SetIsCallingSvc(); | 3014 | thread->SetIsCallingSvc(); |
| 2991 | 3015 | ||
| 2992 | const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) | 3016 | const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) |
| @@ -3007,8 +3031,6 @@ void Call(Core::System& system, u32 immediate) { | |||
| 3007 | auto* host_context = thread->GetHostContext().get(); | 3031 | auto* host_context = thread->GetHostContext().get(); |
| 3008 | host_context->Rewind(); | 3032 | host_context->Rewind(); |
| 3009 | } | 3033 | } |
| 3010 | |||
| 3011 | system.EnterDynarmicProfile(); | ||
| 3012 | } | 3034 | } |
| 3013 | 3035 | ||
| 3014 | } // namespace Kernel::Svc | 3036 | } // namespace Kernel::Svc |
diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h index fab12d070..f27cade33 100644 --- a/src/core/hle/kernel/svc_results.h +++ b/src/core/hle/kernel/svc_results.h | |||
| @@ -9,34 +9,34 @@ namespace Kernel { | |||
| 9 | 9 | ||
| 10 | // Confirmed Switch kernel error codes | 10 | // Confirmed Switch kernel error codes |
| 11 | 11 | ||
| 12 | constexpr ResultCode ResultOutOfSessions{ErrorModule::Kernel, 7}; | 12 | constexpr Result ResultOutOfSessions{ErrorModule::Kernel, 7}; |
| 13 | constexpr ResultCode ResultInvalidArgument{ErrorModule::Kernel, 14}; | 13 | constexpr Result ResultInvalidArgument{ErrorModule::Kernel, 14}; |
| 14 | constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; | 14 | constexpr Result ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; |
| 15 | constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; | 15 | constexpr Result ResultTerminationRequested{ErrorModule::Kernel, 59}; |
| 16 | constexpr ResultCode ResultInvalidSize{ErrorModule::Kernel, 101}; | 16 | constexpr Result ResultInvalidSize{ErrorModule::Kernel, 101}; |
| 17 | constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; | 17 | constexpr Result ResultInvalidAddress{ErrorModule::Kernel, 102}; |
| 18 | constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103}; | 18 | constexpr Result ResultOutOfResource{ErrorModule::Kernel, 103}; |
| 19 | constexpr ResultCode ResultOutOfMemory{ErrorModule::Kernel, 104}; | 19 | constexpr Result ResultOutOfMemory{ErrorModule::Kernel, 104}; |
| 20 | constexpr ResultCode ResultOutOfHandles{ErrorModule::Kernel, 105}; | 20 | constexpr Result ResultOutOfHandles{ErrorModule::Kernel, 105}; |
| 21 | constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; | 21 | constexpr Result ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; |
| 22 | constexpr ResultCode ResultInvalidNewMemoryPermission{ErrorModule::Kernel, 108}; | 22 | constexpr Result ResultInvalidNewMemoryPermission{ErrorModule::Kernel, 108}; |
| 23 | constexpr ResultCode ResultInvalidMemoryRegion{ErrorModule::Kernel, 110}; | 23 | constexpr Result ResultInvalidMemoryRegion{ErrorModule::Kernel, 110}; |
| 24 | constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; | 24 | constexpr Result ResultInvalidPriority{ErrorModule::Kernel, 112}; |
| 25 | constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; | 25 | constexpr Result ResultInvalidCoreId{ErrorModule::Kernel, 113}; |
| 26 | constexpr ResultCode ResultInvalidHandle{ErrorModule::Kernel, 114}; | 26 | constexpr Result ResultInvalidHandle{ErrorModule::Kernel, 114}; |
| 27 | constexpr ResultCode ResultInvalidPointer{ErrorModule::Kernel, 115}; | 27 | constexpr Result ResultInvalidPointer{ErrorModule::Kernel, 115}; |
| 28 | constexpr ResultCode ResultInvalidCombination{ErrorModule::Kernel, 116}; | 28 | constexpr Result ResultInvalidCombination{ErrorModule::Kernel, 116}; |
| 29 | constexpr ResultCode ResultTimedOut{ErrorModule::Kernel, 117}; | 29 | constexpr Result ResultTimedOut{ErrorModule::Kernel, 117}; |
| 30 | constexpr ResultCode ResultCancelled{ErrorModule::Kernel, 118}; | 30 | constexpr Result ResultCancelled{ErrorModule::Kernel, 118}; |
| 31 | constexpr ResultCode ResultOutOfRange{ErrorModule::Kernel, 119}; | 31 | constexpr Result ResultOutOfRange{ErrorModule::Kernel, 119}; |
| 32 | constexpr ResultCode ResultInvalidEnumValue{ErrorModule::Kernel, 120}; | 32 | constexpr Result ResultInvalidEnumValue{ErrorModule::Kernel, 120}; |
| 33 | constexpr ResultCode ResultNotFound{ErrorModule::Kernel, 121}; | 33 | constexpr Result ResultNotFound{ErrorModule::Kernel, 121}; |
| 34 | constexpr ResultCode ResultBusy{ErrorModule::Kernel, 122}; | 34 | constexpr Result ResultBusy{ErrorModule::Kernel, 122}; |
| 35 | constexpr ResultCode ResultSessionClosed{ErrorModule::Kernel, 123}; | 35 | constexpr Result ResultSessionClosed{ErrorModule::Kernel, 123}; |
| 36 | constexpr ResultCode ResultInvalidState{ErrorModule::Kernel, 125}; | 36 | constexpr Result ResultInvalidState{ErrorModule::Kernel, 125}; |
| 37 | constexpr ResultCode ResultReservedUsed{ErrorModule::Kernel, 126}; | 37 | constexpr Result ResultReservedUsed{ErrorModule::Kernel, 126}; |
| 38 | constexpr ResultCode ResultPortClosed{ErrorModule::Kernel, 131}; | 38 | constexpr Result ResultPortClosed{ErrorModule::Kernel, 131}; |
| 39 | constexpr ResultCode ResultLimitReached{ErrorModule::Kernel, 132}; | 39 | constexpr Result ResultLimitReached{ErrorModule::Kernel, 132}; |
| 40 | constexpr ResultCode ResultInvalidId{ErrorModule::Kernel, 519}; | 40 | constexpr Result ResultInvalidId{ErrorModule::Kernel, 519}; |
| 41 | 41 | ||
| 42 | } // namespace Kernel | 42 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 2271bb80c..4bc49087e 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -33,24 +33,24 @@ static inline void FuncReturn32(Core::System& system, u32 result) { | |||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 35 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 36 | // Function wrappers that return type ResultCode | 36 | // Function wrappers that return type Result |
| 37 | 37 | ||
| 38 | template <ResultCode func(Core::System&, u64)> | 38 | template <Result func(Core::System&, u64)> |
| 39 | void SvcWrap64(Core::System& system) { | 39 | void SvcWrap64(Core::System& system) { |
| 40 | FuncReturn(system, func(system, Param(system, 0)).raw); | 40 | FuncReturn(system, func(system, Param(system, 0)).raw); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | template <ResultCode func(Core::System&, u64, u64)> | 43 | template <Result func(Core::System&, u64, u64)> |
| 44 | void SvcWrap64(Core::System& system) { | 44 | void SvcWrap64(Core::System& system) { |
| 45 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1)).raw); | 45 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1)).raw); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | template <ResultCode func(Core::System&, u32)> | 48 | template <Result func(Core::System&, u32)> |
| 49 | void SvcWrap64(Core::System& system) { | 49 | void SvcWrap64(Core::System& system) { |
| 50 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); | 50 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | template <ResultCode func(Core::System&, u32, u32)> | 53 | template <Result func(Core::System&, u32, u32)> |
| 54 | void SvcWrap64(Core::System& system) { | 54 | void SvcWrap64(Core::System& system) { |
| 55 | FuncReturn( | 55 | FuncReturn( |
| 56 | system, | 56 | system, |
| @@ -58,14 +58,14 @@ void SvcWrap64(Core::System& system) { | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | // Used by SetThreadActivity | 60 | // Used by SetThreadActivity |
| 61 | template <ResultCode func(Core::System&, Handle, Svc::ThreadActivity)> | 61 | template <Result func(Core::System&, Handle, Svc::ThreadActivity)> |
| 62 | void SvcWrap64(Core::System& system) { | 62 | void SvcWrap64(Core::System& system) { |
| 63 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), | 63 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), |
| 64 | static_cast<Svc::ThreadActivity>(Param(system, 1))) | 64 | static_cast<Svc::ThreadActivity>(Param(system, 1))) |
| 65 | .raw); | 65 | .raw); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | template <ResultCode func(Core::System&, u32, u64, u64, u64)> | 68 | template <Result func(Core::System&, u32, u64, u64, u64)> |
| 69 | void SvcWrap64(Core::System& system) { | 69 | void SvcWrap64(Core::System& system) { |
| 70 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), | 70 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), |
| 71 | Param(system, 2), Param(system, 3)) | 71 | Param(system, 2), Param(system, 3)) |
| @@ -73,7 +73,7 @@ void SvcWrap64(Core::System& system) { | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | // Used by MapProcessMemory and UnmapProcessMemory | 75 | // Used by MapProcessMemory and UnmapProcessMemory |
| 76 | template <ResultCode func(Core::System&, u64, u32, u64, u64)> | 76 | template <Result func(Core::System&, u64, u32, u64, u64)> |
| 77 | void SvcWrap64(Core::System& system) { | 77 | void SvcWrap64(Core::System& system) { |
| 78 | FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)), | 78 | FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)), |
| 79 | Param(system, 2), Param(system, 3)) | 79 | Param(system, 2), Param(system, 3)) |
| @@ -81,7 +81,7 @@ void SvcWrap64(Core::System& system) { | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | // Used by ControlCodeMemory | 83 | // Used by ControlCodeMemory |
| 84 | template <ResultCode func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)> | 84 | template <Result func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)> |
| 85 | void SvcWrap64(Core::System& system) { | 85 | void SvcWrap64(Core::System& system) { |
| 86 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), | 86 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), |
| 87 | static_cast<u32>(Param(system, 1)), Param(system, 2), Param(system, 3), | 87 | static_cast<u32>(Param(system, 1)), Param(system, 2), Param(system, 3), |
| @@ -89,7 +89,7 @@ void SvcWrap64(Core::System& system) { | |||
| 89 | .raw); | 89 | .raw); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | template <ResultCode func(Core::System&, u32*)> | 92 | template <Result func(Core::System&, u32*)> |
| 93 | void SvcWrap64(Core::System& system) { | 93 | void SvcWrap64(Core::System& system) { |
| 94 | u32 param = 0; | 94 | u32 param = 0; |
| 95 | const u32 retval = func(system, ¶m).raw; | 95 | const u32 retval = func(system, ¶m).raw; |
| @@ -97,7 +97,7 @@ void SvcWrap64(Core::System& system) { | |||
| 97 | FuncReturn(system, retval); | 97 | FuncReturn(system, retval); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | template <ResultCode func(Core::System&, u32*, u32)> | 100 | template <Result func(Core::System&, u32*, u32)> |
| 101 | void SvcWrap64(Core::System& system) { | 101 | void SvcWrap64(Core::System& system) { |
| 102 | u32 param_1 = 0; | 102 | u32 param_1 = 0; |
| 103 | const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; | 103 | const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; |
| @@ -105,7 +105,7 @@ void SvcWrap64(Core::System& system) { | |||
| 105 | FuncReturn(system, retval); | 105 | FuncReturn(system, retval); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | template <ResultCode func(Core::System&, u32*, u32*)> | 108 | template <Result func(Core::System&, u32*, u32*)> |
| 109 | void SvcWrap64(Core::System& system) { | 109 | void SvcWrap64(Core::System& system) { |
| 110 | u32 param_1 = 0; | 110 | u32 param_1 = 0; |
| 111 | u32 param_2 = 0; | 111 | u32 param_2 = 0; |
| @@ -118,7 +118,7 @@ void SvcWrap64(Core::System& system) { | |||
| 118 | FuncReturn(system, retval); | 118 | FuncReturn(system, retval); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | template <ResultCode func(Core::System&, u32*, u64)> | 121 | template <Result func(Core::System&, u32*, u64)> |
| 122 | void SvcWrap64(Core::System& system) { | 122 | void SvcWrap64(Core::System& system) { |
| 123 | u32 param_1 = 0; | 123 | u32 param_1 = 0; |
| 124 | const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; | 124 | const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; |
| @@ -126,7 +126,7 @@ void SvcWrap64(Core::System& system) { | |||
| 126 | FuncReturn(system, retval); | 126 | FuncReturn(system, retval); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | template <ResultCode func(Core::System&, u32*, u64, u32)> | 129 | template <Result func(Core::System&, u32*, u64, u32)> |
| 130 | void SvcWrap64(Core::System& system) { | 130 | void SvcWrap64(Core::System& system) { |
| 131 | u32 param_1 = 0; | 131 | u32 param_1 = 0; |
| 132 | const u32 retval = | 132 | const u32 retval = |
| @@ -136,7 +136,7 @@ void SvcWrap64(Core::System& system) { | |||
| 136 | FuncReturn(system, retval); | 136 | FuncReturn(system, retval); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | template <ResultCode func(Core::System&, u64*, u32)> | 139 | template <Result func(Core::System&, u64*, u32)> |
| 140 | void SvcWrap64(Core::System& system) { | 140 | void SvcWrap64(Core::System& system) { |
| 141 | u64 param_1 = 0; | 141 | u64 param_1 = 0; |
| 142 | const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; | 142 | const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1))).raw; |
| @@ -145,12 +145,12 @@ void SvcWrap64(Core::System& system) { | |||
| 145 | FuncReturn(system, retval); | 145 | FuncReturn(system, retval); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | template <ResultCode func(Core::System&, u64, u32)> | 148 | template <Result func(Core::System&, u64, u32)> |
| 149 | void SvcWrap64(Core::System& system) { | 149 | void SvcWrap64(Core::System& system) { |
| 150 | FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw); | 150 | FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1))).raw); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | template <ResultCode func(Core::System&, u64*, u64)> | 153 | template <Result func(Core::System&, u64*, u64)> |
| 154 | void SvcWrap64(Core::System& system) { | 154 | void SvcWrap64(Core::System& system) { |
| 155 | u64 param_1 = 0; | 155 | u64 param_1 = 0; |
| 156 | const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; | 156 | const u32 retval = func(system, ¶m_1, Param(system, 1)).raw; |
| @@ -159,7 +159,7 @@ void SvcWrap64(Core::System& system) { | |||
| 159 | FuncReturn(system, retval); | 159 | FuncReturn(system, retval); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | template <ResultCode func(Core::System&, u64*, u32, u32)> | 162 | template <Result func(Core::System&, u64*, u32, u32)> |
| 163 | void SvcWrap64(Core::System& system) { | 163 | void SvcWrap64(Core::System& system) { |
| 164 | u64 param_1 = 0; | 164 | u64 param_1 = 0; |
| 165 | const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1)), | 165 | const u32 retval = func(system, ¶m_1, static_cast<u32>(Param(system, 1)), |
| @@ -171,7 +171,7 @@ void SvcWrap64(Core::System& system) { | |||
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | // Used by GetResourceLimitLimitValue. | 173 | // Used by GetResourceLimitLimitValue. |
| 174 | template <ResultCode func(Core::System&, u64*, Handle, LimitableResource)> | 174 | template <Result func(Core::System&, u64*, Handle, LimitableResource)> |
| 175 | void SvcWrap64(Core::System& system) { | 175 | void SvcWrap64(Core::System& system) { |
| 176 | u64 param_1 = 0; | 176 | u64 param_1 = 0; |
| 177 | const u32 retval = func(system, ¶m_1, static_cast<Handle>(Param(system, 1)), | 177 | const u32 retval = func(system, ¶m_1, static_cast<Handle>(Param(system, 1)), |
| @@ -182,13 +182,13 @@ void SvcWrap64(Core::System& system) { | |||
| 182 | FuncReturn(system, retval); | 182 | FuncReturn(system, retval); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | template <ResultCode func(Core::System&, u32, u64)> | 185 | template <Result func(Core::System&, u32, u64)> |
| 186 | void SvcWrap64(Core::System& system) { | 186 | void SvcWrap64(Core::System& system) { |
| 187 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); | 187 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | // Used by SetResourceLimitLimitValue | 190 | // Used by SetResourceLimitLimitValue |
| 191 | template <ResultCode func(Core::System&, Handle, LimitableResource, u64)> | 191 | template <Result func(Core::System&, Handle, LimitableResource, u64)> |
| 192 | void SvcWrap64(Core::System& system) { | 192 | void SvcWrap64(Core::System& system) { |
| 193 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), | 193 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), |
| 194 | static_cast<LimitableResource>(Param(system, 1)), Param(system, 2)) | 194 | static_cast<LimitableResource>(Param(system, 1)), Param(system, 2)) |
| @@ -196,7 +196,7 @@ void SvcWrap64(Core::System& system) { | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | // Used by SetThreadCoreMask | 198 | // Used by SetThreadCoreMask |
| 199 | template <ResultCode func(Core::System&, Handle, s32, u64)> | 199 | template <Result func(Core::System&, Handle, s32, u64)> |
| 200 | void SvcWrap64(Core::System& system) { | 200 | void SvcWrap64(Core::System& system) { |
| 201 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), | 201 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), |
| 202 | static_cast<s32>(Param(system, 1)), Param(system, 2)) | 202 | static_cast<s32>(Param(system, 1)), Param(system, 2)) |
| @@ -204,44 +204,44 @@ void SvcWrap64(Core::System& system) { | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | // Used by GetThreadCoreMask | 206 | // Used by GetThreadCoreMask |
| 207 | template <ResultCode func(Core::System&, Handle, s32*, u64*)> | 207 | template <Result func(Core::System&, Handle, s32*, u64*)> |
| 208 | void SvcWrap64(Core::System& system) { | 208 | void SvcWrap64(Core::System& system) { |
| 209 | s32 param_1 = 0; | 209 | s32 param_1 = 0; |
| 210 | u64 param_2 = 0; | 210 | u64 param_2 = 0; |
| 211 | const ResultCode retval = func(system, static_cast<u32>(Param(system, 2)), ¶m_1, ¶m_2); | 211 | const Result retval = func(system, static_cast<u32>(Param(system, 2)), ¶m_1, ¶m_2); |
| 212 | 212 | ||
| 213 | system.CurrentArmInterface().SetReg(1, param_1); | 213 | system.CurrentArmInterface().SetReg(1, param_1); |
| 214 | system.CurrentArmInterface().SetReg(2, param_2); | 214 | system.CurrentArmInterface().SetReg(2, param_2); |
| 215 | FuncReturn(system, retval.raw); | 215 | FuncReturn(system, retval.raw); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | template <ResultCode func(Core::System&, u64, u64, u32, u32)> | 218 | template <Result func(Core::System&, u64, u64, u32, u32)> |
| 219 | void SvcWrap64(Core::System& system) { | 219 | void SvcWrap64(Core::System& system) { |
| 220 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), | 220 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), |
| 221 | static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) | 221 | static_cast<u32>(Param(system, 2)), static_cast<u32>(Param(system, 3))) |
| 222 | .raw); | 222 | .raw); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | template <ResultCode func(Core::System&, u64, u64, u32, u64)> | 225 | template <Result func(Core::System&, u64, u64, u32, u64)> |
| 226 | void SvcWrap64(Core::System& system) { | 226 | void SvcWrap64(Core::System& system) { |
| 227 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), | 227 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), |
| 228 | static_cast<u32>(Param(system, 2)), Param(system, 3)) | 228 | static_cast<u32>(Param(system, 2)), Param(system, 3)) |
| 229 | .raw); | 229 | .raw); |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | template <ResultCode func(Core::System&, u32, u64, u32)> | 232 | template <Result func(Core::System&, u32, u64, u32)> |
| 233 | void SvcWrap64(Core::System& system) { | 233 | void SvcWrap64(Core::System& system) { |
| 234 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), | 234 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), |
| 235 | static_cast<u32>(Param(system, 2))) | 235 | static_cast<u32>(Param(system, 2))) |
| 236 | .raw); | 236 | .raw); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | template <ResultCode func(Core::System&, u64, u64, u64)> | 239 | template <Result func(Core::System&, u64, u64, u64)> |
| 240 | void SvcWrap64(Core::System& system) { | 240 | void SvcWrap64(Core::System& system) { |
| 241 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw); | 241 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), Param(system, 2)).raw); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | template <ResultCode func(Core::System&, u64, u64, u32)> | 244 | template <Result func(Core::System&, u64, u64, u32)> |
| 245 | void SvcWrap64(Core::System& system) { | 245 | void SvcWrap64(Core::System& system) { |
| 246 | FuncReturn( | 246 | FuncReturn( |
| 247 | system, | 247 | system, |
| @@ -249,7 +249,7 @@ void SvcWrap64(Core::System& system) { | |||
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | // Used by SetMemoryPermission | 251 | // Used by SetMemoryPermission |
| 252 | template <ResultCode func(Core::System&, u64, u64, Svc::MemoryPermission)> | 252 | template <Result func(Core::System&, u64, u64, Svc::MemoryPermission)> |
| 253 | void SvcWrap64(Core::System& system) { | 253 | void SvcWrap64(Core::System& system) { |
| 254 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), | 254 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), |
| 255 | static_cast<Svc::MemoryPermission>(Param(system, 2))) | 255 | static_cast<Svc::MemoryPermission>(Param(system, 2))) |
| @@ -257,14 +257,14 @@ void SvcWrap64(Core::System& system) { | |||
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | // Used by MapSharedMemory | 259 | // Used by MapSharedMemory |
| 260 | template <ResultCode func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)> | 260 | template <Result func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)> |
| 261 | void SvcWrap64(Core::System& system) { | 261 | void SvcWrap64(Core::System& system) { |
| 262 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), Param(system, 1), | 262 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), Param(system, 1), |
| 263 | Param(system, 2), static_cast<Svc::MemoryPermission>(Param(system, 3))) | 263 | Param(system, 2), static_cast<Svc::MemoryPermission>(Param(system, 3))) |
| 264 | .raw); | 264 | .raw); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | template <ResultCode func(Core::System&, u32, u64, u64)> | 267 | template <Result func(Core::System&, u32, u64, u64)> |
| 268 | void SvcWrap64(Core::System& system) { | 268 | void SvcWrap64(Core::System& system) { |
| 269 | FuncReturn( | 269 | FuncReturn( |
| 270 | system, | 270 | system, |
| @@ -272,7 +272,7 @@ void SvcWrap64(Core::System& system) { | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | // Used by WaitSynchronization | 274 | // Used by WaitSynchronization |
| 275 | template <ResultCode func(Core::System&, s32*, u64, s32, s64)> | 275 | template <Result func(Core::System&, s32*, u64, s32, s64)> |
| 276 | void SvcWrap64(Core::System& system) { | 276 | void SvcWrap64(Core::System& system) { |
| 277 | s32 param_1 = 0; | 277 | s32 param_1 = 0; |
| 278 | const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<s32>(Param(system, 2)), | 278 | const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<s32>(Param(system, 2)), |
| @@ -283,7 +283,7 @@ void SvcWrap64(Core::System& system) { | |||
| 283 | FuncReturn(system, retval); | 283 | FuncReturn(system, retval); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | template <ResultCode func(Core::System&, u64, u64, u32, s64)> | 286 | template <Result func(Core::System&, u64, u64, u32, s64)> |
| 287 | void SvcWrap64(Core::System& system) { | 287 | void SvcWrap64(Core::System& system) { |
| 288 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), | 288 | FuncReturn(system, func(system, Param(system, 0), Param(system, 1), |
| 289 | static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) | 289 | static_cast<u32>(Param(system, 2)), static_cast<s64>(Param(system, 3))) |
| @@ -291,7 +291,7 @@ void SvcWrap64(Core::System& system) { | |||
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | // Used by GetInfo | 293 | // Used by GetInfo |
| 294 | template <ResultCode func(Core::System&, u64*, u64, Handle, u64)> | 294 | template <Result func(Core::System&, u64*, u64, Handle, u64)> |
| 295 | void SvcWrap64(Core::System& system) { | 295 | void SvcWrap64(Core::System& system) { |
| 296 | u64 param_1 = 0; | 296 | u64 param_1 = 0; |
| 297 | const u32 retval = func(system, ¶m_1, Param(system, 1), | 297 | const u32 retval = func(system, ¶m_1, Param(system, 1), |
| @@ -302,7 +302,7 @@ void SvcWrap64(Core::System& system) { | |||
| 302 | FuncReturn(system, retval); | 302 | FuncReturn(system, retval); |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | template <ResultCode func(Core::System&, u32*, u64, u64, u64, u32, s32)> | 305 | template <Result func(Core::System&, u32*, u64, u64, u64, u32, s32)> |
| 306 | void SvcWrap64(Core::System& system) { | 306 | void SvcWrap64(Core::System& system) { |
| 307 | u32 param_1 = 0; | 307 | u32 param_1 = 0; |
| 308 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), Param(system, 3), | 308 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), Param(system, 3), |
| @@ -314,7 +314,7 @@ void SvcWrap64(Core::System& system) { | |||
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | // Used by CreateTransferMemory | 316 | // Used by CreateTransferMemory |
| 317 | template <ResultCode func(Core::System&, Handle*, u64, u64, Svc::MemoryPermission)> | 317 | template <Result func(Core::System&, Handle*, u64, u64, Svc::MemoryPermission)> |
| 318 | void SvcWrap64(Core::System& system) { | 318 | void SvcWrap64(Core::System& system) { |
| 319 | u32 param_1 = 0; | 319 | u32 param_1 = 0; |
| 320 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), | 320 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), |
| @@ -326,7 +326,7 @@ void SvcWrap64(Core::System& system) { | |||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | // Used by CreateCodeMemory | 328 | // Used by CreateCodeMemory |
| 329 | template <ResultCode func(Core::System&, Handle*, u64, u64)> | 329 | template <Result func(Core::System&, Handle*, u64, u64)> |
| 330 | void SvcWrap64(Core::System& system) { | 330 | void SvcWrap64(Core::System& system) { |
| 331 | u32 param_1 = 0; | 331 | u32 param_1 = 0; |
| 332 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2)).raw; | 332 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2)).raw; |
| @@ -335,7 +335,7 @@ void SvcWrap64(Core::System& system) { | |||
| 335 | FuncReturn(system, retval); | 335 | FuncReturn(system, retval); |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | template <ResultCode func(Core::System&, Handle*, u64, u32, u32)> | 338 | template <Result func(Core::System&, Handle*, u64, u32, u32)> |
| 339 | void SvcWrap64(Core::System& system) { | 339 | void SvcWrap64(Core::System& system) { |
| 340 | u32 param_1 = 0; | 340 | u32 param_1 = 0; |
| 341 | const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), | 341 | const u32 retval = func(system, ¶m_1, Param(system, 1), static_cast<u32>(Param(system, 2)), |
| @@ -347,7 +347,7 @@ void SvcWrap64(Core::System& system) { | |||
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | // Used by WaitForAddress | 349 | // Used by WaitForAddress |
| 350 | template <ResultCode func(Core::System&, u64, Svc::ArbitrationType, s32, s64)> | 350 | template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)> |
| 351 | void SvcWrap64(Core::System& system) { | 351 | void SvcWrap64(Core::System& system) { |
| 352 | FuncReturn(system, | 352 | FuncReturn(system, |
| 353 | func(system, Param(system, 0), static_cast<Svc::ArbitrationType>(Param(system, 1)), | 353 | func(system, Param(system, 0), static_cast<Svc::ArbitrationType>(Param(system, 1)), |
| @@ -356,7 +356,7 @@ void SvcWrap64(Core::System& system) { | |||
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | // Used by SignalToAddress | 358 | // Used by SignalToAddress |
| 359 | template <ResultCode func(Core::System&, u64, Svc::SignalType, s32, s32)> | 359 | template <Result func(Core::System&, u64, Svc::SignalType, s32, s32)> |
| 360 | void SvcWrap64(Core::System& system) { | 360 | void SvcWrap64(Core::System& system) { |
| 361 | FuncReturn(system, | 361 | FuncReturn(system, |
| 362 | func(system, Param(system, 0), static_cast<Svc::SignalType>(Param(system, 1)), | 362 | func(system, Param(system, 0), static_cast<Svc::SignalType>(Param(system, 1)), |
| @@ -425,7 +425,7 @@ void SvcWrap64(Core::System& system) { | |||
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | // Used by QueryMemory32, ArbitrateLock32 | 427 | // Used by QueryMemory32, ArbitrateLock32 |
| 428 | template <ResultCode func(Core::System&, u32, u32, u32)> | 428 | template <Result func(Core::System&, u32, u32, u32)> |
| 429 | void SvcWrap32(Core::System& system) { | 429 | void SvcWrap32(Core::System& system) { |
| 430 | FuncReturn32(system, | 430 | FuncReturn32(system, |
| 431 | func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw); | 431 | func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2)).raw); |
| @@ -456,7 +456,7 @@ void SvcWrap32(Core::System& system) { | |||
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | // Used by CreateThread32 | 458 | // Used by CreateThread32 |
| 459 | template <ResultCode func(Core::System&, Handle*, u32, u32, u32, u32, s32)> | 459 | template <Result func(Core::System&, Handle*, u32, u32, u32, u32, s32)> |
| 460 | void SvcWrap32(Core::System& system) { | 460 | void SvcWrap32(Core::System& system) { |
| 461 | Handle param_1 = 0; | 461 | Handle param_1 = 0; |
| 462 | 462 | ||
| @@ -469,7 +469,7 @@ void SvcWrap32(Core::System& system) { | |||
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | // Used by GetInfo32 | 471 | // Used by GetInfo32 |
| 472 | template <ResultCode func(Core::System&, u32*, u32*, u32, u32, u32, u32)> | 472 | template <Result func(Core::System&, u32*, u32*, u32, u32, u32, u32)> |
| 473 | void SvcWrap32(Core::System& system) { | 473 | void SvcWrap32(Core::System& system) { |
| 474 | u32 param_1 = 0; | 474 | u32 param_1 = 0; |
| 475 | u32 param_2 = 0; | 475 | u32 param_2 = 0; |
| @@ -484,7 +484,7 @@ void SvcWrap32(Core::System& system) { | |||
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | // Used by GetThreadPriority32, ConnectToNamedPort32 | 486 | // Used by GetThreadPriority32, ConnectToNamedPort32 |
| 487 | template <ResultCode func(Core::System&, u32*, u32)> | 487 | template <Result func(Core::System&, u32*, u32)> |
| 488 | void SvcWrap32(Core::System& system) { | 488 | void SvcWrap32(Core::System& system) { |
| 489 | u32 param_1 = 0; | 489 | u32 param_1 = 0; |
| 490 | const u32 retval = func(system, ¶m_1, Param32(system, 1)).raw; | 490 | const u32 retval = func(system, ¶m_1, Param32(system, 1)).raw; |
| @@ -493,7 +493,7 @@ void SvcWrap32(Core::System& system) { | |||
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | // Used by GetThreadId32 | 495 | // Used by GetThreadId32 |
| 496 | template <ResultCode func(Core::System&, u32*, u32*, u32)> | 496 | template <Result func(Core::System&, u32*, u32*, u32)> |
| 497 | void SvcWrap32(Core::System& system) { | 497 | void SvcWrap32(Core::System& system) { |
| 498 | u32 param_1 = 0; | 498 | u32 param_1 = 0; |
| 499 | u32 param_2 = 0; | 499 | u32 param_2 = 0; |
| @@ -516,7 +516,7 @@ void SvcWrap32(Core::System& system) { | |||
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | // Used by CreateEvent32 | 518 | // Used by CreateEvent32 |
| 519 | template <ResultCode func(Core::System&, Handle*, Handle*)> | 519 | template <Result func(Core::System&, Handle*, Handle*)> |
| 520 | void SvcWrap32(Core::System& system) { | 520 | void SvcWrap32(Core::System& system) { |
| 521 | Handle param_1 = 0; | 521 | Handle param_1 = 0; |
| 522 | Handle param_2 = 0; | 522 | Handle param_2 = 0; |
| @@ -528,7 +528,7 @@ void SvcWrap32(Core::System& system) { | |||
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | // Used by GetThreadId32 | 530 | // Used by GetThreadId32 |
| 531 | template <ResultCode func(Core::System&, Handle, u32*, u32*, u32*)> | 531 | template <Result func(Core::System&, Handle, u32*, u32*, u32*)> |
| 532 | void SvcWrap32(Core::System& system) { | 532 | void SvcWrap32(Core::System& system) { |
| 533 | u32 param_1 = 0; | 533 | u32 param_1 = 0; |
| 534 | u32 param_2 = 0; | 534 | u32 param_2 = 0; |
| @@ -542,7 +542,7 @@ void SvcWrap32(Core::System& system) { | |||
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | // Used by GetThreadCoreMask32 | 544 | // Used by GetThreadCoreMask32 |
| 545 | template <ResultCode func(Core::System&, Handle, s32*, u32*, u32*)> | 545 | template <Result func(Core::System&, Handle, s32*, u32*, u32*)> |
| 546 | void SvcWrap32(Core::System& system) { | 546 | void SvcWrap32(Core::System& system) { |
| 547 | s32 param_1 = 0; | 547 | s32 param_1 = 0; |
| 548 | u32 param_2 = 0; | 548 | u32 param_2 = 0; |
| @@ -562,7 +562,7 @@ void SvcWrap32(Core::System& system) { | |||
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | // Used by SetThreadActivity32 | 564 | // Used by SetThreadActivity32 |
| 565 | template <ResultCode func(Core::System&, Handle, Svc::ThreadActivity)> | 565 | template <Result func(Core::System&, Handle, Svc::ThreadActivity)> |
| 566 | void SvcWrap32(Core::System& system) { | 566 | void SvcWrap32(Core::System& system) { |
| 567 | const u32 retval = func(system, static_cast<Handle>(Param(system, 0)), | 567 | const u32 retval = func(system, static_cast<Handle>(Param(system, 0)), |
| 568 | static_cast<Svc::ThreadActivity>(Param(system, 1))) | 568 | static_cast<Svc::ThreadActivity>(Param(system, 1))) |
| @@ -571,7 +571,7 @@ void SvcWrap32(Core::System& system) { | |||
| 571 | } | 571 | } |
| 572 | 572 | ||
| 573 | // Used by SetThreadPriority32 | 573 | // Used by SetThreadPriority32 |
| 574 | template <ResultCode func(Core::System&, Handle, u32)> | 574 | template <Result func(Core::System&, Handle, u32)> |
| 575 | void SvcWrap32(Core::System& system) { | 575 | void SvcWrap32(Core::System& system) { |
| 576 | const u32 retval = | 576 | const u32 retval = |
| 577 | func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw; | 577 | func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw; |
| @@ -579,7 +579,7 @@ void SvcWrap32(Core::System& system) { | |||
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | // Used by SetMemoryAttribute32 | 581 | // Used by SetMemoryAttribute32 |
| 582 | template <ResultCode func(Core::System&, Handle, u32, u32, u32)> | 582 | template <Result func(Core::System&, Handle, u32, u32, u32)> |
| 583 | void SvcWrap32(Core::System& system) { | 583 | void SvcWrap32(Core::System& system) { |
| 584 | const u32 retval = | 584 | const u32 retval = |
| 585 | func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1)), | 585 | func(system, static_cast<Handle>(Param(system, 0)), static_cast<u32>(Param(system, 1)), |
| @@ -589,7 +589,7 @@ void SvcWrap32(Core::System& system) { | |||
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | // Used by MapSharedMemory32 | 591 | // Used by MapSharedMemory32 |
| 592 | template <ResultCode func(Core::System&, Handle, u32, u32, Svc::MemoryPermission)> | 592 | template <Result func(Core::System&, Handle, u32, u32, Svc::MemoryPermission)> |
| 593 | void SvcWrap32(Core::System& system) { | 593 | void SvcWrap32(Core::System& system) { |
| 594 | const u32 retval = func(system, static_cast<Handle>(Param(system, 0)), | 594 | const u32 retval = func(system, static_cast<Handle>(Param(system, 0)), |
| 595 | static_cast<u32>(Param(system, 1)), static_cast<u32>(Param(system, 2)), | 595 | static_cast<u32>(Param(system, 1)), static_cast<u32>(Param(system, 2)), |
| @@ -599,7 +599,7 @@ void SvcWrap32(Core::System& system) { | |||
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | // Used by SetThreadCoreMask32 | 601 | // Used by SetThreadCoreMask32 |
| 602 | template <ResultCode func(Core::System&, Handle, s32, u32, u32)> | 602 | template <Result func(Core::System&, Handle, s32, u32, u32)> |
| 603 | void SvcWrap32(Core::System& system) { | 603 | void SvcWrap32(Core::System& system) { |
| 604 | const u32 retval = | 604 | const u32 retval = |
| 605 | func(system, static_cast<Handle>(Param(system, 0)), static_cast<s32>(Param(system, 1)), | 605 | func(system, static_cast<Handle>(Param(system, 0)), static_cast<s32>(Param(system, 1)), |
| @@ -609,7 +609,7 @@ void SvcWrap32(Core::System& system) { | |||
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | // Used by WaitProcessWideKeyAtomic32 | 611 | // Used by WaitProcessWideKeyAtomic32 |
| 612 | template <ResultCode func(Core::System&, u32, u32, Handle, u32, u32)> | 612 | template <Result func(Core::System&, u32, u32, Handle, u32, u32)> |
| 613 | void SvcWrap32(Core::System& system) { | 613 | void SvcWrap32(Core::System& system) { |
| 614 | const u32 retval = | 614 | const u32 retval = |
| 615 | func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), | 615 | func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1)), |
| @@ -620,7 +620,7 @@ void SvcWrap32(Core::System& system) { | |||
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | // Used by WaitForAddress32 | 622 | // Used by WaitForAddress32 |
| 623 | template <ResultCode func(Core::System&, u32, Svc::ArbitrationType, s32, u32, u32)> | 623 | template <Result func(Core::System&, u32, Svc::ArbitrationType, s32, u32, u32)> |
| 624 | void SvcWrap32(Core::System& system) { | 624 | void SvcWrap32(Core::System& system) { |
| 625 | const u32 retval = func(system, static_cast<u32>(Param(system, 0)), | 625 | const u32 retval = func(system, static_cast<u32>(Param(system, 0)), |
| 626 | static_cast<Svc::ArbitrationType>(Param(system, 1)), | 626 | static_cast<Svc::ArbitrationType>(Param(system, 1)), |
| @@ -631,7 +631,7 @@ void SvcWrap32(Core::System& system) { | |||
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | // Used by SignalToAddress32 | 633 | // Used by SignalToAddress32 |
| 634 | template <ResultCode func(Core::System&, u32, Svc::SignalType, s32, s32)> | 634 | template <Result func(Core::System&, u32, Svc::SignalType, s32, s32)> |
| 635 | void SvcWrap32(Core::System& system) { | 635 | void SvcWrap32(Core::System& system) { |
| 636 | const u32 retval = func(system, static_cast<u32>(Param(system, 0)), | 636 | const u32 retval = func(system, static_cast<u32>(Param(system, 0)), |
| 637 | static_cast<Svc::SignalType>(Param(system, 1)), | 637 | static_cast<Svc::SignalType>(Param(system, 1)), |
| @@ -641,13 +641,13 @@ void SvcWrap32(Core::System& system) { | |||
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | // Used by SendSyncRequest32, ArbitrateUnlock32 | 643 | // Used by SendSyncRequest32, ArbitrateUnlock32 |
| 644 | template <ResultCode func(Core::System&, u32)> | 644 | template <Result func(Core::System&, u32)> |
| 645 | void SvcWrap32(Core::System& system) { | 645 | void SvcWrap32(Core::System& system) { |
| 646 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); | 646 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0))).raw); |
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | // Used by CreateTransferMemory32 | 649 | // Used by CreateTransferMemory32 |
| 650 | template <ResultCode func(Core::System&, Handle*, u32, u32, Svc::MemoryPermission)> | 650 | template <Result func(Core::System&, Handle*, u32, u32, Svc::MemoryPermission)> |
| 651 | void SvcWrap32(Core::System& system) { | 651 | void SvcWrap32(Core::System& system) { |
| 652 | Handle handle = 0; | 652 | Handle handle = 0; |
| 653 | const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), | 653 | const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), |
| @@ -658,7 +658,7 @@ void SvcWrap32(Core::System& system) { | |||
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | // Used by WaitSynchronization32 | 660 | // Used by WaitSynchronization32 |
| 661 | template <ResultCode func(Core::System&, u32, u32, s32, u32, s32*)> | 661 | template <Result func(Core::System&, u32, u32, s32, u32, s32*)> |
| 662 | void SvcWrap32(Core::System& system) { | 662 | void SvcWrap32(Core::System& system) { |
| 663 | s32 param_1 = 0; | 663 | s32 param_1 = 0; |
| 664 | const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2), | 664 | const u32 retval = func(system, Param32(system, 0), Param32(system, 1), Param32(system, 2), |
| @@ -669,7 +669,7 @@ void SvcWrap32(Core::System& system) { | |||
| 669 | } | 669 | } |
| 670 | 670 | ||
| 671 | // Used by CreateCodeMemory32 | 671 | // Used by CreateCodeMemory32 |
| 672 | template <ResultCode func(Core::System&, Handle*, u32, u32)> | 672 | template <Result func(Core::System&, Handle*, u32, u32)> |
| 673 | void SvcWrap32(Core::System& system) { | 673 | void SvcWrap32(Core::System& system) { |
| 674 | Handle handle = 0; | 674 | Handle handle = 0; |
| 675 | 675 | ||
| @@ -680,7 +680,7 @@ void SvcWrap32(Core::System& system) { | |||
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | // Used by ControlCodeMemory32 | 682 | // Used by ControlCodeMemory32 |
| 683 | template <ResultCode func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)> | 683 | template <Result func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)> |
| 684 | void SvcWrap32(Core::System& system) { | 684 | void SvcWrap32(Core::System& system) { |
| 685 | const u32 retval = | 685 | const u32 retval = |
| 686 | func(system, Param32(system, 0), Param32(system, 1), Param(system, 2), Param(system, 4), | 686 | func(system, Param32(system, 0), Param32(system, 1), Param(system, 2), Param(system, 4), |
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 569dd9f38..aa9e5b89d 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -112,15 +112,15 @@ enum class ErrorModule : u32 { | |||
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | /// Encapsulates a Horizon OS error code, allowing it to be separated into its constituent fields. | 114 | /// Encapsulates a Horizon OS error code, allowing it to be separated into its constituent fields. |
| 115 | union ResultCode { | 115 | union Result { |
| 116 | u32 raw; | 116 | u32 raw; |
| 117 | 117 | ||
| 118 | BitField<0, 9, ErrorModule> module; | 118 | BitField<0, 9, ErrorModule> module; |
| 119 | BitField<9, 13, u32> description; | 119 | BitField<9, 13, u32> description; |
| 120 | 120 | ||
| 121 | constexpr explicit ResultCode(u32 raw_) : raw(raw_) {} | 121 | constexpr explicit Result(u32 raw_) : raw(raw_) {} |
| 122 | 122 | ||
| 123 | constexpr ResultCode(ErrorModule module_, u32 description_) | 123 | constexpr Result(ErrorModule module_, u32 description_) |
| 124 | : raw(module.FormatValue(module_) | description.FormatValue(description_)) {} | 124 | : raw(module.FormatValue(module_) | description.FormatValue(description_)) {} |
| 125 | 125 | ||
| 126 | [[nodiscard]] constexpr bool IsSuccess() const { | 126 | [[nodiscard]] constexpr bool IsSuccess() const { |
| @@ -132,18 +132,18 @@ union ResultCode { | |||
| 132 | } | 132 | } |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | [[nodiscard]] constexpr bool operator==(const ResultCode& a, const ResultCode& b) { | 135 | [[nodiscard]] constexpr bool operator==(const Result& a, const Result& b) { |
| 136 | return a.raw == b.raw; | 136 | return a.raw == b.raw; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | [[nodiscard]] constexpr bool operator!=(const ResultCode& a, const ResultCode& b) { | 139 | [[nodiscard]] constexpr bool operator!=(const Result& a, const Result& b) { |
| 140 | return !operator==(a, b); | 140 | return !operator==(a, b); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | // Convenience functions for creating some common kinds of errors: | 143 | // Convenience functions for creating some common kinds of errors: |
| 144 | 144 | ||
| 145 | /// The default success `ResultCode`. | 145 | /// The default success `Result`. |
| 146 | constexpr ResultCode ResultSuccess(0); | 146 | constexpr Result ResultSuccess(0); |
| 147 | 147 | ||
| 148 | /** | 148 | /** |
| 149 | * Placeholder result code used for unknown error codes. | 149 | * Placeholder result code used for unknown error codes. |
| @@ -151,24 +151,24 @@ constexpr ResultCode ResultSuccess(0); | |||
| 151 | * @note This should only be used when a particular error code | 151 | * @note This should only be used when a particular error code |
| 152 | * is not known yet. | 152 | * is not known yet. |
| 153 | */ | 153 | */ |
| 154 | constexpr ResultCode ResultUnknown(UINT32_MAX); | 154 | constexpr Result ResultUnknown(UINT32_MAX); |
| 155 | 155 | ||
| 156 | /** | 156 | /** |
| 157 | * A ResultRange defines an inclusive range of error descriptions within an error module. | 157 | * A ResultRange defines an inclusive range of error descriptions within an error module. |
| 158 | * This can be used to check whether the description of a given ResultCode falls within the range. | 158 | * This can be used to check whether the description of a given Result falls within the range. |
| 159 | * The conversion function returns a ResultCode with its description set to description_start. | 159 | * The conversion function returns a Result with its description set to description_start. |
| 160 | * | 160 | * |
| 161 | * An example of how it could be used: | 161 | * An example of how it could be used: |
| 162 | * \code | 162 | * \code |
| 163 | * constexpr ResultRange ResultCommonError{ErrorModule::Common, 0, 9999}; | 163 | * constexpr ResultRange ResultCommonError{ErrorModule::Common, 0, 9999}; |
| 164 | * | 164 | * |
| 165 | * ResultCode Example(int value) { | 165 | * Result Example(int value) { |
| 166 | * const ResultCode result = OtherExample(value); | 166 | * const Result result = OtherExample(value); |
| 167 | * | 167 | * |
| 168 | * // This will only evaluate to true if result.module is ErrorModule::Common and | 168 | * // This will only evaluate to true if result.module is ErrorModule::Common and |
| 169 | * // result.description is in between 0 and 9999 inclusive. | 169 | * // result.description is in between 0 and 9999 inclusive. |
| 170 | * if (ResultCommonError.Includes(result)) { | 170 | * if (ResultCommonError.Includes(result)) { |
| 171 | * // This returns ResultCode{ErrorModule::Common, 0}; | 171 | * // This returns Result{ErrorModule::Common, 0}; |
| 172 | * return ResultCommonError; | 172 | * return ResultCommonError; |
| 173 | * } | 173 | * } |
| 174 | * | 174 | * |
| @@ -181,22 +181,22 @@ public: | |||
| 181 | consteval ResultRange(ErrorModule module, u32 description_start, u32 description_end_) | 181 | consteval ResultRange(ErrorModule module, u32 description_start, u32 description_end_) |
| 182 | : code{module, description_start}, description_end{description_end_} {} | 182 | : code{module, description_start}, description_end{description_end_} {} |
| 183 | 183 | ||
| 184 | [[nodiscard]] constexpr operator ResultCode() const { | 184 | [[nodiscard]] constexpr operator Result() const { |
| 185 | return code; | 185 | return code; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | [[nodiscard]] constexpr bool Includes(ResultCode other) const { | 188 | [[nodiscard]] constexpr bool Includes(Result other) const { |
| 189 | return code.module == other.module && code.description <= other.description && | 189 | return code.module == other.module && code.description <= other.description && |
| 190 | other.description <= description_end; | 190 | other.description <= description_end; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | private: | 193 | private: |
| 194 | ResultCode code; | 194 | Result code; |
| 195 | u32 description_end; | 195 | u32 description_end; |
| 196 | }; | 196 | }; |
| 197 | 197 | ||
| 198 | /** | 198 | /** |
| 199 | * This is an optional value type. It holds a `ResultCode` and, if that code is ResultSuccess, it | 199 | * This is an optional value type. It holds a `Result` and, if that code is ResultSuccess, it |
| 200 | * also holds a result of type `T`. If the code is an error code (not ResultSuccess), then trying | 200 | * also holds a result of type `T`. If the code is an error code (not ResultSuccess), then trying |
| 201 | * to access the inner value with operator* is undefined behavior and will assert with Unwrap(). | 201 | * to access the inner value with operator* is undefined behavior and will assert with Unwrap(). |
| 202 | * Users of this class must be cognizant to check the status of the ResultVal with operator bool(), | 202 | * Users of this class must be cognizant to check the status of the ResultVal with operator bool(), |
| @@ -207,7 +207,7 @@ private: | |||
| 207 | * ResultVal<int> Frobnicate(float strength) { | 207 | * ResultVal<int> Frobnicate(float strength) { |
| 208 | * if (strength < 0.f || strength > 1.0f) { | 208 | * if (strength < 0.f || strength > 1.0f) { |
| 209 | * // Can't frobnicate too weakly or too strongly | 209 | * // Can't frobnicate too weakly or too strongly |
| 210 | * return ResultCode{ErrorModule::Common, 1}; | 210 | * return Result{ErrorModule::Common, 1}; |
| 211 | * } else { | 211 | * } else { |
| 212 | * // Frobnicated! Give caller a cookie | 212 | * // Frobnicated! Give caller a cookie |
| 213 | * return 42; | 213 | * return 42; |
| @@ -230,7 +230,7 @@ class ResultVal { | |||
| 230 | public: | 230 | public: |
| 231 | constexpr ResultVal() : expected{} {} | 231 | constexpr ResultVal() : expected{} {} |
| 232 | 232 | ||
| 233 | constexpr ResultVal(ResultCode code) : expected{Common::Unexpected(code)} {} | 233 | constexpr ResultVal(Result code) : expected{Common::Unexpected(code)} {} |
| 234 | 234 | ||
| 235 | constexpr ResultVal(ResultRange range) : expected{Common::Unexpected(range)} {} | 235 | constexpr ResultVal(ResultRange range) : expected{Common::Unexpected(range)} {} |
| 236 | 236 | ||
| @@ -252,7 +252,7 @@ public: | |||
| 252 | return expected.has_value(); | 252 | return expected.has_value(); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | [[nodiscard]] constexpr ResultCode Code() const { | 255 | [[nodiscard]] constexpr Result Code() const { |
| 256 | return expected.has_value() ? ResultSuccess : expected.error(); | 256 | return expected.has_value() ? ResultSuccess : expected.error(); |
| 257 | } | 257 | } |
| 258 | 258 | ||
| @@ -320,7 +320,7 @@ public: | |||
| 320 | 320 | ||
| 321 | private: | 321 | private: |
| 322 | // TODO (Morph): Replace this with C++23 std::expected. | 322 | // TODO (Morph): Replace this with C++23 std::expected. |
| 323 | Common::Expected<T, ResultCode> expected; | 323 | Common::Expected<T, Result> expected; |
| 324 | }; | 324 | }; |
| 325 | 325 | ||
| 326 | /** | 326 | /** |
| @@ -337,7 +337,7 @@ private: | |||
| 337 | target = std::move(*CONCAT2(check_result_L, __LINE__)) | 337 | target = std::move(*CONCAT2(check_result_L, __LINE__)) |
| 338 | 338 | ||
| 339 | /** | 339 | /** |
| 340 | * Analogous to CASCADE_RESULT, but for a bare ResultCode. The code will be propagated if | 340 | * Analogous to CASCADE_RESULT, but for a bare Result. The code will be propagated if |
| 341 | * non-success, or discarded otherwise. | 341 | * non-success, or discarded otherwise. |
| 342 | */ | 342 | */ |
| 343 | #define CASCADE_CODE(source) \ | 343 | #define CASCADE_CODE(source) \ |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 88b74cbb0..b726ac27a 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -28,11 +28,11 @@ | |||
| 28 | 28 | ||
| 29 | namespace Service::Account { | 29 | namespace Service::Account { |
| 30 | 30 | ||
| 31 | constexpr ResultCode ERR_INVALID_USER_ID{ErrorModule::Account, 20}; | 31 | constexpr Result ERR_INVALID_USER_ID{ErrorModule::Account, 20}; |
| 32 | constexpr ResultCode ERR_INVALID_APPLICATION_ID{ErrorModule::Account, 22}; | 32 | constexpr Result ERR_INVALID_APPLICATION_ID{ErrorModule::Account, 22}; |
| 33 | constexpr ResultCode ERR_INVALID_BUFFER{ErrorModule::Account, 30}; | 33 | constexpr Result ERR_INVALID_BUFFER{ErrorModule::Account, 30}; |
| 34 | constexpr ResultCode ERR_INVALID_BUFFER_SIZE{ErrorModule::Account, 31}; | 34 | constexpr Result ERR_INVALID_BUFFER_SIZE{ErrorModule::Account, 31}; |
| 35 | constexpr ResultCode ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100}; | 35 | constexpr Result ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100}; |
| 36 | 36 | ||
| 37 | // Thumbnails are hard coded to be at least this size | 37 | // Thumbnails are hard coded to be at least this size |
| 38 | constexpr std::size_t THUMBNAIL_SIZE = 0x24000; | 38 | constexpr std::size_t THUMBNAIL_SIZE = 0x24000; |
| @@ -505,7 +505,7 @@ protected: | |||
| 505 | 505 | ||
| 506 | void Cancel() override {} | 506 | void Cancel() override {} |
| 507 | 507 | ||
| 508 | ResultCode GetResult() const override { | 508 | Result GetResult() const override { |
| 509 | return ResultSuccess; | 509 | return ResultSuccess; |
| 510 | } | 510 | } |
| 511 | }; | 511 | }; |
| @@ -747,7 +747,7 @@ void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestCo | |||
| 747 | rb.Push(InitializeApplicationInfoBase()); | 747 | rb.Push(InitializeApplicationInfoBase()); |
| 748 | } | 748 | } |
| 749 | 749 | ||
| 750 | ResultCode Module::Interface::InitializeApplicationInfoBase() { | 750 | Result Module::Interface::InitializeApplicationInfoBase() { |
| 751 | if (application_info) { | 751 | if (application_info) { |
| 752 | LOG_ERROR(Service_ACC, "Application already initialized"); | 752 | LOG_ERROR(Service_ACC, "Application already initialized"); |
| 753 | return ERR_ACCOUNTINFO_ALREADY_INITIALIZED; | 753 | return ERR_ACCOUNTINFO_ALREADY_INITIALIZED; |
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index fff447fc3..1621e7c0a 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h | |||
| @@ -41,7 +41,7 @@ public: | |||
| 41 | void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx); | 41 | void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx); |
| 42 | 42 | ||
| 43 | private: | 43 | private: |
| 44 | ResultCode InitializeApplicationInfoBase(); | 44 | Result InitializeApplicationInfoBase(); |
| 45 | void StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx, const Common::UUID& uuid, | 45 | void StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx, const Common::UUID& uuid, |
| 46 | const u64 tid); | 46 | const u64 tid); |
| 47 | 47 | ||
diff --git a/src/core/hle/service/acc/async_context.h b/src/core/hle/service/acc/async_context.h index e4929f7f0..26332d241 100644 --- a/src/core/hle/service/acc/async_context.h +++ b/src/core/hle/service/acc/async_context.h | |||
| @@ -26,7 +26,7 @@ public: | |||
| 26 | protected: | 26 | protected: |
| 27 | virtual bool IsComplete() const = 0; | 27 | virtual bool IsComplete() const = 0; |
| 28 | virtual void Cancel() = 0; | 28 | virtual void Cancel() = 0; |
| 29 | virtual ResultCode GetResult() const = 0; | 29 | virtual Result GetResult() const = 0; |
| 30 | 30 | ||
| 31 | void MarkComplete(); | 31 | void MarkComplete(); |
| 32 | 32 | ||
diff --git a/src/core/hle/service/acc/errors.h b/src/core/hle/service/acc/errors.h index eafb75713..e9c16b951 100644 --- a/src/core/hle/service/acc/errors.h +++ b/src/core/hle/service/acc/errors.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Account { | 8 | namespace Service::Account { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERR_ACCOUNTINFO_BAD_APPLICATION{ErrorModule::Account, 22}; | 10 | constexpr Result ERR_ACCOUNTINFO_BAD_APPLICATION{ErrorModule::Account, 22}; |
| 11 | constexpr ResultCode ERR_ACCOUNTINFO_ALREADY_INITIALIZED{ErrorModule::Account, 41}; | 11 | constexpr Result ERR_ACCOUNTINFO_ALREADY_INITIALIZED{ErrorModule::Account, 41}; |
| 12 | 12 | ||
| 13 | } // namespace Service::Account | 13 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 0ef298180..8118ead33 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp | |||
| @@ -33,9 +33,9 @@ struct ProfileDataRaw { | |||
| 33 | static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size."); | 33 | static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size."); |
| 34 | 34 | ||
| 35 | // TODO(ogniK): Get actual error codes | 35 | // TODO(ogniK): Get actual error codes |
| 36 | constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, u32(-1)); | 36 | constexpr Result ERROR_TOO_MANY_USERS(ErrorModule::Account, u32(-1)); |
| 37 | constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, u32(-2)); | 37 | constexpr Result ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, u32(-2)); |
| 38 | constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); | 38 | constexpr Result ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); |
| 39 | 39 | ||
| 40 | constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "system/save/8000000000000010/su/avators"; | 40 | constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "system/save/8000000000000010/su/avators"; |
| 41 | 41 | ||
| @@ -87,7 +87,7 @@ bool ProfileManager::RemoveProfileAtIndex(std::size_t index) { | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /// Helper function to register a user to the system | 89 | /// Helper function to register a user to the system |
| 90 | ResultCode ProfileManager::AddUser(const ProfileInfo& user) { | 90 | Result ProfileManager::AddUser(const ProfileInfo& user) { |
| 91 | if (!AddToProfiles(user)) { | 91 | if (!AddToProfiles(user)) { |
| 92 | return ERROR_TOO_MANY_USERS; | 92 | return ERROR_TOO_MANY_USERS; |
| 93 | } | 93 | } |
| @@ -96,7 +96,7 @@ ResultCode ProfileManager::AddUser(const ProfileInfo& user) { | |||
| 96 | 96 | ||
| 97 | /// Create a new user on the system. If the uuid of the user already exists, the user is not | 97 | /// Create a new user on the system. If the uuid of the user already exists, the user is not |
| 98 | /// created. | 98 | /// created. |
| 99 | ResultCode ProfileManager::CreateNewUser(UUID uuid, const ProfileUsername& username) { | 99 | Result ProfileManager::CreateNewUser(UUID uuid, const ProfileUsername& username) { |
| 100 | if (user_count == MAX_USERS) { | 100 | if (user_count == MAX_USERS) { |
| 101 | return ERROR_TOO_MANY_USERS; | 101 | return ERROR_TOO_MANY_USERS; |
| 102 | } | 102 | } |
| @@ -123,7 +123,7 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, const ProfileUsername& usern | |||
| 123 | /// Creates a new user on the system. This function allows a much simpler method of registration | 123 | /// Creates a new user on the system. This function allows a much simpler method of registration |
| 124 | /// specifically by allowing an std::string for the username. This is required specifically since | 124 | /// specifically by allowing an std::string for the username. This is required specifically since |
| 125 | /// we're loading a string straight from the config | 125 | /// we're loading a string straight from the config |
| 126 | ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { | 126 | Result ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { |
| 127 | ProfileUsername username_output{}; | 127 | ProfileUsername username_output{}; |
| 128 | 128 | ||
| 129 | if (username.size() > username_output.size()) { | 129 | if (username.size() > username_output.size()) { |
diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 955dbd3d6..9940957f1 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h | |||
| @@ -64,9 +64,9 @@ public: | |||
| 64 | ProfileManager(); | 64 | ProfileManager(); |
| 65 | ~ProfileManager(); | 65 | ~ProfileManager(); |
| 66 | 66 | ||
| 67 | ResultCode AddUser(const ProfileInfo& user); | 67 | Result AddUser(const ProfileInfo& user); |
| 68 | ResultCode CreateNewUser(Common::UUID uuid, const ProfileUsername& username); | 68 | Result CreateNewUser(Common::UUID uuid, const ProfileUsername& username); |
| 69 | ResultCode CreateNewUser(Common::UUID uuid, const std::string& username); | 69 | Result CreateNewUser(Common::UUID uuid, const std::string& username); |
| 70 | std::optional<Common::UUID> GetUser(std::size_t index) const; | 70 | std::optional<Common::UUID> GetUser(std::size_t index) const; |
| 71 | std::optional<std::size_t> GetUserIndex(const Common::UUID& uuid) const; | 71 | std::optional<std::size_t> GetUserIndex(const Common::UUID& uuid) const; |
| 72 | std::optional<std::size_t> GetUserIndex(const ProfileInfo& user) const; | 72 | std::optional<std::size_t> GetUserIndex(const ProfileInfo& user) const; |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 4657bdabc..d35644e73 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -40,9 +40,9 @@ | |||
| 40 | 40 | ||
| 41 | namespace Service::AM { | 41 | namespace Service::AM { |
| 42 | 42 | ||
| 43 | constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 2}; | 43 | constexpr Result ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 2}; |
| 44 | constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 3}; | 44 | constexpr Result ERR_NO_MESSAGES{ErrorModule::AM, 3}; |
| 45 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 503}; | 45 | constexpr Result ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 503}; |
| 46 | 46 | ||
| 47 | enum class LaunchParameterKind : u32 { | 47 | enum class LaunchParameterKind : u32 { |
| 48 | ApplicationSpecific = 1, | 48 | ApplicationSpecific = 1, |
| @@ -365,7 +365,7 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) { | |||
| 365 | // Entry and exit of fatal sections must be balanced. | 365 | // Entry and exit of fatal sections must be balanced. |
| 366 | if (num_fatal_sections_entered == 0) { | 366 | if (num_fatal_sections_entered == 0) { |
| 367 | IPC::ResponseBuilder rb{ctx, 2}; | 367 | IPC::ResponseBuilder rb{ctx, 2}; |
| 368 | rb.Push(ResultCode{ErrorModule::AM, 512}); | 368 | rb.Push(Result{ErrorModule::AM, 512}); |
| 369 | return; | 369 | return; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| @@ -686,7 +686,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, | |||
| 686 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, | 686 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, |
| 687 | {67, nullptr, "CancelCpuBoostMode"}, | 687 | {67, nullptr, "CancelCpuBoostMode"}, |
| 688 | {68, nullptr, "GetBuiltInDisplayType"}, | 688 | {68, nullptr, "GetBuiltInDisplayType"}, |
| 689 | {80, nullptr, "PerformSystemButtonPressingIfInFocus"}, | 689 | {80, &ICommonStateGetter::PerformSystemButtonPressingIfInFocus, "PerformSystemButtonPressingIfInFocus"}, |
| 690 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, | 690 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, |
| 691 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, | 691 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, |
| 692 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, | 692 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, |
| @@ -826,6 +826,16 @@ void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) { | |||
| 826 | apm_sys->SetCpuBoostMode(ctx); | 826 | apm_sys->SetCpuBoostMode(ctx); |
| 827 | } | 827 | } |
| 828 | 828 | ||
| 829 | void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(Kernel::HLERequestContext& ctx) { | ||
| 830 | IPC::RequestParser rp{ctx}; | ||
| 831 | const auto system_button{rp.PopEnum<SystemButtonType>()}; | ||
| 832 | |||
| 833 | LOG_WARNING(Service_AM, "(STUBBED) called, system_button={}", system_button); | ||
| 834 | |||
| 835 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 836 | rb.Push(ResultSuccess); | ||
| 837 | } | ||
| 838 | |||
| 829 | void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( | 839 | void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( |
| 830 | Kernel::HLERequestContext& ctx) { | 840 | Kernel::HLERequestContext& ctx) { |
| 831 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 841 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 06f13aa09..988ead215 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -220,6 +220,18 @@ private: | |||
| 220 | Docked = 1, | 220 | Docked = 1, |
| 221 | }; | 221 | }; |
| 222 | 222 | ||
| 223 | // This is nn::am::service::SystemButtonType | ||
| 224 | enum class SystemButtonType { | ||
| 225 | None, | ||
| 226 | HomeButtonShortPressing, | ||
| 227 | HomeButtonLongPressing, | ||
| 228 | PowerButtonShortPressing, | ||
| 229 | PowerButtonLongPressing, | ||
| 230 | ShutdownSystem, | ||
| 231 | CaptureButtonShortPressing, | ||
| 232 | CaptureButtonLongPressing, | ||
| 233 | }; | ||
| 234 | |||
| 223 | void GetEventHandle(Kernel::HLERequestContext& ctx); | 235 | void GetEventHandle(Kernel::HLERequestContext& ctx); |
| 224 | void ReceiveMessage(Kernel::HLERequestContext& ctx); | 236 | void ReceiveMessage(Kernel::HLERequestContext& ctx); |
| 225 | void GetCurrentFocusState(Kernel::HLERequestContext& ctx); | 237 | void GetCurrentFocusState(Kernel::HLERequestContext& ctx); |
| @@ -234,6 +246,7 @@ private: | |||
| 234 | void EndVrModeEx(Kernel::HLERequestContext& ctx); | 246 | void EndVrModeEx(Kernel::HLERequestContext& ctx); |
| 235 | void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); | 247 | void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); |
| 236 | void SetCpuBoostMode(Kernel::HLERequestContext& ctx); | 248 | void SetCpuBoostMode(Kernel::HLERequestContext& ctx); |
| 249 | void PerformSystemButtonPressingIfInFocus(Kernel::HLERequestContext& ctx); | ||
| 237 | void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(Kernel::HLERequestContext& ctx); | 250 | void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(Kernel::HLERequestContext& ctx); |
| 238 | 251 | ||
| 239 | std::shared_ptr<AppletMessageQueue> msg_queue; | 252 | std::shared_ptr<AppletMessageQueue> msg_queue; |
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp index 655f2e936..b418031de 100644 --- a/src/core/hle/service/am/applets/applet_controller.cpp +++ b/src/core/hle/service/am/applets/applet_controller.cpp | |||
| @@ -20,9 +20,9 @@ | |||
| 20 | namespace Service::AM::Applets { | 20 | namespace Service::AM::Applets { |
| 21 | 21 | ||
| 22 | // This error code (0x183ACA) is thrown when the applet fails to initialize. | 22 | // This error code (0x183ACA) is thrown when the applet fails to initialize. |
| 23 | [[maybe_unused]] constexpr ResultCode ERR_CONTROLLER_APPLET_3101{ErrorModule::HID, 3101}; | 23 | [[maybe_unused]] constexpr Result ERR_CONTROLLER_APPLET_3101{ErrorModule::HID, 3101}; |
| 24 | // This error code (0x183CCA) is thrown when the u32 result in ControllerSupportResultInfo is 2. | 24 | // This error code (0x183CCA) is thrown when the u32 result in ControllerSupportResultInfo is 2. |
| 25 | [[maybe_unused]] constexpr ResultCode ERR_CONTROLLER_APPLET_3102{ErrorModule::HID, 3102}; | 25 | [[maybe_unused]] constexpr Result ERR_CONTROLLER_APPLET_3102{ErrorModule::HID, 3102}; |
| 26 | 26 | ||
| 27 | static Core::Frontend::ControllerParameters ConvertToFrontendParameters( | 27 | static Core::Frontend::ControllerParameters ConvertToFrontendParameters( |
| 28 | ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text, | 28 | ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text, |
| @@ -173,12 +173,12 @@ bool Controller::TransactionComplete() const { | |||
| 173 | return complete; | 173 | return complete; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | ResultCode Controller::GetStatus() const { | 176 | Result Controller::GetStatus() const { |
| 177 | return status; | 177 | return status; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | void Controller::ExecuteInteractive() { | 180 | void Controller::ExecuteInteractive() { |
| 181 | UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); | 181 | ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | void Controller::Execute() { | 184 | void Controller::Execute() { |
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h index e1a34853d..1f9adec65 100644 --- a/src/core/hle/service/am/applets/applet_controller.h +++ b/src/core/hle/service/am/applets/applet_controller.h | |||
| @@ -126,7 +126,7 @@ public: | |||
| 126 | void Initialize() override; | 126 | void Initialize() override; |
| 127 | 127 | ||
| 128 | bool TransactionComplete() const override; | 128 | bool TransactionComplete() const override; |
| 129 | ResultCode GetStatus() const override; | 129 | Result GetStatus() const override; |
| 130 | void ExecuteInteractive() override; | 130 | void ExecuteInteractive() override; |
| 131 | void Execute() override; | 131 | void Execute() override; |
| 132 | 132 | ||
| @@ -143,7 +143,7 @@ private: | |||
| 143 | ControllerUpdateFirmwareArg controller_update_arg; | 143 | ControllerUpdateFirmwareArg controller_update_arg; |
| 144 | ControllerKeyRemappingArg controller_key_remapping_arg; | 144 | ControllerKeyRemappingArg controller_key_remapping_arg; |
| 145 | bool complete{false}; | 145 | bool complete{false}; |
| 146 | ResultCode status{ResultSuccess}; | 146 | Result status{ResultSuccess}; |
| 147 | bool is_single_mode{false}; | 147 | bool is_single_mode{false}; |
| 148 | std::vector<u8> out_data; | 148 | std::vector<u8> out_data; |
| 149 | }; | 149 | }; |
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp index 911b2c229..fcf34bf7e 100644 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ b/src/core/hle/service/am/applets/applet_error.cpp | |||
| @@ -25,15 +25,15 @@ struct ErrorCode { | |||
| 25 | }; | 25 | }; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | static constexpr ErrorCode FromResultCode(ResultCode result) { | 28 | static constexpr ErrorCode FromResult(Result result) { |
| 29 | return { | 29 | return { |
| 30 | .error_category{2000 + static_cast<u32>(result.module.Value())}, | 30 | .error_category{2000 + static_cast<u32>(result.module.Value())}, |
| 31 | .error_number{result.description.Value()}, | 31 | .error_number{result.description.Value()}, |
| 32 | }; | 32 | }; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | constexpr ResultCode ToResultCode() const { | 35 | constexpr Result ToResult() const { |
| 36 | return ResultCode{static_cast<ErrorModule>(error_category - 2000), error_number}; | 36 | return Result{static_cast<ErrorModule>(error_category - 2000), error_number}; |
| 37 | } | 37 | } |
| 38 | }; | 38 | }; |
| 39 | static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size."); | 39 | static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size."); |
| @@ -97,8 +97,8 @@ void CopyArgumentData(const std::vector<u8>& data, T& variable) { | |||
| 97 | std::memcpy(&variable, data.data(), sizeof(T)); | 97 | std::memcpy(&variable, data.data(), sizeof(T)); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | ResultCode Decode64BitError(u64 error) { | 100 | Result Decode64BitError(u64 error) { |
| 101 | return ErrorCode::FromU64(error).ToResultCode(); | 101 | return ErrorCode::FromU64(error).ToResult(); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | } // Anonymous namespace | 104 | } // Anonymous namespace |
| @@ -127,16 +127,16 @@ void Error::Initialize() { | |||
| 127 | if (args->error.use_64bit_error_code) { | 127 | if (args->error.use_64bit_error_code) { |
| 128 | error_code = Decode64BitError(args->error.error_code_64); | 128 | error_code = Decode64BitError(args->error.error_code_64); |
| 129 | } else { | 129 | } else { |
| 130 | error_code = ResultCode(args->error.error_code_32); | 130 | error_code = Result(args->error.error_code_32); |
| 131 | } | 131 | } |
| 132 | break; | 132 | break; |
| 133 | case ErrorAppletMode::ShowSystemError: | 133 | case ErrorAppletMode::ShowSystemError: |
| 134 | CopyArgumentData(data, args->system_error); | 134 | CopyArgumentData(data, args->system_error); |
| 135 | error_code = ResultCode(Decode64BitError(args->system_error.error_code_64)); | 135 | error_code = Result(Decode64BitError(args->system_error.error_code_64)); |
| 136 | break; | 136 | break; |
| 137 | case ErrorAppletMode::ShowApplicationError: | 137 | case ErrorAppletMode::ShowApplicationError: |
| 138 | CopyArgumentData(data, args->application_error); | 138 | CopyArgumentData(data, args->application_error); |
| 139 | error_code = ResultCode(args->application_error.error_code); | 139 | error_code = Result(args->application_error.error_code); |
| 140 | break; | 140 | break; |
| 141 | case ErrorAppletMode::ShowErrorRecord: | 141 | case ErrorAppletMode::ShowErrorRecord: |
| 142 | CopyArgumentData(data, args->error_record); | 142 | CopyArgumentData(data, args->error_record); |
| @@ -151,12 +151,12 @@ bool Error::TransactionComplete() const { | |||
| 151 | return complete; | 151 | return complete; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | ResultCode Error::GetStatus() const { | 154 | Result Error::GetStatus() const { |
| 155 | return ResultSuccess; | 155 | return ResultSuccess; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | void Error::ExecuteInteractive() { | 158 | void Error::ExecuteInteractive() { |
| 159 | UNREACHABLE_MSG("Unexpected interactive applet data!"); | 159 | ASSERT_MSG(false, "Unexpected interactive applet data!"); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | void Error::Execute() { | 162 | void Error::Execute() { |
diff --git a/src/core/hle/service/am/applets/applet_error.h b/src/core/hle/service/am/applets/applet_error.h index 43487f647..d78d6f1d1 100644 --- a/src/core/hle/service/am/applets/applet_error.h +++ b/src/core/hle/service/am/applets/applet_error.h | |||
| @@ -31,7 +31,7 @@ public: | |||
| 31 | void Initialize() override; | 31 | void Initialize() override; |
| 32 | 32 | ||
| 33 | bool TransactionComplete() const override; | 33 | bool TransactionComplete() const override; |
| 34 | ResultCode GetStatus() const override; | 34 | Result GetStatus() const override; |
| 35 | void ExecuteInteractive() override; | 35 | void ExecuteInteractive() override; |
| 36 | void Execute() override; | 36 | void Execute() override; |
| 37 | 37 | ||
| @@ -41,7 +41,7 @@ private: | |||
| 41 | union ErrorArguments; | 41 | union ErrorArguments; |
| 42 | 42 | ||
| 43 | const Core::Frontend::ErrorApplet& frontend; | 43 | const Core::Frontend::ErrorApplet& frontend; |
| 44 | ResultCode error_code = ResultSuccess; | 44 | Result error_code = ResultSuccess; |
| 45 | ErrorAppletMode mode = ErrorAppletMode::ShowError; | 45 | ErrorAppletMode mode = ErrorAppletMode::ShowError; |
| 46 | std::unique_ptr<ErrorArguments> args; | 46 | std::unique_ptr<ErrorArguments> args; |
| 47 | 47 | ||
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp index 3fe1a390a..c34ef08b3 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | namespace Service::AM::Applets { | 14 | namespace Service::AM::Applets { |
| 15 | 15 | ||
| 16 | constexpr ResultCode ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; | 16 | constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; |
| 17 | 17 | ||
| 18 | static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { | 18 | static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { |
| 19 | std::shared_ptr<IStorage> storage = broker.PopNormalDataToApplet(); | 19 | std::shared_ptr<IStorage> storage = broker.PopNormalDataToApplet(); |
| @@ -71,12 +71,12 @@ bool Auth::TransactionComplete() const { | |||
| 71 | return complete; | 71 | return complete; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | ResultCode Auth::GetStatus() const { | 74 | Result Auth::GetStatus() const { |
| 75 | return successful ? ResultSuccess : ERROR_INVALID_PIN; | 75 | return successful ? ResultSuccess : ERROR_INVALID_PIN; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | void Auth::ExecuteInteractive() { | 78 | void Auth::ExecuteInteractive() { |
| 79 | UNREACHABLE_MSG("Unexpected interactive applet data."); | 79 | ASSERT_MSG(false, "Unexpected interactive applet data."); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | void Auth::Execute() { | 82 | void Auth::Execute() { |
| @@ -136,7 +136,7 @@ void Auth::AuthFinished(bool is_successful) { | |||
| 136 | successful = is_successful; | 136 | successful = is_successful; |
| 137 | 137 | ||
| 138 | struct Return { | 138 | struct Return { |
| 139 | ResultCode result_code; | 139 | Result result_code; |
| 140 | }; | 140 | }; |
| 141 | static_assert(sizeof(Return) == 0x4, "Return (AuthApplet) has incorrect size."); | 141 | static_assert(sizeof(Return) == 0x4, "Return (AuthApplet) has incorrect size."); |
| 142 | 142 | ||
| @@ -170,12 +170,12 @@ bool PhotoViewer::TransactionComplete() const { | |||
| 170 | return complete; | 170 | return complete; |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | ResultCode PhotoViewer::GetStatus() const { | 173 | Result PhotoViewer::GetStatus() const { |
| 174 | return ResultSuccess; | 174 | return ResultSuccess; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | void PhotoViewer::ExecuteInteractive() { | 177 | void PhotoViewer::ExecuteInteractive() { |
| 178 | UNREACHABLE_MSG("Unexpected interactive applet data."); | 178 | ASSERT_MSG(false, "Unexpected interactive applet data."); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | void PhotoViewer::Execute() { | 181 | void PhotoViewer::Execute() { |
| @@ -223,7 +223,7 @@ bool StubApplet::TransactionComplete() const { | |||
| 223 | return true; | 223 | return true; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | ResultCode StubApplet::GetStatus() const { | 226 | Result StubApplet::GetStatus() const { |
| 227 | LOG_WARNING(Service_AM, "called (STUBBED)"); | 227 | LOG_WARNING(Service_AM, "called (STUBBED)"); |
| 228 | return ResultSuccess; | 228 | return ResultSuccess; |
| 229 | } | 229 | } |
diff --git a/src/core/hle/service/am/applets/applet_general_backend.h b/src/core/hle/service/am/applets/applet_general_backend.h index e647d0f41..a9f2535a2 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.h +++ b/src/core/hle/service/am/applets/applet_general_backend.h | |||
| @@ -25,7 +25,7 @@ public: | |||
| 25 | 25 | ||
| 26 | void Initialize() override; | 26 | void Initialize() override; |
| 27 | bool TransactionComplete() const override; | 27 | bool TransactionComplete() const override; |
| 28 | ResultCode GetStatus() const override; | 28 | Result GetStatus() const override; |
| 29 | void ExecuteInteractive() override; | 29 | void ExecuteInteractive() override; |
| 30 | void Execute() override; | 30 | void Execute() override; |
| 31 | 31 | ||
| @@ -56,7 +56,7 @@ public: | |||
| 56 | 56 | ||
| 57 | void Initialize() override; | 57 | void Initialize() override; |
| 58 | bool TransactionComplete() const override; | 58 | bool TransactionComplete() const override; |
| 59 | ResultCode GetStatus() const override; | 59 | Result GetStatus() const override; |
| 60 | void ExecuteInteractive() override; | 60 | void ExecuteInteractive() override; |
| 61 | void Execute() override; | 61 | void Execute() override; |
| 62 | 62 | ||
| @@ -77,7 +77,7 @@ public: | |||
| 77 | void Initialize() override; | 77 | void Initialize() override; |
| 78 | 78 | ||
| 79 | bool TransactionComplete() const override; | 79 | bool TransactionComplete() const override; |
| 80 | ResultCode GetStatus() const override; | 80 | Result GetStatus() const override; |
| 81 | void ExecuteInteractive() override; | 81 | void ExecuteInteractive() override; |
| 82 | void Execute() override; | 82 | void Execute() override; |
| 83 | 83 | ||
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index 3acde1630..ae80ef506 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp | |||
| @@ -62,12 +62,12 @@ bool MiiEdit::TransactionComplete() const { | |||
| 62 | return is_complete; | 62 | return is_complete; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | ResultCode MiiEdit::GetStatus() const { | 65 | Result MiiEdit::GetStatus() const { |
| 66 | return ResultSuccess; | 66 | return ResultSuccess; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void MiiEdit::ExecuteInteractive() { | 69 | void MiiEdit::ExecuteInteractive() { |
| 70 | UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); | 70 | ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | void MiiEdit::Execute() { | 73 | void MiiEdit::Execute() { |
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h index 900754e57..d18dd3cf5 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ b/src/core/hle/service/am/applets/applet_mii_edit.h | |||
| @@ -22,7 +22,7 @@ public: | |||
| 22 | void Initialize() override; | 22 | void Initialize() override; |
| 23 | 23 | ||
| 24 | bool TransactionComplete() const override; | 24 | bool TransactionComplete() const override; |
| 25 | ResultCode GetStatus() const override; | 25 | Result GetStatus() const override; |
| 26 | void ExecuteInteractive() override; | 26 | void ExecuteInteractive() override; |
| 27 | void Execute() override; | 27 | void Execute() override; |
| 28 | 28 | ||
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp index fd16f2e49..c738db028 100644 --- a/src/core/hle/service/am/applets/applet_profile_select.cpp +++ b/src/core/hle/service/am/applets/applet_profile_select.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::AM::Applets { | 13 | namespace Service::AM::Applets { |
| 14 | 14 | ||
| 15 | constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; | 15 | constexpr Result ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; |
| 16 | 16 | ||
| 17 | ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, | 17 | ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, |
| 18 | const Core::Frontend::ProfileSelectApplet& frontend_) | 18 | const Core::Frontend::ProfileSelectApplet& frontend_) |
| @@ -39,12 +39,12 @@ bool ProfileSelect::TransactionComplete() const { | |||
| 39 | return complete; | 39 | return complete; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | ResultCode ProfileSelect::GetStatus() const { | 42 | Result ProfileSelect::GetStatus() const { |
| 43 | return status; | 43 | return status; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void ProfileSelect::ExecuteInteractive() { | 46 | void ProfileSelect::ExecuteInteractive() { |
| 47 | UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet."); | 47 | ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | void ProfileSelect::Execute() { | 50 | void ProfileSelect::Execute() { |
diff --git a/src/core/hle/service/am/applets/applet_profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h index 3a6e50eaa..b77f1d205 100644 --- a/src/core/hle/service/am/applets/applet_profile_select.h +++ b/src/core/hle/service/am/applets/applet_profile_select.h | |||
| @@ -39,7 +39,7 @@ public: | |||
| 39 | void Initialize() override; | 39 | void Initialize() override; |
| 40 | 40 | ||
| 41 | bool TransactionComplete() const override; | 41 | bool TransactionComplete() const override; |
| 42 | ResultCode GetStatus() const override; | 42 | Result GetStatus() const override; |
| 43 | void ExecuteInteractive() override; | 43 | void ExecuteInteractive() override; |
| 44 | void Execute() override; | 44 | void Execute() override; |
| 45 | 45 | ||
| @@ -50,7 +50,7 @@ private: | |||
| 50 | 50 | ||
| 51 | UserSelectionConfig config; | 51 | UserSelectionConfig config; |
| 52 | bool complete = false; | 52 | bool complete = false; |
| 53 | ResultCode status = ResultSuccess; | 53 | Result status = ResultSuccess; |
| 54 | std::vector<u8> final_data; | 54 | std::vector<u8> final_data; |
| 55 | Core::System& system; | 55 | Core::System& system; |
| 56 | }; | 56 | }; |
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp index 7c21365e4..faa092957 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp | |||
| @@ -71,7 +71,7 @@ void SoftwareKeyboard::Initialize() { | |||
| 71 | InitializeBackground(applet_mode); | 71 | InitializeBackground(applet_mode); |
| 72 | break; | 72 | break; |
| 73 | default: | 73 | default: |
| 74 | UNREACHABLE_MSG("Invalid LibraryAppletMode={}", applet_mode); | 74 | ASSERT_MSG(false, "Invalid LibraryAppletMode={}", applet_mode); |
| 75 | break; | 75 | break; |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| @@ -80,7 +80,7 @@ bool SoftwareKeyboard::TransactionComplete() const { | |||
| 80 | return complete; | 80 | return complete; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | ResultCode SoftwareKeyboard::GetStatus() const { | 83 | Result SoftwareKeyboard::GetStatus() const { |
| 84 | return status; | 84 | return status; |
| 85 | } | 85 | } |
| 86 | 86 | ||
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.h b/src/core/hle/service/am/applets/applet_software_keyboard.h index c36806a72..b01b31c98 100644 --- a/src/core/hle/service/am/applets/applet_software_keyboard.h +++ b/src/core/hle/service/am/applets/applet_software_keyboard.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 28 | void Initialize() override; | 28 | void Initialize() override; |
| 29 | 29 | ||
| 30 | bool TransactionComplete() const override; | 30 | bool TransactionComplete() const override; |
| 31 | ResultCode GetStatus() const override; | 31 | Result GetStatus() const override; |
| 32 | void ExecuteInteractive() override; | 32 | void ExecuteInteractive() override; |
| 33 | void Execute() override; | 33 | void Execute() override; |
| 34 | 34 | ||
| @@ -180,7 +180,7 @@ private: | |||
| 180 | bool is_background{false}; | 180 | bool is_background{false}; |
| 181 | 181 | ||
| 182 | bool complete{false}; | 182 | bool complete{false}; |
| 183 | ResultCode status{ResultSuccess}; | 183 | Result status{ResultSuccess}; |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | } // namespace Service::AM::Applets | 186 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp index 2aa4a00ad..4b804b78c 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ b/src/core/hle/service/am/applets/applet_web_browser.cpp | |||
| @@ -279,7 +279,7 @@ void WebBrowser::Initialize() { | |||
| 279 | InitializeLobby(); | 279 | InitializeLobby(); |
| 280 | break; | 280 | break; |
| 281 | default: | 281 | default: |
| 282 | UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind); | 282 | ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind); |
| 283 | break; | 283 | break; |
| 284 | } | 284 | } |
| 285 | } | 285 | } |
| @@ -288,7 +288,7 @@ bool WebBrowser::TransactionComplete() const { | |||
| 288 | return complete; | 288 | return complete; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | ResultCode WebBrowser::GetStatus() const { | 291 | Result WebBrowser::GetStatus() const { |
| 292 | return status; | 292 | return status; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| @@ -320,7 +320,7 @@ void WebBrowser::Execute() { | |||
| 320 | ExecuteLobby(); | 320 | ExecuteLobby(); |
| 321 | break; | 321 | break; |
| 322 | default: | 322 | default: |
| 323 | UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind); | 323 | ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind); |
| 324 | WebBrowserExit(WebExitReason::EndButtonPressed); | 324 | WebBrowserExit(WebExitReason::EndButtonPressed); |
| 325 | break; | 325 | break; |
| 326 | } | 326 | } |
diff --git a/src/core/hle/service/am/applets/applet_web_browser.h b/src/core/hle/service/am/applets/applet_web_browser.h index 6b602769b..fd727fac8 100644 --- a/src/core/hle/service/am/applets/applet_web_browser.h +++ b/src/core/hle/service/am/applets/applet_web_browser.h | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | void Initialize() override; | 32 | void Initialize() override; |
| 33 | 33 | ||
| 34 | bool TransactionComplete() const override; | 34 | bool TransactionComplete() const override; |
| 35 | ResultCode GetStatus() const override; | 35 | Result GetStatus() const override; |
| 36 | void ExecuteInteractive() override; | 36 | void ExecuteInteractive() override; |
| 37 | void Execute() override; | 37 | void Execute() override; |
| 38 | 38 | ||
| @@ -66,7 +66,7 @@ private: | |||
| 66 | const Core::Frontend::WebBrowserApplet& frontend; | 66 | const Core::Frontend::WebBrowserApplet& frontend; |
| 67 | 67 | ||
| 68 | bool complete{false}; | 68 | bool complete{false}; |
| 69 | ResultCode status{ResultSuccess}; | 69 | Result status{ResultSuccess}; |
| 70 | 70 | ||
| 71 | WebAppletVersion web_applet_version{}; | 71 | WebAppletVersion web_applet_version{}; |
| 72 | WebArgHeader web_arg_header{}; | 72 | WebArgHeader web_arg_header{}; |
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 2861fed0e..e78a57657 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "common/swap.h" | 9 | #include "common/swap.h" |
| 10 | #include "core/hle/service/kernel_helpers.h" | 10 | #include "core/hle/service/kernel_helpers.h" |
| 11 | 11 | ||
| 12 | union ResultCode; | 12 | union Result; |
| 13 | 13 | ||
| 14 | namespace Core { | 14 | namespace Core { |
| 15 | class System; | 15 | class System; |
| @@ -138,7 +138,7 @@ public: | |||
| 138 | virtual void Initialize(); | 138 | virtual void Initialize(); |
| 139 | 139 | ||
| 140 | virtual bool TransactionComplete() const = 0; | 140 | virtual bool TransactionComplete() const = 0; |
| 141 | virtual ResultCode GetStatus() const = 0; | 141 | virtual Result GetStatus() const = 0; |
| 142 | virtual void ExecuteInteractive() = 0; | 142 | virtual void ExecuteInteractive() = 0; |
| 143 | virtual void Execute() = 0; | 143 | virtual void Execute() = 0; |
| 144 | 144 | ||
diff --git a/src/core/hle/service/audio/errors.h b/src/core/hle/service/audio/errors.h index 542fec899..ac6c514af 100644 --- a/src/core/hle/service/audio/errors.h +++ b/src/core/hle/service/audio/errors.h | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Audio { | 8 | namespace Service::Audio { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::Audio, 2}; | 10 | constexpr Result ERR_OPERATION_FAILED{ErrorModule::Audio, 2}; |
| 11 | constexpr ResultCode ERR_BUFFER_COUNT_EXCEEDED{ErrorModule::Audio, 8}; | 11 | constexpr Result ERR_BUFFER_COUNT_EXCEEDED{ErrorModule::Audio, 8}; |
| 12 | constexpr ResultCode ERR_NOT_SUPPORTED{ErrorModule::Audio, 513}; | 12 | constexpr Result ERR_NOT_SUPPORTED{ErrorModule::Audio, 513}; |
| 13 | 13 | ||
| 14 | } // namespace Service::Audio | 14 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index 7e6d16230..cd0b405ff 100644 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp | |||
| @@ -74,7 +74,7 @@ void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) { | |||
| 74 | SignalUpdate(); | 74 | SignalUpdate(); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | void ProgressServiceBackend::FinishDownload(ResultCode result) { | 77 | void ProgressServiceBackend::FinishDownload(Result result) { |
| 78 | impl.total_downloaded_bytes = impl.total_bytes; | 78 | impl.total_downloaded_bytes = impl.total_bytes; |
| 79 | impl.status = DeliveryCacheProgressImpl::Status::Done; | 79 | impl.status = DeliveryCacheProgressImpl::Status::Done; |
| 80 | impl.result = result; | 80 | impl.result = result; |
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index 7e8026c75..205ed0702 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h | |||
| @@ -49,7 +49,7 @@ struct DeliveryCacheProgressImpl { | |||
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | Status status; | 51 | Status status; |
| 52 | ResultCode result = ResultSuccess; | 52 | Result result = ResultSuccess; |
| 53 | DirectoryName current_directory; | 53 | DirectoryName current_directory; |
| 54 | FileName current_file; | 54 | FileName current_file; |
| 55 | s64 current_downloaded_bytes; ///< Bytes downloaded on current file. | 55 | s64 current_downloaded_bytes; ///< Bytes downloaded on current file. |
| @@ -90,7 +90,7 @@ public: | |||
| 90 | void CommitDirectory(std::string_view dir_name); | 90 | void CommitDirectory(std::string_view dir_name); |
| 91 | 91 | ||
| 92 | // Notifies the application that the operation completed with result code result. | 92 | // Notifies the application that the operation completed with result code result. |
| 93 | void FinishDownload(ResultCode result); | 93 | void FinishDownload(Result result); |
| 94 | 94 | ||
| 95 | private: | 95 | private: |
| 96 | explicit ProgressServiceBackend(Core::System& system, std::string_view event_name); | 96 | explicit ProgressServiceBackend(Core::System& system, std::string_view event_name); |
diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp index 076fd79e7..d928e37fb 100644 --- a/src/core/hle/service/bcat/bcat_module.cpp +++ b/src/core/hle/service/bcat/bcat_module.cpp | |||
| @@ -18,15 +18,15 @@ | |||
| 18 | 18 | ||
| 19 | namespace Service::BCAT { | 19 | namespace Service::BCAT { |
| 20 | 20 | ||
| 21 | constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::BCAT, 1}; | 21 | constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::BCAT, 1}; |
| 22 | constexpr ResultCode ERROR_FAILED_OPEN_ENTITY{ErrorModule::BCAT, 2}; | 22 | constexpr Result ERROR_FAILED_OPEN_ENTITY{ErrorModule::BCAT, 2}; |
| 23 | constexpr ResultCode ERROR_ENTITY_ALREADY_OPEN{ErrorModule::BCAT, 6}; | 23 | constexpr Result ERROR_ENTITY_ALREADY_OPEN{ErrorModule::BCAT, 6}; |
| 24 | constexpr ResultCode ERROR_NO_OPEN_ENTITY{ErrorModule::BCAT, 7}; | 24 | constexpr Result ERROR_NO_OPEN_ENTITY{ErrorModule::BCAT, 7}; |
| 25 | 25 | ||
| 26 | // The command to clear the delivery cache just calls fs IFileSystem DeleteFile on all of the files | 26 | // The command to clear the delivery cache just calls fs IFileSystem DeleteFile on all of the files |
| 27 | // and if any of them have a non-zero result it just forwards that result. This is the FS error code | 27 | // and if any of them have a non-zero result it just forwards that result. This is the FS error code |
| 28 | // for permission denied, which is the closest approximation of this scenario. | 28 | // for permission denied, which is the closest approximation of this scenario. |
| 29 | constexpr ResultCode ERROR_FAILED_CLEAR_CACHE{ErrorModule::FS, 6400}; | 29 | constexpr Result ERROR_FAILED_CLEAR_CACHE{ErrorModule::FS, 6400}; |
| 30 | 30 | ||
| 31 | using BCATDigest = std::array<u8, 0x10>; | 31 | using BCATDigest = std::array<u8, 0x10>; |
| 32 | 32 | ||
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp index cbe9d5f7c..ff9b0427c 100644 --- a/src/core/hle/service/es/es.cpp +++ b/src/core/hle/service/es/es.cpp | |||
| @@ -8,8 +8,8 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::ES { | 9 | namespace Service::ES { |
| 10 | 10 | ||
| 11 | constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::ETicket, 2}; | 11 | constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::ETicket, 2}; |
| 12 | constexpr ResultCode ERROR_INVALID_RIGHTS_ID{ErrorModule::ETicket, 3}; | 12 | constexpr Result ERROR_INVALID_RIGHTS_ID{ErrorModule::ETicket, 3}; |
| 13 | 13 | ||
| 14 | class ETicket final : public ServiceFramework<ETicket> { | 14 | class ETicket final : public ServiceFramework<ETicket> { |
| 15 | public: | 15 | public: |
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index a99c90479..27675615b 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp | |||
| @@ -62,8 +62,7 @@ enum class FatalType : u32 { | |||
| 62 | ErrorScreen = 2, | 62 | ErrorScreen = 2, |
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | static void GenerateErrorReport(Core::System& system, ResultCode error_code, | 65 | static void GenerateErrorReport(Core::System& system, Result error_code, const FatalInfo& info) { |
| 66 | const FatalInfo& info) { | ||
| 67 | const auto title_id = system.GetCurrentProcessProgramID(); | 66 | const auto title_id = system.GetCurrentProcessProgramID(); |
| 68 | std::string crash_report = fmt::format( | 67 | std::string crash_report = fmt::format( |
| 69 | "Yuzu {}-{} crash report\n" | 68 | "Yuzu {}-{} crash report\n" |
| @@ -106,7 +105,7 @@ static void GenerateErrorReport(Core::System& system, ResultCode error_code, | |||
| 106 | info.backtrace_size, info.ArchAsString(), info.unk10); | 105 | info.backtrace_size, info.ArchAsString(), info.unk10); |
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | static void ThrowFatalError(Core::System& system, ResultCode error_code, FatalType fatal_type, | 108 | static void ThrowFatalError(Core::System& system, Result error_code, FatalType fatal_type, |
| 110 | const FatalInfo& info) { | 109 | const FatalInfo& info) { |
| 111 | LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}", fatal_type, | 110 | LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}", fatal_type, |
| 112 | error_code.raw); | 111 | error_code.raw); |
| @@ -129,7 +128,7 @@ static void ThrowFatalError(Core::System& system, ResultCode error_code, FatalTy | |||
| 129 | void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) { | 128 | void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) { |
| 130 | LOG_ERROR(Service_Fatal, "called"); | 129 | LOG_ERROR(Service_Fatal, "called"); |
| 131 | IPC::RequestParser rp{ctx}; | 130 | IPC::RequestParser rp{ctx}; |
| 132 | const auto error_code = rp.Pop<ResultCode>(); | 131 | const auto error_code = rp.Pop<Result>(); |
| 133 | 132 | ||
| 134 | ThrowFatalError(system, error_code, FatalType::ErrorScreen, {}); | 133 | ThrowFatalError(system, error_code, FatalType::ErrorScreen, {}); |
| 135 | IPC::ResponseBuilder rb{ctx, 2}; | 134 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -139,7 +138,7 @@ void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) { | |||
| 139 | void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { | 138 | void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { |
| 140 | LOG_ERROR(Service_Fatal, "called"); | 139 | LOG_ERROR(Service_Fatal, "called"); |
| 141 | IPC::RequestParser rp(ctx); | 140 | IPC::RequestParser rp(ctx); |
| 142 | const auto error_code = rp.Pop<ResultCode>(); | 141 | const auto error_code = rp.Pop<Result>(); |
| 143 | const auto fatal_type = rp.PopEnum<FatalType>(); | 142 | const auto fatal_type = rp.PopEnum<FatalType>(); |
| 144 | 143 | ||
| 145 | ThrowFatalError(system, error_code, fatal_type, | 144 | ThrowFatalError(system, error_code, fatal_type, |
| @@ -151,7 +150,7 @@ void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { | |||
| 151 | void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) { | 150 | void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) { |
| 152 | LOG_ERROR(Service_Fatal, "called"); | 151 | LOG_ERROR(Service_Fatal, "called"); |
| 153 | IPC::RequestParser rp(ctx); | 152 | IPC::RequestParser rp(ctx); |
| 154 | const auto error_code = rp.Pop<ResultCode>(); | 153 | const auto error_code = rp.Pop<Result>(); |
| 155 | const auto fatal_type = rp.PopEnum<FatalType>(); | 154 | const auto fatal_type = rp.PopEnum<FatalType>(); |
| 156 | const auto fatal_info = ctx.ReadBuffer(); | 155 | const auto fatal_info = ctx.ReadBuffer(); |
| 157 | FatalInfo info{}; | 156 | FatalInfo info{}; |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index f8e7519ca..11c604a0f 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -49,7 +49,7 @@ std::string VfsDirectoryServiceWrapper::GetName() const { | |||
| 49 | return backing->GetName(); | 49 | return backing->GetName(); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 size) const { | 52 | Result VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 size) const { |
| 53 | std::string path(Common::FS::SanitizePath(path_)); | 53 | std::string path(Common::FS::SanitizePath(path_)); |
| 54 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path)); | 54 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path)); |
| 55 | if (dir == nullptr) { | 55 | if (dir == nullptr) { |
| @@ -73,7 +73,7 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 | |||
| 73 | return ResultSuccess; | 73 | return ResultSuccess; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const { | 76 | Result VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const { |
| 77 | std::string path(Common::FS::SanitizePath(path_)); | 77 | std::string path(Common::FS::SanitizePath(path_)); |
| 78 | if (path.empty()) { | 78 | if (path.empty()) { |
| 79 | // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but... | 79 | // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but... |
| @@ -92,7 +92,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) cons | |||
| 92 | return ResultSuccess; | 92 | return ResultSuccess; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const { | 95 | Result VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const { |
| 96 | std::string path(Common::FS::SanitizePath(path_)); | 96 | std::string path(Common::FS::SanitizePath(path_)); |
| 97 | 97 | ||
| 98 | // NOTE: This is inaccurate behavior. CreateDirectory is not recursive. | 98 | // NOTE: This is inaccurate behavior. CreateDirectory is not recursive. |
| @@ -116,7 +116,7 @@ ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) | |||
| 116 | return ResultSuccess; | 116 | return ResultSuccess; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) const { | 119 | Result VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) const { |
| 120 | std::string path(Common::FS::SanitizePath(path_)); | 120 | std::string path(Common::FS::SanitizePath(path_)); |
| 121 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path)); | 121 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path)); |
| 122 | if (!dir->DeleteSubdirectory(Common::FS::GetFilename(path))) { | 122 | if (!dir->DeleteSubdirectory(Common::FS::GetFilename(path))) { |
| @@ -126,7 +126,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) | |||
| 126 | return ResultSuccess; | 126 | return ResultSuccess; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path_) const { | 129 | Result VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path_) const { |
| 130 | std::string path(Common::FS::SanitizePath(path_)); | 130 | std::string path(Common::FS::SanitizePath(path_)); |
| 131 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path)); | 131 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path)); |
| 132 | if (!dir->DeleteSubdirectoryRecursive(Common::FS::GetFilename(path))) { | 132 | if (!dir->DeleteSubdirectoryRecursive(Common::FS::GetFilename(path))) { |
| @@ -136,7 +136,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str | |||
| 136 | return ResultSuccess; | 136 | return ResultSuccess; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const { | 139 | Result VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const { |
| 140 | const std::string sanitized_path(Common::FS::SanitizePath(path)); | 140 | const std::string sanitized_path(Common::FS::SanitizePath(path)); |
| 141 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(sanitized_path)); | 141 | auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(sanitized_path)); |
| 142 | 142 | ||
| @@ -148,8 +148,8 @@ ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::stri | |||
| 148 | return ResultSuccess; | 148 | return ResultSuccess; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, | 151 | Result VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, |
| 152 | const std::string& dest_path_) const { | 152 | const std::string& dest_path_) const { |
| 153 | std::string src_path(Common::FS::SanitizePath(src_path_)); | 153 | std::string src_path(Common::FS::SanitizePath(src_path_)); |
| 154 | std::string dest_path(Common::FS::SanitizePath(dest_path_)); | 154 | std::string dest_path(Common::FS::SanitizePath(dest_path_)); |
| 155 | auto src = backing->GetFileRelative(src_path); | 155 | auto src = backing->GetFileRelative(src_path); |
| @@ -183,8 +183,8 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, | |||
| 183 | return ResultSuccess; | 183 | return ResultSuccess; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path_, | 186 | Result VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path_, |
| 187 | const std::string& dest_path_) const { | 187 | const std::string& dest_path_) const { |
| 188 | std::string src_path(Common::FS::SanitizePath(src_path_)); | 188 | std::string src_path(Common::FS::SanitizePath(src_path_)); |
| 189 | std::string dest_path(Common::FS::SanitizePath(dest_path_)); | 189 | std::string dest_path(Common::FS::SanitizePath(dest_path_)); |
| 190 | auto src = GetDirectoryRelativeWrapped(backing, src_path); | 190 | auto src = GetDirectoryRelativeWrapped(backing, src_path); |
| @@ -273,28 +273,27 @@ FileSystemController::FileSystemController(Core::System& system_) : system{syste | |||
| 273 | 273 | ||
| 274 | FileSystemController::~FileSystemController() = default; | 274 | FileSystemController::~FileSystemController() = default; |
| 275 | 275 | ||
| 276 | ResultCode FileSystemController::RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) { | 276 | Result FileSystemController::RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) { |
| 277 | romfs_factory = std::move(factory); | 277 | romfs_factory = std::move(factory); |
| 278 | LOG_DEBUG(Service_FS, "Registered RomFS"); | 278 | LOG_DEBUG(Service_FS, "Registered RomFS"); |
| 279 | return ResultSuccess; | 279 | return ResultSuccess; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | ResultCode FileSystemController::RegisterSaveData( | 282 | Result FileSystemController::RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory) { |
| 283 | std::unique_ptr<FileSys::SaveDataFactory>&& factory) { | ||
| 284 | ASSERT_MSG(save_data_factory == nullptr, "Tried to register a second save data"); | 283 | ASSERT_MSG(save_data_factory == nullptr, "Tried to register a second save data"); |
| 285 | save_data_factory = std::move(factory); | 284 | save_data_factory = std::move(factory); |
| 286 | LOG_DEBUG(Service_FS, "Registered save data"); | 285 | LOG_DEBUG(Service_FS, "Registered save data"); |
| 287 | return ResultSuccess; | 286 | return ResultSuccess; |
| 288 | } | 287 | } |
| 289 | 288 | ||
| 290 | ResultCode FileSystemController::RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) { | 289 | Result FileSystemController::RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) { |
| 291 | ASSERT_MSG(sdmc_factory == nullptr, "Tried to register a second SDMC"); | 290 | ASSERT_MSG(sdmc_factory == nullptr, "Tried to register a second SDMC"); |
| 292 | sdmc_factory = std::move(factory); | 291 | sdmc_factory = std::move(factory); |
| 293 | LOG_DEBUG(Service_FS, "Registered SDMC"); | 292 | LOG_DEBUG(Service_FS, "Registered SDMC"); |
| 294 | return ResultSuccess; | 293 | return ResultSuccess; |
| 295 | } | 294 | } |
| 296 | 295 | ||
| 297 | ResultCode FileSystemController::RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) { | 296 | Result FileSystemController::RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) { |
| 298 | ASSERT_MSG(bis_factory == nullptr, "Tried to register a second BIS"); | 297 | ASSERT_MSG(bis_factory == nullptr, "Tried to register a second BIS"); |
| 299 | bis_factory = std::move(factory); | 298 | bis_factory = std::move(factory); |
| 300 | LOG_DEBUG(Service_FS, "Registered BIS"); | 299 | LOG_DEBUG(Service_FS, "Registered BIS"); |
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 8dd2652fe..5b27de9fa 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -58,10 +58,10 @@ public: | |||
| 58 | explicit FileSystemController(Core::System& system_); | 58 | explicit FileSystemController(Core::System& system_); |
| 59 | ~FileSystemController(); | 59 | ~FileSystemController(); |
| 60 | 60 | ||
| 61 | ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory); | 61 | Result RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory); |
| 62 | ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory); | 62 | Result RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory); |
| 63 | ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory); | 63 | Result RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory); |
| 64 | ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory); | 64 | Result RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory); |
| 65 | 65 | ||
| 66 | void SetPackedUpdate(FileSys::VirtualFile update_raw); | 66 | void SetPackedUpdate(FileSys::VirtualFile update_raw); |
| 67 | ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() const; | 67 | ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() const; |
| @@ -141,7 +141,7 @@ private: | |||
| 141 | 141 | ||
| 142 | void InstallInterfaces(Core::System& system); | 142 | void InstallInterfaces(Core::System& system); |
| 143 | 143 | ||
| 144 | // A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of | 144 | // A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of |
| 145 | // pointers and booleans. This makes using a VfsDirectory with switch services much easier and | 145 | // pointers and booleans. This makes using a VfsDirectory with switch services much easier and |
| 146 | // avoids repetitive code. | 146 | // avoids repetitive code. |
| 147 | class VfsDirectoryServiceWrapper { | 147 | class VfsDirectoryServiceWrapper { |
| @@ -160,35 +160,35 @@ public: | |||
| 160 | * @param size The size of the new file, filled with zeroes | 160 | * @param size The size of the new file, filled with zeroes |
| 161 | * @return Result of the operation | 161 | * @return Result of the operation |
| 162 | */ | 162 | */ |
| 163 | ResultCode CreateFile(const std::string& path, u64 size) const; | 163 | Result CreateFile(const std::string& path, u64 size) const; |
| 164 | 164 | ||
| 165 | /** | 165 | /** |
| 166 | * Delete a file specified by its path | 166 | * Delete a file specified by its path |
| 167 | * @param path Path relative to the archive | 167 | * @param path Path relative to the archive |
| 168 | * @return Result of the operation | 168 | * @return Result of the operation |
| 169 | */ | 169 | */ |
| 170 | ResultCode DeleteFile(const std::string& path) const; | 170 | Result DeleteFile(const std::string& path) const; |
| 171 | 171 | ||
| 172 | /** | 172 | /** |
| 173 | * Create a directory specified by its path | 173 | * Create a directory specified by its path |
| 174 | * @param path Path relative to the archive | 174 | * @param path Path relative to the archive |
| 175 | * @return Result of the operation | 175 | * @return Result of the operation |
| 176 | */ | 176 | */ |
| 177 | ResultCode CreateDirectory(const std::string& path) const; | 177 | Result CreateDirectory(const std::string& path) const; |
| 178 | 178 | ||
| 179 | /** | 179 | /** |
| 180 | * Delete a directory specified by its path | 180 | * Delete a directory specified by its path |
| 181 | * @param path Path relative to the archive | 181 | * @param path Path relative to the archive |
| 182 | * @return Result of the operation | 182 | * @return Result of the operation |
| 183 | */ | 183 | */ |
| 184 | ResultCode DeleteDirectory(const std::string& path) const; | 184 | Result DeleteDirectory(const std::string& path) const; |
| 185 | 185 | ||
| 186 | /** | 186 | /** |
| 187 | * Delete a directory specified by its path and anything under it | 187 | * Delete a directory specified by its path and anything under it |
| 188 | * @param path Path relative to the archive | 188 | * @param path Path relative to the archive |
| 189 | * @return Result of the operation | 189 | * @return Result of the operation |
| 190 | */ | 190 | */ |
| 191 | ResultCode DeleteDirectoryRecursively(const std::string& path) const; | 191 | Result DeleteDirectoryRecursively(const std::string& path) const; |
| 192 | 192 | ||
| 193 | /** | 193 | /** |
| 194 | * Cleans the specified directory. This is similar to DeleteDirectoryRecursively, | 194 | * Cleans the specified directory. This is similar to DeleteDirectoryRecursively, |
| @@ -200,7 +200,7 @@ public: | |||
| 200 | * | 200 | * |
| 201 | * @return Result of the operation. | 201 | * @return Result of the operation. |
| 202 | */ | 202 | */ |
| 203 | ResultCode CleanDirectoryRecursively(const std::string& path) const; | 203 | Result CleanDirectoryRecursively(const std::string& path) const; |
| 204 | 204 | ||
| 205 | /** | 205 | /** |
| 206 | * Rename a File specified by its path | 206 | * Rename a File specified by its path |
| @@ -208,7 +208,7 @@ public: | |||
| 208 | * @param dest_path Destination path relative to the archive | 208 | * @param dest_path Destination path relative to the archive |
| 209 | * @return Result of the operation | 209 | * @return Result of the operation |
| 210 | */ | 210 | */ |
| 211 | ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const; | 211 | Result RenameFile(const std::string& src_path, const std::string& dest_path) const; |
| 212 | 212 | ||
| 213 | /** | 213 | /** |
| 214 | * Rename a Directory specified by its path | 214 | * Rename a Directory specified by its path |
| @@ -216,7 +216,7 @@ public: | |||
| 216 | * @param dest_path Destination path relative to the archive | 216 | * @param dest_path Destination path relative to the archive |
| 217 | * @return Result of the operation | 217 | * @return Result of the operation |
| 218 | */ | 218 | */ |
| 219 | ResultCode RenameDirectory(const std::string& src_path, const std::string& dest_path) const; | 219 | Result RenameDirectory(const std::string& src_path, const std::string& dest_path) const; |
| 220 | 220 | ||
| 221 | /** | 221 | /** |
| 222 | * Open a file specified by its path, using the specified mode | 222 | * Open a file specified by its path, using the specified mode |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index ddfcba0f1..fae6e5aff 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -899,7 +899,7 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) { | |||
| 899 | case FileSys::SaveDataSpaceId::TemporaryStorage: | 899 | case FileSys::SaveDataSpaceId::TemporaryStorage: |
| 900 | case FileSys::SaveDataSpaceId::ProperSystem: | 900 | case FileSys::SaveDataSpaceId::ProperSystem: |
| 901 | case FileSys::SaveDataSpaceId::SafeMode: | 901 | case FileSys::SaveDataSpaceId::SafeMode: |
| 902 | UNREACHABLE(); | 902 | ASSERT(false); |
| 903 | } | 903 | } |
| 904 | 904 | ||
| 905 | auto filesystem = std::make_shared<IFileSystem>(system, std::move(dir.Unwrap()), | 905 | auto filesystem = std::make_shared<IFileSystem>(system, std::move(dir.Unwrap()), |
diff --git a/src/core/hle/service/friend/errors.h b/src/core/hle/service/friend/errors.h index bc9fe0aca..ff525d865 100644 --- a/src/core/hle/service/friend/errors.h +++ b/src/core/hle/service/friend/errors.h | |||
| @@ -7,5 +7,5 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Friend { | 8 | namespace Service::Friend { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERR_NO_NOTIFICATIONS{ErrorModule::Account, 15}; | 10 | constexpr Result ERR_NO_NOTIFICATIONS{ErrorModule::Account, 15}; |
| 11 | } | 11 | } |
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp index fec7787ab..49b6d45fe 100644 --- a/src/core/hle/service/glue/arp.cpp +++ b/src/core/hle/service/glue/arp.cpp | |||
| @@ -153,7 +153,7 @@ class IRegistrar final : public ServiceFramework<IRegistrar> { | |||
| 153 | friend class ARP_W; | 153 | friend class ARP_W; |
| 154 | 154 | ||
| 155 | public: | 155 | public: |
| 156 | using IssuerFn = std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)>; | 156 | using IssuerFn = std::function<Result(u64, ApplicationLaunchProperty, std::vector<u8>)>; |
| 157 | 157 | ||
| 158 | explicit IRegistrar(Core::System& system_, IssuerFn&& issuer) | 158 | explicit IRegistrar(Core::System& system_, IssuerFn&& issuer) |
| 159 | : ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} { | 159 | : ServiceFramework{system_, "IRegistrar"}, issue_process_id{std::move(issuer)} { |
diff --git a/src/core/hle/service/glue/errors.h b/src/core/hle/service/glue/errors.h index aefbe1f3e..d4ce7f44e 100644 --- a/src/core/hle/service/glue/errors.h +++ b/src/core/hle/service/glue/errors.h | |||
| @@ -7,9 +7,9 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Glue { | 8 | namespace Service::Glue { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 30}; | 10 | constexpr Result ERR_INVALID_RESOURCE{ErrorModule::ARP, 30}; |
| 11 | constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 31}; | 11 | constexpr Result ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 31}; |
| 12 | constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 42}; | 12 | constexpr Result ERR_INVALID_ACCESS{ErrorModule::ARP, 42}; |
| 13 | constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 102}; | 13 | constexpr Result ERR_NOT_REGISTERED{ErrorModule::ARP, 102}; |
| 14 | 14 | ||
| 15 | } // namespace Service::Glue | 15 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/glue/glue_manager.cpp b/src/core/hle/service/glue/glue_manager.cpp index f1655b33e..8a654cdca 100644 --- a/src/core/hle/service/glue/glue_manager.cpp +++ b/src/core/hle/service/glue/glue_manager.cpp | |||
| @@ -41,8 +41,8 @@ ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { | |||
| 41 | return iter->second.control; | 41 | return iter->second.control; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, | 44 | Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, |
| 45 | std::vector<u8> control) { | 45 | std::vector<u8> control) { |
| 46 | if (title_id == 0) { | 46 | if (title_id == 0) { |
| 47 | return ERR_INVALID_PROCESS_ID; | 47 | return ERR_INVALID_PROCESS_ID; |
| 48 | } | 48 | } |
| @@ -56,7 +56,7 @@ ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, | |||
| 56 | return ResultSuccess; | 56 | return ResultSuccess; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | ResultCode ARPManager::Unregister(u64 title_id) { | 59 | Result ARPManager::Unregister(u64 title_id) { |
| 60 | if (title_id == 0) { | 60 | if (title_id == 0) { |
| 61 | return ERR_INVALID_PROCESS_ID; | 61 | return ERR_INVALID_PROCESS_ID; |
| 62 | } | 62 | } |
diff --git a/src/core/hle/service/glue/glue_manager.h b/src/core/hle/service/glue/glue_manager.h index 6246fd2ff..cd0b092ac 100644 --- a/src/core/hle/service/glue/glue_manager.h +++ b/src/core/hle/service/glue/glue_manager.h | |||
| @@ -42,12 +42,12 @@ public: | |||
| 42 | // Adds a new entry to the internal database with the provided parameters, returning | 42 | // Adds a new entry to the internal database with the provided parameters, returning |
| 43 | // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister | 43 | // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister |
| 44 | // step, and ERR_INVALID_PROCESS_ID if the title ID is 0. | 44 | // step, and ERR_INVALID_PROCESS_ID if the title ID is 0. |
| 45 | ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); | 45 | Result Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); |
| 46 | 46 | ||
| 47 | // Removes the registration for the provided title ID from the database, returning | 47 | // Removes the registration for the provided title ID from the database, returning |
| 48 | // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the | 48 | // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the |
| 49 | // title ID is 0. | 49 | // title ID is 0. |
| 50 | ResultCode Unregister(u64 title_id); | 50 | Result Unregister(u64 title_id); |
| 51 | 51 | ||
| 52 | // Removes all entries from the database, always succeeds. Should only be used when resetting | 52 | // Removes all entries from the database, always succeeds. Should only be used when resetting |
| 53 | // system state. | 53 | // system state. |
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp index b971846e7..3ace2dabd 100644 --- a/src/core/hle/service/glue/notif.cpp +++ b/src/core/hle/service/glue/notif.cpp | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | ||
| 5 | #include <cstring> | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 4 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 5 | #include "core/hle/service/glue/notif.h" | 10 | #include "core/hle/service/glue/notif.h" |
| 6 | 11 | ||
| @@ -9,11 +14,11 @@ namespace Service::Glue { | |||
| 9 | NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | 14 | NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { |
| 10 | // clang-format off | 15 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 12 | {500, nullptr, "RegisterAlarmSetting"}, | 17 | {500, &NOTIF_A::RegisterAlarmSetting, "RegisterAlarmSetting"}, |
| 13 | {510, nullptr, "UpdateAlarmSetting"}, | 18 | {510, &NOTIF_A::UpdateAlarmSetting, "UpdateAlarmSetting"}, |
| 14 | {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, | 19 | {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, |
| 15 | {530, nullptr, "LoadApplicationParameter"}, | 20 | {530, &NOTIF_A::LoadApplicationParameter, "LoadApplicationParameter"}, |
| 16 | {540, nullptr, "DeleteAlarmSetting"}, | 21 | {540, &NOTIF_A::DeleteAlarmSetting, "DeleteAlarmSetting"}, |
| 17 | {1000, &NOTIF_A::Initialize, "Initialize"}, | 22 | {1000, &NOTIF_A::Initialize, "Initialize"}, |
| 18 | }; | 23 | }; |
| 19 | // clang-format on | 24 | // clang-format on |
| @@ -23,21 +28,132 @@ NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | |||
| 23 | 28 | ||
| 24 | NOTIF_A::~NOTIF_A() = default; | 29 | NOTIF_A::~NOTIF_A() = default; |
| 25 | 30 | ||
| 31 | void NOTIF_A::RegisterAlarmSetting(Kernel::HLERequestContext& ctx) { | ||
| 32 | const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); | ||
| 33 | const auto application_parameter_size = ctx.GetReadBufferSize(1); | ||
| 34 | |||
| 35 | ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), | ||
| 36 | "alarm_setting_buffer_size is not 0x40 bytes"); | ||
| 37 | ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), | ||
| 38 | "application_parameter_size is bigger than 0x400 bytes"); | ||
| 39 | |||
| 40 | AlarmSetting new_alarm{}; | ||
| 41 | memcpy(&new_alarm, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); | ||
| 42 | |||
| 43 | // TODO: Count alarms per game id | ||
| 44 | if (alarms.size() >= max_alarms) { | ||
| 45 | LOG_ERROR(Service_NOTIF, "Alarm limit reached"); | ||
| 46 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 47 | rb.Push(ResultUnknown); | ||
| 48 | return; | ||
| 49 | } | ||
| 50 | |||
| 51 | new_alarm.alarm_setting_id = last_alarm_setting_id++; | ||
| 52 | alarms.push_back(new_alarm); | ||
| 53 | |||
| 54 | // TODO: Save application parameter data | ||
| 55 | |||
| 56 | LOG_WARNING(Service_NOTIF, | ||
| 57 | "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", | ||
| 58 | application_parameter_size, new_alarm.alarm_setting_id, new_alarm.kind, | ||
| 59 | new_alarm.muted); | ||
| 60 | |||
| 61 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 62 | rb.Push(ResultSuccess); | ||
| 63 | rb.Push(new_alarm.alarm_setting_id); | ||
| 64 | } | ||
| 65 | |||
| 66 | void NOTIF_A::UpdateAlarmSetting(Kernel::HLERequestContext& ctx) { | ||
| 67 | const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); | ||
| 68 | const auto application_parameter_size = ctx.GetReadBufferSize(1); | ||
| 69 | |||
| 70 | ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), | ||
| 71 | "alarm_setting_buffer_size is not 0x40 bytes"); | ||
| 72 | ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), | ||
| 73 | "application_parameter_size is bigger than 0x400 bytes"); | ||
| 74 | |||
| 75 | AlarmSetting alarm_setting{}; | ||
| 76 | memcpy(&alarm_setting, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); | ||
| 77 | |||
| 78 | const auto alarm_it = GetAlarmFromId(alarm_setting.alarm_setting_id); | ||
| 79 | if (alarm_it != alarms.end()) { | ||
| 80 | LOG_DEBUG(Service_NOTIF, "Alarm updated"); | ||
| 81 | *alarm_it = alarm_setting; | ||
| 82 | // TODO: Save application parameter data | ||
| 83 | } | ||
| 84 | |||
| 85 | LOG_WARNING(Service_NOTIF, | ||
| 86 | "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", | ||
| 87 | application_parameter_size, alarm_setting.alarm_setting_id, alarm_setting.kind, | ||
| 88 | alarm_setting.muted); | ||
| 89 | |||
| 90 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 91 | rb.Push(ResultSuccess); | ||
| 92 | } | ||
| 93 | |||
| 26 | void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { | 94 | void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { |
| 27 | // Returns an array of AlarmSetting | 95 | LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size()); |
| 28 | constexpr s32 alarm_count = 0; | ||
| 29 | 96 | ||
| 30 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | 97 | // TODO: Only return alarms of this game id |
| 98 | ctx.WriteBuffer(alarms); | ||
| 31 | 99 | ||
| 32 | IPC::ResponseBuilder rb{ctx, 3}; | 100 | IPC::ResponseBuilder rb{ctx, 3}; |
| 33 | rb.Push(ResultSuccess); | 101 | rb.Push(ResultSuccess); |
| 34 | rb.Push(alarm_count); | 102 | rb.Push(static_cast<u32>(alarms.size())); |
| 103 | } | ||
| 104 | |||
| 105 | void NOTIF_A::LoadApplicationParameter(Kernel::HLERequestContext& ctx) { | ||
| 106 | IPC::RequestParser rp{ctx}; | ||
| 107 | const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; | ||
| 108 | |||
| 109 | const auto alarm_it = GetAlarmFromId(alarm_setting_id); | ||
| 110 | if (alarm_it == alarms.end()) { | ||
| 111 | LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id); | ||
| 112 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 113 | rb.Push(ResultUnknown); | ||
| 114 | return; | ||
| 115 | } | ||
| 116 | |||
| 117 | // TODO: Read application parameter related to this setting id | ||
| 118 | ApplicationParameter application_parameter{}; | ||
| 119 | |||
| 120 | LOG_WARNING(Service_NOTIF, "(STUBBED) called, alarm_setting_id={}", alarm_setting_id); | ||
| 121 | |||
| 122 | ctx.WriteBuffer(application_parameter); | ||
| 123 | |||
| 124 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 125 | rb.Push(ResultSuccess); | ||
| 126 | rb.Push(static_cast<u32>(application_parameter.size())); | ||
| 127 | } | ||
| 128 | |||
| 129 | void NOTIF_A::DeleteAlarmSetting(Kernel::HLERequestContext& ctx) { | ||
| 130 | IPC::RequestParser rp{ctx}; | ||
| 131 | const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; | ||
| 132 | |||
| 133 | std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) { | ||
| 134 | return alarm.alarm_setting_id == alarm_setting_id; | ||
| 135 | }); | ||
| 136 | |||
| 137 | LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id); | ||
| 138 | |||
| 139 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 140 | rb.Push(ResultSuccess); | ||
| 35 | } | 141 | } |
| 36 | 142 | ||
| 37 | void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { | 143 | void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { |
| 144 | // TODO: Load previous alarms from config | ||
| 145 | |||
| 38 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | 146 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); |
| 39 | IPC::ResponseBuilder rb{ctx, 2}; | 147 | IPC::ResponseBuilder rb{ctx, 2}; |
| 40 | rb.Push(ResultSuccess); | 148 | rb.Push(ResultSuccess); |
| 41 | } | 149 | } |
| 42 | 150 | ||
| 151 | std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId( | ||
| 152 | AlarmSettingId alarm_setting_id) { | ||
| 153 | return std::find_if(alarms.begin(), alarms.end(), | ||
| 154 | [alarm_setting_id](const AlarmSetting& alarm) { | ||
| 155 | return alarm.alarm_setting_id == alarm_setting_id; | ||
| 156 | }); | ||
| 157 | } | ||
| 158 | |||
| 43 | } // namespace Service::Glue | 159 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h index 7310d7f72..4467e1f35 100644 --- a/src/core/hle/service/glue/notif.h +++ b/src/core/hle/service/glue/notif.h | |||
| @@ -3,6 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "common/uuid.h" | ||
| 6 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 7 | 11 | ||
| 8 | namespace Core { | 12 | namespace Core { |
| @@ -17,8 +21,52 @@ public: | |||
| 17 | ~NOTIF_A() override; | 21 | ~NOTIF_A() override; |
| 18 | 22 | ||
| 19 | private: | 23 | private: |
| 24 | static constexpr std::size_t max_alarms = 8; | ||
| 25 | |||
| 26 | // This is nn::notification::AlarmSettingId | ||
| 27 | using AlarmSettingId = u16; | ||
| 28 | static_assert(sizeof(AlarmSettingId) == 0x2, "AlarmSettingId is an invalid size"); | ||
| 29 | |||
| 30 | using ApplicationParameter = std::array<u8, 0x400>; | ||
| 31 | static_assert(sizeof(ApplicationParameter) == 0x400, "ApplicationParameter is an invalid size"); | ||
| 32 | |||
| 33 | struct DailyAlarmSetting { | ||
| 34 | s8 hour; | ||
| 35 | s8 minute; | ||
| 36 | }; | ||
| 37 | static_assert(sizeof(DailyAlarmSetting) == 0x2, "DailyAlarmSetting is an invalid size"); | ||
| 38 | |||
| 39 | struct WeeklyScheduleAlarmSetting { | ||
| 40 | INSERT_PADDING_BYTES(0xA); | ||
| 41 | std::array<DailyAlarmSetting, 0x7> day_of_week; | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(WeeklyScheduleAlarmSetting) == 0x18, | ||
| 44 | "WeeklyScheduleAlarmSetting is an invalid size"); | ||
| 45 | |||
| 46 | // This is nn::notification::AlarmSetting | ||
| 47 | struct AlarmSetting { | ||
| 48 | AlarmSettingId alarm_setting_id; | ||
| 49 | u8 kind; | ||
| 50 | u8 muted; | ||
| 51 | INSERT_PADDING_BYTES(0x4); | ||
| 52 | Common::UUID account_id; | ||
| 53 | u64 application_id; | ||
| 54 | INSERT_PADDING_BYTES(0x8); | ||
| 55 | WeeklyScheduleAlarmSetting schedule; | ||
| 56 | }; | ||
| 57 | static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size"); | ||
| 58 | |||
| 59 | void RegisterAlarmSetting(Kernel::HLERequestContext& ctx); | ||
| 60 | void UpdateAlarmSetting(Kernel::HLERequestContext& ctx); | ||
| 20 | void ListAlarmSettings(Kernel::HLERequestContext& ctx); | 61 | void ListAlarmSettings(Kernel::HLERequestContext& ctx); |
| 62 | void LoadApplicationParameter(Kernel::HLERequestContext& ctx); | ||
| 63 | void DeleteAlarmSetting(Kernel::HLERequestContext& ctx); | ||
| 21 | void Initialize(Kernel::HLERequestContext& ctx); | 64 | void Initialize(Kernel::HLERequestContext& ctx); |
| 65 | |||
| 66 | std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id); | ||
| 67 | |||
| 68 | std::vector<AlarmSetting> alarms{}; | ||
| 69 | AlarmSettingId last_alarm_setting_id{}; | ||
| 22 | }; | 70 | }; |
| 23 | 71 | ||
| 24 | } // namespace Service::Glue | 72 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 1e04ee3f2..c08b0a5dc 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -56,7 +56,7 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle | |||
| 56 | return npad_id && npad_type && device_index; | 56 | return npad_id && npad_type && device_index; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | ResultCode Controller_NPad::VerifyValidSixAxisSensorHandle( | 59 | Result Controller_NPad::VerifyValidSixAxisSensorHandle( |
| 60 | const Core::HID::SixAxisSensorHandle& device_handle) { | 60 | const Core::HID::SixAxisSensorHandle& device_handle) { |
| 61 | const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)); | 61 | const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)); |
| 62 | if (!npad_id) { | 62 | if (!npad_id) { |
| @@ -160,7 +160,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 160 | shared_memory->system_properties.raw = 0; | 160 | shared_memory->system_properties.raw = 0; |
| 161 | switch (controller_type) { | 161 | switch (controller_type) { |
| 162 | case Core::HID::NpadStyleIndex::None: | 162 | case Core::HID::NpadStyleIndex::None: |
| 163 | UNREACHABLE(); | 163 | ASSERT(false); |
| 164 | break; | 164 | break; |
| 165 | case Core::HID::NpadStyleIndex::ProController: | 165 | case Core::HID::NpadStyleIndex::ProController: |
| 166 | shared_memory->style_tag.fullkey.Assign(1); | 166 | shared_memory->style_tag.fullkey.Assign(1); |
| @@ -422,7 +422,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 422 | libnx_state.connection_status.is_connected.Assign(1); | 422 | libnx_state.connection_status.is_connected.Assign(1); |
| 423 | switch (controller_type) { | 423 | switch (controller_type) { |
| 424 | case Core::HID::NpadStyleIndex::None: | 424 | case Core::HID::NpadStyleIndex::None: |
| 425 | UNREACHABLE(); | 425 | ASSERT(false); |
| 426 | break; | 426 | break; |
| 427 | case Core::HID::NpadStyleIndex::ProController: | 427 | case Core::HID::NpadStyleIndex::ProController: |
| 428 | case Core::HID::NpadStyleIndex::NES: | 428 | case Core::HID::NpadStyleIndex::NES: |
| @@ -597,7 +597,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 597 | 597 | ||
| 598 | switch (controller_type) { | 598 | switch (controller_type) { |
| 599 | case Core::HID::NpadStyleIndex::None: | 599 | case Core::HID::NpadStyleIndex::None: |
| 600 | UNREACHABLE(); | 600 | ASSERT(false); |
| 601 | break; | 601 | break; |
| 602 | case Core::HID::NpadStyleIndex::ProController: | 602 | case Core::HID::NpadStyleIndex::ProController: |
| 603 | case Core::HID::NpadStyleIndex::Pokeball: | 603 | case Core::HID::NpadStyleIndex::Pokeball: |
| @@ -720,9 +720,9 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode | |||
| 720 | return communication_mode; | 720 | return communication_mode; |
| 721 | } | 721 | } |
| 722 | 722 | ||
| 723 | ResultCode Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, | 723 | Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, |
| 724 | NpadJoyDeviceType npad_device_type, | 724 | NpadJoyDeviceType npad_device_type, |
| 725 | NpadJoyAssignmentMode assignment_mode) { | 725 | NpadJoyAssignmentMode assignment_mode) { |
| 726 | if (!IsNpadIdValid(npad_id)) { | 726 | if (!IsNpadIdValid(npad_id)) { |
| 727 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 727 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 728 | return InvalidNpadId; | 728 | return InvalidNpadId; |
| @@ -856,7 +856,7 @@ void Controller_NPad::VibrateController( | |||
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) { | 858 | if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) { |
| 859 | UNREACHABLE_MSG("DeviceIndex should never be None!"); | 859 | ASSERT_MSG(false, "DeviceIndex should never be None!"); |
| 860 | return; | 860 | return; |
| 861 | } | 861 | } |
| 862 | 862 | ||
| @@ -984,7 +984,7 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, | |||
| 984 | InitNewlyAddedController(npad_id); | 984 | InitNewlyAddedController(npad_id); |
| 985 | } | 985 | } |
| 986 | 986 | ||
| 987 | ResultCode Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | 987 | Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { |
| 988 | if (!IsNpadIdValid(npad_id)) { | 988 | if (!IsNpadIdValid(npad_id)) { |
| 989 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 989 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 990 | return InvalidNpadId; | 990 | return InvalidNpadId; |
| @@ -1032,7 +1032,7 @@ ResultCode Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||
| 1032 | WriteEmptyEntry(shared_memory); | 1032 | WriteEmptyEntry(shared_memory); |
| 1033 | return ResultSuccess; | 1033 | return ResultSuccess; |
| 1034 | } | 1034 | } |
| 1035 | ResultCode Controller_NPad::SetGyroscopeZeroDriftMode( | 1035 | Result Controller_NPad::SetGyroscopeZeroDriftMode( |
| 1036 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) { | 1036 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) { |
| 1037 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1037 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1038 | if (is_valid.IsError()) { | 1038 | if (is_valid.IsError()) { |
| @@ -1046,7 +1046,7 @@ ResultCode Controller_NPad::SetGyroscopeZeroDriftMode( | |||
| 1046 | return ResultSuccess; | 1046 | return ResultSuccess; |
| 1047 | } | 1047 | } |
| 1048 | 1048 | ||
| 1049 | ResultCode Controller_NPad::GetGyroscopeZeroDriftMode( | 1049 | Result Controller_NPad::GetGyroscopeZeroDriftMode( |
| 1050 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 1050 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1051 | GyroscopeZeroDriftMode& drift_mode) const { | 1051 | GyroscopeZeroDriftMode& drift_mode) const { |
| 1052 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1052 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| @@ -1061,8 +1061,8 @@ ResultCode Controller_NPad::GetGyroscopeZeroDriftMode( | |||
| 1061 | return ResultSuccess; | 1061 | return ResultSuccess; |
| 1062 | } | 1062 | } |
| 1063 | 1063 | ||
| 1064 | ResultCode Controller_NPad::IsSixAxisSensorAtRest( | 1064 | Result Controller_NPad::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1065 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_at_rest) const { | 1065 | bool& is_at_rest) const { |
| 1066 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1066 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1067 | if (is_valid.IsError()) { | 1067 | if (is_valid.IsError()) { |
| 1068 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | 1068 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); |
| @@ -1074,7 +1074,7 @@ ResultCode Controller_NPad::IsSixAxisSensorAtRest( | |||
| 1074 | return ResultSuccess; | 1074 | return ResultSuccess; |
| 1075 | } | 1075 | } |
| 1076 | 1076 | ||
| 1077 | ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor( | 1077 | Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor( |
| 1078 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { | 1078 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { |
| 1079 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1079 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1080 | if (is_valid.IsError()) { | 1080 | if (is_valid.IsError()) { |
| @@ -1087,7 +1087,7 @@ ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor( | |||
| 1087 | return ResultSuccess; | 1087 | return ResultSuccess; |
| 1088 | } | 1088 | } |
| 1089 | 1089 | ||
| 1090 | ResultCode Controller_NPad::EnableSixAxisSensorUnalteredPassthrough( | 1090 | Result Controller_NPad::EnableSixAxisSensorUnalteredPassthrough( |
| 1091 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) { | 1091 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) { |
| 1092 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1092 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1093 | if (is_valid.IsError()) { | 1093 | if (is_valid.IsError()) { |
| @@ -1100,7 +1100,7 @@ ResultCode Controller_NPad::EnableSixAxisSensorUnalteredPassthrough( | |||
| 1100 | return ResultSuccess; | 1100 | return ResultSuccess; |
| 1101 | } | 1101 | } |
| 1102 | 1102 | ||
| 1103 | ResultCode Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled( | 1103 | Result Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled( |
| 1104 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const { | 1104 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const { |
| 1105 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1105 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1106 | if (is_valid.IsError()) { | 1106 | if (is_valid.IsError()) { |
| @@ -1113,7 +1113,7 @@ ResultCode Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled( | |||
| 1113 | return ResultSuccess; | 1113 | return ResultSuccess; |
| 1114 | } | 1114 | } |
| 1115 | 1115 | ||
| 1116 | ResultCode Controller_NPad::LoadSixAxisSensorCalibrationParameter( | 1116 | Result Controller_NPad::LoadSixAxisSensorCalibrationParameter( |
| 1117 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 1117 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1118 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const { | 1118 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const { |
| 1119 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1119 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| @@ -1128,7 +1128,7 @@ ResultCode Controller_NPad::LoadSixAxisSensorCalibrationParameter( | |||
| 1128 | return ResultSuccess; | 1128 | return ResultSuccess; |
| 1129 | } | 1129 | } |
| 1130 | 1130 | ||
| 1131 | ResultCode Controller_NPad::GetSixAxisSensorIcInformation( | 1131 | Result Controller_NPad::GetSixAxisSensorIcInformation( |
| 1132 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 1132 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1133 | Core::HID::SixAxisSensorIcInformation& ic_information) const { | 1133 | Core::HID::SixAxisSensorIcInformation& ic_information) const { |
| 1134 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1134 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| @@ -1143,7 +1143,7 @@ ResultCode Controller_NPad::GetSixAxisSensorIcInformation( | |||
| 1143 | return ResultSuccess; | 1143 | return ResultSuccess; |
| 1144 | } | 1144 | } |
| 1145 | 1145 | ||
| 1146 | ResultCode Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( | 1146 | Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( |
| 1147 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { | 1147 | const Core::HID::SixAxisSensorHandle& sixaxis_handle) { |
| 1148 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1148 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1149 | if (is_valid.IsError()) { | 1149 | if (is_valid.IsError()) { |
| @@ -1157,8 +1157,8 @@ ResultCode Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( | |||
| 1157 | return ResultSuccess; | 1157 | return ResultSuccess; |
| 1158 | } | 1158 | } |
| 1159 | 1159 | ||
| 1160 | ResultCode Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 1160 | Result Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1161 | bool sixaxis_status) { | 1161 | bool sixaxis_status) { |
| 1162 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1162 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1163 | if (is_valid.IsError()) { | 1163 | if (is_valid.IsError()) { |
| 1164 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | 1164 | LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); |
| @@ -1170,7 +1170,7 @@ ResultCode Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHand | |||
| 1170 | return ResultSuccess; | 1170 | return ResultSuccess; |
| 1171 | } | 1171 | } |
| 1172 | 1172 | ||
| 1173 | ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled( | 1173 | Result Controller_NPad::IsSixAxisSensorFusionEnabled( |
| 1174 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const { | 1174 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const { |
| 1175 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1175 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1176 | if (is_valid.IsError()) { | 1176 | if (is_valid.IsError()) { |
| @@ -1183,7 +1183,7 @@ ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled( | |||
| 1183 | 1183 | ||
| 1184 | return ResultSuccess; | 1184 | return ResultSuccess; |
| 1185 | } | 1185 | } |
| 1186 | ResultCode Controller_NPad::SetSixAxisFusionEnabled( | 1186 | Result Controller_NPad::SetSixAxisFusionEnabled( |
| 1187 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) { | 1187 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) { |
| 1188 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1188 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| 1189 | if (is_valid.IsError()) { | 1189 | if (is_valid.IsError()) { |
| @@ -1197,7 +1197,7 @@ ResultCode Controller_NPad::SetSixAxisFusionEnabled( | |||
| 1197 | return ResultSuccess; | 1197 | return ResultSuccess; |
| 1198 | } | 1198 | } |
| 1199 | 1199 | ||
| 1200 | ResultCode Controller_NPad::SetSixAxisFusionParameters( | 1200 | Result Controller_NPad::SetSixAxisFusionParameters( |
| 1201 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 1201 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1202 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { | 1202 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { |
| 1203 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1203 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| @@ -1217,7 +1217,7 @@ ResultCode Controller_NPad::SetSixAxisFusionParameters( | |||
| 1217 | return ResultSuccess; | 1217 | return ResultSuccess; |
| 1218 | } | 1218 | } |
| 1219 | 1219 | ||
| 1220 | ResultCode Controller_NPad::GetSixAxisFusionParameters( | 1220 | Result Controller_NPad::GetSixAxisFusionParameters( |
| 1221 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 1221 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 1222 | Core::HID::SixAxisSensorFusionParameters& parameters) const { | 1222 | Core::HID::SixAxisSensorFusionParameters& parameters) const { |
| 1223 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | 1223 | const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |
| @@ -1232,8 +1232,8 @@ ResultCode Controller_NPad::GetSixAxisFusionParameters( | |||
| 1232 | return ResultSuccess; | 1232 | return ResultSuccess; |
| 1233 | } | 1233 | } |
| 1234 | 1234 | ||
| 1235 | ResultCode Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | 1235 | Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, |
| 1236 | Core::HID::NpadIdType npad_id_2) { | 1236 | Core::HID::NpadIdType npad_id_2) { |
| 1237 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { | 1237 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { |
| 1238 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, | 1238 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, |
| 1239 | npad_id_2); | 1239 | npad_id_2); |
| @@ -1304,8 +1304,8 @@ void Controller_NPad::StopLRAssignmentMode() { | |||
| 1304 | is_in_lr_assignment_mode = false; | 1304 | is_in_lr_assignment_mode = false; |
| 1305 | } | 1305 | } |
| 1306 | 1306 | ||
| 1307 | ResultCode Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, | 1307 | Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, |
| 1308 | Core::HID::NpadIdType npad_id_2) { | 1308 | Core::HID::NpadIdType npad_id_2) { |
| 1309 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { | 1309 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { |
| 1310 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, | 1310 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, |
| 1311 | npad_id_2); | 1311 | npad_id_2); |
| @@ -1336,8 +1336,8 @@ ResultCode Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, | |||
| 1336 | return ResultSuccess; | 1336 | return ResultSuccess; |
| 1337 | } | 1337 | } |
| 1338 | 1338 | ||
| 1339 | ResultCode Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, | 1339 | Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, |
| 1340 | Core::HID::LedPattern& pattern) const { | 1340 | Core::HID::LedPattern& pattern) const { |
| 1341 | if (!IsNpadIdValid(npad_id)) { | 1341 | if (!IsNpadIdValid(npad_id)) { |
| 1342 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1342 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1343 | return InvalidNpadId; | 1343 | return InvalidNpadId; |
| @@ -1347,8 +1347,8 @@ ResultCode Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, | |||
| 1347 | return ResultSuccess; | 1347 | return ResultSuccess; |
| 1348 | } | 1348 | } |
| 1349 | 1349 | ||
| 1350 | ResultCode Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled( | 1350 | Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, |
| 1351 | Core::HID::NpadIdType npad_id, bool& is_valid) const { | 1351 | bool& is_valid) const { |
| 1352 | if (!IsNpadIdValid(npad_id)) { | 1352 | if (!IsNpadIdValid(npad_id)) { |
| 1353 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1353 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| 1354 | return InvalidNpadId; | 1354 | return InvalidNpadId; |
| @@ -1358,7 +1358,7 @@ ResultCode Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled( | |||
| 1358 | return ResultSuccess; | 1358 | return ResultSuccess; |
| 1359 | } | 1359 | } |
| 1360 | 1360 | ||
| 1361 | ResultCode Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled( | 1361 | Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled( |
| 1362 | bool is_protection_enabled, Core::HID::NpadIdType npad_id) { | 1362 | bool is_protection_enabled, Core::HID::NpadIdType npad_id) { |
| 1363 | if (!IsNpadIdValid(npad_id)) { | 1363 | if (!IsNpadIdValid(npad_id)) { |
| 1364 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 1364 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 0b662b7f8..8b54724ed 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -29,7 +29,7 @@ namespace Service::KernelHelpers { | |||
| 29 | class ServiceContext; | 29 | class ServiceContext; |
| 30 | } // namespace Service::KernelHelpers | 30 | } // namespace Service::KernelHelpers |
| 31 | 31 | ||
| 32 | union ResultCode; | 32 | union Result; |
| 33 | 33 | ||
| 34 | namespace Service::HID { | 34 | namespace Service::HID { |
| 35 | 35 | ||
| @@ -107,8 +107,8 @@ public: | |||
| 107 | void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); | 107 | void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); |
| 108 | NpadCommunicationMode GetNpadCommunicationMode() const; | 108 | NpadCommunicationMode GetNpadCommunicationMode() const; |
| 109 | 109 | ||
| 110 | ResultCode SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, | 110 | Result SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, |
| 111 | NpadJoyAssignmentMode assignment_mode); | 111 | NpadJoyAssignmentMode assignment_mode); |
| 112 | 112 | ||
| 113 | bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, | 113 | bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, |
| 114 | const Core::HID::VibrationValue& vibration_value); | 114 | const Core::HID::VibrationValue& vibration_value); |
| @@ -141,56 +141,55 @@ public: | |||
| 141 | void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id, | 141 | void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id, |
| 142 | bool connected); | 142 | bool connected); |
| 143 | 143 | ||
| 144 | ResultCode DisconnectNpad(Core::HID::NpadIdType npad_id); | 144 | Result DisconnectNpad(Core::HID::NpadIdType npad_id); |
| 145 | 145 | ||
| 146 | ResultCode SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 146 | Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 147 | GyroscopeZeroDriftMode drift_mode); | 147 | GyroscopeZeroDriftMode drift_mode); |
| 148 | ResultCode GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 148 | Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 149 | GyroscopeZeroDriftMode& drift_mode) const; | 149 | GyroscopeZeroDriftMode& drift_mode) const; |
| 150 | ResultCode IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 150 | Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 151 | bool& is_at_rest) const; | 151 | bool& is_at_rest) const; |
| 152 | ResultCode IsFirmwareUpdateAvailableForSixAxisSensor( | 152 | Result IsFirmwareUpdateAvailableForSixAxisSensor( |
| 153 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const; | 153 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const; |
| 154 | ResultCode EnableSixAxisSensorUnalteredPassthrough( | 154 | Result EnableSixAxisSensorUnalteredPassthrough( |
| 155 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled); | 155 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled); |
| 156 | ResultCode IsSixAxisSensorUnalteredPassthroughEnabled( | 156 | Result IsSixAxisSensorUnalteredPassthroughEnabled( |
| 157 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const; | 157 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const; |
| 158 | ResultCode LoadSixAxisSensorCalibrationParameter( | 158 | Result LoadSixAxisSensorCalibrationParameter( |
| 159 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 159 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 160 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const; | 160 | Core::HID::SixAxisSensorCalibrationParameter& calibration) const; |
| 161 | ResultCode GetSixAxisSensorIcInformation( | 161 | Result GetSixAxisSensorIcInformation( |
| 162 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 162 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 163 | Core::HID::SixAxisSensorIcInformation& ic_information) const; | 163 | Core::HID::SixAxisSensorIcInformation& ic_information) const; |
| 164 | ResultCode ResetIsSixAxisSensorDeviceNewlyAssigned( | 164 | Result ResetIsSixAxisSensorDeviceNewlyAssigned( |
| 165 | const Core::HID::SixAxisSensorHandle& sixaxis_handle); | 165 | const Core::HID::SixAxisSensorHandle& sixaxis_handle); |
| 166 | ResultCode SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 166 | Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 167 | bool sixaxis_status); | 167 | bool sixaxis_status); |
| 168 | ResultCode IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 168 | Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 169 | bool& is_fusion_enabled) const; | 169 | bool& is_fusion_enabled) const; |
| 170 | ResultCode SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 170 | Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 171 | bool is_fusion_enabled); | 171 | bool is_fusion_enabled); |
| 172 | ResultCode SetSixAxisFusionParameters( | 172 | Result SetSixAxisFusionParameters( |
| 173 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 173 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 174 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); | 174 | Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); |
| 175 | ResultCode GetSixAxisFusionParameters( | 175 | Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |
| 176 | const Core::HID::SixAxisSensorHandle& sixaxis_handle, | 176 | Core::HID::SixAxisSensorFusionParameters& parameters) const; |
| 177 | Core::HID::SixAxisSensorFusionParameters& parameters) const; | 177 | Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; |
| 178 | ResultCode GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; | 178 | Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, |
| 179 | ResultCode IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, | 179 | bool& is_enabled) const; |
| 180 | bool& is_enabled) const; | 180 | Result SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, |
| 181 | ResultCode SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, | 181 | Core::HID::NpadIdType npad_id); |
| 182 | Core::HID::NpadIdType npad_id); | ||
| 183 | void SetAnalogStickUseCenterClamp(bool use_center_clamp); | 182 | void SetAnalogStickUseCenterClamp(bool use_center_clamp); |
| 184 | void ClearAllConnectedControllers(); | 183 | void ClearAllConnectedControllers(); |
| 185 | void DisconnectAllConnectedControllers(); | 184 | void DisconnectAllConnectedControllers(); |
| 186 | void ConnectAllDisconnectedControllers(); | 185 | void ConnectAllDisconnectedControllers(); |
| 187 | void ClearAllControllers(); | 186 | void ClearAllControllers(); |
| 188 | 187 | ||
| 189 | ResultCode MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | 188 | Result MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, |
| 190 | Core::HID::NpadIdType npad_id_2); | 189 | Core::HID::NpadIdType npad_id_2); |
| 191 | void StartLRAssignmentMode(); | 190 | void StartLRAssignmentMode(); |
| 192 | void StopLRAssignmentMode(); | 191 | void StopLRAssignmentMode(); |
| 193 | ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); | 192 | Result SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); |
| 194 | 193 | ||
| 195 | // Logical OR for all buttons presses on all controllers | 194 | // Logical OR for all buttons presses on all controllers |
| 196 | // Specifically for cheat engine and other features. | 195 | // Specifically for cheat engine and other features. |
| @@ -198,7 +197,7 @@ public: | |||
| 198 | 197 | ||
| 199 | static bool IsNpadIdValid(Core::HID::NpadIdType npad_id); | 198 | static bool IsNpadIdValid(Core::HID::NpadIdType npad_id); |
| 200 | static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); | 199 | static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); |
| 201 | static ResultCode VerifyValidSixAxisSensorHandle( | 200 | static Result VerifyValidSixAxisSensorHandle( |
| 202 | const Core::HID::SixAxisSensorHandle& device_handle); | 201 | const Core::HID::SixAxisSensorHandle& device_handle); |
| 203 | 202 | ||
| 204 | private: | 203 | private: |
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 6c8ad04af..615c23b84 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h | |||
| @@ -7,12 +7,12 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::HID { | 8 | namespace Service::HID { |
| 9 | 9 | ||
| 10 | constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100}; | 10 | constexpr Result NpadInvalidHandle{ErrorModule::HID, 100}; |
| 11 | constexpr ResultCode NpadDeviceIndexOutOfRange{ErrorModule::HID, 107}; | 11 | constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107}; |
| 12 | constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423}; | 12 | constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423}; |
| 13 | constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601}; | 13 | constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601}; |
| 14 | constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602}; | 14 | constexpr Result NpadIsSameType{ErrorModule::HID, 602}; |
| 15 | constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709}; | 15 | constexpr Result InvalidNpadId{ErrorModule::HID, 709}; |
| 16 | constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710}; | 16 | constexpr Result NpadNotConnected{ErrorModule::HID, 710}; |
| 17 | 17 | ||
| 18 | } // namespace Service::HID | 18 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 8a496c38c..dc5d0366d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -1441,7 +1441,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | |||
| 1441 | break; | 1441 | break; |
| 1442 | case Core::HID::DeviceIndex::None: | 1442 | case Core::HID::DeviceIndex::None: |
| 1443 | default: | 1443 | default: |
| 1444 | UNREACHABLE_MSG("DeviceIndex should never be None!"); | 1444 | ASSERT_MSG(false, "DeviceIndex should never be None!"); |
| 1445 | vibration_device_info.position = Core::HID::VibrationDevicePosition::None; | 1445 | vibration_device_info.position = Core::HID::VibrationDevicePosition::None; |
| 1446 | break; | 1446 | break; |
| 1447 | } | 1447 | } |
diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h index 6b3015a0f..8c687f678 100644 --- a/src/core/hle/service/hid/hidbus.h +++ b/src/core/hle/service/hid/hidbus.h | |||
| @@ -71,7 +71,7 @@ private: | |||
| 71 | struct HidbusStatusManagerEntry { | 71 | struct HidbusStatusManagerEntry { |
| 72 | u8 is_connected{}; | 72 | u8 is_connected{}; |
| 73 | INSERT_PADDING_BYTES(0x3); | 73 | INSERT_PADDING_BYTES(0x3); |
| 74 | ResultCode is_connected_result{0}; | 74 | Result is_connected_result{0}; |
| 75 | u8 is_enabled{}; | 75 | u8 is_enabled{}; |
| 76 | u8 is_in_focus{}; | 76 | u8 is_in_focus{}; |
| 77 | u8 is_polling_mode{}; | 77 | u8 is_polling_mode{}; |
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h index 01c52051b..d3960f506 100644 --- a/src/core/hle/service/hid/hidbus/hidbus_base.h +++ b/src/core/hle/service/hid/hidbus/hidbus_base.h | |||
| @@ -26,7 +26,7 @@ enum class JoyPollingMode : u32 { | |||
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | struct DataAccessorHeader { | 28 | struct DataAccessorHeader { |
| 29 | ResultCode result{ResultUnknown}; | 29 | Result result{ResultUnknown}; |
| 30 | INSERT_PADDING_WORDS(0x1); | 30 | INSERT_PADDING_WORDS(0x1); |
| 31 | std::array<u8, 0x18> unused{}; | 31 | std::array<u8, 0x18> unused{}; |
| 32 | u64 latest_entry{}; | 32 | u64 latest_entry{}; |
diff --git a/src/core/hle/service/ldn/errors.h b/src/core/hle/service/ldn/errors.h index fb86b9402..972a74806 100644 --- a/src/core/hle/service/ldn/errors.h +++ b/src/core/hle/service/ldn/errors.h | |||
| @@ -7,6 +7,6 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::LDN { | 8 | namespace Service::LDN { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERROR_DISABLED{ErrorModule::LDN, 22}; | 10 | constexpr Result ERROR_DISABLED{ErrorModule::LDN, 22}; |
| 11 | 11 | ||
| 12 | } // namespace Service::LDN | 12 | } // namespace Service::LDN |
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index fa72fcba9..becd6d1b9 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -20,20 +20,20 @@ | |||
| 20 | 20 | ||
| 21 | namespace Service::LDR { | 21 | namespace Service::LDR { |
| 22 | 22 | ||
| 23 | constexpr ResultCode ERROR_INSUFFICIENT_ADDRESS_SPACE{ErrorModule::RO, 2}; | 23 | constexpr Result ERROR_INSUFFICIENT_ADDRESS_SPACE{ErrorModule::RO, 2}; |
| 24 | 24 | ||
| 25 | [[maybe_unused]] constexpr ResultCode ERROR_INVALID_MEMORY_STATE{ErrorModule::Loader, 51}; | 25 | [[maybe_unused]] constexpr Result ERROR_INVALID_MEMORY_STATE{ErrorModule::Loader, 51}; |
| 26 | constexpr ResultCode ERROR_INVALID_NRO{ErrorModule::Loader, 52}; | 26 | constexpr Result ERROR_INVALID_NRO{ErrorModule::Loader, 52}; |
| 27 | constexpr ResultCode ERROR_INVALID_NRR{ErrorModule::Loader, 53}; | 27 | constexpr Result ERROR_INVALID_NRR{ErrorModule::Loader, 53}; |
| 28 | constexpr ResultCode ERROR_MISSING_NRR_HASH{ErrorModule::Loader, 54}; | 28 | constexpr Result ERROR_MISSING_NRR_HASH{ErrorModule::Loader, 54}; |
| 29 | constexpr ResultCode ERROR_MAXIMUM_NRO{ErrorModule::Loader, 55}; | 29 | constexpr Result ERROR_MAXIMUM_NRO{ErrorModule::Loader, 55}; |
| 30 | constexpr ResultCode ERROR_MAXIMUM_NRR{ErrorModule::Loader, 56}; | 30 | constexpr Result ERROR_MAXIMUM_NRR{ErrorModule::Loader, 56}; |
| 31 | constexpr ResultCode ERROR_ALREADY_LOADED{ErrorModule::Loader, 57}; | 31 | constexpr Result ERROR_ALREADY_LOADED{ErrorModule::Loader, 57}; |
| 32 | constexpr ResultCode ERROR_INVALID_ALIGNMENT{ErrorModule::Loader, 81}; | 32 | constexpr Result ERROR_INVALID_ALIGNMENT{ErrorModule::Loader, 81}; |
| 33 | constexpr ResultCode ERROR_INVALID_SIZE{ErrorModule::Loader, 82}; | 33 | constexpr Result ERROR_INVALID_SIZE{ErrorModule::Loader, 82}; |
| 34 | constexpr ResultCode ERROR_INVALID_NRO_ADDRESS{ErrorModule::Loader, 84}; | 34 | constexpr Result ERROR_INVALID_NRO_ADDRESS{ErrorModule::Loader, 84}; |
| 35 | [[maybe_unused]] constexpr ResultCode ERROR_INVALID_NRR_ADDRESS{ErrorModule::Loader, 85}; | 35 | [[maybe_unused]] constexpr Result ERROR_INVALID_NRR_ADDRESS{ErrorModule::Loader, 85}; |
| 36 | constexpr ResultCode ERROR_NOT_INITIALIZED{ErrorModule::Loader, 87}; | 36 | constexpr Result ERROR_NOT_INITIALIZED{ErrorModule::Loader, 87}; |
| 37 | 37 | ||
| 38 | constexpr std::size_t MAXIMUM_LOADED_RO{0x40}; | 38 | constexpr std::size_t MAXIMUM_LOADED_RO{0x40}; |
| 39 | constexpr std::size_t MAXIMUM_MAP_RETRIES{0x200}; | 39 | constexpr std::size_t MAXIMUM_MAP_RETRIES{0x200}; |
| @@ -307,7 +307,7 @@ public: | |||
| 307 | return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); | 307 | return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize()); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | ResultCode GetAvailableMapRegion(Kernel::KPageTable& page_table, u64 size, VAddr& out_addr) { | 310 | Result GetAvailableMapRegion(Kernel::KPageTable& page_table, u64 size, VAddr& out_addr) { |
| 311 | size = Common::AlignUp(size, Kernel::PageSize); | 311 | size = Common::AlignUp(size, Kernel::PageSize); |
| 312 | size += page_table.GetNumGuardPages() * Kernel::PageSize * 4; | 312 | size += page_table.GetNumGuardPages() * Kernel::PageSize * 4; |
| 313 | 313 | ||
| @@ -347,7 +347,7 @@ public: | |||
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | if (!succeeded) { | 349 | if (!succeeded) { |
| 350 | UNREACHABLE_MSG("Out of address space!"); | 350 | ASSERT_MSG(false, "Out of address space!"); |
| 351 | return Kernel::ResultOutOfMemory; | 351 | return Kernel::ResultOutOfMemory; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| @@ -364,7 +364,7 @@ public: | |||
| 364 | for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { | 364 | for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { |
| 365 | R_TRY(GetAvailableMapRegion(page_table, size, addr)); | 365 | R_TRY(GetAvailableMapRegion(page_table, size, addr)); |
| 366 | 366 | ||
| 367 | const ResultCode result{page_table.MapCodeMemory(addr, base_addr, size)}; | 367 | const Result result{page_table.MapCodeMemory(addr, base_addr, size)}; |
| 368 | if (result == Kernel::ResultInvalidCurrentMemory) { | 368 | if (result == Kernel::ResultInvalidCurrentMemory) { |
| 369 | continue; | 369 | continue; |
| 370 | } | 370 | } |
| @@ -397,8 +397,7 @@ public: | |||
| 397 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange); | 397 | Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange); |
| 398 | }); | 398 | }); |
| 399 | 399 | ||
| 400 | const ResultCode result{ | 400 | const Result result{page_table.MapCodeMemory(addr + nro_size, bss_addr, bss_size)}; |
| 401 | page_table.MapCodeMemory(addr + nro_size, bss_addr, bss_size)}; | ||
| 402 | 401 | ||
| 403 | if (result == Kernel::ResultInvalidCurrentMemory) { | 402 | if (result == Kernel::ResultInvalidCurrentMemory) { |
| 404 | continue; | 403 | continue; |
| @@ -419,8 +418,8 @@ public: | |||
| 419 | return ERROR_INSUFFICIENT_ADDRESS_SPACE; | 418 | return ERROR_INSUFFICIENT_ADDRESS_SPACE; |
| 420 | } | 419 | } |
| 421 | 420 | ||
| 422 | ResultCode LoadNro(Kernel::KProcess* process, const NROHeader& nro_header, VAddr nro_addr, | 421 | Result LoadNro(Kernel::KProcess* process, const NROHeader& nro_header, VAddr nro_addr, |
| 423 | VAddr start) const { | 422 | VAddr start) const { |
| 424 | const VAddr text_start{start + nro_header.segment_headers[TEXT_INDEX].memory_offset}; | 423 | const VAddr text_start{start + nro_header.segment_headers[TEXT_INDEX].memory_offset}; |
| 425 | const VAddr ro_start{start + nro_header.segment_headers[RO_INDEX].memory_offset}; | 424 | const VAddr ro_start{start + nro_header.segment_headers[RO_INDEX].memory_offset}; |
| 426 | const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset}; | 425 | const VAddr data_start{start + nro_header.segment_headers[DATA_INDEX].memory_offset}; |
| @@ -569,7 +568,7 @@ public: | |||
| 569 | rb.Push(*map_result); | 568 | rb.Push(*map_result); |
| 570 | } | 569 | } |
| 571 | 570 | ||
| 572 | ResultCode UnmapNro(const NROInfo& info) { | 571 | Result UnmapNro(const NROInfo& info) { |
| 573 | // Each region must be unmapped separately to validate memory state | 572 | // Each region must be unmapped separately to validate memory state |
| 574 | auto& page_table{system.CurrentProcess()->PageTable()}; | 573 | auto& page_table{system.CurrentProcess()->PageTable()}; |
| 575 | 574 | ||
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index 41755bf0b..efb569993 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::Mii { | 13 | namespace Service::Mii { |
| 14 | 14 | ||
| 15 | constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::Mii, 1}; | 15 | constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::Mii, 1}; |
| 16 | 16 | ||
| 17 | class IDatabaseService final : public ServiceFramework<IDatabaseService> { | 17 | class IDatabaseService final : public ServiceFramework<IDatabaseService> { |
| 18 | public: | 18 | public: |
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 4964539f9..544c92a00 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp | |||
| @@ -16,7 +16,7 @@ namespace Service::Mii { | |||
| 16 | 16 | ||
| 17 | namespace { | 17 | namespace { |
| 18 | 18 | ||
| 19 | constexpr ResultCode ERROR_CANNOT_FIND_ENTRY{ErrorModule::Mii, 4}; | 19 | constexpr Result ERROR_CANNOT_FIND_ENTRY{ErrorModule::Mii, 4}; |
| 20 | 20 | ||
| 21 | constexpr std::size_t BaseMiiCount{2}; | 21 | constexpr std::size_t BaseMiiCount{2}; |
| 22 | constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()}; | 22 | constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()}; |
| @@ -290,7 +290,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo | |||
| 290 | u8 glasses_type{}; | 290 | u8 glasses_type{}; |
| 291 | while (glasses_type_start < glasses_type_info.values[glasses_type]) { | 291 | while (glasses_type_start < glasses_type_info.values[glasses_type]) { |
| 292 | if (++glasses_type >= glasses_type_info.values_count) { | 292 | if (++glasses_type >= glasses_type_info.values_count) { |
| 293 | UNREACHABLE(); | 293 | ASSERT(false); |
| 294 | break; | 294 | break; |
| 295 | } | 295 | } |
| 296 | } | 296 | } |
| @@ -441,7 +441,7 @@ ResultVal<std::vector<MiiInfoElement>> MiiManager::GetDefault(SourceFlag source_ | |||
| 441 | return result; | 441 | return result; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | ResultCode MiiManager::GetIndex([[maybe_unused]] const MiiInfo& info, u32& index) { | 444 | Result MiiManager::GetIndex([[maybe_unused]] const MiiInfo& info, u32& index) { |
| 445 | constexpr u32 INVALID_INDEX{0xFFFFFFFF}; | 445 | constexpr u32 INVALID_INDEX{0xFFFFFFFF}; |
| 446 | 446 | ||
| 447 | index = INVALID_INDEX; | 447 | index = INVALID_INDEX; |
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h index db217b9a5..6a286bd96 100644 --- a/src/core/hle/service/mii/mii_manager.h +++ b/src/core/hle/service/mii/mii_manager.h | |||
| @@ -23,7 +23,7 @@ public: | |||
| 23 | MiiInfo BuildRandom(Age age, Gender gender, Race race); | 23 | MiiInfo BuildRandom(Age age, Gender gender, Race race); |
| 24 | MiiInfo BuildDefault(std::size_t index); | 24 | MiiInfo BuildDefault(std::size_t index); |
| 25 | ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag); | 25 | ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag); |
| 26 | ResultCode GetIndex(const MiiInfo& info, u32& index); | 26 | Result GetIndex(const MiiInfo& info, u32& index); |
| 27 | 27 | ||
| 28 | private: | 28 | private: |
| 29 | const Common::UUID user_id{}; | 29 | const Common::UUID user_id{}; |
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 74891da57..6c5b41dd1 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp | |||
| @@ -17,10 +17,10 @@ | |||
| 17 | 17 | ||
| 18 | namespace Service::NFP { | 18 | namespace Service::NFP { |
| 19 | namespace ErrCodes { | 19 | namespace ErrCodes { |
| 20 | constexpr ResultCode DeviceNotFound(ErrorModule::NFP, 64); | 20 | constexpr Result DeviceNotFound(ErrorModule::NFP, 64); |
| 21 | constexpr ResultCode WrongDeviceState(ErrorModule::NFP, 73); | 21 | constexpr Result WrongDeviceState(ErrorModule::NFP, 73); |
| 22 | constexpr ResultCode ApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); | 22 | constexpr Result ApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); |
| 23 | constexpr ResultCode ApplicationAreaExist(ErrorModule::NFP, 168); | 23 | constexpr Result ApplicationAreaExist(ErrorModule::NFP, 168); |
| 24 | } // namespace ErrCodes | 24 | } // namespace ErrCodes |
| 25 | 25 | ||
| 26 | constexpr u32 ApplicationAreaSize = 0xD8; | 26 | constexpr u32 ApplicationAreaSize = 0xD8; |
| @@ -585,7 +585,7 @@ void Module::Interface::Finalize() { | |||
| 585 | application_area_data.clear(); | 585 | application_area_data.clear(); |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | ResultCode Module::Interface::StartDetection(s32 protocol_) { | 588 | Result Module::Interface::StartDetection(s32 protocol_) { |
| 589 | auto npad_device = system.HIDCore().GetEmulatedController(npad_id); | 589 | auto npad_device = system.HIDCore().GetEmulatedController(npad_id); |
| 590 | 590 | ||
| 591 | // TODO(german77): Add callback for when nfc data is available | 591 | // TODO(german77): Add callback for when nfc data is available |
| @@ -601,7 +601,7 @@ ResultCode Module::Interface::StartDetection(s32 protocol_) { | |||
| 601 | return ErrCodes::WrongDeviceState; | 601 | return ErrCodes::WrongDeviceState; |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | ResultCode Module::Interface::StopDetection() { | 604 | Result Module::Interface::StopDetection() { |
| 605 | auto npad_device = system.HIDCore().GetEmulatedController(npad_id); | 605 | auto npad_device = system.HIDCore().GetEmulatedController(npad_id); |
| 606 | npad_device->SetPollingMode(Common::Input::PollingMode::Active); | 606 | npad_device->SetPollingMode(Common::Input::PollingMode::Active); |
| 607 | 607 | ||
| @@ -618,7 +618,7 @@ ResultCode Module::Interface::StopDetection() { | |||
| 618 | return ErrCodes::WrongDeviceState; | 618 | return ErrCodes::WrongDeviceState; |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | ResultCode Module::Interface::Mount() { | 621 | Result Module::Interface::Mount() { |
| 622 | if (device_state == DeviceState::TagFound) { | 622 | if (device_state == DeviceState::TagFound) { |
| 623 | device_state = DeviceState::TagMounted; | 623 | device_state = DeviceState::TagMounted; |
| 624 | return ResultSuccess; | 624 | return ResultSuccess; |
| @@ -628,7 +628,7 @@ ResultCode Module::Interface::Mount() { | |||
| 628 | return ErrCodes::WrongDeviceState; | 628 | return ErrCodes::WrongDeviceState; |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | ResultCode Module::Interface::Unmount() { | 631 | Result Module::Interface::Unmount() { |
| 632 | if (device_state == DeviceState::TagMounted) { | 632 | if (device_state == DeviceState::TagMounted) { |
| 633 | is_application_area_initialized = false; | 633 | is_application_area_initialized = false; |
| 634 | application_area_id = 0; | 634 | application_area_id = 0; |
| @@ -641,7 +641,7 @@ ResultCode Module::Interface::Unmount() { | |||
| 641 | return ErrCodes::WrongDeviceState; | 641 | return ErrCodes::WrongDeviceState; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | ResultCode Module::Interface::GetTagInfo(TagInfo& tag_info) const { | 644 | Result Module::Interface::GetTagInfo(TagInfo& tag_info) const { |
| 645 | if (device_state == DeviceState::TagFound || device_state == DeviceState::TagMounted) { | 645 | if (device_state == DeviceState::TagFound || device_state == DeviceState::TagMounted) { |
| 646 | tag_info = { | 646 | tag_info = { |
| 647 | .uuid = tag_data.uuid, | 647 | .uuid = tag_data.uuid, |
| @@ -656,7 +656,7 @@ ResultCode Module::Interface::GetTagInfo(TagInfo& tag_info) const { | |||
| 656 | return ErrCodes::WrongDeviceState; | 656 | return ErrCodes::WrongDeviceState; |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | ResultCode Module::Interface::GetCommonInfo(CommonInfo& common_info) const { | 659 | Result Module::Interface::GetCommonInfo(CommonInfo& common_info) const { |
| 660 | if (device_state != DeviceState::TagMounted) { | 660 | if (device_state != DeviceState::TagMounted) { |
| 661 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 661 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 662 | return ErrCodes::WrongDeviceState; | 662 | return ErrCodes::WrongDeviceState; |
| @@ -674,7 +674,7 @@ ResultCode Module::Interface::GetCommonInfo(CommonInfo& common_info) const { | |||
| 674 | return ResultSuccess; | 674 | return ResultSuccess; |
| 675 | } | 675 | } |
| 676 | 676 | ||
| 677 | ResultCode Module::Interface::GetModelInfo(ModelInfo& model_info) const { | 677 | Result Module::Interface::GetModelInfo(ModelInfo& model_info) const { |
| 678 | if (device_state != DeviceState::TagMounted) { | 678 | if (device_state != DeviceState::TagMounted) { |
| 679 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 679 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 680 | return ErrCodes::WrongDeviceState; | 680 | return ErrCodes::WrongDeviceState; |
| @@ -684,7 +684,7 @@ ResultCode Module::Interface::GetModelInfo(ModelInfo& model_info) const { | |||
| 684 | return ResultSuccess; | 684 | return ResultSuccess; |
| 685 | } | 685 | } |
| 686 | 686 | ||
| 687 | ResultCode Module::Interface::GetRegisterInfo(RegisterInfo& register_info) const { | 687 | Result Module::Interface::GetRegisterInfo(RegisterInfo& register_info) const { |
| 688 | if (device_state != DeviceState::TagMounted) { | 688 | if (device_state != DeviceState::TagMounted) { |
| 689 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 689 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 690 | return ErrCodes::WrongDeviceState; | 690 | return ErrCodes::WrongDeviceState; |
| @@ -704,7 +704,7 @@ ResultCode Module::Interface::GetRegisterInfo(RegisterInfo& register_info) const | |||
| 704 | return ResultSuccess; | 704 | return ResultSuccess; |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | ResultCode Module::Interface::OpenApplicationArea(u32 access_id) { | 707 | Result Module::Interface::OpenApplicationArea(u32 access_id) { |
| 708 | if (device_state != DeviceState::TagMounted) { | 708 | if (device_state != DeviceState::TagMounted) { |
| 709 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 709 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 710 | return ErrCodes::WrongDeviceState; | 710 | return ErrCodes::WrongDeviceState; |
| @@ -721,7 +721,7 @@ ResultCode Module::Interface::OpenApplicationArea(u32 access_id) { | |||
| 721 | return ResultSuccess; | 721 | return ResultSuccess; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | ResultCode Module::Interface::GetApplicationArea(std::vector<u8>& data) const { | 724 | Result Module::Interface::GetApplicationArea(std::vector<u8>& data) const { |
| 725 | if (device_state != DeviceState::TagMounted) { | 725 | if (device_state != DeviceState::TagMounted) { |
| 726 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 726 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 727 | return ErrCodes::WrongDeviceState; | 727 | return ErrCodes::WrongDeviceState; |
| @@ -736,7 +736,7 @@ ResultCode Module::Interface::GetApplicationArea(std::vector<u8>& data) const { | |||
| 736 | return ResultSuccess; | 736 | return ResultSuccess; |
| 737 | } | 737 | } |
| 738 | 738 | ||
| 739 | ResultCode Module::Interface::SetApplicationArea(const std::vector<u8>& data) { | 739 | Result Module::Interface::SetApplicationArea(const std::vector<u8>& data) { |
| 740 | if (device_state != DeviceState::TagMounted) { | 740 | if (device_state != DeviceState::TagMounted) { |
| 741 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 741 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 742 | return ErrCodes::WrongDeviceState; | 742 | return ErrCodes::WrongDeviceState; |
| @@ -750,7 +750,7 @@ ResultCode Module::Interface::SetApplicationArea(const std::vector<u8>& data) { | |||
| 750 | return ResultSuccess; | 750 | return ResultSuccess; |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | ResultCode Module::Interface::CreateApplicationArea(u32 access_id, const std::vector<u8>& data) { | 753 | Result Module::Interface::CreateApplicationArea(u32 access_id, const std::vector<u8>& data) { |
| 754 | if (device_state != DeviceState::TagMounted) { | 754 | if (device_state != DeviceState::TagMounted) { |
| 755 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 755 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 756 | return ErrCodes::WrongDeviceState; | 756 | return ErrCodes::WrongDeviceState; |
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index d307c6a35..0fc808781 100644 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h | |||
| @@ -178,20 +178,20 @@ public: | |||
| 178 | void Initialize(); | 178 | void Initialize(); |
| 179 | void Finalize(); | 179 | void Finalize(); |
| 180 | 180 | ||
| 181 | ResultCode StartDetection(s32 protocol_); | 181 | Result StartDetection(s32 protocol_); |
| 182 | ResultCode StopDetection(); | 182 | Result StopDetection(); |
| 183 | ResultCode Mount(); | 183 | Result Mount(); |
| 184 | ResultCode Unmount(); | 184 | Result Unmount(); |
| 185 | 185 | ||
| 186 | ResultCode GetTagInfo(TagInfo& tag_info) const; | 186 | Result GetTagInfo(TagInfo& tag_info) const; |
| 187 | ResultCode GetCommonInfo(CommonInfo& common_info) const; | 187 | Result GetCommonInfo(CommonInfo& common_info) const; |
| 188 | ResultCode GetModelInfo(ModelInfo& model_info) const; | 188 | Result GetModelInfo(ModelInfo& model_info) const; |
| 189 | ResultCode GetRegisterInfo(RegisterInfo& register_info) const; | 189 | Result GetRegisterInfo(RegisterInfo& register_info) const; |
| 190 | 190 | ||
| 191 | ResultCode OpenApplicationArea(u32 access_id); | 191 | Result OpenApplicationArea(u32 access_id); |
| 192 | ResultCode GetApplicationArea(std::vector<u8>& data) const; | 192 | Result GetApplicationArea(std::vector<u8>& data) const; |
| 193 | ResultCode SetApplicationArea(const std::vector<u8>& data); | 193 | Result SetApplicationArea(const std::vector<u8>& data); |
| 194 | ResultCode CreateApplicationArea(u32 access_id, const std::vector<u8>& data); | 194 | Result CreateApplicationArea(u32 access_id, const std::vector<u8>& data); |
| 195 | 195 | ||
| 196 | u64 GetHandle() const; | 196 | u64 GetHandle() const; |
| 197 | DeviceState GetCurrentState() const; | 197 | DeviceState GetCurrentState() const; |
diff --git a/src/core/hle/service/ns/errors.h b/src/core/hle/service/ns/errors.h index 3c50c66e0..8a7621798 100644 --- a/src/core/hle/service/ns/errors.h +++ b/src/core/hle/service/ns/errors.h | |||
| @@ -7,5 +7,5 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::NS { | 8 | namespace Service::NS { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300}; | 10 | constexpr Result ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300}; |
| 11 | } \ No newline at end of file | 11 | } \ No newline at end of file |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 705fefc83..527531f29 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -150,9 +150,9 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | |||
| 150 | event.event->GetWritableEvent().Clear(); | 150 | event.event->GetWritableEvent().Clear(); |
| 151 | if (events_interface.failed[event_id]) { | 151 | if (events_interface.failed[event_id]) { |
| 152 | { | 152 | { |
| 153 | auto lk = system.StallCPU(); | 153 | auto lk = system.StallProcesses(); |
| 154 | gpu.WaitFence(params.syncpt_id, target_value); | 154 | gpu.WaitFence(params.syncpt_id, target_value); |
| 155 | system.UnstallCPU(); | 155 | system.UnstallProcesses(); |
| 156 | } | 156 | } |
| 157 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 157 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 158 | events_interface.failed[event_id] = false; | 158 | events_interface.failed[event_id] = false; |
diff --git a/src/core/hle/service/nvdrv/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/syncpoint_manager.cpp index f77f0df27..a6fa943e8 100644 --- a/src/core/hle/service/nvdrv/syncpoint_manager.cpp +++ b/src/core/hle/service/nvdrv/syncpoint_manager.cpp | |||
| @@ -23,7 +23,7 @@ u32 SyncpointManager::AllocateSyncpoint() { | |||
| 23 | return syncpoint_id; | 23 | return syncpoint_id; |
| 24 | } | 24 | } |
| 25 | } | 25 | } |
| 26 | UNREACHABLE_MSG("No more available syncpoints!"); | 26 | ASSERT_MSG(false, "No more available syncpoints!"); |
| 27 | return {}; | 27 | return {}; |
| 28 | } | 28 | } |
| 29 | 29 | ||
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp index fe95d1b73..337431488 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp | |||
| @@ -659,7 +659,7 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) { | |||
| 659 | value = core->consumer_usage_bit; | 659 | value = core->consumer_usage_bit; |
| 660 | break; | 660 | break; |
| 661 | default: | 661 | default: |
| 662 | UNREACHABLE(); | 662 | ASSERT(false); |
| 663 | return Status::BadValue; | 663 | return Status::BadValue; |
| 664 | } | 664 | } |
| 665 | 665 | ||
diff --git a/src/core/hle/service/pctl/pctl_module.cpp b/src/core/hle/service/pctl/pctl_module.cpp index 8d5729003..2a123b42d 100644 --- a/src/core/hle/service/pctl/pctl_module.cpp +++ b/src/core/hle/service/pctl/pctl_module.cpp | |||
| @@ -13,10 +13,10 @@ namespace Service::PCTL { | |||
| 13 | 13 | ||
| 14 | namespace Error { | 14 | namespace Error { |
| 15 | 15 | ||
| 16 | constexpr ResultCode ResultNoFreeCommunication{ErrorModule::PCTL, 101}; | 16 | constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101}; |
| 17 | constexpr ResultCode ResultStereoVisionRestricted{ErrorModule::PCTL, 104}; | 17 | constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104}; |
| 18 | constexpr ResultCode ResultNoCapability{ErrorModule::PCTL, 131}; | 18 | constexpr Result ResultNoCapability{ErrorModule::PCTL, 131}; |
| 19 | constexpr ResultCode ResultNoRestrictionEnabled{ErrorModule::PCTL, 181}; | 19 | constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181}; |
| 20 | 20 | ||
| 21 | } // namespace Error | 21 | } // namespace Error |
| 22 | 22 | ||
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index a8e2a5cbd..b10e86c8f 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp | |||
| @@ -12,12 +12,12 @@ namespace Service::PM { | |||
| 12 | 12 | ||
| 13 | namespace { | 13 | namespace { |
| 14 | 14 | ||
| 15 | constexpr ResultCode ResultProcessNotFound{ErrorModule::PM, 1}; | 15 | constexpr Result ResultProcessNotFound{ErrorModule::PM, 1}; |
| 16 | [[maybe_unused]] constexpr ResultCode ResultAlreadyStarted{ErrorModule::PM, 2}; | 16 | [[maybe_unused]] constexpr Result ResultAlreadyStarted{ErrorModule::PM, 2}; |
| 17 | [[maybe_unused]] constexpr ResultCode ResultNotTerminated{ErrorModule::PM, 3}; | 17 | [[maybe_unused]] constexpr Result ResultNotTerminated{ErrorModule::PM, 3}; |
| 18 | [[maybe_unused]] constexpr ResultCode ResultDebugHookInUse{ErrorModule::PM, 4}; | 18 | [[maybe_unused]] constexpr Result ResultDebugHookInUse{ErrorModule::PM, 4}; |
| 19 | [[maybe_unused]] constexpr ResultCode ResultApplicationRunning{ErrorModule::PM, 5}; | 19 | [[maybe_unused]] constexpr Result ResultApplicationRunning{ErrorModule::PM, 5}; |
| 20 | [[maybe_unused]] constexpr ResultCode ResultInvalidSize{ErrorModule::PM, 6}; | 20 | [[maybe_unused]] constexpr Result ResultInvalidSize{ErrorModule::PM, 6}; |
| 21 | 21 | ||
| 22 | constexpr u64 NO_PROCESS_FOUND_PID{0}; | 22 | constexpr u64 NO_PROCESS_FOUND_PID{0}; |
| 23 | 23 | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 574272b0c..318009e4f 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -190,8 +190,8 @@ void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) { | |||
| 190 | handler_invoker(this, info->handler_callback, ctx); | 190 | handler_invoker(this, info->handler_callback, ctx); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, | 193 | Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, |
| 194 | Kernel::HLERequestContext& ctx) { | 194 | Kernel::HLERequestContext& ctx) { |
| 195 | const auto guard = LockService(); | 195 | const auto guard = LockService(); |
| 196 | 196 | ||
| 197 | switch (ctx.GetCommandType()) { | 197 | switch (ctx.GetCommandType()) { |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index f23e0cd64..5bf197c51 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -79,8 +79,8 @@ public: | |||
| 79 | Kernel::KClientPort& CreatePort(); | 79 | Kernel::KClientPort& CreatePort(); |
| 80 | 80 | ||
| 81 | /// Handles a synchronization request for the service. | 81 | /// Handles a synchronization request for the service. |
| 82 | ResultCode HandleSyncRequest(Kernel::KServerSession& session, | 82 | Result HandleSyncRequest(Kernel::KServerSession& session, |
| 83 | Kernel::HLERequestContext& context) override; | 83 | Kernel::HLERequestContext& context) override; |
| 84 | 84 | ||
| 85 | protected: | 85 | protected: |
| 86 | /// Member-function pointer type of SyncRequest handlers. | 86 | /// Member-function pointer type of SyncRequest handlers. |
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 2839cffcf..f761c2da4 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -74,7 +74,7 @@ constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_la | |||
| 74 | constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; | 74 | constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; |
| 75 | constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; | 75 | constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; |
| 76 | 76 | ||
| 77 | constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; | 77 | constexpr Result ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; |
| 78 | 78 | ||
| 79 | void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_language_codes) { | 79 | void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_language_codes) { |
| 80 | IPC::ResponseBuilder rb{ctx, 3}; | 80 | IPC::ResponseBuilder rb{ctx, 3}; |
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index 87c6f7f85..2a0b812c1 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp | |||
| @@ -32,7 +32,7 @@ void GetFirmwareVersionImpl(Kernel::HLERequestContext& ctx, GetFirmwareVersionTy | |||
| 32 | // consistence (currently reports as 5.1.0-0.0) | 32 | // consistence (currently reports as 5.1.0-0.0) |
| 33 | const auto archive = FileSys::SystemArchive::SystemVersion(); | 33 | const auto archive = FileSys::SystemArchive::SystemVersion(); |
| 34 | 34 | ||
| 35 | const auto early_exit_failure = [&ctx](std::string_view desc, ResultCode code) { | 35 | const auto early_exit_failure = [&ctx](std::string_view desc, Result code) { |
| 36 | LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", | 36 | LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", |
| 37 | desc); | 37 | desc); |
| 38 | IPC::ResponseBuilder rb{ctx, 2}; | 38 | IPC::ResponseBuilder rb{ctx, 2}; |
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 925608875..246c94623 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -17,10 +17,10 @@ | |||
| 17 | 17 | ||
| 18 | namespace Service::SM { | 18 | namespace Service::SM { |
| 19 | 19 | ||
| 20 | constexpr ResultCode ERR_NOT_INITIALIZED(ErrorModule::SM, 2); | 20 | constexpr Result ERR_NOT_INITIALIZED(ErrorModule::SM, 2); |
| 21 | constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::SM, 4); | 21 | constexpr Result ERR_ALREADY_REGISTERED(ErrorModule::SM, 4); |
| 22 | constexpr ResultCode ERR_INVALID_NAME(ErrorModule::SM, 6); | 22 | constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); |
| 23 | constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); | 23 | constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); |
| 24 | 24 | ||
| 25 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} | 25 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} |
| 26 | ServiceManager::~ServiceManager() = default; | 26 | ServiceManager::~ServiceManager() = default; |
| @@ -29,7 +29,7 @@ void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { | |||
| 29 | controller_interface->InvokeRequest(context); | 29 | controller_interface->InvokeRequest(context); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static ResultCode ValidateServiceName(const std::string& name) { | 32 | static Result ValidateServiceName(const std::string& name) { |
| 33 | if (name.empty() || name.size() > 8) { | 33 | if (name.empty() || name.size() > 8) { |
| 34 | LOG_ERROR(Service_SM, "Invalid service name! service={}", name); | 34 | LOG_ERROR(Service_SM, "Invalid service name! service={}", name); |
| 35 | return ERR_INVALID_NAME; | 35 | return ERR_INVALID_NAME; |
| @@ -43,8 +43,8 @@ Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core | |||
| 43 | return self.sm_interface->CreatePort(); | 43 | return self.sm_interface->CreatePort(); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | ResultCode ServiceManager::RegisterService(std::string name, u32 max_sessions, | 46 | Result ServiceManager::RegisterService(std::string name, u32 max_sessions, |
| 47 | Kernel::SessionRequestHandlerPtr handler) { | 47 | Kernel::SessionRequestHandlerPtr handler) { |
| 48 | 48 | ||
| 49 | CASCADE_CODE(ValidateServiceName(name)); | 49 | CASCADE_CODE(ValidateServiceName(name)); |
| 50 | 50 | ||
| @@ -58,7 +58,7 @@ ResultCode ServiceManager::RegisterService(std::string name, u32 max_sessions, | |||
| 58 | return ResultSuccess; | 58 | return ResultSuccess; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | ResultCode ServiceManager::UnregisterService(const std::string& name) { | 61 | Result ServiceManager::UnregisterService(const std::string& name) { |
| 62 | CASCADE_CODE(ValidateServiceName(name)); | 62 | CASCADE_CODE(ValidateServiceName(name)); |
| 63 | 63 | ||
| 64 | const auto iter = registered_services.find(name); | 64 | const auto iter = registered_services.find(name); |
| @@ -94,7 +94,7 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name | |||
| 94 | * Inputs: | 94 | * Inputs: |
| 95 | * 0: 0x00000000 | 95 | * 0: 0x00000000 |
| 96 | * Outputs: | 96 | * Outputs: |
| 97 | * 0: ResultCode | 97 | * 0: Result |
| 98 | */ | 98 | */ |
| 99 | void SM::Initialize(Kernel::HLERequestContext& ctx) { | 99 | void SM::Initialize(Kernel::HLERequestContext& ctx) { |
| 100 | LOG_DEBUG(Service_SM, "called"); | 100 | LOG_DEBUG(Service_SM, "called"); |
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 43d445e97..878decc6f 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -55,9 +55,9 @@ public: | |||
| 55 | explicit ServiceManager(Kernel::KernelCore& kernel_); | 55 | explicit ServiceManager(Kernel::KernelCore& kernel_); |
| 56 | ~ServiceManager(); | 56 | ~ServiceManager(); |
| 57 | 57 | ||
| 58 | ResultCode RegisterService(std::string name, u32 max_sessions, | 58 | Result RegisterService(std::string name, u32 max_sessions, |
| 59 | Kernel::SessionRequestHandlerPtr handler); | 59 | Kernel::SessionRequestHandlerPtr handler); |
| 60 | ResultCode UnregisterService(const std::string& name); | 60 | Result UnregisterService(const std::string& name); |
| 61 | ResultVal<Kernel::KPort*> GetServicePort(const std::string& name); | 61 | ResultVal<Kernel::KPort*> GetServicePort(const std::string& name); |
| 62 | 62 | ||
| 63 | template <Common::DerivedFrom<Kernel::SessionRequestHandler> T> | 63 | template <Common::DerivedFrom<Kernel::SessionRequestHandler> T> |
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index a4ed4193e..2a4bd64ab 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp | |||
| @@ -33,7 +33,7 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { | |||
| 33 | 33 | ||
| 34 | // Create a session. | 34 | // Create a session. |
| 35 | Kernel::KClientSession* session{}; | 35 | Kernel::KClientSession* session{}; |
| 36 | const ResultCode result = parent_port.CreateSession(std::addressof(session), session_manager); | 36 | const Result result = parent_port.CreateSession(std::addressof(session), session_manager); |
| 37 | if (result.IsError()) { | 37 | if (result.IsError()) { |
| 38 | LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw); | 38 | LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw); |
| 39 | IPC::ResponseBuilder rb{ctx, 2}; | 39 | IPC::ResponseBuilder rb{ctx, 2}; |
diff --git a/src/core/hle/service/spl/spl_results.h b/src/core/hle/service/spl/spl_results.h index 17ef655a9..dd7ba11f3 100644 --- a/src/core/hle/service/spl/spl_results.h +++ b/src/core/hle/service/spl/spl_results.h | |||
| @@ -8,23 +8,23 @@ | |||
| 8 | namespace Service::SPL { | 8 | namespace Service::SPL { |
| 9 | 9 | ||
| 10 | // Description 0 - 99 | 10 | // Description 0 - 99 |
| 11 | constexpr ResultCode ResultSecureMonitorError{ErrorModule::SPL, 0}; | 11 | constexpr Result ResultSecureMonitorError{ErrorModule::SPL, 0}; |
| 12 | constexpr ResultCode ResultSecureMonitorNotImplemented{ErrorModule::SPL, 1}; | 12 | constexpr Result ResultSecureMonitorNotImplemented{ErrorModule::SPL, 1}; |
| 13 | constexpr ResultCode ResultSecureMonitorInvalidArgument{ErrorModule::SPL, 2}; | 13 | constexpr Result ResultSecureMonitorInvalidArgument{ErrorModule::SPL, 2}; |
| 14 | constexpr ResultCode ResultSecureMonitorBusy{ErrorModule::SPL, 3}; | 14 | constexpr Result ResultSecureMonitorBusy{ErrorModule::SPL, 3}; |
| 15 | constexpr ResultCode ResultSecureMonitorNoAsyncOperation{ErrorModule::SPL, 4}; | 15 | constexpr Result ResultSecureMonitorNoAsyncOperation{ErrorModule::SPL, 4}; |
| 16 | constexpr ResultCode ResultSecureMonitorInvalidAsyncOperation{ErrorModule::SPL, 5}; | 16 | constexpr Result ResultSecureMonitorInvalidAsyncOperation{ErrorModule::SPL, 5}; |
| 17 | constexpr ResultCode ResultSecureMonitorNotPermitted{ErrorModule::SPL, 6}; | 17 | constexpr Result ResultSecureMonitorNotPermitted{ErrorModule::SPL, 6}; |
| 18 | constexpr ResultCode ResultSecureMonitorNotInitialized{ErrorModule::SPL, 7}; | 18 | constexpr Result ResultSecureMonitorNotInitialized{ErrorModule::SPL, 7}; |
| 19 | 19 | ||
| 20 | constexpr ResultCode ResultInvalidSize{ErrorModule::SPL, 100}; | 20 | constexpr Result ResultInvalidSize{ErrorModule::SPL, 100}; |
| 21 | constexpr ResultCode ResultUnknownSecureMonitorError{ErrorModule::SPL, 101}; | 21 | constexpr Result ResultUnknownSecureMonitorError{ErrorModule::SPL, 101}; |
| 22 | constexpr ResultCode ResultDecryptionFailed{ErrorModule::SPL, 102}; | 22 | constexpr Result ResultDecryptionFailed{ErrorModule::SPL, 102}; |
| 23 | 23 | ||
| 24 | constexpr ResultCode ResultOutOfKeySlots{ErrorModule::SPL, 104}; | 24 | constexpr Result ResultOutOfKeySlots{ErrorModule::SPL, 104}; |
| 25 | constexpr ResultCode ResultInvalidKeySlot{ErrorModule::SPL, 105}; | 25 | constexpr Result ResultInvalidKeySlot{ErrorModule::SPL, 105}; |
| 26 | constexpr ResultCode ResultBootReasonAlreadySet{ErrorModule::SPL, 106}; | 26 | constexpr Result ResultBootReasonAlreadySet{ErrorModule::SPL, 106}; |
| 27 | constexpr ResultCode ResultBootReasonNotSet{ErrorModule::SPL, 107}; | 27 | constexpr Result ResultBootReasonNotSet{ErrorModule::SPL, 107}; |
| 28 | constexpr ResultCode ResultInvalidArgument{ErrorModule::SPL, 108}; | 28 | constexpr Result ResultInvalidArgument{ErrorModule::SPL, 108}; |
| 29 | 29 | ||
| 30 | } // namespace Service::SPL | 30 | } // namespace Service::SPL |
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h index d0af06d94..ef070f32f 100644 --- a/src/core/hle/service/time/clock_types.h +++ b/src/core/hle/service/time/clock_types.h | |||
| @@ -22,7 +22,7 @@ struct SteadyClockTimePoint { | |||
| 22 | s64 time_point; | 22 | s64 time_point; |
| 23 | Common::UUID clock_source_id; | 23 | Common::UUID clock_source_id; |
| 24 | 24 | ||
| 25 | ResultCode GetSpanBetween(SteadyClockTimePoint other, s64& span) const { | 25 | Result GetSpanBetween(SteadyClockTimePoint other, s64& span) const { |
| 26 | span = 0; | 26 | span = 0; |
| 27 | 27 | ||
| 28 | if (clock_source_id != other.clock_source_id) { | 28 | if (clock_source_id != other.clock_source_id) { |
| @@ -92,9 +92,9 @@ struct ClockSnapshot { | |||
| 92 | TimeType type; | 92 | TimeType type; |
| 93 | INSERT_PADDING_BYTES_NOINIT(0x2); | 93 | INSERT_PADDING_BYTES_NOINIT(0x2); |
| 94 | 94 | ||
| 95 | static ResultCode GetCurrentTime(s64& current_time, | 95 | static Result GetCurrentTime(s64& current_time, |
| 96 | const SteadyClockTimePoint& steady_clock_time_point, | 96 | const SteadyClockTimePoint& steady_clock_time_point, |
| 97 | const SystemClockContext& context) { | 97 | const SystemClockContext& context) { |
| 98 | if (steady_clock_time_point.clock_source_id != context.steady_time_point.clock_source_id) { | 98 | if (steady_clock_time_point.clock_source_id != context.steady_time_point.clock_source_id) { |
| 99 | current_time = 0; | 99 | current_time = 0; |
| 100 | return ERROR_TIME_MISMATCH; | 100 | return ERROR_TIME_MISMATCH; |
diff --git a/src/core/hle/service/time/errors.h b/src/core/hle/service/time/errors.h index 592921f6b..6655d30e1 100644 --- a/src/core/hle/service/time/errors.h +++ b/src/core/hle/service/time/errors.h | |||
| @@ -7,15 +7,15 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Time { | 8 | namespace Service::Time { |
| 9 | 9 | ||
| 10 | constexpr ResultCode ERROR_PERMISSION_DENIED{ErrorModule::Time, 1}; | 10 | constexpr Result ERROR_PERMISSION_DENIED{ErrorModule::Time, 1}; |
| 11 | constexpr ResultCode ERROR_TIME_MISMATCH{ErrorModule::Time, 102}; | 11 | constexpr Result ERROR_TIME_MISMATCH{ErrorModule::Time, 102}; |
| 12 | constexpr ResultCode ERROR_UNINITIALIZED_CLOCK{ErrorModule::Time, 103}; | 12 | constexpr Result ERROR_UNINITIALIZED_CLOCK{ErrorModule::Time, 103}; |
| 13 | constexpr ResultCode ERROR_TIME_NOT_FOUND{ErrorModule::Time, 200}; | 13 | constexpr Result ERROR_TIME_NOT_FOUND{ErrorModule::Time, 200}; |
| 14 | constexpr ResultCode ERROR_OVERFLOW{ErrorModule::Time, 201}; | 14 | constexpr Result ERROR_OVERFLOW{ErrorModule::Time, 201}; |
| 15 | constexpr ResultCode ERROR_LOCATION_NAME_TOO_LONG{ErrorModule::Time, 801}; | 15 | constexpr Result ERROR_LOCATION_NAME_TOO_LONG{ErrorModule::Time, 801}; |
| 16 | constexpr ResultCode ERROR_OUT_OF_RANGE{ErrorModule::Time, 902}; | 16 | constexpr Result ERROR_OUT_OF_RANGE{ErrorModule::Time, 902}; |
| 17 | constexpr ResultCode ERROR_TIME_ZONE_CONVERSION_FAILED{ErrorModule::Time, 903}; | 17 | constexpr Result ERROR_TIME_ZONE_CONVERSION_FAILED{ErrorModule::Time, 903}; |
| 18 | constexpr ResultCode ERROR_TIME_ZONE_NOT_FOUND{ErrorModule::Time, 989}; | 18 | constexpr Result ERROR_TIME_ZONE_NOT_FOUND{ErrorModule::Time, 989}; |
| 19 | constexpr ResultCode ERROR_NOT_IMPLEMENTED{ErrorModule::Time, 990}; | 19 | constexpr Result ERROR_NOT_IMPLEMENTED{ErrorModule::Time, 990}; |
| 20 | 20 | ||
| 21 | } // namespace Service::Time | 21 | } // namespace Service::Time |
diff --git a/src/core/hle/service/time/local_system_clock_context_writer.h b/src/core/hle/service/time/local_system_clock_context_writer.h index 0977806b3..1639ef2b9 100644 --- a/src/core/hle/service/time/local_system_clock_context_writer.h +++ b/src/core/hle/service/time/local_system_clock_context_writer.h | |||
| @@ -14,7 +14,7 @@ public: | |||
| 14 | : SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {} | 14 | : SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {} |
| 15 | 15 | ||
| 16 | protected: | 16 | protected: |
| 17 | ResultCode Update() override { | 17 | Result Update() override { |
| 18 | shared_memory.UpdateLocalSystemClockContext(context); | 18 | shared_memory.UpdateLocalSystemClockContext(context); |
| 19 | return ResultSuccess; | 19 | return ResultSuccess; |
| 20 | } | 20 | } |
diff --git a/src/core/hle/service/time/network_system_clock_context_writer.h b/src/core/hle/service/time/network_system_clock_context_writer.h index 975089af8..655e4c06d 100644 --- a/src/core/hle/service/time/network_system_clock_context_writer.h +++ b/src/core/hle/service/time/network_system_clock_context_writer.h | |||
| @@ -15,7 +15,7 @@ public: | |||
| 15 | : SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {} | 15 | : SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {} |
| 16 | 16 | ||
| 17 | protected: | 17 | protected: |
| 18 | ResultCode Update() override { | 18 | Result Update() override { |
| 19 | shared_memory.UpdateNetworkSystemClockContext(context); | 19 | shared_memory.UpdateNetworkSystemClockContext(context); |
| 20 | return ResultSuccess; | 20 | return ResultSuccess; |
| 21 | } | 21 | } |
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp index f0cc9a155..b033757ed 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp | |||
| @@ -27,9 +27,9 @@ StandardUserSystemClockCore::~StandardUserSystemClockCore() { | |||
| 27 | service_context.CloseEvent(auto_correction_event); | 27 | service_context.CloseEvent(auto_correction_event); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, | 30 | Result StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, |
| 31 | bool value) { | 31 | bool value) { |
| 32 | if (const ResultCode result{ApplyAutomaticCorrection(system, value)}; result != ResultSuccess) { | 32 | if (const Result result{ApplyAutomaticCorrection(system, value)}; result != ResultSuccess) { |
| 33 | return result; | 33 | return result; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| @@ -38,27 +38,27 @@ ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::Syst | |||
| 38 | return ResultSuccess; | 38 | return ResultSuccess; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | ResultCode StandardUserSystemClockCore::GetClockContext(Core::System& system, | 41 | Result StandardUserSystemClockCore::GetClockContext(Core::System& system, |
| 42 | SystemClockContext& ctx) const { | 42 | SystemClockContext& ctx) const { |
| 43 | if (const ResultCode result{ApplyAutomaticCorrection(system, false)}; result != ResultSuccess) { | 43 | if (const Result result{ApplyAutomaticCorrection(system, false)}; result != ResultSuccess) { |
| 44 | return result; | 44 | return result; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | return local_system_clock_core.GetClockContext(system, ctx); | 47 | return local_system_clock_core.GetClockContext(system, ctx); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | ResultCode StandardUserSystemClockCore::Flush(const SystemClockContext&) { | 50 | Result StandardUserSystemClockCore::Flush(const SystemClockContext&) { |
| 51 | UNREACHABLE(); | 51 | UNIMPLEMENTED(); |
| 52 | return ERROR_NOT_IMPLEMENTED; | 52 | return ERROR_NOT_IMPLEMENTED; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | ResultCode StandardUserSystemClockCore::SetClockContext(const SystemClockContext&) { | 55 | Result StandardUserSystemClockCore::SetClockContext(const SystemClockContext&) { |
| 56 | UNREACHABLE(); | 56 | UNIMPLEMENTED(); |
| 57 | return ERROR_NOT_IMPLEMENTED; | 57 | return ERROR_NOT_IMPLEMENTED; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | ResultCode StandardUserSystemClockCore::ApplyAutomaticCorrection(Core::System& system, | 60 | Result StandardUserSystemClockCore::ApplyAutomaticCorrection(Core::System& system, |
| 61 | bool value) const { | 61 | bool value) const { |
| 62 | if (auto_correction_enabled == value) { | 62 | if (auto_correction_enabled == value) { |
| 63 | return ResultSuccess; | 63 | return ResultSuccess; |
| 64 | } | 64 | } |
| @@ -68,7 +68,7 @@ ResultCode StandardUserSystemClockCore::ApplyAutomaticCorrection(Core::System& s | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | SystemClockContext ctx{}; | 70 | SystemClockContext ctx{}; |
| 71 | if (const ResultCode result{network_system_clock_core.GetClockContext(system, ctx)}; | 71 | if (const Result result{network_system_clock_core.GetClockContext(system, ctx)}; |
| 72 | result != ResultSuccess) { | 72 | result != ResultSuccess) { |
| 73 | return result; | 73 | return result; |
| 74 | } | 74 | } |
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h index 22df23b29..ee6e29487 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.h +++ b/src/core/hle/service/time/standard_user_system_clock_core.h | |||
| @@ -28,9 +28,9 @@ public: | |||
| 28 | 28 | ||
| 29 | ~StandardUserSystemClockCore() override; | 29 | ~StandardUserSystemClockCore() override; |
| 30 | 30 | ||
| 31 | ResultCode SetAutomaticCorrectionEnabled(Core::System& system, bool value); | 31 | Result SetAutomaticCorrectionEnabled(Core::System& system, bool value); |
| 32 | 32 | ||
| 33 | ResultCode GetClockContext(Core::System& system, SystemClockContext& ctx) const override; | 33 | Result GetClockContext(Core::System& system, SystemClockContext& ctx) const override; |
| 34 | 34 | ||
| 35 | bool IsAutomaticCorrectionEnabled() const { | 35 | bool IsAutomaticCorrectionEnabled() const { |
| 36 | return auto_correction_enabled; | 36 | return auto_correction_enabled; |
| @@ -41,11 +41,11 @@ public: | |||
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | protected: | 43 | protected: |
| 44 | ResultCode Flush(const SystemClockContext&) override; | 44 | Result Flush(const SystemClockContext&) override; |
| 45 | 45 | ||
| 46 | ResultCode SetClockContext(const SystemClockContext&) override; | 46 | Result SetClockContext(const SystemClockContext&) override; |
| 47 | 47 | ||
| 48 | ResultCode ApplyAutomaticCorrection(Core::System& system, bool value) const; | 48 | Result ApplyAutomaticCorrection(Core::System& system, bool value) const; |
| 49 | 49 | ||
| 50 | const SteadyClockTimePoint& GetAutomaticCorrectionUpdatedTime() const { | 50 | const SteadyClockTimePoint& GetAutomaticCorrectionUpdatedTime() const { |
| 51 | return auto_correction_time; | 51 | return auto_correction_time; |
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.cpp b/src/core/hle/service/time/system_clock_context_update_callback.cpp index 37c140c6f..a649bed3a 100644 --- a/src/core/hle/service/time/system_clock_context_update_callback.cpp +++ b/src/core/hle/service/time/system_clock_context_update_callback.cpp | |||
| @@ -30,8 +30,8 @@ void SystemClockContextUpdateCallback::BroadcastOperationEvent() { | |||
| 30 | } | 30 | } |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | ResultCode SystemClockContextUpdateCallback::Update(const SystemClockContext& value) { | 33 | Result SystemClockContextUpdateCallback::Update(const SystemClockContext& value) { |
| 34 | ResultCode result{ResultSuccess}; | 34 | Result result{ResultSuccess}; |
| 35 | 35 | ||
| 36 | if (NeedUpdate(value)) { | 36 | if (NeedUpdate(value)) { |
| 37 | context = value; | 37 | context = value; |
| @@ -47,7 +47,7 @@ ResultCode SystemClockContextUpdateCallback::Update(const SystemClockContext& va | |||
| 47 | return result; | 47 | return result; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | ResultCode SystemClockContextUpdateCallback::Update() { | 50 | Result SystemClockContextUpdateCallback::Update() { |
| 51 | return ResultSuccess; | 51 | return ResultSuccess; |
| 52 | } | 52 | } |
| 53 | 53 | ||
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h index bee90e329..9c6caf196 100644 --- a/src/core/hle/service/time/system_clock_context_update_callback.h +++ b/src/core/hle/service/time/system_clock_context_update_callback.h | |||
| @@ -28,10 +28,10 @@ public: | |||
| 28 | 28 | ||
| 29 | void BroadcastOperationEvent(); | 29 | void BroadcastOperationEvent(); |
| 30 | 30 | ||
| 31 | ResultCode Update(const SystemClockContext& value); | 31 | Result Update(const SystemClockContext& value); |
| 32 | 32 | ||
| 33 | protected: | 33 | protected: |
| 34 | virtual ResultCode Update(); | 34 | virtual Result Update(); |
| 35 | 35 | ||
| 36 | SystemClockContext context{}; | 36 | SystemClockContext context{}; |
| 37 | 37 | ||
diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp index cb132239c..da078241f 100644 --- a/src/core/hle/service/time/system_clock_core.cpp +++ b/src/core/hle/service/time/system_clock_core.cpp | |||
| @@ -14,13 +14,13 @@ SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core_) | |||
| 14 | 14 | ||
| 15 | SystemClockCore::~SystemClockCore() = default; | 15 | SystemClockCore::~SystemClockCore() = default; |
| 16 | 16 | ||
| 17 | ResultCode SystemClockCore::GetCurrentTime(Core::System& system, s64& posix_time) const { | 17 | Result SystemClockCore::GetCurrentTime(Core::System& system, s64& posix_time) const { |
| 18 | posix_time = 0; | 18 | posix_time = 0; |
| 19 | 19 | ||
| 20 | const SteadyClockTimePoint current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; | 20 | const SteadyClockTimePoint current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; |
| 21 | 21 | ||
| 22 | SystemClockContext clock_context{}; | 22 | SystemClockContext clock_context{}; |
| 23 | if (const ResultCode result{GetClockContext(system, clock_context)}; result != ResultSuccess) { | 23 | if (const Result result{GetClockContext(system, clock_context)}; result != ResultSuccess) { |
| 24 | return result; | 24 | return result; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| @@ -33,26 +33,26 @@ ResultCode SystemClockCore::GetCurrentTime(Core::System& system, s64& posix_time | |||
| 33 | return ResultSuccess; | 33 | return ResultSuccess; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | ResultCode SystemClockCore::SetCurrentTime(Core::System& system, s64 posix_time) { | 36 | Result SystemClockCore::SetCurrentTime(Core::System& system, s64 posix_time) { |
| 37 | const SteadyClockTimePoint current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; | 37 | const SteadyClockTimePoint current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; |
| 38 | const SystemClockContext clock_context{posix_time - current_time_point.time_point, | 38 | const SystemClockContext clock_context{posix_time - current_time_point.time_point, |
| 39 | current_time_point}; | 39 | current_time_point}; |
| 40 | 40 | ||
| 41 | if (const ResultCode result{SetClockContext(clock_context)}; result != ResultSuccess) { | 41 | if (const Result result{SetClockContext(clock_context)}; result != ResultSuccess) { |
| 42 | return result; | 42 | return result; |
| 43 | } | 43 | } |
| 44 | return Flush(clock_context); | 44 | return Flush(clock_context); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | ResultCode SystemClockCore::Flush(const SystemClockContext& clock_context) { | 47 | Result SystemClockCore::Flush(const SystemClockContext& clock_context) { |
| 48 | if (!system_clock_context_update_callback) { | 48 | if (!system_clock_context_update_callback) { |
| 49 | return ResultSuccess; | 49 | return ResultSuccess; |
| 50 | } | 50 | } |
| 51 | return system_clock_context_update_callback->Update(clock_context); | 51 | return system_clock_context_update_callback->Update(clock_context); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | ResultCode SystemClockCore::SetSystemClockContext(const SystemClockContext& clock_context) { | 54 | Result SystemClockCore::SetSystemClockContext(const SystemClockContext& clock_context) { |
| 55 | if (const ResultCode result{SetClockContext(clock_context)}; result != ResultSuccess) { | 55 | if (const Result result{SetClockContext(clock_context)}; result != ResultSuccess) { |
| 56 | return result; | 56 | return result; |
| 57 | } | 57 | } |
| 58 | return Flush(clock_context); | 58 | return Flush(clock_context); |
diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h index 76d82f976..8cb34126f 100644 --- a/src/core/hle/service/time/system_clock_core.h +++ b/src/core/hle/service/time/system_clock_core.h | |||
| @@ -29,28 +29,28 @@ public: | |||
| 29 | return steady_clock_core; | 29 | return steady_clock_core; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | ResultCode GetCurrentTime(Core::System& system, s64& posix_time) const; | 32 | Result GetCurrentTime(Core::System& system, s64& posix_time) const; |
| 33 | 33 | ||
| 34 | ResultCode SetCurrentTime(Core::System& system, s64 posix_time); | 34 | Result SetCurrentTime(Core::System& system, s64 posix_time); |
| 35 | 35 | ||
| 36 | virtual ResultCode GetClockContext([[maybe_unused]] Core::System& system, | 36 | virtual Result GetClockContext([[maybe_unused]] Core::System& system, |
| 37 | SystemClockContext& value) const { | 37 | SystemClockContext& value) const { |
| 38 | value = context; | 38 | value = context; |
| 39 | return ResultSuccess; | 39 | return ResultSuccess; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | virtual ResultCode SetClockContext(const SystemClockContext& value) { | 42 | virtual Result SetClockContext(const SystemClockContext& value) { |
| 43 | context = value; | 43 | context = value; |
| 44 | return ResultSuccess; | 44 | return ResultSuccess; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | virtual ResultCode Flush(const SystemClockContext& clock_context); | 47 | virtual Result Flush(const SystemClockContext& clock_context); |
| 48 | 48 | ||
| 49 | void SetUpdateCallbackInstance(std::shared_ptr<SystemClockContextUpdateCallback> callback) { | 49 | void SetUpdateCallbackInstance(std::shared_ptr<SystemClockContextUpdateCallback> callback) { |
| 50 | system_clock_context_update_callback = std::move(callback); | 50 | system_clock_context_update_callback = std::move(callback); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | ResultCode SetSystemClockContext(const SystemClockContext& context); | 53 | Result SetSystemClockContext(const SystemClockContext& context); |
| 54 | 54 | ||
| 55 | bool IsInitialized() const { | 55 | bool IsInitialized() const { |
| 56 | return is_initialized; | 56 | return is_initialized; |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 095fa021c..f77cdbb43 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -43,8 +43,7 @@ private: | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | s64 posix_time{}; | 45 | s64 posix_time{}; |
| 46 | if (const ResultCode result{clock_core.GetCurrentTime(system, posix_time)}; | 46 | if (const Result result{clock_core.GetCurrentTime(system, posix_time)}; result.IsError()) { |
| 47 | result.IsError()) { | ||
| 48 | IPC::ResponseBuilder rb{ctx, 2}; | 47 | IPC::ResponseBuilder rb{ctx, 2}; |
| 49 | rb.Push(result); | 48 | rb.Push(result); |
| 50 | return; | 49 | return; |
| @@ -65,7 +64,7 @@ private: | |||
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | Clock::SystemClockContext system_clock_context{}; | 66 | Clock::SystemClockContext system_clock_context{}; |
| 68 | if (const ResultCode result{clock_core.GetClockContext(system, system_clock_context)}; | 67 | if (const Result result{clock_core.GetClockContext(system, system_clock_context)}; |
| 69 | result.IsError()) { | 68 | result.IsError()) { |
| 70 | IPC::ResponseBuilder rb{ctx, 2}; | 69 | IPC::ResponseBuilder rb{ctx, 2}; |
| 71 | rb.Push(result); | 70 | rb.Push(result); |
| @@ -116,7 +115,7 @@ private: | |||
| 116 | Clock::SteadyClockCore& clock_core; | 115 | Clock::SteadyClockCore& clock_core; |
| 117 | }; | 116 | }; |
| 118 | 117 | ||
| 119 | ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | 118 | Result Module::Interface::GetClockSnapshotFromSystemClockContextInternal( |
| 120 | Kernel::KThread* thread, Clock::SystemClockContext user_context, | 119 | Kernel::KThread* thread, Clock::SystemClockContext user_context, |
| 121 | Clock::SystemClockContext network_context, Clock::TimeType type, | 120 | Clock::SystemClockContext network_context, Clock::TimeType type, |
| 122 | Clock::ClockSnapshot& clock_snapshot) { | 121 | Clock::ClockSnapshot& clock_snapshot) { |
| @@ -129,7 +128,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 129 | time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); | 128 | time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); |
| 130 | clock_snapshot.type = type; | 129 | clock_snapshot.type = type; |
| 131 | 130 | ||
| 132 | if (const ResultCode result{ | 131 | if (const Result result{ |
| 133 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().GetDeviceLocationName( | 132 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().GetDeviceLocationName( |
| 134 | clock_snapshot.location_name)}; | 133 | clock_snapshot.location_name)}; |
| 135 | result != ResultSuccess) { | 134 | result != ResultSuccess) { |
| @@ -138,7 +137,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 138 | 137 | ||
| 139 | clock_snapshot.user_context = user_context; | 138 | clock_snapshot.user_context = user_context; |
| 140 | 139 | ||
| 141 | if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime( | 140 | if (const Result result{Clock::ClockSnapshot::GetCurrentTime( |
| 142 | clock_snapshot.user_time, clock_snapshot.steady_clock_time_point, | 141 | clock_snapshot.user_time, clock_snapshot.steady_clock_time_point, |
| 143 | clock_snapshot.user_context)}; | 142 | clock_snapshot.user_context)}; |
| 144 | result != ResultSuccess) { | 143 | result != ResultSuccess) { |
| @@ -146,7 +145,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | TimeZone::CalendarInfo userCalendarInfo{}; | 147 | TimeZone::CalendarInfo userCalendarInfo{}; |
| 149 | if (const ResultCode result{ | 148 | if (const Result result{ |
| 150 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().ToCalendarTimeWithMyRules( | 149 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().ToCalendarTimeWithMyRules( |
| 151 | clock_snapshot.user_time, userCalendarInfo)}; | 150 | clock_snapshot.user_time, userCalendarInfo)}; |
| 152 | result != ResultSuccess) { | 151 | result != ResultSuccess) { |
| @@ -165,7 +164,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( | |||
| 165 | } | 164 | } |
| 166 | 165 | ||
| 167 | TimeZone::CalendarInfo networkCalendarInfo{}; | 166 | TimeZone::CalendarInfo networkCalendarInfo{}; |
| 168 | if (const ResultCode result{ | 167 | if (const Result result{ |
| 169 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().ToCalendarTimeWithMyRules( | 168 | time_manager.GetTimeZoneContentManager().GetTimeZoneManager().ToCalendarTimeWithMyRules( |
| 170 | clock_snapshot.network_time, networkCalendarInfo)}; | 169 | clock_snapshot.network_time, networkCalendarInfo)}; |
| 171 | result != ResultSuccess) { | 170 | result != ResultSuccess) { |
| @@ -262,7 +261,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | |||
| 262 | LOG_DEBUG(Service_Time, "called, type={}", type); | 261 | LOG_DEBUG(Service_Time, "called, type={}", type); |
| 263 | 262 | ||
| 264 | Clock::SystemClockContext user_context{}; | 263 | Clock::SystemClockContext user_context{}; |
| 265 | if (const ResultCode result{ | 264 | if (const Result result{ |
| 266 | system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system, | 265 | system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system, |
| 267 | user_context)}; | 266 | user_context)}; |
| 268 | result.IsError()) { | 267 | result.IsError()) { |
| @@ -272,7 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | |||
| 272 | } | 271 | } |
| 273 | 272 | ||
| 274 | Clock::SystemClockContext network_context{}; | 273 | Clock::SystemClockContext network_context{}; |
| 275 | if (const ResultCode result{ | 274 | if (const Result result{ |
| 276 | system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( | 275 | system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( |
| 277 | system, network_context)}; | 276 | system, network_context)}; |
| 278 | result.IsError()) { | 277 | result.IsError()) { |
| @@ -282,7 +281,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { | |||
| 282 | } | 281 | } |
| 283 | 282 | ||
| 284 | Clock::ClockSnapshot clock_snapshot{}; | 283 | Clock::ClockSnapshot clock_snapshot{}; |
| 285 | if (const ResultCode result{GetClockSnapshotFromSystemClockContextInternal( | 284 | if (const Result result{GetClockSnapshotFromSystemClockContextInternal( |
| 286 | &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; | 285 | &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; |
| 287 | result.IsError()) { | 286 | result.IsError()) { |
| 288 | IPC::ResponseBuilder rb{ctx, 2}; | 287 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -308,7 +307,7 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques | |||
| 308 | LOG_DEBUG(Service_Time, "called, type={}", type); | 307 | LOG_DEBUG(Service_Time, "called, type={}", type); |
| 309 | 308 | ||
| 310 | Clock::ClockSnapshot clock_snapshot{}; | 309 | Clock::ClockSnapshot clock_snapshot{}; |
| 311 | if (const ResultCode result{GetClockSnapshotFromSystemClockContextInternal( | 310 | if (const Result result{GetClockSnapshotFromSystemClockContextInternal( |
| 312 | &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; | 311 | &ctx.GetThread(), user_context, network_context, type, clock_snapshot)}; |
| 313 | result != ResultSuccess) { | 312 | result != ResultSuccess) { |
| 314 | IPC::ResponseBuilder rb{ctx, 2}; | 313 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -365,7 +364,7 @@ void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { | |||
| 365 | Clock::TimeSpanType time_span_type{}; | 364 | Clock::TimeSpanType time_span_type{}; |
| 366 | s64 span{}; | 365 | s64 span{}; |
| 367 | 366 | ||
| 368 | if (const ResultCode result{snapshot_a.steady_clock_time_point.GetSpanBetween( | 367 | if (const Result result{snapshot_a.steady_clock_time_point.GetSpanBetween( |
| 369 | snapshot_b.steady_clock_time_point, span)}; | 368 | snapshot_b.steady_clock_time_point, span)}; |
| 370 | result != ResultSuccess) { | 369 | result != ResultSuccess) { |
| 371 | if (snapshot_a.network_time && snapshot_b.network_time) { | 370 | if (snapshot_a.network_time && snapshot_b.network_time) { |
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 017f20a23..76a46cfc7 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h | |||
| @@ -36,7 +36,7 @@ public: | |||
| 36 | void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); | 36 | void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); |
| 37 | 37 | ||
| 38 | private: | 38 | private: |
| 39 | ResultCode GetClockSnapshotFromSystemClockContextInternal( | 39 | Result GetClockSnapshotFromSystemClockContextInternal( |
| 40 | Kernel::KThread* thread, Clock::SystemClockContext user_context, | 40 | Kernel::KThread* thread, Clock::SystemClockContext user_context, |
| 41 | Clock::SystemClockContext network_context, Clock::TimeType type, | 41 | Clock::SystemClockContext network_context, Clock::TimeType type, |
| 42 | Clock::ClockSnapshot& cloc_snapshot); | 42 | Clock::ClockSnapshot& cloc_snapshot); |
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index acc038dbf..28667710e 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp | |||
| @@ -111,7 +111,7 @@ struct TimeManager::Impl final { | |||
| 111 | FileSys::VirtualFile& vfs_file) { | 111 | FileSys::VirtualFile& vfs_file) { |
| 112 | if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule( | 112 | if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule( |
| 113 | location_name, vfs_file) != ResultSuccess) { | 113 | location_name, vfs_file) != ResultSuccess) { |
| 114 | UNREACHABLE(); | 114 | ASSERT(false); |
| 115 | return; | 115 | return; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| @@ -155,7 +155,7 @@ struct TimeManager::Impl final { | |||
| 155 | } else { | 155 | } else { |
| 156 | if (standard_local_system_clock_core.SetCurrentTime(system_, posix_time) != | 156 | if (standard_local_system_clock_core.SetCurrentTime(system_, posix_time) != |
| 157 | ResultSuccess) { | 157 | ResultSuccess) { |
| 158 | UNREACHABLE(); | 158 | ASSERT(false); |
| 159 | return; | 159 | return; |
| 160 | } | 160 | } |
| 161 | } | 161 | } |
| @@ -170,7 +170,7 @@ struct TimeManager::Impl final { | |||
| 170 | 170 | ||
| 171 | if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != | 171 | if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != |
| 172 | ResultSuccess) { | 172 | ResultSuccess) { |
| 173 | UNREACHABLE(); | 173 | ASSERT(false); |
| 174 | return; | 174 | return; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| @@ -183,7 +183,7 @@ struct TimeManager::Impl final { | |||
| 183 | Clock::SteadyClockTimePoint steady_clock_time_point) { | 183 | Clock::SteadyClockTimePoint steady_clock_time_point) { |
| 184 | if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( | 184 | if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( |
| 185 | system_, is_automatic_correction_enabled) != ResultSuccess) { | 185 | system_, is_automatic_correction_enabled) != ResultSuccess) { |
| 186 | UNREACHABLE(); | 186 | ASSERT(false); |
| 187 | return; | 187 | return; |
| 188 | } | 188 | } |
| 189 | 189 | ||
| @@ -203,7 +203,7 @@ struct TimeManager::Impl final { | |||
| 203 | if (GetStandardLocalSystemClockCore() | 203 | if (GetStandardLocalSystemClockCore() |
| 204 | .SetCurrentTime(system_, timespan.ToSeconds()) | 204 | .SetCurrentTime(system_, timespan.ToSeconds()) |
| 205 | .IsError()) { | 205 | .IsError()) { |
| 206 | UNREACHABLE(); | 206 | ASSERT(false); |
| 207 | return; | 207 | return; |
| 208 | } | 208 | } |
| 209 | } | 209 | } |
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp index 80818eb70..afbfe9715 100644 --- a/src/core/hle/service/time/time_zone_content_manager.cpp +++ b/src/core/hle/service/time/time_zone_content_manager.cpp | |||
| @@ -90,10 +90,10 @@ void TimeZoneContentManager::Initialize(TimeManager& time_manager) { | |||
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | ResultCode TimeZoneContentManager::LoadTimeZoneRule(TimeZoneRule& rules, | 93 | Result TimeZoneContentManager::LoadTimeZoneRule(TimeZoneRule& rules, |
| 94 | const std::string& location_name) const { | 94 | const std::string& location_name) const { |
| 95 | FileSys::VirtualFile vfs_file; | 95 | FileSys::VirtualFile vfs_file; |
| 96 | if (const ResultCode result{GetTimeZoneInfoFile(location_name, vfs_file)}; | 96 | if (const Result result{GetTimeZoneInfoFile(location_name, vfs_file)}; |
| 97 | result != ResultSuccess) { | 97 | result != ResultSuccess) { |
| 98 | return result; | 98 | return result; |
| 99 | } | 99 | } |
| @@ -106,8 +106,8 @@ bool TimeZoneContentManager::IsLocationNameValid(const std::string& location_nam | |||
| 106 | location_name_cache.end(); | 106 | location_name_cache.end(); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | ResultCode TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& location_name, | 109 | Result TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& location_name, |
| 110 | FileSys::VirtualFile& vfs_file) const { | 110 | FileSys::VirtualFile& vfs_file) const { |
| 111 | if (!IsLocationNameValid(location_name)) { | 111 | if (!IsLocationNameValid(location_name)) { |
| 112 | return ERROR_TIME_NOT_FOUND; | 112 | return ERROR_TIME_NOT_FOUND; |
| 113 | } | 113 | } |
diff --git a/src/core/hle/service/time/time_zone_content_manager.h b/src/core/hle/service/time/time_zone_content_manager.h index c6c94bcc0..3d94b6428 100644 --- a/src/core/hle/service/time/time_zone_content_manager.h +++ b/src/core/hle/service/time/time_zone_content_manager.h | |||
| @@ -32,12 +32,12 @@ public: | |||
| 32 | return time_zone_manager; | 32 | return time_zone_manager; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | ResultCode LoadTimeZoneRule(TimeZoneRule& rules, const std::string& location_name) const; | 35 | Result LoadTimeZoneRule(TimeZoneRule& rules, const std::string& location_name) const; |
| 36 | 36 | ||
| 37 | private: | 37 | private: |
| 38 | bool IsLocationNameValid(const std::string& location_name) const; | 38 | bool IsLocationNameValid(const std::string& location_name) const; |
| 39 | ResultCode GetTimeZoneInfoFile(const std::string& location_name, | 39 | Result GetTimeZoneInfoFile(const std::string& location_name, |
| 40 | FileSys::VirtualFile& vfs_file) const; | 40 | FileSys::VirtualFile& vfs_file) const; |
| 41 | 41 | ||
| 42 | Core::System& system; | 42 | Core::System& system; |
| 43 | TimeZoneManager time_zone_manager; | 43 | TimeZoneManager time_zone_manager; |
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index eeec34436..2aa675df9 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -279,7 +279,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) { | |||
| 279 | break; | 279 | break; |
| 280 | } | 280 | } |
| 281 | default: | 281 | default: |
| 282 | UNREACHABLE(); | 282 | ASSERT(false); |
| 283 | } | 283 | } |
| 284 | return value + rule.transition_time + offset; | 284 | return value + rule.transition_time + offset; |
| 285 | } | 285 | } |
| @@ -666,8 +666,8 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi | |||
| 666 | return true; | 666 | return true; |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | static ResultCode CreateCalendarTime(s64 time, int gmt_offset, CalendarTimeInternal& calendar_time, | 669 | static Result CreateCalendarTime(s64 time, int gmt_offset, CalendarTimeInternal& calendar_time, |
| 670 | CalendarAdditionalInfo& calendar_additional_info) { | 670 | CalendarAdditionalInfo& calendar_additional_info) { |
| 671 | s64 year{epoch_year}; | 671 | s64 year{epoch_year}; |
| 672 | s64 time_days{time / seconds_per_day}; | 672 | s64 time_days{time / seconds_per_day}; |
| 673 | s64 remaining_seconds{time % seconds_per_day}; | 673 | s64 remaining_seconds{time % seconds_per_day}; |
| @@ -741,9 +741,9 @@ static ResultCode CreateCalendarTime(s64 time, int gmt_offset, CalendarTimeInter | |||
| 741 | return ResultSuccess; | 741 | return ResultSuccess; |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | 744 | static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, |
| 745 | CalendarTimeInternal& calendar_time, | 745 | CalendarTimeInternal& calendar_time, |
| 746 | CalendarAdditionalInfo& calendar_additional_info) { | 746 | CalendarAdditionalInfo& calendar_additional_info) { |
| 747 | if ((rules.go_ahead && time < rules.ats[0]) || | 747 | if ((rules.go_ahead && time < rules.ats[0]) || |
| 748 | (rules.go_back && time > rules.ats[rules.time_count - 1])) { | 748 | (rules.go_back && time > rules.ats[rules.time_count - 1])) { |
| 749 | s64 seconds{}; | 749 | s64 seconds{}; |
| @@ -766,7 +766,7 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | |||
| 766 | if (new_time < rules.ats[0] && new_time > rules.ats[rules.time_count - 1]) { | 766 | if (new_time < rules.ats[0] && new_time > rules.ats[rules.time_count - 1]) { |
| 767 | return ERROR_TIME_NOT_FOUND; | 767 | return ERROR_TIME_NOT_FOUND; |
| 768 | } | 768 | } |
| 769 | if (const ResultCode result{ | 769 | if (const Result result{ |
| 770 | ToCalendarTimeInternal(rules, new_time, calendar_time, calendar_additional_info)}; | 770 | ToCalendarTimeInternal(rules, new_time, calendar_time, calendar_additional_info)}; |
| 771 | result != ResultSuccess) { | 771 | result != ResultSuccess) { |
| 772 | return result; | 772 | return result; |
| @@ -797,8 +797,8 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | |||
| 797 | tti_index = rules.types[low - 1]; | 797 | tti_index = rules.types[low - 1]; |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | if (const ResultCode result{CreateCalendarTime(time, rules.ttis[tti_index].gmt_offset, | 800 | if (const Result result{CreateCalendarTime(time, rules.ttis[tti_index].gmt_offset, |
| 801 | calendar_time, calendar_additional_info)}; | 801 | calendar_time, calendar_additional_info)}; |
| 802 | result != ResultSuccess) { | 802 | result != ResultSuccess) { |
| 803 | return result; | 803 | return result; |
| 804 | } | 804 | } |
| @@ -811,9 +811,9 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | |||
| 811 | return ResultSuccess; | 811 | return ResultSuccess; |
| 812 | } | 812 | } |
| 813 | 813 | ||
| 814 | static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) { | 814 | static Result ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) { |
| 815 | CalendarTimeInternal calendar_time{}; | 815 | CalendarTimeInternal calendar_time{}; |
| 816 | const ResultCode result{ | 816 | const Result result{ |
| 817 | ToCalendarTimeInternal(rules, time, calendar_time, calendar.additional_info)}; | 817 | ToCalendarTimeInternal(rules, time, calendar_time, calendar.additional_info)}; |
| 818 | calendar.time.year = static_cast<s16>(calendar_time.year); | 818 | calendar.time.year = static_cast<s16>(calendar_time.year); |
| 819 | 819 | ||
| @@ -830,13 +830,13 @@ static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, Calend | |||
| 830 | TimeZoneManager::TimeZoneManager() = default; | 830 | TimeZoneManager::TimeZoneManager() = default; |
| 831 | TimeZoneManager::~TimeZoneManager() = default; | 831 | TimeZoneManager::~TimeZoneManager() = default; |
| 832 | 832 | ||
| 833 | ResultCode TimeZoneManager::ToCalendarTime(const TimeZoneRule& rules, s64 time, | 833 | Result TimeZoneManager::ToCalendarTime(const TimeZoneRule& rules, s64 time, |
| 834 | CalendarInfo& calendar) const { | 834 | CalendarInfo& calendar) const { |
| 835 | return ToCalendarTimeImpl(rules, time, calendar); | 835 | return ToCalendarTimeImpl(rules, time, calendar); |
| 836 | } | 836 | } |
| 837 | 837 | ||
| 838 | ResultCode TimeZoneManager::SetDeviceLocationNameWithTimeZoneRule(const std::string& location_name, | 838 | Result TimeZoneManager::SetDeviceLocationNameWithTimeZoneRule(const std::string& location_name, |
| 839 | FileSys::VirtualFile& vfs_file) { | 839 | FileSys::VirtualFile& vfs_file) { |
| 840 | TimeZoneRule rule{}; | 840 | TimeZoneRule rule{}; |
| 841 | if (ParseTimeZoneBinary(rule, vfs_file)) { | 841 | if (ParseTimeZoneBinary(rule, vfs_file)) { |
| 842 | device_location_name = location_name; | 842 | device_location_name = location_name; |
| @@ -846,12 +846,12 @@ ResultCode TimeZoneManager::SetDeviceLocationNameWithTimeZoneRule(const std::str | |||
| 846 | return ERROR_TIME_ZONE_CONVERSION_FAILED; | 846 | return ERROR_TIME_ZONE_CONVERSION_FAILED; |
| 847 | } | 847 | } |
| 848 | 848 | ||
| 849 | ResultCode TimeZoneManager::SetUpdatedTime(const Clock::SteadyClockTimePoint& value) { | 849 | Result TimeZoneManager::SetUpdatedTime(const Clock::SteadyClockTimePoint& value) { |
| 850 | time_zone_update_time_point = value; | 850 | time_zone_update_time_point = value; |
| 851 | return ResultSuccess; | 851 | return ResultSuccess; |
| 852 | } | 852 | } |
| 853 | 853 | ||
| 854 | ResultCode TimeZoneManager::ToCalendarTimeWithMyRules(s64 time, CalendarInfo& calendar) const { | 854 | Result TimeZoneManager::ToCalendarTimeWithMyRules(s64 time, CalendarInfo& calendar) const { |
| 855 | if (is_initialized) { | 855 | if (is_initialized) { |
| 856 | return ToCalendarTime(time_zone_rule, time, calendar); | 856 | return ToCalendarTime(time_zone_rule, time, calendar); |
| 857 | } else { | 857 | } else { |
| @@ -859,16 +859,16 @@ ResultCode TimeZoneManager::ToCalendarTimeWithMyRules(s64 time, CalendarInfo& ca | |||
| 859 | } | 859 | } |
| 860 | } | 860 | } |
| 861 | 861 | ||
| 862 | ResultCode TimeZoneManager::ParseTimeZoneRuleBinary(TimeZoneRule& rules, | 862 | Result TimeZoneManager::ParseTimeZoneRuleBinary(TimeZoneRule& rules, |
| 863 | FileSys::VirtualFile& vfs_file) const { | 863 | FileSys::VirtualFile& vfs_file) const { |
| 864 | if (!ParseTimeZoneBinary(rules, vfs_file)) { | 864 | if (!ParseTimeZoneBinary(rules, vfs_file)) { |
| 865 | return ERROR_TIME_ZONE_CONVERSION_FAILED; | 865 | return ERROR_TIME_ZONE_CONVERSION_FAILED; |
| 866 | } | 866 | } |
| 867 | return ResultSuccess; | 867 | return ResultSuccess; |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | ResultCode TimeZoneManager::ToPosixTime(const TimeZoneRule& rules, | 870 | Result TimeZoneManager::ToPosixTime(const TimeZoneRule& rules, const CalendarTime& calendar_time, |
| 871 | const CalendarTime& calendar_time, s64& posix_time) const { | 871 | s64& posix_time) const { |
| 872 | posix_time = 0; | 872 | posix_time = 0; |
| 873 | 873 | ||
| 874 | CalendarTimeInternal internal_time{ | 874 | CalendarTimeInternal internal_time{ |
| @@ -1020,8 +1020,8 @@ ResultCode TimeZoneManager::ToPosixTime(const TimeZoneRule& rules, | |||
| 1020 | return ResultSuccess; | 1020 | return ResultSuccess; |
| 1021 | } | 1021 | } |
| 1022 | 1022 | ||
| 1023 | ResultCode TimeZoneManager::ToPosixTimeWithMyRule(const CalendarTime& calendar_time, | 1023 | Result TimeZoneManager::ToPosixTimeWithMyRule(const CalendarTime& calendar_time, |
| 1024 | s64& posix_time) const { | 1024 | s64& posix_time) const { |
| 1025 | if (is_initialized) { | 1025 | if (is_initialized) { |
| 1026 | return ToPosixTime(time_zone_rule, calendar_time, posix_time); | 1026 | return ToPosixTime(time_zone_rule, calendar_time, posix_time); |
| 1027 | } | 1027 | } |
| @@ -1029,7 +1029,7 @@ ResultCode TimeZoneManager::ToPosixTimeWithMyRule(const CalendarTime& calendar_t | |||
| 1029 | return ERROR_UNINITIALIZED_CLOCK; | 1029 | return ERROR_UNINITIALIZED_CLOCK; |
| 1030 | } | 1030 | } |
| 1031 | 1031 | ||
| 1032 | ResultCode TimeZoneManager::GetDeviceLocationName(LocationName& value) const { | 1032 | Result TimeZoneManager::GetDeviceLocationName(LocationName& value) const { |
| 1033 | if (!is_initialized) { | 1033 | if (!is_initialized) { |
| 1034 | return ERROR_UNINITIALIZED_CLOCK; | 1034 | return ERROR_UNINITIALIZED_CLOCK; |
| 1035 | } | 1035 | } |
diff --git a/src/core/hle/service/time/time_zone_manager.h b/src/core/hle/service/time/time_zone_manager.h index 8c1b19f81..5ebd4035e 100644 --- a/src/core/hle/service/time/time_zone_manager.h +++ b/src/core/hle/service/time/time_zone_manager.h | |||
| @@ -29,16 +29,16 @@ public: | |||
| 29 | is_initialized = true; | 29 | is_initialized = true; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | ResultCode SetDeviceLocationNameWithTimeZoneRule(const std::string& location_name, | 32 | Result SetDeviceLocationNameWithTimeZoneRule(const std::string& location_name, |
| 33 | FileSys::VirtualFile& vfs_file); | 33 | FileSys::VirtualFile& vfs_file); |
| 34 | ResultCode SetUpdatedTime(const Clock::SteadyClockTimePoint& value); | 34 | Result SetUpdatedTime(const Clock::SteadyClockTimePoint& value); |
| 35 | ResultCode GetDeviceLocationName(TimeZone::LocationName& value) const; | 35 | Result GetDeviceLocationName(TimeZone::LocationName& value) const; |
| 36 | ResultCode ToCalendarTime(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) const; | 36 | Result ToCalendarTime(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) const; |
| 37 | ResultCode ToCalendarTimeWithMyRules(s64 time, CalendarInfo& calendar) const; | 37 | Result ToCalendarTimeWithMyRules(s64 time, CalendarInfo& calendar) const; |
| 38 | ResultCode ParseTimeZoneRuleBinary(TimeZoneRule& rules, FileSys::VirtualFile& vfs_file) const; | 38 | Result ParseTimeZoneRuleBinary(TimeZoneRule& rules, FileSys::VirtualFile& vfs_file) const; |
| 39 | ResultCode ToPosixTime(const TimeZoneRule& rules, const CalendarTime& calendar_time, | 39 | Result ToPosixTime(const TimeZoneRule& rules, const CalendarTime& calendar_time, |
| 40 | s64& posix_time) const; | 40 | s64& posix_time) const; |
| 41 | ResultCode ToPosixTimeWithMyRule(const CalendarTime& calendar_time, s64& posix_time) const; | 41 | Result ToPosixTimeWithMyRule(const CalendarTime& calendar_time, s64& posix_time) const; |
| 42 | 42 | ||
| 43 | private: | 43 | private: |
| 44 | bool is_initialized{}; | 44 | bool is_initialized{}; |
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp index cbf0ef6fa..961040bfc 100644 --- a/src/core/hle/service/time/time_zone_service.cpp +++ b/src/core/hle/service/time/time_zone_service.cpp | |||
| @@ -32,7 +32,7 @@ void ITimeZoneService::GetDeviceLocationName(Kernel::HLERequestContext& ctx) { | |||
| 32 | LOG_DEBUG(Service_Time, "called"); | 32 | LOG_DEBUG(Service_Time, "called"); |
| 33 | 33 | ||
| 34 | TimeZone::LocationName location_name{}; | 34 | TimeZone::LocationName location_name{}; |
| 35 | if (const ResultCode result{ | 35 | if (const Result result{ |
| 36 | time_zone_content_manager.GetTimeZoneManager().GetDeviceLocationName(location_name)}; | 36 | time_zone_content_manager.GetTimeZoneManager().GetDeviceLocationName(location_name)}; |
| 37 | result != ResultSuccess) { | 37 | result != ResultSuccess) { |
| 38 | IPC::ResponseBuilder rb{ctx, 2}; | 38 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -61,7 +61,7 @@ void ITimeZoneService::LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { | |||
| 61 | LOG_DEBUG(Service_Time, "called, location_name={}", location_name); | 61 | LOG_DEBUG(Service_Time, "called, location_name={}", location_name); |
| 62 | 62 | ||
| 63 | TimeZone::TimeZoneRule time_zone_rule{}; | 63 | TimeZone::TimeZoneRule time_zone_rule{}; |
| 64 | if (const ResultCode result{ | 64 | if (const Result result{ |
| 65 | time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)}; | 65 | time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)}; |
| 66 | result != ResultSuccess) { | 66 | result != ResultSuccess) { |
| 67 | IPC::ResponseBuilder rb{ctx, 2}; | 67 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -88,7 +88,7 @@ void ITimeZoneService::ToCalendarTime(Kernel::HLERequestContext& ctx) { | |||
| 88 | std::memcpy(&time_zone_rule, buffer.data(), buffer.size()); | 88 | std::memcpy(&time_zone_rule, buffer.data(), buffer.size()); |
| 89 | 89 | ||
| 90 | TimeZone::CalendarInfo calendar_info{}; | 90 | TimeZone::CalendarInfo calendar_info{}; |
| 91 | if (const ResultCode result{time_zone_content_manager.GetTimeZoneManager().ToCalendarTime( | 91 | if (const Result result{time_zone_content_manager.GetTimeZoneManager().ToCalendarTime( |
| 92 | time_zone_rule, posix_time, calendar_info)}; | 92 | time_zone_rule, posix_time, calendar_info)}; |
| 93 | result != ResultSuccess) { | 93 | result != ResultSuccess) { |
| 94 | IPC::ResponseBuilder rb{ctx, 2}; | 94 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -108,7 +108,7 @@ void ITimeZoneService::ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) | |||
| 108 | LOG_DEBUG(Service_Time, "called, posix_time=0x{:016X}", posix_time); | 108 | LOG_DEBUG(Service_Time, "called, posix_time=0x{:016X}", posix_time); |
| 109 | 109 | ||
| 110 | TimeZone::CalendarInfo calendar_info{}; | 110 | TimeZone::CalendarInfo calendar_info{}; |
| 111 | if (const ResultCode result{ | 111 | if (const Result result{ |
| 112 | time_zone_content_manager.GetTimeZoneManager().ToCalendarTimeWithMyRules( | 112 | time_zone_content_manager.GetTimeZoneManager().ToCalendarTimeWithMyRules( |
| 113 | posix_time, calendar_info)}; | 113 | posix_time, calendar_info)}; |
| 114 | result != ResultSuccess) { | 114 | result != ResultSuccess) { |
| @@ -131,7 +131,7 @@ void ITimeZoneService::ToPosixTime(Kernel::HLERequestContext& ctx) { | |||
| 131 | std::memcpy(&time_zone_rule, ctx.ReadBuffer().data(), sizeof(TimeZone::TimeZoneRule)); | 131 | std::memcpy(&time_zone_rule, ctx.ReadBuffer().data(), sizeof(TimeZone::TimeZoneRule)); |
| 132 | 132 | ||
| 133 | s64 posix_time{}; | 133 | s64 posix_time{}; |
| 134 | if (const ResultCode result{time_zone_content_manager.GetTimeZoneManager().ToPosixTime( | 134 | if (const Result result{time_zone_content_manager.GetTimeZoneManager().ToPosixTime( |
| 135 | time_zone_rule, calendar_time, posix_time)}; | 135 | time_zone_rule, calendar_time, posix_time)}; |
| 136 | result != ResultSuccess) { | 136 | result != ResultSuccess) { |
| 137 | IPC::ResponseBuilder rb{ctx, 2}; | 137 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -154,9 +154,8 @@ void ITimeZoneService::ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx) { | |||
| 154 | const auto calendar_time{rp.PopRaw<TimeZone::CalendarTime>()}; | 154 | const auto calendar_time{rp.PopRaw<TimeZone::CalendarTime>()}; |
| 155 | 155 | ||
| 156 | s64 posix_time{}; | 156 | s64 posix_time{}; |
| 157 | if (const ResultCode result{ | 157 | if (const Result result{time_zone_content_manager.GetTimeZoneManager().ToPosixTimeWithMyRule( |
| 158 | time_zone_content_manager.GetTimeZoneManager().ToPosixTimeWithMyRule(calendar_time, | 158 | calendar_time, posix_time)}; |
| 159 | posix_time)}; | ||
| 160 | result != ResultSuccess) { | 159 | result != ResultSuccess) { |
| 161 | IPC::ResponseBuilder rb{ctx, 2}; | 160 | IPC::ResponseBuilder rb{ctx, 2}; |
| 162 | rb.Push(result); | 161 | rb.Push(result); |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index a7b53d7dc..546879648 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -34,10 +34,10 @@ | |||
| 34 | 34 | ||
| 35 | namespace Service::VI { | 35 | namespace Service::VI { |
| 36 | 36 | ||
| 37 | constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1}; | 37 | constexpr Result ERR_OPERATION_FAILED{ErrorModule::VI, 1}; |
| 38 | constexpr ResultCode ERR_PERMISSION_DENIED{ErrorModule::VI, 5}; | 38 | constexpr Result ERR_PERMISSION_DENIED{ErrorModule::VI, 5}; |
| 39 | constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6}; | 39 | constexpr Result ERR_UNSUPPORTED{ErrorModule::VI, 6}; |
| 40 | constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7}; | 40 | constexpr Result ERR_NOT_FOUND{ErrorModule::VI, 7}; |
| 41 | 41 | ||
| 42 | struct DisplayInfo { | 42 | struct DisplayInfo { |
| 43 | /// The name of this particular display. | 43 | /// The name of this particular display. |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 8a938aa83..8dd956fc6 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -128,11 +128,10 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: | |||
| 128 | 128 | ||
| 129 | // Apply patches if necessary | 129 | // Apply patches if necessary |
| 130 | if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) { | 130 | if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) { |
| 131 | std::vector<u8> pi_header; | 131 | std::vector<u8> pi_header(sizeof(NSOHeader) + program_image.size()); |
| 132 | pi_header.insert(pi_header.begin(), reinterpret_cast<u8*>(&nso_header), | 132 | std::memcpy(pi_header.data(), &nso_header, sizeof(NSOHeader)); |
| 133 | reinterpret_cast<u8*>(&nso_header) + sizeof(NSOHeader)); | 133 | std::memcpy(pi_header.data() + sizeof(NSOHeader), program_image.data(), |
| 134 | pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.data(), | 134 | program_image.size()); |
| 135 | program_image.data() + program_image.size()); | ||
| 136 | 135 | ||
| 137 | pi_header = pm->PatchNSO(pi_header, nso_file.GetName()); | 136 | pi_header = pm->PatchNSO(pi_header, nso_file.GetName()); |
| 138 | 137 | ||
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7534de01e..584808d50 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -67,6 +67,16 @@ struct Memory::Impl { | |||
| 67 | return system.DeviceMemory().GetPointer(paddr) + vaddr; | 67 | return system.DeviceMemory().GetPointer(paddr) + vaddr; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | [[nodiscard]] u8* GetPointerFromDebugMemory(VAddr vaddr) const { | ||
| 71 | const PAddr paddr{current_page_table->backing_addr[vaddr >> PAGE_BITS]}; | ||
| 72 | |||
| 73 | if (paddr == 0) { | ||
| 74 | return {}; | ||
| 75 | } | ||
| 76 | |||
| 77 | return system.DeviceMemory().GetPointer(paddr) + vaddr; | ||
| 78 | } | ||
| 79 | |||
| 70 | u8 Read8(const VAddr addr) { | 80 | u8 Read8(const VAddr addr) { |
| 71 | return Read<u8>(addr); | 81 | return Read<u8>(addr); |
| 72 | } | 82 | } |
| @@ -187,6 +197,12 @@ struct Memory::Impl { | |||
| 187 | on_memory(copy_amount, mem_ptr); | 197 | on_memory(copy_amount, mem_ptr); |
| 188 | break; | 198 | break; |
| 189 | } | 199 | } |
| 200 | case Common::PageType::DebugMemory: { | ||
| 201 | DEBUG_ASSERT(pointer); | ||
| 202 | u8* const mem_ptr{GetPointerFromDebugMemory(current_vaddr)}; | ||
| 203 | on_memory(copy_amount, mem_ptr); | ||
| 204 | break; | ||
| 205 | } | ||
| 190 | case Common::PageType::RasterizerCachedMemory: { | 206 | case Common::PageType::RasterizerCachedMemory: { |
| 191 | u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)}; | 207 | u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)}; |
| 192 | on_rasterizer(current_vaddr, copy_amount, host_ptr); | 208 | on_rasterizer(current_vaddr, copy_amount, host_ptr); |
| @@ -316,6 +332,58 @@ struct Memory::Impl { | |||
| 316 | }); | 332 | }); |
| 317 | } | 333 | } |
| 318 | 334 | ||
| 335 | void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { | ||
| 336 | if (vaddr == 0) { | ||
| 337 | return; | ||
| 338 | } | ||
| 339 | |||
| 340 | // Iterate over a contiguous CPU address space, marking/unmarking the region. | ||
| 341 | // The region is at a granularity of CPU pages. | ||
| 342 | |||
| 343 | const u64 num_pages = ((vaddr + size - 1) >> PAGE_BITS) - (vaddr >> PAGE_BITS) + 1; | ||
| 344 | for (u64 i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { | ||
| 345 | const Common::PageType page_type{ | ||
| 346 | current_page_table->pointers[vaddr >> PAGE_BITS].Type()}; | ||
| 347 | if (debug) { | ||
| 348 | // Switch page type to debug if now debug | ||
| 349 | switch (page_type) { | ||
| 350 | case Common::PageType::Unmapped: | ||
| 351 | ASSERT_MSG(false, "Attempted to mark unmapped pages as debug"); | ||
| 352 | break; | ||
| 353 | case Common::PageType::RasterizerCachedMemory: | ||
| 354 | case Common::PageType::DebugMemory: | ||
| 355 | // Page is already marked. | ||
| 356 | break; | ||
| 357 | case Common::PageType::Memory: | ||
| 358 | current_page_table->pointers[vaddr >> PAGE_BITS].Store( | ||
| 359 | nullptr, Common::PageType::DebugMemory); | ||
| 360 | break; | ||
| 361 | default: | ||
| 362 | UNREACHABLE(); | ||
| 363 | } | ||
| 364 | } else { | ||
| 365 | // Switch page type to non-debug if now non-debug | ||
| 366 | switch (page_type) { | ||
| 367 | case Common::PageType::Unmapped: | ||
| 368 | ASSERT_MSG(false, "Attempted to mark unmapped pages as non-debug"); | ||
| 369 | break; | ||
| 370 | case Common::PageType::RasterizerCachedMemory: | ||
| 371 | case Common::PageType::Memory: | ||
| 372 | // Don't mess with already non-debug or rasterizer memory. | ||
| 373 | break; | ||
| 374 | case Common::PageType::DebugMemory: { | ||
| 375 | u8* const pointer{GetPointerFromDebugMemory(vaddr & ~PAGE_MASK)}; | ||
| 376 | current_page_table->pointers[vaddr >> PAGE_BITS].Store( | ||
| 377 | pointer - (vaddr & ~PAGE_MASK), Common::PageType::Memory); | ||
| 378 | break; | ||
| 379 | } | ||
| 380 | default: | ||
| 381 | UNREACHABLE(); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 319 | void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | 387 | void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { |
| 320 | if (vaddr == 0) { | 388 | if (vaddr == 0) { |
| 321 | return; | 389 | return; |
| @@ -342,6 +410,7 @@ struct Memory::Impl { | |||
| 342 | // It is not necessary for a process to have this region mapped into its address | 410 | // It is not necessary for a process to have this region mapped into its address |
| 343 | // space, for example, a system module need not have a VRAM mapping. | 411 | // space, for example, a system module need not have a VRAM mapping. |
| 344 | break; | 412 | break; |
| 413 | case Common::PageType::DebugMemory: | ||
| 345 | case Common::PageType::Memory: | 414 | case Common::PageType::Memory: |
| 346 | current_page_table->pointers[vaddr >> PAGE_BITS].Store( | 415 | current_page_table->pointers[vaddr >> PAGE_BITS].Store( |
| 347 | nullptr, Common::PageType::RasterizerCachedMemory); | 416 | nullptr, Common::PageType::RasterizerCachedMemory); |
| @@ -360,6 +429,7 @@ struct Memory::Impl { | |||
| 360 | // It is not necessary for a process to have this region mapped into its address | 429 | // It is not necessary for a process to have this region mapped into its address |
| 361 | // space, for example, a system module need not have a VRAM mapping. | 430 | // space, for example, a system module need not have a VRAM mapping. |
| 362 | break; | 431 | break; |
| 432 | case Common::PageType::DebugMemory: | ||
| 363 | case Common::PageType::Memory: | 433 | case Common::PageType::Memory: |
| 364 | // There can be more than one GPU region mapped per CPU region, so it's common | 434 | // There can be more than one GPU region mapped per CPU region, so it's common |
| 365 | // that this area is already unmarked as cached. | 435 | // that this area is already unmarked as cached. |
| @@ -460,6 +530,8 @@ struct Memory::Impl { | |||
| 460 | case Common::PageType::Memory: | 530 | case Common::PageType::Memory: |
| 461 | ASSERT_MSG(false, "Mapped memory page without a pointer @ 0x{:016X}", vaddr); | 531 | ASSERT_MSG(false, "Mapped memory page without a pointer @ 0x{:016X}", vaddr); |
| 462 | return nullptr; | 532 | return nullptr; |
| 533 | case Common::PageType::DebugMemory: | ||
| 534 | return GetPointerFromDebugMemory(vaddr); | ||
| 463 | case Common::PageType::RasterizerCachedMemory: { | 535 | case Common::PageType::RasterizerCachedMemory: { |
| 464 | u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; | 536 | u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; |
| 465 | on_rasterizer(); | 537 | on_rasterizer(); |
| @@ -591,7 +663,8 @@ bool Memory::IsValidVirtualAddress(const VAddr vaddr) const { | |||
| 591 | return false; | 663 | return false; |
| 592 | } | 664 | } |
| 593 | const auto [pointer, type] = page_table.pointers[page].PointerType(); | 665 | const auto [pointer, type] = page_table.pointers[page].PointerType(); |
| 594 | return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory; | 666 | return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory || |
| 667 | type == Common::PageType::DebugMemory; | ||
| 595 | } | 668 | } |
| 596 | 669 | ||
| 597 | bool Memory::IsValidVirtualAddressRange(VAddr base, u64 size) const { | 670 | bool Memory::IsValidVirtualAddressRange(VAddr base, u64 size) const { |
| @@ -707,4 +780,8 @@ void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | |||
| 707 | impl->RasterizerMarkRegionCached(vaddr, size, cached); | 780 | impl->RasterizerMarkRegionCached(vaddr, size, cached); |
| 708 | } | 781 | } |
| 709 | 782 | ||
| 783 | void Memory::MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { | ||
| 784 | impl->MarkRegionDebug(vaddr, size, debug); | ||
| 785 | } | ||
| 786 | |||
| 710 | } // namespace Core::Memory | 787 | } // namespace Core::Memory |
diff --git a/src/core/memory.h b/src/core/memory.h index 58cc27b29..f22c0a2d8 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -446,6 +446,17 @@ public: | |||
| 446 | */ | 446 | */ |
| 447 | void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); | 447 | void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); |
| 448 | 448 | ||
| 449 | /** | ||
| 450 | * Marks each page within the specified address range as debug or non-debug. | ||
| 451 | * Debug addresses are not accessible from fastmem pointers. | ||
| 452 | * | ||
| 453 | * @param vaddr The virtual address indicating the start of the address range. | ||
| 454 | * @param size The size of the address range in bytes. | ||
| 455 | * @param debug Whether or not any pages within the address range should be | ||
| 456 | * marked as debug or non-debug. | ||
| 457 | */ | ||
| 458 | void MarkRegionDebug(VAddr vaddr, u64 size, bool debug); | ||
| 459 | |||
| 449 | private: | 460 | private: |
| 450 | Core::System& system; | 461 | Core::System& system; |
| 451 | 462 | ||
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index fa2729f54..6e21296f6 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp | |||
| @@ -63,7 +63,7 @@ json GetYuzuVersionData() { | |||
| 63 | }; | 63 | }; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | json GetReportCommonData(u64 title_id, ResultCode result, const std::string& timestamp, | 66 | json GetReportCommonData(u64 title_id, Result result, const std::string& timestamp, |
| 67 | std::optional<u128> user_id = {}) { | 67 | std::optional<u128> user_id = {}) { |
| 68 | auto out = json{ | 68 | auto out = json{ |
| 69 | {"title_id", fmt::format("{:016X}", title_id)}, | 69 | {"title_id", fmt::format("{:016X}", title_id)}, |
| @@ -198,8 +198,8 @@ Reporter::Reporter(System& system_) : system(system_) { | |||
| 198 | 198 | ||
| 199 | Reporter::~Reporter() = default; | 199 | Reporter::~Reporter() = default; |
| 200 | 200 | ||
| 201 | void Reporter::SaveCrashReport(u64 title_id, ResultCode result, u64 set_flags, u64 entry_point, | 201 | void Reporter::SaveCrashReport(u64 title_id, Result result, u64 set_flags, u64 entry_point, u64 sp, |
| 202 | u64 sp, u64 pc, u64 pstate, u64 afsr0, u64 afsr1, u64 esr, u64 far, | 202 | u64 pc, u64 pstate, u64 afsr0, u64 afsr1, u64 esr, u64 far, |
| 203 | const std::array<u64, 31>& registers, | 203 | const std::array<u64, 31>& registers, |
| 204 | const std::array<u64, 32>& backtrace, u32 backtrace_size, | 204 | const std::array<u64, 32>& backtrace, u32 backtrace_size, |
| 205 | const std::string& arch, u32 unk10) const { | 205 | const std::string& arch, u32 unk10) const { |
| @@ -338,7 +338,7 @@ void Reporter::SavePlayReport(PlayReportType type, u64 title_id, std::vector<std | |||
| 338 | SaveToFile(std::move(out), GetPath("play_report", title_id, timestamp)); | 338 | SaveToFile(std::move(out), GetPath("play_report", title_id, timestamp)); |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | void Reporter::SaveErrorReport(u64 title_id, ResultCode result, | 341 | void Reporter::SaveErrorReport(u64 title_id, Result result, |
| 342 | std::optional<std::string> custom_text_main, | 342 | std::optional<std::string> custom_text_main, |
| 343 | std::optional<std::string> custom_text_detail) const { | 343 | std::optional<std::string> custom_text_detail) const { |
| 344 | if (!IsReportingEnabled()) { | 344 | if (!IsReportingEnabled()) { |
diff --git a/src/core/reporter.h b/src/core/reporter.h index a5386bc83..68755cbde 100644 --- a/src/core/reporter.h +++ b/src/core/reporter.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | 11 | ||
| 12 | union ResultCode; | 12 | union Result; |
| 13 | 13 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | class HLERequestContext; | 15 | class HLERequestContext; |
| @@ -29,7 +29,7 @@ public: | |||
| 29 | ~Reporter(); | 29 | ~Reporter(); |
| 30 | 30 | ||
| 31 | // Used by fatal services | 31 | // Used by fatal services |
| 32 | void SaveCrashReport(u64 title_id, ResultCode result, u64 set_flags, u64 entry_point, u64 sp, | 32 | void SaveCrashReport(u64 title_id, Result result, u64 set_flags, u64 entry_point, u64 sp, |
| 33 | u64 pc, u64 pstate, u64 afsr0, u64 afsr1, u64 esr, u64 far, | 33 | u64 pc, u64 pstate, u64 afsr0, u64 afsr1, u64 esr, u64 far, |
| 34 | const std::array<u64, 31>& registers, const std::array<u64, 32>& backtrace, | 34 | const std::array<u64, 31>& registers, const std::array<u64, 32>& backtrace, |
| 35 | u32 backtrace_size, const std::string& arch, u32 unk10) const; | 35 | u32 backtrace_size, const std::string& arch, u32 unk10) const; |
| @@ -60,7 +60,7 @@ public: | |||
| 60 | std::optional<u64> process_id = {}, std::optional<u128> user_id = {}) const; | 60 | std::optional<u64> process_id = {}, std::optional<u128> user_id = {}) const; |
| 61 | 61 | ||
| 62 | // Used by error applet | 62 | // Used by error applet |
| 63 | void SaveErrorReport(u64 title_id, ResultCode result, | 63 | void SaveErrorReport(u64 title_id, Result result, |
| 64 | std::optional<std::string> custom_text_main = {}, | 64 | std::optional<std::string> custom_text_main = {}, |
| 65 | std::optional<std::string> custom_text_detail = {}) const; | 65 | std::optional<std::string> custom_text_detail = {}) const; |
| 66 | 66 | ||
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp index 7a0b73eca..5cc99fbe4 100644 --- a/src/core/tools/freezer.cpp +++ b/src/core/tools/freezer.cpp | |||
| @@ -25,7 +25,6 @@ u64 MemoryReadWidth(Core::Memory::Memory& memory, u32 width, VAddr addr) { | |||
| 25 | return memory.Read64(addr); | 25 | return memory.Read64(addr); |
| 26 | default: | 26 | default: |
| 27 | UNREACHABLE(); | 27 | UNREACHABLE(); |
| 28 | return 0; | ||
| 29 | } | 28 | } |
| 30 | } | 29 | } |
| 31 | 30 | ||
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index d4fa69a77..48e799cf5 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt | |||
| @@ -44,7 +44,6 @@ else() | |||
| 44 | -Werror | 44 | -Werror |
| 45 | -Werror=conversion | 45 | -Werror=conversion |
| 46 | -Werror=ignored-qualifiers | 46 | -Werror=ignored-qualifiers |
| 47 | -Werror=shadow | ||
| 48 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 47 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
| 49 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> | 48 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> |
| 50 | -Werror=unused-variable | 49 | -Werror=unused-variable |
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 1a14ef10b..446c027d3 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -13,11 +13,11 @@ | |||
| 13 | namespace InputCommon { | 13 | namespace InputCommon { |
| 14 | 14 | ||
| 15 | namespace { | 15 | namespace { |
| 16 | std::string GetGUID(SDL_Joystick* joystick) { | 16 | Common::UUID GetGUID(SDL_Joystick* joystick) { |
| 17 | const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); | 17 | const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); |
| 18 | char guid_str[33]; | 18 | std::array<u8, 16> data{}; |
| 19 | SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); | 19 | std::memcpy(data.data(), guid.data, sizeof(data)); |
| 20 | return guid_str; | 20 | return Common::UUID{data}; |
| 21 | } | 21 | } |
| 22 | } // Anonymous namespace | 22 | } // Anonymous namespace |
| 23 | 23 | ||
| @@ -31,9 +31,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) { | |||
| 31 | 31 | ||
| 32 | class SDLJoystick { | 32 | class SDLJoystick { |
| 33 | public: | 33 | public: |
| 34 | SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, | 34 | SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, |
| 35 | SDL_GameController* game_controller) | 35 | SDL_GameController* game_controller) |
| 36 | : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, | 36 | : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, |
| 37 | sdl_controller{game_controller, &SDL_GameControllerClose} { | 37 | sdl_controller{game_controller, &SDL_GameControllerClose} { |
| 38 | EnableMotion(); | 38 | EnableMotion(); |
| 39 | } | 39 | } |
| @@ -120,7 +120,7 @@ public: | |||
| 120 | */ | 120 | */ |
| 121 | const PadIdentifier GetPadIdentifier() const { | 121 | const PadIdentifier GetPadIdentifier() const { |
| 122 | return { | 122 | return { |
| 123 | .guid = Common::UUID{guid}, | 123 | .guid = guid, |
| 124 | .port = static_cast<std::size_t>(port), | 124 | .port = static_cast<std::size_t>(port), |
| 125 | .pad = 0, | 125 | .pad = 0, |
| 126 | }; | 126 | }; |
| @@ -129,7 +129,7 @@ public: | |||
| 129 | /** | 129 | /** |
| 130 | * The guid of the joystick | 130 | * The guid of the joystick |
| 131 | */ | 131 | */ |
| 132 | const std::string& GetGUID() const { | 132 | const Common::UUID& GetGUID() const { |
| 133 | return guid; | 133 | return guid; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| @@ -228,7 +228,7 @@ public: | |||
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | private: | 230 | private: |
| 231 | std::string guid; | 231 | Common::UUID guid; |
| 232 | int port; | 232 | int port; |
| 233 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | 233 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
| 234 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; | 234 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
| @@ -240,7 +240,7 @@ private: | |||
| 240 | BasicMotion motion; | 240 | BasicMotion motion; |
| 241 | }; | 241 | }; |
| 242 | 242 | ||
| 243 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& guid, int port) { | 243 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const Common::UUID& guid, int port) { |
| 244 | std::scoped_lock lock{joystick_map_mutex}; | 244 | std::scoped_lock lock{joystick_map_mutex}; |
| 245 | const auto it = joystick_map.find(guid); | 245 | const auto it = joystick_map.find(guid); |
| 246 | 246 | ||
| @@ -259,9 +259,13 @@ std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& | |||
| 259 | return joystick_map[guid].emplace_back(std::move(joystick)); | 259 | return joystick_map[guid].emplace_back(std::move(joystick)); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& guid, int port) { | ||
| 263 | return GetSDLJoystickByGUID(Common::UUID{guid}, port); | ||
| 264 | } | ||
| 265 | |||
| 262 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { | 266 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { |
| 263 | auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); | 267 | auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); |
| 264 | const std::string guid = GetGUID(sdl_joystick); | 268 | const auto guid = GetGUID(sdl_joystick); |
| 265 | 269 | ||
| 266 | std::scoped_lock lock{joystick_map_mutex}; | 270 | std::scoped_lock lock{joystick_map_mutex}; |
| 267 | const auto map_it = joystick_map.find(guid); | 271 | const auto map_it = joystick_map.find(guid); |
| @@ -295,7 +299,7 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 295 | return; | 299 | return; |
| 296 | } | 300 | } |
| 297 | 301 | ||
| 298 | const std::string guid = GetGUID(sdl_joystick); | 302 | const auto guid = GetGUID(sdl_joystick); |
| 299 | 303 | ||
| 300 | std::scoped_lock lock{joystick_map_mutex}; | 304 | std::scoped_lock lock{joystick_map_mutex}; |
| 301 | if (joystick_map.find(guid) == joystick_map.end()) { | 305 | if (joystick_map.find(guid) == joystick_map.end()) { |
| @@ -324,7 +328,7 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 324 | } | 328 | } |
| 325 | 329 | ||
| 326 | void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) { | 330 | void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) { |
| 327 | const std::string guid = GetGUID(sdl_joystick); | 331 | const auto guid = GetGUID(sdl_joystick); |
| 328 | 332 | ||
| 329 | std::scoped_lock lock{joystick_map_mutex}; | 333 | std::scoped_lock lock{joystick_map_mutex}; |
| 330 | // This call to guid is safe since the joystick is guaranteed to be in the map | 334 | // This call to guid is safe since the joystick is guaranteed to be in the map |
| @@ -470,7 +474,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||
| 470 | devices.emplace_back(Common::ParamPackage{ | 474 | devices.emplace_back(Common::ParamPackage{ |
| 471 | {"engine", GetEngineName()}, | 475 | {"engine", GetEngineName()}, |
| 472 | {"display", std::move(name)}, | 476 | {"display", std::move(name)}, |
| 473 | {"guid", joystick->GetGUID()}, | 477 | {"guid", joystick->GetGUID().RawString()}, |
| 474 | {"port", std::to_string(joystick->GetPort())}, | 478 | {"port", std::to_string(joystick->GetPort())}, |
| 475 | }); | 479 | }); |
| 476 | if (joystick->IsJoyconLeft()) { | 480 | if (joystick->IsJoyconLeft()) { |
| @@ -493,8 +497,8 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||
| 493 | devices.emplace_back(Common::ParamPackage{ | 497 | devices.emplace_back(Common::ParamPackage{ |
| 494 | {"engine", GetEngineName()}, | 498 | {"engine", GetEngineName()}, |
| 495 | {"display", std::move(name)}, | 499 | {"display", std::move(name)}, |
| 496 | {"guid", joystick->GetGUID()}, | 500 | {"guid", joystick->GetGUID().RawString()}, |
| 497 | {"guid2", joystick2->GetGUID()}, | 501 | {"guid2", joystick2->GetGUID().RawString()}, |
| 498 | {"port", std::to_string(joystick->GetPort())}, | 502 | {"port", std::to_string(joystick->GetPort())}, |
| 499 | }); | 503 | }); |
| 500 | } | 504 | } |
| @@ -557,50 +561,50 @@ void SDLDriver::SendVibrations() { | |||
| 557 | } | 561 | } |
| 558 | } | 562 | } |
| 559 | 563 | ||
| 560 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, | 564 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, const Common::UUID& guid, |
| 561 | s32 axis, float value) const { | 565 | s32 axis, float value) const { |
| 562 | Common::ParamPackage params{}; | 566 | Common::ParamPackage params{}; |
| 563 | params.Set("engine", GetEngineName()); | 567 | params.Set("engine", GetEngineName()); |
| 564 | params.Set("port", port); | 568 | params.Set("port", port); |
| 565 | params.Set("guid", std::move(guid)); | 569 | params.Set("guid", guid.RawString()); |
| 566 | params.Set("axis", axis); | 570 | params.Set("axis", axis); |
| 567 | params.Set("threshold", "0.5"); | 571 | params.Set("threshold", "0.5"); |
| 568 | params.Set("invert", value < 0 ? "-" : "+"); | 572 | params.Set("invert", value < 0 ? "-" : "+"); |
| 569 | return params; | 573 | return params; |
| 570 | } | 574 | } |
| 571 | 575 | ||
| 572 | Common::ParamPackage SDLDriver::BuildButtonParamPackageForButton(int port, std::string guid, | 576 | Common::ParamPackage SDLDriver::BuildButtonParamPackageForButton(int port, const Common::UUID& guid, |
| 573 | s32 button) const { | 577 | s32 button) const { |
| 574 | Common::ParamPackage params{}; | 578 | Common::ParamPackage params{}; |
| 575 | params.Set("engine", GetEngineName()); | 579 | params.Set("engine", GetEngineName()); |
| 576 | params.Set("port", port); | 580 | params.Set("port", port); |
| 577 | params.Set("guid", std::move(guid)); | 581 | params.Set("guid", guid.RawString()); |
| 578 | params.Set("button", button); | 582 | params.Set("button", button); |
| 579 | return params; | 583 | return params; |
| 580 | } | 584 | } |
| 581 | 585 | ||
| 582 | Common::ParamPackage SDLDriver::BuildHatParamPackageForButton(int port, std::string guid, s32 hat, | 586 | Common::ParamPackage SDLDriver::BuildHatParamPackageForButton(int port, const Common::UUID& guid, |
| 583 | u8 value) const { | 587 | s32 hat, u8 value) const { |
| 584 | Common::ParamPackage params{}; | 588 | Common::ParamPackage params{}; |
| 585 | params.Set("engine", GetEngineName()); | 589 | params.Set("engine", GetEngineName()); |
| 586 | params.Set("port", port); | 590 | params.Set("port", port); |
| 587 | params.Set("guid", std::move(guid)); | 591 | params.Set("guid", guid.RawString()); |
| 588 | params.Set("hat", hat); | 592 | params.Set("hat", hat); |
| 589 | params.Set("direction", GetHatButtonName(value)); | 593 | params.Set("direction", GetHatButtonName(value)); |
| 590 | return params; | 594 | return params; |
| 591 | } | 595 | } |
| 592 | 596 | ||
| 593 | Common::ParamPackage SDLDriver::BuildMotionParam(int port, std::string guid) const { | 597 | Common::ParamPackage SDLDriver::BuildMotionParam(int port, const Common::UUID& guid) const { |
| 594 | Common::ParamPackage params{}; | 598 | Common::ParamPackage params{}; |
| 595 | params.Set("engine", GetEngineName()); | 599 | params.Set("engine", GetEngineName()); |
| 596 | params.Set("motion", 0); | 600 | params.Set("motion", 0); |
| 597 | params.Set("port", port); | 601 | params.Set("port", port); |
| 598 | params.Set("guid", std::move(guid)); | 602 | params.Set("guid", guid.RawString()); |
| 599 | return params; | 603 | return params; |
| 600 | } | 604 | } |
| 601 | 605 | ||
| 602 | Common::ParamPackage SDLDriver::BuildParamPackageForBinding( | 606 | Common::ParamPackage SDLDriver::BuildParamPackageForBinding( |
| 603 | int port, const std::string& guid, const SDL_GameControllerButtonBind& binding) const { | 607 | int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { |
| 604 | switch (binding.bindType) { | 608 | switch (binding.bindType) { |
| 605 | case SDL_CONTROLLER_BINDTYPE_NONE: | 609 | case SDL_CONTROLLER_BINDTYPE_NONE: |
| 606 | break; | 610 | break; |
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index c82632506..0846fbb50 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h | |||
| @@ -47,6 +47,7 @@ public: | |||
| 47 | * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so | 47 | * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so |
| 48 | * tie it to a SDLJoystick with the same guid and that port | 48 | * tie it to a SDLJoystick with the same guid and that port |
| 49 | */ | 49 | */ |
| 50 | std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const Common::UUID& guid, int port); | ||
| 50 | std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const std::string& guid, int port); | 51 | std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const std::string& guid, int port); |
| 51 | 52 | ||
| 52 | std::vector<Common::ParamPackage> GetInputDevices() const override; | 53 | std::vector<Common::ParamPackage> GetInputDevices() const override; |
| @@ -79,18 +80,18 @@ private: | |||
| 79 | /// Takes all vibrations from the queue and sends the command to the controller | 80 | /// Takes all vibrations from the queue and sends the command to the controller |
| 80 | void SendVibrations(); | 81 | void SendVibrations(); |
| 81 | 82 | ||
| 82 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, | 83 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, const Common::UUID& guid, |
| 83 | float value = 0.1f) const; | 84 | s32 axis, float value = 0.1f) const; |
| 84 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, | 85 | Common::ParamPackage BuildButtonParamPackageForButton(int port, const Common::UUID& guid, |
| 85 | s32 button) const; | 86 | s32 button) const; |
| 86 | 87 | ||
| 87 | Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, s32 hat, | 88 | Common::ParamPackage BuildHatParamPackageForButton(int port, const Common::UUID& guid, s32 hat, |
| 88 | u8 value) const; | 89 | u8 value) const; |
| 89 | 90 | ||
| 90 | Common::ParamPackage BuildMotionParam(int port, std::string guid) const; | 91 | Common::ParamPackage BuildMotionParam(int port, const Common::UUID& guid) const; |
| 91 | 92 | ||
| 92 | Common::ParamPackage BuildParamPackageForBinding( | 93 | Common::ParamPackage BuildParamPackageForBinding( |
| 93 | int port, const std::string& guid, const SDL_GameControllerButtonBind& binding) const; | 94 | int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const; |
| 94 | 95 | ||
| 95 | Common::ParamPackage BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x, | 96 | Common::ParamPackage BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x, |
| 96 | int axis_y, float offset_x, | 97 | int axis_y, float offset_x, |
| @@ -120,7 +121,7 @@ private: | |||
| 120 | Common::SPSCQueue<VibrationRequest> vibration_queue; | 121 | Common::SPSCQueue<VibrationRequest> vibration_queue; |
| 121 | 122 | ||
| 122 | /// Map of GUID of a list of corresponding virtual Joysticks | 123 | /// Map of GUID of a list of corresponding virtual Joysticks |
| 123 | std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; | 124 | std::unordered_map<Common::UUID, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; |
| 124 | std::mutex joystick_map_mutex; | 125 | std::mutex joystick_map_mutex; |
| 125 | 126 | ||
| 126 | bool start_thread = false; | 127 | bool start_thread = false; |
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 4c76ce1ea..ae1dbe619 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -253,9 +253,6 @@ else() | |||
| 253 | -Werror | 253 | -Werror |
| 254 | -Werror=conversion | 254 | -Werror=conversion |
| 255 | -Werror=ignored-qualifiers | 255 | -Werror=ignored-qualifiers |
| 256 | -Werror=implicit-fallthrough | ||
| 257 | -Werror=shadow | ||
| 258 | -Werror=sign-compare | ||
| 259 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 256 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
| 260 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> | 257 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> |
| 261 | -Werror=unused-variable | 258 | -Werror=unused-variable |
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.h b/src/shader_recompiler/frontend/maxwell/control_flow.h index 2487b9b0b..1ce45b3a5 100644 --- a/src/shader_recompiler/frontend/maxwell/control_flow.h +++ b/src/shader_recompiler/frontend/maxwell/control_flow.h | |||
| @@ -58,7 +58,7 @@ public: | |||
| 58 | [[nodiscard]] Stack Remove(Token token) const; | 58 | [[nodiscard]] Stack Remove(Token token) const; |
| 59 | 59 | ||
| 60 | private: | 60 | private: |
| 61 | boost::container::small_vector<StackEntry, 3> entries; | 61 | std::vector<StackEntry> entries; |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | struct IndirectBranch { | 64 | struct IndirectBranch { |
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index 3dc7c9a11..578bc8c1b 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | |||
| @@ -975,13 +975,7 @@ private: | |||
| 975 | Environment& env; | 975 | Environment& env; |
| 976 | IR::AbstractSyntaxList& syntax_list; | 976 | IR::AbstractSyntaxList& syntax_list; |
| 977 | bool uses_demote_to_helper{}; | 977 | bool uses_demote_to_helper{}; |
| 978 | |||
| 979 | // TODO: C++20 Remove this when all compilers support constexpr std::vector | ||
| 980 | #if __cpp_lib_constexpr_vector >= 201907 | ||
| 981 | static constexpr Flow::Block dummy_flow_block; | ||
| 982 | #else | ||
| 983 | const Flow::Block dummy_flow_block; | 978 | const Flow::Block dummy_flow_block; |
| 984 | #endif | ||
| 985 | }; | 979 | }; |
| 986 | } // Anonymous namespace | 980 | } // Anonymous namespace |
| 987 | 981 | ||
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp index 8358d36b5..e687416a8 100644 --- a/src/tests/core/core_timing.cpp +++ b/src/tests/core/core_timing.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <chrono> | 8 | #include <chrono> |
| 9 | #include <cstdlib> | 9 | #include <cstdlib> |
| 10 | #include <memory> | 10 | #include <memory> |
| 11 | #include <mutex> | ||
| 11 | #include <string> | 12 | #include <string> |
| 12 | 13 | ||
| 13 | #include "core/core.h" | 14 | #include "core/core.h" |
| @@ -21,13 +22,14 @@ std::array<s64, 5> delays{}; | |||
| 21 | 22 | ||
| 22 | std::bitset<CB_IDS.size()> callbacks_ran_flags; | 23 | std::bitset<CB_IDS.size()> callbacks_ran_flags; |
| 23 | u64 expected_callback = 0; | 24 | u64 expected_callback = 0; |
| 25 | std::mutex control_mutex; | ||
| 24 | 26 | ||
| 25 | template <unsigned int IDX> | 27 | template <unsigned int IDX> |
| 26 | void HostCallbackTemplate(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | 28 | void HostCallbackTemplate(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { |
| 29 | std::unique_lock<std::mutex> lk(control_mutex); | ||
| 27 | static_assert(IDX < CB_IDS.size(), "IDX out of range"); | 30 | static_assert(IDX < CB_IDS.size(), "IDX out of range"); |
| 28 | callbacks_ran_flags.set(IDX); | 31 | callbacks_ran_flags.set(IDX); |
| 29 | REQUIRE(CB_IDS[IDX] == user_data); | 32 | REQUIRE(CB_IDS[IDX] == user_data); |
| 30 | REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]); | ||
| 31 | delays[IDX] = ns_late.count(); | 33 | delays[IDX] = ns_late.count(); |
| 32 | ++expected_callback; | 34 | ++expected_callback; |
| 33 | } | 35 | } |
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 256695804..14de7bc89 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -258,10 +258,6 @@ if (MSVC) | |||
| 258 | target_compile_options(video_core PRIVATE | 258 | target_compile_options(video_core PRIVATE |
| 259 | /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data | 259 | /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data |
| 260 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data | 260 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data |
| 261 | /we4456 # Declaration of 'identifier' hides previous local declaration | ||
| 262 | /we4457 # Declaration of 'identifier' hides function parameter | ||
| 263 | /we4458 # Declaration of 'identifier' hides class member | ||
| 264 | /we4459 # Declaration of 'identifier' hides global declaration | ||
| 265 | ) | 261 | ) |
| 266 | else() | 262 | else() |
| 267 | target_compile_options(video_core PRIVATE | 263 | target_compile_options(video_core PRIVATE |
| @@ -269,7 +265,6 @@ else() | |||
| 269 | -Wno-error=sign-conversion | 265 | -Wno-error=sign-conversion |
| 270 | -Werror=pessimizing-move | 266 | -Werror=pessimizing-move |
| 271 | -Werror=redundant-move | 267 | -Werror=redundant-move |
| 272 | -Werror=shadow | ||
| 273 | -Werror=type-limits | 268 | -Werror=type-limits |
| 274 | 269 | ||
| 275 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> | 270 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> |
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 83b2e0fc4..a5eb97b7f 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp | |||
| @@ -224,7 +224,7 @@ void Codec::Decode() { | |||
| 224 | vp9_hidden_frame = vp9_decoder->WasFrameHidden(); | 224 | vp9_hidden_frame = vp9_decoder->WasFrameHidden(); |
| 225 | return vp9_decoder->GetFrameBytes(); | 225 | return vp9_decoder->GetFrameBytes(); |
| 226 | default: | 226 | default: |
| 227 | UNREACHABLE(); | 227 | ASSERT(false); |
| 228 | return std::vector<u8>{}; | 228 | return std::vector<u8>{}; |
| 229 | } | 229 | } |
| 230 | }(); | 230 | }(); |
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index bef321b6e..7c17df353 100644 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp | |||
| @@ -228,7 +228,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) { | |||
| 228 | break; | 228 | break; |
| 229 | } | 229 | } |
| 230 | default: | 230 | default: |
| 231 | UNREACHABLE(); | 231 | ASSERT(false); |
| 232 | break; | 232 | break; |
| 233 | } | 233 | } |
| 234 | gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(), | 234 | gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(), |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 434ba0877..5f9eb208c 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -202,7 +202,7 @@ public: | |||
| 202 | case Size::Size_11_11_10: | 202 | case Size::Size_11_11_10: |
| 203 | return 3; | 203 | return 3; |
| 204 | default: | 204 | default: |
| 205 | UNREACHABLE(); | 205 | ASSERT(false); |
| 206 | return 1; | 206 | return 1; |
| 207 | } | 207 | } |
| 208 | } | 208 | } |
| @@ -238,7 +238,7 @@ public: | |||
| 238 | case Size::Size_11_11_10: | 238 | case Size::Size_11_11_10: |
| 239 | return 4; | 239 | return 4; |
| 240 | default: | 240 | default: |
| 241 | UNREACHABLE(); | 241 | ASSERT(false); |
| 242 | return 1; | 242 | return 1; |
| 243 | } | 243 | } |
| 244 | } | 244 | } |
| @@ -274,7 +274,7 @@ public: | |||
| 274 | case Size::Size_11_11_10: | 274 | case Size::Size_11_11_10: |
| 275 | return "11_11_10"; | 275 | return "11_11_10"; |
| 276 | default: | 276 | default: |
| 277 | UNREACHABLE(); | 277 | ASSERT(false); |
| 278 | return {}; | 278 | return {}; |
| 279 | } | 279 | } |
| 280 | } | 280 | } |
| @@ -296,7 +296,7 @@ public: | |||
| 296 | case Type::Float: | 296 | case Type::Float: |
| 297 | return "FLOAT"; | 297 | return "FLOAT"; |
| 298 | } | 298 | } |
| 299 | UNREACHABLE(); | 299 | ASSERT(false); |
| 300 | return {}; | 300 | return {}; |
| 301 | } | 301 | } |
| 302 | 302 | ||
| @@ -336,7 +336,7 @@ public: | |||
| 336 | case 3: | 336 | case 3: |
| 337 | return {x3, y3}; | 337 | return {x3, y3}; |
| 338 | default: | 338 | default: |
| 339 | UNREACHABLE(); | 339 | ASSERT(false); |
| 340 | return {0, 0}; | 340 | return {0, 0}; |
| 341 | } | 341 | } |
| 342 | } | 342 | } |
| @@ -1193,7 +1193,7 @@ public: | |||
| 1193 | case IndexFormat::UnsignedInt: | 1193 | case IndexFormat::UnsignedInt: |
| 1194 | return 4; | 1194 | return 4; |
| 1195 | } | 1195 | } |
| 1196 | UNREACHABLE(); | 1196 | ASSERT(false); |
| 1197 | return 1; | 1197 | return 1; |
| 1198 | } | 1198 | } |
| 1199 | 1199 | ||
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index a7302f7c1..0efe58282 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -62,7 +62,7 @@ void MaxwellDMA::Launch() { | |||
| 62 | 62 | ||
| 63 | if (!is_src_pitch && !is_dst_pitch) { | 63 | if (!is_src_pitch && !is_dst_pitch) { |
| 64 | // If both the source and the destination are in block layout, assert. | 64 | // If both the source and the destination are in block layout, assert. |
| 65 | UNREACHABLE_MSG("Tiled->Tiled DMA transfers are not yet implemented"); | 65 | UNIMPLEMENTED_MSG("Tiled->Tiled DMA transfers are not yet implemented"); |
| 66 | return; | 66 | return; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| @@ -260,7 +260,7 @@ void MaxwellDMA::ReleaseSemaphore() { | |||
| 260 | memory_manager.Write<u64>(address + 8, system.GPU().GetTicks()); | 260 | memory_manager.Write<u64>(address + 8, system.GPU().GetTicks()); |
| 261 | break; | 261 | break; |
| 262 | default: | 262 | default: |
| 263 | UNREACHABLE_MSG("Unknown semaphore type: {}", static_cast<u32>(type.Value())); | 263 | ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value())); |
| 264 | } | 264 | } |
| 265 | } | 265 | } |
| 266 | 266 | ||
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 8479dc6d2..b0ce9f000 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -50,7 +50,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system, | |||
| 50 | } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) { | 50 | } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) { |
| 51 | rasterizer->OnCPUWrite(invalidate->addr, invalidate->size); | 51 | rasterizer->OnCPUWrite(invalidate->addr, invalidate->size); |
| 52 | } else { | 52 | } else { |
| 53 | UNREACHABLE(); | 53 | ASSERT(false); |
| 54 | } | 54 | } |
| 55 | state.signaled_fence.store(next.fence); | 55 | state.signaled_fence.store(next.fence); |
| 56 | if (next.block) { | 56 | if (next.block) { |
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index ad9fd5eff..be0ac2214 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h | |||
| @@ -98,7 +98,7 @@ struct CommandDataContainer { | |||
| 98 | struct SynchState final { | 98 | struct SynchState final { |
| 99 | using CommandQueue = Common::MPSCQueue<CommandDataContainer>; | 99 | using CommandQueue = Common::MPSCQueue<CommandDataContainer>; |
| 100 | std::mutex write_lock; | 100 | std::mutex write_lock; |
| 101 | CommandQueue queue{512}; // size must be 2^n | 101 | CommandQueue queue; |
| 102 | u64 last_fence{}; | 102 | u64 last_fence{}; |
| 103 | std::atomic<u64> signaled_fence{}; | 103 | std::atomic<u64> signaled_fence{}; |
| 104 | std::condition_variable_any cv; | 104 | std::condition_variable_any cv; |
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index e7279efcd..43f8b5904 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp | |||
| @@ -71,7 +71,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { | |||
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| 73 | if (!mid_method.has_value()) { | 73 | if (!mid_method.has_value()) { |
| 74 | UNREACHABLE_MSG("Macro 0x{0:x} was not uploaded", method); | 74 | ASSERT_MSG(false, "Macro 0x{0:x} was not uploaded", method); |
| 75 | return; | 75 | return; |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp index 87d2e8721..f670b1bca 100644 --- a/src/video_core/macro/macro_interpreter.cpp +++ b/src/video_core/macro/macro_interpreter.cpp | |||
| @@ -308,7 +308,6 @@ bool MacroInterpreterImpl::EvaluateBranchCondition(Macro::BranchCondition cond, | |||
| 308 | return value != 0; | 308 | return value != 0; |
| 309 | } | 309 | } |
| 310 | UNREACHABLE(); | 310 | UNREACHABLE(); |
| 311 | return true; | ||
| 312 | } | 311 | } |
| 313 | 312 | ||
| 314 | Macro::Opcode MacroInterpreterImpl::GetOpcode() const { | 313 | Macro::Opcode MacroInterpreterImpl::GetOpcode() const { |
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp index dc5376501..aca25d902 100644 --- a/src/video_core/macro/macro_jit_x64.cpp +++ b/src/video_core/macro/macro_jit_x64.cpp | |||
| @@ -411,7 +411,7 @@ void MacroJITx64Impl::Compile_Branch(Macro::Opcode opcode) { | |||
| 411 | 411 | ||
| 412 | Xbyak::Label end; | 412 | Xbyak::Label end; |
| 413 | auto value = Compile_GetRegister(opcode.src_a, eax); | 413 | auto value = Compile_GetRegister(opcode.src_a, eax); |
| 414 | test(value, value); | 414 | cmp(value, 0); // test(value, value); |
| 415 | if (optimizer.has_delayed_pc) { | 415 | if (optimizer.has_delayed_pc) { |
| 416 | switch (opcode.branch_condition) { | 416 | switch (opcode.branch_condition) { |
| 417 | case Macro::BranchCondition::Zero: | 417 | case Macro::BranchCondition::Zero: |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index c8d99fdb5..d373be0ba 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -67,7 +67,7 @@ void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) { | |||
| 67 | ASSERT(it->first == gpu_addr); | 67 | ASSERT(it->first == gpu_addr); |
| 68 | map_ranges.erase(it); | 68 | map_ranges.erase(it); |
| 69 | } else { | 69 | } else { |
| 70 | UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr); | 70 | ASSERT_MSG(false, "Unmapping non-existent GPU address=0x{:x}", gpu_addr); |
| 71 | } | 71 | } |
| 72 | const auto submapped_ranges = GetSubmappedRange(gpu_addr, size); | 72 | const auto submapped_ranges = GetSubmappedRange(gpu_addr, size); |
| 73 | 73 | ||
| @@ -206,7 +206,7 @@ T MemoryManager::Read(GPUVAddr addr) const { | |||
| 206 | return value; | 206 | return value; |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | UNREACHABLE(); | 209 | ASSERT(false); |
| 210 | 210 | ||
| 211 | return {}; | 211 | return {}; |
| 212 | } | 212 | } |
| @@ -219,7 +219,7 @@ void MemoryManager::Write(GPUVAddr addr, T data) { | |||
| 219 | return; | 219 | return; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | UNREACHABLE(); | 222 | ASSERT(false); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; | 225 | template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 35f42f2f8..67eae369d 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -48,7 +48,7 @@ GLenum Stage(size_t stage_index) { | |||
| 48 | case 4: | 48 | case 4: |
| 49 | return GL_FRAGMENT_SHADER; | 49 | return GL_FRAGMENT_SHADER; |
| 50 | } | 50 | } |
| 51 | UNREACHABLE_MSG("{}", stage_index); | 51 | ASSERT_MSG(false, "{}", stage_index); |
| 52 | return GL_NONE; | 52 | return GL_NONE; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| @@ -65,7 +65,7 @@ GLenum AssemblyStage(size_t stage_index) { | |||
| 65 | case 4: | 65 | case 4: |
| 66 | return GL_FRAGMENT_PROGRAM_NV; | 66 | return GL_FRAGMENT_PROGRAM_NV; |
| 67 | } | 67 | } |
| 68 | UNREACHABLE_MSG("{}", stage_index); | 68 | ASSERT_MSG(false, "{}", stage_index); |
| 69 | return GL_NONE; | 69 | return GL_NONE; |
| 70 | } | 70 | } |
| 71 | 71 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index cd48fef26..07d4b7cf0 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -85,7 +85,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | |||
| 85 | case Maxwell::TessellationPrimitive::Quads: | 85 | case Maxwell::TessellationPrimitive::Quads: |
| 86 | return Shader::TessPrimitive::Quads; | 86 | return Shader::TessPrimitive::Quads; |
| 87 | } | 87 | } |
| 88 | UNREACHABLE(); | 88 | ASSERT(false); |
| 89 | return Shader::TessPrimitive::Triangles; | 89 | return Shader::TessPrimitive::Triangles; |
| 90 | }(); | 90 | }(); |
| 91 | info.tess_spacing = [&] { | 91 | info.tess_spacing = [&] { |
| @@ -97,7 +97,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | |||
| 97 | case Maxwell::TessellationSpacing::FractionalEven: | 97 | case Maxwell::TessellationSpacing::FractionalEven: |
| 98 | return Shader::TessSpacing::FractionalEven; | 98 | return Shader::TessSpacing::FractionalEven; |
| 99 | } | 99 | } |
| 100 | UNREACHABLE(); | 100 | ASSERT(false); |
| 101 | return Shader::TessSpacing::Equal; | 101 | return Shader::TessSpacing::Equal; |
| 102 | }(); | 102 | }(); |
| 103 | break; | 103 | break; |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 29ff736fb..8c0fffc67 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -83,7 +83,7 @@ GLenum ImageTarget(const VideoCommon::ImageInfo& info) { | |||
| 83 | case ImageType::Buffer: | 83 | case ImageType::Buffer: |
| 84 | return GL_TEXTURE_BUFFER; | 84 | return GL_TEXTURE_BUFFER; |
| 85 | } | 85 | } |
| 86 | UNREACHABLE_MSG("Invalid image type={}", info.type); | 86 | ASSERT_MSG(false, "Invalid image type={}", info.type); |
| 87 | return GL_NONE; | 87 | return GL_NONE; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| @@ -107,7 +107,7 @@ GLenum ImageTarget(Shader::TextureType type, int num_samples = 1) { | |||
| 107 | case Shader::TextureType::Buffer: | 107 | case Shader::TextureType::Buffer: |
| 108 | return GL_TEXTURE_BUFFER; | 108 | return GL_TEXTURE_BUFFER; |
| 109 | } | 109 | } |
| 110 | UNREACHABLE_MSG("Invalid image view type={}", type); | 110 | ASSERT_MSG(false, "Invalid image view type={}", type); |
| 111 | return GL_NONE; | 111 | return GL_NONE; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| @@ -119,7 +119,7 @@ GLenum TextureMode(PixelFormat format, bool is_first) { | |||
| 119 | case PixelFormat::S8_UINT_D24_UNORM: | 119 | case PixelFormat::S8_UINT_D24_UNORM: |
| 120 | return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; | 120 | return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; |
| 121 | default: | 121 | default: |
| 122 | UNREACHABLE(); | 122 | ASSERT(false); |
| 123 | return GL_DEPTH_COMPONENT; | 123 | return GL_DEPTH_COMPONENT; |
| 124 | } | 124 | } |
| 125 | } | 125 | } |
| @@ -140,7 +140,7 @@ GLint Swizzle(SwizzleSource source) { | |||
| 140 | case SwizzleSource::OneFloat: | 140 | case SwizzleSource::OneFloat: |
| 141 | return GL_ONE; | 141 | return GL_ONE; |
| 142 | } | 142 | } |
| 143 | UNREACHABLE_MSG("Invalid swizzle source={}", source); | 143 | ASSERT_MSG(false, "Invalid swizzle source={}", source); |
| 144 | return GL_NONE; | 144 | return GL_NONE; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| @@ -197,7 +197,7 @@ GLint ConvertA5B5G5R1_UNORM(SwizzleSource source) { | |||
| 197 | case SwizzleSource::OneFloat: | 197 | case SwizzleSource::OneFloat: |
| 198 | return GL_ONE; | 198 | return GL_ONE; |
| 199 | } | 199 | } |
| 200 | UNREACHABLE_MSG("Invalid swizzle source={}", source); | 200 | ASSERT_MSG(false, "Invalid swizzle source={}", source); |
| 201 | return GL_NONE; | 201 | return GL_NONE; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| @@ -381,10 +381,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form | |||
| 381 | glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, depth); | 381 | glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, depth); |
| 382 | break; | 382 | break; |
| 383 | case GL_TEXTURE_BUFFER: | 383 | case GL_TEXTURE_BUFFER: |
| 384 | UNREACHABLE(); | 384 | ASSERT(false); |
| 385 | break; | 385 | break; |
| 386 | default: | 386 | default: |
| 387 | UNREACHABLE_MSG("Invalid target=0x{:x}", target); | 387 | ASSERT_MSG(false, "Invalid target=0x{:x}", target); |
| 388 | break; | 388 | break; |
| 389 | } | 389 | } |
| 390 | return texture; | 390 | return texture; |
| @@ -420,7 +420,7 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form | |||
| 420 | case Shader::ImageFormat::R32G32B32A32_UINT: | 420 | case Shader::ImageFormat::R32G32B32A32_UINT: |
| 421 | return GL_RGBA32UI; | 421 | return GL_RGBA32UI; |
| 422 | } | 422 | } |
| 423 | UNREACHABLE_MSG("Invalid image format={}", format); | 423 | ASSERT_MSG(false, "Invalid image format={}", format); |
| 424 | return GL_R32UI; | 424 | return GL_R32UI; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| @@ -579,7 +579,7 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src, | |||
| 579 | } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { | 579 | } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { |
| 580 | format_conversion_pass.ConvertImage(dst, src, copies); | 580 | format_conversion_pass.ConvertImage(dst, src, copies); |
| 581 | } else { | 581 | } else { |
| 582 | UNREACHABLE(); | 582 | ASSERT(false); |
| 583 | } | 583 | } |
| 584 | } | 584 | } |
| 585 | 585 | ||
| @@ -620,7 +620,7 @@ void TextureCacheRuntime::AccelerateImageUpload(Image& image, const ImageBufferM | |||
| 620 | case ImageType::Linear: | 620 | case ImageType::Linear: |
| 621 | return util_shaders.PitchUpload(image, map, swizzles); | 621 | return util_shaders.PitchUpload(image, map, swizzles); |
| 622 | default: | 622 | default: |
| 623 | UNREACHABLE(); | 623 | ASSERT(false); |
| 624 | break; | 624 | break; |
| 625 | } | 625 | } |
| 626 | } | 626 | } |
| @@ -639,7 +639,7 @@ FormatProperties TextureCacheRuntime::FormatInfo(ImageType type, GLenum internal | |||
| 639 | case ImageType::e3D: | 639 | case ImageType::e3D: |
| 640 | return format_properties[2].at(internal_format); | 640 | return format_properties[2].at(internal_format); |
| 641 | default: | 641 | default: |
| 642 | UNREACHABLE(); | 642 | ASSERT(false); |
| 643 | return FormatProperties{}; | 643 | return FormatProperties{}; |
| 644 | } | 644 | } |
| 645 | } | 645 | } |
| @@ -888,7 +888,7 @@ void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 888 | } | 888 | } |
| 889 | break; | 889 | break; |
| 890 | default: | 890 | default: |
| 891 | UNREACHABLE(); | 891 | ASSERT(false); |
| 892 | } | 892 | } |
| 893 | } | 893 | } |
| 894 | 894 | ||
| @@ -924,7 +924,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b | |||
| 924 | depth = copy.image_extent.depth; | 924 | depth = copy.image_extent.depth; |
| 925 | break; | 925 | break; |
| 926 | default: | 926 | default: |
| 927 | UNREACHABLE(); | 927 | ASSERT(false); |
| 928 | } | 928 | } |
| 929 | // Compressed formats don't have a pixel format or type | 929 | // Compressed formats don't have a pixel format or type |
| 930 | const bool is_compressed = gl_format == GL_NONE; | 930 | const bool is_compressed = gl_format == GL_NONE; |
| @@ -950,7 +950,7 @@ void Image::Scale(bool up_scale) { | |||
| 950 | case SurfaceType::DepthStencil: | 950 | case SurfaceType::DepthStencil: |
| 951 | return GL_DEPTH_STENCIL_ATTACHMENT; | 951 | return GL_DEPTH_STENCIL_ATTACHMENT; |
| 952 | default: | 952 | default: |
| 953 | UNREACHABLE(); | 953 | ASSERT(false); |
| 954 | return GL_COLOR_ATTACHMENT0; | 954 | return GL_COLOR_ATTACHMENT0; |
| 955 | } | 955 | } |
| 956 | }(); | 956 | }(); |
| @@ -965,7 +965,7 @@ void Image::Scale(bool up_scale) { | |||
| 965 | case SurfaceType::DepthStencil: | 965 | case SurfaceType::DepthStencil: |
| 966 | return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; | 966 | return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; |
| 967 | default: | 967 | default: |
| 968 | UNREACHABLE(); | 968 | ASSERT(false); |
| 969 | return GL_COLOR_BUFFER_BIT; | 969 | return GL_COLOR_BUFFER_BIT; |
| 970 | } | 970 | } |
| 971 | }(); | 971 | }(); |
| @@ -980,7 +980,7 @@ void Image::Scale(bool up_scale) { | |||
| 980 | case SurfaceType::DepthStencil: | 980 | case SurfaceType::DepthStencil: |
| 981 | return 3; | 981 | return 3; |
| 982 | default: | 982 | default: |
| 983 | UNREACHABLE(); | 983 | ASSERT(false); |
| 984 | return 0; | 984 | return 0; |
| 985 | } | 985 | } |
| 986 | }(); | 986 | }(); |
| @@ -1045,7 +1045,7 @@ bool Image::ScaleUp(bool ignore) { | |||
| 1045 | return false; | 1045 | return false; |
| 1046 | } | 1046 | } |
| 1047 | if (info.type == ImageType::Linear) { | 1047 | if (info.type == ImageType::Linear) { |
| 1048 | UNREACHABLE(); | 1048 | ASSERT(false); |
| 1049 | return false; | 1049 | return false; |
| 1050 | } | 1050 | } |
| 1051 | flags |= ImageFlagBits::Rescaled; | 1051 | flags |= ImageFlagBits::Rescaled; |
| @@ -1139,7 +1139,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI | |||
| 1139 | UNIMPLEMENTED(); | 1139 | UNIMPLEMENTED(); |
| 1140 | break; | 1140 | break; |
| 1141 | case ImageViewType::Buffer: | 1141 | case ImageViewType::Buffer: |
| 1142 | UNREACHABLE(); | 1142 | ASSERT(false); |
| 1143 | break; | 1143 | break; |
| 1144 | } | 1144 | } |
| 1145 | switch (info.type) { | 1145 | switch (info.type) { |
| @@ -1319,7 +1319,7 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM | |||
| 1319 | buffer_bits |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; | 1319 | buffer_bits |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; |
| 1320 | break; | 1320 | break; |
| 1321 | default: | 1321 | default: |
| 1322 | UNREACHABLE(); | 1322 | ASSERT(false); |
| 1323 | buffer_bits |= GL_DEPTH_BUFFER_BIT; | 1323 | buffer_bits |= GL_DEPTH_BUFFER_BIT; |
| 1324 | break; | 1324 | break; |
| 1325 | } | 1325 | } |
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index c2a6da5a7..644b60d73 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -206,7 +206,7 @@ inline GLenum IndexFormat(Maxwell::IndexFormat index_format) { | |||
| 206 | case Maxwell::IndexFormat::UnsignedInt: | 206 | case Maxwell::IndexFormat::UnsignedInt: |
| 207 | return GL_UNSIGNED_INT; | 207 | return GL_UNSIGNED_INT; |
| 208 | } | 208 | } |
| 209 | UNREACHABLE_MSG("Invalid index_format={}", index_format); | 209 | ASSERT_MSG(false, "Invalid index_format={}", index_format); |
| 210 | return {}; | 210 | return {}; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| @@ -243,7 +243,7 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) { | |||
| 243 | case Maxwell::PrimitiveTopology::Patches: | 243 | case Maxwell::PrimitiveTopology::Patches: |
| 244 | return GL_PATCHES; | 244 | return GL_PATCHES; |
| 245 | } | 245 | } |
| 246 | UNREACHABLE_MSG("Invalid topology={}", topology); | 246 | ASSERT_MSG(false, "Invalid topology={}", topology); |
| 247 | return GL_POINTS; | 247 | return GL_POINTS; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| @@ -271,8 +271,8 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode, | |||
| 271 | } | 271 | } |
| 272 | break; | 272 | break; |
| 273 | } | 273 | } |
| 274 | UNREACHABLE_MSG("Invalid texture filter mode={} and mipmap filter mode={}", filter_mode, | 274 | ASSERT_MSG(false, "Invalid texture filter mode={} and mipmap filter mode={}", filter_mode, |
| 275 | mipmap_filter_mode); | 275 | mipmap_filter_mode); |
| 276 | return GL_NEAREST; | 276 | return GL_NEAREST; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| @@ -550,7 +550,7 @@ inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) { | |||
| 550 | case Maxwell::PolygonMode::Fill: | 550 | case Maxwell::PolygonMode::Fill: |
| 551 | return GL_FILL; | 551 | return GL_FILL; |
| 552 | } | 552 | } |
| 553 | UNREACHABLE_MSG("Invalid polygon mode={}", polygon_mode); | 553 | ASSERT_MSG(false, "Invalid polygon mode={}", polygon_mode); |
| 554 | return GL_FILL; | 554 | return GL_FILL; |
| 555 | } | 555 | } |
| 556 | 556 | ||
| @@ -563,7 +563,7 @@ inline GLenum ReductionFilter(Tegra::Texture::SamplerReduction filter) { | |||
| 563 | case Tegra::Texture::SamplerReduction::Max: | 563 | case Tegra::Texture::SamplerReduction::Max: |
| 564 | return GL_MAX; | 564 | return GL_MAX; |
| 565 | } | 565 | } |
| 566 | UNREACHABLE_MSG("Invalid reduction filter={}", static_cast<int>(filter)); | 566 | ASSERT_MSG(false, "Invalid reduction filter={}", static_cast<int>(filter)); |
| 567 | return GL_WEIGHTED_AVERAGE_ARB; | 567 | return GL_WEIGHTED_AVERAGE_ARB; |
| 568 | } | 568 | } |
| 569 | 569 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 3a3c213bb..9a9243544 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -79,7 +79,7 @@ const char* GetSource(GLenum source) { | |||
| 79 | case GL_DEBUG_SOURCE_OTHER: | 79 | case GL_DEBUG_SOURCE_OTHER: |
| 80 | return "OTHER"; | 80 | return "OTHER"; |
| 81 | default: | 81 | default: |
| 82 | UNREACHABLE(); | 82 | ASSERT(false); |
| 83 | return "Unknown source"; | 83 | return "Unknown source"; |
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| @@ -101,7 +101,7 @@ const char* GetType(GLenum type) { | |||
| 101 | case GL_DEBUG_TYPE_MARKER: | 101 | case GL_DEBUG_TYPE_MARKER: |
| 102 | return "MARKER"; | 102 | return "MARKER"; |
| 103 | default: | 103 | default: |
| 104 | UNREACHABLE(); | 104 | ASSERT(false); |
| 105 | return "Unknown type"; | 105 | return "Unknown type"; |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp index 837825737..404def62e 100644 --- a/src/video_core/renderer_opengl/util_shaders.cpp +++ b/src/video_core/renderer_opengl/util_shaders.cpp | |||
| @@ -282,7 +282,7 @@ GLenum StoreFormat(u32 bytes_per_block) { | |||
| 282 | case 16: | 282 | case 16: |
| 283 | return GL_RGBA32UI; | 283 | return GL_RGBA32UI; |
| 284 | } | 284 | } |
| 285 | UNREACHABLE(); | 285 | ASSERT(false); |
| 286 | return GL_R8UI; | 286 | return GL_R8UI; |
| 287 | } | 287 | } |
| 288 | 288 | ||
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 5d35366f7..3f2b139e0 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -349,7 +349,7 @@ VkExtent2D GetConversionExtent(const ImageView& src_image_view) { | |||
| 349 | } | 349 | } |
| 350 | } // Anonymous namespace | 350 | } // Anonymous namespace |
| 351 | 351 | ||
| 352 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, | 352 | BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, |
| 353 | StateTracker& state_tracker_, DescriptorPool& descriptor_pool) | 353 | StateTracker& state_tracker_, DescriptorPool& descriptor_pool) |
| 354 | : device{device_}, scheduler{scheduler_}, state_tracker{state_tracker_}, | 354 | : device{device_}, scheduler{scheduler_}, state_tracker{state_tracker_}, |
| 355 | one_texture_set_layout(device.GetLogical().CreateDescriptorSetLayout( | 355 | one_texture_set_layout(device.GetLogical().CreateDescriptorSetLayout( |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 21e9d7d69..5df679fb4 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -16,7 +16,7 @@ class Device; | |||
| 16 | class Framebuffer; | 16 | class Framebuffer; |
| 17 | class ImageView; | 17 | class ImageView; |
| 18 | class StateTracker; | 18 | class StateTracker; |
| 19 | class VKScheduler; | 19 | class Scheduler; |
| 20 | 20 | ||
| 21 | struct BlitImagePipelineKey { | 21 | struct BlitImagePipelineKey { |
| 22 | constexpr auto operator<=>(const BlitImagePipelineKey&) const noexcept = default; | 22 | constexpr auto operator<=>(const BlitImagePipelineKey&) const noexcept = default; |
| @@ -27,7 +27,7 @@ struct BlitImagePipelineKey { | |||
| 27 | 27 | ||
| 28 | class BlitImageHelper { | 28 | class BlitImageHelper { |
| 29 | public: | 29 | public: |
| 30 | explicit BlitImageHelper(const Device& device, VKScheduler& scheduler, | 30 | explicit BlitImageHelper(const Device& device, Scheduler& scheduler, |
| 31 | StateTracker& state_tracker, DescriptorPool& descriptor_pool); | 31 | StateTracker& state_tracker, DescriptorPool& descriptor_pool); |
| 32 | ~BlitImageHelper(); | 32 | ~BlitImageHelper(); |
| 33 | 33 | ||
| @@ -82,7 +82,7 @@ private: | |||
| 82 | vk::ShaderModule& module); | 82 | vk::ShaderModule& module); |
| 83 | 83 | ||
| 84 | const Device& device; | 84 | const Device& device; |
| 85 | VKScheduler& scheduler; | 85 | Scheduler& scheduler; |
| 86 | StateTracker& state_tracker; | 86 | StateTracker& state_tracker; |
| 87 | 87 | ||
| 88 | vk::DescriptorSetLayout one_texture_set_layout; | 88 | vk::DescriptorSetLayout one_texture_set_layout; |
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index ea360f339..193cbe15e 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -25,7 +25,7 @@ VkFilter Filter(Tegra::Texture::TextureFilter filter) { | |||
| 25 | case Tegra::Texture::TextureFilter::Linear: | 25 | case Tegra::Texture::TextureFilter::Linear: |
| 26 | return VK_FILTER_LINEAR; | 26 | return VK_FILTER_LINEAR; |
| 27 | } | 27 | } |
| 28 | UNREACHABLE_MSG("Invalid sampler filter={}", filter); | 28 | ASSERT_MSG(false, "Invalid sampler filter={}", filter); |
| 29 | return {}; | 29 | return {}; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| @@ -42,7 +42,7 @@ VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter | |||
| 42 | case Tegra::Texture::TextureMipmapFilter::Linear: | 42 | case Tegra::Texture::TextureMipmapFilter::Linear: |
| 43 | return VK_SAMPLER_MIPMAP_MODE_LINEAR; | 43 | return VK_SAMPLER_MIPMAP_MODE_LINEAR; |
| 44 | } | 44 | } |
| 45 | UNREACHABLE_MSG("Invalid sampler mipmap mode={}", mipmap_filter); | 45 | ASSERT_MSG(false, "Invalid sampler mipmap mode={}", mipmap_filter); |
| 46 | return {}; | 46 | return {}; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| @@ -70,7 +70,7 @@ VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wra | |||
| 70 | case Tegra::Texture::TextureFilter::Linear: | 70 | case Tegra::Texture::TextureFilter::Linear: |
| 71 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; | 71 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; |
| 72 | } | 72 | } |
| 73 | UNREACHABLE(); | 73 | ASSERT(false); |
| 74 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; | 74 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; |
| 75 | case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: | 75 | case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: |
| 76 | return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; | 76 | return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; |
| @@ -744,7 +744,7 @@ VkViewportCoordinateSwizzleNV ViewportSwizzle(Maxwell::ViewportSwizzle swizzle) | |||
| 744 | case Maxwell::ViewportSwizzle::NegativeW: | 744 | case Maxwell::ViewportSwizzle::NegativeW: |
| 745 | return VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV; | 745 | return VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV; |
| 746 | } | 746 | } |
| 747 | UNREACHABLE_MSG("Invalid swizzle={}", swizzle); | 747 | ASSERT_MSG(false, "Invalid swizzle={}", swizzle); |
| 748 | return {}; | 748 | return {}; |
| 749 | } | 749 | } |
| 750 | 750 | ||
| @@ -757,7 +757,7 @@ VkSamplerReductionMode SamplerReduction(Tegra::Texture::SamplerReduction reducti | |||
| 757 | case Tegra::Texture::SamplerReduction::Max: | 757 | case Tegra::Texture::SamplerReduction::Max: |
| 758 | return VK_SAMPLER_REDUCTION_MODE_MAX_EXT; | 758 | return VK_SAMPLER_REDUCTION_MODE_MAX_EXT; |
| 759 | } | 759 | } |
| 760 | UNREACHABLE_MSG("Invalid sampler mode={}", static_cast<int>(reduction)); | 760 | ASSERT_MSG(false, "Invalid sampler mode={}", static_cast<int>(reduction)); |
| 761 | return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT; | 761 | return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT; |
| 762 | } | 762 | } |
| 763 | 763 | ||
| @@ -780,7 +780,7 @@ VkSampleCountFlagBits MsaaMode(Tegra::Texture::MsaaMode msaa_mode) { | |||
| 780 | case Tegra::Texture::MsaaMode::Msaa4x4: | 780 | case Tegra::Texture::MsaaMode::Msaa4x4: |
| 781 | return VK_SAMPLE_COUNT_16_BIT; | 781 | return VK_SAMPLE_COUNT_16_BIT; |
| 782 | default: | 782 | default: |
| 783 | UNREACHABLE_MSG("Invalid msaa_mode={}", static_cast<int>(msaa_mode)); | 783 | ASSERT_MSG(false, "Invalid msaa_mode={}", static_cast<int>(msaa_mode)); |
| 784 | return VK_SAMPLE_COUNT_1_BIT; | 784 | return VK_SAMPLE_COUNT_1_BIT; |
| 785 | } | 785 | } |
| 786 | } | 786 | } |
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 9d676612c..b24f3424a 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h | |||
| @@ -168,7 +168,7 @@ private: | |||
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | inline void PushImageDescriptors(TextureCache& texture_cache, | 170 | inline void PushImageDescriptors(TextureCache& texture_cache, |
| 171 | VKUpdateDescriptorQueue& update_descriptor_queue, | 171 | UpdateDescriptorQueue& update_descriptor_queue, |
| 172 | const Shader::Info& info, RescalingPushConstant& rescaling, | 172 | const Shader::Info& info, RescalingPushConstant& rescaling, |
| 173 | const VkSampler*& samplers, | 173 | const VkSampler*& samplers, |
| 174 | const VideoCommon::ImageViewInOut*& views) { | 174 | const VideoCommon::ImageViewInOut*& views) { |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 8a8cb347c..e7bfecb20 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -65,14 +65,14 @@ private: | |||
| 65 | vk::DebugUtilsMessenger debug_callback; | 65 | vk::DebugUtilsMessenger debug_callback; |
| 66 | vk::SurfaceKHR surface; | 66 | vk::SurfaceKHR surface; |
| 67 | 67 | ||
| 68 | VKScreenInfo screen_info; | 68 | ScreenInfo screen_info; |
| 69 | 69 | ||
| 70 | Device device; | 70 | Device device; |
| 71 | MemoryAllocator memory_allocator; | 71 | MemoryAllocator memory_allocator; |
| 72 | StateTracker state_tracker; | 72 | StateTracker state_tracker; |
| 73 | VKScheduler scheduler; | 73 | Scheduler scheduler; |
| 74 | VKSwapchain swapchain; | 74 | Swapchain swapchain; |
| 75 | VKBlitScreen blit_screen; | 75 | BlitScreen blit_screen; |
| 76 | RasterizerVulkan rasterizer; | 76 | RasterizerVulkan rasterizer; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 289bfd7b6..1ec8392e1 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -108,7 +108,7 @@ VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) { | |||
| 108 | 108 | ||
| 109 | } // Anonymous namespace | 109 | } // Anonymous namespace |
| 110 | 110 | ||
| 111 | struct VKBlitScreen::BufferData { | 111 | struct BlitScreen::BufferData { |
| 112 | struct { | 112 | struct { |
| 113 | std::array<f32, 4 * 4> modelview_matrix; | 113 | std::array<f32, 4 * 4> modelview_matrix; |
| 114 | } uniform; | 114 | } uniform; |
| @@ -118,10 +118,9 @@ struct VKBlitScreen::BufferData { | |||
| 118 | // Unaligned image data goes here | 118 | // Unaligned image data goes here |
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | VKBlitScreen::VKBlitScreen(Core::Memory::Memory& cpu_memory_, | 121 | BlitScreen::BlitScreen(Core::Memory::Memory& cpu_memory_, Core::Frontend::EmuWindow& render_window_, |
| 122 | Core::Frontend::EmuWindow& render_window_, const Device& device_, | 122 | const Device& device_, MemoryAllocator& memory_allocator_, |
| 123 | MemoryAllocator& memory_allocator_, VKSwapchain& swapchain_, | 123 | Swapchain& swapchain_, Scheduler& scheduler_, const ScreenInfo& screen_info_) |
| 124 | VKScheduler& scheduler_, const VKScreenInfo& screen_info_) | ||
| 125 | : cpu_memory{cpu_memory_}, render_window{render_window_}, device{device_}, | 124 | : cpu_memory{cpu_memory_}, render_window{render_window_}, device{device_}, |
| 126 | memory_allocator{memory_allocator_}, swapchain{swapchain_}, scheduler{scheduler_}, | 125 | memory_allocator{memory_allocator_}, swapchain{swapchain_}, scheduler{scheduler_}, |
| 127 | image_count{swapchain.GetImageCount()}, screen_info{screen_info_} { | 126 | image_count{swapchain.GetImageCount()}, screen_info{screen_info_} { |
| @@ -131,16 +130,16 @@ VKBlitScreen::VKBlitScreen(Core::Memory::Memory& cpu_memory_, | |||
| 131 | CreateDynamicResources(); | 130 | CreateDynamicResources(); |
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | VKBlitScreen::~VKBlitScreen() = default; | 133 | BlitScreen::~BlitScreen() = default; |
| 135 | 134 | ||
| 136 | void VKBlitScreen::Recreate() { | 135 | void BlitScreen::Recreate() { |
| 137 | CreateDynamicResources(); | 136 | CreateDynamicResources(); |
| 138 | } | 137 | } |
| 139 | 138 | ||
| 140 | VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | 139 | VkSemaphore BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, |
| 141 | const VkFramebuffer& host_framebuffer, | 140 | const VkFramebuffer& host_framebuffer, |
| 142 | const Layout::FramebufferLayout layout, VkExtent2D render_area, | 141 | const Layout::FramebufferLayout layout, VkExtent2D render_area, |
| 143 | bool use_accelerated) { | 142 | bool use_accelerated) { |
| 144 | RefreshResources(framebuffer); | 143 | RefreshResources(framebuffer); |
| 145 | 144 | ||
| 146 | // Finish any pending renderpass | 145 | // Finish any pending renderpass |
| @@ -419,20 +418,20 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
| 419 | return *semaphores[image_index]; | 418 | return *semaphores[image_index]; |
| 420 | } | 419 | } |
| 421 | 420 | ||
| 422 | VkSemaphore VKBlitScreen::DrawToSwapchain(const Tegra::FramebufferConfig& framebuffer, | 421 | VkSemaphore BlitScreen::DrawToSwapchain(const Tegra::FramebufferConfig& framebuffer, |
| 423 | bool use_accelerated) { | 422 | bool use_accelerated) { |
| 424 | const std::size_t image_index = swapchain.GetImageIndex(); | 423 | const std::size_t image_index = swapchain.GetImageIndex(); |
| 425 | const VkExtent2D render_area = swapchain.GetSize(); | 424 | const VkExtent2D render_area = swapchain.GetSize(); |
| 426 | const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); | 425 | const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); |
| 427 | return Draw(framebuffer, *framebuffers[image_index], layout, render_area, use_accelerated); | 426 | return Draw(framebuffer, *framebuffers[image_index], layout, render_area, use_accelerated); |
| 428 | } | 427 | } |
| 429 | 428 | ||
| 430 | vk::Framebuffer VKBlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent) { | 429 | vk::Framebuffer BlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent) { |
| 431 | return CreateFramebuffer(image_view, extent, renderpass); | 430 | return CreateFramebuffer(image_view, extent, renderpass); |
| 432 | } | 431 | } |
| 433 | 432 | ||
| 434 | vk::Framebuffer VKBlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent, | 433 | vk::Framebuffer BlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent, |
| 435 | vk::RenderPass& rd) { | 434 | vk::RenderPass& rd) { |
| 436 | return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{ | 435 | return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{ |
| 437 | .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, | 436 | .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, |
| 438 | .pNext = nullptr, | 437 | .pNext = nullptr, |
| @@ -446,7 +445,7 @@ vk::Framebuffer VKBlitScreen::CreateFramebuffer(const VkImageView& image_view, V | |||
| 446 | }); | 445 | }); |
| 447 | } | 446 | } |
| 448 | 447 | ||
| 449 | void VKBlitScreen::CreateStaticResources() { | 448 | void BlitScreen::CreateStaticResources() { |
| 450 | CreateShaders(); | 449 | CreateShaders(); |
| 451 | CreateSemaphores(); | 450 | CreateSemaphores(); |
| 452 | CreateDescriptorPool(); | 451 | CreateDescriptorPool(); |
| @@ -456,7 +455,7 @@ void VKBlitScreen::CreateStaticResources() { | |||
| 456 | CreateSampler(); | 455 | CreateSampler(); |
| 457 | } | 456 | } |
| 458 | 457 | ||
| 459 | void VKBlitScreen::CreateDynamicResources() { | 458 | void BlitScreen::CreateDynamicResources() { |
| 460 | CreateRenderPass(); | 459 | CreateRenderPass(); |
| 461 | CreateFramebuffers(); | 460 | CreateFramebuffers(); |
| 462 | CreateGraphicsPipeline(); | 461 | CreateGraphicsPipeline(); |
| @@ -466,7 +465,7 @@ void VKBlitScreen::CreateDynamicResources() { | |||
| 466 | } | 465 | } |
| 467 | } | 466 | } |
| 468 | 467 | ||
| 469 | void VKBlitScreen::RefreshResources(const Tegra::FramebufferConfig& framebuffer) { | 468 | void BlitScreen::RefreshResources(const Tegra::FramebufferConfig& framebuffer) { |
| 470 | if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { | 469 | if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { |
| 471 | if (!fsr) { | 470 | if (!fsr) { |
| 472 | CreateFSR(); | 471 | CreateFSR(); |
| @@ -486,7 +485,7 @@ void VKBlitScreen::RefreshResources(const Tegra::FramebufferConfig& framebuffer) | |||
| 486 | CreateRawImages(framebuffer); | 485 | CreateRawImages(framebuffer); |
| 487 | } | 486 | } |
| 488 | 487 | ||
| 489 | void VKBlitScreen::CreateShaders() { | 488 | void BlitScreen::CreateShaders() { |
| 490 | vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV); | 489 | vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV); |
| 491 | fxaa_vertex_shader = BuildShader(device, FXAA_VERT_SPV); | 490 | fxaa_vertex_shader = BuildShader(device, FXAA_VERT_SPV); |
| 492 | fxaa_fragment_shader = BuildShader(device, FXAA_FRAG_SPV); | 491 | fxaa_fragment_shader = BuildShader(device, FXAA_FRAG_SPV); |
| @@ -500,12 +499,12 @@ void VKBlitScreen::CreateShaders() { | |||
| 500 | } | 499 | } |
| 501 | } | 500 | } |
| 502 | 501 | ||
| 503 | void VKBlitScreen::CreateSemaphores() { | 502 | void BlitScreen::CreateSemaphores() { |
| 504 | semaphores.resize(image_count); | 503 | semaphores.resize(image_count); |
| 505 | std::ranges::generate(semaphores, [this] { return device.GetLogical().CreateSemaphore(); }); | 504 | std::ranges::generate(semaphores, [this] { return device.GetLogical().CreateSemaphore(); }); |
| 506 | } | 505 | } |
| 507 | 506 | ||
| 508 | void VKBlitScreen::CreateDescriptorPool() { | 507 | void BlitScreen::CreateDescriptorPool() { |
| 509 | const std::array<VkDescriptorPoolSize, 2> pool_sizes{{ | 508 | const std::array<VkDescriptorPoolSize, 2> pool_sizes{{ |
| 510 | { | 509 | { |
| 511 | .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | 510 | .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, |
| @@ -545,11 +544,11 @@ void VKBlitScreen::CreateDescriptorPool() { | |||
| 545 | aa_descriptor_pool = device.GetLogical().CreateDescriptorPool(ci_aa); | 544 | aa_descriptor_pool = device.GetLogical().CreateDescriptorPool(ci_aa); |
| 546 | } | 545 | } |
| 547 | 546 | ||
| 548 | void VKBlitScreen::CreateRenderPass() { | 547 | void BlitScreen::CreateRenderPass() { |
| 549 | renderpass = CreateRenderPassImpl(swapchain.GetImageViewFormat()); | 548 | renderpass = CreateRenderPassImpl(swapchain.GetImageViewFormat()); |
| 550 | } | 549 | } |
| 551 | 550 | ||
| 552 | vk::RenderPass VKBlitScreen::CreateRenderPassImpl(VkFormat format, bool is_present) { | 551 | vk::RenderPass BlitScreen::CreateRenderPassImpl(VkFormat format, bool is_present) { |
| 553 | const VkAttachmentDescription color_attachment{ | 552 | const VkAttachmentDescription color_attachment{ |
| 554 | .flags = 0, | 553 | .flags = 0, |
| 555 | .format = format, | 554 | .format = format, |
| @@ -605,7 +604,7 @@ vk::RenderPass VKBlitScreen::CreateRenderPassImpl(VkFormat format, bool is_prese | |||
| 605 | return device.GetLogical().CreateRenderPass(renderpass_ci); | 604 | return device.GetLogical().CreateRenderPass(renderpass_ci); |
| 606 | } | 605 | } |
| 607 | 606 | ||
| 608 | void VKBlitScreen::CreateDescriptorSetLayout() { | 607 | void BlitScreen::CreateDescriptorSetLayout() { |
| 609 | const std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings{{ | 608 | const std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings{{ |
| 610 | { | 609 | { |
| 611 | .binding = 0, | 610 | .binding = 0, |
| @@ -660,7 +659,7 @@ void VKBlitScreen::CreateDescriptorSetLayout() { | |||
| 660 | aa_descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci_aa); | 659 | aa_descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci_aa); |
| 661 | } | 660 | } |
| 662 | 661 | ||
| 663 | void VKBlitScreen::CreateDescriptorSets() { | 662 | void BlitScreen::CreateDescriptorSets() { |
| 664 | const std::vector layouts(image_count, *descriptor_set_layout); | 663 | const std::vector layouts(image_count, *descriptor_set_layout); |
| 665 | const std::vector layouts_aa(image_count, *aa_descriptor_set_layout); | 664 | const std::vector layouts_aa(image_count, *aa_descriptor_set_layout); |
| 666 | 665 | ||
| @@ -684,7 +683,7 @@ void VKBlitScreen::CreateDescriptorSets() { | |||
| 684 | aa_descriptor_sets = aa_descriptor_pool.Allocate(ai_aa); | 683 | aa_descriptor_sets = aa_descriptor_pool.Allocate(ai_aa); |
| 685 | } | 684 | } |
| 686 | 685 | ||
| 687 | void VKBlitScreen::CreatePipelineLayout() { | 686 | void BlitScreen::CreatePipelineLayout() { |
| 688 | const VkPipelineLayoutCreateInfo ci{ | 687 | const VkPipelineLayoutCreateInfo ci{ |
| 689 | .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | 688 | .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, |
| 690 | .pNext = nullptr, | 689 | .pNext = nullptr, |
| @@ -707,7 +706,7 @@ void VKBlitScreen::CreatePipelineLayout() { | |||
| 707 | aa_pipeline_layout = device.GetLogical().CreatePipelineLayout(ci_aa); | 706 | aa_pipeline_layout = device.GetLogical().CreatePipelineLayout(ci_aa); |
| 708 | } | 707 | } |
| 709 | 708 | ||
| 710 | void VKBlitScreen::CreateGraphicsPipeline() { | 709 | void BlitScreen::CreateGraphicsPipeline() { |
| 711 | const std::array<VkPipelineShaderStageCreateInfo, 2> bilinear_shader_stages{{ | 710 | const std::array<VkPipelineShaderStageCreateInfo, 2> bilinear_shader_stages{{ |
| 712 | { | 711 | { |
| 713 | .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, | 712 | .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
| @@ -980,7 +979,7 @@ void VKBlitScreen::CreateGraphicsPipeline() { | |||
| 980 | scaleforce_pipeline = device.GetLogical().CreateGraphicsPipeline(scaleforce_pipeline_ci); | 979 | scaleforce_pipeline = device.GetLogical().CreateGraphicsPipeline(scaleforce_pipeline_ci); |
| 981 | } | 980 | } |
| 982 | 981 | ||
| 983 | void VKBlitScreen::CreateSampler() { | 982 | void BlitScreen::CreateSampler() { |
| 984 | const VkSamplerCreateInfo ci{ | 983 | const VkSamplerCreateInfo ci{ |
| 985 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, | 984 | .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, |
| 986 | .pNext = nullptr, | 985 | .pNext = nullptr, |
| @@ -1027,7 +1026,7 @@ void VKBlitScreen::CreateSampler() { | |||
| 1027 | nn_sampler = device.GetLogical().CreateSampler(ci_nn); | 1026 | nn_sampler = device.GetLogical().CreateSampler(ci_nn); |
| 1028 | } | 1027 | } |
| 1029 | 1028 | ||
| 1030 | void VKBlitScreen::CreateFramebuffers() { | 1029 | void BlitScreen::CreateFramebuffers() { |
| 1031 | const VkExtent2D size{swapchain.GetSize()}; | 1030 | const VkExtent2D size{swapchain.GetSize()}; |
| 1032 | framebuffers.resize(image_count); | 1031 | framebuffers.resize(image_count); |
| 1033 | 1032 | ||
| @@ -1037,7 +1036,7 @@ void VKBlitScreen::CreateFramebuffers() { | |||
| 1037 | } | 1036 | } |
| 1038 | } | 1037 | } |
| 1039 | 1038 | ||
| 1040 | void VKBlitScreen::ReleaseRawImages() { | 1039 | void BlitScreen::ReleaseRawImages() { |
| 1041 | for (const u64 tick : resource_ticks) { | 1040 | for (const u64 tick : resource_ticks) { |
| 1042 | scheduler.Wait(tick); | 1041 | scheduler.Wait(tick); |
| 1043 | } | 1042 | } |
| @@ -1052,7 +1051,7 @@ void VKBlitScreen::ReleaseRawImages() { | |||
| 1052 | buffer_commit = MemoryCommit{}; | 1051 | buffer_commit = MemoryCommit{}; |
| 1053 | } | 1052 | } |
| 1054 | 1053 | ||
| 1055 | void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) { | 1054 | void BlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) { |
| 1056 | const VkBufferCreateInfo ci{ | 1055 | const VkBufferCreateInfo ci{ |
| 1057 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | 1056 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, |
| 1058 | .pNext = nullptr, | 1057 | .pNext = nullptr, |
| @@ -1069,7 +1068,7 @@ void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuff | |||
| 1069 | buffer_commit = memory_allocator.Commit(buffer, MemoryUsage::Upload); | 1068 | buffer_commit = memory_allocator.Commit(buffer, MemoryUsage::Upload); |
| 1070 | } | 1069 | } |
| 1071 | 1070 | ||
| 1072 | void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) { | 1071 | void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) { |
| 1073 | raw_images.resize(image_count); | 1072 | raw_images.resize(image_count); |
| 1074 | raw_image_views.resize(image_count); | 1073 | raw_image_views.resize(image_count); |
| 1075 | raw_buffer_commits.resize(image_count); | 1074 | raw_buffer_commits.resize(image_count); |
| @@ -1294,8 +1293,8 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) | |||
| 1294 | aa_pipeline = device.GetLogical().CreateGraphicsPipeline(fxaa_pipeline_ci); | 1293 | aa_pipeline = device.GetLogical().CreateGraphicsPipeline(fxaa_pipeline_ci); |
| 1295 | } | 1294 | } |
| 1296 | 1295 | ||
| 1297 | void VKBlitScreen::UpdateAADescriptorSet(std::size_t image_index, VkImageView image_view, | 1296 | void BlitScreen::UpdateAADescriptorSet(std::size_t image_index, VkImageView image_view, |
| 1298 | bool nn) const { | 1297 | bool nn) const { |
| 1299 | const VkDescriptorImageInfo image_info{ | 1298 | const VkDescriptorImageInfo image_info{ |
| 1300 | .sampler = nn ? *nn_sampler : *sampler, | 1299 | .sampler = nn ? *nn_sampler : *sampler, |
| 1301 | .imageView = image_view, | 1300 | .imageView = image_view, |
| @@ -1331,8 +1330,8 @@ void VKBlitScreen::UpdateAADescriptorSet(std::size_t image_index, VkImageView im | |||
| 1331 | device.GetLogical().UpdateDescriptorSets(std::array{sampler_write, sampler_write_2}, {}); | 1330 | device.GetLogical().UpdateDescriptorSets(std::array{sampler_write, sampler_write_2}, {}); |
| 1332 | } | 1331 | } |
| 1333 | 1332 | ||
| 1334 | void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, | 1333 | void BlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, |
| 1335 | bool nn) const { | 1334 | bool nn) const { |
| 1336 | const VkDescriptorBufferInfo buffer_info{ | 1335 | const VkDescriptorBufferInfo buffer_info{ |
| 1337 | .buffer = *buffer, | 1336 | .buffer = *buffer, |
| 1338 | .offset = offsetof(BufferData, uniform), | 1337 | .offset = offsetof(BufferData, uniform), |
| @@ -1374,13 +1373,13 @@ void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView imag | |||
| 1374 | device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {}); | 1373 | device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {}); |
| 1375 | } | 1374 | } |
| 1376 | 1375 | ||
| 1377 | void VKBlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const { | 1376 | void BlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const { |
| 1378 | data.uniform.modelview_matrix = | 1377 | data.uniform.modelview_matrix = |
| 1379 | MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); | 1378 | MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); |
| 1380 | } | 1379 | } |
| 1381 | 1380 | ||
| 1382 | void VKBlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, | 1381 | void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, |
| 1383 | const Layout::FramebufferLayout layout) const { | 1382 | const Layout::FramebufferLayout layout) const { |
| 1384 | const auto& framebuffer_transform_flags = framebuffer.transform_flags; | 1383 | const auto& framebuffer_transform_flags = framebuffer.transform_flags; |
| 1385 | const auto& framebuffer_crop_rect = framebuffer.crop_rect; | 1384 | const auto& framebuffer_crop_rect = framebuffer.crop_rect; |
| 1386 | 1385 | ||
| @@ -1432,7 +1431,7 @@ void VKBlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfi | |||
| 1432 | data.vertices[3] = ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v); | 1431 | data.vertices[3] = ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v); |
| 1433 | } | 1432 | } |
| 1434 | 1433 | ||
| 1435 | void VKBlitScreen::CreateFSR() { | 1434 | void BlitScreen::CreateFSR() { |
| 1436 | const auto& layout = render_window.GetFramebufferLayout(); | 1435 | const auto& layout = render_window.GetFramebufferLayout(); |
| 1437 | const VkExtent2D fsr_size{ | 1436 | const VkExtent2D fsr_size{ |
| 1438 | .width = layout.screen.GetWidth(), | 1437 | .width = layout.screen.GetWidth(), |
| @@ -1441,12 +1440,12 @@ void VKBlitScreen::CreateFSR() { | |||
| 1441 | fsr = std::make_unique<FSR>(device, memory_allocator, image_count, fsr_size); | 1440 | fsr = std::make_unique<FSR>(device, memory_allocator, image_count, fsr_size); |
| 1442 | } | 1441 | } |
| 1443 | 1442 | ||
| 1444 | u64 VKBlitScreen::CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const { | 1443 | u64 BlitScreen::CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const { |
| 1445 | return sizeof(BufferData) + GetSizeInBytes(framebuffer) * image_count; | 1444 | return sizeof(BufferData) + GetSizeInBytes(framebuffer) * image_count; |
| 1446 | } | 1445 | } |
| 1447 | 1446 | ||
| 1448 | u64 VKBlitScreen::GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, | 1447 | u64 BlitScreen::GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, |
| 1449 | std::size_t image_index) const { | 1448 | std::size_t image_index) const { |
| 1450 | constexpr auto first_image_offset = static_cast<u64>(sizeof(BufferData)); | 1449 | constexpr auto first_image_offset = static_cast<u64>(sizeof(BufferData)); |
| 1451 | return first_image_offset + GetSizeInBytes(framebuffer) * image_index; | 1450 | return first_image_offset + GetSizeInBytes(framebuffer) * image_index; |
| 1452 | } | 1451 | } |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h index 1b4260f36..b8c67bef0 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.h +++ b/src/video_core/renderer_vulkan/vk_blit_screen.h | |||
| @@ -35,23 +35,22 @@ struct ScreenInfo; | |||
| 35 | class Device; | 35 | class Device; |
| 36 | class FSR; | 36 | class FSR; |
| 37 | class RasterizerVulkan; | 37 | class RasterizerVulkan; |
| 38 | class VKScheduler; | 38 | class Scheduler; |
| 39 | class VKSwapchain; | 39 | class Swapchain; |
| 40 | 40 | ||
| 41 | struct VKScreenInfo { | 41 | struct ScreenInfo { |
| 42 | VkImageView image_view{}; | 42 | VkImageView image_view{}; |
| 43 | u32 width{}; | 43 | u32 width{}; |
| 44 | u32 height{}; | 44 | u32 height{}; |
| 45 | bool is_srgb{}; | 45 | bool is_srgb{}; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | class VKBlitScreen { | 48 | class BlitScreen { |
| 49 | public: | 49 | public: |
| 50 | explicit VKBlitScreen(Core::Memory::Memory& cpu_memory, | 50 | explicit BlitScreen(Core::Memory::Memory& cpu_memory, Core::Frontend::EmuWindow& render_window, |
| 51 | Core::Frontend::EmuWindow& render_window, const Device& device, | 51 | const Device& device, MemoryAllocator& memory_manager, Swapchain& swapchain, |
| 52 | MemoryAllocator& memory_manager, VKSwapchain& swapchain, | 52 | Scheduler& scheduler, const ScreenInfo& screen_info); |
| 53 | VKScheduler& scheduler, const VKScreenInfo& screen_info); | 53 | ~BlitScreen(); |
| 54 | ~VKBlitScreen(); | ||
| 55 | 54 | ||
| 56 | void Recreate(); | 55 | void Recreate(); |
| 57 | 56 | ||
| @@ -108,10 +107,10 @@ private: | |||
| 108 | Core::Frontend::EmuWindow& render_window; | 107 | Core::Frontend::EmuWindow& render_window; |
| 109 | const Device& device; | 108 | const Device& device; |
| 110 | MemoryAllocator& memory_allocator; | 109 | MemoryAllocator& memory_allocator; |
| 111 | VKSwapchain& swapchain; | 110 | Swapchain& swapchain; |
| 112 | VKScheduler& scheduler; | 111 | Scheduler& scheduler; |
| 113 | const std::size_t image_count; | 112 | const std::size_t image_count; |
| 114 | const VKScreenInfo& screen_info; | 113 | const ScreenInfo& screen_info; |
| 115 | 114 | ||
| 116 | vk::ShaderModule vertex_shader; | 115 | vk::ShaderModule vertex_shader; |
| 117 | vk::ShaderModule fxaa_vertex_shader; | 116 | vk::ShaderModule fxaa_vertex_shader; |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 0aeb37538..558b8db56 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -46,7 +46,7 @@ size_t BytesPerIndex(VkIndexType index_type) { | |||
| 46 | case VK_INDEX_TYPE_UINT32: | 46 | case VK_INDEX_TYPE_UINT32: |
| 47 | return 4; | 47 | return 4; |
| 48 | default: | 48 | default: |
| 49 | UNREACHABLE_MSG("Invalid index type={}", index_type); | 49 | ASSERT_MSG(false, "Invalid index type={}", index_type); |
| 50 | return 1; | 50 | return 1; |
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| @@ -124,8 +124,8 @@ VkBufferView Buffer::View(u32 offset, u32 size, VideoCore::Surface::PixelFormat | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_allocator_, | 126 | BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_allocator_, |
| 127 | VKScheduler& scheduler_, StagingBufferPool& staging_pool_, | 127 | Scheduler& scheduler_, StagingBufferPool& staging_pool_, |
| 128 | VKUpdateDescriptorQueue& update_descriptor_queue_, | 128 | UpdateDescriptorQueue& update_descriptor_queue_, |
| 129 | DescriptorPool& descriptor_pool) | 129 | DescriptorPool& descriptor_pool) |
| 130 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, | 130 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, |
| 131 | staging_pool{staging_pool_}, update_descriptor_queue{update_descriptor_queue_}, | 131 | staging_pool{staging_pool_}, update_descriptor_queue{update_descriptor_queue_}, |
| @@ -366,7 +366,7 @@ void BufferCacheRuntime::ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle | |||
| 366 | std::memcpy(staging_data, MakeQuadIndices<u32>(quad, first).data(), quad_size); | 366 | std::memcpy(staging_data, MakeQuadIndices<u32>(quad, first).data(), quad_size); |
| 367 | break; | 367 | break; |
| 368 | default: | 368 | default: |
| 369 | UNREACHABLE(); | 369 | ASSERT(false); |
| 370 | break; | 370 | break; |
| 371 | } | 371 | } |
| 372 | staging_data += quad_size; | 372 | staging_data += quad_size; |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 6fa618f18..a15c8b39b 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h | |||
| @@ -16,7 +16,7 @@ namespace Vulkan { | |||
| 16 | 16 | ||
| 17 | class Device; | 17 | class Device; |
| 18 | class DescriptorPool; | 18 | class DescriptorPool; |
| 19 | class VKScheduler; | 19 | class Scheduler; |
| 20 | 20 | ||
| 21 | class BufferCacheRuntime; | 21 | class BufferCacheRuntime; |
| 22 | 22 | ||
| @@ -58,8 +58,8 @@ class BufferCacheRuntime { | |||
| 58 | 58 | ||
| 59 | public: | 59 | public: |
| 60 | explicit BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_manager_, | 60 | explicit BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_manager_, |
| 61 | VKScheduler& scheduler_, StagingBufferPool& staging_pool_, | 61 | Scheduler& scheduler_, StagingBufferPool& staging_pool_, |
| 62 | VKUpdateDescriptorQueue& update_descriptor_queue_, | 62 | UpdateDescriptorQueue& update_descriptor_queue_, |
| 63 | DescriptorPool& descriptor_pool); | 63 | DescriptorPool& descriptor_pool); |
| 64 | 64 | ||
| 65 | void Finish(); | 65 | void Finish(); |
| @@ -124,9 +124,9 @@ private: | |||
| 124 | 124 | ||
| 125 | const Device& device; | 125 | const Device& device; |
| 126 | MemoryAllocator& memory_allocator; | 126 | MemoryAllocator& memory_allocator; |
| 127 | VKScheduler& scheduler; | 127 | Scheduler& scheduler; |
| 128 | StagingBufferPool& staging_pool; | 128 | StagingBufferPool& staging_pool; |
| 129 | VKUpdateDescriptorQueue& update_descriptor_queue; | 129 | UpdateDescriptorQueue& update_descriptor_queue; |
| 130 | 130 | ||
| 131 | vk::Buffer quad_array_lut; | 131 | vk::Buffer quad_array_lut; |
| 132 | MemoryCommit quad_array_lut_commit; | 132 | MemoryCommit quad_array_lut_commit; |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 29481a102..f17a5ccd6 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp | |||
| @@ -200,9 +200,9 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, | |||
| 200 | 200 | ||
| 201 | ComputePass::~ComputePass() = default; | 201 | ComputePass::~ComputePass() = default; |
| 202 | 202 | ||
| 203 | Uint8Pass::Uint8Pass(const Device& device_, VKScheduler& scheduler_, | 203 | Uint8Pass::Uint8Pass(const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool, |
| 204 | DescriptorPool& descriptor_pool, StagingBufferPool& staging_buffer_pool_, | 204 | StagingBufferPool& staging_buffer_pool_, |
| 205 | VKUpdateDescriptorQueue& update_descriptor_queue_) | 205 | UpdateDescriptorQueue& update_descriptor_queue_) |
| 206 | : ComputePass(device_, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, | 206 | : ComputePass(device_, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, |
| 207 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, {}, | 207 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, {}, |
| 208 | VULKAN_UINT8_COMP_SPV), | 208 | VULKAN_UINT8_COMP_SPV), |
| @@ -241,10 +241,10 @@ std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer | |||
| 241 | return {staging.buffer, staging.offset}; | 241 | return {staging.buffer, staging.offset}; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | QuadIndexedPass::QuadIndexedPass(const Device& device_, VKScheduler& scheduler_, | 244 | QuadIndexedPass::QuadIndexedPass(const Device& device_, Scheduler& scheduler_, |
| 245 | DescriptorPool& descriptor_pool_, | 245 | DescriptorPool& descriptor_pool_, |
| 246 | StagingBufferPool& staging_buffer_pool_, | 246 | StagingBufferPool& staging_buffer_pool_, |
| 247 | VKUpdateDescriptorQueue& update_descriptor_queue_) | 247 | UpdateDescriptorQueue& update_descriptor_queue_) |
| 248 | : ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, | 248 | : ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, |
| 249 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, | 249 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, |
| 250 | COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 2>, VULKAN_QUAD_INDEXED_COMP_SPV), | 250 | COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 2>, VULKAN_QUAD_INDEXED_COMP_SPV), |
| @@ -265,7 +265,7 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble( | |||
| 265 | case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedInt: | 265 | case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedInt: |
| 266 | return 2; | 266 | return 2; |
| 267 | } | 267 | } |
| 268 | UNREACHABLE(); | 268 | ASSERT(false); |
| 269 | return 2; | 269 | return 2; |
| 270 | }(); | 270 | }(); |
| 271 | const u32 input_size = num_vertices << index_shift; | 271 | const u32 input_size = num_vertices << index_shift; |
| @@ -303,10 +303,10 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble( | |||
| 303 | return {staging.buffer, staging.offset}; | 303 | return {staging.buffer, staging.offset}; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | ASTCDecoderPass::ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_, | 306 | ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, |
| 307 | DescriptorPool& descriptor_pool_, | 307 | DescriptorPool& descriptor_pool_, |
| 308 | StagingBufferPool& staging_buffer_pool_, | 308 | StagingBufferPool& staging_buffer_pool_, |
| 309 | VKUpdateDescriptorQueue& update_descriptor_queue_, | 309 | UpdateDescriptorQueue& update_descriptor_queue_, |
| 310 | MemoryAllocator& memory_allocator_) | 310 | MemoryAllocator& memory_allocator_) |
| 311 | : ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, | 311 | : ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, |
| 312 | ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, | 312 | ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, |
| @@ -328,31 +328,32 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, | |||
| 328 | const VkImageAspectFlags aspect_mask = image.AspectMask(); | 328 | const VkImageAspectFlags aspect_mask = image.AspectMask(); |
| 329 | const VkImage vk_image = image.Handle(); | 329 | const VkImage vk_image = image.Handle(); |
| 330 | const bool is_initialized = image.ExchangeInitialization(); | 330 | const bool is_initialized = image.ExchangeInitialization(); |
| 331 | scheduler.Record( | 331 | scheduler.Record([vk_pipeline, vk_image, aspect_mask, |
| 332 | [vk_pipeline, vk_image, aspect_mask, is_initialized](vk::CommandBuffer cmdbuf) { | 332 | is_initialized](vk::CommandBuffer cmdbuf) { |
| 333 | const VkImageMemoryBarrier image_barrier{ | 333 | const VkImageMemoryBarrier image_barrier{ |
| 334 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | 334 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
| 335 | .pNext = nullptr, | 335 | .pNext = nullptr, |
| 336 | .srcAccessMask = is_initialized ? VK_ACCESS_SHADER_WRITE_BIT : VkAccessFlags{}, | 336 | .srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT |
| 337 | .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, | 337 | : VK_ACCESS_NONE), |
| 338 | .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, | 338 | .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
| 339 | .newLayout = VK_IMAGE_LAYOUT_GENERAL, | 339 | .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, |
| 340 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | 340 | .newLayout = VK_IMAGE_LAYOUT_GENERAL, |
| 341 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | 341 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
| 342 | .image = vk_image, | 342 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
| 343 | .subresourceRange{ | 343 | .image = vk_image, |
| 344 | .aspectMask = aspect_mask, | 344 | .subresourceRange{ |
| 345 | .baseMipLevel = 0, | 345 | .aspectMask = aspect_mask, |
| 346 | .levelCount = VK_REMAINING_MIP_LEVELS, | 346 | .baseMipLevel = 0, |
| 347 | .baseArrayLayer = 0, | 347 | .levelCount = VK_REMAINING_MIP_LEVELS, |
| 348 | .layerCount = VK_REMAINING_ARRAY_LAYERS, | 348 | .baseArrayLayer = 0, |
| 349 | }, | 349 | .layerCount = VK_REMAINING_ARRAY_LAYERS, |
| 350 | }; | 350 | }, |
| 351 | cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | 351 | }; |
| 352 | : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, | 352 | cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT |
| 353 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); | 353 | : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
| 354 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); | 354 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); |
| 355 | }); | 355 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); |
| 356 | }); | ||
| 356 | for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { | 357 | for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { |
| 357 | const size_t input_offset = swizzle.buffer_offset + map.offset; | 358 | const size_t input_offset = swizzle.buffer_offset + map.offset; |
| 358 | const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 8U); | 359 | const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 8U); |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h index 1c6aa0805..dcc691a8e 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.h +++ b/src/video_core/renderer_vulkan/vk_compute_pass.h | |||
| @@ -20,8 +20,8 @@ namespace Vulkan { | |||
| 20 | 20 | ||
| 21 | class Device; | 21 | class Device; |
| 22 | class StagingBufferPool; | 22 | class StagingBufferPool; |
| 23 | class VKScheduler; | 23 | class Scheduler; |
| 24 | class VKUpdateDescriptorQueue; | 24 | class UpdateDescriptorQueue; |
| 25 | class Image; | 25 | class Image; |
| 26 | struct StagingBufferRef; | 26 | struct StagingBufferRef; |
| 27 | 27 | ||
| @@ -48,9 +48,9 @@ private: | |||
| 48 | 48 | ||
| 49 | class Uint8Pass final : public ComputePass { | 49 | class Uint8Pass final : public ComputePass { |
| 50 | public: | 50 | public: |
| 51 | explicit Uint8Pass(const Device& device_, VKScheduler& scheduler_, | 51 | explicit Uint8Pass(const Device& device_, Scheduler& scheduler_, |
| 52 | DescriptorPool& descriptor_pool_, StagingBufferPool& staging_buffer_pool_, | 52 | DescriptorPool& descriptor_pool_, StagingBufferPool& staging_buffer_pool_, |
| 53 | VKUpdateDescriptorQueue& update_descriptor_queue_); | 53 | UpdateDescriptorQueue& update_descriptor_queue_); |
| 54 | ~Uint8Pass(); | 54 | ~Uint8Pass(); |
| 55 | 55 | ||
| 56 | /// Assemble uint8 indices into an uint16 index buffer | 56 | /// Assemble uint8 indices into an uint16 index buffer |
| @@ -59,17 +59,17 @@ public: | |||
| 59 | u32 src_offset); | 59 | u32 src_offset); |
| 60 | 60 | ||
| 61 | private: | 61 | private: |
| 62 | VKScheduler& scheduler; | 62 | Scheduler& scheduler; |
| 63 | StagingBufferPool& staging_buffer_pool; | 63 | StagingBufferPool& staging_buffer_pool; |
| 64 | VKUpdateDescriptorQueue& update_descriptor_queue; | 64 | UpdateDescriptorQueue& update_descriptor_queue; |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | class QuadIndexedPass final : public ComputePass { | 67 | class QuadIndexedPass final : public ComputePass { |
| 68 | public: | 68 | public: |
| 69 | explicit QuadIndexedPass(const Device& device_, VKScheduler& scheduler_, | 69 | explicit QuadIndexedPass(const Device& device_, Scheduler& scheduler_, |
| 70 | DescriptorPool& descriptor_pool_, | 70 | DescriptorPool& descriptor_pool_, |
| 71 | StagingBufferPool& staging_buffer_pool_, | 71 | StagingBufferPool& staging_buffer_pool_, |
| 72 | VKUpdateDescriptorQueue& update_descriptor_queue_); | 72 | UpdateDescriptorQueue& update_descriptor_queue_); |
| 73 | ~QuadIndexedPass(); | 73 | ~QuadIndexedPass(); |
| 74 | 74 | ||
| 75 | std::pair<VkBuffer, VkDeviceSize> Assemble( | 75 | std::pair<VkBuffer, VkDeviceSize> Assemble( |
| @@ -77,17 +77,17 @@ public: | |||
| 77 | u32 base_vertex, VkBuffer src_buffer, u32 src_offset); | 77 | u32 base_vertex, VkBuffer src_buffer, u32 src_offset); |
| 78 | 78 | ||
| 79 | private: | 79 | private: |
| 80 | VKScheduler& scheduler; | 80 | Scheduler& scheduler; |
| 81 | StagingBufferPool& staging_buffer_pool; | 81 | StagingBufferPool& staging_buffer_pool; |
| 82 | VKUpdateDescriptorQueue& update_descriptor_queue; | 82 | UpdateDescriptorQueue& update_descriptor_queue; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | class ASTCDecoderPass final : public ComputePass { | 85 | class ASTCDecoderPass final : public ComputePass { |
| 86 | public: | 86 | public: |
| 87 | explicit ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_, | 87 | explicit ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, |
| 88 | DescriptorPool& descriptor_pool_, | 88 | DescriptorPool& descriptor_pool_, |
| 89 | StagingBufferPool& staging_buffer_pool_, | 89 | StagingBufferPool& staging_buffer_pool_, |
| 90 | VKUpdateDescriptorQueue& update_descriptor_queue_, | 90 | UpdateDescriptorQueue& update_descriptor_queue_, |
| 91 | MemoryAllocator& memory_allocator_); | 91 | MemoryAllocator& memory_allocator_); |
| 92 | ~ASTCDecoderPass(); | 92 | ~ASTCDecoderPass(); |
| 93 | 93 | ||
| @@ -95,9 +95,9 @@ public: | |||
| 95 | std::span<const VideoCommon::SwizzleParameters> swizzles); | 95 | std::span<const VideoCommon::SwizzleParameters> swizzles); |
| 96 | 96 | ||
| 97 | private: | 97 | private: |
| 98 | VKScheduler& scheduler; | 98 | Scheduler& scheduler; |
| 99 | StagingBufferPool& staging_buffer_pool; | 99 | StagingBufferPool& staging_buffer_pool; |
| 100 | VKUpdateDescriptorQueue& update_descriptor_queue; | 100 | UpdateDescriptorQueue& update_descriptor_queue; |
| 101 | MemoryAllocator& memory_allocator; | 101 | MemoryAllocator& memory_allocator; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 6c497b5d4..6447210e2 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -25,7 +25,7 @@ using Shader::Backend::SPIRV::RESCALING_LAYOUT_WORDS_OFFSET; | |||
| 25 | using Tegra::Texture::TexturePair; | 25 | using Tegra::Texture::TexturePair; |
| 26 | 26 | ||
| 27 | ComputePipeline::ComputePipeline(const Device& device_, DescriptorPool& descriptor_pool, | 27 | ComputePipeline::ComputePipeline(const Device& device_, DescriptorPool& descriptor_pool, |
| 28 | VKUpdateDescriptorQueue& update_descriptor_queue_, | 28 | UpdateDescriptorQueue& update_descriptor_queue_, |
| 29 | Common::ThreadWorker* thread_worker, | 29 | Common::ThreadWorker* thread_worker, |
| 30 | PipelineStatistics* pipeline_statistics, | 30 | PipelineStatistics* pipeline_statistics, |
| 31 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info_, | 31 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info_, |
| @@ -91,7 +91,7 @@ ComputePipeline::ComputePipeline(const Device& device_, DescriptorPool& descript | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | 93 | void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, |
| 94 | Tegra::MemoryManager& gpu_memory, VKScheduler& scheduler, | 94 | Tegra::MemoryManager& gpu_memory, Scheduler& scheduler, |
| 95 | BufferCache& buffer_cache, TextureCache& texture_cache) { | 95 | BufferCache& buffer_cache, TextureCache& texture_cache) { |
| 96 | update_descriptor_queue.Acquire(); | 96 | update_descriptor_queue.Acquire(); |
| 97 | 97 | ||
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h index d4c0e2015..9879735fe 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h | |||
| @@ -24,12 +24,12 @@ namespace Vulkan { | |||
| 24 | 24 | ||
| 25 | class Device; | 25 | class Device; |
| 26 | class PipelineStatistics; | 26 | class PipelineStatistics; |
| 27 | class VKScheduler; | 27 | class Scheduler; |
| 28 | 28 | ||
| 29 | class ComputePipeline { | 29 | class ComputePipeline { |
| 30 | public: | 30 | public: |
| 31 | explicit ComputePipeline(const Device& device, DescriptorPool& descriptor_pool, | 31 | explicit ComputePipeline(const Device& device, DescriptorPool& descriptor_pool, |
| 32 | VKUpdateDescriptorQueue& update_descriptor_queue, | 32 | UpdateDescriptorQueue& update_descriptor_queue, |
| 33 | Common::ThreadWorker* thread_worker, | 33 | Common::ThreadWorker* thread_worker, |
| 34 | PipelineStatistics* pipeline_statistics, | 34 | PipelineStatistics* pipeline_statistics, |
| 35 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info, | 35 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info, |
| @@ -42,11 +42,11 @@ public: | |||
| 42 | ComputePipeline(const ComputePipeline&) = delete; | 42 | ComputePipeline(const ComputePipeline&) = delete; |
| 43 | 43 | ||
| 44 | void Configure(Tegra::Engines::KeplerCompute& kepler_compute, Tegra::MemoryManager& gpu_memory, | 44 | void Configure(Tegra::Engines::KeplerCompute& kepler_compute, Tegra::MemoryManager& gpu_memory, |
| 45 | VKScheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache); | 45 | Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache); |
| 46 | 46 | ||
| 47 | private: | 47 | private: |
| 48 | const Device& device; | 48 | const Device& device; |
| 49 | VKUpdateDescriptorQueue& update_descriptor_queue; | 49 | UpdateDescriptorQueue& update_descriptor_queue; |
| 50 | Shader::Info info; | 50 | Shader::Info info; |
| 51 | 51 | ||
| 52 | VideoCommon::ComputeUniformBufferSizes uniform_buffer_sizes{}; | 52 | VideoCommon::ComputeUniformBufferSizes uniform_buffer_sizes{}; |
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp index 7073a874b..c7196b64e 100644 --- a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp | |||
| @@ -121,7 +121,7 @@ vk::DescriptorSets DescriptorAllocator::AllocateDescriptors(size_t count) { | |||
| 121 | throw vk::Exception(VK_ERROR_OUT_OF_POOL_MEMORY); | 121 | throw vk::Exception(VK_ERROR_OUT_OF_POOL_MEMORY); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | DescriptorPool::DescriptorPool(const Device& device_, VKScheduler& scheduler) | 124 | DescriptorPool::DescriptorPool(const Device& device_, Scheduler& scheduler) |
| 125 | : device{device_}, master_semaphore{scheduler.GetMasterSemaphore()} {} | 125 | : device{device_}, master_semaphore{scheduler.GetMasterSemaphore()} {} |
| 126 | 126 | ||
| 127 | DescriptorPool::~DescriptorPool() = default; | 127 | DescriptorPool::~DescriptorPool() = default; |
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.h b/src/video_core/renderer_vulkan/vk_descriptor_pool.h index 30895f259..bd6696b07 100644 --- a/src/video_core/renderer_vulkan/vk_descriptor_pool.h +++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | namespace Vulkan { | 14 | namespace Vulkan { |
| 15 | 15 | ||
| 16 | class Device; | 16 | class Device; |
| 17 | class VKScheduler; | 17 | class Scheduler; |
| 18 | 18 | ||
| 19 | struct DescriptorBank; | 19 | struct DescriptorBank; |
| 20 | 20 | ||
| @@ -62,7 +62,7 @@ private: | |||
| 62 | 62 | ||
| 63 | class DescriptorPool { | 63 | class DescriptorPool { |
| 64 | public: | 64 | public: |
| 65 | explicit DescriptorPool(const Device& device, VKScheduler& scheduler); | 65 | explicit DescriptorPool(const Device& device, Scheduler& scheduler); |
| 66 | ~DescriptorPool(); | 66 | ~DescriptorPool(); |
| 67 | 67 | ||
| 68 | DescriptorPool& operator=(const DescriptorPool&) = delete; | 68 | DescriptorPool& operator=(const DescriptorPool&) = delete; |
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp index 96335f22c..c249b34d4 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp | |||
| @@ -11,10 +11,10 @@ | |||
| 11 | 11 | ||
| 12 | namespace Vulkan { | 12 | namespace Vulkan { |
| 13 | 13 | ||
| 14 | InnerFence::InnerFence(VKScheduler& scheduler_, u32 payload_, bool is_stubbed_) | 14 | InnerFence::InnerFence(Scheduler& scheduler_, u32 payload_, bool is_stubbed_) |
| 15 | : FenceBase{payload_, is_stubbed_}, scheduler{scheduler_} {} | 15 | : FenceBase{payload_, is_stubbed_}, scheduler{scheduler_} {} |
| 16 | 16 | ||
| 17 | InnerFence::InnerFence(VKScheduler& scheduler_, GPUVAddr address_, u32 payload_, bool is_stubbed_) | 17 | InnerFence::InnerFence(Scheduler& scheduler_, GPUVAddr address_, u32 payload_, bool is_stubbed_) |
| 18 | : FenceBase{address_, payload_, is_stubbed_}, scheduler{scheduler_} {} | 18 | : FenceBase{address_, payload_, is_stubbed_}, scheduler{scheduler_} {} |
| 19 | 19 | ||
| 20 | InnerFence::~InnerFence() = default; | 20 | InnerFence::~InnerFence() = default; |
| @@ -42,30 +42,29 @@ void InnerFence::Wait() { | |||
| 42 | scheduler.Wait(wait_tick); | 42 | scheduler.Wait(wait_tick); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | VKFenceManager::VKFenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_, | 45 | FenceManager::FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_, |
| 46 | TextureCache& texture_cache_, BufferCache& buffer_cache_, | 46 | TextureCache& texture_cache_, BufferCache& buffer_cache_, |
| 47 | VKQueryCache& query_cache_, const Device& device_, | 47 | QueryCache& query_cache_, const Device& device_, Scheduler& scheduler_) |
| 48 | VKScheduler& scheduler_) | ||
| 49 | : GenericFenceManager{rasterizer_, gpu_, texture_cache_, buffer_cache_, query_cache_}, | 48 | : GenericFenceManager{rasterizer_, gpu_, texture_cache_, buffer_cache_, query_cache_}, |
| 50 | scheduler{scheduler_} {} | 49 | scheduler{scheduler_} {} |
| 51 | 50 | ||
| 52 | Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) { | 51 | Fence FenceManager::CreateFence(u32 value, bool is_stubbed) { |
| 53 | return std::make_shared<InnerFence>(scheduler, value, is_stubbed); | 52 | return std::make_shared<InnerFence>(scheduler, value, is_stubbed); |
| 54 | } | 53 | } |
| 55 | 54 | ||
| 56 | Fence VKFenceManager::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) { | 55 | Fence FenceManager::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) { |
| 57 | return std::make_shared<InnerFence>(scheduler, addr, value, is_stubbed); | 56 | return std::make_shared<InnerFence>(scheduler, addr, value, is_stubbed); |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | void VKFenceManager::QueueFence(Fence& fence) { | 59 | void FenceManager::QueueFence(Fence& fence) { |
| 61 | fence->Queue(); | 60 | fence->Queue(); |
| 62 | } | 61 | } |
| 63 | 62 | ||
| 64 | bool VKFenceManager::IsFenceSignaled(Fence& fence) const { | 63 | bool FenceManager::IsFenceSignaled(Fence& fence) const { |
| 65 | return fence->IsSignaled(); | 64 | return fence->IsSignaled(); |
| 66 | } | 65 | } |
| 67 | 66 | ||
| 68 | void VKFenceManager::WaitFence(Fence& fence) { | 67 | void FenceManager::WaitFence(Fence& fence) { |
| 69 | fence->Wait(); | 68 | fence->Wait(); |
| 70 | } | 69 | } |
| 71 | 70 | ||
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h index 04eb575ce..7c0bbd80a 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.h +++ b/src/video_core/renderer_vulkan/vk_fence_manager.h | |||
| @@ -20,13 +20,13 @@ class RasterizerInterface; | |||
| 20 | namespace Vulkan { | 20 | namespace Vulkan { |
| 21 | 21 | ||
| 22 | class Device; | 22 | class Device; |
| 23 | class VKQueryCache; | 23 | class QueryCache; |
| 24 | class VKScheduler; | 24 | class Scheduler; |
| 25 | 25 | ||
| 26 | class InnerFence : public VideoCommon::FenceBase { | 26 | class InnerFence : public VideoCommon::FenceBase { |
| 27 | public: | 27 | public: |
| 28 | explicit InnerFence(VKScheduler& scheduler_, u32 payload_, bool is_stubbed_); | 28 | explicit InnerFence(Scheduler& scheduler_, u32 payload_, bool is_stubbed_); |
| 29 | explicit InnerFence(VKScheduler& scheduler_, GPUVAddr address_, u32 payload_, bool is_stubbed_); | 29 | explicit InnerFence(Scheduler& scheduler_, GPUVAddr address_, u32 payload_, bool is_stubbed_); |
| 30 | ~InnerFence(); | 30 | ~InnerFence(); |
| 31 | 31 | ||
| 32 | void Queue(); | 32 | void Queue(); |
| @@ -36,20 +36,18 @@ public: | |||
| 36 | void Wait(); | 36 | void Wait(); |
| 37 | 37 | ||
| 38 | private: | 38 | private: |
| 39 | VKScheduler& scheduler; | 39 | Scheduler& scheduler; |
| 40 | u64 wait_tick = 0; | 40 | u64 wait_tick = 0; |
| 41 | }; | 41 | }; |
| 42 | using Fence = std::shared_ptr<InnerFence>; | 42 | using Fence = std::shared_ptr<InnerFence>; |
| 43 | 43 | ||
| 44 | using GenericFenceManager = | 44 | using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCache, BufferCache, QueryCache>; |
| 45 | VideoCommon::FenceManager<Fence, TextureCache, BufferCache, VKQueryCache>; | ||
| 46 | 45 | ||
| 47 | class VKFenceManager final : public GenericFenceManager { | 46 | class FenceManager final : public GenericFenceManager { |
| 48 | public: | 47 | public: |
| 49 | explicit VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu, | 48 | explicit FenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu, |
| 50 | TextureCache& texture_cache, BufferCache& buffer_cache, | 49 | TextureCache& texture_cache, BufferCache& buffer_cache, |
| 51 | VKQueryCache& query_cache, const Device& device, | 50 | QueryCache& query_cache, const Device& device, Scheduler& scheduler); |
| 52 | VKScheduler& scheduler); | ||
| 53 | 51 | ||
| 54 | protected: | 52 | protected: |
| 55 | Fence CreateFence(u32 value, bool is_stubbed) override; | 53 | Fence CreateFence(u32 value, bool is_stubbed) override; |
| @@ -59,7 +57,7 @@ protected: | |||
| 59 | void WaitFence(Fence& fence) override; | 57 | void WaitFence(Fence& fence) override; |
| 60 | 58 | ||
| 61 | private: | 59 | private: |
| 62 | VKScheduler& scheduler; | 60 | Scheduler& scheduler; |
| 63 | }; | 61 | }; |
| 64 | 62 | ||
| 65 | } // namespace Vulkan | 63 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_fsr.cpp b/src/video_core/renderer_vulkan/vk_fsr.cpp index b563bd51d..dd450169e 100644 --- a/src/video_core/renderer_vulkan/vk_fsr.cpp +++ b/src/video_core/renderer_vulkan/vk_fsr.cpp | |||
| @@ -172,7 +172,7 @@ FSR::FSR(const Device& device_, MemoryAllocator& memory_allocator_, size_t image | |||
| 172 | CreatePipeline(); | 172 | CreatePipeline(); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | VkImageView FSR::Draw(VKScheduler& scheduler, size_t image_index, VkImageView image_view, | 175 | VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view, |
| 176 | VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect) { | 176 | VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect) { |
| 177 | 177 | ||
| 178 | UpdateDescriptorSet(image_index, image_view); | 178 | UpdateDescriptorSet(image_index, image_view); |
diff --git a/src/video_core/renderer_vulkan/vk_fsr.h b/src/video_core/renderer_vulkan/vk_fsr.h index 836592cb3..5d872861f 100644 --- a/src/video_core/renderer_vulkan/vk_fsr.h +++ b/src/video_core/renderer_vulkan/vk_fsr.h | |||
| @@ -10,13 +10,13 @@ | |||
| 10 | namespace Vulkan { | 10 | namespace Vulkan { |
| 11 | 11 | ||
| 12 | class Device; | 12 | class Device; |
| 13 | class VKScheduler; | 13 | class Scheduler; |
| 14 | 14 | ||
| 15 | class FSR { | 15 | class FSR { |
| 16 | public: | 16 | public: |
| 17 | explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, | 17 | explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, |
| 18 | VkExtent2D output_size); | 18 | VkExtent2D output_size); |
| 19 | VkImageView Draw(VKScheduler& scheduler, size_t image_index, VkImageView image_view, | 19 | VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view, |
| 20 | VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect); | 20 | VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect); |
| 21 | 21 | ||
| 22 | private: | 22 | private: |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 0179679c8..682f05335 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -215,10 +215,10 @@ ConfigureFuncPtr ConfigureFunc(const std::array<vk::ShaderModule, NUM_STAGES>& m | |||
| 215 | } // Anonymous namespace | 215 | } // Anonymous namespace |
| 216 | 216 | ||
| 217 | GraphicsPipeline::GraphicsPipeline( | 217 | GraphicsPipeline::GraphicsPipeline( |
| 218 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, | 218 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, Scheduler& scheduler_, |
| 219 | VKScheduler& scheduler_, BufferCache& buffer_cache_, TextureCache& texture_cache_, | 219 | BufferCache& buffer_cache_, TextureCache& texture_cache_, |
| 220 | VideoCore::ShaderNotify* shader_notify, const Device& device_, DescriptorPool& descriptor_pool, | 220 | VideoCore::ShaderNotify* shader_notify, const Device& device_, DescriptorPool& descriptor_pool, |
| 221 | VKUpdateDescriptorQueue& update_descriptor_queue_, Common::ThreadWorker* worker_thread, | 221 | UpdateDescriptorQueue& update_descriptor_queue_, Common::ThreadWorker* worker_thread, |
| 222 | PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, | 222 | PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, |
| 223 | const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages, | 223 | const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages, |
| 224 | const std::array<const Shader::Info*, NUM_STAGES>& infos) | 224 | const std::array<const Shader::Info*, NUM_STAGES>& infos) |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index b3bcb0a2d..e8949a9ab 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h | |||
| @@ -62,8 +62,8 @@ class Device; | |||
| 62 | class PipelineStatistics; | 62 | class PipelineStatistics; |
| 63 | class RenderPassCache; | 63 | class RenderPassCache; |
| 64 | class RescalingPushConstant; | 64 | class RescalingPushConstant; |
| 65 | class VKScheduler; | 65 | class Scheduler; |
| 66 | class VKUpdateDescriptorQueue; | 66 | class UpdateDescriptorQueue; |
| 67 | 67 | ||
| 68 | class GraphicsPipeline { | 68 | class GraphicsPipeline { |
| 69 | static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; | 69 | static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; |
| @@ -71,9 +71,9 @@ class GraphicsPipeline { | |||
| 71 | public: | 71 | public: |
| 72 | explicit GraphicsPipeline( | 72 | explicit GraphicsPipeline( |
| 73 | Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory, | 73 | Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory, |
| 74 | VKScheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache, | 74 | Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache, |
| 75 | VideoCore::ShaderNotify* shader_notify, const Device& device, | 75 | VideoCore::ShaderNotify* shader_notify, const Device& device, |
| 76 | DescriptorPool& descriptor_pool, VKUpdateDescriptorQueue& update_descriptor_queue, | 76 | DescriptorPool& descriptor_pool, UpdateDescriptorQueue& update_descriptor_queue, |
| 77 | Common::ThreadWorker* worker_thread, PipelineStatistics* pipeline_statistics, | 77 | Common::ThreadWorker* worker_thread, PipelineStatistics* pipeline_statistics, |
| 78 | RenderPassCache& render_pass_cache, const GraphicsPipelineCacheKey& key, | 78 | RenderPassCache& render_pass_cache, const GraphicsPipelineCacheKey& key, |
| 79 | std::array<vk::ShaderModule, NUM_STAGES> stages, | 79 | std::array<vk::ShaderModule, NUM_STAGES> stages, |
| @@ -125,8 +125,8 @@ private: | |||
| 125 | const Device& device; | 125 | const Device& device; |
| 126 | TextureCache& texture_cache; | 126 | TextureCache& texture_cache; |
| 127 | BufferCache& buffer_cache; | 127 | BufferCache& buffer_cache; |
| 128 | VKScheduler& scheduler; | 128 | Scheduler& scheduler; |
| 129 | VKUpdateDescriptorQueue& update_descriptor_queue; | 129 | UpdateDescriptorQueue& update_descriptor_queue; |
| 130 | 130 | ||
| 131 | void (*configure_func)(GraphicsPipeline*, bool){}; | 131 | void (*configure_func)(GraphicsPipeline*, bool){}; |
| 132 | 132 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 5196bdcf2..09e035799 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -174,7 +174,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program | |||
| 174 | case Maxwell::TessellationPrimitive::Quads: | 174 | case Maxwell::TessellationPrimitive::Quads: |
| 175 | return Shader::TessPrimitive::Quads; | 175 | return Shader::TessPrimitive::Quads; |
| 176 | } | 176 | } |
| 177 | UNREACHABLE(); | 177 | ASSERT(false); |
| 178 | return Shader::TessPrimitive::Triangles; | 178 | return Shader::TessPrimitive::Triangles; |
| 179 | }(); | 179 | }(); |
| 180 | info.tess_spacing = [&] { | 180 | info.tess_spacing = [&] { |
| @@ -187,7 +187,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program | |||
| 187 | case Maxwell::TessellationSpacing::FractionalEven: | 187 | case Maxwell::TessellationSpacing::FractionalEven: |
| 188 | return Shader::TessSpacing::FractionalEven; | 188 | return Shader::TessSpacing::FractionalEven; |
| 189 | } | 189 | } |
| 190 | UNREACHABLE(); | 190 | ASSERT(false); |
| 191 | return Shader::TessSpacing::Equal; | 191 | return Shader::TessSpacing::Equal; |
| 192 | }(); | 192 | }(); |
| 193 | break; | 193 | break; |
| @@ -262,8 +262,8 @@ bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) c | |||
| 262 | PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxwell3D& maxwell3d_, | 262 | PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxwell3D& maxwell3d_, |
| 263 | Tegra::Engines::KeplerCompute& kepler_compute_, | 263 | Tegra::Engines::KeplerCompute& kepler_compute_, |
| 264 | Tegra::MemoryManager& gpu_memory_, const Device& device_, | 264 | Tegra::MemoryManager& gpu_memory_, const Device& device_, |
| 265 | VKScheduler& scheduler_, DescriptorPool& descriptor_pool_, | 265 | Scheduler& scheduler_, DescriptorPool& descriptor_pool_, |
| 266 | VKUpdateDescriptorQueue& update_descriptor_queue_, | 266 | UpdateDescriptorQueue& update_descriptor_queue_, |
| 267 | RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_, | 267 | RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_, |
| 268 | TextureCache& texture_cache_, VideoCore::ShaderNotify& shader_notify_) | 268 | TextureCache& texture_cache_, VideoCore::ShaderNotify& shader_notify_) |
| 269 | : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_}, | 269 | : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_}, |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 5d3a9e496..127957dbf 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -81,8 +81,8 @@ class Device; | |||
| 81 | class PipelineStatistics; | 81 | class PipelineStatistics; |
| 82 | class RasterizerVulkan; | 82 | class RasterizerVulkan; |
| 83 | class RenderPassCache; | 83 | class RenderPassCache; |
| 84 | class VKScheduler; | 84 | class Scheduler; |
| 85 | class VKUpdateDescriptorQueue; | 85 | class UpdateDescriptorQueue; |
| 86 | 86 | ||
| 87 | using VideoCommon::ShaderInfo; | 87 | using VideoCommon::ShaderInfo; |
| 88 | 88 | ||
| @@ -103,8 +103,8 @@ public: | |||
| 103 | explicit PipelineCache(RasterizerVulkan& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d, | 103 | explicit PipelineCache(RasterizerVulkan& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d, |
| 104 | Tegra::Engines::KeplerCompute& kepler_compute, | 104 | Tegra::Engines::KeplerCompute& kepler_compute, |
| 105 | Tegra::MemoryManager& gpu_memory, const Device& device, | 105 | Tegra::MemoryManager& gpu_memory, const Device& device, |
| 106 | VKScheduler& scheduler, DescriptorPool& descriptor_pool, | 106 | Scheduler& scheduler, DescriptorPool& descriptor_pool, |
| 107 | VKUpdateDescriptorQueue& update_descriptor_queue, | 107 | UpdateDescriptorQueue& update_descriptor_queue, |
| 108 | RenderPassCache& render_pass_cache, BufferCache& buffer_cache, | 108 | RenderPassCache& render_pass_cache, BufferCache& buffer_cache, |
| 109 | TextureCache& texture_cache, VideoCore::ShaderNotify& shader_notify_); | 109 | TextureCache& texture_cache, VideoCore::ShaderNotify& shader_notify_); |
| 110 | ~PipelineCache(); | 110 | ~PipelineCache(); |
| @@ -138,9 +138,9 @@ private: | |||
| 138 | bool build_in_parallel); | 138 | bool build_in_parallel); |
| 139 | 139 | ||
| 140 | const Device& device; | 140 | const Device& device; |
| 141 | VKScheduler& scheduler; | 141 | Scheduler& scheduler; |
| 142 | DescriptorPool& descriptor_pool; | 142 | DescriptorPool& descriptor_pool; |
| 143 | VKUpdateDescriptorQueue& update_descriptor_queue; | 143 | UpdateDescriptorQueue& update_descriptor_queue; |
| 144 | RenderPassCache& render_pass_cache; | 144 | RenderPassCache& render_pass_cache; |
| 145 | BufferCache& buffer_cache; | 145 | BufferCache& buffer_cache; |
| 146 | TextureCache& texture_cache; | 146 | TextureCache& texture_cache; |
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index ea989d3bc..2b859c6b8 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp | |||
| @@ -26,7 +26,7 @@ constexpr VkQueryType GetTarget(QueryType type) { | |||
| 26 | 26 | ||
| 27 | } // Anonymous namespace | 27 | } // Anonymous namespace |
| 28 | 28 | ||
| 29 | QueryPool::QueryPool(const Device& device_, VKScheduler& scheduler, QueryType type_) | 29 | QueryPool::QueryPool(const Device& device_, Scheduler& scheduler, QueryType type_) |
| 30 | : ResourcePool{scheduler.GetMasterSemaphore(), GROW_STEP}, device{device_}, type{type_} {} | 30 | : ResourcePool{scheduler.GetMasterSemaphore(), GROW_STEP}, device{device_}, type{type_} {} |
| 31 | 31 | ||
| 32 | QueryPool::~QueryPool() = default; | 32 | QueryPool::~QueryPool() = default; |
| @@ -65,15 +65,15 @@ void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) { | |||
| 65 | usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false; | 65 | usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | VKQueryCache::VKQueryCache(VideoCore::RasterizerInterface& rasterizer_, | 68 | QueryCache::QueryCache(VideoCore::RasterizerInterface& rasterizer_, |
| 69 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, | 69 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, |
| 70 | const Device& device_, VKScheduler& scheduler_) | 70 | const Device& device_, Scheduler& scheduler_) |
| 71 | : QueryCacheBase{rasterizer_, maxwell3d_, gpu_memory_}, device{device_}, scheduler{scheduler_}, | 71 | : QueryCacheBase{rasterizer_, maxwell3d_, gpu_memory_}, device{device_}, scheduler{scheduler_}, |
| 72 | query_pools{ | 72 | query_pools{ |
| 73 | QueryPool{device_, scheduler_, QueryType::SamplesPassed}, | 73 | QueryPool{device_, scheduler_, QueryType::SamplesPassed}, |
| 74 | } {} | 74 | } {} |
| 75 | 75 | ||
| 76 | VKQueryCache::~VKQueryCache() { | 76 | QueryCache::~QueryCache() { |
| 77 | // TODO(Rodrigo): This is a hack to destroy all HostCounter instances before the base class | 77 | // TODO(Rodrigo): This is a hack to destroy all HostCounter instances before the base class |
| 78 | // destructor is called. The query cache should be redesigned to have a proper ownership model | 78 | // destructor is called. The query cache should be redesigned to have a proper ownership model |
| 79 | // instead of using shared pointers. | 79 | // instead of using shared pointers. |
| @@ -84,15 +84,15 @@ VKQueryCache::~VKQueryCache() { | |||
| 84 | } | 84 | } |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | std::pair<VkQueryPool, u32> VKQueryCache::AllocateQuery(QueryType type) { | 87 | std::pair<VkQueryPool, u32> QueryCache::AllocateQuery(QueryType type) { |
| 88 | return query_pools[static_cast<std::size_t>(type)].Commit(); | 88 | return query_pools[static_cast<std::size_t>(type)].Commit(); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | void VKQueryCache::Reserve(QueryType type, std::pair<VkQueryPool, u32> query) { | 91 | void QueryCache::Reserve(QueryType type, std::pair<VkQueryPool, u32> query) { |
| 92 | query_pools[static_cast<std::size_t>(type)].Reserve(query); | 92 | query_pools[static_cast<std::size_t>(type)].Reserve(query); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | HostCounter::HostCounter(VKQueryCache& cache_, std::shared_ptr<HostCounter> dependency_, | 95 | HostCounter::HostCounter(QueryCache& cache_, std::shared_ptr<HostCounter> dependency_, |
| 96 | QueryType type_) | 96 | QueryType type_) |
| 97 | : HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_}, | 97 | : HostCounterBase{std::move(dependency_)}, cache{cache_}, type{type_}, |
| 98 | query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} { | 98 | query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} { |
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.h b/src/video_core/renderer_vulkan/vk_query_cache.h index fc176d907..b0d86c4f8 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.h +++ b/src/video_core/renderer_vulkan/vk_query_cache.h | |||
| @@ -22,14 +22,14 @@ namespace Vulkan { | |||
| 22 | class CachedQuery; | 22 | class CachedQuery; |
| 23 | class Device; | 23 | class Device; |
| 24 | class HostCounter; | 24 | class HostCounter; |
| 25 | class VKQueryCache; | 25 | class QueryCache; |
| 26 | class VKScheduler; | 26 | class Scheduler; |
| 27 | 27 | ||
| 28 | using CounterStream = VideoCommon::CounterStreamBase<VKQueryCache, HostCounter>; | 28 | using CounterStream = VideoCommon::CounterStreamBase<QueryCache, HostCounter>; |
| 29 | 29 | ||
| 30 | class QueryPool final : public ResourcePool { | 30 | class QueryPool final : public ResourcePool { |
| 31 | public: | 31 | public: |
| 32 | explicit QueryPool(const Device& device, VKScheduler& scheduler, VideoCore::QueryType type); | 32 | explicit QueryPool(const Device& device, Scheduler& scheduler, VideoCore::QueryType type); |
| 33 | ~QueryPool() override; | 33 | ~QueryPool() override; |
| 34 | 34 | ||
| 35 | std::pair<VkQueryPool, u32> Commit(); | 35 | std::pair<VkQueryPool, u32> Commit(); |
| @@ -49,13 +49,13 @@ private: | |||
| 49 | std::vector<bool> usage; | 49 | std::vector<bool> usage; |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | class VKQueryCache final | 52 | class QueryCache final |
| 53 | : public VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter> { | 53 | : public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream, HostCounter> { |
| 54 | public: | 54 | public: |
| 55 | explicit VKQueryCache(VideoCore::RasterizerInterface& rasterizer_, | 55 | explicit QueryCache(VideoCore::RasterizerInterface& rasterizer_, |
| 56 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, | 56 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, |
| 57 | const Device& device_, VKScheduler& scheduler_); | 57 | const Device& device_, Scheduler& scheduler_); |
| 58 | ~VKQueryCache(); | 58 | ~QueryCache(); |
| 59 | 59 | ||
| 60 | std::pair<VkQueryPool, u32> AllocateQuery(VideoCore::QueryType type); | 60 | std::pair<VkQueryPool, u32> AllocateQuery(VideoCore::QueryType type); |
| 61 | 61 | ||
| @@ -65,19 +65,19 @@ public: | |||
| 65 | return device; | 65 | return device; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | VKScheduler& GetScheduler() const noexcept { | 68 | Scheduler& GetScheduler() const noexcept { |
| 69 | return scheduler; | 69 | return scheduler; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | private: | 72 | private: |
| 73 | const Device& device; | 73 | const Device& device; |
| 74 | VKScheduler& scheduler; | 74 | Scheduler& scheduler; |
| 75 | std::array<QueryPool, VideoCore::NumQueryTypes> query_pools; | 75 | std::array<QueryPool, VideoCore::NumQueryTypes> query_pools; |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | class HostCounter final : public VideoCommon::HostCounterBase<VKQueryCache, HostCounter> { | 78 | class HostCounter final : public VideoCommon::HostCounterBase<QueryCache, HostCounter> { |
| 79 | public: | 79 | public: |
| 80 | explicit HostCounter(VKQueryCache& cache_, std::shared_ptr<HostCounter> dependency_, | 80 | explicit HostCounter(QueryCache& cache_, std::shared_ptr<HostCounter> dependency_, |
| 81 | VideoCore::QueryType type_); | 81 | VideoCore::QueryType type_); |
| 82 | ~HostCounter(); | 82 | ~HostCounter(); |
| 83 | 83 | ||
| @@ -86,7 +86,7 @@ public: | |||
| 86 | private: | 86 | private: |
| 87 | u64 BlockingQuery() const override; | 87 | u64 BlockingQuery() const override; |
| 88 | 88 | ||
| 89 | VKQueryCache& cache; | 89 | QueryCache& cache; |
| 90 | const VideoCore::QueryType type; | 90 | const VideoCore::QueryType type; |
| 91 | const std::pair<VkQueryPool, u32> query; | 91 | const std::pair<VkQueryPool, u32> query; |
| 92 | const u64 tick; | 92 | const u64 tick; |
| @@ -94,7 +94,7 @@ private: | |||
| 94 | 94 | ||
| 95 | class CachedQuery : public VideoCommon::CachedQueryBase<HostCounter> { | 95 | class CachedQuery : public VideoCommon::CachedQueryBase<HostCounter> { |
| 96 | public: | 96 | public: |
| 97 | explicit CachedQuery(VKQueryCache&, VideoCore::QueryType, VAddr cpu_addr_, u8* host_ptr_) | 97 | explicit CachedQuery(QueryCache&, VideoCore::QueryType, VAddr cpu_addr_, u8* host_ptr_) |
| 98 | : CachedQueryBase{cpu_addr_, host_ptr_} {} | 98 | : CachedQueryBase{cpu_addr_, host_ptr_} {} |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index ce6c853c1..10f9fe7fe 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -142,9 +142,9 @@ DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instan | |||
| 142 | 142 | ||
| 143 | RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, | 143 | RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, |
| 144 | Tegra::MemoryManager& gpu_memory_, | 144 | Tegra::MemoryManager& gpu_memory_, |
| 145 | Core::Memory::Memory& cpu_memory_, VKScreenInfo& screen_info_, | 145 | Core::Memory::Memory& cpu_memory_, ScreenInfo& screen_info_, |
| 146 | const Device& device_, MemoryAllocator& memory_allocator_, | 146 | const Device& device_, MemoryAllocator& memory_allocator_, |
| 147 | StateTracker& state_tracker_, VKScheduler& scheduler_) | 147 | StateTracker& state_tracker_, Scheduler& scheduler_) |
| 148 | : RasterizerAccelerated{cpu_memory_}, gpu{gpu_}, | 148 | : RasterizerAccelerated{cpu_memory_}, gpu{gpu_}, |
| 149 | gpu_memory{gpu_memory_}, maxwell3d{gpu.Maxwell3D()}, kepler_compute{gpu.KeplerCompute()}, | 149 | gpu_memory{gpu_memory_}, maxwell3d{gpu.Maxwell3D()}, kepler_compute{gpu.KeplerCompute()}, |
| 150 | screen_info{screen_info_}, device{device_}, memory_allocator{memory_allocator_}, | 150 | screen_info{screen_info_}, device{device_}, memory_allocator{memory_allocator_}, |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 97eeedd9e..0370ea39b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -38,7 +38,7 @@ class Maxwell3D; | |||
| 38 | 38 | ||
| 39 | namespace Vulkan { | 39 | namespace Vulkan { |
| 40 | 40 | ||
| 41 | struct VKScreenInfo; | 41 | struct ScreenInfo; |
| 42 | 42 | ||
| 43 | class StateTracker; | 43 | class StateTracker; |
| 44 | 44 | ||
| @@ -58,9 +58,9 @@ class RasterizerVulkan final : public VideoCore::RasterizerAccelerated { | |||
| 58 | public: | 58 | public: |
| 59 | explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, | 59 | explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, |
| 60 | Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_, | 60 | Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_, |
| 61 | VKScreenInfo& screen_info_, const Device& device_, | 61 | ScreenInfo& screen_info_, const Device& device_, |
| 62 | MemoryAllocator& memory_allocator_, StateTracker& state_tracker_, | 62 | MemoryAllocator& memory_allocator_, StateTracker& state_tracker_, |
| 63 | VKScheduler& scheduler_); | 63 | Scheduler& scheduler_); |
| 64 | ~RasterizerVulkan() override; | 64 | ~RasterizerVulkan() override; |
| 65 | 65 | ||
| 66 | void Draw(bool is_indexed, bool is_instanced) override; | 66 | void Draw(bool is_indexed, bool is_instanced) override; |
| @@ -138,15 +138,15 @@ private: | |||
| 138 | Tegra::Engines::Maxwell3D& maxwell3d; | 138 | Tegra::Engines::Maxwell3D& maxwell3d; |
| 139 | Tegra::Engines::KeplerCompute& kepler_compute; | 139 | Tegra::Engines::KeplerCompute& kepler_compute; |
| 140 | 140 | ||
| 141 | VKScreenInfo& screen_info; | 141 | ScreenInfo& screen_info; |
| 142 | const Device& device; | 142 | const Device& device; |
| 143 | MemoryAllocator& memory_allocator; | 143 | MemoryAllocator& memory_allocator; |
| 144 | StateTracker& state_tracker; | 144 | StateTracker& state_tracker; |
| 145 | VKScheduler& scheduler; | 145 | Scheduler& scheduler; |
| 146 | 146 | ||
| 147 | StagingBufferPool staging_pool; | 147 | StagingBufferPool staging_pool; |
| 148 | DescriptorPool descriptor_pool; | 148 | DescriptorPool descriptor_pool; |
| 149 | VKUpdateDescriptorQueue update_descriptor_queue; | 149 | UpdateDescriptorQueue update_descriptor_queue; |
| 150 | BlitImageHelper blit_image; | 150 | BlitImageHelper blit_image; |
| 151 | ASTCDecoderPass astc_decoder_pass; | 151 | ASTCDecoderPass astc_decoder_pass; |
| 152 | RenderPassCache render_pass_cache; | 152 | RenderPassCache render_pass_cache; |
| @@ -156,9 +156,9 @@ private: | |||
| 156 | BufferCacheRuntime buffer_cache_runtime; | 156 | BufferCacheRuntime buffer_cache_runtime; |
| 157 | BufferCache buffer_cache; | 157 | BufferCache buffer_cache; |
| 158 | PipelineCache pipeline_cache; | 158 | PipelineCache pipeline_cache; |
| 159 | VKQueryCache query_cache; | 159 | QueryCache query_cache; |
| 160 | AccelerateDMA accelerate_dma; | 160 | AccelerateDMA accelerate_dma; |
| 161 | VKFenceManager fence_manager; | 161 | FenceManager fence_manager; |
| 162 | 162 | ||
| 163 | vk::Event wfi_event; | 163 | vk::Event wfi_event; |
| 164 | 164 | ||
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index a7261cf97..a331ff37e 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp | |||
| @@ -21,7 +21,7 @@ namespace Vulkan { | |||
| 21 | 21 | ||
| 22 | MICROPROFILE_DECLARE(Vulkan_WaitForWorker); | 22 | MICROPROFILE_DECLARE(Vulkan_WaitForWorker); |
| 23 | 23 | ||
| 24 | void VKScheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf) { | 24 | void Scheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf) { |
| 25 | auto command = first; | 25 | auto command = first; |
| 26 | while (command != nullptr) { | 26 | while (command != nullptr) { |
| 27 | auto next = command->GetNext(); | 27 | auto next = command->GetNext(); |
| @@ -35,7 +35,7 @@ void VKScheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf) { | |||
| 35 | last = nullptr; | 35 | last = nullptr; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | VKScheduler::VKScheduler(const Device& device_, StateTracker& state_tracker_) | 38 | Scheduler::Scheduler(const Device& device_, StateTracker& state_tracker_) |
| 39 | : device{device_}, state_tracker{state_tracker_}, | 39 | : device{device_}, state_tracker{state_tracker_}, |
| 40 | master_semaphore{std::make_unique<MasterSemaphore>(device)}, | 40 | master_semaphore{std::make_unique<MasterSemaphore>(device)}, |
| 41 | command_pool{std::make_unique<CommandPool>(*master_semaphore, device)} { | 41 | command_pool{std::make_unique<CommandPool>(*master_semaphore, device)} { |
| @@ -44,14 +44,14 @@ VKScheduler::VKScheduler(const Device& device_, StateTracker& state_tracker_) | |||
| 44 | worker_thread = std::jthread([this](std::stop_token token) { WorkerThread(token); }); | 44 | worker_thread = std::jthread([this](std::stop_token token) { WorkerThread(token); }); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | VKScheduler::~VKScheduler() = default; | 47 | Scheduler::~Scheduler() = default; |
| 48 | 48 | ||
| 49 | void VKScheduler::Flush(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { | 49 | void Scheduler::Flush(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { |
| 50 | SubmitExecution(signal_semaphore, wait_semaphore); | 50 | SubmitExecution(signal_semaphore, wait_semaphore); |
| 51 | AllocateNewContext(); | 51 | AllocateNewContext(); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | void VKScheduler::Finish(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { | 54 | void Scheduler::Finish(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { |
| 55 | const u64 presubmit_tick = CurrentTick(); | 55 | const u64 presubmit_tick = CurrentTick(); |
| 56 | SubmitExecution(signal_semaphore, wait_semaphore); | 56 | SubmitExecution(signal_semaphore, wait_semaphore); |
| 57 | WaitWorker(); | 57 | WaitWorker(); |
| @@ -59,7 +59,7 @@ void VKScheduler::Finish(VkSemaphore signal_semaphore, VkSemaphore wait_semaphor | |||
| 59 | AllocateNewContext(); | 59 | AllocateNewContext(); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | void VKScheduler::WaitWorker() { | 62 | void Scheduler::WaitWorker() { |
| 63 | MICROPROFILE_SCOPE(Vulkan_WaitForWorker); | 63 | MICROPROFILE_SCOPE(Vulkan_WaitForWorker); |
| 64 | DispatchWork(); | 64 | DispatchWork(); |
| 65 | 65 | ||
| @@ -67,7 +67,7 @@ void VKScheduler::WaitWorker() { | |||
| 67 | wait_cv.wait(lock, [this] { return work_queue.empty(); }); | 67 | wait_cv.wait(lock, [this] { return work_queue.empty(); }); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | void VKScheduler::DispatchWork() { | 70 | void Scheduler::DispatchWork() { |
| 71 | if (chunk->Empty()) { | 71 | if (chunk->Empty()) { |
| 72 | return; | 72 | return; |
| 73 | } | 73 | } |
| @@ -79,7 +79,7 @@ void VKScheduler::DispatchWork() { | |||
| 79 | AcquireNewChunk(); | 79 | AcquireNewChunk(); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | void VKScheduler::RequestRenderpass(const Framebuffer* framebuffer) { | 82 | void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) { |
| 83 | const VkRenderPass renderpass = framebuffer->RenderPass(); | 83 | const VkRenderPass renderpass = framebuffer->RenderPass(); |
| 84 | const VkFramebuffer framebuffer_handle = framebuffer->Handle(); | 84 | const VkFramebuffer framebuffer_handle = framebuffer->Handle(); |
| 85 | const VkExtent2D render_area = framebuffer->RenderArea(); | 85 | const VkExtent2D render_area = framebuffer->RenderArea(); |
| @@ -114,11 +114,11 @@ void VKScheduler::RequestRenderpass(const Framebuffer* framebuffer) { | |||
| 114 | renderpass_image_ranges = framebuffer->ImageRanges(); | 114 | renderpass_image_ranges = framebuffer->ImageRanges(); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | void VKScheduler::RequestOutsideRenderPassOperationContext() { | 117 | void Scheduler::RequestOutsideRenderPassOperationContext() { |
| 118 | EndRenderPass(); | 118 | EndRenderPass(); |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | bool VKScheduler::UpdateGraphicsPipeline(GraphicsPipeline* pipeline) { | 121 | bool Scheduler::UpdateGraphicsPipeline(GraphicsPipeline* pipeline) { |
| 122 | if (state.graphics_pipeline == pipeline) { | 122 | if (state.graphics_pipeline == pipeline) { |
| 123 | return false; | 123 | return false; |
| 124 | } | 124 | } |
| @@ -126,7 +126,7 @@ bool VKScheduler::UpdateGraphicsPipeline(GraphicsPipeline* pipeline) { | |||
| 126 | return true; | 126 | return true; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | bool VKScheduler::UpdateRescaling(bool is_rescaling) { | 129 | bool Scheduler::UpdateRescaling(bool is_rescaling) { |
| 130 | if (state.rescaling_defined && is_rescaling == state.is_rescaling) { | 130 | if (state.rescaling_defined && is_rescaling == state.is_rescaling) { |
| 131 | return false; | 131 | return false; |
| 132 | } | 132 | } |
| @@ -135,7 +135,7 @@ bool VKScheduler::UpdateRescaling(bool is_rescaling) { | |||
| 135 | return true; | 135 | return true; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | void VKScheduler::WorkerThread(std::stop_token stop_token) { | 138 | void Scheduler::WorkerThread(std::stop_token stop_token) { |
| 139 | Common::SetCurrentThreadName("yuzu:VulkanWorker"); | 139 | Common::SetCurrentThreadName("yuzu:VulkanWorker"); |
| 140 | do { | 140 | do { |
| 141 | std::unique_ptr<CommandChunk> work; | 141 | std::unique_ptr<CommandChunk> work; |
| @@ -161,7 +161,7 @@ void VKScheduler::WorkerThread(std::stop_token stop_token) { | |||
| 161 | } while (!stop_token.stop_requested()); | 161 | } while (!stop_token.stop_requested()); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | void VKScheduler::AllocateWorkerCommandBuffer() { | 164 | void Scheduler::AllocateWorkerCommandBuffer() { |
| 165 | current_cmdbuf = vk::CommandBuffer(command_pool->Commit(), device.GetDispatchLoader()); | 165 | current_cmdbuf = vk::CommandBuffer(command_pool->Commit(), device.GetDispatchLoader()); |
| 166 | current_cmdbuf.Begin({ | 166 | current_cmdbuf.Begin({ |
| 167 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, | 167 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| @@ -171,7 +171,7 @@ void VKScheduler::AllocateWorkerCommandBuffer() { | |||
| 171 | }); | 171 | }); |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | void VKScheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { | 174 | void Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_semaphore) { |
| 175 | EndPendingOperations(); | 175 | EndPendingOperations(); |
| 176 | InvalidateState(); | 176 | InvalidateState(); |
| 177 | 177 | ||
| @@ -225,25 +225,25 @@ void VKScheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait | |||
| 225 | DispatchWork(); | 225 | DispatchWork(); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | void VKScheduler::AllocateNewContext() { | 228 | void Scheduler::AllocateNewContext() { |
| 229 | // Enable counters once again. These are disabled when a command buffer is finished. | 229 | // Enable counters once again. These are disabled when a command buffer is finished. |
| 230 | if (query_cache) { | 230 | if (query_cache) { |
| 231 | query_cache->UpdateCounters(); | 231 | query_cache->UpdateCounters(); |
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | void VKScheduler::InvalidateState() { | 235 | void Scheduler::InvalidateState() { |
| 236 | state.graphics_pipeline = nullptr; | 236 | state.graphics_pipeline = nullptr; |
| 237 | state.rescaling_defined = false; | 237 | state.rescaling_defined = false; |
| 238 | state_tracker.InvalidateCommandBufferState(); | 238 | state_tracker.InvalidateCommandBufferState(); |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | void VKScheduler::EndPendingOperations() { | 241 | void Scheduler::EndPendingOperations() { |
| 242 | query_cache->DisableStreams(); | 242 | query_cache->DisableStreams(); |
| 243 | EndRenderPass(); | 243 | EndRenderPass(); |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | void VKScheduler::EndRenderPass() { | 246 | void Scheduler::EndRenderPass() { |
| 247 | if (!state.renderpass) { | 247 | if (!state.renderpass) { |
| 248 | return; | 248 | return; |
| 249 | } | 249 | } |
| @@ -280,7 +280,7 @@ void VKScheduler::EndRenderPass() { | |||
| 280 | num_renderpass_images = 0; | 280 | num_renderpass_images = 0; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | void VKScheduler::AcquireNewChunk() { | 283 | void Scheduler::AcquireNewChunk() { |
| 284 | std::scoped_lock lock{reserve_mutex}; | 284 | std::scoped_lock lock{reserve_mutex}; |
| 285 | if (chunk_reserve.empty()) { | 285 | if (chunk_reserve.empty()) { |
| 286 | chunk = std::make_unique<CommandChunk>(); | 286 | chunk = std::make_unique<CommandChunk>(); |
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 7a2200474..c04aad08f 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h | |||
| @@ -22,14 +22,14 @@ class Device; | |||
| 22 | class Framebuffer; | 22 | class Framebuffer; |
| 23 | class GraphicsPipeline; | 23 | class GraphicsPipeline; |
| 24 | class StateTracker; | 24 | class StateTracker; |
| 25 | class VKQueryCache; | 25 | class QueryCache; |
| 26 | 26 | ||
| 27 | /// The scheduler abstracts command buffer and fence management with an interface that's able to do | 27 | /// The scheduler abstracts command buffer and fence management with an interface that's able to do |
| 28 | /// OpenGL-like operations on Vulkan command buffers. | 28 | /// OpenGL-like operations on Vulkan command buffers. |
| 29 | class VKScheduler { | 29 | class Scheduler { |
| 30 | public: | 30 | public: |
| 31 | explicit VKScheduler(const Device& device, StateTracker& state_tracker); | 31 | explicit Scheduler(const Device& device, StateTracker& state_tracker); |
| 32 | ~VKScheduler(); | 32 | ~Scheduler(); |
| 33 | 33 | ||
| 34 | /// Sends the current execution context to the GPU. | 34 | /// Sends the current execution context to the GPU. |
| 35 | void Flush(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr); | 35 | void Flush(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr); |
| @@ -61,7 +61,7 @@ public: | |||
| 61 | void InvalidateState(); | 61 | void InvalidateState(); |
| 62 | 62 | ||
| 63 | /// Assigns the query cache. | 63 | /// Assigns the query cache. |
| 64 | void SetQueryCache(VKQueryCache& query_cache_) { | 64 | void SetQueryCache(QueryCache& query_cache_) { |
| 65 | query_cache = &query_cache_; | 65 | query_cache = &query_cache_; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| @@ -212,7 +212,7 @@ private: | |||
| 212 | std::unique_ptr<MasterSemaphore> master_semaphore; | 212 | std::unique_ptr<MasterSemaphore> master_semaphore; |
| 213 | std::unique_ptr<CommandPool> command_pool; | 213 | std::unique_ptr<CommandPool> command_pool; |
| 214 | 214 | ||
| 215 | VKQueryCache* query_cache = nullptr; | 215 | QueryCache* query_cache = nullptr; |
| 216 | 216 | ||
| 217 | vk::CommandBuffer current_cmdbuf; | 217 | vk::CommandBuffer current_cmdbuf; |
| 218 | 218 | ||
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 31ce2f815..06f68d09a 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | |||
| @@ -85,7 +85,7 @@ size_t Region(size_t iterator) noexcept { | |||
| 85 | } // Anonymous namespace | 85 | } // Anonymous namespace |
| 86 | 86 | ||
| 87 | StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, | 87 | StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_, |
| 88 | VKScheduler& scheduler_) | 88 | Scheduler& scheduler_) |
| 89 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_} { | 89 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_} { |
| 90 | const vk::Device& dev = device.GetLogical(); | 90 | const vk::Device& dev = device.GetLogical(); |
| 91 | stream_buffer = dev.CreateBuffer(VkBufferCreateInfo{ | 91 | stream_buffer = dev.CreateBuffer(VkBufferCreateInfo{ |
| @@ -263,7 +263,7 @@ StagingBufferPool::StagingBuffersCache& StagingBufferPool::GetCache(MemoryUsage | |||
| 263 | case MemoryUsage::Download: | 263 | case MemoryUsage::Download: |
| 264 | return download_cache; | 264 | return download_cache; |
| 265 | default: | 265 | default: |
| 266 | UNREACHABLE_MSG("Invalid memory usage={}", usage); | 266 | ASSERT_MSG(false, "Invalid memory usage={}", usage); |
| 267 | return upload_cache; | 267 | return upload_cache; |
| 268 | } | 268 | } |
| 269 | } | 269 | } |
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h index d4d7efa68..91dc84da8 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | namespace Vulkan { | 14 | namespace Vulkan { |
| 15 | 15 | ||
| 16 | class Device; | 16 | class Device; |
| 17 | class VKScheduler; | 17 | class Scheduler; |
| 18 | 18 | ||
| 19 | struct StagingBufferRef { | 19 | struct StagingBufferRef { |
| 20 | VkBuffer buffer; | 20 | VkBuffer buffer; |
| @@ -27,7 +27,7 @@ public: | |||
| 27 | static constexpr size_t NUM_SYNCS = 16; | 27 | static constexpr size_t NUM_SYNCS = 16; |
| 28 | 28 | ||
| 29 | explicit StagingBufferPool(const Device& device, MemoryAllocator& memory_allocator, | 29 | explicit StagingBufferPool(const Device& device, MemoryAllocator& memory_allocator, |
| 30 | VKScheduler& scheduler); | 30 | Scheduler& scheduler); |
| 31 | ~StagingBufferPool(); | 31 | ~StagingBufferPool(); |
| 32 | 32 | ||
| 33 | StagingBufferRef Request(size_t size, MemoryUsage usage); | 33 | StagingBufferRef Request(size_t size, MemoryUsage usage); |
| @@ -82,7 +82,7 @@ private: | |||
| 82 | 82 | ||
| 83 | const Device& device; | 83 | const Device& device; |
| 84 | MemoryAllocator& memory_allocator; | 84 | MemoryAllocator& memory_allocator; |
| 85 | VKScheduler& scheduler; | 85 | Scheduler& scheduler; |
| 86 | 86 | ||
| 87 | vk::Buffer stream_buffer; | 87 | vk::Buffer stream_buffer; |
| 88 | vk::DeviceMemory stream_memory; | 88 | vk::DeviceMemory stream_memory; |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 7da81551a..a0c26a72a 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp | |||
| @@ -64,15 +64,15 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi | |||
| 64 | 64 | ||
| 65 | } // Anonymous namespace | 65 | } // Anonymous namespace |
| 66 | 66 | ||
| 67 | VKSwapchain::VKSwapchain(VkSurfaceKHR surface_, const Device& device_, VKScheduler& scheduler_, | 67 | Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, u32 width, |
| 68 | u32 width, u32 height, bool srgb) | 68 | u32 height, bool srgb) |
| 69 | : surface{surface_}, device{device_}, scheduler{scheduler_} { | 69 | : surface{surface_}, device{device_}, scheduler{scheduler_} { |
| 70 | Create(width, height, srgb); | 70 | Create(width, height, srgb); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | VKSwapchain::~VKSwapchain() = default; | 73 | Swapchain::~Swapchain() = default; |
| 74 | 74 | ||
| 75 | void VKSwapchain::Create(u32 width, u32 height, bool srgb) { | 75 | void Swapchain::Create(u32 width, u32 height, bool srgb) { |
| 76 | is_outdated = false; | 76 | is_outdated = false; |
| 77 | is_suboptimal = false; | 77 | is_suboptimal = false; |
| 78 | 78 | ||
| @@ -93,7 +93,7 @@ void VKSwapchain::Create(u32 width, u32 height, bool srgb) { | |||
| 93 | resource_ticks.resize(image_count); | 93 | resource_ticks.resize(image_count); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | void VKSwapchain::AcquireNextImage() { | 96 | void Swapchain::AcquireNextImage() { |
| 97 | const VkResult result = device.GetLogical().AcquireNextImageKHR( | 97 | const VkResult result = device.GetLogical().AcquireNextImageKHR( |
| 98 | *swapchain, std::numeric_limits<u64>::max(), *present_semaphores[frame_index], | 98 | *swapchain, std::numeric_limits<u64>::max(), *present_semaphores[frame_index], |
| 99 | VK_NULL_HANDLE, &image_index); | 99 | VK_NULL_HANDLE, &image_index); |
| @@ -114,7 +114,7 @@ void VKSwapchain::AcquireNextImage() { | |||
| 114 | resource_ticks[image_index] = scheduler.CurrentTick(); | 114 | resource_ticks[image_index] = scheduler.CurrentTick(); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | void VKSwapchain::Present(VkSemaphore render_semaphore) { | 117 | void Swapchain::Present(VkSemaphore render_semaphore) { |
| 118 | const auto present_queue{device.GetPresentQueue()}; | 118 | const auto present_queue{device.GetPresentQueue()}; |
| 119 | const VkPresentInfoKHR present_info{ | 119 | const VkPresentInfoKHR present_info{ |
| 120 | .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, | 120 | .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, |
| @@ -145,8 +145,8 @@ void VKSwapchain::Present(VkSemaphore render_semaphore) { | |||
| 145 | } | 145 | } |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, | 148 | void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, |
| 149 | u32 height, bool srgb) { | 149 | bool srgb) { |
| 150 | const auto physical_device{device.GetPhysical()}; | 150 | const auto physical_device{device.GetPhysical()}; |
| 151 | const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; | 151 | const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; |
| 152 | const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; | 152 | const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; |
| @@ -212,13 +212,13 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, | |||
| 212 | image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; | 212 | image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | void VKSwapchain::CreateSemaphores() { | 215 | void Swapchain::CreateSemaphores() { |
| 216 | present_semaphores.resize(image_count); | 216 | present_semaphores.resize(image_count); |
| 217 | std::ranges::generate(present_semaphores, | 217 | std::ranges::generate(present_semaphores, |
| 218 | [this] { return device.GetLogical().CreateSemaphore(); }); | 218 | [this] { return device.GetLogical().CreateSemaphore(); }); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | void VKSwapchain::CreateImageViews() { | 221 | void Swapchain::CreateImageViews() { |
| 222 | VkImageViewCreateInfo ci{ | 222 | VkImageViewCreateInfo ci{ |
| 223 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, | 223 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
| 224 | .pNext = nullptr, | 224 | .pNext = nullptr, |
| @@ -250,7 +250,7 @@ void VKSwapchain::CreateImageViews() { | |||
| 250 | } | 250 | } |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | void VKSwapchain::Destroy() { | 253 | void Swapchain::Destroy() { |
| 254 | frame_index = 0; | 254 | frame_index = 0; |
| 255 | present_semaphores.clear(); | 255 | present_semaphores.clear(); |
| 256 | framebuffers.clear(); | 256 | framebuffers.clear(); |
| @@ -258,11 +258,11 @@ void VKSwapchain::Destroy() { | |||
| 258 | swapchain.reset(); | 258 | swapchain.reset(); |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | bool VKSwapchain::HasFpsUnlockChanged() const { | 261 | bool Swapchain::HasFpsUnlockChanged() const { |
| 262 | return current_fps_unlocked != Settings::values.disable_fps_limit.GetValue(); | 262 | return current_fps_unlocked != Settings::values.disable_fps_limit.GetValue(); |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | bool VKSwapchain::NeedsPresentModeUpdate() const { | 265 | bool Swapchain::NeedsPresentModeUpdate() const { |
| 266 | // Mailbox present mode is the ideal for all scenarios. If it is not available, | 266 | // Mailbox present mode is the ideal for all scenarios. If it is not available, |
| 267 | // A different present mode is needed to support unlocked FPS above the monitor's refresh rate. | 267 | // A different present mode is needed to support unlocked FPS above the monitor's refresh rate. |
| 268 | return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged(); | 268 | return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged(); |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index 6d9d8fec9..111b3902d 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h | |||
| @@ -15,13 +15,13 @@ struct FramebufferLayout; | |||
| 15 | namespace Vulkan { | 15 | namespace Vulkan { |
| 16 | 16 | ||
| 17 | class Device; | 17 | class Device; |
| 18 | class VKScheduler; | 18 | class Scheduler; |
| 19 | 19 | ||
| 20 | class VKSwapchain { | 20 | class Swapchain { |
| 21 | public: | 21 | public: |
| 22 | explicit VKSwapchain(VkSurfaceKHR surface, const Device& device, VKScheduler& scheduler, | 22 | explicit Swapchain(VkSurfaceKHR surface, const Device& device, Scheduler& scheduler, u32 width, |
| 23 | u32 width, u32 height, bool srgb); | 23 | u32 height, bool srgb); |
| 24 | ~VKSwapchain(); | 24 | ~Swapchain(); |
| 25 | 25 | ||
| 26 | /// Creates (or recreates) the swapchain with a given size. | 26 | /// Creates (or recreates) the swapchain with a given size. |
| 27 | void Create(u32 width, u32 height, bool srgb); | 27 | void Create(u32 width, u32 height, bool srgb); |
| @@ -94,7 +94,7 @@ private: | |||
| 94 | 94 | ||
| 95 | const VkSurfaceKHR surface; | 95 | const VkSurfaceKHR surface; |
| 96 | const Device& device; | 96 | const Device& device; |
| 97 | VKScheduler& scheduler; | 97 | Scheduler& scheduler; |
| 98 | 98 | ||
| 99 | vk::SwapchainKHR swapchain; | 99 | vk::SwapchainKHR swapchain; |
| 100 | 100 | ||
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 353594293..ba6d81420 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -70,7 +70,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 70 | case ImageType::Buffer: | 70 | case ImageType::Buffer: |
| 71 | break; | 71 | break; |
| 72 | } | 72 | } |
| 73 | UNREACHABLE_MSG("Invalid image type={}", type); | 73 | ASSERT_MSG(false, "Invalid image type={}", type); |
| 74 | return {}; | 74 | return {}; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| @@ -87,7 +87,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 87 | case 16: | 87 | case 16: |
| 88 | return VK_SAMPLE_COUNT_16_BIT; | 88 | return VK_SAMPLE_COUNT_16_BIT; |
| 89 | default: | 89 | default: |
| 90 | UNREACHABLE_MSG("Invalid number of samples={}", num_samples); | 90 | ASSERT_MSG(false, "Invalid number of samples={}", num_samples); |
| 91 | return VK_SAMPLE_COUNT_1_BIT; | 91 | return VK_SAMPLE_COUNT_1_BIT; |
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| @@ -107,7 +107,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 107 | usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; | 107 | usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; |
| 108 | break; | 108 | break; |
| 109 | default: | 109 | default: |
| 110 | UNREACHABLE_MSG("Invalid surface type"); | 110 | ASSERT_MSG(false, "Invalid surface type"); |
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | if (info.storage) { | 113 | if (info.storage) { |
| @@ -179,7 +179,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 179 | case VideoCore::Surface::SurfaceType::DepthStencil: | 179 | case VideoCore::Surface::SurfaceType::DepthStencil: |
| 180 | return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; | 180 | return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; |
| 181 | default: | 181 | default: |
| 182 | UNREACHABLE_MSG("Invalid surface type"); | 182 | ASSERT_MSG(false, "Invalid surface type"); |
| 183 | return VkImageAspectFlags{}; | 183 | return VkImageAspectFlags{}; |
| 184 | } | 184 | } |
| 185 | } | 185 | } |
| @@ -221,7 +221,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 221 | case SwizzleSource::OneInt: | 221 | case SwizzleSource::OneInt: |
| 222 | return VK_COMPONENT_SWIZZLE_ONE; | 222 | return VK_COMPONENT_SWIZZLE_ONE; |
| 223 | } | 223 | } |
| 224 | UNREACHABLE_MSG("Invalid swizzle={}", swizzle); | 224 | ASSERT_MSG(false, "Invalid swizzle={}", swizzle); |
| 225 | return VK_COMPONENT_SWIZZLE_ZERO; | 225 | return VK_COMPONENT_SWIZZLE_ZERO; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| @@ -242,10 +242,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 242 | case Shader::TextureType::ColorArrayCube: | 242 | case Shader::TextureType::ColorArrayCube: |
| 243 | return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; | 243 | return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; |
| 244 | case Shader::TextureType::Buffer: | 244 | case Shader::TextureType::Buffer: |
| 245 | UNREACHABLE_MSG("Texture buffers can't be image views"); | 245 | ASSERT_MSG(false, "Texture buffers can't be image views"); |
| 246 | return VK_IMAGE_VIEW_TYPE_1D; | 246 | return VK_IMAGE_VIEW_TYPE_1D; |
| 247 | } | 247 | } |
| 248 | UNREACHABLE_MSG("Invalid image view type={}", type); | 248 | ASSERT_MSG(false, "Invalid image view type={}", type); |
| 249 | return VK_IMAGE_VIEW_TYPE_2D; | 249 | return VK_IMAGE_VIEW_TYPE_2D; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| @@ -269,10 +269,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { | |||
| 269 | UNIMPLEMENTED_MSG("Rect image view"); | 269 | UNIMPLEMENTED_MSG("Rect image view"); |
| 270 | return VK_IMAGE_VIEW_TYPE_2D; | 270 | return VK_IMAGE_VIEW_TYPE_2D; |
| 271 | case VideoCommon::ImageViewType::Buffer: | 271 | case VideoCommon::ImageViewType::Buffer: |
| 272 | UNREACHABLE_MSG("Texture buffers can't be image views"); | 272 | ASSERT_MSG(false, "Texture buffers can't be image views"); |
| 273 | return VK_IMAGE_VIEW_TYPE_1D; | 273 | return VK_IMAGE_VIEW_TYPE_1D; |
| 274 | } | 274 | } |
| 275 | UNREACHABLE_MSG("Invalid image view type={}", type); | 275 | ASSERT_MSG(false, "Invalid image view type={}", type); |
| 276 | return VK_IMAGE_VIEW_TYPE_2D; | 276 | return VK_IMAGE_VIEW_TYPE_2D; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| @@ -644,11 +644,11 @@ struct RangedBarrierRange { | |||
| 644 | case Shader::ImageFormat::R32G32B32A32_UINT: | 644 | case Shader::ImageFormat::R32G32B32A32_UINT: |
| 645 | return VK_FORMAT_R32G32B32A32_UINT; | 645 | return VK_FORMAT_R32G32B32A32_UINT; |
| 646 | } | 646 | } |
| 647 | UNREACHABLE_MSG("Invalid image format={}", format); | 647 | ASSERT_MSG(false, "Invalid image format={}", format); |
| 648 | return VK_FORMAT_R32_UINT; | 648 | return VK_FORMAT_R32_UINT; |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, | 651 | void BlitScale(Scheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, |
| 652 | VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution, | 652 | VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution, |
| 653 | bool up_scaling = true) { | 653 | bool up_scaling = true) { |
| 654 | const bool is_2d = info.type == ImageType::e2D; | 654 | const bool is_2d = info.type == ImageType::e2D; |
| @@ -788,7 +788,7 @@ void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, con | |||
| 788 | } | 788 | } |
| 789 | } // Anonymous namespace | 789 | } // Anonymous namespace |
| 790 | 790 | ||
| 791 | TextureCacheRuntime::TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_, | 791 | TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& scheduler_, |
| 792 | MemoryAllocator& memory_allocator_, | 792 | MemoryAllocator& memory_allocator_, |
| 793 | StagingBufferPool& staging_buffer_pool_, | 793 | StagingBufferPool& staging_buffer_pool_, |
| 794 | BlitImageHelper& blit_image_helper_, | 794 | BlitImageHelper& blit_image_helper_, |
| @@ -1596,7 +1596,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI | |||
| 1596 | UNIMPLEMENTED(); | 1596 | UNIMPLEMENTED(); |
| 1597 | break; | 1597 | break; |
| 1598 | case VideoCommon::ImageViewType::Buffer: | 1598 | case VideoCommon::ImageViewType::Buffer: |
| 1599 | UNREACHABLE(); | 1599 | ASSERT(false); |
| 1600 | break; | 1600 | break; |
| 1601 | } | 1601 | } |
| 1602 | } | 1602 | } |
| @@ -1822,7 +1822,7 @@ void TextureCacheRuntime::AccelerateImageUpload( | |||
| 1822 | if (IsPixelFormatASTC(image.info.format)) { | 1822 | if (IsPixelFormatASTC(image.info.format)) { |
| 1823 | return astc_decoder_pass.Assemble(image, map, swizzles); | 1823 | return astc_decoder_pass.Assemble(image, map, swizzles); |
| 1824 | } | 1824 | } |
| 1825 | UNREACHABLE(); | 1825 | ASSERT(false); |
| 1826 | } | 1826 | } |
| 1827 | 1827 | ||
| 1828 | } // namespace Vulkan | 1828 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 356dcc703..69f06ee7b 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -33,11 +33,11 @@ class ImageView; | |||
| 33 | class Framebuffer; | 33 | class Framebuffer; |
| 34 | class RenderPassCache; | 34 | class RenderPassCache; |
| 35 | class StagingBufferPool; | 35 | class StagingBufferPool; |
| 36 | class VKScheduler; | 36 | class Scheduler; |
| 37 | 37 | ||
| 38 | class TextureCacheRuntime { | 38 | class TextureCacheRuntime { |
| 39 | public: | 39 | public: |
| 40 | explicit TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_, | 40 | explicit TextureCacheRuntime(const Device& device_, Scheduler& scheduler_, |
| 41 | MemoryAllocator& memory_allocator_, | 41 | MemoryAllocator& memory_allocator_, |
| 42 | StagingBufferPool& staging_buffer_pool_, | 42 | StagingBufferPool& staging_buffer_pool_, |
| 43 | BlitImageHelper& blit_image_helper_, | 43 | BlitImageHelper& blit_image_helper_, |
| @@ -93,7 +93,7 @@ public: | |||
| 93 | [[nodiscard]] VkBuffer GetTemporaryBuffer(size_t needed_size); | 93 | [[nodiscard]] VkBuffer GetTemporaryBuffer(size_t needed_size); |
| 94 | 94 | ||
| 95 | const Device& device; | 95 | const Device& device; |
| 96 | VKScheduler& scheduler; | 96 | Scheduler& scheduler; |
| 97 | MemoryAllocator& memory_allocator; | 97 | MemoryAllocator& memory_allocator; |
| 98 | StagingBufferPool& staging_buffer_pool; | 98 | StagingBufferPool& staging_buffer_pool; |
| 99 | BlitImageHelper& blit_image_helper; | 99 | BlitImageHelper& blit_image_helper; |
| @@ -154,7 +154,7 @@ private: | |||
| 154 | 154 | ||
| 155 | bool NeedsScaleHelper() const; | 155 | bool NeedsScaleHelper() const; |
| 156 | 156 | ||
| 157 | VKScheduler* scheduler{}; | 157 | Scheduler* scheduler{}; |
| 158 | TextureCacheRuntime* runtime{}; | 158 | TextureCacheRuntime* runtime{}; |
| 159 | 159 | ||
| 160 | vk::Image original_image; | 160 | vk::Image original_image; |
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp index d29540fec..4d4a6753b 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp | |||
| @@ -12,18 +12,18 @@ | |||
| 12 | 12 | ||
| 13 | namespace Vulkan { | 13 | namespace Vulkan { |
| 14 | 14 | ||
| 15 | VKUpdateDescriptorQueue::VKUpdateDescriptorQueue(const Device& device_, VKScheduler& scheduler_) | 15 | UpdateDescriptorQueue::UpdateDescriptorQueue(const Device& device_, Scheduler& scheduler_) |
| 16 | : device{device_}, scheduler{scheduler_} { | 16 | : device{device_}, scheduler{scheduler_} { |
| 17 | payload_cursor = payload.data(); | 17 | payload_cursor = payload.data(); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | VKUpdateDescriptorQueue::~VKUpdateDescriptorQueue() = default; | 20 | UpdateDescriptorQueue::~UpdateDescriptorQueue() = default; |
| 21 | 21 | ||
| 22 | void VKUpdateDescriptorQueue::TickFrame() { | 22 | void UpdateDescriptorQueue::TickFrame() { |
| 23 | payload_cursor = payload.data(); | 23 | payload_cursor = payload.data(); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | void VKUpdateDescriptorQueue::Acquire() { | 26 | void UpdateDescriptorQueue::Acquire() { |
| 27 | // Minimum number of entries required. | 27 | // Minimum number of entries required. |
| 28 | // This is the maximum number of entries a single draw call migth use. | 28 | // This is the maximum number of entries a single draw call migth use. |
| 29 | static constexpr size_t MIN_ENTRIES = 0x400; | 29 | static constexpr size_t MIN_ENTRIES = 0x400; |
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h index d8a56b153..625bcc809 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.h +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | namespace Vulkan { | 10 | namespace Vulkan { |
| 11 | 11 | ||
| 12 | class Device; | 12 | class Device; |
| 13 | class VKScheduler; | 13 | class Scheduler; |
| 14 | 14 | ||
| 15 | struct DescriptorUpdateEntry { | 15 | struct DescriptorUpdateEntry { |
| 16 | struct Empty {}; | 16 | struct Empty {}; |
| @@ -28,10 +28,10 @@ struct DescriptorUpdateEntry { | |||
| 28 | }; | 28 | }; |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | class VKUpdateDescriptorQueue final { | 31 | class UpdateDescriptorQueue final { |
| 32 | public: | 32 | public: |
| 33 | explicit VKUpdateDescriptorQueue(const Device& device_, VKScheduler& scheduler_); | 33 | explicit UpdateDescriptorQueue(const Device& device_, Scheduler& scheduler_); |
| 34 | ~VKUpdateDescriptorQueue(); | 34 | ~UpdateDescriptorQueue(); |
| 35 | 35 | ||
| 36 | void TickFrame(); | 36 | void TickFrame(); |
| 37 | 37 | ||
| @@ -71,7 +71,7 @@ public: | |||
| 71 | 71 | ||
| 72 | private: | 72 | private: |
| 73 | const Device& device; | 73 | const Device& device; |
| 74 | VKScheduler& scheduler; | 74 | Scheduler& scheduler; |
| 75 | 75 | ||
| 76 | DescriptorUpdateEntry* payload_cursor = nullptr; | 76 | DescriptorUpdateEntry* payload_cursor = nullptr; |
| 77 | const DescriptorUpdateEntry* upload_start = nullptr; | 77 | const DescriptorUpdateEntry* upload_start = nullptr; |
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index d469964f6..c4e923bbf 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp | |||
| @@ -280,7 +280,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, | |||
| 280 | stage_index = 4; | 280 | stage_index = 4; |
| 281 | break; | 281 | break; |
| 282 | default: | 282 | default: |
| 283 | UNREACHABLE_MSG("Invalid program={}", program); | 283 | ASSERT_MSG(false, "Invalid program={}", program); |
| 284 | break; | 284 | break; |
| 285 | } | 285 | } |
| 286 | const u64 local_size{sph.LocalMemorySize()}; | 286 | const u64 local_size{sph.LocalMemorySize()}; |
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 5f428d35d..69c1b1e6d 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp | |||
| @@ -29,7 +29,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t | |||
| 29 | return SurfaceTarget::Texture2DArray; | 29 | return SurfaceTarget::Texture2DArray; |
| 30 | default: | 30 | default: |
| 31 | LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", texture_type); | 31 | LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", texture_type); |
| 32 | UNREACHABLE(); | 32 | ASSERT(false); |
| 33 | return SurfaceTarget::Texture2D; | 33 | return SurfaceTarget::Texture2D; |
| 34 | } | 34 | } |
| 35 | } | 35 | } |
| @@ -48,7 +48,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) { | |||
| 48 | return true; | 48 | return true; |
| 49 | default: | 49 | default: |
| 50 | LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target); | 50 | LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target); |
| 51 | UNREACHABLE(); | 51 | ASSERT(false); |
| 52 | return false; | 52 | return false; |
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| @@ -67,7 +67,7 @@ bool SurfaceTargetIsArray(SurfaceTarget target) { | |||
| 67 | return true; | 67 | return true; |
| 68 | default: | 68 | default: |
| 69 | LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target); | 69 | LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target); |
| 70 | UNREACHABLE(); | 70 | ASSERT(false); |
| 71 | return false; | 71 | return false; |
| 72 | } | 72 | } |
| 73 | } | 73 | } |
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 802939f6c..6c073ee57 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp | |||
| @@ -94,7 +94,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { | |||
| 94 | resources.layers = 1; | 94 | resources.layers = 1; |
| 95 | break; | 95 | break; |
| 96 | default: | 96 | default: |
| 97 | UNREACHABLE_MSG("Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); | 97 | ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); |
| 98 | break; | 98 | break; |
| 99 | } | 99 | } |
| 100 | if (type != ImageType::Linear) { | 100 | if (type != ImageType::Linear) { |
diff --git a/src/video_core/texture_cache/image_view_info.cpp b/src/video_core/texture_cache/image_view_info.cpp index 0cee5e45f..f47885147 100644 --- a/src/video_core/texture_cache/image_view_info.cpp +++ b/src/video_core/texture_cache/image_view_info.cpp | |||
| @@ -71,7 +71,7 @@ ImageViewInfo::ImageViewInfo(const TICEntry& config, s32 base_layer) noexcept | |||
| 71 | range.extent.layers = config.Depth() * 6; | 71 | range.extent.layers = config.Depth() * 6; |
| 72 | break; | 72 | break; |
| 73 | default: | 73 | default: |
| 74 | UNREACHABLE_MSG("Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); | 74 | ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); |
| 75 | break; | 75 | break; |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
diff --git a/src/video_core/texture_cache/samples_helper.h b/src/video_core/texture_cache/samples_helper.h index 91fec60bd..d552bccf0 100644 --- a/src/video_core/texture_cache/samples_helper.h +++ b/src/video_core/texture_cache/samples_helper.h | |||
| @@ -23,7 +23,7 @@ namespace VideoCommon { | |||
| 23 | case 16: | 23 | case 16: |
| 24 | return {2, 2}; | 24 | return {2, 2}; |
| 25 | } | 25 | } |
| 26 | UNREACHABLE_MSG("Invalid number of samples={}", num_samples); | 26 | ASSERT_MSG(false, "Invalid number of samples={}", num_samples); |
| 27 | return {1, 1}; | 27 | return {1, 1}; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| @@ -47,7 +47,7 @@ namespace VideoCommon { | |||
| 47 | case MsaaMode::Msaa4x4: | 47 | case MsaaMode::Msaa4x4: |
| 48 | return 16; | 48 | return 16; |
| 49 | } | 49 | } |
| 50 | UNREACHABLE_MSG("Invalid MSAA mode={}", static_cast<int>(msaa_mode)); | 50 | ASSERT_MSG(false, "Invalid MSAA mode={}", static_cast<int>(msaa_mode)); |
| 51 | return 1; | 51 | return 1; |
| 52 | } | 52 | } |
| 53 | 53 | ||
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6622d7818..cf3ca06a6 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1485,14 +1485,14 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { | |||
| 1485 | std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>>& selected_page_table) { | 1485 | std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>>& selected_page_table) { |
| 1486 | const auto page_it = selected_page_table.find(page); | 1486 | const auto page_it = selected_page_table.find(page); |
| 1487 | if (page_it == selected_page_table.end()) { | 1487 | if (page_it == selected_page_table.end()) { |
| 1488 | UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS); | 1488 | ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS); |
| 1489 | return; | 1489 | return; |
| 1490 | } | 1490 | } |
| 1491 | std::vector<ImageId>& image_ids = page_it->second; | 1491 | std::vector<ImageId>& image_ids = page_it->second; |
| 1492 | const auto vector_it = std::ranges::find(image_ids, image_id); | 1492 | const auto vector_it = std::ranges::find(image_ids, image_id); |
| 1493 | if (vector_it == image_ids.end()) { | 1493 | if (vector_it == image_ids.end()) { |
| 1494 | UNREACHABLE_MSG("Unregistering unregistered image in page=0x{:x}", | 1494 | ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", |
| 1495 | page << PAGE_BITS); | 1495 | page << PAGE_BITS); |
| 1496 | return; | 1496 | return; |
| 1497 | } | 1497 | } |
| 1498 | image_ids.erase(vector_it); | 1498 | image_ids.erase(vector_it); |
| @@ -1504,14 +1504,14 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { | |||
| 1504 | ForEachCPUPage(image.cpu_addr, image.guest_size_bytes, [this, map_id](u64 page) { | 1504 | ForEachCPUPage(image.cpu_addr, image.guest_size_bytes, [this, map_id](u64 page) { |
| 1505 | const auto page_it = page_table.find(page); | 1505 | const auto page_it = page_table.find(page); |
| 1506 | if (page_it == page_table.end()) { | 1506 | if (page_it == page_table.end()) { |
| 1507 | UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS); | 1507 | ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS); |
| 1508 | return; | 1508 | return; |
| 1509 | } | 1509 | } |
| 1510 | std::vector<ImageMapId>& image_map_ids = page_it->second; | 1510 | std::vector<ImageMapId>& image_map_ids = page_it->second; |
| 1511 | const auto vector_it = std::ranges::find(image_map_ids, map_id); | 1511 | const auto vector_it = std::ranges::find(image_map_ids, map_id); |
| 1512 | if (vector_it == image_map_ids.end()) { | 1512 | if (vector_it == image_map_ids.end()) { |
| 1513 | UNREACHABLE_MSG("Unregistering unregistered image in page=0x{:x}", | 1513 | ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", |
| 1514 | page << PAGE_BITS); | 1514 | page << PAGE_BITS); |
| 1515 | return; | 1515 | return; |
| 1516 | } | 1516 | } |
| 1517 | image_map_ids.erase(vector_it); | 1517 | image_map_ids.erase(vector_it); |
| @@ -1532,7 +1532,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { | |||
| 1532 | ForEachCPUPage(cpu_addr, size, [this, image_id](u64 page) { | 1532 | ForEachCPUPage(cpu_addr, size, [this, image_id](u64 page) { |
| 1533 | const auto page_it = page_table.find(page); | 1533 | const auto page_it = page_table.find(page); |
| 1534 | if (page_it == page_table.end()) { | 1534 | if (page_it == page_table.end()) { |
| 1535 | UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS); | 1535 | ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS); |
| 1536 | return; | 1536 | return; |
| 1537 | } | 1537 | } |
| 1538 | std::vector<ImageMapId>& image_map_ids = page_it->second; | 1538 | std::vector<ImageMapId>& image_map_ids = page_it->second; |
| @@ -1616,15 +1616,15 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { | |||
| 1616 | const GPUVAddr gpu_addr = image.gpu_addr; | 1616 | const GPUVAddr gpu_addr = image.gpu_addr; |
| 1617 | const auto alloc_it = image_allocs_table.find(gpu_addr); | 1617 | const auto alloc_it = image_allocs_table.find(gpu_addr); |
| 1618 | if (alloc_it == image_allocs_table.end()) { | 1618 | if (alloc_it == image_allocs_table.end()) { |
| 1619 | UNREACHABLE_MSG("Trying to delete an image alloc that does not exist in address 0x{:x}", | 1619 | ASSERT_MSG(false, "Trying to delete an image alloc that does not exist in address 0x{:x}", |
| 1620 | gpu_addr); | 1620 | gpu_addr); |
| 1621 | return; | 1621 | return; |
| 1622 | } | 1622 | } |
| 1623 | const ImageAllocId alloc_id = alloc_it->second; | 1623 | const ImageAllocId alloc_id = alloc_it->second; |
| 1624 | std::vector<ImageId>& alloc_images = slot_image_allocs[alloc_id].images; | 1624 | std::vector<ImageId>& alloc_images = slot_image_allocs[alloc_id].images; |
| 1625 | const auto alloc_image_it = std::ranges::find(alloc_images, image_id); | 1625 | const auto alloc_image_it = std::ranges::find(alloc_images, image_id); |
| 1626 | if (alloc_image_it == alloc_images.end()) { | 1626 | if (alloc_image_it == alloc_images.end()) { |
| 1627 | UNREACHABLE_MSG("Trying to delete an image that does not exist"); | 1627 | ASSERT_MSG(false, "Trying to delete an image that does not exist"); |
| 1628 | return; | 1628 | return; |
| 1629 | } | 1629 | } |
| 1630 | ASSERT_MSG(False(image.flags & ImageFlagBits::Tracked), "Image was not untracked"); | 1630 | ASSERT_MSG(False(image.flags & ImageFlagBits::Tracked), "Image was not untracked"); |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index c81343850..9b6b8527b 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -87,7 +87,7 @@ void Swizzle(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixe | |||
| 87 | BPP_CASE(16) | 87 | BPP_CASE(16) |
| 88 | #undef BPP_CASE | 88 | #undef BPP_CASE |
| 89 | default: | 89 | default: |
| 90 | UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); | 90 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | 93 | ||
| @@ -209,7 +209,7 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 | |||
| 209 | BPP_CASE(16) | 209 | BPP_CASE(16) |
| 210 | #undef BPP_CASE | 210 | #undef BPP_CASE |
| 211 | default: | 211 | default: |
| 212 | UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); | 212 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 213 | } | 213 | } |
| 214 | } | 214 | } |
| 215 | 215 | ||
| @@ -230,7 +230,7 @@ void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width, | |||
| 230 | BPP_CASE(16) | 230 | BPP_CASE(16) |
| 231 | #undef BPP_CASE | 231 | #undef BPP_CASE |
| 232 | default: | 232 | default: |
| 233 | UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); | 233 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 234 | } | 234 | } |
| 235 | } | 235 | } |
| 236 | 236 | ||
| @@ -253,7 +253,7 @@ void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 widt | |||
| 253 | BPP_CASE(16) | 253 | BPP_CASE(16) |
| 254 | #undef BPP_CASE | 254 | #undef BPP_CASE |
| 255 | default: | 255 | default: |
| 256 | UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); | 256 | ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); |
| 257 | } | 257 | } |
| 258 | } | 258 | } |
| 259 | 259 | ||
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index b3a77e07f..743ac09f6 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -669,17 +669,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 669 | const bool is_amd = | 669 | const bool is_amd = |
| 670 | driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; | 670 | driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; |
| 671 | if (is_amd) { | 671 | if (is_amd) { |
| 672 | // TODO(lat9nq): Add an upper bound when AMD fixes their VK_KHR_push_descriptor | ||
| 673 | const bool has_broken_push_descriptor = VK_VERSION_MAJOR(properties.driverVersion) == 2 && | ||
| 674 | VK_VERSION_MINOR(properties.driverVersion) == 0 && | ||
| 675 | VK_VERSION_PATCH(properties.driverVersion) >= 226; | ||
| 676 | if (khr_push_descriptor && has_broken_push_descriptor) { | ||
| 677 | LOG_WARNING( | ||
| 678 | Render_Vulkan, | ||
| 679 | "Disabling AMD driver 2.0.226 and later from broken VK_KHR_push_descriptor"); | ||
| 680 | khr_push_descriptor = false; | ||
| 681 | } | ||
| 682 | |||
| 683 | // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2. | 672 | // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2. |
| 684 | sets_per_pool = 96; | 673 | sets_per_pool = 96; |
| 685 | // Disable VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT on AMD GCN4 and lower as it is broken. | 674 | // Disable VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT on AMD GCN4 and lower as it is broken. |
| @@ -738,9 +727,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags | |||
| 738 | // The wanted format is not supported by hardware, search for alternatives | 727 | // The wanted format is not supported by hardware, search for alternatives |
| 739 | const VkFormat* alternatives = GetFormatAlternatives(wanted_format); | 728 | const VkFormat* alternatives = GetFormatAlternatives(wanted_format); |
| 740 | if (alternatives == nullptr) { | 729 | if (alternatives == nullptr) { |
| 741 | UNREACHABLE_MSG("Format={} with usage={} and type={} has no defined alternatives and host " | 730 | ASSERT_MSG(false, |
| 742 | "hardware does not support it", | 731 | "Format={} with usage={} and type={} has no defined alternatives and host " |
| 743 | wanted_format, wanted_usage, format_type); | 732 | "hardware does not support it", |
| 733 | wanted_format, wanted_usage, format_type); | ||
| 744 | return wanted_format; | 734 | return wanted_format; |
| 745 | } | 735 | } |
| 746 | 736 | ||
| @@ -756,9 +746,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags | |||
| 756 | } | 746 | } |
| 757 | 747 | ||
| 758 | // No alternatives found, panic | 748 | // No alternatives found, panic |
| 759 | UNREACHABLE_MSG("Format={} with usage={} and type={} is not supported by the host hardware and " | 749 | ASSERT_MSG(false, |
| 760 | "doesn't support any of the alternatives", | 750 | "Format={} with usage={} and type={} is not supported by the host hardware and " |
| 761 | wanted_format, wanted_usage, format_type); | 751 | "doesn't support any of the alternatives", |
| 752 | wanted_format, wanted_usage, format_type); | ||
| 762 | return wanted_format; | 753 | return wanted_format; |
| 763 | } | 754 | } |
| 764 | 755 | ||
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index caae6dfdc..6442898bd 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -49,7 +49,7 @@ struct Range { | |||
| 49 | return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | | 49 | return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | |
| 50 | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; | 50 | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; |
| 51 | } | 51 | } |
| 52 | UNREACHABLE_MSG("Invalid memory usage={}", usage); | 52 | ASSERT_MSG(false, "Invalid memory usage={}", usage); |
| 53 | return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; | 53 | return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| @@ -325,7 +325,7 @@ VkMemoryPropertyFlags MemoryAllocator::MemoryPropertyFlags(u32 type_mask, | |||
| 325 | // Remove device local, if it's not supported by the requested resource | 325 | // Remove device local, if it's not supported by the requested resource |
| 326 | return MemoryPropertyFlags(type_mask, flags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); | 326 | return MemoryPropertyFlags(type_mask, flags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| 327 | } | 327 | } |
| 328 | UNREACHABLE_MSG("No compatible memory types found"); | 328 | ASSERT_MSG(false, "No compatible memory types found"); |
| 329 | return 0; | 329 | return 0; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| @@ -349,7 +349,7 @@ bool IsHostVisible(MemoryUsage usage) noexcept { | |||
| 349 | case MemoryUsage::Download: | 349 | case MemoryUsage::Download: |
| 350 | return true; | 350 | return true; |
| 351 | } | 351 | } |
| 352 | UNREACHABLE_MSG("Invalid memory usage={}", usage); | 352 | ASSERT_MSG(false, "Invalid memory usage={}", usage); |
| 353 | return false; | 353 | return false; |
| 354 | } | 354 | } |
| 355 | 355 | ||
diff --git a/src/web_service/telemetry_json.cpp b/src/web_service/telemetry_json.cpp index 6215c914f..46faddb61 100644 --- a/src/web_service/telemetry_json.cpp +++ b/src/web_service/telemetry_json.cpp | |||
| @@ -13,8 +13,8 @@ namespace WebService { | |||
| 13 | namespace Telemetry = Common::Telemetry; | 13 | namespace Telemetry = Common::Telemetry; |
| 14 | 14 | ||
| 15 | struct TelemetryJson::Impl { | 15 | struct TelemetryJson::Impl { |
| 16 | Impl(std::string host, std::string username, std::string token) | 16 | Impl(std::string host_, std::string username_, std::string token_) |
| 17 | : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} {} | 17 | : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} {} |
| 18 | 18 | ||
| 19 | nlohmann::json& TopSection() { | 19 | nlohmann::json& TopSection() { |
| 20 | return sections[static_cast<u8>(Telemetry::FieldType::None)]; | 20 | return sections[static_cast<u8>(Telemetry::FieldType::None)]; |
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index 58b0c2f10..dce9772fe 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp | |||
| @@ -30,10 +30,10 @@ constexpr std::array<const char, 1> API_VERSION{'1'}; | |||
| 30 | constexpr std::size_t TIMEOUT_SECONDS = 30; | 30 | constexpr std::size_t TIMEOUT_SECONDS = 30; |
| 31 | 31 | ||
| 32 | struct Client::Impl { | 32 | struct Client::Impl { |
| 33 | Impl(std::string host, std::string username, std::string token) | 33 | Impl(std::string host_, std::string username_, std::string token_) |
| 34 | : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} { | 34 | : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} { |
| 35 | std::scoped_lock lock{jwt_cache.mutex}; | 35 | std::scoped_lock lock{jwt_cache.mutex}; |
| 36 | if (this->username == jwt_cache.username && this->token == jwt_cache.token) { | 36 | if (username == jwt_cache.username && token == jwt_cache.token) { |
| 37 | jwt = jwt_cache.jwt; | 37 | jwt = jwt_cache.jwt; |
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| @@ -69,8 +69,8 @@ struct Client::Impl { | |||
| 69 | */ | 69 | */ |
| 70 | WebResult GenericRequest(const std::string& method, const std::string& path, | 70 | WebResult GenericRequest(const std::string& method, const std::string& path, |
| 71 | const std::string& data, const std::string& accept, | 71 | const std::string& data, const std::string& accept, |
| 72 | const std::string& jwt = "", const std::string& username = "", | 72 | const std::string& jwt_ = "", const std::string& username_ = "", |
| 73 | const std::string& token = "") { | 73 | const std::string& token_ = "") { |
| 74 | if (cli == nullptr) { | 74 | if (cli == nullptr) { |
| 75 | cli = std::make_unique<httplib::Client>(host.c_str()); | 75 | cli = std::make_unique<httplib::Client>(host.c_str()); |
| 76 | } | 76 | } |
| @@ -85,14 +85,14 @@ struct Client::Impl { | |||
| 85 | cli->set_write_timeout(TIMEOUT_SECONDS); | 85 | cli->set_write_timeout(TIMEOUT_SECONDS); |
| 86 | 86 | ||
| 87 | httplib::Headers params; | 87 | httplib::Headers params; |
| 88 | if (!jwt.empty()) { | 88 | if (!jwt_.empty()) { |
| 89 | params = { | 89 | params = { |
| 90 | {std::string("Authorization"), fmt::format("Bearer {}", jwt)}, | 90 | {std::string("Authorization"), fmt::format("Bearer {}", jwt_)}, |
| 91 | }; | 91 | }; |
| 92 | } else if (!username.empty()) { | 92 | } else if (!username_.empty()) { |
| 93 | params = { | 93 | params = { |
| 94 | {std::string("x-username"), username}, | 94 | {std::string("x-username"), username_}, |
| 95 | {std::string("x-token"), token}, | 95 | {std::string("x-token"), token_}, |
| 96 | }; | 96 | }; |
| 97 | } | 97 | } |
| 98 | 98 | ||
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index c924cb0cb..8be311fcb 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp | |||
| @@ -631,7 +631,7 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() { | |||
| 631 | switch (max_supported_players) { | 631 | switch (max_supported_players) { |
| 632 | case 0: | 632 | case 0: |
| 633 | default: | 633 | default: |
| 634 | UNREACHABLE(); | 634 | ASSERT(false); |
| 635 | return; | 635 | return; |
| 636 | case 1: | 636 | case 1: |
| 637 | ui->widgetSpacer->hide(); | 637 | ui->widgetSpacer->hide(); |
diff --git a/src/yuzu/applets/qt_error.cpp b/src/yuzu/applets/qt_error.cpp index 5bd8d85bb..367d5352d 100644 --- a/src/yuzu/applets/qt_error.cpp +++ b/src/yuzu/applets/qt_error.cpp | |||
| @@ -14,7 +14,7 @@ QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) { | |||
| 14 | 14 | ||
| 15 | QtErrorDisplay::~QtErrorDisplay() = default; | 15 | QtErrorDisplay::~QtErrorDisplay() = default; |
| 16 | 16 | ||
| 17 | void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const { | 17 | void QtErrorDisplay::ShowError(Result error, std::function<void()> finished) const { |
| 18 | callback = std::move(finished); | 18 | callback = std::move(finished); |
| 19 | emit MainWindowDisplayError( | 19 | emit MainWindowDisplayError( |
| 20 | tr("Error Code: %1-%2 (0x%3)") | 20 | tr("Error Code: %1-%2 (0x%3)") |
| @@ -24,7 +24,7 @@ void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) | |||
| 24 | tr("An error has occurred.\nPlease try again or contact the developer of the software.")); | 24 | tr("An error has occurred.\nPlease try again or contact the developer of the software.")); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | 27 | void QtErrorDisplay::ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 28 | std::function<void()> finished) const { | 28 | std::function<void()> finished) const { |
| 29 | callback = std::move(finished); | 29 | callback = std::move(finished); |
| 30 | 30 | ||
| @@ -40,7 +40,7 @@ void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::secon | |||
| 40 | .arg(date_time.toString(QStringLiteral("h:mm:ss A")))); | 40 | .arg(date_time.toString(QStringLiteral("h:mm:ss A")))); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text, | 43 | void QtErrorDisplay::ShowCustomErrorText(Result error, std::string dialog_text, |
| 44 | std::string fullscreen_text, | 44 | std::string fullscreen_text, |
| 45 | std::function<void()> finished) const { | 45 | std::function<void()> finished) const { |
| 46 | callback = std::move(finished); | 46 | callback = std::move(finished); |
diff --git a/src/yuzu/applets/qt_error.h b/src/yuzu/applets/qt_error.h index 2d045b4fc..eb4107c7e 100644 --- a/src/yuzu/applets/qt_error.h +++ b/src/yuzu/applets/qt_error.h | |||
| @@ -16,10 +16,10 @@ public: | |||
| 16 | explicit QtErrorDisplay(GMainWindow& parent); | 16 | explicit QtErrorDisplay(GMainWindow& parent); |
| 17 | ~QtErrorDisplay() override; | 17 | ~QtErrorDisplay() override; |
| 18 | 18 | ||
| 19 | void ShowError(ResultCode error, std::function<void()> finished) const override; | 19 | void ShowError(Result error, std::function<void()> finished) const override; |
| 20 | void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | 20 | void ShowErrorWithTimestamp(Result error, std::chrono::seconds time, |
| 21 | std::function<void()> finished) const override; | 21 | std::function<void()> finished) const override; |
| 22 | void ShowCustomErrorText(ResultCode error, std::string dialog_text, std::string fullscreen_text, | 22 | void ShowCustomErrorText(Result error, std::string dialog_text, std::string fullscreen_text, |
| 23 | std::function<void()> finished) const override; | 23 | std::function<void()> finished) const override; |
| 24 | 24 | ||
| 25 | signals: | 25 | signals: |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index bde465485..01acda22b 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "common/scm_rev.h" | 29 | #include "common/scm_rev.h" |
| 30 | #include "common/settings.h" | 30 | #include "common/settings.h" |
| 31 | #include "core/core.h" | 31 | #include "core/core.h" |
| 32 | #include "core/cpu_manager.h" | ||
| 32 | #include "core/frontend/framebuffer_layout.h" | 33 | #include "core/frontend/framebuffer_layout.h" |
| 33 | #include "input_common/drivers/keyboard.h" | 34 | #include "input_common/drivers/keyboard.h" |
| 34 | #include "input_common/drivers/mouse.h" | 35 | #include "input_common/drivers/mouse.h" |
| @@ -73,6 +74,8 @@ void EmuThread::run() { | |||
| 73 | 74 | ||
| 74 | gpu.ReleaseContext(); | 75 | gpu.ReleaseContext(); |
| 75 | 76 | ||
| 77 | system.GetCpuManager().OnGpuReady(); | ||
| 78 | |||
| 76 | // Holds whether the cpu was running during the last iteration, | 79 | // Holds whether the cpu was running during the last iteration, |
| 77 | // so that the DebugModeLeft signal can be emitted before the | 80 | // so that the DebugModeLeft signal can be emitted before the |
| 78 | // next execution step | 81 | // next execution step |
| @@ -127,7 +130,7 @@ void EmuThread::run() { | |||
| 127 | class OpenGLSharedContext : public Core::Frontend::GraphicsContext { | 130 | class OpenGLSharedContext : public Core::Frontend::GraphicsContext { |
| 128 | public: | 131 | public: |
| 129 | /// Create the original context that should be shared from | 132 | /// Create the original context that should be shared from |
| 130 | explicit OpenGLSharedContext(QSurface* surface) : surface(surface) { | 133 | explicit OpenGLSharedContext(QSurface* surface_) : surface{surface_} { |
| 131 | QSurfaceFormat format; | 134 | QSurfaceFormat format; |
| 132 | format.setVersion(4, 6); | 135 | format.setVersion(4, 6); |
| 133 | format.setProfile(QSurfaceFormat::CompatibilityProfile); | 136 | format.setProfile(QSurfaceFormat::CompatibilityProfile); |
| @@ -364,9 +367,9 @@ void GRenderWindow::RestoreGeometry() { | |||
| 364 | QWidget::restoreGeometry(geometry); | 367 | QWidget::restoreGeometry(geometry); |
| 365 | } | 368 | } |
| 366 | 369 | ||
| 367 | void GRenderWindow::restoreGeometry(const QByteArray& geometry) { | 370 | void GRenderWindow::restoreGeometry(const QByteArray& geometry_) { |
| 368 | // Make sure users of this class don't need to deal with backing up the geometry themselves | 371 | // Make sure users of this class don't need to deal with backing up the geometry themselves |
| 369 | QWidget::restoreGeometry(geometry); | 372 | QWidget::restoreGeometry(geometry_); |
| 370 | BackupGeometry(); | 373 | BackupGeometry(); |
| 371 | } | 374 | } |
| 372 | 375 | ||
| @@ -1014,8 +1017,8 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const { | |||
| 1014 | return unsupported_ext; | 1017 | return unsupported_ext; |
| 1015 | } | 1018 | } |
| 1016 | 1019 | ||
| 1017 | void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) { | 1020 | void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread_) { |
| 1018 | this->emu_thread = emu_thread; | 1021 | emu_thread = emu_thread_; |
| 1019 | } | 1022 | } |
| 1020 | 1023 | ||
| 1021 | void GRenderWindow::OnEmulationStopping() { | 1024 | void GRenderWindow::OnEmulationStopping() { |
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index d01538039..81fe52c0e 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h | |||
| @@ -56,12 +56,12 @@ public: | |||
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | * Sets whether the emulation thread is running or not | 58 | * Sets whether the emulation thread is running or not |
| 59 | * @param running Boolean value, set the emulation thread to running if true | 59 | * @param running_ Boolean value, set the emulation thread to running if true |
| 60 | * @note This function is thread-safe | 60 | * @note This function is thread-safe |
| 61 | */ | 61 | */ |
| 62 | void SetRunning(bool running) { | 62 | void SetRunning(bool running_) { |
| 63 | std::unique_lock lock{running_mutex}; | 63 | std::unique_lock lock{running_mutex}; |
| 64 | this->running = running; | 64 | running = running_; |
| 65 | lock.unlock(); | 65 | lock.unlock(); |
| 66 | running_cv.notify_all(); | 66 | running_cv.notify_all(); |
| 67 | if (!running) { | 67 | if (!running) { |
| @@ -138,8 +138,8 @@ public: | |||
| 138 | 138 | ||
| 139 | void BackupGeometry(); | 139 | void BackupGeometry(); |
| 140 | void RestoreGeometry(); | 140 | void RestoreGeometry(); |
| 141 | void restoreGeometry(const QByteArray& geometry); // overridden | 141 | void restoreGeometry(const QByteArray& geometry_); // overridden |
| 142 | QByteArray saveGeometry(); // overridden | 142 | QByteArray saveGeometry(); // overridden |
| 143 | 143 | ||
| 144 | qreal windowPixelRatio() const; | 144 | qreal windowPixelRatio() const; |
| 145 | 145 | ||
| @@ -189,7 +189,7 @@ public: | |||
| 189 | void Exit(); | 189 | void Exit(); |
| 190 | 190 | ||
| 191 | public slots: | 191 | public slots: |
| 192 | void OnEmulationStarting(EmuThread* emu_thread); | 192 | void OnEmulationStarting(EmuThread* emu_thread_); |
| 193 | void OnEmulationStopping(); | 193 | void OnEmulationStopping(); |
| 194 | void OnFramebufferSizeChanged(); | 194 | void OnFramebufferSizeChanged(); |
| 195 | 195 | ||
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index b415a1cc4..e99657bd6 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -27,12 +27,11 @@ | |||
| 27 | #include "yuzu/hotkeys.h" | 27 | #include "yuzu/hotkeys.h" |
| 28 | #include "yuzu/uisettings.h" | 28 | #include "yuzu/uisettings.h" |
| 29 | 29 | ||
| 30 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, | 30 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, |
| 31 | InputCommon::InputSubsystem* input_subsystem, | 31 | InputCommon::InputSubsystem* input_subsystem, |
| 32 | Core::System& system_) | 32 | Core::System& system_) |
| 33 | : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, | 33 | : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_}, |
| 34 | registry(registry), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, | 34 | system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, this)}, |
| 35 | this)}, | ||
| 36 | cpu_tab{std::make_unique<ConfigureCpu>(system_, this)}, | 35 | cpu_tab{std::make_unique<ConfigureCpu>(system_, this)}, |
| 37 | debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, | 36 | debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, |
| 38 | filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, | 37 | filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 32ddfd4e0..12cf25daf 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -40,7 +40,7 @@ class ConfigureDialog : public QDialog { | |||
| 40 | Q_OBJECT | 40 | Q_OBJECT |
| 41 | 41 | ||
| 42 | public: | 42 | public: |
| 43 | explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, | 43 | explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, |
| 44 | InputCommon::InputSubsystem* input_subsystem, Core::System& system_); | 44 | InputCommon::InputSubsystem* input_subsystem, Core::System& system_); |
| 45 | ~ConfigureDialog() override; | 45 | ~ConfigureDialog() override; |
| 46 | 46 | ||
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 1c05dd0f3..f3be9a374 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -264,15 +264,16 @@ QString ConfigureInputPlayer::AnalogToText(const Common::ParamPackage& param, | |||
| 264 | return QObject::tr("[unknown]"); | 264 | return QObject::tr("[unknown]"); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index, | 267 | ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index_, |
| 268 | QWidget* bottom_row, | 268 | QWidget* bottom_row_, |
| 269 | InputCommon::InputSubsystem* input_subsystem_, | 269 | InputCommon::InputSubsystem* input_subsystem_, |
| 270 | InputProfiles* profiles_, Core::HID::HIDCore& hid_core_, | 270 | InputProfiles* profiles_, Core::HID::HIDCore& hid_core_, |
| 271 | bool is_powered_on_, bool debug) | 271 | bool is_powered_on_, bool debug_) |
| 272 | : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index), | 272 | : QWidget(parent), |
| 273 | debug(debug), is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, | 273 | ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index{player_index_}, debug{debug_}, |
| 274 | profiles(profiles_), timeout_timer(std::make_unique<QTimer>()), | 274 | is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, profiles(profiles_), |
| 275 | poll_timer(std::make_unique<QTimer>()), bottom_row(bottom_row), hid_core{hid_core_} { | 275 | timeout_timer(std::make_unique<QTimer>()), |
| 276 | poll_timer(std::make_unique<QTimer>()), bottom_row{bottom_row_}, hid_core{hid_core_} { | ||
| 276 | if (player_index == 0) { | 277 | if (player_index == 0) { |
| 277 | auto* emulated_controller_p1 = | 278 | auto* emulated_controller_p1 = |
| 278 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | 279 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); |
| @@ -696,39 +697,38 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 696 | UpdateControllerEnabledButtons(); | 697 | UpdateControllerEnabledButtons(); |
| 697 | UpdateControllerButtonNames(); | 698 | UpdateControllerButtonNames(); |
| 698 | UpdateMotionButtons(); | 699 | UpdateMotionButtons(); |
| 699 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), | 700 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { |
| 700 | [this, player_index](int) { | 701 | UpdateControllerAvailableButtons(); |
| 701 | UpdateControllerAvailableButtons(); | 702 | UpdateControllerEnabledButtons(); |
| 702 | UpdateControllerEnabledButtons(); | 703 | UpdateControllerButtonNames(); |
| 703 | UpdateControllerButtonNames(); | 704 | UpdateMotionButtons(); |
| 704 | UpdateMotionButtons(); | 705 | const Core::HID::NpadStyleIndex type = |
| 705 | const Core::HID::NpadStyleIndex type = | 706 | GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); |
| 706 | GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | 707 | |
| 707 | 708 | if (player_index == 0) { | |
| 708 | if (player_index == 0) { | 709 | auto* emulated_controller_p1 = |
| 709 | auto* emulated_controller_p1 = | 710 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); |
| 710 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | 711 | auto* emulated_controller_handheld = |
| 711 | auto* emulated_controller_handheld = | 712 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); |
| 712 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); | 713 | bool is_connected = emulated_controller->IsConnected(true); |
| 713 | bool is_connected = emulated_controller->IsConnected(true); | 714 | |
| 714 | 715 | emulated_controller_p1->SetNpadStyleIndex(type); | |
| 715 | emulated_controller_p1->SetNpadStyleIndex(type); | 716 | emulated_controller_handheld->SetNpadStyleIndex(type); |
| 716 | emulated_controller_handheld->SetNpadStyleIndex(type); | 717 | if (is_connected) { |
| 717 | if (is_connected) { | 718 | if (type == Core::HID::NpadStyleIndex::Handheld) { |
| 718 | if (type == Core::HID::NpadStyleIndex::Handheld) { | 719 | emulated_controller_p1->Disconnect(); |
| 719 | emulated_controller_p1->Disconnect(); | 720 | emulated_controller_handheld->Connect(true); |
| 720 | emulated_controller_handheld->Connect(true); | 721 | emulated_controller = emulated_controller_handheld; |
| 721 | emulated_controller = emulated_controller_handheld; | 722 | } else { |
| 722 | } else { | 723 | emulated_controller_handheld->Disconnect(); |
| 723 | emulated_controller_handheld->Disconnect(); | 724 | emulated_controller_p1->Connect(true); |
| 724 | emulated_controller_p1->Connect(true); | 725 | emulated_controller = emulated_controller_p1; |
| 725 | emulated_controller = emulated_controller_p1; | ||
| 726 | } | ||
| 727 | } | ||
| 728 | ui->controllerFrame->SetController(emulated_controller); | ||
| 729 | } | 726 | } |
| 730 | emulated_controller->SetNpadStyleIndex(type); | 727 | } |
| 731 | }); | 728 | ui->controllerFrame->SetController(emulated_controller); |
| 729 | } | ||
| 730 | emulated_controller->SetNpadStyleIndex(type); | ||
| 731 | }); | ||
| 732 | 732 | ||
| 733 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, | 733 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, |
| 734 | &ConfigureInputPlayer::UpdateMappingWithDefaults); | 734 | &ConfigureInputPlayer::UpdateMappingWithDefaults); |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 54b3fe150..af8343b2e 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -35,10 +35,10 @@ | |||
| 35 | #include "yuzu/uisettings.h" | 35 | #include "yuzu/uisettings.h" |
| 36 | #include "yuzu/util/util.h" | 36 | #include "yuzu/util/util.h" |
| 37 | 37 | ||
| 38 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::string& file_name, | 38 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, |
| 39 | Core::System& system_) | 39 | Core::System& system_) |
| 40 | : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), | 40 | : QDialog(parent), |
| 41 | title_id(title_id), system{system_} { | 41 | ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} { |
| 42 | const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); | 42 | const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); |
| 43 | const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) | 43 | const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) |
| 44 | : fmt::format("{:016X}", title_id); | 44 | : fmt::format("{:016X}", title_id); |
| @@ -116,8 +116,8 @@ void ConfigurePerGame::HandleApplyButtonClicked() { | |||
| 116 | ApplyConfiguration(); | 116 | ApplyConfiguration(); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file) { | 119 | void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file_) { |
| 120 | this->file = std::move(file); | 120 | file = std::move(file_); |
| 121 | LoadConfiguration(); | 121 | LoadConfiguration(); |
| 122 | } | 122 | } |
| 123 | 123 | ||
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index e6dc05546..17a98a0f3 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h | |||
| @@ -39,14 +39,14 @@ class ConfigurePerGame : public QDialog { | |||
| 39 | 39 | ||
| 40 | public: | 40 | public: |
| 41 | // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 | 41 | // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 |
| 42 | explicit ConfigurePerGame(QWidget* parent, u64 title_id, const std::string& file_name, | 42 | explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, |
| 43 | Core::System& system_); | 43 | Core::System& system_); |
| 44 | ~ConfigurePerGame() override; | 44 | ~ConfigurePerGame() override; |
| 45 | 45 | ||
| 46 | /// Save all button configurations to settings file | 46 | /// Save all button configurations to settings file |
| 47 | void ApplyConfiguration(); | 47 | void ApplyConfiguration(); |
| 48 | 48 | ||
| 49 | void LoadFromFile(FileSys::VirtualFile file); | 49 | void LoadFromFile(FileSys::VirtualFile file_); |
| 50 | 50 | ||
| 51 | private: | 51 | private: |
| 52 | void changeEvent(QEvent* event) override; | 52 | void changeEvent(QEvent* event) override; |
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 7893a85bb..4906997ab 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp | |||
| @@ -89,8 +89,8 @@ void ConfigurePerGameAddons::ApplyConfiguration() { | |||
| 89 | Settings::values.disabled_addons[title_id] = disabled_addons; | 89 | Settings::values.disabled_addons[title_id] = disabled_addons; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file) { | 92 | void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file_) { |
| 93 | this->file = std::move(file); | 93 | file = std::move(file_); |
| 94 | LoadConfiguration(); | 94 | LoadConfiguration(); |
| 95 | } | 95 | } |
| 96 | 96 | ||
diff --git a/src/yuzu/configuration/configure_per_game_addons.h b/src/yuzu/configuration/configure_per_game_addons.h index 24b017494..14690fba8 100644 --- a/src/yuzu/configuration/configure_per_game_addons.h +++ b/src/yuzu/configuration/configure_per_game_addons.h | |||
| @@ -35,7 +35,7 @@ public: | |||
| 35 | /// Save all button configurations to settings file | 35 | /// Save all button configurations to settings file |
| 36 | void ApplyConfiguration(); | 36 | void ApplyConfiguration(); |
| 37 | 37 | ||
| 38 | void LoadFromFile(FileSys::VirtualFile file); | 38 | void LoadFromFile(FileSys::VirtualFile file_); |
| 39 | 39 | ||
| 40 | void SetTitleId(u64 id); | 40 | void SetTitleId(u64 id); |
| 41 | 41 | ||
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp index 4fcc22b7a..688c2dd38 100644 --- a/src/yuzu/configuration/configure_ringcon.cpp +++ b/src/yuzu/configuration/configure_ringcon.cpp | |||
| @@ -165,10 +165,10 @@ ConfigureRingController::ConfigureRingController(QWidget* parent, | |||
| 165 | const std::string invert_str = invert_value ? "+" : "-"; | 165 | const std::string invert_str = invert_value ? "+" : "-"; |
| 166 | param.Set("invert_x", invert_str); | 166 | param.Set("invert_x", invert_str); |
| 167 | emulated_device->SetRingParam(param); | 167 | emulated_device->SetRingParam(param); |
| 168 | for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; | 168 | for (int sub_button_id2 = 0; sub_button_id2 < ANALOG_SUB_BUTTONS_NUM; |
| 169 | ++sub_button_id) { | 169 | ++sub_button_id2) { |
| 170 | analog_map_buttons[sub_button_id]->setText( | 170 | analog_map_buttons[sub_button_id2]->setText( |
| 171 | AnalogToText(param, analog_sub_buttons[sub_button_id])); | 171 | AnalogToText(param, analog_sub_buttons[sub_button_id2])); |
| 172 | } | 172 | } |
| 173 | }); | 173 | }); |
| 174 | context_menu.exec( | 174 | context_menu.exec( |
diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp index c17da6fd1..06cc452c3 100644 --- a/src/yuzu/configuration/configure_touch_from_button.cpp +++ b/src/yuzu/configuration/configure_touch_from_button.cpp | |||
| @@ -68,10 +68,10 @@ static QString ButtonToText(const Common::ParamPackage& param) { | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | ConfigureTouchFromButton::ConfigureTouchFromButton( | 70 | ConfigureTouchFromButton::ConfigureTouchFromButton( |
| 71 | QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps, | 71 | QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps_, |
| 72 | InputCommon::InputSubsystem* input_subsystem_, const int default_index) | 72 | InputCommon::InputSubsystem* input_subsystem_, const int default_index) |
| 73 | : QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), | 73 | : QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), |
| 74 | touch_maps(touch_maps), input_subsystem{input_subsystem_}, selected_index(default_index), | 74 | touch_maps{touch_maps_}, input_subsystem{input_subsystem_}, selected_index{default_index}, |
| 75 | timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { | 75 | timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { |
| 76 | ui->setupUi(this); | 76 | ui->setupUi(this); |
| 77 | binding_list_model = new QStandardItemModel(0, 3, this); | 77 | binding_list_model = new QStandardItemModel(0, 3, this); |
diff --git a/src/yuzu/configuration/configure_touch_from_button.h b/src/yuzu/configuration/configure_touch_from_button.h index e1400481a..b8c55db66 100644 --- a/src/yuzu/configuration/configure_touch_from_button.h +++ b/src/yuzu/configuration/configure_touch_from_button.h | |||
| @@ -37,7 +37,7 @@ class ConfigureTouchFromButton : public QDialog { | |||
| 37 | 37 | ||
| 38 | public: | 38 | public: |
| 39 | explicit ConfigureTouchFromButton(QWidget* parent, | 39 | explicit ConfigureTouchFromButton(QWidget* parent, |
| 40 | const std::vector<Settings::TouchFromButtonMap>& touch_maps, | 40 | const std::vector<Settings::TouchFromButtonMap>& touch_maps_, |
| 41 | InputCommon::InputSubsystem* input_subsystem_, | 41 | InputCommon::InputSubsystem* input_subsystem_, |
| 42 | int default_index = 0); | 42 | int default_index = 0); |
| 43 | ~ConfigureTouchFromButton() override; | 43 | ~ConfigureTouchFromButton() override; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 8f486a131..0ea31cd33 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -113,9 +113,9 @@ QString WaitTreeText::GetText() const { | |||
| 113 | return text; | 113 | return text; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table, | 116 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address_, const Kernel::KHandleTable& handle_table, |
| 117 | Core::System& system_) | 117 | Core::System& system_) |
| 118 | : mutex_address(mutex_address), system{system_} { | 118 | : mutex_address{mutex_address_}, system{system_} { |
| 119 | mutex_value = system.Memory().Read32(mutex_address); | 119 | mutex_value = system.Memory().Read32(mutex_address); |
| 120 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); | 120 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); |
| 121 | owner = handle_table.GetObject<Kernel::KThread>(owner_handle).GetPointerUnsafe(); | 121 | owner = handle_table.GetObject<Kernel::KThread>(owner_handle).GetPointerUnsafe(); |
| @@ -140,8 +140,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() cons | |||
| 140 | return list; | 140 | return list; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread, Core::System& system_) | 143 | WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_) |
| 144 | : thread(thread), system{system_} {} | 144 | : thread{thread_}, system{system_} {} |
| 145 | WaitTreeCallstack::~WaitTreeCallstack() = default; | 145 | WaitTreeCallstack::~WaitTreeCallstack() = default; |
| 146 | 146 | ||
| 147 | QString WaitTreeCallstack::GetText() const { | 147 | QString WaitTreeCallstack::GetText() const { |
| @@ -171,8 +171,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons | |||
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | WaitTreeSynchronizationObject::WaitTreeSynchronizationObject( | 173 | WaitTreeSynchronizationObject::WaitTreeSynchronizationObject( |
| 174 | const Kernel::KSynchronizationObject& o, Core::System& system_) | 174 | const Kernel::KSynchronizationObject& object_, Core::System& system_) |
| 175 | : object(o), system{system_} {} | 175 | : object{object_}, system{system_} {} |
| 176 | WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default; | 176 | WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default; |
| 177 | 177 | ||
| 178 | WaitTreeExpandableItem::WaitTreeExpandableItem() = default; | 178 | WaitTreeExpandableItem::WaitTreeExpandableItem() = default; |
| @@ -380,8 +380,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 380 | return list; | 380 | return list; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object, Core::System& system_) | 383 | WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_) |
| 384 | : WaitTreeSynchronizationObject(object, system_) {} | 384 | : WaitTreeSynchronizationObject(object_, system_) {} |
| 385 | WaitTreeEvent::~WaitTreeEvent() = default; | 385 | WaitTreeEvent::~WaitTreeEvent() = default; |
| 386 | 386 | ||
| 387 | WaitTreeThreadList::WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_) | 387 | WaitTreeThreadList::WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_) |
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 4a36dfc48..f21b9f467 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -78,7 +78,7 @@ public: | |||
| 78 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { | 78 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { |
| 79 | Q_OBJECT | 79 | Q_OBJECT |
| 80 | public: | 80 | public: |
| 81 | explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table, | 81 | explicit WaitTreeMutexInfo(VAddr mutex_address_, const Kernel::KHandleTable& handle_table, |
| 82 | Core::System& system_); | 82 | Core::System& system_); |
| 83 | ~WaitTreeMutexInfo() override; | 83 | ~WaitTreeMutexInfo() override; |
| 84 | 84 | ||
| @@ -97,7 +97,7 @@ private: | |||
| 97 | class WaitTreeCallstack : public WaitTreeExpandableItem { | 97 | class WaitTreeCallstack : public WaitTreeExpandableItem { |
| 98 | Q_OBJECT | 98 | Q_OBJECT |
| 99 | public: | 99 | public: |
| 100 | explicit WaitTreeCallstack(const Kernel::KThread& thread, Core::System& system_); | 100 | explicit WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_); |
| 101 | ~WaitTreeCallstack() override; | 101 | ~WaitTreeCallstack() override; |
| 102 | 102 | ||
| 103 | QString GetText() const override; | 103 | QString GetText() const override; |
| @@ -112,7 +112,7 @@ private: | |||
| 112 | class WaitTreeSynchronizationObject : public WaitTreeExpandableItem { | 112 | class WaitTreeSynchronizationObject : public WaitTreeExpandableItem { |
| 113 | Q_OBJECT | 113 | Q_OBJECT |
| 114 | public: | 114 | public: |
| 115 | explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object, | 115 | explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object_, |
| 116 | Core::System& system_); | 116 | Core::System& system_); |
| 117 | ~WaitTreeSynchronizationObject() override; | 117 | ~WaitTreeSynchronizationObject() override; |
| 118 | 118 | ||
| @@ -162,7 +162,7 @@ private: | |||
| 162 | class WaitTreeEvent : public WaitTreeSynchronizationObject { | 162 | class WaitTreeEvent : public WaitTreeSynchronizationObject { |
| 163 | Q_OBJECT | 163 | Q_OBJECT |
| 164 | public: | 164 | public: |
| 165 | explicit WaitTreeEvent(const Kernel::KReadableEvent& object, Core::System& system_); | 165 | explicit WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_); |
| 166 | ~WaitTreeEvent() override; | 166 | ~WaitTreeEvent() override; |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 6321afc83..05d309827 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -28,8 +28,8 @@ | |||
| 28 | #include "yuzu/uisettings.h" | 28 | #include "yuzu/uisettings.h" |
| 29 | #include "yuzu/util/controller_navigation.h" | 29 | #include "yuzu/util/controller_navigation.h" |
| 30 | 30 | ||
| 31 | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent) | 31 | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent) |
| 32 | : QObject(parent), gamelist{gamelist} {} | 32 | : QObject(parent), gamelist{gamelist_} {} |
| 33 | 33 | ||
| 34 | // EventFilter in order to process systemkeys while editing the searchfield | 34 | // EventFilter in order to process systemkeys while editing the searchfield |
| 35 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { | 35 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { |
| @@ -80,9 +80,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve | |||
| 80 | return QObject::eventFilter(obj, event); | 80 | return QObject::eventFilter(obj, event); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | void GameListSearchField::setFilterResult(int visible, int total) { | 83 | void GameListSearchField::setFilterResult(int visible_, int total_) { |
| 84 | this->visible = visible; | 84 | visible = visible_; |
| 85 | this->total = total; | 85 | total = total_; |
| 86 | 86 | ||
| 87 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); | 87 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); |
| 88 | } | 88 | } |
| @@ -309,9 +309,9 @@ void GameList::OnFilterCloseClicked() { | |||
| 309 | main_window->filterBarSetChecked(false); | 309 | main_window->filterBarSetChecked(false); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvider* provider, | 312 | GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvider* provider_, |
| 313 | Core::System& system_, GMainWindow* parent) | 313 | Core::System& system_, GMainWindow* parent) |
| 314 | : QWidget{parent}, vfs(std::move(vfs)), provider(provider), system{system_} { | 314 | : QWidget{parent}, vfs{std::move(vfs_)}, provider{provider_}, system{system_} { |
| 315 | watcher = new QFileSystemWatcher(this); | 315 | watcher = new QFileSystemWatcher(this); |
| 316 | connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); | 316 | connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); |
| 317 | 317 | ||
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 464da98ad..bc36d015a 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -67,8 +67,8 @@ public: | |||
| 67 | COLUMN_COUNT, // Number of columns | 67 | COLUMN_COUNT, // Number of columns |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs, | 70 | explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs_, |
| 71 | FileSys::ManualContentProvider* provider, Core::System& system_, | 71 | FileSys::ManualContentProvider* provider_, Core::System& system_, |
| 72 | GMainWindow* parent = nullptr); | 72 | GMainWindow* parent = nullptr); |
| 73 | ~GameList() override; | 73 | ~GameList() override; |
| 74 | 74 | ||
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index f2a986ed8..cd7d63536 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h | |||
| @@ -225,8 +225,8 @@ public: | |||
| 225 | static constexpr int GameDirRole = Qt::UserRole + 2; | 225 | static constexpr int GameDirRole = Qt::UserRole + 2; |
| 226 | 226 | ||
| 227 | explicit GameListDir(UISettings::GameDir& directory, | 227 | explicit GameListDir(UISettings::GameDir& directory, |
| 228 | GameListItemType dir_type = GameListItemType::CustomDir) | 228 | GameListItemType dir_type_ = GameListItemType::CustomDir) |
| 229 | : dir_type{dir_type} { | 229 | : dir_type{dir_type_} { |
| 230 | setData(type(), TypeRole); | 230 | setData(type(), TypeRole); |
| 231 | 231 | ||
| 232 | UISettings::GameDir* game_dir = &directory; | 232 | UISettings::GameDir* game_dir = &directory; |
| @@ -348,7 +348,7 @@ public: | |||
| 348 | explicit GameListSearchField(GameList* parent = nullptr); | 348 | explicit GameListSearchField(GameList* parent = nullptr); |
| 349 | 349 | ||
| 350 | QString filterText() const; | 350 | QString filterText() const; |
| 351 | void setFilterResult(int visible, int total); | 351 | void setFilterResult(int visible_, int total_); |
| 352 | 352 | ||
| 353 | void clear(); | 353 | void clear(); |
| 354 | void setFocus(); | 354 | void setFocus(); |
| @@ -356,7 +356,7 @@ public: | |||
| 356 | private: | 356 | private: |
| 357 | class KeyReleaseEater : public QObject { | 357 | class KeyReleaseEater : public QObject { |
| 358 | public: | 358 | public: |
| 359 | explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr); | 359 | explicit KeyReleaseEater(GameList* gamelist_, QObject* parent = nullptr); |
| 360 | 360 | ||
| 361 | private: | 361 | private: |
| 362 | GameList* gamelist = nullptr; | 362 | GameList* gamelist = nullptr; |
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index ca1899b5c..63326968b 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp | |||
| @@ -223,12 +223,12 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri | |||
| 223 | } | 223 | } |
| 224 | } // Anonymous namespace | 224 | } // Anonymous namespace |
| 225 | 225 | ||
| 226 | GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, | 226 | GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_, |
| 227 | FileSys::ManualContentProvider* provider, | 227 | FileSys::ManualContentProvider* provider_, |
| 228 | QVector<UISettings::GameDir>& game_dirs, | 228 | QVector<UISettings::GameDir>& game_dirs_, |
| 229 | const CompatibilityList& compatibility_list, Core::System& system_) | 229 | const CompatibilityList& compatibility_list_, Core::System& system_) |
| 230 | : vfs(std::move(vfs)), provider(provider), game_dirs(game_dirs), | 230 | : vfs{std::move(vfs_)}, provider{provider_}, game_dirs{game_dirs_}, |
| 231 | compatibility_list(compatibility_list), system{system_} {} | 231 | compatibility_list{compatibility_list_}, system{system_} {} |
| 232 | 232 | ||
| 233 | GameListWorker::~GameListWorker() = default; | 233 | GameListWorker::~GameListWorker() = default; |
| 234 | 234 | ||
diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 622d241fb..24a4e92c3 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h | |||
| @@ -33,10 +33,10 @@ class GameListWorker : public QObject, public QRunnable { | |||
| 33 | Q_OBJECT | 33 | Q_OBJECT |
| 34 | 34 | ||
| 35 | public: | 35 | public: |
| 36 | explicit GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs, | 36 | explicit GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs_, |
| 37 | FileSys::ManualContentProvider* provider, | 37 | FileSys::ManualContentProvider* provider_, |
| 38 | QVector<UISettings::GameDir>& game_dirs, | 38 | QVector<UISettings::GameDir>& game_dirs_, |
| 39 | const CompatibilityList& compatibility_list, Core::System& system_); | 39 | const CompatibilityList& compatibility_list_, Core::System& system_); |
| 40 | ~GameListWorker() override; | 40 | ~GameListWorker() override; |
| 41 | 41 | ||
| 42 | /// Starts the processing of directory tree information. | 42 | /// Starts the processing of directory tree information. |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 27f23bcb0..b460020b1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -934,8 +934,7 @@ void GMainWindow::InitializeWidgets() { | |||
| 934 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); | 934 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); |
| 935 | } else { | 935 | } else { |
| 936 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); | 936 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); |
| 937 | const auto filter = Settings::values.scaling_filter.GetValue(); | 937 | if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { |
| 938 | if (filter == Settings::ScalingFilter::Fsr) { | ||
| 939 | Settings::values.scaling_filter.SetValue(Settings::ScalingFilter::NearestNeighbor); | 938 | Settings::values.scaling_filter.SetValue(Settings::ScalingFilter::NearestNeighbor); |
| 940 | UpdateFilterText(); | 939 | UpdateFilterText(); |
| 941 | } | 940 | } |
| @@ -1442,7 +1441,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | |||
| 1442 | } | 1441 | } |
| 1443 | return false; | 1442 | return false; |
| 1444 | } | 1443 | } |
| 1445 | game_path = filename; | 1444 | current_game_path = filename; |
| 1446 | 1445 | ||
| 1447 | system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); | 1446 | system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); |
| 1448 | return true; | 1447 | return true; |
| @@ -1508,7 +1507,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | |||
| 1508 | 1507 | ||
| 1509 | // Register an ExecuteProgram callback such that Core can execute a sub-program | 1508 | // Register an ExecuteProgram callback such that Core can execute a sub-program |
| 1510 | system->RegisterExecuteProgramCallback( | 1509 | system->RegisterExecuteProgramCallback( |
| 1511 | [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); }); | 1510 | [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); }); |
| 1512 | 1511 | ||
| 1513 | // Register an Exit callback such that Core can exit the currently running application. | 1512 | // Register an Exit callback such that Core can exit the currently running application. |
| 1514 | system->RegisterExitCallback([this]() { render_window->Exit(); }); | 1513 | system->RegisterExitCallback([this]() { render_window->Exit(); }); |
| @@ -1591,6 +1590,7 @@ void GMainWindow::ShutdownGame() { | |||
| 1591 | 1590 | ||
| 1592 | AllowOSSleep(); | 1591 | AllowOSSleep(); |
| 1593 | 1592 | ||
| 1593 | system->DetachDebugger(); | ||
| 1594 | discord_rpc->Pause(); | 1594 | discord_rpc->Pause(); |
| 1595 | emu_thread->RequestStop(); | 1595 | emu_thread->RequestStop(); |
| 1596 | 1596 | ||
| @@ -1640,7 +1640,7 @@ void GMainWindow::ShutdownGame() { | |||
| 1640 | emu_frametime_label->setVisible(false); | 1640 | emu_frametime_label->setVisible(false); |
| 1641 | renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); | 1641 | renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); |
| 1642 | 1642 | ||
| 1643 | game_path.clear(); | 1643 | current_game_path.clear(); |
| 1644 | 1644 | ||
| 1645 | // When closing the game, destroy the GLWindow to clear the context after the game is closed | 1645 | // When closing the game, destroy the GLWindow to clear the context after the game is closed |
| 1646 | render_window->ReleaseRenderTarget(); | 1646 | render_window->ReleaseRenderTarget(); |
| @@ -2559,7 +2559,7 @@ void GMainWindow::OnRestartGame() { | |||
| 2559 | return; | 2559 | return; |
| 2560 | } | 2560 | } |
| 2561 | // Make a copy since BootGame edits game_path | 2561 | // Make a copy since BootGame edits game_path |
| 2562 | BootGame(QString(game_path)); | 2562 | BootGame(QString(current_game_path)); |
| 2563 | } | 2563 | } |
| 2564 | 2564 | ||
| 2565 | void GMainWindow::OnPauseGame() { | 2565 | void GMainWindow::OnPauseGame() { |
| @@ -2988,7 +2988,7 @@ void GMainWindow::OnToggleAdaptingFilter() { | |||
| 2988 | 2988 | ||
| 2989 | void GMainWindow::OnConfigurePerGame() { | 2989 | void GMainWindow::OnConfigurePerGame() { |
| 2990 | const u64 title_id = system->GetCurrentProcessProgramID(); | 2990 | const u64 title_id = system->GetCurrentProcessProgramID(); |
| 2991 | OpenPerGameConfiguration(title_id, game_path.toStdString()); | 2991 | OpenPerGameConfiguration(title_id, current_game_path.toStdString()); |
| 2992 | } | 2992 | } |
| 2993 | 2993 | ||
| 2994 | void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) { | 2994 | void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 600647015..8cf224c9c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -369,7 +369,7 @@ private: | |||
| 369 | bool emulation_running = false; | 369 | bool emulation_running = false; |
| 370 | std::unique_ptr<EmuThread> emu_thread; | 370 | std::unique_ptr<EmuThread> emu_thread; |
| 371 | // The path to the game currently running | 371 | // The path to the game currently running |
| 372 | QString game_path; | 372 | QString current_game_path; |
| 373 | 373 | ||
| 374 | bool auto_paused = false; | 374 | bool auto_paused = false; |
| 375 | bool auto_muted = false; | 375 | bool auto_muted = false; |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index fc16f0f0c..fc4744fb0 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -344,6 +344,8 @@ void Config::ReadValues() { | |||
| 344 | ReadSetting("Debugging", Settings::values.use_debug_asserts); | 344 | ReadSetting("Debugging", Settings::values.use_debug_asserts); |
| 345 | ReadSetting("Debugging", Settings::values.use_auto_stub); | 345 | ReadSetting("Debugging", Settings::values.use_auto_stub); |
| 346 | ReadSetting("Debugging", Settings::values.disable_macro_jit); | 346 | ReadSetting("Debugging", Settings::values.disable_macro_jit); |
| 347 | ReadSetting("Debugging", Settings::values.use_gdbstub); | ||
| 348 | ReadSetting("Debugging", Settings::values.gdbstub_port); | ||
| 347 | 349 | ||
| 348 | const auto title_list = sdl2_config->Get("AddOns", "title_ids", ""); | 350 | const auto title_list = sdl2_config->Get("AddOns", "title_ids", ""); |
| 349 | std::stringstream ss(title_list); | 351 | std::stringstream ss(title_list); |
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 39063e32b..a3b8432f5 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -437,6 +437,11 @@ disable_macro_jit=false | |||
| 437 | # Presents guest frames as they become available. Experimental. | 437 | # Presents guest frames as they become available. Experimental. |
| 438 | # false: Disabled (default), true: Enabled | 438 | # false: Disabled (default), true: Enabled |
| 439 | disable_fps_limit=false | 439 | disable_fps_limit=false |
| 440 | # Determines whether to enable the GDB stub and wait for the debugger to attach before running. | ||
| 441 | # false: Disabled (default), true: Enabled | ||
| 442 | use_gdbstub=false | ||
| 443 | # The port to use for the GDB server, if it is enabled. | ||
| 444 | gdbstub_port=6543 | ||
| 440 | 445 | ||
| 441 | [WebService] | 446 | [WebService] |
| 442 | # Whether or not to enable telemetry | 447 | # Whether or not to enable telemetry |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 71c413e64..8e38724db 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | |||
| @@ -162,7 +162,15 @@ void EmuWindow_SDL2::WaitEvent() { | |||
| 162 | SDL_Event event; | 162 | SDL_Event event; |
| 163 | 163 | ||
| 164 | if (!SDL_WaitEvent(&event)) { | 164 | if (!SDL_WaitEvent(&event)) { |
| 165 | LOG_CRITICAL(Frontend, "SDL_WaitEvent failed: {}", SDL_GetError()); | 165 | const char* error = SDL_GetError(); |
| 166 | if (!error || strcmp(error, "") == 0) { | ||
| 167 | // https://github.com/libsdl-org/SDL/issues/5780 | ||
| 168 | // Sometimes SDL will return without actually having hit an error condition; | ||
| 169 | // just ignore it in this case. | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | |||
| 173 | LOG_CRITICAL(Frontend, "SDL_WaitEvent failed: {}", error); | ||
| 166 | exit(1); | 174 | exit(1); |
| 167 | } | 175 | } |
| 168 | 176 | ||
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 9746585f5..58b885465 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h | |||
| @@ -20,7 +20,7 @@ enum class MouseButton; | |||
| 20 | 20 | ||
| 21 | class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { | 21 | class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { |
| 22 | public: | 22 | public: |
| 23 | explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem, Core::System& system_); | 23 | explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); |
| 24 | ~EmuWindow_SDL2(); | 24 | ~EmuWindow_SDL2(); |
| 25 | 25 | ||
| 26 | /// Whether the window is still open, and a close request hasn't yet been sent | 26 | /// Whether the window is still open, and a close request hasn't yet been sent |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 8075c9082..9b660c13c 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | |||
| @@ -73,9 +73,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { | |||
| 73 | return unsupported_ext.empty(); | 73 | return unsupported_ext.empty(); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, | 76 | EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, |
| 77 | Core::System& system_, bool fullscreen) | 77 | Core::System& system_, bool fullscreen) |
| 78 | : EmuWindow_SDL2{input_subsystem, system_} { | 78 | : EmuWindow_SDL2{input_subsystem_, system_} { |
| 79 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); | 79 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); |
| 80 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); | 80 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); |
| 81 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); | 81 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h index d159166fd..39346e704 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h | |||
| @@ -17,7 +17,7 @@ class InputSubsystem; | |||
| 17 | 17 | ||
| 18 | class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { | 18 | class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { |
| 19 | public: | 19 | public: |
| 20 | explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, Core::System& system_, | 20 | explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, |
| 21 | bool fullscreen); | 21 | bool fullscreen); |
| 22 | ~EmuWindow_SDL2_GL(); | 22 | ~EmuWindow_SDL2_GL(); |
| 23 | 23 | ||
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index d5fe35aa0..65455c86e 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp | |||
| @@ -21,9 +21,9 @@ | |||
| 21 | #include <SDL.h> | 21 | #include <SDL.h> |
| 22 | #include <SDL_syswm.h> | 22 | #include <SDL_syswm.h> |
| 23 | 23 | ||
| 24 | EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, | 24 | EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, |
| 25 | Core::System& system_, bool fullscreen) | 25 | Core::System& system_, bool fullscreen) |
| 26 | : EmuWindow_SDL2{input_subsystem, system_} { | 26 | : EmuWindow_SDL2{input_subsystem_, system_} { |
| 27 | const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, | 27 | const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, |
| 28 | Common::g_scm_branch, Common::g_scm_desc); | 28 | Common::g_scm_branch, Common::g_scm_desc); |
| 29 | render_window = | 29 | render_window = |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h index d92e3aaab..e39ad754d 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h | |||
| @@ -18,7 +18,7 @@ class InputSubsystem; | |||
| 18 | 18 | ||
| 19 | class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { | 19 | class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { |
| 20 | public: | 20 | public: |
| 21 | explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, Core::System& system, | 21 | explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, |
| 22 | bool fullscreen); | 22 | bool fullscreen); |
| 23 | ~EmuWindow_SDL2_VK() override; | 23 | ~EmuWindow_SDL2_VK() override; |
| 24 | 24 | ||
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index ab12dd15d..cb301e78b 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "common/string_util.h" | 21 | #include "common/string_util.h" |
| 22 | #include "common/telemetry.h" | 22 | #include "common/telemetry.h" |
| 23 | #include "core/core.h" | 23 | #include "core/core.h" |
| 24 | #include "core/cpu_manager.h" | ||
| 24 | #include "core/crypto/key_manager.h" | 25 | #include "core/crypto/key_manager.h" |
| 25 | #include "core/file_sys/registered_cache.h" | 26 | #include "core/file_sys/registered_cache.h" |
| 26 | #include "core/file_sys/vfs_real.h" | 27 | #include "core/file_sys/vfs_real.h" |
| @@ -138,6 +139,12 @@ int main(int argc, char** argv) { | |||
| 138 | 139 | ||
| 139 | Config config{config_path}; | 140 | Config config{config_path}; |
| 140 | 141 | ||
| 142 | // apply the log_filter setting | ||
| 143 | // the logger was initialized before and doesn't pick up the filter on its own | ||
| 144 | Common::Log::Filter filter; | ||
| 145 | filter.ParseFilterString(Settings::values.log_filter.GetValue()); | ||
| 146 | Common::Log::SetGlobalFilter(filter); | ||
| 147 | |||
| 141 | if (!program_args.empty()) { | 148 | if (!program_args.empty()) { |
| 142 | Settings::values.program_args = program_args; | 149 | Settings::values.program_args = program_args; |
| 143 | } | 150 | } |
| @@ -210,6 +217,7 @@ int main(int argc, char** argv) { | |||
| 210 | 217 | ||
| 211 | // Core is loaded, start the GPU (makes the GPU contexts current to this thread) | 218 | // Core is loaded, start the GPU (makes the GPU contexts current to this thread) |
| 212 | system.GPU().Start(); | 219 | system.GPU().Start(); |
| 220 | system.GetCpuManager().OnGpuReady(); | ||
| 213 | 221 | ||
| 214 | if (Settings::values.use_disk_shader_cache.GetValue()) { | 222 | if (Settings::values.use_disk_shader_cache.GetValue()) { |
| 215 | system.Renderer().ReadRasterizer()->LoadDiskResources( | 223 | system.Renderer().ReadRasterizer()->LoadDiskResources( |
| @@ -217,10 +225,19 @@ int main(int argc, char** argv) { | |||
| 217 | [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); | 225 | [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); |
| 218 | } | 226 | } |
| 219 | 227 | ||
| 228 | system.RegisterExitCallback([&] { | ||
| 229 | // Just exit right away. | ||
| 230 | exit(0); | ||
| 231 | }); | ||
| 232 | |||
| 220 | void(system.Run()); | 233 | void(system.Run()); |
| 234 | if (system.DebuggerEnabled()) { | ||
| 235 | system.InitializeDebugger(); | ||
| 236 | } | ||
| 221 | while (emu_window->IsOpen()) { | 237 | while (emu_window->IsOpen()) { |
| 222 | emu_window->WaitEvent(); | 238 | emu_window->WaitEvent(); |
| 223 | } | 239 | } |
| 240 | system.DetachDebugger(); | ||
| 224 | void(system.Pause()); | 241 | void(system.Pause()); |
| 225 | system.Shutdown(); | 242 | system.Shutdown(); |
| 226 | 243 | ||