diff options
| author | 2023-12-25 07:32:16 +0100 | |
|---|---|---|
| committer | 2024-01-18 21:12:30 -0500 | |
| commit | 0a2536a0df1f4aea406f2132d3edda0430acc9d1 (patch) | |
| tree | c0ad53890581c9c7e180c5ccb3b66e3c63e3ba64 /src/core/hle | |
| parent | SMMU: Implement backing CPU page protect/unprotect (diff) | |
| download | yuzu-0a2536a0df1f4aea406f2132d3edda0430acc9d1.tar.gz yuzu-0a2536a0df1f4aea406f2132d3edda0430acc9d1.tar.xz yuzu-0a2536a0df1f4aea406f2132d3edda0430acc9d1.zip | |
SMMU: Initial adaptation to video_core.
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/hle_ipc.cpp | 61 | ||||
| -rw-r--r-- | src/core/hle/service/hle_ipc.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/core/nvmap.cpp | 64 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/core/nvmap.h | 19 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 57 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 20 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv_interface.cpp | 6 |
10 files changed, 94 insertions, 156 deletions
diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index 3f38ceb03..9f6274c7d 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp | |||
| @@ -22,19 +22,7 @@ | |||
| 22 | #include "core/hle/service/hle_ipc.h" | 22 | #include "core/hle/service/hle_ipc.h" |
| 23 | #include "core/hle/service/ipc_helpers.h" | 23 | #include "core/hle/service/ipc_helpers.h" |
| 24 | #include "core/memory.h" | 24 | #include "core/memory.h" |
| 25 | 25 | #include "core/guest_memory.h" | |
| 26 | namespace { | ||
| 27 | static thread_local std::array read_buffer_data_a{ | ||
| 28 | Common::ScratchBuffer<u8>(), | ||
| 29 | Common::ScratchBuffer<u8>(), | ||
| 30 | Common::ScratchBuffer<u8>(), | ||
| 31 | }; | ||
| 32 | static thread_local std::array read_buffer_data_x{ | ||
| 33 | Common::ScratchBuffer<u8>(), | ||
| 34 | Common::ScratchBuffer<u8>(), | ||
| 35 | Common::ScratchBuffer<u8>(), | ||
| 36 | }; | ||
| 37 | } // Anonymous namespace | ||
| 38 | 26 | ||
| 39 | namespace Service { | 27 | namespace Service { |
| 40 | 28 | ||
| @@ -343,48 +331,27 @@ std::vector<u8> HLERequestContext::ReadBufferCopy(std::size_t buffer_index) cons | |||
| 343 | } | 331 | } |
| 344 | 332 | ||
| 345 | std::span<const u8> HLERequestContext::ReadBufferA(std::size_t buffer_index) const { | 333 | std::span<const u8> HLERequestContext::ReadBufferA(std::size_t buffer_index) const { |
| 346 | static thread_local std::array read_buffer_a{ | 334 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::UnsafeRead> gm(memory, 0, 0); |
| 347 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 348 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 349 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 350 | }; | ||
| 351 | 335 | ||
| 352 | ASSERT_OR_EXECUTE_MSG( | 336 | ASSERT_OR_EXECUTE_MSG( |
| 353 | BufferDescriptorA().size() > buffer_index, { return {}; }, | 337 | BufferDescriptorA().size() > buffer_index, { return {}; }, |
| 354 | "BufferDescriptorA invalid buffer_index {}", buffer_index); | 338 | "BufferDescriptorA invalid buffer_index {}", buffer_index); |
| 355 | auto& read_buffer = read_buffer_a[buffer_index]; | 339 | return gm.Read(BufferDescriptorA()[buffer_index].Address(), |
| 356 | return read_buffer.Read(BufferDescriptorA()[buffer_index].Address(), | 340 | BufferDescriptorA()[buffer_index].Size(), &read_buffer_data_a[buffer_index]); |
| 357 | BufferDescriptorA()[buffer_index].Size(), | ||
| 358 | &read_buffer_data_a[buffer_index]); | ||
| 359 | } | 341 | } |
| 360 | 342 | ||
| 361 | std::span<const u8> HLERequestContext::ReadBufferX(std::size_t buffer_index) const { | 343 | std::span<const u8> HLERequestContext::ReadBufferX(std::size_t buffer_index) const { |
| 362 | static thread_local std::array read_buffer_x{ | 344 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::UnsafeRead> gm(memory, 0, 0); |
| 363 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 364 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 365 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 366 | }; | ||
| 367 | 345 | ||
| 368 | ASSERT_OR_EXECUTE_MSG( | 346 | ASSERT_OR_EXECUTE_MSG( |
| 369 | BufferDescriptorX().size() > buffer_index, { return {}; }, | 347 | BufferDescriptorX().size() > buffer_index, { return {}; }, |
| 370 | "BufferDescriptorX invalid buffer_index {}", buffer_index); | 348 | "BufferDescriptorX invalid buffer_index {}", buffer_index); |
| 371 | auto& read_buffer = read_buffer_x[buffer_index]; | 349 | return gm.Read(BufferDescriptorX()[buffer_index].Address(), |
| 372 | return read_buffer.Read(BufferDescriptorX()[buffer_index].Address(), | 350 | BufferDescriptorX()[buffer_index].Size(), &read_buffer_data_x[buffer_index]); |
| 373 | BufferDescriptorX()[buffer_index].Size(), | ||
| 374 | &read_buffer_data_x[buffer_index]); | ||
| 375 | } | 351 | } |
| 376 | 352 | ||
| 377 | std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { | 353 | std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { |
| 378 | static thread_local std::array read_buffer_a{ | 354 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::UnsafeRead> gm(memory, 0, 0); |
| 379 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 380 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 381 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 382 | }; | ||
| 383 | static thread_local std::array read_buffer_x{ | ||
| 384 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 385 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 386 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 387 | }; | ||
| 388 | 355 | ||
| 389 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && | 356 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && |
| 390 | BufferDescriptorA()[buffer_index].Size()}; | 357 | BufferDescriptorA()[buffer_index].Size()}; |
| @@ -401,18 +368,14 @@ std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) cons | |||
| 401 | ASSERT_OR_EXECUTE_MSG( | 368 | ASSERT_OR_EXECUTE_MSG( |
| 402 | BufferDescriptorA().size() > buffer_index, { return {}; }, | 369 | BufferDescriptorA().size() > buffer_index, { return {}; }, |
| 403 | "BufferDescriptorA invalid buffer_index {}", buffer_index); | 370 | "BufferDescriptorA invalid buffer_index {}", buffer_index); |
| 404 | auto& read_buffer = read_buffer_a[buffer_index]; | 371 | return gm.Read(BufferDescriptorA()[buffer_index].Address(), |
| 405 | return read_buffer.Read(BufferDescriptorA()[buffer_index].Address(), | 372 | BufferDescriptorA()[buffer_index].Size(), &read_buffer_data_a[buffer_index]); |
| 406 | BufferDescriptorA()[buffer_index].Size(), | ||
| 407 | &read_buffer_data_a[buffer_index]); | ||
| 408 | } else { | 373 | } else { |
| 409 | ASSERT_OR_EXECUTE_MSG( | 374 | ASSERT_OR_EXECUTE_MSG( |
| 410 | BufferDescriptorX().size() > buffer_index, { return {}; }, | 375 | BufferDescriptorX().size() > buffer_index, { return {}; }, |
| 411 | "BufferDescriptorX invalid buffer_index {}", buffer_index); | 376 | "BufferDescriptorX invalid buffer_index {}", buffer_index); |
| 412 | auto& read_buffer = read_buffer_x[buffer_index]; | 377 | return gm.Read(BufferDescriptorX()[buffer_index].Address(), |
| 413 | return read_buffer.Read(BufferDescriptorX()[buffer_index].Address(), | 378 | BufferDescriptorX()[buffer_index].Size(), &read_buffer_data_x[buffer_index]); |
| 414 | BufferDescriptorX()[buffer_index].Size(), | ||
| 415 | &read_buffer_data_x[buffer_index]); | ||
| 416 | } | 379 | } |
| 417 | } | 380 | } |
| 418 | 381 | ||
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h index d550a11b7..8329d7265 100644 --- a/src/core/hle/service/hle_ipc.h +++ b/src/core/hle/service/hle_ipc.h | |||
| @@ -19,8 +19,6 @@ | |||
| 19 | #include "core/hle/ipc.h" | 19 | #include "core/hle/ipc.h" |
| 20 | #include "core/hle/kernel/k_handle_table.h" | 20 | #include "core/hle/kernel/k_handle_table.h" |
| 21 | #include "core/hle/kernel/svc_common.h" | 21 | #include "core/hle/kernel/svc_common.h" |
| 22 | #include "core/hle/kernel/k_auto_object.h" | ||
| 23 | #include "core/hle/kernel/k_handle_table.h" | ||
| 24 | 22 | ||
| 25 | union Result; | 23 | union Result; |
| 26 | 24 | ||
| @@ -377,10 +375,6 @@ public: | |||
| 377 | return nullptr; | 375 | return nullptr; |
| 378 | } | 376 | } |
| 379 | 377 | ||
| 380 | Kernel::KScopedAutoObject<Kernel::KAutoObject> GetObjectFromHandle(u32 handle) { | ||
| 381 | return GetClientHandleTable().GetObjectForIpc(handle, thread); | ||
| 382 | } | ||
| 383 | |||
| 384 | [[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const { | 378 | [[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const { |
| 385 | return manager.lock(); | 379 | return manager.lock(); |
| 386 | } | 380 | } |
| @@ -432,6 +426,9 @@ private: | |||
| 432 | 426 | ||
| 433 | Kernel::KernelCore& kernel; | 427 | Kernel::KernelCore& kernel; |
| 434 | Core::Memory::Memory& memory; | 428 | Core::Memory::Memory& memory; |
| 429 | |||
| 430 | mutable std::array<Common::ScratchBuffer<u8>, 3> read_buffer_data_a{}; | ||
| 431 | mutable std::array<Common::ScratchBuffer<u8>, 3> read_buffer_data_x{}; | ||
| 435 | }; | 432 | }; |
| 436 | 433 | ||
| 437 | } // namespace Service | 434 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index fd6c9aa0c..7879c6f04 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // SPDX-FileCopyrightText: 2022 Skyline Team and Contributors | 2 | // SPDX-FileCopyrightText: 2022 Skyline Team and Contributors |
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later | 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | 4 | ||
| 5 | #include <functional> | ||
| 6 | |||
| 5 | #include "common/alignment.h" | 7 | #include "common/alignment.h" |
| 6 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| @@ -18,6 +20,7 @@ NvMap::Handle::Handle(u64 size_, Id id_) | |||
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { | 22 | NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { |
| 23 | std::scoped_lock lock(mutex); | ||
| 21 | // Handles cannot be allocated twice | 24 | // Handles cannot be allocated twice |
| 22 | if (allocated) { | 25 | if (allocated) { |
| 23 | return NvResult::AccessDenied; | 26 | return NvResult::AccessDenied; |
| @@ -78,11 +81,9 @@ void NvMap::UnmapHandle(Handle& handle_description) { | |||
| 78 | 81 | ||
| 79 | // Free and unmap the handle from the SMMU | 82 | // Free and unmap the handle from the SMMU |
| 80 | auto& smmu = host1x.MemoryManager(); | 83 | auto& smmu = host1x.MemoryManager(); |
| 81 | smmu.Unmap(static_cast<DAddr>(handle_description.pin_virt_address), | 84 | smmu.Unmap(handle_description.d_address, handle_description.aligned_size); |
| 82 | handle_description.aligned_size); | 85 | smmu.Free(handle_description.d_address, static_cast<size_t>(handle_description.aligned_size)); |
| 83 | smmu.Free(handle_description.pin_virt_address, | 86 | handle_description.d_address = 0; |
| 84 | static_cast<size_t>(handle_description.aligned_size)); | ||
| 85 | handle_description.pin_virt_address = 0; | ||
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | bool NvMap::TryRemoveHandle(const Handle& handle_description) { | 89 | bool NvMap::TryRemoveHandle(const Handle& handle_description) { |
| @@ -123,41 +124,16 @@ std::shared_ptr<NvMap::Handle> NvMap::GetHandle(Handle::Id handle) { | |||
| 123 | } | 124 | } |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | VAddr NvMap::GetHandleAddress(Handle::Id handle) { | 127 | DAddr NvMap::GetHandleAddress(Handle::Id handle) { |
| 127 | std::scoped_lock lock(handles_lock); | 128 | std::scoped_lock lock(handles_lock); |
| 128 | try { | 129 | try { |
| 129 | return handles.at(handle)->address; | 130 | return handles.at(handle)->d_address; |
| 130 | } catch (std::out_of_range&) { | 131 | } catch (std::out_of_range&) { |
| 131 | return 0; | 132 | return 0; |
| 132 | } | 133 | } |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 135 | NvResult NvMap::AllocateHandle(Handle::Id handle, Handle::Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t session_id) { | 136 | DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_area_pin) { |
| 136 | auto handle_description{GetHandle(handle)}; | ||
| 137 | if (!handle_description) [[unlikely]] { | ||
| 138 | return NvResult::BadParameter; | ||
| 139 | } | ||
| 140 | |||
| 141 | if (handle_description->allocated) [[unlikely]] { | ||
| 142 | return NvResult::InsufficientMemory; | ||
| 143 | } | ||
| 144 | |||
| 145 | std::scoped_lock lock(handle_description->mutex); | ||
| 146 | NvResult result = handle_description->Alloc(pFlags, pAlign, pKind, pAddress); | ||
| 147 | if (result != NvResult::Success) { | ||
| 148 | return result; | ||
| 149 | } | ||
| 150 | auto& smmu = host1x.MemoryManager(); | ||
| 151 | size_t total_size = static_cast<size_t>(handle_description->aligned_size); | ||
| 152 | handle_description->d_address = smmu.Allocate(total_size); | ||
| 153 | if (handle_description->d_address == 0) { | ||
| 154 | return NvResult::InsufficientMemory; | ||
| 155 | } | ||
| 156 | smmu.Map(handle_description->d_address, handle_description->address, total_size, session_id); | ||
| 157 | return NvResult::Success; | ||
| 158 | } | ||
| 159 | |||
| 160 | u32 NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id) { | ||
| 161 | auto handle_description{GetHandle(handle)}; | 137 | auto handle_description{GetHandle(handle)}; |
| 162 | if (!handle_description) [[unlikely]] { | 138 | if (!handle_description) [[unlikely]] { |
| 163 | return 0; | 139 | return 0; |
| @@ -176,35 +152,38 @@ u32 NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id) { | |||
| 176 | handle_description->unmap_queue_entry.reset(); | 152 | handle_description->unmap_queue_entry.reset(); |
| 177 | 153 | ||
| 178 | handle_description->pins++; | 154 | handle_description->pins++; |
| 179 | return handle_description->pin_virt_address; | 155 | return handle_description->d_address; |
| 180 | } | 156 | } |
| 181 | } | 157 | } |
| 182 | 158 | ||
| 159 | using namespace std::placeholders; | ||
| 183 | // If not then allocate some space and map it | 160 | // If not then allocate some space and map it |
| 184 | DAddr address{}; | 161 | DAddr address{}; |
| 185 | auto& smmu = host1x.MemoryManager(); | 162 | auto& smmu = host1x.MemoryManager(); |
| 186 | while ((address = smmu.AllocatePinned( | 163 | auto allocate = std::bind(&Tegra::MaxwellDeviceMemoryManager::Allocate, &smmu, _1); |
| 187 | static_cast<size_t>(handle_description->aligned_size))) == 0) { | 164 | //: std::bind(&Tegra::MaxwellDeviceMemoryManager::Allocate, &smmu, _1); |
| 165 | while ((address = allocate(static_cast<size_t>(handle_description->aligned_size))) == 0) { | ||
| 188 | // Free handles until the allocation succeeds | 166 | // Free handles until the allocation succeeds |
| 189 | std::scoped_lock queueLock(unmap_queue_lock); | 167 | std::scoped_lock queueLock(unmap_queue_lock); |
| 190 | if (auto freeHandleDesc{unmap_queue.front()}) { | 168 | if (auto freeHandleDesc{unmap_queue.front()}) { |
| 191 | // Handles in the unmap queue are guaranteed not to be pinned so don't bother | 169 | // Handles in the unmap queue are guaranteed not to be pinned so don't bother |
| 192 | // checking if they are before unmapping | 170 | // checking if they are before unmapping |
| 193 | std::scoped_lock freeLock(freeHandleDesc->mutex); | 171 | std::scoped_lock freeLock(freeHandleDesc->mutex); |
| 194 | if (handle_description->pin_virt_address) | 172 | if (handle_description->d_address) |
| 195 | UnmapHandle(*freeHandleDesc); | 173 | UnmapHandle(*freeHandleDesc); |
| 196 | } else { | 174 | } else { |
| 197 | LOG_CRITICAL(Service_NVDRV, "Ran out of SMMU address space!"); | 175 | LOG_CRITICAL(Service_NVDRV, "Ran out of SMMU address space!"); |
| 198 | } | 176 | } |
| 199 | } | 177 | } |
| 200 | 178 | ||
| 179 | handle_description->d_address = address; | ||
| 180 | |||
| 201 | smmu.Map(address, handle_description->address, handle_description->aligned_size, | 181 | smmu.Map(address, handle_description->address, handle_description->aligned_size, |
| 202 | session_id); | 182 | session_id); |
| 203 | handle_description->pin_virt_address = static_cast<u32>(address); | ||
| 204 | } | 183 | } |
| 205 | 184 | ||
| 206 | handle_description->pins++; | 185 | handle_description->pins++; |
| 207 | return handle_description->pin_virt_address; | 186 | return handle_description->d_address; |
| 208 | } | 187 | } |
| 209 | 188 | ||
| 210 | void NvMap::UnpinHandle(Handle::Id handle) { | 189 | void NvMap::UnpinHandle(Handle::Id handle) { |
| @@ -255,15 +234,10 @@ std::optional<NvMap::FreeInfo> NvMap::FreeHandle(Handle::Id handle, bool interna | |||
| 255 | LOG_WARNING(Service_NVDRV, "User duplicate count imbalance detected!"); | 234 | LOG_WARNING(Service_NVDRV, "User duplicate count imbalance detected!"); |
| 256 | } else if (handle_description->dupes == 0) { | 235 | } else if (handle_description->dupes == 0) { |
| 257 | // Force unmap the handle | 236 | // Force unmap the handle |
| 258 | if (handle_description->pin_virt_address) { | 237 | if (handle_description->d_address) { |
| 259 | std::scoped_lock queueLock(unmap_queue_lock); | 238 | std::scoped_lock queueLock(unmap_queue_lock); |
| 260 | UnmapHandle(*handle_description); | 239 | UnmapHandle(*handle_description); |
| 261 | } | 240 | } |
| 262 | if (handle_description->allocated) { | ||
| 263 | auto& smmu = host1x.MemoryManager(); | ||
| 264 | smmu.Free(handle_description->d_address, handle_description->aligned_size); | ||
| 265 | smmu.Unmap(handle_description->d_address, handle_description->aligned_size); | ||
| 266 | } | ||
| 267 | 241 | ||
| 268 | handle_description->pins = 0; | 242 | handle_description->pins = 0; |
| 269 | } | 243 | } |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index 7c3110d91..e9e9e8b5b 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h | |||
| @@ -48,7 +48,7 @@ public: | |||
| 48 | using Id = u32; | 48 | using Id = u32; |
| 49 | Id id; //!< A globally unique identifier for this handle | 49 | Id id; //!< A globally unique identifier for this handle |
| 50 | 50 | ||
| 51 | s32 pins{}; | 51 | s64 pins{}; |
| 52 | u32 pin_virt_address{}; | 52 | u32 pin_virt_address{}; |
| 53 | std::optional<typename std::list<std::shared_ptr<Handle>>::iterator> unmap_queue_entry{}; | 53 | std::optional<typename std::list<std::shared_ptr<Handle>>::iterator> unmap_queue_entry{}; |
| 54 | 54 | ||
| @@ -63,15 +63,14 @@ public: | |||
| 63 | 63 | ||
| 64 | VAddr address{}; //!< The memory location in the guest's AS that this handle corresponds to, | 64 | VAddr address{}; //!< The memory location in the guest's AS that this handle corresponds to, |
| 65 | //!< this can also be in the nvdrv tmem | 65 | //!< this can also be in the nvdrv tmem |
| 66 | DAddr d_address{}; //!< The memory location in the device's AS that this handle corresponds to, | ||
| 67 | //!< this can also be in the nvdrv tmem | ||
| 68 | bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC | 66 | bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC |
| 69 | //!< call | 67 | //!< call |
| 70 | 68 | ||
| 71 | u8 kind{}; //!< Used for memory compression | 69 | u8 kind{}; //!< Used for memory compression |
| 72 | bool allocated{}; //!< If the handle has been allocated with `Alloc` | 70 | bool allocated{}; //!< If the handle has been allocated with `Alloc` |
| 73 | 71 | ||
| 74 | u64 dma_map_addr{}; //! remove me after implementing pinning. | 72 | DAddr d_address{}; //!< The memory location in the device's AS that this handle corresponds to, |
| 73 | //!< this can also be in the nvdrv tmem | ||
| 75 | 74 | ||
| 76 | Handle(u64 size, Id id); | 75 | Handle(u64 size, Id id); |
| 77 | 76 | ||
| @@ -119,15 +118,7 @@ public: | |||
| 119 | 118 | ||
| 120 | std::shared_ptr<Handle> GetHandle(Handle::Id handle); | 119 | std::shared_ptr<Handle> GetHandle(Handle::Id handle); |
| 121 | 120 | ||
| 122 | VAddr GetHandleAddress(Handle::Id handle); | 121 | DAddr GetHandleAddress(Handle::Id handle); |
| 123 | |||
| 124 | /** | ||
| 125 | * @brief Maps a handle into the SMMU address space | ||
| 126 | * @note This operation is refcounted, the number of calls to this must eventually match the | ||
| 127 | * number of calls to `UnpinHandle` | ||
| 128 | * @return The SMMU virtual address that the handle has been mapped to | ||
| 129 | */ | ||
| 130 | u32 PinHandle(Handle::Id handle, size_t session_id); | ||
| 131 | 122 | ||
| 132 | /** | 123 | /** |
| 133 | * @brief Maps a handle into the SMMU address space | 124 | * @brief Maps a handle into the SMMU address space |
| @@ -135,7 +126,7 @@ public: | |||
| 135 | * number of calls to `UnpinHandle` | 126 | * number of calls to `UnpinHandle` |
| 136 | * @return The SMMU virtual address that the handle has been mapped to | 127 | * @return The SMMU virtual address that the handle has been mapped to |
| 137 | */ | 128 | */ |
| 138 | NvResult AllocateHandle(Handle::Id handle, Handle::Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t session_id); | 129 | DAddr PinHandle(Handle::Id handle, size_t session_id, bool low_area_pin); |
| 139 | 130 | ||
| 140 | /** | 131 | /** |
| 141 | * @brief When this has been called an equal number of times to `PinHandle` for the supplied | 132 | * @brief When this has been called an equal number of times to `PinHandle` for the supplied |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 0ff41c6b2..f1404b9da 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -42,7 +42,7 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat form | |||
| 42 | u32 height, u32 stride, android::BufferTransformFlags transform, | 42 | u32 height, u32 stride, android::BufferTransformFlags transform, |
| 43 | const Common::Rectangle<int>& crop_rect, | 43 | const Common::Rectangle<int>& crop_rect, |
| 44 | std::array<Service::Nvidia::NvFence, 4>& fences, u32 num_fences) { | 44 | std::array<Service::Nvidia::NvFence, 4>& fences, u32 num_fences) { |
| 45 | const VAddr addr = nvmap.GetHandleAddress(buffer_handle); | 45 | const DAddr addr = nvmap.GetHandleAddress(buffer_handle); |
| 46 | LOG_TRACE(Service, | 46 | LOG_TRACE(Service, |
| 47 | "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", | 47 | "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", |
| 48 | addr, offset, width, height, stride, format); | 48 | addr, offset, width, height, stride, format); |
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 c92a7b2f6..8bc10eac2 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -40,15 +40,15 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 40 | case 0x3: | 40 | case 0x3: |
| 41 | return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); | 41 | return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); |
| 42 | case 0x5: | 42 | case 0x5: |
| 43 | return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output); | 43 | return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output, fd); |
| 44 | case 0x6: | 44 | case 0x6: |
| 45 | return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output); | 45 | return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output, fd); |
| 46 | case 0x8: | 46 | case 0x8: |
| 47 | return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); | 47 | return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); |
| 48 | case 0x9: | 48 | case 0x9: |
| 49 | return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); | 49 | return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); |
| 50 | case 0x14: | 50 | case 0x14: |
| 51 | return WrapVariable(this, &nvhost_as_gpu::Remap, input, output); | 51 | return WrapVariable(this, &nvhost_as_gpu::Remap, input, output, fd); |
| 52 | default: | 52 | default: |
| 53 | break; | 53 | break; |
| 54 | } | 54 | } |
| @@ -86,8 +86,15 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 86 | return NvResult::NotImplemented; | 86 | return NvResult::NotImplemented; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) {} | 89 | void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) { |
| 90 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} | 90 | sessions[fd] = session_id; |
| 91 | } | ||
| 92 | void nvhost_as_gpu::OnClose(DeviceFD fd) { | ||
| 93 | auto it = sessions.find(fd); | ||
| 94 | if (it != sessions.end()) { | ||
| 95 | sessions.erase(it); | ||
| 96 | } | ||
| 97 | } | ||
| 91 | 98 | ||
| 92 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { | 99 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { |
| 93 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); | 100 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); |
| @@ -206,6 +213,8 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) { | |||
| 206 | static_cast<u32>(aligned_size >> page_size_bits)); | 213 | static_cast<u32>(aligned_size >> page_size_bits)); |
| 207 | } | 214 | } |
| 208 | 215 | ||
| 216 | nvmap.UnpinHandle(mapping->handle); | ||
| 217 | |||
| 209 | // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state | 218 | // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state |
| 210 | // Only FreeSpace can unmap them fully | 219 | // Only FreeSpace can unmap them fully |
| 211 | if (mapping->sparse_alloc) { | 220 | if (mapping->sparse_alloc) { |
| @@ -259,7 +268,7 @@ NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { | |||
| 259 | return NvResult::Success; | 268 | return NvResult::Success; |
| 260 | } | 269 | } |
| 261 | 270 | ||
| 262 | NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) { | 271 | NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries, DeviceFD fd) { |
| 263 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); | 272 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); |
| 264 | 273 | ||
| 265 | if (!vm.initialised) { | 274 | if (!vm.initialised) { |
| @@ -293,19 +302,19 @@ NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) { | |||
| 293 | return NvResult::BadValue; | 302 | return NvResult::BadValue; |
| 294 | } | 303 | } |
| 295 | 304 | ||
| 296 | VAddr cpu_address{static_cast<VAddr>( | 305 | DAddr base = nvmap.PinHandle(entry.handle, sessions[fd], false); |
| 297 | handle->address + | 306 | DAddr device_address{static_cast<DAddr>( |
| 298 | (static_cast<u64>(entry.handle_offset_big_pages) << vm.big_page_size_bits))}; | 307 | base + (static_cast<u64>(entry.handle_offset_big_pages) << vm.big_page_size_bits))}; |
| 299 | 308 | ||
| 300 | gmmu->Map(virtual_address, cpu_address, size, static_cast<Tegra::PTEKind>(entry.kind), | 309 | gmmu->Map(virtual_address, device_address, size, |
| 301 | use_big_pages); | 310 | static_cast<Tegra::PTEKind>(entry.kind), use_big_pages); |
| 302 | } | 311 | } |
| 303 | } | 312 | } |
| 304 | 313 | ||
| 305 | return NvResult::Success; | 314 | return NvResult::Success; |
| 306 | } | 315 | } |
| 307 | 316 | ||
| 308 | NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { | 317 | NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { |
| 309 | LOG_DEBUG(Service_NVDRV, | 318 | LOG_DEBUG(Service_NVDRV, |
| 310 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" | 319 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" |
| 311 | ", offset={}", | 320 | ", offset={}", |
| @@ -331,9 +340,9 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { | |||
| 331 | } | 340 | } |
| 332 | 341 | ||
| 333 | u64 gpu_address{static_cast<u64>(params.offset + params.buffer_offset)}; | 342 | u64 gpu_address{static_cast<u64>(params.offset + params.buffer_offset)}; |
| 334 | VAddr cpu_address{mapping->ptr + params.buffer_offset}; | 343 | VAddr device_address{mapping->ptr + params.buffer_offset}; |
| 335 | 344 | ||
| 336 | gmmu->Map(gpu_address, cpu_address, params.mapping_size, | 345 | gmmu->Map(gpu_address, device_address, params.mapping_size, |
| 337 | static_cast<Tegra::PTEKind>(params.kind), mapping->big_page); | 346 | static_cast<Tegra::PTEKind>(params.kind), mapping->big_page); |
| 338 | 347 | ||
| 339 | return NvResult::Success; | 348 | return NvResult::Success; |
| @@ -349,7 +358,8 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { | |||
| 349 | return NvResult::BadValue; | 358 | return NvResult::BadValue; |
| 350 | } | 359 | } |
| 351 | 360 | ||
| 352 | VAddr cpu_address{static_cast<VAddr>(handle->address + params.buffer_offset)}; | 361 | DAddr device_address{static_cast<DAddr>(nvmap.PinHandle(params.handle, sessions[fd], false) + |
| 362 | params.buffer_offset)}; | ||
| 353 | u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; | 363 | u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; |
| 354 | 364 | ||
| 355 | bool big_page{[&]() { | 365 | bool big_page{[&]() { |
| @@ -373,15 +383,14 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { | |||
| 373 | } | 383 | } |
| 374 | 384 | ||
| 375 | const bool use_big_pages = alloc->second.big_pages && big_page; | 385 | const bool use_big_pages = alloc->second.big_pages && big_page; |
| 376 | gmmu->Map(params.offset, cpu_address, size, static_cast<Tegra::PTEKind>(params.kind), | 386 | gmmu->Map(params.offset, device_address, size, static_cast<Tegra::PTEKind>(params.kind), |
| 377 | use_big_pages); | 387 | use_big_pages); |
| 378 | 388 | ||
| 379 | auto mapping{std::make_shared<Mapping>(cpu_address, params.offset, size, true, | 389 | auto mapping{std::make_shared<Mapping>(params.handle, device_address, params.offset, size, |
| 380 | use_big_pages, alloc->second.sparse)}; | 390 | true, use_big_pages, alloc->second.sparse)}; |
| 381 | alloc->second.mappings.push_back(mapping); | 391 | alloc->second.mappings.push_back(mapping); |
| 382 | mapping_map[params.offset] = mapping; | 392 | mapping_map[params.offset] = mapping; |
| 383 | } else { | 393 | } else { |
| 384 | |||
| 385 | auto& allocator{big_page ? *vm.big_page_allocator : *vm.small_page_allocator}; | 394 | auto& allocator{big_page ? *vm.big_page_allocator : *vm.small_page_allocator}; |
| 386 | u32 page_size{big_page ? vm.big_page_size : VM::YUZU_PAGESIZE}; | 395 | u32 page_size{big_page ? vm.big_page_size : VM::YUZU_PAGESIZE}; |
| 387 | u32 page_size_bits{big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS}; | 396 | u32 page_size_bits{big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS}; |
| @@ -394,18 +403,18 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { | |||
| 394 | return NvResult::InsufficientMemory; | 403 | return NvResult::InsufficientMemory; |
| 395 | } | 404 | } |
| 396 | 405 | ||
| 397 | gmmu->Map(params.offset, cpu_address, Common::AlignUp(size, page_size), | 406 | gmmu->Map(params.offset, device_address, Common::AlignUp(size, page_size), |
| 398 | static_cast<Tegra::PTEKind>(params.kind), big_page); | 407 | static_cast<Tegra::PTEKind>(params.kind), big_page); |
| 399 | 408 | ||
| 400 | auto mapping{ | 409 | auto mapping{std::make_shared<Mapping>(params.handle, device_address, params.offset, size, |
| 401 | std::make_shared<Mapping>(cpu_address, params.offset, size, false, big_page, false)}; | 410 | false, big_page, false)}; |
| 402 | mapping_map[params.offset] = mapping; | 411 | mapping_map[params.offset] = mapping; |
| 403 | } | 412 | } |
| 404 | 413 | ||
| 405 | return NvResult::Success; | 414 | return NvResult::Success; |
| 406 | } | 415 | } |
| 407 | 416 | ||
| 408 | NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { | 417 | NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd) { |
| 409 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); | 418 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); |
| 410 | 419 | ||
| 411 | std::scoped_lock lock(mutex); | 420 | std::scoped_lock lock(mutex); |
| @@ -433,6 +442,8 @@ NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { | |||
| 433 | gmmu->Unmap(params.offset, mapping->size); | 442 | gmmu->Unmap(params.offset, mapping->size); |
| 434 | } | 443 | } |
| 435 | 444 | ||
| 445 | nvmap.UnpinHandle(mapping->handle); | ||
| 446 | |||
| 436 | mapping_map.erase(params.offset); | 447 | mapping_map.erase(params.offset); |
| 437 | } catch (const std::out_of_range&) { | 448 | } catch (const std::out_of_range&) { |
| 438 | LOG_WARNING(Service_NVDRV, "Couldn't find region to unmap at 0x{:X}", params.offset); | 449 | LOG_WARNING(Service_NVDRV, "Couldn't find region to unmap at 0x{:X}", params.offset); |
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 0dd279f88..4b28f5078 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -141,9 +141,9 @@ private: | |||
| 141 | 141 | ||
| 142 | NvResult AllocAsEx(IoctlAllocAsEx& params); | 142 | NvResult AllocAsEx(IoctlAllocAsEx& params); |
| 143 | NvResult AllocateSpace(IoctlAllocSpace& params); | 143 | NvResult AllocateSpace(IoctlAllocSpace& params); |
| 144 | NvResult Remap(std::span<IoctlRemapEntry> params); | 144 | NvResult Remap(std::span<IoctlRemapEntry> params, DeviceFD fd); |
| 145 | NvResult MapBufferEx(IoctlMapBufferEx& params); | 145 | NvResult MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd); |
| 146 | NvResult UnmapBuffer(IoctlUnmapBuffer& params); | 146 | NvResult UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd); |
| 147 | NvResult FreeSpace(IoctlFreeSpace& params); | 147 | NvResult FreeSpace(IoctlFreeSpace& params); |
| 148 | NvResult BindChannel(IoctlBindChannel& params); | 148 | NvResult BindChannel(IoctlBindChannel& params); |
| 149 | 149 | ||
| @@ -159,16 +159,18 @@ private: | |||
| 159 | NvCore::NvMap& nvmap; | 159 | NvCore::NvMap& nvmap; |
| 160 | 160 | ||
| 161 | struct Mapping { | 161 | struct Mapping { |
| 162 | VAddr ptr; | 162 | NvCore::NvMap::Handle::Id handle; |
| 163 | DAddr ptr; | ||
| 163 | u64 offset; | 164 | u64 offset; |
| 164 | u64 size; | 165 | u64 size; |
| 165 | bool fixed; | 166 | bool fixed; |
| 166 | bool big_page; // Only valid if fixed == false | 167 | bool big_page; // Only valid if fixed == false |
| 167 | bool sparse_alloc; | 168 | bool sparse_alloc; |
| 168 | 169 | ||
| 169 | Mapping(VAddr ptr_, u64 offset_, u64 size_, bool fixed_, bool big_page_, bool sparse_alloc_) | 170 | Mapping(NvCore::NvMap::Handle::Id handle_, DAddr ptr_, u64 offset_, u64 size_, bool fixed_, |
| 170 | : ptr(ptr_), offset(offset_), size(size_), fixed(fixed_), big_page(big_page_), | 171 | bool big_page_, bool sparse_alloc_) |
| 171 | sparse_alloc(sparse_alloc_) {} | 172 | : handle(handle_), ptr(ptr_), offset(offset_), size(size_), fixed(fixed_), |
| 173 | big_page(big_page_), sparse_alloc(sparse_alloc_) {} | ||
| 172 | }; | 174 | }; |
| 173 | 175 | ||
| 174 | struct Allocation { | 176 | struct Allocation { |
| @@ -212,9 +214,7 @@ private: | |||
| 212 | bool initialised{}; | 214 | bool initialised{}; |
| 213 | } vm; | 215 | } vm; |
| 214 | std::shared_ptr<Tegra::MemoryManager> gmmu; | 216 | std::shared_ptr<Tegra::MemoryManager> gmmu; |
| 215 | 217 | std::unordered_map<DeviceFD, size_t> sessions; | |
| 216 | // s32 channel{}; | ||
| 217 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; | ||
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | } // namespace Service::Nvidia::Devices | 220 | } // namespace Service::Nvidia::Devices |
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 9ab0ae4d8..78bc5f3c4 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -95,6 +95,9 @@ NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span<u8> data, De | |||
| 95 | offset += SliceVectors(data, fence_thresholds, params.fence_count, offset); | 95 | offset += SliceVectors(data, fence_thresholds, params.fence_count, offset); |
| 96 | 96 | ||
| 97 | auto& gpu = system.GPU(); | 97 | auto& gpu = system.GPU(); |
| 98 | //auto& device_memory = system.Host1x().MemoryManager(); | ||
| 99 | auto* session = core.GetSession(sessions[fd]); | ||
| 100 | |||
| 98 | if (gpu.UseNvdec()) { | 101 | if (gpu.UseNvdec()) { |
| 99 | for (std::size_t i = 0; i < syncpt_increments.size(); i++) { | 102 | for (std::size_t i = 0; i < syncpt_increments.size(); i++) { |
| 100 | const SyncptIncr& syncpt_incr = syncpt_increments[i]; | 103 | const SyncptIncr& syncpt_incr = syncpt_increments[i]; |
| @@ -106,7 +109,7 @@ NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span<u8> data, De | |||
| 106 | const auto object = nvmap.GetHandle(cmd_buffer.memory_id); | 109 | const auto object = nvmap.GetHandle(cmd_buffer.memory_id); |
| 107 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); | 110 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); |
| 108 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); | 111 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); |
| 109 | system.ApplicationMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), | 112 | session->process->GetMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), |
| 110 | cmdlist.size() * sizeof(u32)); | 113 | cmdlist.size() * sizeof(u32)); |
| 111 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); | 114 | gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); |
| 112 | } | 115 | } |
| @@ -136,7 +139,8 @@ NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { | |||
| 136 | NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd) { | 139 | NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd) { |
| 137 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); | 140 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); |
| 138 | for (size_t i = 0; i < num_entries; i++) { | 141 | for (size_t i = 0; i < num_entries; i++) { |
| 139 | entries[i].map_address = nvmap.PinHandle(entries[i].map_handle, sessions[fd]); | 142 | DAddr pin_address = nvmap.PinHandle(entries[i].map_handle, sessions[fd], true); |
| 143 | entries[i].map_address = static_cast<u32>(pin_address); | ||
| 140 | } | 144 | } |
| 141 | 145 | ||
| 142 | return NvResult::Success; | 146 | return NvResult::Success; |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 2b107f009..7765ca1be 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -123,8 +123,8 @@ NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) { | |||
| 123 | return NvResult::InsufficientMemory; | 123 | return NvResult::InsufficientMemory; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | const auto result = file.AllocateHandle(params.handle, params.flags, params.align, params.kind, | 126 | const auto result = |
| 127 | params.address, sessions[fd]); | 127 | handle_description->Alloc(params.flags, params.align, params.kind, params.address); |
| 128 | if (result != NvResult::Success) { | 128 | if (result != NvResult::Success) { |
| 129 | LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); | 129 | LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); |
| 130 | return result; | 130 | return result; |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index 492ad849a..6e4825313 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp | |||
| @@ -13,8 +13,6 @@ | |||
| 13 | #include "core/hle/service/nvdrv/nvdrv.h" | 13 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 14 | #include "core/hle/service/nvdrv/nvdrv_interface.h" | 14 | #include "core/hle/service/nvdrv/nvdrv_interface.h" |
| 15 | 15 | ||
| 16 | #pragma optimize("", off) | ||
| 17 | |||
| 18 | namespace Service::Nvidia { | 16 | namespace Service::Nvidia { |
| 19 | 17 | ||
| 20 | void NVDRV::Open(HLERequestContext& ctx) { | 18 | void NVDRV::Open(HLERequestContext& ctx) { |
| @@ -173,8 +171,8 @@ void NVDRV::Initialize(HLERequestContext& ctx) { | |||
| 173 | [[maybe_unused]] const auto transfer_memory_size = rp.Pop<u32>(); | 171 | [[maybe_unused]] const auto transfer_memory_size = rp.Pop<u32>(); |
| 174 | 172 | ||
| 175 | auto& container = nvdrv->GetContainer(); | 173 | auto& container = nvdrv->GetContainer(); |
| 176 | auto process = ctx.GetObjectFromHandle(process_handle); | 174 | auto process = ctx.GetObjectFromHandle<Kernel::KProcess>(process_handle); |
| 177 | session_id = container.OpenSession(process->DynamicCast<Kernel::KProcess*>()); | 175 | session_id = container.OpenSession(process.GetPointerUnsafe()); |
| 178 | 176 | ||
| 179 | is_initialized = true; | 177 | is_initialized = true; |
| 180 | } | 178 | } |