diff options
Diffstat (limited to 'src/core')
70 files changed, 644 insertions, 612 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4c53aed72..dd2c053d0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -14,7 +14,6 @@ add_library(core STATIC | |||
| 14 | core.h | 14 | core.h |
| 15 | core_timing.cpp | 15 | core_timing.cpp |
| 16 | core_timing.h | 16 | core_timing.h |
| 17 | core_timing_util.h | ||
| 18 | cpu_manager.cpp | 17 | cpu_manager.cpp |
| 19 | cpu_manager.h | 18 | cpu_manager.h |
| 20 | crypto/aes_util.cpp | 19 | crypto/aes_util.cpp |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 5acf9008d..3b82fb73c 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -322,11 +322,6 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* | |||
| 322 | } | 322 | } |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | #ifdef ARCHITECTURE_arm64 | ||
| 326 | // TODO: remove when fixed in dynarmic | ||
| 327 | config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking; | ||
| 328 | #endif | ||
| 329 | |||
| 330 | return std::make_unique<Dynarmic::A32::Jit>(config); | 325 | return std::make_unique<Dynarmic::A32::Jit>(config); |
| 331 | } | 326 | } |
| 332 | 327 | ||
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 4f2692b05..4f0a3f8ea 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -16,12 +16,11 @@ | |||
| 16 | 16 | ||
| 17 | #include "common/microprofile.h" | 17 | #include "common/microprofile.h" |
| 18 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 19 | #include "core/core_timing_util.h" | ||
| 20 | #include "core/hardware_properties.h" | 19 | #include "core/hardware_properties.h" |
| 21 | 20 | ||
| 22 | namespace Core::Timing { | 21 | namespace Core::Timing { |
| 23 | 22 | ||
| 24 | constexpr s64 MAX_SLICE_LENGTH = 4000; | 23 | constexpr s64 MAX_SLICE_LENGTH = 10000; |
| 25 | 24 | ||
| 26 | std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) { | 25 | std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) { |
| 27 | return std::make_shared<EventType>(std::move(callback), std::move(name)); | 26 | return std::make_shared<EventType>(std::move(callback), std::move(name)); |
| @@ -45,9 +44,7 @@ struct CoreTiming::Event { | |||
| 45 | } | 44 | } |
| 46 | }; | 45 | }; |
| 47 | 46 | ||
| 48 | CoreTiming::CoreTiming() | 47 | CoreTiming::CoreTiming() : clock{Common::CreateOptimalClock()} {} |
| 49 | : cpu_clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)}, | ||
| 50 | event_clock{Common::CreateStandardWallClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} | ||
| 51 | 48 | ||
| 52 | CoreTiming::~CoreTiming() { | 49 | CoreTiming::~CoreTiming() { |
| 53 | Reset(); | 50 | Reset(); |
| @@ -68,7 +65,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { | |||
| 68 | on_thread_init = std::move(on_thread_init_); | 65 | on_thread_init = std::move(on_thread_init_); |
| 69 | event_fifo_id = 0; | 66 | event_fifo_id = 0; |
| 70 | shutting_down = false; | 67 | shutting_down = false; |
| 71 | ticks = 0; | 68 | cpu_ticks = 0; |
| 72 | const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds) | 69 | const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds) |
| 73 | -> std::optional<std::chrono::nanoseconds> { return std::nullopt; }; | 70 | -> std::optional<std::chrono::nanoseconds> { return std::nullopt; }; |
| 74 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); | 71 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); |
| @@ -173,38 +170,30 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, | |||
| 173 | } | 170 | } |
| 174 | 171 | ||
| 175 | void CoreTiming::AddTicks(u64 ticks_to_add) { | 172 | void CoreTiming::AddTicks(u64 ticks_to_add) { |
| 176 | ticks += ticks_to_add; | 173 | cpu_ticks += ticks_to_add; |
| 177 | downcount -= static_cast<s64>(ticks); | 174 | downcount -= static_cast<s64>(cpu_ticks); |
| 178 | } | 175 | } |
| 179 | 176 | ||
| 180 | void CoreTiming::Idle() { | 177 | void CoreTiming::Idle() { |
| 181 | if (!event_queue.empty()) { | 178 | cpu_ticks += 1000U; |
| 182 | const u64 next_event_time = event_queue.front().time; | ||
| 183 | const u64 next_ticks = nsToCycles(std::chrono::nanoseconds(next_event_time)) + 10U; | ||
| 184 | if (next_ticks > ticks) { | ||
| 185 | ticks = next_ticks; | ||
| 186 | } | ||
| 187 | return; | ||
| 188 | } | ||
| 189 | ticks += 1000U; | ||
| 190 | } | 179 | } |
| 191 | 180 | ||
| 192 | void CoreTiming::ResetTicks() { | 181 | void CoreTiming::ResetTicks() { |
| 193 | downcount = MAX_SLICE_LENGTH; | 182 | downcount = MAX_SLICE_LENGTH; |
| 194 | } | 183 | } |
| 195 | 184 | ||
| 196 | u64 CoreTiming::GetCPUTicks() const { | 185 | u64 CoreTiming::GetClockTicks() const { |
| 197 | if (is_multicore) [[likely]] { | 186 | if (is_multicore) [[likely]] { |
| 198 | return cpu_clock->GetCPUCycles(); | 187 | return clock->GetCNTPCT(); |
| 199 | } | 188 | } |
| 200 | return ticks; | 189 | return Common::WallClock::CPUTickToCNTPCT(cpu_ticks); |
| 201 | } | 190 | } |
| 202 | 191 | ||
| 203 | u64 CoreTiming::GetClockTicks() const { | 192 | u64 CoreTiming::GetGPUTicks() const { |
| 204 | if (is_multicore) [[likely]] { | 193 | if (is_multicore) [[likely]] { |
| 205 | return cpu_clock->GetClockCycles(); | 194 | return clock->GetGPUTick(); |
| 206 | } | 195 | } |
| 207 | return CpuCyclesToClockCycles(ticks); | 196 | return Common::WallClock::CPUTickToGPUTick(cpu_ticks); |
| 208 | } | 197 | } |
| 209 | 198 | ||
| 210 | std::optional<s64> CoreTiming::Advance() { | 199 | std::optional<s64> CoreTiming::Advance() { |
| @@ -297,9 +286,7 @@ void CoreTiming::ThreadLoop() { | |||
| 297 | } | 286 | } |
| 298 | 287 | ||
| 299 | paused_set = true; | 288 | paused_set = true; |
| 300 | event_clock->Pause(true); | ||
| 301 | pause_event.Wait(); | 289 | pause_event.Wait(); |
| 302 | event_clock->Pause(false); | ||
| 303 | } | 290 | } |
| 304 | } | 291 | } |
| 305 | 292 | ||
| @@ -315,25 +302,18 @@ void CoreTiming::Reset() { | |||
| 315 | has_started = false; | 302 | has_started = false; |
| 316 | } | 303 | } |
| 317 | 304 | ||
| 318 | std::chrono::nanoseconds CoreTiming::GetCPUTimeNs() const { | ||
| 319 | if (is_multicore) [[likely]] { | ||
| 320 | return cpu_clock->GetTimeNS(); | ||
| 321 | } | ||
| 322 | return CyclesToNs(ticks); | ||
| 323 | } | ||
| 324 | |||
| 325 | std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { | 305 | std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { |
| 326 | if (is_multicore) [[likely]] { | 306 | if (is_multicore) [[likely]] { |
| 327 | return event_clock->GetTimeNS(); | 307 | return clock->GetTimeNS(); |
| 328 | } | 308 | } |
| 329 | return CyclesToNs(ticks); | 309 | return std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)}; |
| 330 | } | 310 | } |
| 331 | 311 | ||
| 332 | std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { | 312 | std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { |
| 333 | if (is_multicore) [[likely]] { | 313 | if (is_multicore) [[likely]] { |
| 334 | return event_clock->GetTimeUS(); | 314 | return clock->GetTimeUS(); |
| 335 | } | 315 | } |
| 336 | return CyclesToUs(ticks); | 316 | return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)}; |
| 337 | } | 317 | } |
| 338 | 318 | ||
| 339 | } // namespace Core::Timing | 319 | } // namespace Core::Timing |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index e7c4a949f..10db1de55 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -116,14 +116,11 @@ public: | |||
| 116 | return downcount; | 116 | return downcount; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /// Returns current time in emulated CPU cycles | 119 | /// Returns the current CNTPCT tick value. |
| 120 | u64 GetCPUTicks() const; | ||
| 121 | |||
| 122 | /// Returns current time in emulated in Clock cycles | ||
| 123 | u64 GetClockTicks() const; | 120 | u64 GetClockTicks() const; |
| 124 | 121 | ||
| 125 | /// Returns current time in nanoseconds. | 122 | /// Returns the current GPU tick value. |
| 126 | std::chrono::nanoseconds GetCPUTimeNs() const; | 123 | u64 GetGPUTicks() const; |
| 127 | 124 | ||
| 128 | /// Returns current time in microseconds. | 125 | /// Returns current time in microseconds. |
| 129 | std::chrono::microseconds GetGlobalTimeUs() const; | 126 | std::chrono::microseconds GetGlobalTimeUs() const; |
| @@ -142,8 +139,7 @@ private: | |||
| 142 | 139 | ||
| 143 | void Reset(); | 140 | void Reset(); |
| 144 | 141 | ||
| 145 | std::unique_ptr<Common::WallClock> cpu_clock; | 142 | std::unique_ptr<Common::WallClock> clock; |
| 146 | std::unique_ptr<Common::WallClock> event_clock; | ||
| 147 | 143 | ||
| 148 | s64 global_timer = 0; | 144 | s64 global_timer = 0; |
| 149 | 145 | ||
| @@ -171,7 +167,7 @@ private: | |||
| 171 | s64 pause_end_time{}; | 167 | s64 pause_end_time{}; |
| 172 | 168 | ||
| 173 | /// Cycle timing | 169 | /// Cycle timing |
| 174 | u64 ticks{}; | 170 | u64 cpu_ticks{}; |
| 175 | s64 downcount{}; | 171 | s64 downcount{}; |
| 176 | }; | 172 | }; |
| 177 | 173 | ||
diff --git a/src/core/core_timing_util.h b/src/core/core_timing_util.h deleted file mode 100644 index fe5aaefc7..000000000 --- a/src/core/core_timing_util.h +++ /dev/null | |||
| @@ -1,58 +0,0 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <chrono> | ||
| 7 | |||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hardware_properties.h" | ||
| 10 | |||
| 11 | namespace Core::Timing { | ||
| 12 | |||
| 13 | namespace detail { | ||
| 14 | constexpr u64 CNTFREQ_ADJUSTED = Hardware::CNTFREQ / 1000; | ||
| 15 | constexpr u64 BASE_CLOCK_RATE_ADJUSTED = Hardware::BASE_CLOCK_RATE / 1000; | ||
| 16 | } // namespace detail | ||
| 17 | |||
| 18 | [[nodiscard]] constexpr s64 msToCycles(std::chrono::milliseconds ms) { | ||
| 19 | return ms.count() * detail::BASE_CLOCK_RATE_ADJUSTED; | ||
| 20 | } | ||
| 21 | |||
| 22 | [[nodiscard]] constexpr s64 usToCycles(std::chrono::microseconds us) { | ||
| 23 | return us.count() * detail::BASE_CLOCK_RATE_ADJUSTED / 1000; | ||
| 24 | } | ||
| 25 | |||
| 26 | [[nodiscard]] constexpr s64 nsToCycles(std::chrono::nanoseconds ns) { | ||
| 27 | return ns.count() * detail::BASE_CLOCK_RATE_ADJUSTED / 1000000; | ||
| 28 | } | ||
| 29 | |||
| 30 | [[nodiscard]] constexpr u64 msToClockCycles(std::chrono::milliseconds ms) { | ||
| 31 | return static_cast<u64>(ms.count()) * detail::CNTFREQ_ADJUSTED; | ||
| 32 | } | ||
| 33 | |||
| 34 | [[nodiscard]] constexpr u64 usToClockCycles(std::chrono::microseconds us) { | ||
| 35 | return us.count() * detail::CNTFREQ_ADJUSTED / 1000; | ||
| 36 | } | ||
| 37 | |||
| 38 | [[nodiscard]] constexpr u64 nsToClockCycles(std::chrono::nanoseconds ns) { | ||
| 39 | return ns.count() * detail::CNTFREQ_ADJUSTED / 1000000; | ||
| 40 | } | ||
| 41 | |||
| 42 | [[nodiscard]] constexpr u64 CpuCyclesToClockCycles(u64 ticks) { | ||
| 43 | return ticks * detail::CNTFREQ_ADJUSTED / detail::BASE_CLOCK_RATE_ADJUSTED; | ||
| 44 | } | ||
| 45 | |||
| 46 | [[nodiscard]] constexpr std::chrono::milliseconds CyclesToMs(s64 cycles) { | ||
| 47 | return std::chrono::milliseconds(cycles / detail::BASE_CLOCK_RATE_ADJUSTED); | ||
| 48 | } | ||
| 49 | |||
| 50 | [[nodiscard]] constexpr std::chrono::nanoseconds CyclesToNs(s64 cycles) { | ||
| 51 | return std::chrono::nanoseconds(cycles * 1000000 / detail::BASE_CLOCK_RATE_ADJUSTED); | ||
| 52 | } | ||
| 53 | |||
| 54 | [[nodiscard]] constexpr std::chrono::microseconds CyclesToUs(s64 cycles) { | ||
| 55 | return std::chrono::microseconds(cycles * 1000 / detail::BASE_CLOCK_RATE_ADJUSTED); | ||
| 56 | } | ||
| 57 | |||
| 58 | } // namespace Core::Timing | ||
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 4e61d4335..d3286b352 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -153,7 +153,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { | |||
| 153 | const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | 153 | const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); |
| 154 | 154 | ||
| 155 | std::vector<VirtualDir> patch_dirs = {sdmc_load_dir}; | 155 | std::vector<VirtualDir> patch_dirs = {sdmc_load_dir}; |
| 156 | if (load_dir != nullptr && load_dir->GetSize() > 0) { | 156 | if (load_dir != nullptr) { |
| 157 | const auto load_patch_dirs = load_dir->GetSubdirectories(); | 157 | const auto load_patch_dirs = load_dir->GetSubdirectories(); |
| 158 | patch_dirs.insert(patch_dirs.end(), load_patch_dirs.begin(), load_patch_dirs.end()); | 158 | patch_dirs.insert(patch_dirs.end(), load_patch_dirs.begin(), load_patch_dirs.end()); |
| 159 | } | 159 | } |
| @@ -354,8 +354,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 354 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); | 354 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 355 | const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | 355 | const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); |
| 356 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || | 356 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || |
| 357 | ((load_dir == nullptr || load_dir->GetSize() <= 0) && | 357 | (load_dir == nullptr && sdmc_load_dir == nullptr)) { |
| 358 | (sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) { | ||
| 359 | return; | 358 | return; |
| 360 | } | 359 | } |
| 361 | 360 | ||
| @@ -496,7 +495,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 496 | 495 | ||
| 497 | // General Mods (LayeredFS and IPS) | 496 | // General Mods (LayeredFS and IPS) |
| 498 | const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id); | 497 | const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 499 | if (mod_dir != nullptr && mod_dir->GetSize() > 0) { | 498 | if (mod_dir != nullptr) { |
| 500 | for (const auto& mod : mod_dir->GetSubdirectories()) { | 499 | for (const auto& mod : mod_dir->GetSubdirectories()) { |
| 501 | std::string types; | 500 | std::string types; |
| 502 | 501 | ||
| @@ -540,7 +539,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 540 | 539 | ||
| 541 | // SDMC mod directory (RomFS LayeredFS) | 540 | // SDMC mod directory (RomFS LayeredFS) |
| 542 | const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | 541 | const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); |
| 543 | if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0) { | 542 | if (sdmc_mod_dir != nullptr) { |
| 544 | std::string types; | 543 | std::string types; |
| 545 | if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"))) { | 544 | if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"))) { |
| 546 | AppendCommaIfNotEmpty(types, "LayeredExeFS"); | 545 | AppendCommaIfNotEmpty(types, "LayeredExeFS"); |
diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp index 853b893a1..311a59e5f 100644 --- a/src/core/file_sys/vfs_concat.cpp +++ b/src/core/file_sys/vfs_concat.cpp | |||
| @@ -150,23 +150,29 @@ std::size_t ConcatenatedVfsFile::Read(u8* data, std::size_t length, std::size_t | |||
| 150 | while (cur_length > 0 && it != concatenation_map.end()) { | 150 | while (cur_length > 0 && it != concatenation_map.end()) { |
| 151 | // Check if we can read the file at this position. | 151 | // Check if we can read the file at this position. |
| 152 | const auto& file = it->file; | 152 | const auto& file = it->file; |
| 153 | const u64 file_offset = it->offset; | 153 | const u64 map_offset = it->offset; |
| 154 | const u64 file_size = file->GetSize(); | 154 | const u64 file_size = file->GetSize(); |
| 155 | 155 | ||
| 156 | if (cur_offset >= file_offset + file_size) { | 156 | if (cur_offset > map_offset + file_size) { |
| 157 | // Entirely out of bounds read. | 157 | // Entirely out of bounds read. |
| 158 | break; | 158 | break; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | // Read the file at this position. | 161 | // Read the file at this position. |
| 162 | const u64 intended_read_size = std::min<u64>(cur_length, file_size); | 162 | const u64 file_seek = cur_offset - map_offset; |
| 163 | const u64 intended_read_size = std::min<u64>(cur_length, file_size - file_seek); | ||
| 163 | const u64 actual_read_size = | 164 | const u64 actual_read_size = |
| 164 | file->Read(data + (cur_offset - offset), intended_read_size, cur_offset - file_offset); | 165 | file->Read(data + (cur_offset - offset), intended_read_size, file_seek); |
| 165 | 166 | ||
| 166 | // Update tracking. | 167 | // Update tracking. |
| 167 | cur_offset += actual_read_size; | 168 | cur_offset += actual_read_size; |
| 168 | cur_length -= actual_read_size; | 169 | cur_length -= actual_read_size; |
| 169 | it++; | 170 | it++; |
| 171 | |||
| 172 | // If we encountered a short read, we're done. | ||
| 173 | if (actual_read_size < intended_read_size) { | ||
| 174 | break; | ||
| 175 | } | ||
| 170 | } | 176 | } |
| 171 | 177 | ||
| 172 | return cur_offset - offset; | 178 | return cur_offset - offset; |
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 7a15d8438..b0515ec05 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "common/fs/fs.h" | 10 | #include "common/fs/fs.h" |
| 11 | #include "common/fs/path_util.h" | 11 | #include "common/fs/path_util.h" |
| 12 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 13 | #include "core/file_sys/vfs.h" | ||
| 13 | #include "core/file_sys/vfs_real.h" | 14 | #include "core/file_sys/vfs_real.h" |
| 14 | 15 | ||
| 15 | // For FileTimeStampRaw | 16 | // For FileTimeStampRaw |
| @@ -72,8 +73,10 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { | |||
| 72 | return VfsEntryType::File; | 73 | return VfsEntryType::File; |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | 76 | VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size, |
| 77 | Mode perms) { | ||
| 76 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); | 78 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); |
| 79 | std::scoped_lock lk{list_lock}; | ||
| 77 | 80 | ||
| 78 | if (auto it = cache.find(path); it != cache.end()) { | 81 | if (auto it = cache.find(path); it != cache.end()) { |
| 79 | if (auto file = it->second.lock(); file) { | 82 | if (auto file = it->second.lock(); file) { |
| @@ -81,23 +84,30 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | |||
| 81 | } | 84 | } |
| 82 | } | 85 | } |
| 83 | 86 | ||
| 84 | if (!FS::Exists(path) || !FS::IsFile(path)) { | 87 | if (!size && !FS::IsFile(path)) { |
| 85 | return nullptr; | 88 | return nullptr; |
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | auto reference = std::make_unique<FileReference>(); | 91 | auto reference = std::make_unique<FileReference>(); |
| 89 | this->InsertReferenceIntoList(*reference); | 92 | this->InsertReferenceIntoListLocked(*reference); |
| 90 | 93 | ||
| 91 | auto file = | 94 | auto file = std::shared_ptr<RealVfsFile>( |
| 92 | std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, std::move(reference), path, perms)); | 95 | new RealVfsFile(*this, std::move(reference), path, perms, size)); |
| 93 | cache[path] = file; | 96 | cache[path] = file; |
| 94 | 97 | ||
| 95 | return file; | 98 | return file; |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 101 | VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | ||
| 102 | return OpenFileFromEntry(path_, {}, perms); | ||
| 103 | } | ||
| 104 | |||
| 98 | VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { | 105 | VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { |
| 99 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); | 106 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); |
| 100 | cache.erase(path); | 107 | { |
| 108 | std::scoped_lock lk{list_lock}; | ||
| 109 | cache.erase(path); | ||
| 110 | } | ||
| 101 | 111 | ||
| 102 | // Current usages of CreateFile expect to delete the contents of an existing file. | 112 | // Current usages of CreateFile expect to delete the contents of an existing file. |
| 103 | if (FS::IsFile(path)) { | 113 | if (FS::IsFile(path)) { |
| @@ -127,8 +137,11 @@ VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_ | |||
| 127 | VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { | 137 | VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { |
| 128 | const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); | 138 | const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); |
| 129 | const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); | 139 | const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); |
| 130 | cache.erase(old_path); | 140 | { |
| 131 | cache.erase(new_path); | 141 | std::scoped_lock lk{list_lock}; |
| 142 | cache.erase(old_path); | ||
| 143 | cache.erase(new_path); | ||
| 144 | } | ||
| 132 | if (!FS::RenameFile(old_path, new_path)) { | 145 | if (!FS::RenameFile(old_path, new_path)) { |
| 133 | return nullptr; | 146 | return nullptr; |
| 134 | } | 147 | } |
| @@ -137,7 +150,10 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ | |||
| 137 | 150 | ||
| 138 | bool RealVfsFilesystem::DeleteFile(std::string_view path_) { | 151 | bool RealVfsFilesystem::DeleteFile(std::string_view path_) { |
| 139 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); | 152 | const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); |
| 140 | cache.erase(path); | 153 | { |
| 154 | std::scoped_lock lk{list_lock}; | ||
| 155 | cache.erase(path); | ||
| 156 | } | ||
| 141 | return FS::RemoveFile(path); | 157 | return FS::RemoveFile(path); |
| 142 | } | 158 | } |
| 143 | 159 | ||
| @@ -176,14 +192,17 @@ bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { | |||
| 176 | return FS::RemoveDirRecursively(path); | 192 | return FS::RemoveDirRecursively(path); |
| 177 | } | 193 | } |
| 178 | 194 | ||
| 179 | void RealVfsFilesystem::RefreshReference(const std::string& path, Mode perms, | 195 | std::unique_lock<std::mutex> RealVfsFilesystem::RefreshReference(const std::string& path, |
| 180 | FileReference& reference) { | 196 | Mode perms, |
| 197 | FileReference& reference) { | ||
| 198 | std::unique_lock lk{list_lock}; | ||
| 199 | |||
| 181 | // Temporarily remove from list. | 200 | // Temporarily remove from list. |
| 182 | this->RemoveReferenceFromList(reference); | 201 | this->RemoveReferenceFromListLocked(reference); |
| 183 | 202 | ||
| 184 | // Restore file if needed. | 203 | // Restore file if needed. |
| 185 | if (!reference.file) { | 204 | if (!reference.file) { |
| 186 | this->EvictSingleReference(); | 205 | this->EvictSingleReferenceLocked(); |
| 187 | 206 | ||
| 188 | reference.file = | 207 | reference.file = |
| 189 | FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile); | 208 | FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile); |
| @@ -193,12 +212,16 @@ void RealVfsFilesystem::RefreshReference(const std::string& path, Mode perms, | |||
| 193 | } | 212 | } |
| 194 | 213 | ||
| 195 | // Reinsert into list. | 214 | // Reinsert into list. |
| 196 | this->InsertReferenceIntoList(reference); | 215 | this->InsertReferenceIntoListLocked(reference); |
| 216 | |||
| 217 | return lk; | ||
| 197 | } | 218 | } |
| 198 | 219 | ||
| 199 | void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference) { | 220 | void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference) { |
| 221 | std::scoped_lock lk{list_lock}; | ||
| 222 | |||
| 200 | // Remove from list. | 223 | // Remove from list. |
| 201 | this->RemoveReferenceFromList(*reference); | 224 | this->RemoveReferenceFromListLocked(*reference); |
| 202 | 225 | ||
| 203 | // Close the file. | 226 | // Close the file. |
| 204 | if (reference->file) { | 227 | if (reference->file) { |
| @@ -207,14 +230,14 @@ void RealVfsFilesystem::DropReference(std::unique_ptr<FileReference>&& reference | |||
| 207 | } | 230 | } |
| 208 | } | 231 | } |
| 209 | 232 | ||
| 210 | void RealVfsFilesystem::EvictSingleReference() { | 233 | void RealVfsFilesystem::EvictSingleReferenceLocked() { |
| 211 | if (num_open_files < MaxOpenFiles || open_references.empty()) { | 234 | if (num_open_files < MaxOpenFiles || open_references.empty()) { |
| 212 | return; | 235 | return; |
| 213 | } | 236 | } |
| 214 | 237 | ||
| 215 | // Get and remove from list. | 238 | // Get and remove from list. |
| 216 | auto& reference = open_references.back(); | 239 | auto& reference = open_references.back(); |
| 217 | this->RemoveReferenceFromList(reference); | 240 | this->RemoveReferenceFromListLocked(reference); |
| 218 | 241 | ||
| 219 | // Close the file. | 242 | // Close the file. |
| 220 | if (reference.file) { | 243 | if (reference.file) { |
| @@ -223,10 +246,10 @@ void RealVfsFilesystem::EvictSingleReference() { | |||
| 223 | } | 246 | } |
| 224 | 247 | ||
| 225 | // Reinsert into closed list. | 248 | // Reinsert into closed list. |
| 226 | this->InsertReferenceIntoList(reference); | 249 | this->InsertReferenceIntoListLocked(reference); |
| 227 | } | 250 | } |
| 228 | 251 | ||
| 229 | void RealVfsFilesystem::InsertReferenceIntoList(FileReference& reference) { | 252 | void RealVfsFilesystem::InsertReferenceIntoListLocked(FileReference& reference) { |
| 230 | if (reference.file) { | 253 | if (reference.file) { |
| 231 | open_references.push_front(reference); | 254 | open_references.push_front(reference); |
| 232 | } else { | 255 | } else { |
| @@ -234,7 +257,7 @@ void RealVfsFilesystem::InsertReferenceIntoList(FileReference& reference) { | |||
| 234 | } | 257 | } |
| 235 | } | 258 | } |
| 236 | 259 | ||
| 237 | void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) { | 260 | void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference) { |
| 238 | if (reference.file) { | 261 | if (reference.file) { |
| 239 | open_references.erase(open_references.iterator_to(reference)); | 262 | open_references.erase(open_references.iterator_to(reference)); |
| 240 | } else { | 263 | } else { |
| @@ -243,10 +266,10 @@ void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) { | |||
| 243 | } | 266 | } |
| 244 | 267 | ||
| 245 | RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, | 268 | RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, |
| 246 | const std::string& path_, Mode perms_) | 269 | const std::string& path_, Mode perms_, std::optional<u64> size_) |
| 247 | : base(base_), reference(std::move(reference_)), path(path_), | 270 | : base(base_), reference(std::move(reference_)), path(path_), |
| 248 | parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)), | 271 | parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)), |
| 249 | perms(perms_) {} | 272 | size(size_), perms(perms_) {} |
| 250 | 273 | ||
| 251 | RealVfsFile::~RealVfsFile() { | 274 | RealVfsFile::~RealVfsFile() { |
| 252 | base.DropReference(std::move(reference)); | 275 | base.DropReference(std::move(reference)); |
| @@ -257,12 +280,15 @@ std::string RealVfsFile::GetName() const { | |||
| 257 | } | 280 | } |
| 258 | 281 | ||
| 259 | std::size_t RealVfsFile::GetSize() const { | 282 | std::size_t RealVfsFile::GetSize() const { |
| 260 | base.RefreshReference(path, perms, *reference); | 283 | if (size) { |
| 261 | return reference->file ? reference->file->GetSize() : 0; | 284 | return *size; |
| 285 | } | ||
| 286 | return FS::GetSize(path); | ||
| 262 | } | 287 | } |
| 263 | 288 | ||
| 264 | bool RealVfsFile::Resize(std::size_t new_size) { | 289 | bool RealVfsFile::Resize(std::size_t new_size) { |
| 265 | base.RefreshReference(path, perms, *reference); | 290 | size.reset(); |
| 291 | auto lk = base.RefreshReference(path, perms, *reference); | ||
| 266 | return reference->file ? reference->file->SetSize(new_size) : false; | 292 | return reference->file ? reference->file->SetSize(new_size) : false; |
| 267 | } | 293 | } |
| 268 | 294 | ||
| @@ -279,7 +305,7 @@ bool RealVfsFile::IsReadable() const { | |||
| 279 | } | 305 | } |
| 280 | 306 | ||
| 281 | std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { | 307 | std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { |
| 282 | base.RefreshReference(path, perms, *reference); | 308 | auto lk = base.RefreshReference(path, perms, *reference); |
| 283 | if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) { | 309 | if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) { |
| 284 | return 0; | 310 | return 0; |
| 285 | } | 311 | } |
| @@ -287,7 +313,8 @@ std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) | |||
| 287 | } | 313 | } |
| 288 | 314 | ||
| 289 | std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { | 315 | std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { |
| 290 | base.RefreshReference(path, perms, *reference); | 316 | size.reset(); |
| 317 | auto lk = base.RefreshReference(path, perms, *reference); | ||
| 291 | if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) { | 318 | if (!reference->file || !reference->file->Seek(static_cast<s64>(offset))) { |
| 292 | return 0; | 319 | return 0; |
| 293 | } | 320 | } |
| @@ -309,10 +336,11 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>( | |||
| 309 | 336 | ||
| 310 | std::vector<VirtualFile> out; | 337 | std::vector<VirtualFile> out; |
| 311 | 338 | ||
| 312 | const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { | 339 | const FS::DirEntryCallable callback = [this, |
| 313 | const auto full_path_string = FS::PathToUTF8String(full_path); | 340 | &out](const std::filesystem::directory_entry& entry) { |
| 341 | const auto full_path_string = FS::PathToUTF8String(entry.path()); | ||
| 314 | 342 | ||
| 315 | out.emplace_back(base.OpenFile(full_path_string, perms)); | 343 | out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms)); |
| 316 | 344 | ||
| 317 | return true; | 345 | return true; |
| 318 | }; | 346 | }; |
| @@ -330,8 +358,9 @@ std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDi | |||
| 330 | 358 | ||
| 331 | std::vector<VirtualDir> out; | 359 | std::vector<VirtualDir> out; |
| 332 | 360 | ||
| 333 | const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { | 361 | const FS::DirEntryCallable callback = [this, |
| 334 | const auto full_path_string = FS::PathToUTF8String(full_path); | 362 | &out](const std::filesystem::directory_entry& entry) { |
| 363 | const auto full_path_string = FS::PathToUTF8String(entry.path()); | ||
| 335 | 364 | ||
| 336 | out.emplace_back(base.OpenDirectory(full_path_string, perms)); | 365 | out.emplace_back(base.OpenDirectory(full_path_string, perms)); |
| 337 | 366 | ||
| @@ -483,12 +512,10 @@ std::map<std::string, VfsEntryType, std::less<>> RealVfsDirectory::GetEntries() | |||
| 483 | 512 | ||
| 484 | std::map<std::string, VfsEntryType, std::less<>> out; | 513 | std::map<std::string, VfsEntryType, std::less<>> out; |
| 485 | 514 | ||
| 486 | const FS::DirEntryCallable callback = [&out](const std::filesystem::path& full_path) { | 515 | const FS::DirEntryCallable callback = [&out](const std::filesystem::directory_entry& entry) { |
| 487 | const auto filename = FS::PathToUTF8String(full_path.filename()); | 516 | const auto filename = FS::PathToUTF8String(entry.path().filename()); |
| 488 | |||
| 489 | out.insert_or_assign(filename, | 517 | out.insert_or_assign(filename, |
| 490 | FS::IsDir(full_path) ? VfsEntryType::Directory : VfsEntryType::File); | 518 | entry.is_directory() ? VfsEntryType::Directory : VfsEntryType::File); |
| 491 | |||
| 492 | return true; | 519 | return true; |
| 493 | }; | 520 | }; |
| 494 | 521 | ||
diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index d8c900e33..26ea7df62 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <map> | 6 | #include <map> |
| 7 | #include <mutex> | ||
| 8 | #include <optional> | ||
| 7 | #include <string_view> | 9 | #include <string_view> |
| 8 | #include "common/intrusive_list.h" | 10 | #include "common/intrusive_list.h" |
| 9 | #include "core/file_sys/mode.h" | 11 | #include "core/file_sys/mode.h" |
| @@ -20,6 +22,8 @@ struct FileReference : public Common::IntrusiveListBaseNode<FileReference> { | |||
| 20 | }; | 22 | }; |
| 21 | 23 | ||
| 22 | class RealVfsFile; | 24 | class RealVfsFile; |
| 25 | class RealVfsDirectory; | ||
| 26 | |||
| 23 | class RealVfsFilesystem : public VfsFilesystem { | 27 | class RealVfsFilesystem : public VfsFilesystem { |
| 24 | public: | 28 | public: |
| 25 | RealVfsFilesystem(); | 29 | RealVfsFilesystem(); |
| @@ -45,17 +49,24 @@ private: | |||
| 45 | std::map<std::string, std::weak_ptr<VfsFile>, std::less<>> cache; | 49 | std::map<std::string, std::weak_ptr<VfsFile>, std::less<>> cache; |
| 46 | ReferenceListType open_references; | 50 | ReferenceListType open_references; |
| 47 | ReferenceListType closed_references; | 51 | ReferenceListType closed_references; |
| 52 | std::mutex list_lock; | ||
| 48 | size_t num_open_files{}; | 53 | size_t num_open_files{}; |
| 49 | 54 | ||
| 50 | private: | 55 | private: |
| 51 | friend class RealVfsFile; | 56 | friend class RealVfsFile; |
| 52 | void RefreshReference(const std::string& path, Mode perms, FileReference& reference); | 57 | std::unique_lock<std::mutex> RefreshReference(const std::string& path, Mode perms, |
| 58 | FileReference& reference); | ||
| 53 | void DropReference(std::unique_ptr<FileReference>&& reference); | 59 | void DropReference(std::unique_ptr<FileReference>&& reference); |
| 54 | void EvictSingleReference(); | ||
| 55 | 60 | ||
| 56 | private: | 61 | private: |
| 57 | void InsertReferenceIntoList(FileReference& reference); | 62 | friend class RealVfsDirectory; |
| 58 | void RemoveReferenceFromList(FileReference& reference); | 63 | VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size, |
| 64 | Mode perms = Mode::Read); | ||
| 65 | |||
| 66 | private: | ||
| 67 | void EvictSingleReferenceLocked(); | ||
| 68 | void InsertReferenceIntoListLocked(FileReference& reference); | ||
| 69 | void RemoveReferenceFromListLocked(FileReference& reference); | ||
| 59 | }; | 70 | }; |
| 60 | 71 | ||
| 61 | // An implementation of VfsFile that represents a file on the user's computer. | 72 | // An implementation of VfsFile that represents a file on the user's computer. |
| @@ -78,13 +89,14 @@ public: | |||
| 78 | 89 | ||
| 79 | private: | 90 | private: |
| 80 | RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference, | 91 | RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference, |
| 81 | const std::string& path, Mode perms = Mode::Read); | 92 | const std::string& path, Mode perms = Mode::Read, std::optional<u64> size = {}); |
| 82 | 93 | ||
| 83 | RealVfsFilesystem& base; | 94 | RealVfsFilesystem& base; |
| 84 | std::unique_ptr<FileReference> reference; | 95 | std::unique_ptr<FileReference> reference; |
| 85 | std::string path; | 96 | std::string path; |
| 86 | std::string parent_path; | 97 | std::string parent_path; |
| 87 | std::vector<std::string> path_components; | 98 | std::vector<std::string> path_components; |
| 99 | std::optional<u64> size; | ||
| 88 | Mode perms; | 100 | Mode perms; |
| 89 | }; | 101 | }; |
| 90 | 102 | ||
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 0a7777732..1ebc32c1e 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -149,12 +149,16 @@ void EmulatedController::LoadDevices() { | |||
| 149 | 149 | ||
| 150 | camera_params[0] = right_joycon; | 150 | camera_params[0] = right_joycon; |
| 151 | camera_params[0].Set("camera", true); | 151 | camera_params[0].Set("camera", true); |
| 152 | camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"}; | ||
| 153 | ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"}; | ||
| 154 | nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"}; | ||
| 155 | nfc_params[1] = right_joycon; | 152 | nfc_params[1] = right_joycon; |
| 156 | nfc_params[1].Set("nfc", true); | 153 | nfc_params[1].Set("nfc", true); |
| 157 | 154 | ||
| 155 | // Only map virtual devices to the first controller | ||
| 156 | if (npad_id_type == NpadIdType::Player1 || npad_id_type == NpadIdType::Handheld) { | ||
| 157 | camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"}; | ||
| 158 | ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"}; | ||
| 159 | nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"}; | ||
| 160 | } | ||
| 161 | |||
| 158 | output_params[LeftIndex] = left_joycon; | 162 | output_params[LeftIndex] = left_joycon; |
| 159 | output_params[RightIndex] = right_joycon; | 163 | output_params[RightIndex] = right_joycon; |
| 160 | output_params[2] = camera_params[1]; | 164 | output_params[2] = camera_params[1]; |
| @@ -1176,10 +1180,7 @@ void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { | |||
| 1176 | return; | 1180 | return; |
| 1177 | } | 1181 | } |
| 1178 | 1182 | ||
| 1179 | controller.nfc_state = { | 1183 | controller.nfc_state = controller.nfc_values; |
| 1180 | controller.nfc_values.state, | ||
| 1181 | controller.nfc_values.data, | ||
| 1182 | }; | ||
| 1183 | } | 1184 | } |
| 1184 | 1185 | ||
| 1185 | bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { | 1186 | bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { |
| @@ -1249,6 +1250,11 @@ Common::Input::DriverResult EmulatedController::SetPollingMode( | |||
| 1249 | const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode); | 1250 | const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode); |
| 1250 | const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode); | 1251 | const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode); |
| 1251 | 1252 | ||
| 1253 | // Restore previous state | ||
| 1254 | if (mapped_nfc_result != Common::Input::DriverResult::Success) { | ||
| 1255 | right_output_device->SetPollingMode(Common::Input::PollingMode::Active); | ||
| 1256 | } | ||
| 1257 | |||
| 1252 | if (virtual_nfc_result == Common::Input::DriverResult::Success) { | 1258 | if (virtual_nfc_result == Common::Input::DriverResult::Success) { |
| 1253 | return virtual_nfc_result; | 1259 | return virtual_nfc_result; |
| 1254 | } | 1260 | } |
| @@ -1308,6 +1314,79 @@ bool EmulatedController::HasNfc() const { | |||
| 1308 | return is_connected && (has_virtual_nfc && is_virtual_nfc_supported); | 1314 | return is_connected && (has_virtual_nfc && is_virtual_nfc_supported); |
| 1309 | } | 1315 | } |
| 1310 | 1316 | ||
| 1317 | bool EmulatedController::AddNfcHandle() { | ||
| 1318 | nfc_handles++; | ||
| 1319 | return SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::NFC) == | ||
| 1320 | Common::Input::DriverResult::Success; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | bool EmulatedController::RemoveNfcHandle() { | ||
| 1324 | nfc_handles--; | ||
| 1325 | if (nfc_handles <= 0) { | ||
| 1326 | return SetPollingMode(EmulatedDeviceIndex::RightIndex, | ||
| 1327 | Common::Input::PollingMode::Active) == | ||
| 1328 | Common::Input::DriverResult::Success; | ||
| 1329 | } | ||
| 1330 | return true; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | bool EmulatedController::StartNfcPolling() { | ||
| 1334 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; | ||
| 1335 | auto& nfc_virtual_output_device = output_devices[3]; | ||
| 1336 | |||
| 1337 | const auto device_result = nfc_output_device->StartNfcPolling(); | ||
| 1338 | const auto virtual_device_result = nfc_virtual_output_device->StartNfcPolling(); | ||
| 1339 | |||
| 1340 | return device_result == Common::Input::NfcState::Success || | ||
| 1341 | virtual_device_result == Common::Input::NfcState::Success; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | bool EmulatedController::StopNfcPolling() { | ||
| 1345 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; | ||
| 1346 | auto& nfc_virtual_output_device = output_devices[3]; | ||
| 1347 | |||
| 1348 | const auto device_result = nfc_output_device->StopNfcPolling(); | ||
| 1349 | const auto virtual_device_result = nfc_virtual_output_device->StopNfcPolling(); | ||
| 1350 | |||
| 1351 | return device_result == Common::Input::NfcState::Success || | ||
| 1352 | virtual_device_result == Common::Input::NfcState::Success; | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) { | ||
| 1356 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; | ||
| 1357 | auto& nfc_virtual_output_device = output_devices[3]; | ||
| 1358 | |||
| 1359 | if (nfc_output_device->ReadAmiiboData(data) == Common::Input::NfcState::Success) { | ||
| 1360 | return true; | ||
| 1361 | } | ||
| 1362 | |||
| 1363 | return nfc_virtual_output_device->ReadAmiiboData(data) == Common::Input::NfcState::Success; | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& request, | ||
| 1367 | Common::Input::MifareRequest& out_data) { | ||
| 1368 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; | ||
| 1369 | auto& nfc_virtual_output_device = output_devices[3]; | ||
| 1370 | |||
| 1371 | if (nfc_output_device->ReadMifareData(request, out_data) == Common::Input::NfcState::Success) { | ||
| 1372 | return true; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | return nfc_virtual_output_device->ReadMifareData(request, out_data) == | ||
| 1376 | Common::Input::NfcState::Success; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& request) { | ||
| 1380 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; | ||
| 1381 | auto& nfc_virtual_output_device = output_devices[3]; | ||
| 1382 | |||
| 1383 | if (nfc_output_device->WriteMifareData(request) == Common::Input::NfcState::Success) { | ||
| 1384 | return true; | ||
| 1385 | } | ||
| 1386 | |||
| 1387 | return nfc_virtual_output_device->WriteMifareData(request) == Common::Input::NfcState::Success; | ||
| 1388 | } | ||
| 1389 | |||
| 1311 | bool EmulatedController::WriteNfc(const std::vector<u8>& data) { | 1390 | bool EmulatedController::WriteNfc(const std::vector<u8>& data) { |
| 1312 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; | 1391 | auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; |
| 1313 | auto& nfc_virtual_output_device = output_devices[3]; | 1392 | auto& nfc_virtual_output_device = output_devices[3]; |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 09fe1a0ab..d511e5fac 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -97,10 +97,7 @@ struct RingSensorForce { | |||
| 97 | f32 force; | 97 | f32 force; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | struct NfcState { | 100 | using NfcState = Common::Input::NfcStatus; |
| 101 | Common::Input::NfcState state{}; | ||
| 102 | std::vector<u8> data{}; | ||
| 103 | }; | ||
| 104 | 101 | ||
| 105 | struct ControllerMotion { | 102 | struct ControllerMotion { |
| 106 | Common::Vec3f accel{}; | 103 | Common::Vec3f accel{}; |
| @@ -393,9 +390,31 @@ public: | |||
| 393 | /// Returns true if the device has nfc support | 390 | /// Returns true if the device has nfc support |
| 394 | bool HasNfc() const; | 391 | bool HasNfc() const; |
| 395 | 392 | ||
| 393 | /// Sets the joycon in nfc mode and increments the handle count | ||
| 394 | bool AddNfcHandle(); | ||
| 395 | |||
| 396 | /// Decrements the handle count if zero sets the joycon in active mode | ||
| 397 | bool RemoveNfcHandle(); | ||
| 398 | |||
| 399 | /// Start searching for nfc tags | ||
| 400 | bool StartNfcPolling(); | ||
| 401 | |||
| 402 | /// Stop searching for nfc tags | ||
| 403 | bool StopNfcPolling(); | ||
| 404 | |||
| 405 | /// Returns true if the nfc tag was readable | ||
| 406 | bool ReadAmiiboData(std::vector<u8>& data); | ||
| 407 | |||
| 396 | /// Returns true if the nfc tag was written | 408 | /// Returns true if the nfc tag was written |
| 397 | bool WriteNfc(const std::vector<u8>& data); | 409 | bool WriteNfc(const std::vector<u8>& data); |
| 398 | 410 | ||
| 411 | /// Returns true if the nfc tag was readable | ||
| 412 | bool ReadMifareData(const Common::Input::MifareRequest& request, | ||
| 413 | Common::Input::MifareRequest& out_data); | ||
| 414 | |||
| 415 | /// Returns true if the nfc tag was written | ||
| 416 | bool WriteMifareData(const Common::Input::MifareRequest& request); | ||
| 417 | |||
| 399 | /// Returns the led pattern corresponding to this emulated controller | 418 | /// Returns the led pattern corresponding to this emulated controller |
| 400 | LedPattern GetLedPattern() const; | 419 | LedPattern GetLedPattern() const; |
| 401 | 420 | ||
| @@ -532,6 +551,7 @@ private: | |||
| 532 | bool system_buttons_enabled{true}; | 551 | bool system_buttons_enabled{true}; |
| 533 | f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; | 552 | f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; |
| 534 | u32 turbo_button_state{0}; | 553 | u32 turbo_button_state{0}; |
| 554 | std::size_t nfc_handles{0}; | ||
| 535 | 555 | ||
| 536 | // Temporary values to avoid doing changes while the controller is in configuring mode | 556 | // Temporary values to avoid doing changes while the controller is in configuring mode |
| 537 | NpadStyleIndex tmp_npad_type{NpadStyleIndex::None}; | 557 | NpadStyleIndex tmp_npad_type{NpadStyleIndex::None}; |
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index 4ccb1c596..a05716fd8 100644 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp | |||
| @@ -299,11 +299,7 @@ Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& cal | |||
| 299 | Common::Input::NfcStatus nfc{}; | 299 | Common::Input::NfcStatus nfc{}; |
| 300 | switch (callback.type) { | 300 | switch (callback.type) { |
| 301 | case Common::Input::InputType::Nfc: | 301 | case Common::Input::InputType::Nfc: |
| 302 | nfc = { | 302 | return callback.nfc_status; |
| 303 | .state = callback.nfc_status, | ||
| 304 | .data = callback.raw_data, | ||
| 305 | }; | ||
| 306 | break; | ||
| 307 | default: | 303 | default: |
| 308 | LOG_ERROR(Input, "Conversion from type {} to NFC not implemented", callback.type); | 304 | LOG_ERROR(Input, "Conversion from type {} to NFC not implemented", callback.type); |
| 309 | break; | 305 | break; |
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index faa12b4f0..75ce5a23c 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -184,7 +184,8 @@ u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) { | |||
| 184 | prev_highest_thread != highest_thread) [[likely]] { | 184 | prev_highest_thread != highest_thread) [[likely]] { |
| 185 | if (prev_highest_thread != nullptr) [[likely]] { | 185 | if (prev_highest_thread != nullptr) [[likely]] { |
| 186 | IncrementScheduledCount(prev_highest_thread); | 186 | IncrementScheduledCount(prev_highest_thread); |
| 187 | prev_highest_thread->SetLastScheduledTick(m_kernel.System().CoreTiming().GetCPUTicks()); | 187 | prev_highest_thread->SetLastScheduledTick( |
| 188 | m_kernel.System().CoreTiming().GetClockTicks()); | ||
| 188 | } | 189 | } |
| 189 | if (m_state.should_count_idle) { | 190 | if (m_state.should_count_idle) { |
| 190 | if (highest_thread != nullptr) [[likely]] { | 191 | if (highest_thread != nullptr) [[likely]] { |
| @@ -351,7 +352,7 @@ void KScheduler::SwitchThread(KThread* next_thread) { | |||
| 351 | 352 | ||
| 352 | // Update the CPU time tracking variables. | 353 | // Update the CPU time tracking variables. |
| 353 | const s64 prev_tick = m_last_context_switch_time; | 354 | const s64 prev_tick = m_last_context_switch_time; |
| 354 | const s64 cur_tick = m_kernel.System().CoreTiming().GetCPUTicks(); | 355 | const s64 cur_tick = m_kernel.System().CoreTiming().GetClockTicks(); |
| 355 | const s64 tick_diff = cur_tick - prev_tick; | 356 | const s64 tick_diff = cur_tick - prev_tick; |
| 356 | cur_thread->AddCpuTime(m_core_id, tick_diff); | 357 | cur_thread->AddCpuTime(m_core_id, tick_diff); |
| 357 | if (cur_process != nullptr) { | 358 | if (cur_process != nullptr) { |
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index b7da3eee7..3e5b735b1 100644 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include "common/assert.h" | 4 | #include "common/assert.h" |
| 5 | #include "common/common_types.h" | 5 | #include "common/common_types.h" |
| 6 | #include "common/scratch_buffer.h" | ||
| 6 | #include "core/hle/kernel/k_scheduler.h" | 7 | #include "core/hle/kernel/k_scheduler.h" |
| 7 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 8 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 8 | #include "core/hle/kernel/k_synchronization_object.h" | 9 | #include "core/hle/kernel/k_synchronization_object.h" |
| @@ -75,7 +76,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, | |||
| 75 | KSynchronizationObject** objects, const s32 num_objects, | 76 | KSynchronizationObject** objects, const s32 num_objects, |
| 76 | s64 timeout) { | 77 | s64 timeout) { |
| 77 | // Allocate space on stack for thread nodes. | 78 | // Allocate space on stack for thread nodes. |
| 78 | std::vector<ThreadListNode> thread_nodes(num_objects); | 79 | std::array<ThreadListNode, Svc::ArgumentHandleCountMax> thread_nodes; |
| 79 | 80 | ||
| 80 | // Prepare for wait. | 81 | // Prepare for wait. |
| 81 | KThread* thread = GetCurrentThreadPointer(kernel); | 82 | KThread* thread = GetCurrentThreadPointer(kernel); |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 908811e2c..adb6ec581 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -909,7 +909,7 @@ Result KThread::SetActivity(Svc::ThreadActivity activity) { | |||
| 909 | R_SUCCEED(); | 909 | R_SUCCEED(); |
| 910 | } | 910 | } |
| 911 | 911 | ||
| 912 | Result KThread::GetThreadContext3(std::vector<u8>& out) { | 912 | Result KThread::GetThreadContext3(Common::ScratchBuffer<u8>& out) { |
| 913 | // Lock ourselves. | 913 | // Lock ourselves. |
| 914 | KScopedLightLock lk{m_activity_pause_lock}; | 914 | KScopedLightLock lk{m_activity_pause_lock}; |
| 915 | 915 | ||
| @@ -927,15 +927,13 @@ Result KThread::GetThreadContext3(std::vector<u8>& out) { | |||
| 927 | // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. | 927 | // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. |
| 928 | auto context = GetContext64(); | 928 | auto context = GetContext64(); |
| 929 | context.pstate &= 0xFF0FFE20; | 929 | context.pstate &= 0xFF0FFE20; |
| 930 | 930 | out.resize_destructive(sizeof(context)); | |
| 931 | out.resize(sizeof(context)); | ||
| 932 | std::memcpy(out.data(), std::addressof(context), sizeof(context)); | 931 | std::memcpy(out.data(), std::addressof(context), sizeof(context)); |
| 933 | } else { | 932 | } else { |
| 934 | // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. | 933 | // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. |
| 935 | auto context = GetContext32(); | 934 | auto context = GetContext32(); |
| 936 | context.cpsr &= 0xFF0FFE20; | 935 | context.cpsr &= 0xFF0FFE20; |
| 937 | 936 | out.resize_destructive(sizeof(context)); | |
| 938 | out.resize(sizeof(context)); | ||
| 939 | std::memcpy(out.data(), std::addressof(context), sizeof(context)); | 937 | std::memcpy(out.data(), std::addressof(context), sizeof(context)); |
| 940 | } | 938 | } |
| 941 | } | 939 | } |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 37fe5db77..dd662b3f8 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "common/intrusive_list.h" | 15 | #include "common/intrusive_list.h" |
| 16 | 16 | ||
| 17 | #include "common/intrusive_red_black_tree.h" | 17 | #include "common/intrusive_red_black_tree.h" |
| 18 | #include "common/scratch_buffer.h" | ||
| 18 | #include "common/spin_lock.h" | 19 | #include "common/spin_lock.h" |
| 19 | #include "core/arm/arm_interface.h" | 20 | #include "core/arm/arm_interface.h" |
| 20 | #include "core/hle/kernel/k_affinity_mask.h" | 21 | #include "core/hle/kernel/k_affinity_mask.h" |
| @@ -567,7 +568,7 @@ public: | |||
| 567 | 568 | ||
| 568 | void RemoveWaiter(KThread* thread); | 569 | void RemoveWaiter(KThread* thread); |
| 569 | 570 | ||
| 570 | Result GetThreadContext3(std::vector<u8>& out); | 571 | Result GetThreadContext3(Common::ScratchBuffer<u8>& out); |
| 571 | 572 | ||
| 572 | KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) { | 573 | KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) { |
| 573 | return this->RemoveWaiterByKey(out_has_waiters, key, false); | 574 | return this->RemoveWaiterByKey(out_has_waiters, key, false); |
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index 2b2c878b5..445cdd87b 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp | |||
| @@ -199,9 +199,9 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle | |||
| 199 | if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) { | 199 | if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) { |
| 200 | const u64 thread_ticks = current_thread->GetCpuTime(); | 200 | const u64 thread_ticks = current_thread->GetCpuTime(); |
| 201 | 201 | ||
| 202 | out_ticks = thread_ticks + (core_timing.GetCPUTicks() - prev_ctx_ticks); | 202 | out_ticks = thread_ticks + (core_timing.GetClockTicks() - prev_ctx_ticks); |
| 203 | } else if (same_thread && info_sub_id == system.Kernel().CurrentPhysicalCoreIndex()) { | 203 | } else if (same_thread && info_sub_id == system.Kernel().CurrentPhysicalCoreIndex()) { |
| 204 | out_ticks = core_timing.GetCPUTicks() - prev_ctx_ticks; | 204 | out_ticks = core_timing.GetClockTicks() - prev_ctx_ticks; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | *result = out_ticks; | 207 | *result = out_ticks; |
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index ea03068aa..60247df2e 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/scope_exit.h" | 4 | #include "common/scope_exit.h" |
| 5 | #include "common/scratch_buffer.h" | ||
| 5 | #include "core/core.h" | 6 | #include "core/core.h" |
| 6 | #include "core/hle/kernel/k_client_session.h" | 7 | #include "core/hle/kernel/k_client_session.h" |
| 7 | #include "core/hle/kernel/k_process.h" | 8 | #include "core/hle/kernel/k_process.h" |
| @@ -45,11 +46,11 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad | |||
| 45 | handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), | 46 | handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), |
| 46 | ResultInvalidPointer); | 47 | ResultInvalidPointer); |
| 47 | 48 | ||
| 48 | std::vector<Handle> handles(num_handles); | 49 | std::array<Handle, Svc::ArgumentHandleCountMax> handles; |
| 49 | GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); | 50 | GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); |
| 50 | 51 | ||
| 51 | // Convert handle list to object table. | 52 | // Convert handle list to object table. |
| 52 | std::vector<KSynchronizationObject*> objs(num_handles); | 53 | std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs; |
| 53 | R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), | 54 | R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), |
| 54 | num_handles), | 55 | num_handles), |
| 55 | ResultInvalidHandle); | 56 | ResultInvalidHandle); |
| @@ -80,7 +81,7 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad | |||
| 80 | // Wait for an object. | 81 | // Wait for an object. |
| 81 | s32 index; | 82 | s32 index; |
| 82 | Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), | 83 | Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), |
| 83 | static_cast<s32>(objs.size()), timeout_ns); | 84 | num_handles, timeout_ns); |
| 84 | if (result == ResultTimedOut) { | 85 | if (result == ResultTimedOut) { |
| 85 | R_RETURN(result); | 86 | R_RETURN(result); |
| 86 | } | 87 | } |
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 04d65f0bd..53df5bcd8 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/scope_exit.h" | 4 | #include "common/scope_exit.h" |
| 5 | #include "common/scratch_buffer.h" | ||
| 5 | #include "core/core.h" | 6 | #include "core/core.h" |
| 6 | #include "core/hle/kernel/k_process.h" | 7 | #include "core/hle/kernel/k_process.h" |
| 7 | #include "core/hle/kernel/k_readable_event.h" | 8 | #include "core/hle/kernel/k_readable_event.h" |
| @@ -54,7 +55,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons | |||
| 54 | // Get the synchronization context. | 55 | // Get the synchronization context. |
| 55 | auto& kernel = system.Kernel(); | 56 | auto& kernel = system.Kernel(); |
| 56 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); | 57 | auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); |
| 57 | std::vector<KSynchronizationObject*> objs(num_handles); | 58 | std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs; |
| 58 | 59 | ||
| 59 | // Copy user handles. | 60 | // Copy user handles. |
| 60 | if (num_handles > 0) { | 61 | if (num_handles > 0) { |
| @@ -72,8 +73,8 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons | |||
| 72 | }); | 73 | }); |
| 73 | 74 | ||
| 74 | // Wait on the objects. | 75 | // Wait on the objects. |
| 75 | Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), | 76 | Result res = |
| 76 | static_cast<s32>(objs.size()), timeout_ns); | 77 | KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns); |
| 77 | 78 | ||
| 78 | R_SUCCEED_IF(res == ResultSessionClosed); | 79 | R_SUCCEED_IF(res == ResultSessionClosed); |
| 79 | R_RETURN(res); | 80 | R_RETURN(res); |
| @@ -87,8 +88,7 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha | |||
| 87 | 88 | ||
| 88 | // Ensure number of handles is valid. | 89 | // Ensure number of handles is valid. |
| 89 | R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); | 90 | R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); |
| 90 | 91 | std::array<Handle, Svc::ArgumentHandleCountMax> handles; | |
| 91 | std::vector<Handle> handles(num_handles); | ||
| 92 | if (num_handles > 0) { | 92 | if (num_handles > 0) { |
| 93 | GetCurrentMemory(system.Kernel()) | 93 | GetCurrentMemory(system.Kernel()) |
| 94 | .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); | 94 | .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); |
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 37b54079c..36b94e6bf 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp | |||
| @@ -174,7 +174,7 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha | |||
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | // Get the thread context. | 176 | // Get the thread context. |
| 177 | std::vector<u8> context; | 177 | static thread_local Common::ScratchBuffer<u8> context; |
| 178 | R_TRY(thread->GetThreadContext3(context)); | 178 | R_TRY(thread->GetThreadContext3(context)); |
| 179 | 179 | ||
| 180 | // Copy the thread context to user space. | 180 | // Copy the thread context to user space. |
diff --git a/src/core/hle/kernel/svc/svc_tick.cpp b/src/core/hle/kernel/svc/svc_tick.cpp index 561336482..7dd7c6e51 100644 --- a/src/core/hle/kernel/svc/svc_tick.cpp +++ b/src/core/hle/kernel/svc/svc_tick.cpp | |||
| @@ -12,16 +12,8 @@ namespace Kernel::Svc { | |||
| 12 | int64_t GetSystemTick(Core::System& system) { | 12 | int64_t GetSystemTick(Core::System& system) { |
| 13 | LOG_TRACE(Kernel_SVC, "called"); | 13 | LOG_TRACE(Kernel_SVC, "called"); |
| 14 | 14 | ||
| 15 | auto& core_timing = system.CoreTiming(); | ||
| 16 | |||
| 17 | // Returns the value of cntpct_el0 (https://switchbrew.org/wiki/SVC#svcGetSystemTick) | 15 | // Returns the value of cntpct_el0 (https://switchbrew.org/wiki/SVC#svcGetSystemTick) |
| 18 | const u64 result{core_timing.GetClockTicks()}; | 16 | return static_cast<int64_t>(system.CoreTiming().GetClockTicks()); |
| 19 | |||
| 20 | if (!system.Kernel().IsMulticore()) { | ||
| 21 | core_timing.AddTicks(400U); | ||
| 22 | } | ||
| 23 | |||
| 24 | return static_cast<int64_t>(result); | ||
| 25 | } | 17 | } |
| 26 | 18 | ||
| 27 | int64_t GetSystemTick64(Core::System& system) { | 19 | int64_t GetSystemTick64(Core::System& system) { |
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 8b754e9d4..19ed184e8 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp | |||
| @@ -141,7 +141,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) | |||
| 141 | applet_output.device_handle = applet_input_common.device_handle; | 141 | applet_output.device_handle = applet_input_common.device_handle; |
| 142 | applet_output.result = CabinetResult::Cancel; | 142 | applet_output.result = CabinetResult::Cancel; |
| 143 | const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info); | 143 | const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info); |
| 144 | const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info, false); | 144 | const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); |
| 145 | nfp_device->Finalize(); | 145 | nfp_device->Finalize(); |
| 146 | 146 | ||
| 147 | if (reg_result.IsSuccess()) { | 147 | if (reg_result.IsSuccess()) { |
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index f0640c64f..c8d574993 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "audio_core/renderer/audio_device.h" | 5 | #include "audio_core/renderer/audio_device.h" |
| 6 | #include "common/common_funcs.h" | 6 | #include "common/common_funcs.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "common/settings.h" | ||
| 8 | #include "common/string_util.h" | 9 | #include "common/string_util.h" |
| 9 | #include "core/core.h" | 10 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/k_event.h" | 11 | #include "core/hle/kernel/k_event.h" |
| @@ -123,19 +124,13 @@ private: | |||
| 123 | 124 | ||
| 124 | void GetReleasedAudioInBuffer(HLERequestContext& ctx) { | 125 | void GetReleasedAudioInBuffer(HLERequestContext& ctx) { |
| 125 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); | 126 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); |
| 126 | std::vector<u64> released_buffers(write_buffer_size); | 127 | tmp_buffer.resize_destructive(write_buffer_size); |
| 128 | tmp_buffer[0] = 0; | ||
| 127 | 129 | ||
| 128 | const auto count = impl->GetReleasedBuffers(released_buffers); | 130 | const auto count = impl->GetReleasedBuffers(tmp_buffer); |
| 129 | 131 | ||
| 130 | [[maybe_unused]] std::string tags{}; | 132 | ctx.WriteBuffer(tmp_buffer); |
| 131 | for (u32 i = 0; i < count; i++) { | ||
| 132 | tags += fmt::format("{:08X}, ", released_buffers[i]); | ||
| 133 | } | ||
| 134 | [[maybe_unused]] auto sessionid{impl->GetSystem().GetSessionId()}; | ||
| 135 | LOG_TRACE(Service_Audio, "called. Session {} released {} buffers: {}", sessionid, count, | ||
| 136 | tags); | ||
| 137 | 133 | ||
| 138 | ctx.WriteBuffer(released_buffers); | ||
| 139 | IPC::ResponseBuilder rb{ctx, 3}; | 134 | IPC::ResponseBuilder rb{ctx, 3}; |
| 140 | rb.Push(ResultSuccess); | 135 | rb.Push(ResultSuccess); |
| 141 | rb.Push(count); | 136 | rb.Push(count); |
| @@ -200,6 +195,7 @@ private: | |||
| 200 | KernelHelpers::ServiceContext service_context; | 195 | KernelHelpers::ServiceContext service_context; |
| 201 | Kernel::KEvent* event; | 196 | Kernel::KEvent* event; |
| 202 | std::shared_ptr<AudioCore::AudioIn::In> impl; | 197 | std::shared_ptr<AudioCore::AudioIn::In> impl; |
| 198 | Common::ScratchBuffer<u64> tmp_buffer; | ||
| 203 | }; | 199 | }; |
| 204 | 200 | ||
| 205 | AudInU::AudInU(Core::System& system_) | 201 | AudInU::AudInU(Core::System& system_) |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 3e62fa4fc..032c8c11f 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -123,19 +123,13 @@ private: | |||
| 123 | 123 | ||
| 124 | void GetReleasedAudioOutBuffers(HLERequestContext& ctx) { | 124 | void GetReleasedAudioOutBuffers(HLERequestContext& ctx) { |
| 125 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); | 125 | const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); |
| 126 | std::vector<u64> released_buffers(write_buffer_size); | 126 | tmp_buffer.resize_destructive(write_buffer_size); |
| 127 | tmp_buffer[0] = 0; | ||
| 127 | 128 | ||
| 128 | const auto count = impl->GetReleasedBuffers(released_buffers); | 129 | const auto count = impl->GetReleasedBuffers(tmp_buffer); |
| 129 | 130 | ||
| 130 | [[maybe_unused]] std::string tags{}; | 131 | ctx.WriteBuffer(tmp_buffer); |
| 131 | for (u32 i = 0; i < count; i++) { | ||
| 132 | tags += fmt::format("{:08X}, ", released_buffers[i]); | ||
| 133 | } | ||
| 134 | [[maybe_unused]] const auto sessionid{impl->GetSystem().GetSessionId()}; | ||
| 135 | LOG_TRACE(Service_Audio, "called. Session {} released {} buffers: {}", sessionid, count, | ||
| 136 | tags); | ||
| 137 | 132 | ||
| 138 | ctx.WriteBuffer(released_buffers); | ||
| 139 | IPC::ResponseBuilder rb{ctx, 3}; | 133 | IPC::ResponseBuilder rb{ctx, 3}; |
| 140 | rb.Push(ResultSuccess); | 134 | rb.Push(ResultSuccess); |
| 141 | rb.Push(count); | 135 | rb.Push(count); |
| @@ -211,6 +205,7 @@ private: | |||
| 211 | KernelHelpers::ServiceContext service_context; | 205 | KernelHelpers::ServiceContext service_context; |
| 212 | Kernel::KEvent* event; | 206 | Kernel::KEvent* event; |
| 213 | std::shared_ptr<AudioCore::AudioOut::Out> impl; | 207 | std::shared_ptr<AudioCore::AudioOut::Out> impl; |
| 208 | Common::ScratchBuffer<u64> tmp_buffer; | ||
| 214 | }; | 209 | }; |
| 215 | 210 | ||
| 216 | AudOutU::AudOutU(Core::System& system_) | 211 | AudOutU::AudOutU(Core::System& system_) |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 7086d4750..12845c23a 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -116,28 +116,26 @@ private: | |||
| 116 | // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for | 116 | // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for |
| 117 | // checking size 0. Performance size is 0 for most games. | 117 | // checking size 0. Performance size is 0 for most games. |
| 118 | 118 | ||
| 119 | std::vector<u8> output{}; | ||
| 120 | std::vector<u8> performance{}; | ||
| 121 | auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; | 119 | auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; |
| 122 | if (is_buffer_b) { | 120 | if (is_buffer_b) { |
| 123 | const auto buffersB{ctx.BufferDescriptorB()}; | 121 | const auto buffersB{ctx.BufferDescriptorB()}; |
| 124 | output.resize(buffersB[0].Size(), 0); | 122 | tmp_output.resize_destructive(buffersB[0].Size()); |
| 125 | performance.resize(buffersB[1].Size(), 0); | 123 | tmp_performance.resize_destructive(buffersB[1].Size()); |
| 126 | } else { | 124 | } else { |
| 127 | const auto buffersC{ctx.BufferDescriptorC()}; | 125 | const auto buffersC{ctx.BufferDescriptorC()}; |
| 128 | output.resize(buffersC[0].Size(), 0); | 126 | tmp_output.resize_destructive(buffersC[0].Size()); |
| 129 | performance.resize(buffersC[1].Size(), 0); | 127 | tmp_performance.resize_destructive(buffersC[1].Size()); |
| 130 | } | 128 | } |
| 131 | 129 | ||
| 132 | auto result = impl->RequestUpdate(input, performance, output); | 130 | auto result = impl->RequestUpdate(input, tmp_performance, tmp_output); |
| 133 | 131 | ||
| 134 | if (result.IsSuccess()) { | 132 | if (result.IsSuccess()) { |
| 135 | if (is_buffer_b) { | 133 | if (is_buffer_b) { |
| 136 | ctx.WriteBufferB(output.data(), output.size(), 0); | 134 | ctx.WriteBufferB(tmp_output.data(), tmp_output.size(), 0); |
| 137 | ctx.WriteBufferB(performance.data(), performance.size(), 1); | 135 | ctx.WriteBufferB(tmp_performance.data(), tmp_performance.size(), 1); |
| 138 | } else { | 136 | } else { |
| 139 | ctx.WriteBufferC(output.data(), output.size(), 0); | 137 | ctx.WriteBufferC(tmp_output.data(), tmp_output.size(), 0); |
| 140 | ctx.WriteBufferC(performance.data(), performance.size(), 1); | 138 | ctx.WriteBufferC(tmp_performance.data(), tmp_performance.size(), 1); |
| 141 | } | 139 | } |
| 142 | } else { | 140 | } else { |
| 143 | LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.description); | 141 | LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.description); |
| @@ -235,6 +233,8 @@ private: | |||
| 235 | Kernel::KEvent* rendered_event; | 233 | Kernel::KEvent* rendered_event; |
| 236 | Manager& manager; | 234 | Manager& manager; |
| 237 | std::unique_ptr<Renderer> impl; | 235 | std::unique_ptr<Renderer> impl; |
| 236 | Common::ScratchBuffer<u8> tmp_output; | ||
| 237 | Common::ScratchBuffer<u8> tmp_performance; | ||
| 238 | }; | 238 | }; |
| 239 | 239 | ||
| 240 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { | 240 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { |
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index 24ce37e87..d8e9c8719 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "audio_core/audio_render_manager.h" | 6 | #include "audio_core/audio_render_manager.h" |
| 7 | #include "common/scratch_buffer.h" | ||
| 7 | #include "core/hle/service/kernel_helpers.h" | 8 | #include "core/hle/service/kernel_helpers.h" |
| 8 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 9 | 10 | ||
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 451ac224a..c835f6cb7 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp | |||
| @@ -68,13 +68,13 @@ private: | |||
| 68 | ExtraBehavior extra_behavior) { | 68 | ExtraBehavior extra_behavior) { |
| 69 | u32 consumed = 0; | 69 | u32 consumed = 0; |
| 70 | u32 sample_count = 0; | 70 | u32 sample_count = 0; |
| 71 | std::vector<opus_int16> samples(ctx.GetWriteBufferNumElements<opus_int16>()); | 71 | tmp_samples.resize_destructive(ctx.GetWriteBufferNumElements<opus_int16>()); |
| 72 | 72 | ||
| 73 | if (extra_behavior == ExtraBehavior::ResetContext) { | 73 | if (extra_behavior == ExtraBehavior::ResetContext) { |
| 74 | ResetDecoderContext(); | 74 | ResetDecoderContext(); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), samples, performance)) { | 77 | if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), tmp_samples, performance)) { |
| 78 | LOG_ERROR(Audio, "Failed to decode opus data"); | 78 | LOG_ERROR(Audio, "Failed to decode opus data"); |
| 79 | IPC::ResponseBuilder rb{ctx, 2}; | 79 | IPC::ResponseBuilder rb{ctx, 2}; |
| 80 | // TODO(ogniK): Use correct error code | 80 | // TODO(ogniK): Use correct error code |
| @@ -90,11 +90,11 @@ private: | |||
| 90 | if (performance) { | 90 | if (performance) { |
| 91 | rb.Push<u64>(*performance); | 91 | rb.Push<u64>(*performance); |
| 92 | } | 92 | } |
| 93 | ctx.WriteBuffer(samples); | 93 | ctx.WriteBuffer(tmp_samples); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input, | 96 | bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input, |
| 97 | std::vector<opus_int16>& output, u64* out_performance_time) const { | 97 | std::span<opus_int16> output, u64* out_performance_time) const { |
| 98 | const auto start_time = std::chrono::steady_clock::now(); | 98 | const auto start_time = std::chrono::steady_clock::now(); |
| 99 | const std::size_t raw_output_sz = output.size() * sizeof(opus_int16); | 99 | const std::size_t raw_output_sz = output.size() * sizeof(opus_int16); |
| 100 | if (sizeof(OpusPacketHeader) > input.size()) { | 100 | if (sizeof(OpusPacketHeader) > input.size()) { |
| @@ -154,6 +154,7 @@ private: | |||
| 154 | OpusDecoderPtr decoder; | 154 | OpusDecoderPtr decoder; |
| 155 | u32 sample_rate; | 155 | u32 sample_rate; |
| 156 | u32 channel_count; | 156 | u32 channel_count; |
| 157 | Common::ScratchBuffer<opus_int16> tmp_samples; | ||
| 157 | }; | 158 | }; |
| 158 | 159 | ||
| 159 | class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { | 160 | class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { |
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp index 5604a6fda..80aac221b 100644 --- a/src/core/hle/service/hid/hidbus.cpp +++ b/src/core/hle/service/hid/hidbus.cpp | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #include "common/settings.h" | 5 | #include "common/settings.h" |
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/core_timing_util.h" | ||
| 9 | #include "core/hid/hid_types.h" | 8 | #include "core/hid/hid_types.h" |
| 10 | #include "core/hle/kernel/k_event.h" | 9 | #include "core/hle/kernel/k_event.h" |
| 11 | #include "core/hle/kernel/k_readable_event.h" | 10 | #include "core/hle/kernel/k_readable_event.h" |
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index f4b180b06..5bf289818 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp | |||
| @@ -93,7 +93,8 @@ void NfcDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { | |||
| 93 | const auto nfc_status = npad_device->GetNfc(); | 93 | const auto nfc_status = npad_device->GetNfc(); |
| 94 | switch (nfc_status.state) { | 94 | switch (nfc_status.state) { |
| 95 | case Common::Input::NfcState::NewAmiibo: | 95 | case Common::Input::NfcState::NewAmiibo: |
| 96 | LoadNfcTag(nfc_status.data); | 96 | LoadNfcTag(nfc_status.protocol, nfc_status.tag_type, nfc_status.uuid_length, |
| 97 | nfc_status.uuid); | ||
| 97 | break; | 98 | break; |
| 98 | case Common::Input::NfcState::AmiiboRemoved: | 99 | case Common::Input::NfcState::AmiiboRemoved: |
| 99 | if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) { | 100 | if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) { |
| @@ -108,28 +109,46 @@ void NfcDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { | |||
| 108 | } | 109 | } |
| 109 | } | 110 | } |
| 110 | 111 | ||
| 111 | bool NfcDevice::LoadNfcTag(std::span<const u8> data) { | 112 | bool NfcDevice::LoadNfcTag(u8 protocol, u8 tag_type, u8 uuid_length, UniqueSerialNumber uuid) { |
| 112 | if (device_state != DeviceState::SearchingForTag) { | 113 | if (device_state != DeviceState::SearchingForTag) { |
| 113 | LOG_ERROR(Service_NFC, "Game is not looking for nfc tag, current state {}", device_state); | 114 | LOG_ERROR(Service_NFC, "Game is not looking for nfc tag, current state {}", device_state); |
| 114 | return false; | 115 | return false; |
| 115 | } | 116 | } |
| 116 | 117 | ||
| 118 | if ((protocol & static_cast<u8>(allowed_protocols)) == 0) { | ||
| 119 | LOG_ERROR(Service_NFC, "Protocol not supported {}", protocol); | ||
| 120 | return false; | ||
| 121 | } | ||
| 122 | |||
| 123 | real_tag_info = { | ||
| 124 | .uuid = uuid, | ||
| 125 | .uuid_length = uuid_length, | ||
| 126 | .protocol = static_cast<NfcProtocol>(protocol), | ||
| 127 | .tag_type = static_cast<TagType>(tag_type), | ||
| 128 | }; | ||
| 129 | |||
| 130 | device_state = DeviceState::TagFound; | ||
| 131 | deactivate_event->GetReadableEvent().Clear(); | ||
| 132 | activate_event->Signal(); | ||
| 133 | return true; | ||
| 134 | } | ||
| 135 | |||
| 136 | bool NfcDevice::LoadAmiiboData() { | ||
| 137 | std::vector<u8> data{}; | ||
| 138 | |||
| 139 | if (!npad_device->ReadAmiiboData(data)) { | ||
| 140 | return false; | ||
| 141 | } | ||
| 142 | |||
| 117 | if (data.size() < sizeof(NFP::EncryptedNTAG215File)) { | 143 | if (data.size() < sizeof(NFP::EncryptedNTAG215File)) { |
| 118 | LOG_ERROR(Service_NFC, "Not an amiibo, size={}", data.size()); | 144 | LOG_ERROR(Service_NFC, "Not an amiibo, size={}", data.size()); |
| 119 | return false; | 145 | return false; |
| 120 | } | 146 | } |
| 121 | 147 | ||
| 122 | mifare_data.resize(data.size()); | ||
| 123 | memcpy(mifare_data.data(), data.data(), data.size()); | ||
| 124 | |||
| 125 | memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | 148 | memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); |
| 126 | is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data); | 149 | is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data); |
| 127 | is_write_protected = false; | 150 | is_write_protected = false; |
| 128 | 151 | ||
| 129 | device_state = DeviceState::TagFound; | ||
| 130 | deactivate_event->GetReadableEvent().Clear(); | ||
| 131 | activate_event->Signal(); | ||
| 132 | |||
| 133 | // Fallback for plain amiibos | 152 | // Fallback for plain amiibos |
| 134 | if (is_plain_amiibo) { | 153 | if (is_plain_amiibo) { |
| 135 | LOG_INFO(Service_NFP, "Using plain amiibo"); | 154 | LOG_INFO(Service_NFP, "Using plain amiibo"); |
| @@ -147,6 +166,7 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) { | |||
| 147 | return true; | 166 | return true; |
| 148 | } | 167 | } |
| 149 | 168 | ||
| 169 | LOG_INFO(Service_NFP, "Using encrypted amiibo"); | ||
| 150 | tag_data = {}; | 170 | tag_data = {}; |
| 151 | memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | 171 | memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); |
| 152 | return true; | 172 | return true; |
| @@ -162,7 +182,6 @@ void NfcDevice::CloseNfcTag() { | |||
| 162 | device_state = DeviceState::TagRemoved; | 182 | device_state = DeviceState::TagRemoved; |
| 163 | encrypted_tag_data = {}; | 183 | encrypted_tag_data = {}; |
| 164 | tag_data = {}; | 184 | tag_data = {}; |
| 165 | mifare_data = {}; | ||
| 166 | activate_event->GetReadableEvent().Clear(); | 185 | activate_event->GetReadableEvent().Clear(); |
| 167 | deactivate_event->Signal(); | 186 | deactivate_event->Signal(); |
| 168 | } | 187 | } |
| @@ -179,8 +198,12 @@ void NfcDevice::Initialize() { | |||
| 179 | device_state = npad_device->HasNfc() ? DeviceState::Initialized : DeviceState::Unavailable; | 198 | device_state = npad_device->HasNfc() ? DeviceState::Initialized : DeviceState::Unavailable; |
| 180 | encrypted_tag_data = {}; | 199 | encrypted_tag_data = {}; |
| 181 | tag_data = {}; | 200 | tag_data = {}; |
| 182 | mifare_data = {}; | 201 | |
| 183 | is_initalized = true; | 202 | if (device_state != DeviceState::Initialized) { |
| 203 | return; | ||
| 204 | } | ||
| 205 | |||
| 206 | is_initalized = npad_device->AddNfcHandle(); | ||
| 184 | } | 207 | } |
| 185 | 208 | ||
| 186 | void NfcDevice::Finalize() { | 209 | void NfcDevice::Finalize() { |
| @@ -190,6 +213,11 @@ void NfcDevice::Finalize() { | |||
| 190 | if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { | 213 | if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { |
| 191 | StopDetection(); | 214 | StopDetection(); |
| 192 | } | 215 | } |
| 216 | |||
| 217 | if (device_state != DeviceState::Unavailable) { | ||
| 218 | npad_device->RemoveNfcHandle(); | ||
| 219 | } | ||
| 220 | |||
| 193 | device_state = DeviceState::Unavailable; | 221 | device_state = DeviceState::Unavailable; |
| 194 | is_initalized = false; | 222 | is_initalized = false; |
| 195 | } | 223 | } |
| @@ -200,10 +228,8 @@ Result NfcDevice::StartDetection(NfcProtocol allowed_protocol) { | |||
| 200 | return ResultWrongDeviceState; | 228 | return ResultWrongDeviceState; |
| 201 | } | 229 | } |
| 202 | 230 | ||
| 203 | if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, | 231 | if (!npad_device->StartNfcPolling()) { |
| 204 | Common::Input::PollingMode::NFC) != | 232 | LOG_ERROR(Service_NFC, "Nfc polling not supported"); |
| 205 | Common::Input::DriverResult::Success) { | ||
| 206 | LOG_ERROR(Service_NFC, "Nfc not supported"); | ||
| 207 | return ResultNfcDisabled; | 233 | return ResultNfcDisabled; |
| 208 | } | 234 | } |
| 209 | 235 | ||
| @@ -213,9 +239,6 @@ Result NfcDevice::StartDetection(NfcProtocol allowed_protocol) { | |||
| 213 | } | 239 | } |
| 214 | 240 | ||
| 215 | Result NfcDevice::StopDetection() { | 241 | Result NfcDevice::StopDetection() { |
| 216 | npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, | ||
| 217 | Common::Input::PollingMode::Active); | ||
| 218 | |||
| 219 | if (device_state == DeviceState::Initialized) { | 242 | if (device_state == DeviceState::Initialized) { |
| 220 | return ResultSuccess; | 243 | return ResultSuccess; |
| 221 | } | 244 | } |
| @@ -225,6 +248,7 @@ Result NfcDevice::StopDetection() { | |||
| 225 | } | 248 | } |
| 226 | 249 | ||
| 227 | if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { | 250 | if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) { |
| 251 | npad_device->StopNfcPolling(); | ||
| 228 | device_state = DeviceState::Initialized; | 252 | device_state = DeviceState::Initialized; |
| 229 | return ResultSuccess; | 253 | return ResultSuccess; |
| 230 | } | 254 | } |
| @@ -233,7 +257,7 @@ Result NfcDevice::StopDetection() { | |||
| 233 | return ResultWrongDeviceState; | 257 | return ResultWrongDeviceState; |
| 234 | } | 258 | } |
| 235 | 259 | ||
| 236 | Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { | 260 | Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info) const { |
| 237 | if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) { | 261 | if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) { |
| 238 | LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); | 262 | LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); |
| 239 | if (device_state == DeviceState::TagRemoved) { | 263 | if (device_state == DeviceState::TagRemoved) { |
| @@ -242,41 +266,15 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { | |||
| 242 | return ResultWrongDeviceState; | 266 | return ResultWrongDeviceState; |
| 243 | } | 267 | } |
| 244 | 268 | ||
| 245 | UniqueSerialNumber uuid{}; | 269 | tag_info = real_tag_info; |
| 246 | u8 uuid_length{}; | ||
| 247 | NfcProtocol protocol{NfcProtocol::TypeA}; | ||
| 248 | TagType tag_type{TagType::Type2}; | ||
| 249 | |||
| 250 | if (is_mifare) { | ||
| 251 | tag_type = TagType::Mifare; | ||
| 252 | uuid_length = sizeof(NFP::NtagTagUuid); | ||
| 253 | memcpy(uuid.data(), mifare_data.data(), uuid_length); | ||
| 254 | } else { | ||
| 255 | tag_type = TagType::Type2; | ||
| 256 | uuid_length = sizeof(NFP::NtagTagUuid); | ||
| 257 | NFP::NtagTagUuid nUuid{ | ||
| 258 | .part1 = encrypted_tag_data.uuid.part1, | ||
| 259 | .part2 = encrypted_tag_data.uuid.part2, | ||
| 260 | .nintendo_id = encrypted_tag_data.uuid.nintendo_id, | ||
| 261 | }; | ||
| 262 | memcpy(uuid.data(), &nUuid, uuid_length); | ||
| 263 | 270 | ||
| 264 | // Generate random UUID to bypass amiibo load limits | 271 | // Generate random UUID to bypass amiibo load limits |
| 265 | if (Settings::values.random_amiibo_id) { | 272 | if (real_tag_info.tag_type == TagType::Type2 && Settings::values.random_amiibo_id) { |
| 266 | Common::TinyMT rng{}; | 273 | Common::TinyMT rng{}; |
| 267 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); | 274 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); |
| 268 | rng.GenerateRandomBytes(uuid.data(), uuid_length); | 275 | rng.GenerateRandomBytes(tag_info.uuid.data(), tag_info.uuid_length); |
| 269 | } | ||
| 270 | } | 276 | } |
| 271 | 277 | ||
| 272 | // Protocol and tag type may change here | ||
| 273 | tag_info = { | ||
| 274 | .uuid = uuid, | ||
| 275 | .uuid_length = uuid_length, | ||
| 276 | .protocol = protocol, | ||
| 277 | .tag_type = tag_type, | ||
| 278 | }; | ||
| 279 | |||
| 280 | return ResultSuccess; | 278 | return ResultSuccess; |
| 281 | } | 279 | } |
| 282 | 280 | ||
| @@ -293,7 +291,7 @@ Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameter | |||
| 293 | Result result = ResultSuccess; | 291 | Result result = ResultSuccess; |
| 294 | 292 | ||
| 295 | TagInfo tag_info{}; | 293 | TagInfo tag_info{}; |
| 296 | result = GetTagInfo(tag_info, true); | 294 | result = GetTagInfo(tag_info); |
| 297 | 295 | ||
| 298 | if (result.IsError()) { | 296 | if (result.IsError()) { |
| 299 | return result; | 297 | return result; |
| @@ -307,6 +305,8 @@ Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameter | |||
| 307 | return ResultInvalidArgument; | 305 | return ResultInvalidArgument; |
| 308 | } | 306 | } |
| 309 | 307 | ||
| 308 | Common::Input::MifareRequest request{}; | ||
| 309 | Common::Input::MifareRequest out_data{}; | ||
| 310 | const auto unknown = parameters[0].sector_key.unknown; | 310 | const auto unknown = parameters[0].sector_key.unknown; |
| 311 | for (std::size_t i = 0; i < parameters.size(); i++) { | 311 | for (std::size_t i = 0; i < parameters.size(); i++) { |
| 312 | if (unknown != parameters[i].sector_key.unknown) { | 312 | if (unknown != parameters[i].sector_key.unknown) { |
| @@ -315,25 +315,29 @@ Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameter | |||
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | for (std::size_t i = 0; i < parameters.size(); i++) { | 317 | for (std::size_t i = 0; i < parameters.size(); i++) { |
| 318 | result = ReadMifare(parameters[i], read_block_data[i]); | 318 | if (parameters[i].sector_key.command == MifareCmd::None) { |
| 319 | if (result.IsError()) { | 319 | continue; |
| 320 | break; | ||
| 321 | } | 320 | } |
| 321 | request.data[i].command = static_cast<u8>(parameters[i].sector_key.command); | ||
| 322 | request.data[i].sector = parameters[i].sector_number; | ||
| 323 | memcpy(request.data[i].key.data(), parameters[i].sector_key.sector_key.data(), | ||
| 324 | sizeof(KeyData)); | ||
| 322 | } | 325 | } |
| 323 | 326 | ||
| 324 | return result; | 327 | if (!npad_device->ReadMifareData(request, out_data)) { |
| 325 | } | ||
| 326 | |||
| 327 | Result NfcDevice::ReadMifare(const MifareReadBlockParameter& parameter, | ||
| 328 | MifareReadBlockData& read_block_data) const { | ||
| 329 | const std::size_t sector_index = parameter.sector_number * sizeof(DataBlock); | ||
| 330 | read_block_data.sector_number = parameter.sector_number; | ||
| 331 | if (mifare_data.size() < sector_index + sizeof(DataBlock)) { | ||
| 332 | return ResultMifareError288; | 328 | return ResultMifareError288; |
| 333 | } | 329 | } |
| 334 | 330 | ||
| 335 | // TODO: Use parameter.sector_key to read encrypted data | 331 | for (std::size_t i = 0; i < read_block_data.size(); i++) { |
| 336 | memcpy(read_block_data.data.data(), mifare_data.data() + sector_index, sizeof(DataBlock)); | 332 | if (static_cast<MifareCmd>(out_data.data[i].command) == MifareCmd::None) { |
| 333 | continue; | ||
| 334 | } | ||
| 335 | |||
| 336 | read_block_data[i] = { | ||
| 337 | .data = out_data.data[i].data, | ||
| 338 | .sector_number = out_data.data[i].sector, | ||
| 339 | }; | ||
| 340 | } | ||
| 337 | 341 | ||
| 338 | return ResultSuccess; | 342 | return ResultSuccess; |
| 339 | } | 343 | } |
| @@ -342,7 +346,7 @@ Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> paramet | |||
| 342 | Result result = ResultSuccess; | 346 | Result result = ResultSuccess; |
| 343 | 347 | ||
| 344 | TagInfo tag_info{}; | 348 | TagInfo tag_info{}; |
| 345 | result = GetTagInfo(tag_info, true); | 349 | result = GetTagInfo(tag_info); |
| 346 | 350 | ||
| 347 | if (result.IsError()) { | 351 | if (result.IsError()) { |
| 348 | return result; | 352 | return result; |
| @@ -363,42 +367,25 @@ Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> paramet | |||
| 363 | } | 367 | } |
| 364 | } | 368 | } |
| 365 | 369 | ||
| 370 | Common::Input::MifareRequest request{}; | ||
| 366 | for (std::size_t i = 0; i < parameters.size(); i++) { | 371 | for (std::size_t i = 0; i < parameters.size(); i++) { |
| 367 | result = WriteMifare(parameters[i]); | 372 | if (parameters[i].sector_key.command == MifareCmd::None) { |
| 368 | if (result.IsError()) { | 373 | continue; |
| 369 | break; | ||
| 370 | } | 374 | } |
| 375 | request.data[i].command = static_cast<u8>(parameters[i].sector_key.command); | ||
| 376 | request.data[i].sector = parameters[i].sector_number; | ||
| 377 | memcpy(request.data[i].key.data(), parameters[i].sector_key.sector_key.data(), | ||
| 378 | sizeof(KeyData)); | ||
| 379 | memcpy(request.data[i].data.data(), parameters[i].data.data(), sizeof(KeyData)); | ||
| 371 | } | 380 | } |
| 372 | 381 | ||
| 373 | if (!npad_device->WriteNfc(mifare_data)) { | 382 | if (!npad_device->WriteMifareData(request)) { |
| 374 | LOG_ERROR(Service_NFP, "Error writing to file"); | ||
| 375 | return ResultMifareError288; | 383 | return ResultMifareError288; |
| 376 | } | 384 | } |
| 377 | 385 | ||
| 378 | return result; | 386 | return result; |
| 379 | } | 387 | } |
| 380 | 388 | ||
| 381 | Result NfcDevice::WriteMifare(const MifareWriteBlockParameter& parameter) { | ||
| 382 | const std::size_t sector_index = parameter.sector_number * sizeof(DataBlock); | ||
| 383 | |||
| 384 | if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) { | ||
| 385 | LOG_ERROR(Service_NFC, "Wrong device state {}", device_state); | ||
| 386 | if (device_state == DeviceState::TagRemoved) { | ||
| 387 | return ResultTagRemoved; | ||
| 388 | } | ||
| 389 | return ResultWrongDeviceState; | ||
| 390 | } | ||
| 391 | |||
| 392 | if (mifare_data.size() < sector_index + sizeof(DataBlock)) { | ||
| 393 | return ResultMifareError288; | ||
| 394 | } | ||
| 395 | |||
| 396 | // TODO: Use parameter.sector_key to encrypt the data | ||
| 397 | memcpy(mifare_data.data() + sector_index, parameter.data.data(), sizeof(DataBlock)); | ||
| 398 | |||
| 399 | return ResultSuccess; | ||
| 400 | } | ||
| 401 | |||
| 402 | Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, | 389 | Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, |
| 403 | std::span<const u8> command_data, | 390 | std::span<const u8> command_data, |
| 404 | std::span<u8> out_data) { | 391 | std::span<u8> out_data) { |
| @@ -412,6 +399,11 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target | |||
| 412 | return ResultWrongDeviceState; | 399 | return ResultWrongDeviceState; |
| 413 | } | 400 | } |
| 414 | 401 | ||
| 402 | if (!LoadAmiiboData()) { | ||
| 403 | LOG_ERROR(Service_NFP, "Not an amiibo"); | ||
| 404 | return ResultInvalidTagType; | ||
| 405 | } | ||
| 406 | |||
| 415 | if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { | 407 | if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { |
| 416 | LOG_ERROR(Service_NFP, "Not an amiibo"); | 408 | LOG_ERROR(Service_NFP, "Not an amiibo"); |
| 417 | return ResultInvalidTagType; | 409 | return ResultInvalidTagType; |
| @@ -562,7 +554,7 @@ Result NfcDevice::Restore() { | |||
| 562 | 554 | ||
| 563 | NFC::TagInfo tag_info{}; | 555 | NFC::TagInfo tag_info{}; |
| 564 | std::array<u8, sizeof(NFP::EncryptedNTAG215File)> data{}; | 556 | std::array<u8, sizeof(NFP::EncryptedNTAG215File)> data{}; |
| 565 | Result result = GetTagInfo(tag_info, false); | 557 | Result result = GetTagInfo(tag_info); |
| 566 | 558 | ||
| 567 | if (result.IsError()) { | 559 | if (result.IsError()) { |
| 568 | return result; | 560 | return result; |
| @@ -635,7 +627,7 @@ Result NfcDevice::GetCommonInfo(NFP::CommonInfo& common_info) const { | |||
| 635 | // TODO: Validate this data | 627 | // TODO: Validate this data |
| 636 | common_info = { | 628 | common_info = { |
| 637 | .last_write_date = settings.write_date.GetWriteDate(), | 629 | .last_write_date = settings.write_date.GetWriteDate(), |
| 638 | .write_counter = tag_data.write_counter, | 630 | .write_counter = tag_data.application_write_counter, |
| 639 | .version = tag_data.amiibo_version, | 631 | .version = tag_data.amiibo_version, |
| 640 | .application_area_size = sizeof(NFP::ApplicationArea), | 632 | .application_area_size = sizeof(NFP::ApplicationArea), |
| 641 | }; | 633 | }; |
diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 7560210d6..0ed1ff34c 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h | |||
| @@ -42,15 +42,12 @@ public: | |||
| 42 | Result StartDetection(NfcProtocol allowed_protocol); | 42 | Result StartDetection(NfcProtocol allowed_protocol); |
| 43 | Result StopDetection(); | 43 | Result StopDetection(); |
| 44 | 44 | ||
| 45 | Result GetTagInfo(TagInfo& tag_info, bool is_mifare) const; | 45 | Result GetTagInfo(TagInfo& tag_info) const; |
| 46 | 46 | ||
| 47 | Result ReadMifare(std::span<const MifareReadBlockParameter> parameters, | 47 | Result ReadMifare(std::span<const MifareReadBlockParameter> parameters, |
| 48 | std::span<MifareReadBlockData> read_block_data) const; | 48 | std::span<MifareReadBlockData> read_block_data) const; |
| 49 | Result ReadMifare(const MifareReadBlockParameter& parameter, | ||
| 50 | MifareReadBlockData& read_block_data) const; | ||
| 51 | 49 | ||
| 52 | Result WriteMifare(std::span<const MifareWriteBlockParameter> parameters); | 50 | Result WriteMifare(std::span<const MifareWriteBlockParameter> parameters); |
| 53 | Result WriteMifare(const MifareWriteBlockParameter& parameter); | ||
| 54 | 51 | ||
| 55 | Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, | 52 | Result SendCommandByPassThrough(const Time::Clock::TimeSpanType& timeout, |
| 56 | std::span<const u8> command_data, std::span<u8> out_data); | 53 | std::span<const u8> command_data, std::span<u8> out_data); |
| @@ -105,7 +102,8 @@ public: | |||
| 105 | 102 | ||
| 106 | private: | 103 | private: |
| 107 | void NpadUpdate(Core::HID::ControllerTriggerType type); | 104 | void NpadUpdate(Core::HID::ControllerTriggerType type); |
| 108 | bool LoadNfcTag(std::span<const u8> data); | 105 | bool LoadNfcTag(u8 protocol, u8 tag_type, u8 uuid_length, UniqueSerialNumber uuid); |
| 106 | bool LoadAmiiboData(); | ||
| 109 | void CloseNfcTag(); | 107 | void CloseNfcTag(); |
| 110 | 108 | ||
| 111 | NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; | 109 | NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; |
| @@ -140,8 +138,8 @@ private: | |||
| 140 | bool is_write_protected{}; | 138 | bool is_write_protected{}; |
| 141 | NFP::MountTarget mount_target{NFP::MountTarget::None}; | 139 | NFP::MountTarget mount_target{NFP::MountTarget::None}; |
| 142 | 140 | ||
| 141 | TagInfo real_tag_info{}; | ||
| 143 | NFP::NTAG215File tag_data{}; | 142 | NFP::NTAG215File tag_data{}; |
| 144 | std::vector<u8> mifare_data{}; | ||
| 145 | NFP::EncryptedNTAG215File encrypted_tag_data{}; | 143 | NFP::EncryptedNTAG215File encrypted_tag_data{}; |
| 146 | }; | 144 | }; |
| 147 | 145 | ||
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index b0456508e..562f3a28e 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp | |||
| @@ -29,6 +29,9 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex | |||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | DeviceManager ::~DeviceManager() { | 31 | DeviceManager ::~DeviceManager() { |
| 32 | if (is_initialized) { | ||
| 33 | Finalize(); | ||
| 34 | } | ||
| 32 | service_context.CloseEvent(availability_change_event); | 35 | service_context.CloseEvent(availability_change_event); |
| 33 | } | 36 | } |
| 34 | 37 | ||
| @@ -125,14 +128,14 @@ Result DeviceManager::StopDetection(u64 device_handle) { | |||
| 125 | return result; | 128 | return result; |
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info, bool is_mifare) const { | 131 | Result DeviceManager::GetTagInfo(u64 device_handle, TagInfo& tag_info) const { |
| 129 | std::scoped_lock lock{mutex}; | 132 | std::scoped_lock lock{mutex}; |
| 130 | 133 | ||
| 131 | std::shared_ptr<NfcDevice> device = nullptr; | 134 | std::shared_ptr<NfcDevice> device = nullptr; |
| 132 | auto result = GetDeviceHandle(device_handle, device); | 135 | auto result = GetDeviceHandle(device_handle, device); |
| 133 | 136 | ||
| 134 | if (result.IsSuccess()) { | 137 | if (result.IsSuccess()) { |
| 135 | result = device->GetTagInfo(tag_info, is_mifare); | 138 | result = device->GetTagInfo(tag_info); |
| 136 | result = VerifyDeviceResult(device, result); | 139 | result = VerifyDeviceResult(device, result); |
| 137 | } | 140 | } |
| 138 | 141 | ||
| @@ -546,7 +549,7 @@ Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) cons | |||
| 546 | NFC::TagInfo tag_info{}; | 549 | NFC::TagInfo tag_info{}; |
| 547 | 550 | ||
| 548 | if (result.IsSuccess()) { | 551 | if (result.IsSuccess()) { |
| 549 | result = device->GetTagInfo(tag_info, false); | 552 | result = device->GetTagInfo(tag_info); |
| 550 | } | 553 | } |
| 551 | 554 | ||
| 552 | if (result.IsSuccess()) { | 555 | if (result.IsSuccess()) { |
| @@ -565,7 +568,7 @@ Result DeviceManager::WriteBackupData(u64 device_handle, std::span<const u8> dat | |||
| 565 | NFC::TagInfo tag_info{}; | 568 | NFC::TagInfo tag_info{}; |
| 566 | 569 | ||
| 567 | if (result.IsSuccess()) { | 570 | if (result.IsSuccess()) { |
| 568 | result = device->GetTagInfo(tag_info, false); | 571 | result = device->GetTagInfo(tag_info); |
| 569 | } | 572 | } |
| 570 | 573 | ||
| 571 | if (result.IsSuccess()) { | 574 | if (result.IsSuccess()) { |
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index 2971e280f..c61ba0cf3 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h | |||
| @@ -33,7 +33,7 @@ public: | |||
| 33 | Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const; | 33 | Kernel::KReadableEvent& AttachAvailabilityChangeEvent() const; |
| 34 | Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); | 34 | Result StartDetection(u64 device_handle, NfcProtocol tag_protocol); |
| 35 | Result StopDetection(u64 device_handle); | 35 | Result StopDetection(u64 device_handle); |
| 36 | Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info, bool is_mifare) const; | 36 | Result GetTagInfo(u64 device_handle, NFP::TagInfo& tag_info) const; |
| 37 | Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const; | 37 | Kernel::KReadableEvent& AttachActivateEvent(u64 device_handle) const; |
| 38 | Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const; | 38 | Kernel::KReadableEvent& AttachDeactivateEvent(u64 device_handle) const; |
| 39 | Result ReadMifare(u64 device_handle, | 39 | Result ReadMifare(u64 device_handle, |
diff --git a/src/core/hle/service/nfc/mifare_types.h b/src/core/hle/service/nfc/mifare_types.h index 75b59f021..467937399 100644 --- a/src/core/hle/service/nfc/mifare_types.h +++ b/src/core/hle/service/nfc/mifare_types.h | |||
| @@ -11,9 +11,10 @@ | |||
| 11 | namespace Service::NFC { | 11 | namespace Service::NFC { |
| 12 | 12 | ||
| 13 | enum class MifareCmd : u8 { | 13 | enum class MifareCmd : u8 { |
| 14 | None = 0x00, | ||
| 15 | Read = 0x30, | ||
| 14 | AuthA = 0x60, | 16 | AuthA = 0x60, |
| 15 | AuthB = 0x61, | 17 | AuthB = 0x61, |
| 16 | Read = 0x30, | ||
| 17 | Write = 0xA0, | 18 | Write = 0xA0, |
| 18 | Transfer = 0xB0, | 19 | Transfer = 0xB0, |
| 19 | Decrement = 0xC0, | 20 | Decrement = 0xC0, |
| @@ -35,17 +36,17 @@ static_assert(sizeof(SectorKey) == 0x10, "SectorKey is an invalid size"); | |||
| 35 | 36 | ||
| 36 | // This is nn::nfc::MifareReadBlockParameter | 37 | // This is nn::nfc::MifareReadBlockParameter |
| 37 | struct MifareReadBlockParameter { | 38 | struct MifareReadBlockParameter { |
| 38 | u8 sector_number; | 39 | u8 sector_number{}; |
| 39 | INSERT_PADDING_BYTES(0x7); | 40 | INSERT_PADDING_BYTES(0x7); |
| 40 | SectorKey sector_key; | 41 | SectorKey sector_key{}; |
| 41 | }; | 42 | }; |
| 42 | static_assert(sizeof(MifareReadBlockParameter) == 0x18, | 43 | static_assert(sizeof(MifareReadBlockParameter) == 0x18, |
| 43 | "MifareReadBlockParameter is an invalid size"); | 44 | "MifareReadBlockParameter is an invalid size"); |
| 44 | 45 | ||
| 45 | // This is nn::nfc::MifareReadBlockData | 46 | // This is nn::nfc::MifareReadBlockData |
| 46 | struct MifareReadBlockData { | 47 | struct MifareReadBlockData { |
| 47 | DataBlock data; | 48 | DataBlock data{}; |
| 48 | u8 sector_number; | 49 | u8 sector_number{}; |
| 49 | INSERT_PADDING_BYTES(0x7); | 50 | INSERT_PADDING_BYTES(0x7); |
| 50 | }; | 51 | }; |
| 51 | static_assert(sizeof(MifareReadBlockData) == 0x18, "MifareReadBlockData is an invalid size"); | 52 | static_assert(sizeof(MifareReadBlockData) == 0x18, "MifareReadBlockData is an invalid size"); |
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index 130fb7f78..e7ca7582e 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp | |||
| @@ -174,8 +174,7 @@ void NfcInterface::GetTagInfo(HLERequestContext& ctx) { | |||
| 174 | LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); | 174 | LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); |
| 175 | 175 | ||
| 176 | TagInfo tag_info{}; | 176 | TagInfo tag_info{}; |
| 177 | auto result = | 177 | auto result = GetManager()->GetTagInfo(device_handle, tag_info); |
| 178 | GetManager()->GetTagInfo(device_handle, tag_info, backend_type == BackendType::Mifare); | ||
| 179 | result = TranslateResultToServiceError(result); | 178 | result = TranslateResultToServiceError(result); |
| 180 | 179 | ||
| 181 | if (result.IsSuccess()) { | 180 | if (result.IsSuccess()) { |
| @@ -216,8 +215,8 @@ void NfcInterface::ReadMifare(HLERequestContext& ctx) { | |||
| 216 | memcpy(read_commands.data(), buffer.data(), | 215 | memcpy(read_commands.data(), buffer.data(), |
| 217 | number_of_commands * sizeof(MifareReadBlockParameter)); | 216 | number_of_commands * sizeof(MifareReadBlockParameter)); |
| 218 | 217 | ||
| 219 | LOG_INFO(Service_NFC, "(STUBBED) called, device_handle={}, read_commands_size={}", | 218 | LOG_INFO(Service_NFC, "called, device_handle={}, read_commands_size={}", device_handle, |
| 220 | device_handle, number_of_commands); | 219 | number_of_commands); |
| 221 | 220 | ||
| 222 | std::vector<MifareReadBlockData> out_data(number_of_commands); | 221 | std::vector<MifareReadBlockData> out_data(number_of_commands); |
| 223 | auto result = GetManager()->ReadMifare(device_handle, read_commands, out_data); | 222 | auto result = GetManager()->ReadMifare(device_handle, read_commands, out_data); |
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index ab1f30f9e..a04538d5d 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h | |||
| @@ -34,7 +34,7 @@ public: | |||
| 34 | * @returns The result code of the ioctl. | 34 | * @returns The result code of the ioctl. |
| 35 | */ | 35 | */ |
| 36 | virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 36 | virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 37 | std::vector<u8>& output) = 0; | 37 | std::span<u8> output) = 0; |
| 38 | 38 | ||
| 39 | /** | 39 | /** |
| 40 | * Handles an ioctl2 request. | 40 | * Handles an ioctl2 request. |
| @@ -45,7 +45,7 @@ public: | |||
| 45 | * @returns The result code of the ioctl. | 45 | * @returns The result code of the ioctl. |
| 46 | */ | 46 | */ |
| 47 | virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 47 | virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 48 | std::span<const u8> inline_input, std::vector<u8>& output) = 0; | 48 | std::span<const u8> inline_input, std::span<u8> output) = 0; |
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| 51 | * Handles an ioctl3 request. | 51 | * Handles an ioctl3 request. |
| @@ -56,7 +56,7 @@ public: | |||
| 56 | * @returns The result code of the ioctl. | 56 | * @returns The result code of the ioctl. |
| 57 | */ | 57 | */ |
| 58 | virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 58 | virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 59 | std::vector<u8>& output, std::vector<u8>& inline_output) = 0; | 59 | std::span<u8> output, std::span<u8> inline_output) = 0; |
| 60 | 60 | ||
| 61 | /** | 61 | /** |
| 62 | * Called once a device is opened | 62 | * Called once a device is opened |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 5a5b2e305..05a43d8dc 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -18,19 +18,19 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system_, NvCore::Container& core) | |||
| 18 | nvdisp_disp0::~nvdisp_disp0() = default; | 18 | nvdisp_disp0::~nvdisp_disp0() = default; |
| 19 | 19 | ||
| 20 | NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 20 | NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 21 | std::vector<u8>& output) { | 21 | std::span<u8> output) { |
| 22 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 22 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 23 | return NvResult::NotImplemented; | 23 | return NvResult::NotImplemented; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 26 | NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 27 | std::span<const u8> inline_input, std::vector<u8>& output) { | 27 | std::span<const u8> inline_input, std::span<u8> output) { |
| 28 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 28 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 29 | return NvResult::NotImplemented; | 29 | return NvResult::NotImplemented; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 32 | NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 33 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 33 | std::span<u8> output, std::span<u8> inline_output) { |
| 34 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 34 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 35 | return NvResult::NotImplemented; | 35 | return NvResult::NotImplemented; |
| 36 | } | 36 | } |
| @@ -51,8 +51,8 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat form | |||
| 51 | stride, format, transform, crop_rect}; | 51 | stride, format, transform, crop_rect}; |
| 52 | 52 | ||
| 53 | system.GPU().RequestSwapBuffers(&framebuffer, fences, num_fences); | 53 | system.GPU().RequestSwapBuffers(&framebuffer, fences, num_fences); |
| 54 | system.GetPerfStats().EndSystemFrame(); | ||
| 55 | system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs()); | 54 | system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs()); |
| 55 | system.GetPerfStats().EndSystemFrame(); | ||
| 56 | system.GetPerfStats().BeginSystemFrame(); | 56 | system.GetPerfStats().BeginSystemFrame(); |
| 57 | } | 57 | } |
| 58 | 58 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index bcd0e3ed5..daee05fe8 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -26,11 +26,11 @@ public: | |||
| 26 | ~nvdisp_disp0() override; | 26 | ~nvdisp_disp0() override; |
| 27 | 27 | ||
| 28 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 28 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 29 | std::vector<u8>& output) override; | 29 | std::span<u8> output) override; |
| 30 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 30 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 31 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 31 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 33 | std::vector<u8>& inline_output) override; | 33 | std::span<u8> inline_output) override; |
| 34 | 34 | ||
| 35 | void OnOpen(DeviceFD fd) override; | 35 | void OnOpen(DeviceFD fd) override; |
| 36 | void OnClose(DeviceFD fd) override; | 36 | void OnClose(DeviceFD fd) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 681bd0867..07e570a9f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -28,7 +28,7 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, Module& module_, NvCore::Con | |||
| 28 | nvhost_as_gpu::~nvhost_as_gpu() = default; | 28 | nvhost_as_gpu::~nvhost_as_gpu() = default; |
| 29 | 29 | ||
| 30 | NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 30 | NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 31 | std::vector<u8>& output) { | 31 | std::span<u8> output) { |
| 32 | switch (command.group) { | 32 | switch (command.group) { |
| 33 | case 'A': | 33 | case 'A': |
| 34 | switch (command.cmd) { | 34 | switch (command.cmd) { |
| @@ -61,13 +61,13 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 63 | NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 64 | std::span<const u8> inline_input, std::vector<u8>& output) { | 64 | std::span<const u8> inline_input, std::span<u8> output) { |
| 65 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 65 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 66 | return NvResult::NotImplemented; | 66 | return NvResult::NotImplemented; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 69 | NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 70 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 70 | std::span<u8> output, std::span<u8> inline_output) { |
| 71 | switch (command.group) { | 71 | switch (command.group) { |
| 72 | case 'A': | 72 | case 'A': |
| 73 | switch (command.cmd) { | 73 | switch (command.cmd) { |
| @@ -87,7 +87,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 87 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} | 87 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} |
| 88 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} | 88 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} |
| 89 | 89 | ||
| 90 | NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::vector<u8>& output) { | 90 | NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> output) { |
| 91 | IoctlAllocAsEx params{}; | 91 | IoctlAllocAsEx params{}; |
| 92 | std::memcpy(¶ms, input.data(), input.size()); | 92 | std::memcpy(¶ms, input.data(), input.size()); |
| 93 | 93 | ||
| @@ -141,7 +141,7 @@ NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::vector<u8>& ou | |||
| 141 | return NvResult::Success; | 141 | return NvResult::Success; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::vector<u8>& output) { | 144 | NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> output) { |
| 145 | IoctlAllocSpace params{}; | 145 | IoctlAllocSpace params{}; |
| 146 | std::memcpy(¶ms, input.data(), input.size()); | 146 | std::memcpy(¶ms, input.data(), input.size()); |
| 147 | 147 | ||
| @@ -220,7 +220,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) { | |||
| 220 | mapping_map.erase(offset); | 220 | mapping_map.erase(offset); |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::vector<u8>& output) { | 223 | NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> output) { |
| 224 | IoctlFreeSpace params{}; | 224 | IoctlFreeSpace params{}; |
| 225 | std::memcpy(¶ms, input.data(), input.size()); | 225 | std::memcpy(¶ms, input.data(), input.size()); |
| 226 | 226 | ||
| @@ -266,15 +266,14 @@ NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::vector<u8>& ou | |||
| 266 | return NvResult::Success; | 266 | return NvResult::Success; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::vector<u8>& output) { | 269 | NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) { |
| 270 | const auto num_entries = input.size() / sizeof(IoctlRemapEntry); | 270 | const auto num_entries = input.size() / sizeof(IoctlRemapEntry); |
| 271 | 271 | ||
| 272 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); | 272 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); |
| 273 | 273 | ||
| 274 | std::vector<IoctlRemapEntry> entries(num_entries); | ||
| 275 | std::memcpy(entries.data(), input.data(), input.size()); | ||
| 276 | |||
| 277 | std::scoped_lock lock(mutex); | 274 | std::scoped_lock lock(mutex); |
| 275 | entries.resize_destructive(num_entries); | ||
| 276 | std::memcpy(entries.data(), input.data(), input.size()); | ||
| 278 | 277 | ||
| 279 | if (!vm.initialised) { | 278 | if (!vm.initialised) { |
| 280 | return NvResult::BadValue; | 279 | return NvResult::BadValue; |
| @@ -320,7 +319,7 @@ NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::vector<u8>& output | |||
| 320 | return NvResult::Success; | 319 | return NvResult::Success; |
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::vector<u8>& output) { | 322 | NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> output) { |
| 324 | IoctlMapBufferEx params{}; | 323 | IoctlMapBufferEx params{}; |
| 325 | std::memcpy(¶ms, input.data(), input.size()); | 324 | std::memcpy(¶ms, input.data(), input.size()); |
| 326 | 325 | ||
| @@ -424,7 +423,7 @@ NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::vector<u8>& | |||
| 424 | return NvResult::Success; | 423 | return NvResult::Success; |
| 425 | } | 424 | } |
| 426 | 425 | ||
| 427 | NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::vector<u8>& output) { | 426 | NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> output) { |
| 428 | IoctlUnmapBuffer params{}; | 427 | IoctlUnmapBuffer params{}; |
| 429 | std::memcpy(¶ms, input.data(), input.size()); | 428 | std::memcpy(¶ms, input.data(), input.size()); |
| 430 | 429 | ||
| @@ -463,7 +462,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::vector<u8>& | |||
| 463 | return NvResult::Success; | 462 | return NvResult::Success; |
| 464 | } | 463 | } |
| 465 | 464 | ||
| 466 | NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::vector<u8>& output) { | 465 | NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::span<u8> output) { |
| 467 | IoctlBindChannel params{}; | 466 | IoctlBindChannel params{}; |
| 468 | std::memcpy(¶ms, input.data(), input.size()); | 467 | std::memcpy(¶ms, input.data(), input.size()); |
| 469 | LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); | 468 | LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); |
| @@ -492,7 +491,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) { | |||
| 492 | }; | 491 | }; |
| 493 | } | 492 | } |
| 494 | 493 | ||
| 495 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& output) { | 494 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output) { |
| 496 | IoctlGetVaRegions params{}; | 495 | IoctlGetVaRegions params{}; |
| 497 | std::memcpy(¶ms, input.data(), input.size()); | 496 | std::memcpy(¶ms, input.data(), input.size()); |
| 498 | 497 | ||
| @@ -511,8 +510,8 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& | |||
| 511 | return NvResult::Success; | 510 | return NvResult::Success; |
| 512 | } | 511 | } |
| 513 | 512 | ||
| 514 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& output, | 513 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output, |
| 515 | std::vector<u8>& inline_output) { | 514 | std::span<u8> inline_output) { |
| 516 | IoctlGetVaRegions params{}; | 515 | IoctlGetVaRegions params{}; |
| 517 | std::memcpy(¶ms, input.data(), input.size()); | 516 | std::memcpy(¶ms, input.data(), input.size()); |
| 518 | 517 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 1aba8d579..2af3e1260 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "common/address_space.h" | 15 | #include "common/address_space.h" |
| 16 | #include "common/common_funcs.h" | 16 | #include "common/common_funcs.h" |
| 17 | #include "common/common_types.h" | 17 | #include "common/common_types.h" |
| 18 | #include "common/scratch_buffer.h" | ||
| 18 | #include "common/swap.h" | 19 | #include "common/swap.h" |
| 19 | #include "core/hle/service/nvdrv/core/nvmap.h" | 20 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 20 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 21 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| @@ -48,11 +49,11 @@ public: | |||
| 48 | ~nvhost_as_gpu() override; | 49 | ~nvhost_as_gpu() override; |
| 49 | 50 | ||
| 50 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 51 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 51 | std::vector<u8>& output) override; | 52 | std::span<u8> output) override; |
| 52 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 53 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 53 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 54 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 54 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 55 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 55 | std::vector<u8>& inline_output) override; | 56 | std::span<u8> inline_output) override; |
| 56 | 57 | ||
| 57 | void OnOpen(DeviceFD fd) override; | 58 | void OnOpen(DeviceFD fd) override; |
| 58 | void OnClose(DeviceFD fd) override; | 59 | void OnClose(DeviceFD fd) override; |
| @@ -138,18 +139,18 @@ private: | |||
| 138 | static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, | 139 | static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, |
| 139 | "IoctlGetVaRegions is incorrect size"); | 140 | "IoctlGetVaRegions is incorrect size"); |
| 140 | 141 | ||
| 141 | NvResult AllocAsEx(std::span<const u8> input, std::vector<u8>& output); | 142 | NvResult AllocAsEx(std::span<const u8> input, std::span<u8> output); |
| 142 | NvResult AllocateSpace(std::span<const u8> input, std::vector<u8>& output); | 143 | NvResult AllocateSpace(std::span<const u8> input, std::span<u8> output); |
| 143 | NvResult Remap(std::span<const u8> input, std::vector<u8>& output); | 144 | NvResult Remap(std::span<const u8> input, std::span<u8> output); |
| 144 | NvResult MapBufferEx(std::span<const u8> input, std::vector<u8>& output); | 145 | NvResult MapBufferEx(std::span<const u8> input, std::span<u8> output); |
| 145 | NvResult UnmapBuffer(std::span<const u8> input, std::vector<u8>& output); | 146 | NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output); |
| 146 | NvResult FreeSpace(std::span<const u8> input, std::vector<u8>& output); | 147 | NvResult FreeSpace(std::span<const u8> input, std::span<u8> output); |
| 147 | NvResult BindChannel(std::span<const u8> input, std::vector<u8>& output); | 148 | NvResult BindChannel(std::span<const u8> input, std::span<u8> output); |
| 148 | 149 | ||
| 149 | void GetVARegionsImpl(IoctlGetVaRegions& params); | 150 | void GetVARegionsImpl(IoctlGetVaRegions& params); |
| 150 | NvResult GetVARegions(std::span<const u8> input, std::vector<u8>& output); | 151 | NvResult GetVARegions(std::span<const u8> input, std::span<u8> output); |
| 151 | NvResult GetVARegions(std::span<const u8> input, std::vector<u8>& output, | 152 | NvResult GetVARegions(std::span<const u8> input, std::span<u8> output, |
| 152 | std::vector<u8>& inline_output); | 153 | std::span<u8> inline_output); |
| 153 | 154 | ||
| 154 | void FreeMappingLocked(u64 offset); | 155 | void FreeMappingLocked(u64 offset); |
| 155 | 156 | ||
| @@ -212,6 +213,7 @@ private: | |||
| 212 | bool initialised{}; | 213 | bool initialised{}; |
| 213 | } vm; | 214 | } vm; |
| 214 | std::shared_ptr<Tegra::MemoryManager> gmmu; | 215 | std::shared_ptr<Tegra::MemoryManager> gmmu; |
| 216 | Common::ScratchBuffer<IoctlRemapEntry> entries; | ||
| 215 | 217 | ||
| 216 | // s32 channel{}; | 218 | // s32 channel{}; |
| 217 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; | 219 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index e12025560..4d55554b4 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -35,7 +35,7 @@ nvhost_ctrl::~nvhost_ctrl() { | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 37 | NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 38 | std::vector<u8>& output) { | 38 | std::span<u8> output) { |
| 39 | switch (command.group) { | 39 | switch (command.group) { |
| 40 | case 0x0: | 40 | case 0x0: |
| 41 | switch (command.cmd) { | 41 | switch (command.cmd) { |
| @@ -64,13 +64,13 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inp | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 66 | NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 67 | std::span<const u8> inline_input, std::vector<u8>& output) { | 67 | std::span<const u8> inline_input, std::span<u8> output) { |
| 68 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 68 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 69 | return NvResult::NotImplemented; | 69 | return NvResult::NotImplemented; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 72 | NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 73 | std::vector<u8>& output, std::vector<u8>& inline_outpu) { | 73 | std::span<u8> output, std::span<u8> inline_outpu) { |
| 74 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 74 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 75 | return NvResult::NotImplemented; | 75 | return NvResult::NotImplemented; |
| 76 | } | 76 | } |
| @@ -79,7 +79,7 @@ void nvhost_ctrl::OnOpen(DeviceFD fd) {} | |||
| 79 | 79 | ||
| 80 | void nvhost_ctrl::OnClose(DeviceFD fd) {} | 80 | void nvhost_ctrl::OnClose(DeviceFD fd) {} |
| 81 | 81 | ||
| 82 | NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::vector<u8>& output) { | 82 | NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output) { |
| 83 | IocGetConfigParams params{}; | 83 | IocGetConfigParams params{}; |
| 84 | std::memcpy(¶ms, input.data(), sizeof(params)); | 84 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 85 | LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), | 85 | LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), |
| @@ -87,7 +87,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::vector<u8 | |||
| 87 | return NvResult::ConfigVarNotFound; // Returns error on production mode | 87 | return NvResult::ConfigVarNotFound; // Returns error on production mode |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::vector<u8>& output, | 90 | NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::span<u8> output, |
| 91 | bool is_allocation) { | 91 | bool is_allocation) { |
| 92 | IocCtrlEventWaitParams params{}; | 92 | IocCtrlEventWaitParams params{}; |
| 93 | std::memcpy(¶ms, input.data(), sizeof(params)); | 93 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| @@ -231,7 +231,7 @@ NvResult nvhost_ctrl::FreeEvent(u32 slot) { | |||
| 231 | return NvResult::Success; | 231 | return NvResult::Success; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::vector<u8>& output) { | 234 | NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output) { |
| 235 | IocCtrlEventRegisterParams params{}; | 235 | IocCtrlEventRegisterParams params{}; |
| 236 | std::memcpy(¶ms, input.data(), sizeof(params)); | 236 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 237 | const u32 event_id = params.user_event_id; | 237 | const u32 event_id = params.user_event_id; |
| @@ -252,7 +252,7 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::vecto | |||
| 252 | return NvResult::Success; | 252 | return NvResult::Success; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::vector<u8>& output) { | 255 | NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output) { |
| 256 | IocCtrlEventUnregisterParams params{}; | 256 | IocCtrlEventUnregisterParams params{}; |
| 257 | std::memcpy(¶ms, input.data(), sizeof(params)); | 257 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 258 | const u32 event_id = params.user_event_id & 0x00FF; | 258 | const u32 event_id = params.user_event_id & 0x00FF; |
| @@ -262,8 +262,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::vec | |||
| 262 | return FreeEvent(event_id); | 262 | return FreeEvent(event_id); |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, | 265 | NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output) { |
| 266 | std::vector<u8>& output) { | ||
| 267 | IocCtrlEventUnregisterBatchParams params{}; | 266 | IocCtrlEventUnregisterBatchParams params{}; |
| 268 | std::memcpy(¶ms, input.data(), sizeof(params)); | 267 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 269 | u64 event_mask = params.user_events; | 268 | u64 event_mask = params.user_events; |
| @@ -281,7 +280,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, | |||
| 281 | return NvResult::Success; | 280 | return NvResult::Success; |
| 282 | } | 281 | } |
| 283 | 282 | ||
| 284 | NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::vector<u8>& output) { | 283 | NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output) { |
| 285 | IocCtrlEventClearParams params{}; | 284 | IocCtrlEventClearParams params{}; |
| 286 | std::memcpy(¶ms, input.data(), sizeof(params)); | 285 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 287 | 286 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index dd2e7888a..2efed4862 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -26,11 +26,11 @@ public: | |||
| 26 | ~nvhost_ctrl() override; | 26 | ~nvhost_ctrl() override; |
| 27 | 27 | ||
| 28 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 28 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 29 | std::vector<u8>& output) override; | 29 | std::span<u8> output) override; |
| 30 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 30 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 31 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 31 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 33 | std::vector<u8>& inline_output) override; | 33 | std::span<u8> inline_output) override; |
| 34 | 34 | ||
| 35 | void OnOpen(DeviceFD fd) override; | 35 | void OnOpen(DeviceFD fd) override; |
| 36 | void OnClose(DeviceFD fd) override; | 36 | void OnClose(DeviceFD fd) override; |
| @@ -186,13 +186,12 @@ private: | |||
| 186 | static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, | 186 | static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, |
| 187 | "IocCtrlEventKill is incorrect size"); | 187 | "IocCtrlEventKill is incorrect size"); |
| 188 | 188 | ||
| 189 | NvResult NvOsGetConfigU32(std::span<const u8> input, std::vector<u8>& output); | 189 | NvResult NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output); |
| 190 | NvResult IocCtrlEventWait(std::span<const u8> input, std::vector<u8>& output, | 190 | NvResult IocCtrlEventWait(std::span<const u8> input, std::span<u8> output, bool is_allocation); |
| 191 | bool is_allocation); | 191 | NvResult IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output); |
| 192 | NvResult IocCtrlEventRegister(std::span<const u8> input, std::vector<u8>& output); | 192 | NvResult IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output); |
| 193 | NvResult IocCtrlEventUnregister(std::span<const u8> input, std::vector<u8>& output); | 193 | NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output); |
| 194 | NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::vector<u8>& output); | 194 | NvResult IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output); |
| 195 | NvResult IocCtrlClearEventWait(std::span<const u8> input, std::vector<u8>& output); | ||
| 196 | 195 | ||
| 197 | NvResult FreeEvent(u32 slot); | 196 | NvResult FreeEvent(u32 slot); |
| 198 | 197 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index be3c083db..6081d92e9 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -22,7 +22,7 @@ nvhost_ctrl_gpu::~nvhost_ctrl_gpu() { | |||
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 24 | NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 25 | std::vector<u8>& output) { | 25 | std::span<u8> output) { |
| 26 | switch (command.group) { | 26 | switch (command.group) { |
| 27 | case 'G': | 27 | case 'G': |
| 28 | switch (command.cmd) { | 28 | switch (command.cmd) { |
| @@ -54,13 +54,13 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> | |||
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 56 | NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 57 | std::span<const u8> inline_input, std::vector<u8>& output) { | 57 | std::span<const u8> inline_input, std::span<u8> output) { |
| 58 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 58 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 59 | return NvResult::NotImplemented; | 59 | return NvResult::NotImplemented; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 62 | NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 63 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 63 | std::span<u8> output, std::span<u8> inline_output) { |
| 64 | switch (command.group) { | 64 | switch (command.group) { |
| 65 | case 'G': | 65 | case 'G': |
| 66 | switch (command.cmd) { | 66 | switch (command.cmd) { |
| @@ -82,7 +82,7 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> | |||
| 82 | void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} | 82 | void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} |
| 83 | void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} | 83 | void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} |
| 84 | 84 | ||
| 85 | NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vector<u8>& output) { | 85 | NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output) { |
| 86 | LOG_DEBUG(Service_NVDRV, "called"); | 86 | LOG_DEBUG(Service_NVDRV, "called"); |
| 87 | IoctlCharacteristics params{}; | 87 | IoctlCharacteristics params{}; |
| 88 | std::memcpy(¶ms, input.data(), input.size()); | 88 | std::memcpy(¶ms, input.data(), input.size()); |
| @@ -127,8 +127,8 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vec | |||
| 127 | return NvResult::Success; | 127 | return NvResult::Success; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vector<u8>& output, | 130 | NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output, |
| 131 | std::vector<u8>& inline_output) { | 131 | std::span<u8> inline_output) { |
| 132 | LOG_DEBUG(Service_NVDRV, "called"); | 132 | LOG_DEBUG(Service_NVDRV, "called"); |
| 133 | IoctlCharacteristics params{}; | 133 | IoctlCharacteristics params{}; |
| 134 | std::memcpy(¶ms, input.data(), input.size()); | 134 | std::memcpy(¶ms, input.data(), input.size()); |
| @@ -175,7 +175,7 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vec | |||
| 175 | return NvResult::Success; | 175 | return NvResult::Success; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>& output) { | 178 | NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output) { |
| 179 | IoctlGpuGetTpcMasksArgs params{}; | 179 | IoctlGpuGetTpcMasksArgs params{}; |
| 180 | std::memcpy(¶ms, input.data(), input.size()); | 180 | std::memcpy(¶ms, input.data(), input.size()); |
| 181 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); | 181 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); |
| @@ -186,8 +186,8 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8> | |||
| 186 | return NvResult::Success; | 186 | return NvResult::Success; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>& output, | 189 | NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output, |
| 190 | std::vector<u8>& inline_output) { | 190 | std::span<u8> inline_output) { |
| 191 | IoctlGpuGetTpcMasksArgs params{}; | 191 | IoctlGpuGetTpcMasksArgs params{}; |
| 192 | std::memcpy(¶ms, input.data(), input.size()); | 192 | std::memcpy(¶ms, input.data(), input.size()); |
| 193 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); | 193 | LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); |
| @@ -199,7 +199,7 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8> | |||
| 199 | return NvResult::Success; | 199 | return NvResult::Success; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::vector<u8>& output) { | 202 | NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::span<u8> output) { |
| 203 | LOG_DEBUG(Service_NVDRV, "called"); | 203 | LOG_DEBUG(Service_NVDRV, "called"); |
| 204 | 204 | ||
| 205 | IoctlActiveSlotMask params{}; | 205 | IoctlActiveSlotMask params{}; |
| @@ -212,7 +212,7 @@ NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::vect | |||
| 212 | return NvResult::Success; | 212 | return NvResult::Success; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::vector<u8>& output) { | 215 | NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output) { |
| 216 | LOG_DEBUG(Service_NVDRV, "called"); | 216 | LOG_DEBUG(Service_NVDRV, "called"); |
| 217 | 217 | ||
| 218 | IoctlZcullGetCtxSize params{}; | 218 | IoctlZcullGetCtxSize params{}; |
| @@ -224,7 +224,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::vector | |||
| 224 | return NvResult::Success; | 224 | return NvResult::Success; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::vector<u8>& output) { | 227 | NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::span<u8> output) { |
| 228 | LOG_DEBUG(Service_NVDRV, "called"); | 228 | LOG_DEBUG(Service_NVDRV, "called"); |
| 229 | 229 | ||
| 230 | IoctlNvgpuGpuZcullGetInfoArgs params{}; | 230 | IoctlNvgpuGpuZcullGetInfoArgs params{}; |
| @@ -247,7 +247,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::vector<u8 | |||
| 247 | return NvResult::Success; | 247 | return NvResult::Success; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::vector<u8>& output) { | 250 | NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::span<u8> output) { |
| 251 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 251 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 252 | 252 | ||
| 253 | IoctlZbcSetTable params{}; | 253 | IoctlZbcSetTable params{}; |
| @@ -263,7 +263,7 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::vector<u8> | |||
| 263 | return NvResult::Success; | 263 | return NvResult::Success; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::vector<u8>& output) { | 266 | NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::span<u8> output) { |
| 267 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 267 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 268 | 268 | ||
| 269 | IoctlZbcQueryTable params{}; | 269 | IoctlZbcQueryTable params{}; |
| @@ -273,7 +273,7 @@ NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::vector<u | |||
| 273 | return NvResult::Success; | 273 | return NvResult::Success; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::vector<u8>& output) { | 276 | NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::span<u8> output) { |
| 277 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 277 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 278 | 278 | ||
| 279 | IoctlFlushL2 params{}; | 279 | IoctlFlushL2 params{}; |
| @@ -283,7 +283,7 @@ NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::vector<u8>& ou | |||
| 283 | return NvResult::Success; | 283 | return NvResult::Success; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::vector<u8>& output) { | 286 | NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::span<u8> output) { |
| 287 | LOG_DEBUG(Service_NVDRV, "called"); | 287 | LOG_DEBUG(Service_NVDRV, "called"); |
| 288 | 288 | ||
| 289 | IoctlGetGpuTime params{}; | 289 | IoctlGetGpuTime params{}; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index b9333d9d3..97995551c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | |||
| @@ -22,11 +22,11 @@ public: | |||
| 22 | ~nvhost_ctrl_gpu() override; | 22 | ~nvhost_ctrl_gpu() override; |
| 23 | 23 | ||
| 24 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 24 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 25 | std::vector<u8>& output) override; | 25 | std::span<u8> output) override; |
| 26 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 26 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 27 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 27 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 28 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 28 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 29 | std::vector<u8>& inline_output) override; | 29 | std::span<u8> inline_output) override; |
| 30 | 30 | ||
| 31 | void OnOpen(DeviceFD fd) override; | 31 | void OnOpen(DeviceFD fd) override; |
| 32 | void OnClose(DeviceFD fd) override; | 32 | void OnClose(DeviceFD fd) override; |
| @@ -151,21 +151,21 @@ private: | |||
| 151 | }; | 151 | }; |
| 152 | static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); | 152 | static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); |
| 153 | 153 | ||
| 154 | NvResult GetCharacteristics(std::span<const u8> input, std::vector<u8>& output); | 154 | NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output); |
| 155 | NvResult GetCharacteristics(std::span<const u8> input, std::vector<u8>& output, | 155 | NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output, |
| 156 | std::vector<u8>& inline_output); | 156 | std::span<u8> inline_output); |
| 157 | 157 | ||
| 158 | NvResult GetTPCMasks(std::span<const u8> input, std::vector<u8>& output); | 158 | NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output); |
| 159 | NvResult GetTPCMasks(std::span<const u8> input, std::vector<u8>& output, | 159 | NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output, |
| 160 | std::vector<u8>& inline_output); | 160 | std::span<u8> inline_output); |
| 161 | 161 | ||
| 162 | NvResult GetActiveSlotMask(std::span<const u8> input, std::vector<u8>& output); | 162 | NvResult GetActiveSlotMask(std::span<const u8> input, std::span<u8> output); |
| 163 | NvResult ZCullGetCtxSize(std::span<const u8> input, std::vector<u8>& output); | 163 | NvResult ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output); |
| 164 | NvResult ZCullGetInfo(std::span<const u8> input, std::vector<u8>& output); | 164 | NvResult ZCullGetInfo(std::span<const u8> input, std::span<u8> output); |
| 165 | NvResult ZBCSetTable(std::span<const u8> input, std::vector<u8>& output); | 165 | NvResult ZBCSetTable(std::span<const u8> input, std::span<u8> output); |
| 166 | NvResult ZBCQueryTable(std::span<const u8> input, std::vector<u8>& output); | 166 | NvResult ZBCQueryTable(std::span<const u8> input, std::span<u8> output); |
| 167 | NvResult FlushL2(std::span<const u8> input, std::vector<u8>& output); | 167 | NvResult FlushL2(std::span<const u8> input, std::span<u8> output); |
| 168 | NvResult GetGpuTime(std::span<const u8> input, std::vector<u8>& output); | 168 | NvResult GetGpuTime(std::span<const u8> input, std::span<u8> output); |
| 169 | 169 | ||
| 170 | EventInterface& events_interface; | 170 | EventInterface& events_interface; |
| 171 | 171 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 453a965dc..46a25fcab 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -47,7 +47,7 @@ nvhost_gpu::~nvhost_gpu() { | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 49 | NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 50 | std::vector<u8>& output) { | 50 | std::span<u8> output) { |
| 51 | switch (command.group) { | 51 | switch (command.group) { |
| 52 | case 0x0: | 52 | case 0x0: |
| 53 | switch (command.cmd) { | 53 | switch (command.cmd) { |
| @@ -99,7 +99,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 101 | NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 102 | std::span<const u8> inline_input, std::vector<u8>& output) { | 102 | std::span<const u8> inline_input, std::span<u8> output) { |
| 103 | switch (command.group) { | 103 | switch (command.group) { |
| 104 | case 'H': | 104 | case 'H': |
| 105 | switch (command.cmd) { | 105 | switch (command.cmd) { |
| @@ -113,7 +113,7 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 115 | NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 116 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 116 | std::span<u8> output, std::span<u8> inline_output) { |
| 117 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 117 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 118 | return NvResult::NotImplemented; | 118 | return NvResult::NotImplemented; |
| 119 | } | 119 | } |
| @@ -121,7 +121,7 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 121 | void nvhost_gpu::OnOpen(DeviceFD fd) {} | 121 | void nvhost_gpu::OnOpen(DeviceFD fd) {} |
| 122 | void nvhost_gpu::OnClose(DeviceFD fd) {} | 122 | void nvhost_gpu::OnClose(DeviceFD fd) {} |
| 123 | 123 | ||
| 124 | NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output) { | 124 | NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) { |
| 125 | IoctlSetNvmapFD params{}; | 125 | IoctlSetNvmapFD params{}; |
| 126 | std::memcpy(¶ms, input.data(), input.size()); | 126 | std::memcpy(¶ms, input.data(), input.size()); |
| 127 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 127 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| @@ -130,7 +130,7 @@ NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& outp | |||
| 130 | return NvResult::Success; | 130 | return NvResult::Success; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::vector<u8>& output) { | 133 | NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::span<u8> output) { |
| 134 | LOG_DEBUG(Service_NVDRV, "called"); | 134 | LOG_DEBUG(Service_NVDRV, "called"); |
| 135 | 135 | ||
| 136 | IoctlClientData params{}; | 136 | IoctlClientData params{}; |
| @@ -139,7 +139,7 @@ NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::vector<u8>& o | |||
| 139 | return NvResult::Success; | 139 | return NvResult::Success; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::vector<u8>& output) { | 142 | NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::span<u8> output) { |
| 143 | LOG_DEBUG(Service_NVDRV, "called"); | 143 | LOG_DEBUG(Service_NVDRV, "called"); |
| 144 | 144 | ||
| 145 | IoctlClientData params{}; | 145 | IoctlClientData params{}; |
| @@ -149,7 +149,7 @@ NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::vector<u8>& o | |||
| 149 | return NvResult::Success; | 149 | return NvResult::Success; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::vector<u8>& output) { | 152 | NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::span<u8> output) { |
| 153 | std::memcpy(&zcull_params, input.data(), input.size()); | 153 | std::memcpy(&zcull_params, input.data(), input.size()); |
| 154 | LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, | 154 | LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, |
| 155 | zcull_params.mode); | 155 | zcull_params.mode); |
| @@ -158,7 +158,7 @@ NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::vector<u8>& outpu | |||
| 158 | return NvResult::Success; | 158 | return NvResult::Success; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::vector<u8>& output) { | 161 | NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::span<u8> output) { |
| 162 | IoctlSetErrorNotifier params{}; | 162 | IoctlSetErrorNotifier params{}; |
| 163 | std::memcpy(¶ms, input.data(), input.size()); | 163 | std::memcpy(¶ms, input.data(), input.size()); |
| 164 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, | 164 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, |
| @@ -168,14 +168,14 @@ NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::vector<u8> | |||
| 168 | return NvResult::Success; | 168 | return NvResult::Success; |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::vector<u8>& output) { | 171 | NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::span<u8> output) { |
| 172 | std::memcpy(&channel_priority, input.data(), input.size()); | 172 | std::memcpy(&channel_priority, input.data(), input.size()); |
| 173 | LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); | 173 | LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); |
| 174 | 174 | ||
| 175 | return NvResult::Success; | 175 | return NvResult::Success; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& output) { | 178 | NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output) { |
| 179 | IoctlAllocGpfifoEx2 params{}; | 179 | IoctlAllocGpfifoEx2 params{}; |
| 180 | std::memcpy(¶ms, input.data(), input.size()); | 180 | std::memcpy(¶ms, input.data(), input.size()); |
| 181 | LOG_WARNING(Service_NVDRV, | 181 | LOG_WARNING(Service_NVDRV, |
| @@ -197,7 +197,7 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& | |||
| 197 | return NvResult::Success; | 197 | return NvResult::Success; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::vector<u8>& output) { | 200 | NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::span<u8> output) { |
| 201 | IoctlAllocObjCtx params{}; | 201 | IoctlAllocObjCtx params{}; |
| 202 | std::memcpy(¶ms, input.data(), input.size()); | 202 | std::memcpy(¶ms, input.data(), input.size()); |
| 203 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, | 203 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, |
| @@ -208,7 +208,8 @@ NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::vecto | |||
| 208 | return NvResult::Success; | 208 | return NvResult::Success; |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) { | 211 | static boost::container::small_vector<Tegra::CommandHeader, 512> BuildWaitCommandList( |
| 212 | NvFence fence) { | ||
| 212 | return { | 213 | return { |
| 213 | Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1, | 214 | Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1, |
| 214 | Tegra::SubmissionMode::Increasing), | 215 | Tegra::SubmissionMode::Increasing), |
| @@ -219,35 +220,35 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) { | |||
| 219 | }; | 220 | }; |
| 220 | } | 221 | } |
| 221 | 222 | ||
| 222 | static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence) { | 223 | static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementCommandList( |
| 223 | std::vector<Tegra::CommandHeader> result{ | 224 | NvFence fence) { |
| 225 | boost::container::small_vector<Tegra::CommandHeader, 512> result{ | ||
| 224 | Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1, | 226 | Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1, |
| 225 | Tegra::SubmissionMode::Increasing), | 227 | Tegra::SubmissionMode::Increasing), |
| 226 | {}}; | 228 | {}}; |
| 227 | 229 | ||
| 228 | for (u32 count = 0; count < 2; ++count) { | 230 | for (u32 count = 0; count < 2; ++count) { |
| 229 | result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1, | 231 | result.push_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1, |
| 230 | Tegra::SubmissionMode::Increasing)); | 232 | Tegra::SubmissionMode::Increasing)); |
| 231 | result.emplace_back( | 233 | result.push_back( |
| 232 | BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id)); | 234 | BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id)); |
| 233 | } | 235 | } |
| 234 | 236 | ||
| 235 | return result; | 237 | return result; |
| 236 | } | 238 | } |
| 237 | 239 | ||
| 238 | static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence) { | 240 | static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementWithWfiCommandList( |
| 239 | std::vector<Tegra::CommandHeader> result{ | 241 | NvFence fence) { |
| 242 | boost::container::small_vector<Tegra::CommandHeader, 512> result{ | ||
| 240 | Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1, | 243 | Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1, |
| 241 | Tegra::SubmissionMode::Increasing), | 244 | Tegra::SubmissionMode::Increasing), |
| 242 | {}}; | 245 | {}}; |
| 243 | const std::vector<Tegra::CommandHeader> increment{BuildIncrementCommandList(fence)}; | 246 | auto increment_list{BuildIncrementCommandList(fence)}; |
| 244 | 247 | result.insert(result.end(), increment_list.begin(), increment_list.end()); | |
| 245 | result.insert(result.end(), increment.begin(), increment.end()); | ||
| 246 | |||
| 247 | return result; | 248 | return result; |
| 248 | } | 249 | } |
| 249 | 250 | ||
| 250 | NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output, | 251 | NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output, |
| 251 | Tegra::CommandList&& entries) { | 252 | Tegra::CommandList&& entries) { |
| 252 | LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, | 253 | LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, |
| 253 | params.num_entries, params.flags.raw); | 254 | params.num_entries, params.flags.raw); |
| @@ -293,7 +294,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8> | |||
| 293 | return NvResult::Success; | 294 | return NvResult::Success; |
| 294 | } | 295 | } |
| 295 | 296 | ||
| 296 | NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>& output, | 297 | NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output, |
| 297 | bool kickoff) { | 298 | bool kickoff) { |
| 298 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { | 299 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { |
| 299 | UNIMPLEMENTED(); | 300 | UNIMPLEMENTED(); |
| @@ -315,7 +316,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8> | |||
| 315 | } | 316 | } |
| 316 | 317 | ||
| 317 | NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, | 318 | NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, |
| 318 | std::vector<u8>& output) { | 319 | std::span<u8> output) { |
| 319 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { | 320 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { |
| 320 | UNIMPLEMENTED(); | 321 | UNIMPLEMENTED(); |
| 321 | return NvResult::InvalidSize; | 322 | return NvResult::InvalidSize; |
| @@ -327,7 +328,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const | |||
| 327 | return SubmitGPFIFOImpl(params, output, std::move(entries)); | 328 | return SubmitGPFIFOImpl(params, output, std::move(entries)); |
| 328 | } | 329 | } |
| 329 | 330 | ||
| 330 | NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::vector<u8>& output) { | 331 | NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::span<u8> output) { |
| 331 | IoctlGetWaitbase params{}; | 332 | IoctlGetWaitbase params{}; |
| 332 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); | 333 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); |
| 333 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); | 334 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); |
| @@ -337,7 +338,7 @@ NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::vector<u8>& out | |||
| 337 | return NvResult::Success; | 338 | return NvResult::Success; |
| 338 | } | 339 | } |
| 339 | 340 | ||
| 340 | NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::vector<u8>& output) { | 341 | NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::span<u8> output) { |
| 341 | IoctlChannelSetTimeout params{}; | 342 | IoctlChannelSetTimeout params{}; |
| 342 | std::memcpy(¶ms, input.data(), sizeof(IoctlChannelSetTimeout)); | 343 | std::memcpy(¶ms, input.data(), sizeof(IoctlChannelSetTimeout)); |
| 343 | LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); | 344 | LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); |
| @@ -345,7 +346,7 @@ NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::vector<u8 | |||
| 345 | return NvResult::Success; | 346 | return NvResult::Success; |
| 346 | } | 347 | } |
| 347 | 348 | ||
| 348 | NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::vector<u8>& output) { | 349 | NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output) { |
| 349 | IoctlSetTimeslice params{}; | 350 | IoctlSetTimeslice params{}; |
| 350 | std::memcpy(¶ms, input.data(), sizeof(IoctlSetTimeslice)); | 351 | std::memcpy(¶ms, input.data(), sizeof(IoctlSetTimeslice)); |
| 351 | LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); | 352 | LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 3ca58202d..529c20526 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -41,11 +41,11 @@ public: | |||
| 41 | ~nvhost_gpu() override; | 41 | ~nvhost_gpu() override; |
| 42 | 42 | ||
| 43 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 43 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 44 | std::vector<u8>& output) override; | 44 | std::span<u8> output) override; |
| 45 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 45 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 46 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 46 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 47 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 47 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 48 | std::vector<u8>& inline_output) override; | 48 | std::span<u8> inline_output) override; |
| 49 | 49 | ||
| 50 | void OnOpen(DeviceFD fd) override; | 50 | void OnOpen(DeviceFD fd) override; |
| 51 | void OnClose(DeviceFD fd) override; | 51 | void OnClose(DeviceFD fd) override; |
| @@ -186,23 +186,23 @@ private: | |||
| 186 | u32_le channel_priority{}; | 186 | u32_le channel_priority{}; |
| 187 | u32_le channel_timeslice{}; | 187 | u32_le channel_timeslice{}; |
| 188 | 188 | ||
| 189 | NvResult SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output); | 189 | NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output); |
| 190 | NvResult SetClientData(std::span<const u8> input, std::vector<u8>& output); | 190 | NvResult SetClientData(std::span<const u8> input, std::span<u8> output); |
| 191 | NvResult GetClientData(std::span<const u8> input, std::vector<u8>& output); | 191 | NvResult GetClientData(std::span<const u8> input, std::span<u8> output); |
| 192 | NvResult ZCullBind(std::span<const u8> input, std::vector<u8>& output); | 192 | NvResult ZCullBind(std::span<const u8> input, std::span<u8> output); |
| 193 | NvResult SetErrorNotifier(std::span<const u8> input, std::vector<u8>& output); | 193 | NvResult SetErrorNotifier(std::span<const u8> input, std::span<u8> output); |
| 194 | NvResult SetChannelPriority(std::span<const u8> input, std::vector<u8>& output); | 194 | NvResult SetChannelPriority(std::span<const u8> input, std::span<u8> output); |
| 195 | NvResult AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& output); | 195 | NvResult AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output); |
| 196 | NvResult AllocateObjectContext(std::span<const u8> input, std::vector<u8>& output); | 196 | NvResult AllocateObjectContext(std::span<const u8> input, std::span<u8> output); |
| 197 | NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output, | 197 | NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output, |
| 198 | Tegra::CommandList&& entries); | 198 | Tegra::CommandList&& entries); |
| 199 | NvResult SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>& output, | 199 | NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output, |
| 200 | bool kickoff = false); | 200 | bool kickoff = false); |
| 201 | NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, | 201 | NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, |
| 202 | std::vector<u8>& output); | 202 | std::span<u8> output); |
| 203 | NvResult GetWaitbase(std::span<const u8> input, std::vector<u8>& output); | 203 | NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output); |
| 204 | NvResult ChannelSetTimeout(std::span<const u8> input, std::vector<u8>& output); | 204 | NvResult ChannelSetTimeout(std::span<const u8> input, std::span<u8> output); |
| 205 | NvResult ChannelSetTimeslice(std::span<const u8> input, std::vector<u8>& output); | 205 | NvResult ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output); |
| 206 | 206 | ||
| 207 | EventInterface& events_interface; | 207 | EventInterface& events_interface; |
| 208 | NvCore::Container& core; | 208 | NvCore::Container& core; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index dc45169ad..a174442a6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -16,7 +16,7 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system_, NvCore::Container& core_) | |||
| 16 | nvhost_nvdec::~nvhost_nvdec() = default; | 16 | nvhost_nvdec::~nvhost_nvdec() = default; |
| 17 | 17 | ||
| 18 | NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 18 | NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 19 | std::vector<u8>& output) { | 19 | std::span<u8> output) { |
| 20 | switch (command.group) { | 20 | switch (command.group) { |
| 21 | case 0x0: | 21 | case 0x0: |
| 22 | switch (command.cmd) { | 22 | switch (command.cmd) { |
| @@ -56,13 +56,13 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 58 | NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 59 | std::span<const u8> inline_input, std::vector<u8>& output) { | 59 | std::span<const u8> inline_input, std::span<u8> output) { |
| 60 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 60 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 61 | return NvResult::NotImplemented; | 61 | return NvResult::NotImplemented; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 64 | NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 65 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 65 | std::span<u8> output, std::span<u8> inline_output) { |
| 66 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 66 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 67 | return NvResult::NotImplemented; | 67 | return NvResult::NotImplemented; |
| 68 | } | 68 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 0d615bbcb..ad2233c49 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -14,11 +14,11 @@ public: | |||
| 14 | ~nvhost_nvdec() override; | 14 | ~nvhost_nvdec() override; |
| 15 | 15 | ||
| 16 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 16 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 17 | std::vector<u8>& output) override; | 17 | std::span<u8> output) override; |
| 18 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 18 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 19 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 19 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 20 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 20 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 21 | std::vector<u8>& inline_output) override; | 21 | std::span<u8> inline_output) override; |
| 22 | 22 | ||
| 23 | void OnOpen(DeviceFD fd) override; | 23 | void OnOpen(DeviceFD fd) override; |
| 24 | void OnClose(DeviceFD fd) override; | 24 | void OnClose(DeviceFD fd) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 1ab51f10b..61649aa4a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -36,7 +36,7 @@ std::size_t SliceVectors(std::span<const u8> input, std::vector<T>& dst, std::si | |||
| 36 | // Writes the data in src to an offset into the dst vector. The offset is specified in bytes | 36 | // Writes the data in src to an offset into the dst vector. The offset is specified in bytes |
| 37 | // Returns the number of bytes written into dst. | 37 | // Returns the number of bytes written into dst. |
| 38 | template <typename T> | 38 | template <typename T> |
| 39 | std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) { | 39 | std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size_t offset) { |
| 40 | if (src.empty()) { | 40 | if (src.empty()) { |
| 41 | return 0; | 41 | return 0; |
| 42 | } | 42 | } |
| @@ -72,8 +72,7 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(std::span<const u8> input) { | |||
| 72 | return NvResult::Success; | 72 | return NvResult::Success; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, | 75 | NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output) { |
| 76 | std::vector<u8>& output) { | ||
| 77 | IoctlSubmit params{}; | 76 | IoctlSubmit params{}; |
| 78 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | 77 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); |
| 79 | LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); | 78 | LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); |
| @@ -121,7 +120,7 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, | |||
| 121 | return NvResult::Success; | 120 | return NvResult::Success; |
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::vector<u8>& output) { | 123 | NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::span<u8> output) { |
| 125 | IoctlGetSyncpoint params{}; | 124 | IoctlGetSyncpoint params{}; |
| 126 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | 125 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); |
| 127 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); | 126 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); |
| @@ -133,7 +132,7 @@ NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::vecto | |||
| 133 | return NvResult::Success; | 132 | return NvResult::Success; |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::vector<u8>& output) { | 135 | NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::span<u8> output) { |
| 137 | IoctlGetWaitbase params{}; | 136 | IoctlGetWaitbase params{}; |
| 138 | LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); | 137 | LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); |
| 139 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); | 138 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); |
| @@ -142,7 +141,7 @@ NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::vector | |||
| 142 | return NvResult::Success; | 141 | return NvResult::Success; |
| 143 | } | 142 | } |
| 144 | 143 | ||
| 145 | NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::vector<u8>& output) { | 144 | NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::span<u8> output) { |
| 146 | IoctlMapBuffer params{}; | 145 | IoctlMapBuffer params{}; |
| 147 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); | 146 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); |
| 148 | std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); | 147 | std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); |
| @@ -159,7 +158,7 @@ NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::vector<u | |||
| 159 | return NvResult::Success; | 158 | return NvResult::Success; |
| 160 | } | 159 | } |
| 161 | 160 | ||
| 162 | NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::vector<u8>& output) { | 161 | NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::span<u8> output) { |
| 163 | IoctlMapBuffer params{}; | 162 | IoctlMapBuffer params{}; |
| 164 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); | 163 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); |
| 165 | std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); | 164 | std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); |
| @@ -173,7 +172,7 @@ NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::vector | |||
| 173 | return NvResult::Success; | 172 | return NvResult::Success; |
| 174 | } | 173 | } |
| 175 | 174 | ||
| 176 | NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::vector<u8>& output) { | 175 | NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::span<u8> output) { |
| 177 | std::memcpy(&submit_timeout, input.data(), input.size()); | 176 | std::memcpy(&submit_timeout, input.data(), input.size()); |
| 178 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 177 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 179 | return NvResult::Success; | 178 | return NvResult::Success; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 5af26a26f..9bb573bfe 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h | |||
| @@ -108,12 +108,12 @@ protected: | |||
| 108 | 108 | ||
| 109 | /// Ioctl command implementations | 109 | /// Ioctl command implementations |
| 110 | NvResult SetNVMAPfd(std::span<const u8> input); | 110 | NvResult SetNVMAPfd(std::span<const u8> input); |
| 111 | NvResult Submit(DeviceFD fd, std::span<const u8> input, std::vector<u8>& output); | 111 | NvResult Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output); |
| 112 | NvResult GetSyncpoint(std::span<const u8> input, std::vector<u8>& output); | 112 | NvResult GetSyncpoint(std::span<const u8> input, std::span<u8> output); |
| 113 | NvResult GetWaitbase(std::span<const u8> input, std::vector<u8>& output); | 113 | NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output); |
| 114 | NvResult MapBuffer(std::span<const u8> input, std::vector<u8>& output); | 114 | NvResult MapBuffer(std::span<const u8> input, std::span<u8> output); |
| 115 | NvResult UnmapBuffer(std::span<const u8> input, std::vector<u8>& output); | 115 | NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output); |
| 116 | NvResult SetSubmitTimeout(std::span<const u8> input, std::vector<u8>& output); | 116 | NvResult SetSubmitTimeout(std::span<const u8> input, std::span<u8> output); |
| 117 | 117 | ||
| 118 | Kernel::KEvent* QueryEvent(u32 event_id) override; | 118 | Kernel::KEvent* QueryEvent(u32 event_id) override; |
| 119 | 119 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index 39f30e7c8..a05c8cdae 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp | |||
| @@ -13,7 +13,7 @@ nvhost_nvjpg::nvhost_nvjpg(Core::System& system_) : nvdevice{system_} {} | |||
| 13 | nvhost_nvjpg::~nvhost_nvjpg() = default; | 13 | nvhost_nvjpg::~nvhost_nvjpg() = default; |
| 14 | 14 | ||
| 15 | NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 15 | NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 16 | std::vector<u8>& output) { | 16 | std::span<u8> output) { |
| 17 | switch (command.group) { | 17 | switch (command.group) { |
| 18 | case 'H': | 18 | case 'H': |
| 19 | switch (command.cmd) { | 19 | switch (command.cmd) { |
| @@ -32,13 +32,13 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 34 | NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 35 | std::span<const u8> inline_input, std::vector<u8>& output) { | 35 | std::span<const u8> inline_input, std::span<u8> output) { |
| 36 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 36 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 37 | return NvResult::NotImplemented; | 37 | return NvResult::NotImplemented; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 40 | NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 41 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 41 | std::span<u8> output, std::span<u8> inline_output) { |
| 42 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 42 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 43 | return NvResult::NotImplemented; | 43 | return NvResult::NotImplemented; |
| 44 | } | 44 | } |
| @@ -46,7 +46,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 46 | void nvhost_nvjpg::OnOpen(DeviceFD fd) {} | 46 | void nvhost_nvjpg::OnOpen(DeviceFD fd) {} |
| 47 | void nvhost_nvjpg::OnClose(DeviceFD fd) {} | 47 | void nvhost_nvjpg::OnClose(DeviceFD fd) {} |
| 48 | 48 | ||
| 49 | NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output) { | 49 | NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) { |
| 50 | IoctlSetNvmapFD params{}; | 50 | IoctlSetNvmapFD params{}; |
| 51 | std::memcpy(¶ms, input.data(), input.size()); | 51 | std::memcpy(¶ms, input.data(), input.size()); |
| 52 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 52 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 41b57e872..5623e0d47 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h | |||
| @@ -16,11 +16,11 @@ public: | |||
| 16 | ~nvhost_nvjpg() override; | 16 | ~nvhost_nvjpg() override; |
| 17 | 17 | ||
| 18 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 18 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 19 | std::vector<u8>& output) override; | 19 | std::span<u8> output) override; |
| 20 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 20 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 21 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 21 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 22 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 22 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 23 | std::vector<u8>& inline_output) override; | 23 | std::span<u8> inline_output) override; |
| 24 | 24 | ||
| 25 | void OnOpen(DeviceFD fd) override; | 25 | void OnOpen(DeviceFD fd) override; |
| 26 | void OnClose(DeviceFD fd) override; | 26 | void OnClose(DeviceFD fd) override; |
| @@ -33,7 +33,7 @@ private: | |||
| 33 | 33 | ||
| 34 | s32_le nvmap_fd{}; | 34 | s32_le nvmap_fd{}; |
| 35 | 35 | ||
| 36 | NvResult SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output); | 36 | NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output); |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | } // namespace Service::Nvidia::Devices | 39 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index b0ea402a7..c0b8684c3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -16,7 +16,7 @@ nvhost_vic::nvhost_vic(Core::System& system_, NvCore::Container& core_) | |||
| 16 | nvhost_vic::~nvhost_vic() = default; | 16 | nvhost_vic::~nvhost_vic() = default; |
| 17 | 17 | ||
| 18 | NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 18 | NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 19 | std::vector<u8>& output) { | 19 | std::span<u8> output) { |
| 20 | switch (command.group) { | 20 | switch (command.group) { |
| 21 | case 0x0: | 21 | case 0x0: |
| 22 | switch (command.cmd) { | 22 | switch (command.cmd) { |
| @@ -56,13 +56,13 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 58 | NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 59 | std::span<const u8> inline_input, std::vector<u8>& output) { | 59 | std::span<const u8> inline_input, std::span<u8> output) { |
| 60 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 60 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 61 | return NvResult::NotImplemented; | 61 | return NvResult::NotImplemented; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 64 | NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 65 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 65 | std::span<u8> output, std::span<u8> inline_output) { |
| 66 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 66 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 67 | return NvResult::NotImplemented; | 67 | return NvResult::NotImplemented; |
| 68 | } | 68 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index b5e350a83..cadbcb0a5 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -13,11 +13,11 @@ public: | |||
| 13 | ~nvhost_vic(); | 13 | ~nvhost_vic(); |
| 14 | 14 | ||
| 15 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 15 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 16 | std::vector<u8>& output) override; | 16 | std::span<u8> output) override; |
| 17 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 17 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 18 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 18 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 19 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 19 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 20 | std::vector<u8>& inline_output) override; | 20 | std::span<u8> inline_output) override; |
| 21 | 21 | ||
| 22 | void OnOpen(DeviceFD fd) override; | 22 | void OnOpen(DeviceFD fd) override; |
| 23 | void OnClose(DeviceFD fd) override; | 23 | void OnClose(DeviceFD fd) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 07417f045..e7f7e273b 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -26,7 +26,7 @@ nvmap::nvmap(Core::System& system_, NvCore::Container& container_) | |||
| 26 | nvmap::~nvmap() = default; | 26 | nvmap::~nvmap() = default; |
| 27 | 27 | ||
| 28 | NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 28 | NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 29 | std::vector<u8>& output) { | 29 | std::span<u8> output) { |
| 30 | switch (command.group) { | 30 | switch (command.group) { |
| 31 | case 0x1: | 31 | case 0x1: |
| 32 | switch (command.cmd) { | 32 | switch (command.cmd) { |
| @@ -55,13 +55,13 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 57 | NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 58 | std::span<const u8> inline_input, std::vector<u8>& output) { | 58 | std::span<const u8> inline_input, std::span<u8> output) { |
| 59 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 59 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 60 | return NvResult::NotImplemented; | 60 | return NvResult::NotImplemented; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 63 | NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 64 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 64 | std::span<u8> inline_output) { |
| 65 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); | 65 | UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); |
| 66 | return NvResult::NotImplemented; | 66 | return NvResult::NotImplemented; |
| 67 | } | 67 | } |
| @@ -69,7 +69,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | |||
| 69 | void nvmap::OnOpen(DeviceFD fd) {} | 69 | void nvmap::OnOpen(DeviceFD fd) {} |
| 70 | void nvmap::OnClose(DeviceFD fd) {} | 70 | void nvmap::OnClose(DeviceFD fd) {} |
| 71 | 71 | ||
| 72 | NvResult nvmap::IocCreate(std::span<const u8> input, std::vector<u8>& output) { | 72 | NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) { |
| 73 | IocCreateParams params; | 73 | IocCreateParams params; |
| 74 | std::memcpy(¶ms, input.data(), sizeof(params)); | 74 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 75 | LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); | 75 | LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); |
| @@ -89,7 +89,7 @@ NvResult nvmap::IocCreate(std::span<const u8> input, std::vector<u8>& output) { | |||
| 89 | return NvResult::Success; | 89 | return NvResult::Success; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | NvResult nvmap::IocAlloc(std::span<const u8> input, std::vector<u8>& output) { | 92 | NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) { |
| 93 | IocAllocParams params; | 93 | IocAllocParams params; |
| 94 | std::memcpy(¶ms, input.data(), sizeof(params)); | 94 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 95 | LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); | 95 | LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); |
| @@ -137,7 +137,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::vector<u8>& output) { | |||
| 137 | return result; | 137 | return result; |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | NvResult nvmap::IocGetId(std::span<const u8> input, std::vector<u8>& output) { | 140 | NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) { |
| 141 | IocGetIdParams params; | 141 | IocGetIdParams params; |
| 142 | std::memcpy(¶ms, input.data(), sizeof(params)); | 142 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 143 | 143 | ||
| @@ -161,7 +161,7 @@ NvResult nvmap::IocGetId(std::span<const u8> input, std::vector<u8>& output) { | |||
| 161 | return NvResult::Success; | 161 | return NvResult::Success; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | NvResult nvmap::IocFromId(std::span<const u8> input, std::vector<u8>& output) { | 164 | NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) { |
| 165 | IocFromIdParams params; | 165 | IocFromIdParams params; |
| 166 | std::memcpy(¶ms, input.data(), sizeof(params)); | 166 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 167 | 167 | ||
| @@ -192,7 +192,7 @@ NvResult nvmap::IocFromId(std::span<const u8> input, std::vector<u8>& output) { | |||
| 192 | return NvResult::Success; | 192 | return NvResult::Success; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | NvResult nvmap::IocParam(std::span<const u8> input, std::vector<u8>& output) { | 195 | NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) { |
| 196 | enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; | 196 | enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; |
| 197 | 197 | ||
| 198 | IocParamParams params; | 198 | IocParamParams params; |
| @@ -241,7 +241,7 @@ NvResult nvmap::IocParam(std::span<const u8> input, std::vector<u8>& output) { | |||
| 241 | return NvResult::Success; | 241 | return NvResult::Success; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | NvResult nvmap::IocFree(std::span<const u8> input, std::vector<u8>& output) { | 244 | NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) { |
| 245 | IocFreeParams params; | 245 | IocFreeParams params; |
| 246 | std::memcpy(¶ms, input.data(), sizeof(params)); | 246 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 247 | 247 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index 82bd3b118..40c65b430 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -27,11 +27,11 @@ public: | |||
| 27 | nvmap& operator=(const nvmap&) = delete; | 27 | nvmap& operator=(const nvmap&) = delete; |
| 28 | 28 | ||
| 29 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 29 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 30 | std::vector<u8>& output) override; | 30 | std::span<u8> output) override; |
| 31 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 31 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 32 | std::span<const u8> inline_input, std::vector<u8>& output) override; | 32 | std::span<const u8> inline_input, std::span<u8> output) override; |
| 33 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 33 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 34 | std::vector<u8>& inline_output) override; | 34 | std::span<u8> inline_output) override; |
| 35 | 35 | ||
| 36 | void OnOpen(DeviceFD fd) override; | 36 | void OnOpen(DeviceFD fd) override; |
| 37 | void OnClose(DeviceFD fd) override; | 37 | void OnClose(DeviceFD fd) override; |
| @@ -106,12 +106,12 @@ private: | |||
| 106 | }; | 106 | }; |
| 107 | static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); | 107 | static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); |
| 108 | 108 | ||
| 109 | NvResult IocCreate(std::span<const u8> input, std::vector<u8>& output); | 109 | NvResult IocCreate(std::span<const u8> input, std::span<u8> output); |
| 110 | NvResult IocAlloc(std::span<const u8> input, std::vector<u8>& output); | 110 | NvResult IocAlloc(std::span<const u8> input, std::span<u8> output); |
| 111 | NvResult IocGetId(std::span<const u8> input, std::vector<u8>& output); | 111 | NvResult IocGetId(std::span<const u8> input, std::span<u8> output); |
| 112 | NvResult IocFromId(std::span<const u8> input, std::vector<u8>& output); | 112 | NvResult IocFromId(std::span<const u8> input, std::span<u8> output); |
| 113 | NvResult IocParam(std::span<const u8> input, std::vector<u8>& output); | 113 | NvResult IocParam(std::span<const u8> input, std::span<u8> output); |
| 114 | NvResult IocFree(std::span<const u8> input, std::vector<u8>& output); | 114 | NvResult IocFree(std::span<const u8> input, std::span<u8> output); |
| 115 | 115 | ||
| 116 | NvCore::Container& container; | 116 | NvCore::Container& container; |
| 117 | NvCore::NvMap& file; | 117 | NvCore::NvMap& file; |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 3d774eec4..9e46ee8dd 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -130,7 +130,7 @@ DeviceFD Module::Open(const std::string& device_name) { | |||
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | 132 | NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 133 | std::vector<u8>& output) { | 133 | std::span<u8> output) { |
| 134 | if (fd < 0) { | 134 | if (fd < 0) { |
| 135 | LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); | 135 | LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); |
| 136 | return NvResult::InvalidState; | 136 | return NvResult::InvalidState; |
| @@ -147,7 +147,7 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | |||
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 149 | NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 150 | std::span<const u8> inline_input, std::vector<u8>& output) { | 150 | std::span<const u8> inline_input, std::span<u8> output) { |
| 151 | if (fd < 0) { | 151 | if (fd < 0) { |
| 152 | LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); | 152 | LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); |
| 153 | return NvResult::InvalidState; | 153 | return NvResult::InvalidState; |
| @@ -163,8 +163,8 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | |||
| 163 | return itr->second->Ioctl2(fd, command, input, inline_input, output); | 163 | return itr->second->Ioctl2(fd, command, input, inline_input, output); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, | 166 | NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 167 | std::vector<u8>& output, std::vector<u8>& inline_output) { | 167 | std::span<u8> inline_output) { |
| 168 | if (fd < 0) { | 168 | if (fd < 0) { |
| 169 | LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); | 169 | LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); |
| 170 | return NvResult::InvalidState; | 170 | return NvResult::InvalidState; |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 668be742b..d8622b3ca 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -80,13 +80,13 @@ public: | |||
| 80 | DeviceFD Open(const std::string& device_name); | 80 | DeviceFD Open(const std::string& device_name); |
| 81 | 81 | ||
| 82 | /// Sends an ioctl command to the specified file descriptor. | 82 | /// Sends an ioctl command to the specified file descriptor. |
| 83 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output); | 83 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output); |
| 84 | 84 | ||
| 85 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, | 85 | NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, |
| 86 | std::span<const u8> inline_input, std::vector<u8>& output); | 86 | std::span<const u8> inline_input, std::span<u8> output); |
| 87 | 87 | ||
| 88 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, | 88 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 89 | std::vector<u8>& inline_output); | 89 | std::span<u8> inline_output); |
| 90 | 90 | ||
| 91 | /// Closes a device file descriptor and returns operation success. | 91 | /// Closes a device file descriptor and returns operation success. |
| 92 | NvResult Close(DeviceFD fd); | 92 | NvResult Close(DeviceFD fd); |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index d010a1e03..348207e25 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp | |||
| @@ -63,12 +63,12 @@ void NVDRV::Ioctl1(HLERequestContext& ctx) { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | // Check device | 65 | // Check device |
| 66 | std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); | 66 | tmp_output.resize_destructive(ctx.GetWriteBufferSize(0)); |
| 67 | const auto input_buffer = ctx.ReadBuffer(0); | 67 | const auto input_buffer = ctx.ReadBuffer(0); |
| 68 | 68 | ||
| 69 | const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer); | 69 | const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output); |
| 70 | if (command.is_out != 0) { | 70 | if (command.is_out != 0) { |
| 71 | ctx.WriteBuffer(output_buffer); | 71 | ctx.WriteBuffer(tmp_output); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | IPC::ResponseBuilder rb{ctx, 3}; | 74 | IPC::ResponseBuilder rb{ctx, 3}; |
| @@ -90,12 +90,12 @@ void NVDRV::Ioctl2(HLERequestContext& ctx) { | |||
| 90 | 90 | ||
| 91 | const auto input_buffer = ctx.ReadBuffer(0); | 91 | const auto input_buffer = ctx.ReadBuffer(0); |
| 92 | const auto input_inlined_buffer = ctx.ReadBuffer(1); | 92 | const auto input_inlined_buffer = ctx.ReadBuffer(1); |
| 93 | std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); | 93 | tmp_output.resize_destructive(ctx.GetWriteBufferSize(0)); |
| 94 | 94 | ||
| 95 | const auto nv_result = | 95 | const auto nv_result = |
| 96 | nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer); | 96 | nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, tmp_output); |
| 97 | if (command.is_out != 0) { | 97 | if (command.is_out != 0) { |
| 98 | ctx.WriteBuffer(output_buffer); | 98 | ctx.WriteBuffer(tmp_output); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | IPC::ResponseBuilder rb{ctx, 3}; | 101 | IPC::ResponseBuilder rb{ctx, 3}; |
| @@ -116,14 +116,12 @@ void NVDRV::Ioctl3(HLERequestContext& ctx) { | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | const auto input_buffer = ctx.ReadBuffer(0); | 118 | const auto input_buffer = ctx.ReadBuffer(0); |
| 119 | std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); | 119 | tmp_output.resize_destructive(ctx.GetWriteBufferSize(0)); |
| 120 | std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1)); | 120 | tmp_output_inline.resize_destructive(ctx.GetWriteBufferSize(1)); |
| 121 | 121 | const auto nv_result = nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output_inline); | |
| 122 | const auto nv_result = | ||
| 123 | nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline); | ||
| 124 | if (command.is_out != 0) { | 122 | if (command.is_out != 0) { |
| 125 | ctx.WriteBuffer(output_buffer, 0); | 123 | ctx.WriteBuffer(tmp_output, 0); |
| 126 | ctx.WriteBuffer(output_buffer_inline, 1); | 124 | ctx.WriteBuffer(tmp_output_inline, 1); |
| 127 | } | 125 | } |
| 128 | 126 | ||
| 129 | IPC::ResponseBuilder rb{ctx, 3}; | 127 | IPC::ResponseBuilder rb{ctx, 3}; |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h index 881ea1a6b..4b593ff90 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.h +++ b/src/core/hle/service/nvdrv/nvdrv_interface.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include "common/scratch_buffer.h" | ||
| 7 | #include "core/hle/service/nvdrv/nvdrv.h" | 8 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 8 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 9 | 10 | ||
| @@ -33,6 +34,8 @@ private: | |||
| 33 | 34 | ||
| 34 | u64 pid{}; | 35 | u64 pid{}; |
| 35 | bool is_initialized{}; | 36 | bool is_initialized{}; |
| 37 | Common::ScratchBuffer<u8> tmp_output; | ||
| 38 | Common::ScratchBuffer<u8> tmp_output_inline; | ||
| 36 | }; | 39 | }; |
| 37 | 40 | ||
| 38 | } // namespace Service::Nvidia | 41 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp index da2d5890f..5f55cd31e 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.cpp +++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp | |||
| @@ -43,14 +43,10 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) { | |||
| 43 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | 43 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); |
| 44 | 44 | ||
| 45 | while (!stop_token.stop_requested()) { | 45 | while (!stop_token.stop_requested()) { |
| 46 | vsync_signal.wait(false); | 46 | vsync_signal.Wait(); |
| 47 | vsync_signal.store(false); | ||
| 48 | |||
| 49 | guard->lock(); | ||
| 50 | 47 | ||
| 48 | const auto lock_guard = Lock(); | ||
| 51 | Compose(); | 49 | Compose(); |
| 52 | |||
| 53 | guard->unlock(); | ||
| 54 | } | 50 | } |
| 55 | } | 51 | } |
| 56 | 52 | ||
| @@ -69,8 +65,8 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_ | |||
| 69 | "ScreenComposition", | 65 | "ScreenComposition", |
| 70 | [this](std::uintptr_t, s64 time, | 66 | [this](std::uintptr_t, s64 time, |
| 71 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | 67 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { |
| 72 | vsync_signal.store(true); | 68 | { const auto lock_guard = Lock(); } |
| 73 | vsync_signal.notify_all(); | 69 | vsync_signal.Set(); |
| 74 | return std::chrono::nanoseconds(GetNextTicks()); | 70 | return std::chrono::nanoseconds(GetNextTicks()); |
| 75 | }); | 71 | }); |
| 76 | 72 | ||
| @@ -96,8 +92,7 @@ Nvnflinger::~Nvnflinger() { | |||
| 96 | if (system.IsMulticore()) { | 92 | if (system.IsMulticore()) { |
| 97 | system.CoreTiming().UnscheduleEvent(multi_composition_event, {}); | 93 | system.CoreTiming().UnscheduleEvent(multi_composition_event, {}); |
| 98 | vsync_thread.request_stop(); | 94 | vsync_thread.request_stop(); |
| 99 | vsync_signal.store(true); | 95 | vsync_signal.Set(); |
| 100 | vsync_signal.notify_all(); | ||
| 101 | } else { | 96 | } else { |
| 102 | system.CoreTiming().UnscheduleEvent(single_composition_event, {}); | 97 | system.CoreTiming().UnscheduleEvent(single_composition_event, {}); |
| 103 | } | 98 | } |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h index a043cceb2..ef236303a 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.h +++ b/src/core/hle/service/nvnflinger/nvnflinger.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/polyfill_thread.h" | 14 | #include "common/polyfill_thread.h" |
| 15 | #include "common/thread.h" | ||
| 15 | #include "core/hle/result.h" | 16 | #include "core/hle/result.h" |
| 16 | #include "core/hle/service/kernel_helpers.h" | 17 | #include "core/hle/service/kernel_helpers.h" |
| 17 | 18 | ||
| @@ -143,7 +144,7 @@ private: | |||
| 143 | 144 | ||
| 144 | Core::System& system; | 145 | Core::System& system; |
| 145 | 146 | ||
| 146 | std::atomic<bool> vsync_signal; | 147 | Common::Event vsync_signal; |
| 147 | 148 | ||
| 148 | std::jthread vsync_thread; | 149 | std::jthread vsync_thread; |
| 149 | 150 | ||
diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h index fb56d75d7..23ba315a0 100644 --- a/src/core/hle/service/nvnflinger/parcel.h +++ b/src/core/hle/service/nvnflinger/parcel.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <span> | 7 | #include <span> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include <boost/container/small_vector.hpp> | ||
| 9 | 10 | ||
| 10 | #include "common/alignment.h" | 11 | #include "common/alignment.h" |
| 11 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| @@ -167,7 +168,7 @@ public: | |||
| 167 | private: | 168 | private: |
| 168 | template <typename T> | 169 | template <typename T> |
| 169 | requires(std::is_trivially_copyable_v<T>) | 170 | requires(std::is_trivially_copyable_v<T>) |
| 170 | void WriteImpl(const T& val, std::vector<u8>& buffer) { | 171 | void WriteImpl(const T& val, boost::container::small_vector<u8, 0x200>& buffer) { |
| 171 | const size_t aligned_size = Common::AlignUp(sizeof(T), 4); | 172 | const size_t aligned_size = Common::AlignUp(sizeof(T), 4); |
| 172 | const size_t old_size = buffer.size(); | 173 | const size_t old_size = buffer.size(); |
| 173 | buffer.resize(old_size + aligned_size); | 174 | buffer.resize(old_size + aligned_size); |
| @@ -176,8 +177,8 @@ private: | |||
| 176 | } | 177 | } |
| 177 | 178 | ||
| 178 | private: | 179 | private: |
| 179 | std::vector<u8> m_data_buffer; | 180 | boost::container::small_vector<u8, 0x200> m_data_buffer; |
| 180 | std::vector<u8> m_object_buffer; | 181 | boost::container::small_vector<u8, 0x200> m_object_buffer; |
| 181 | }; | 182 | }; |
| 182 | 183 | ||
| 183 | } // namespace Service::android | 184 | } // namespace Service::android |
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index 156bc27d8..d1e99b184 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp | |||
| @@ -44,7 +44,7 @@ ServerManager::~ServerManager() { | |||
| 44 | m_event->Signal(); | 44 | m_event->Signal(); |
| 45 | 45 | ||
| 46 | // Wait for processing to stop. | 46 | // Wait for processing to stop. |
| 47 | m_stopped.wait(false); | 47 | m_stopped.Wait(); |
| 48 | m_threads.clear(); | 48 | m_threads.clear(); |
| 49 | 49 | ||
| 50 | // Clean up ports. | 50 | // Clean up ports. |
| @@ -182,10 +182,7 @@ void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_thre | |||
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | Result ServerManager::LoopProcess() { | 184 | Result ServerManager::LoopProcess() { |
| 185 | SCOPE_EXIT({ | 185 | SCOPE_EXIT({ m_stopped.Set(); }); |
| 186 | m_stopped.store(true); | ||
| 187 | m_stopped.notify_all(); | ||
| 188 | }); | ||
| 189 | 186 | ||
| 190 | R_RETURN(this->LoopProcessImpl()); | 187 | R_RETURN(this->LoopProcessImpl()); |
| 191 | } | 188 | } |
diff --git a/src/core/hle/service/server_manager.h b/src/core/hle/service/server_manager.h index fdb8af2ff..58b0a0832 100644 --- a/src/core/hle/service/server_manager.h +++ b/src/core/hle/service/server_manager.h | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <atomic> | ||
| 7 | #include <functional> | 6 | #include <functional> |
| 8 | #include <list> | 7 | #include <list> |
| 9 | #include <map> | 8 | #include <map> |
| @@ -12,6 +11,7 @@ | |||
| 12 | #include <vector> | 11 | #include <vector> |
| 13 | 12 | ||
| 14 | #include "common/polyfill_thread.h" | 13 | #include "common/polyfill_thread.h" |
| 14 | #include "common/thread.h" | ||
| 15 | #include "core/hle/result.h" | 15 | #include "core/hle/result.h" |
| 16 | #include "core/hle/service/mutex.h" | 16 | #include "core/hle/service/mutex.h" |
| 17 | 17 | ||
| @@ -82,7 +82,7 @@ private: | |||
| 82 | std::list<RequestState> m_deferrals{}; | 82 | std::list<RequestState> m_deferrals{}; |
| 83 | 83 | ||
| 84 | // Host state tracking | 84 | // Host state tracking |
| 85 | std::atomic<bool> m_stopped{}; | 85 | Common::Event m_stopped{}; |
| 86 | std::vector<std::jthread> m_threads{}; | 86 | std::vector<std::jthread> m_threads{}; |
| 87 | std::stop_source m_stop_source{}; | 87 | std::stop_source m_stop_source{}; |
| 88 | }; | 88 | }; |
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h index e6293ffb9..9fc01ea90 100644 --- a/src/core/hle/service/time/clock_types.h +++ b/src/core/hle/service/time/clock_types.h | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <ratio> | ||
| 7 | |||
| 6 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 7 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 8 | #include "common/uuid.h" | 10 | #include "common/uuid.h" |
| @@ -74,18 +76,19 @@ static_assert(std::is_trivially_copyable_v<ContinuousAdjustmentTimePoint>, | |||
| 74 | /// https://switchbrew.org/wiki/Glue_services#TimeSpanType | 76 | /// https://switchbrew.org/wiki/Glue_services#TimeSpanType |
| 75 | struct TimeSpanType { | 77 | struct TimeSpanType { |
| 76 | s64 nanoseconds{}; | 78 | s64 nanoseconds{}; |
| 77 | static constexpr s64 ns_per_second{1000000000ULL}; | ||
| 78 | 79 | ||
| 79 | s64 ToSeconds() const { | 80 | s64 ToSeconds() const { |
| 80 | return nanoseconds / ns_per_second; | 81 | return nanoseconds / std::nano::den; |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | static TimeSpanType FromSeconds(s64 seconds) { | 84 | static TimeSpanType FromSeconds(s64 seconds) { |
| 84 | return {seconds * ns_per_second}; | 85 | return {seconds * std::nano::den}; |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | static TimeSpanType FromTicks(u64 ticks, u64 frequency) { | 88 | template <u64 Frequency> |
| 88 | return FromSeconds(static_cast<s64>(ticks) / static_cast<s64>(frequency)); | 89 | static TimeSpanType FromTicks(u64 ticks) { |
| 90 | using TicksToNSRatio = std::ratio<std::nano::den, Frequency>; | ||
| 91 | return {static_cast<s64>(ticks * TicksToNSRatio::num / TicksToNSRatio::den)}; | ||
| 89 | } | 92 | } |
| 90 | }; | 93 | }; |
| 91 | static_assert(sizeof(TimeSpanType) == 8, "TimeSpanType is incorrect size"); | 94 | static_assert(sizeof(TimeSpanType) == 8, "TimeSpanType is incorrect size"); |
diff --git a/src/core/hle/service/time/standard_steady_clock_core.cpp b/src/core/hle/service/time/standard_steady_clock_core.cpp index 3dbbb9850..5627b7003 100644 --- a/src/core/hle/service/time/standard_steady_clock_core.cpp +++ b/src/core/hle/service/time/standard_steady_clock_core.cpp | |||
| @@ -10,7 +10,7 @@ namespace Service::Time::Clock { | |||
| 10 | 10 | ||
| 11 | TimeSpanType StandardSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) { | 11 | TimeSpanType StandardSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) { |
| 12 | const TimeSpanType ticks_time_span{ | 12 | const TimeSpanType ticks_time_span{ |
| 13 | TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; | 13 | TimeSpanType::FromTicks<Core::Hardware::CNTFREQ>(system.CoreTiming().GetClockTicks())}; |
| 14 | TimeSpanType raw_time_point{setup_value.nanoseconds + ticks_time_span.nanoseconds}; | 14 | TimeSpanType raw_time_point{setup_value.nanoseconds + ticks_time_span.nanoseconds}; |
| 15 | 15 | ||
| 16 | if (raw_time_point.nanoseconds < cached_raw_time_point.nanoseconds) { | 16 | if (raw_time_point.nanoseconds < cached_raw_time_point.nanoseconds) { |
diff --git a/src/core/hle/service/time/tick_based_steady_clock_core.cpp b/src/core/hle/service/time/tick_based_steady_clock_core.cpp index 27600413e..0d9fb3143 100644 --- a/src/core/hle/service/time/tick_based_steady_clock_core.cpp +++ b/src/core/hle/service/time/tick_based_steady_clock_core.cpp | |||
| @@ -10,7 +10,7 @@ namespace Service::Time::Clock { | |||
| 10 | 10 | ||
| 11 | SteadyClockTimePoint TickBasedSteadyClockCore::GetTimePoint(Core::System& system) { | 11 | SteadyClockTimePoint TickBasedSteadyClockCore::GetTimePoint(Core::System& system) { |
| 12 | const TimeSpanType ticks_time_span{ | 12 | const TimeSpanType ticks_time_span{ |
| 13 | TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; | 13 | TimeSpanType::FromTicks<Core::Hardware::CNTFREQ>(system.CoreTiming().GetClockTicks())}; |
| 14 | 14 | ||
| 15 | return {ticks_time_span.ToSeconds(), GetClockSourceId()}; | 15 | return {ticks_time_span.ToSeconds(), GetClockSourceId()}; |
| 16 | } | 16 | } |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 868be60c5..7197ca30f 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -240,8 +240,8 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(HLERequestCon | |||
| 240 | const auto current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; | 240 | const auto current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; |
| 241 | 241 | ||
| 242 | if (current_time_point.clock_source_id == context.steady_time_point.clock_source_id) { | 242 | if (current_time_point.clock_source_id == context.steady_time_point.clock_source_id) { |
| 243 | const auto ticks{Clock::TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), | 243 | const auto ticks{Clock::TimeSpanType::FromTicks<Core::Hardware::CNTFREQ>( |
| 244 | Core::Hardware::CNTFREQ)}; | 244 | system.CoreTiming().GetClockTicks())}; |
| 245 | const s64 base_time_point{context.offset + current_time_point.time_point - | 245 | const s64 base_time_point{context.offset + current_time_point.time_point - |
| 246 | ticks.ToSeconds()}; | 246 | ticks.ToSeconds()}; |
| 247 | IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; | 247 | IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; |
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index ce1c85bcc..a00676669 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp | |||
| @@ -21,8 +21,9 @@ SharedMemory::~SharedMemory() = default; | |||
| 21 | 21 | ||
| 22 | void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id, | 22 | void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id, |
| 23 | Clock::TimeSpanType current_time_point) { | 23 | Clock::TimeSpanType current_time_point) { |
| 24 | const Clock::TimeSpanType ticks_time_span{Clock::TimeSpanType::FromTicks( | 24 | const Clock::TimeSpanType ticks_time_span{ |
| 25 | system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; | 25 | Clock::TimeSpanType::FromTicks<Core::Hardware::CNTFREQ>( |
| 26 | system.CoreTiming().GetClockTicks())}; | ||
| 26 | const Clock::SteadyClockContext context{ | 27 | const Clock::SteadyClockContext context{ |
| 27 | static_cast<u64>(current_time_point.nanoseconds - ticks_time_span.nanoseconds), | 28 | static_cast<u64>(current_time_point.nanoseconds - ticks_time_span.nanoseconds), |
| 28 | clock_source_id}; | 29 | clock_source_id}; |
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 63aacd19f..205371a26 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -911,9 +911,13 @@ static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | |||
| 911 | 911 | ||
| 912 | calendar_additional_info.is_dst = rules.ttis[tti_index].is_dst; | 912 | calendar_additional_info.is_dst = rules.ttis[tti_index].is_dst; |
| 913 | const char* time_zone{&rules.chars[rules.ttis[tti_index].abbreviation_list_index]}; | 913 | const char* time_zone{&rules.chars[rules.ttis[tti_index].abbreviation_list_index]}; |
| 914 | for (int index{}; time_zone[index] != '\0'; ++index) { | 914 | u32 index; |
| 915 | for (index = 0; time_zone[index] != '\0' && time_zone[index] != ',' && | ||
| 916 | index < calendar_additional_info.timezone_name.size() - 1; | ||
| 917 | ++index) { | ||
| 915 | calendar_additional_info.timezone_name[index] = time_zone[index]; | 918 | calendar_additional_info.timezone_name[index] = time_zone[index]; |
| 916 | } | 919 | } |
| 920 | calendar_additional_info.timezone_name[index] = '\0'; | ||
| 917 | return ResultSuccess; | 921 | return ResultSuccess; |
| 918 | } | 922 | } |
| 919 | 923 | ||