From 6256e3ca8e74d7f97e4dabc3e9b24de1a0d8df3c Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 10:28:03 -0400 Subject: [PATCH 1/8] nvdrv: add ioctl command serialization, convert nvhost_as_gpu --- .../nvdrv/devices/ioctl_serialization.h | 107 ++++++++++++++++++ src/core/hle/service/nvdrv/devices/nvdevice.h | 12 ++ .../service/nvdrv/devices/nvhost_as_gpu.cpp | 78 ++++--------- .../hle/service/nvdrv/devices/nvhost_as_gpu.h | 20 ++-- .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 6 +- 5 files changed, 152 insertions(+), 71 deletions(-) create mode 100644 src/core/hle/service/nvdrv/devices/ioctl_serialization.h diff --git a/src/core/hle/service/nvdrv/devices/ioctl_serialization.h b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h new file mode 100644 index 000000000..c560974f1 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/concepts.h" +#include "core/hle/service/nvdrv/devices/nvdevice.h" + +namespace Service::Nvidia::Devices { + +struct Ioctl1Traits { + template + static T GetClassImpl(R (T::*)(A)); + + template + static A GetArgImpl(R (T::*)(A)); +}; + +struct Ioctl23Traits { + template + static T GetClassImpl(R (T::*)(A, B)); + + template + static A GetArgImpl(R (T::*)(A, B)); +}; + +template +struct ContainerType { + using ValueType = T; +}; + +template +struct ContainerType { + using ValueType = T::value_type; +}; + +template +NvResult Wrap(std::span input, std::span output, Self* self, F&& callable, + Rest&&... rest) { + using Arg = ContainerType::ValueType; + constexpr bool ArgumentIsContainer = Common::IsContiguousContainer; + + // Verify that the input and output sizes are valid. + const size_t in_params = input.size() / sizeof(Arg); + const size_t out_params = output.size() / sizeof(Arg); + if (in_params * sizeof(Arg) != input.size()) { + return NvResult::InvalidSize; + } + if (out_params * sizeof(Arg) != output.size()) { + return NvResult::InvalidSize; + } + if (in_params == 0 && out_params == 0 && !ArgumentIsContainer) { + return NvResult::InvalidSize; + } + + // Copy inputs, if needed. + std::vector params(std::max(in_params, out_params)); + if (in_params > 0) { + std::memcpy(params.data(), input.data(), input.size()); + } + + // Perform the call. + NvResult result; + if constexpr (ArgumentIsContainer) { + result = (self->*callable)(params, std::forward(rest)...); + } else { + result = (self->*callable)(params.front(), std::forward(rest)...); + } + + // Copy outputs, if needed. + if (out_params > 0) { + std::memcpy(output.data(), params.data(), output.size()); + } + + return result; +} + +template +NvResult nvdevice::Wrap1(F&& callable, std::span input, std::span output) { + using Self = decltype(Ioctl1Traits::GetClassImpl(callable)); + using InnerArg = std::remove_reference_t; + + return Wrap(input, output, static_cast(this), callable); +} + +template +NvResult nvdevice::Wrap2(F&& callable, std::span input, std::span inline_input, + std::span output) { + using Self = decltype(Ioctl23Traits::GetClassImpl(callable)); + using InnerArg = std::remove_reference_t; + + return Wrap(input, output, static_cast(this), callable, inline_input); +} + +template +NvResult nvdevice::Wrap3(F&& callable, std::span input, std::span output, + std::span inline_output) { + using Self = decltype(Ioctl23Traits::GetClassImpl(callable)); + using InnerArg = std::remove_reference_t; + + return Wrap(input, output, static_cast(this), callable, inline_output); +} + +} // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index a04538d5d..af766f320 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -74,6 +74,18 @@ public: return nullptr; } +protected: + template + NvResult Wrap1(F&& callable, std::span input, std::span output); + + template + NvResult Wrap2(F&& callable, std::span input, std::span inline_input, + std::span output); + + template + NvResult Wrap3(F&& callable, std::span input, std::span output, + std::span inline_output); + protected: Core::System& system; }; 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 7d7bb8687..484001071 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -11,6 +11,7 @@ #include "core/core.h" #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/nvmap.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" #include "core/hle/service/nvdrv/nvdrv.h" @@ -33,21 +34,21 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span i case 'A': switch (command.cmd) { case 0x1: - return BindChannel(input, output); + return Wrap1(&nvhost_as_gpu::BindChannel, input, output); case 0x2: - return AllocateSpace(input, output); + return Wrap1(&nvhost_as_gpu::AllocateSpace, input, output); case 0x3: - return FreeSpace(input, output); + return Wrap1(&nvhost_as_gpu::FreeSpace, input, output); case 0x5: - return UnmapBuffer(input, output); + return Wrap1(&nvhost_as_gpu::UnmapBuffer, input, output); case 0x6: - return MapBufferEx(input, output); + return Wrap1(&nvhost_as_gpu::MapBufferEx, input, output); case 0x8: - return GetVARegions(input, output); + return Wrap1(&nvhost_as_gpu::GetVARegions1, input, output); case 0x9: - return AllocAsEx(input, output); + return Wrap1(&nvhost_as_gpu::AllocAsEx, input, output); case 0x14: - return Remap(input, output); + return Wrap1(&nvhost_as_gpu::Remap, input, output); default: break; } @@ -72,7 +73,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span i case 'A': switch (command.cmd) { case 0x8: - return GetVARegions(input, output, inline_output); + return Wrap3(&nvhost_as_gpu::GetVARegions3, input, output, inline_output); default: break; } @@ -87,10 +88,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span i void nvhost_as_gpu::OnOpen(DeviceFD fd) {} void nvhost_as_gpu::OnClose(DeviceFD fd) {} -NvResult nvhost_as_gpu::AllocAsEx(std::span input, std::span output) { - IoctlAllocAsEx params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); std::scoped_lock lock(mutex); @@ -141,10 +139,7 @@ NvResult nvhost_as_gpu::AllocAsEx(std::span input, std::span outpu return NvResult::Success; } -NvResult nvhost_as_gpu::AllocateSpace(std::span input, std::span output) { - IoctlAllocSpace params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::AllocateSpace(IoctlAllocSpace& params) { LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, params.page_size, params.flags); @@ -194,7 +189,6 @@ NvResult nvhost_as_gpu::AllocateSpace(std::span input, std::span o .big_pages = params.page_size != VM::YUZU_PAGESIZE, }; - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } @@ -222,10 +216,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) { mapping_map.erase(offset); } -NvResult nvhost_as_gpu::FreeSpace(std::span input, std::span output) { - IoctlFreeSpace params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, params.pages, params.page_size); @@ -264,18 +255,11 @@ NvResult nvhost_as_gpu::FreeSpace(std::span input, std::span outpu return NvResult::BadValue; } - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_as_gpu::Remap(std::span input, std::span output) { - const auto num_entries = input.size() / sizeof(IoctlRemapEntry); - - LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); - - std::scoped_lock lock(mutex); - entries.resize_destructive(num_entries); - std::memcpy(entries.data(), input.data(), input.size()); +NvResult nvhost_as_gpu::Remap(std::span entries) { + LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); if (!vm.initialised) { return NvResult::BadValue; @@ -317,14 +301,10 @@ NvResult nvhost_as_gpu::Remap(std::span input, std::span output) { } } - std::memcpy(output.data(), entries.data(), output.size()); return NvResult::Success; } -NvResult nvhost_as_gpu::MapBufferEx(std::span input, std::span output) { - IoctlMapBufferEx params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { LOG_DEBUG(Service_NVDRV, "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" ", offset={}", @@ -421,14 +401,10 @@ NvResult nvhost_as_gpu::MapBufferEx(std::span input, std::span out mapping_map[params.offset] = mapping; } - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_as_gpu::UnmapBuffer(std::span input, std::span output) { - IoctlUnmapBuffer params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); std::scoped_lock lock(mutex); @@ -464,9 +440,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(std::span input, std::span out return NvResult::Success; } -NvResult nvhost_as_gpu::BindChannel(std::span input, std::span output) { - IoctlBindChannel params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_as_gpu::BindChannel(IoctlBindChannel& params) { LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); auto gpu_channel_device = module.GetDevice(params.fd); @@ -493,10 +467,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) { }; } -NvResult nvhost_as_gpu::GetVARegions(std::span input, std::span output) { - IoctlGetVaRegions params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::GetVARegions1(IoctlGetVaRegions& params) { LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, params.buf_size); @@ -508,15 +479,10 @@ NvResult nvhost_as_gpu::GetVARegions(std::span input, std::span ou GetVARegionsImpl(params); - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_as_gpu::GetVARegions(std::span input, std::span output, - std::span inline_output) { - IoctlGetVaRegions params{}; - std::memcpy(¶ms, input.data(), input.size()); - +NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span inline_output) { LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, params.buf_size); @@ -528,9 +494,7 @@ NvResult nvhost_as_gpu::GetVARegions(std::span input, std::span ou GetVARegionsImpl(params); - std::memcpy(output.data(), ¶ms, output.size()); - std::memcpy(inline_output.data(), ¶ms.regions[0], sizeof(VaRegion)); - std::memcpy(inline_output.data() + sizeof(VaRegion), ¶ms.regions[1], sizeof(VaRegion)); + std::memcpy(inline_output.data(), params.regions.data(), 2 * sizeof(VaRegion)); return NvResult::Success; } 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 2af3e1260..bc041f215 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -139,18 +139,17 @@ private: static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, "IoctlGetVaRegions is incorrect size"); - NvResult AllocAsEx(std::span input, std::span output); - NvResult AllocateSpace(std::span input, std::span output); - NvResult Remap(std::span input, std::span output); - NvResult MapBufferEx(std::span input, std::span output); - NvResult UnmapBuffer(std::span input, std::span output); - NvResult FreeSpace(std::span input, std::span output); - NvResult BindChannel(std::span input, std::span output); + NvResult AllocAsEx(IoctlAllocAsEx& params); + NvResult AllocateSpace(IoctlAllocSpace& params); + NvResult Remap(std::span params); + NvResult MapBufferEx(IoctlMapBufferEx& params); + NvResult UnmapBuffer(IoctlUnmapBuffer& params); + NvResult FreeSpace(IoctlFreeSpace& params); + NvResult BindChannel(IoctlBindChannel& params); void GetVARegionsImpl(IoctlGetVaRegions& params); - NvResult GetVARegions(std::span input, std::span output); - NvResult GetVARegions(std::span input, std::span output, - std::span inline_output); + NvResult GetVARegions1(IoctlGetVaRegions& params); + NvResult GetVARegions3(IoctlGetVaRegions& params, std::span inline_output); void FreeMappingLocked(u64 offset); @@ -213,7 +212,6 @@ private: bool initialised{}; } vm; std::shared_ptr gmmu; - Common::ScratchBuffer entries; // s32 channel{}; // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 46a25fcab..804157ce3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -134,7 +134,7 @@ NvResult nvhost_gpu::SetClientData(std::span input, std::span outp LOG_DEBUG(Service_NVDRV, "called"); IoctlClientData params{}; - std::memcpy(¶ms, input.data(), input.size()); + std::memcpy(¶ms, input.data(), std::min(sizeof(IoctlClientData), input.size())); user_data = params.data; return NvResult::Success; } @@ -143,9 +143,9 @@ NvResult nvhost_gpu::GetClientData(std::span input, std::span outp LOG_DEBUG(Service_NVDRV, "called"); IoctlClientData params{}; - std::memcpy(¶ms, input.data(), input.size()); + std::memcpy(¶ms, input.data(), std::min(sizeof(IoctlClientData), input.size())); params.data = user_data; - std::memcpy(output.data(), ¶ms, output.size()); + std::memcpy(output.data(), ¶ms, std::min(sizeof(IoctlClientData), output.size())); return NvResult::Success; } From 4df063209bebeb8737cbefd47a8958977aff9c2d Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 12:53:53 -0400 Subject: [PATCH 2/8] nvdrv: convert nvhost_ctrl_gpu --- .../service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 112 +++++------------- .../service/nvdrv/devices/nvhost_ctrl_gpu.h | 24 ++-- 2 files changed, 41 insertions(+), 95 deletions(-) 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 6081d92e9..92e677b3d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -6,6 +6,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/core_timing.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" #include "core/hle/service/nvdrv/nvdrv.h" @@ -27,23 +28,23 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span case 'G': switch (command.cmd) { case 0x1: - return ZCullGetCtxSize(input, output); + return Wrap1(&nvhost_ctrl_gpu::ZCullGetCtxSize, input, output); case 0x2: - return ZCullGetInfo(input, output); + return Wrap1(&nvhost_ctrl_gpu::ZCullGetInfo, input, output); case 0x3: - return ZBCSetTable(input, output); + return Wrap1(&nvhost_ctrl_gpu::ZBCSetTable, input, output); case 0x4: - return ZBCQueryTable(input, output); + return Wrap1(&nvhost_ctrl_gpu::ZBCQueryTable, input, output); case 0x5: - return GetCharacteristics(input, output); + return Wrap1(&nvhost_ctrl_gpu::GetCharacteristics1, input, output); case 0x6: - return GetTPCMasks(input, output); + return Wrap1(&nvhost_ctrl_gpu::GetTPCMasks1, input, output); case 0x7: - return FlushL2(input, output); + return Wrap1(&nvhost_ctrl_gpu::FlushL2, input, output); case 0x14: - return GetActiveSlotMask(input, output); + return Wrap1(&nvhost_ctrl_gpu::GetActiveSlotMask, input, output); case 0x1c: - return GetGpuTime(input, output); + return Wrap1(&nvhost_ctrl_gpu::GetGpuTime, input, output); default: break; } @@ -65,9 +66,9 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span case 'G': switch (command.cmd) { case 0x5: - return GetCharacteristics(input, output, inline_output); + return Wrap3(&nvhost_ctrl_gpu::GetCharacteristics3, input, output, inline_output); case 0x6: - return GetTPCMasks(input, output, inline_output); + return Wrap3(&nvhost_ctrl_gpu::GetTPCMasks3, input, output, inline_output); default: break; } @@ -82,10 +83,8 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} -NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) { LOG_DEBUG(Service_NVDRV, "called"); - IoctlCharacteristics params{}; - std::memcpy(¶ms, input.data(), input.size()); params.gc.arch = 0x120; params.gc.impl = 0xb; params.gc.rev = 0xa1; @@ -123,15 +122,13 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span input, std::spa params.gc.gr_compbit_store_base_hw = 0x0; params.gpu_characteristics_buf_size = 0xA0; params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span input, std::span output, - std::span inline_output) { +NvResult nvhost_ctrl_gpu::GetCharacteristics3(IoctlCharacteristics& params, + std::span inline_output) { LOG_DEBUG(Service_NVDRV, "called"); - IoctlCharacteristics params{}; - std::memcpy(¶ms, input.data(), input.size()); + params.gc.arch = 0x120; params.gc.impl = 0xb; params.gc.rev = 0xa1; @@ -169,70 +166,46 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span input, std::spa params.gc.gr_compbit_store_base_hw = 0x0; params.gpu_characteristics_buf_size = 0xA0; params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) - - std::memcpy(output.data(), ¶ms, output.size()); - std::memcpy(inline_output.data(), ¶ms.gc, inline_output.size()); + std::memcpy(inline_output.data(), ¶ms.gc, + std::min(sizeof(params.gc), inline_output.size())); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span input, std::span output) { - IoctlGpuGetTpcMasksArgs params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_ctrl_gpu::GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params) { LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); if (params.mask_buffer_size != 0) { params.tcp_mask = 3; } - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span input, std::span output, - std::span inline_output) { - IoctlGpuGetTpcMasksArgs params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_ctrl_gpu::GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, + std::span inline_output) { LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); if (params.mask_buffer_size != 0) { params.tcp_mask = 3; } - std::memcpy(output.data(), ¶ms, output.size()); - std::memcpy(inline_output.data(), ¶ms.tcp_mask, inline_output.size()); + std::memcpy(inline_output.data(), ¶ms.tcp_mask, + std::min(sizeof(params.tcp_mask), inline_output.size())); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::GetActiveSlotMask(IoctlActiveSlotMask& params) { LOG_DEBUG(Service_NVDRV, "called"); - IoctlActiveSlotMask params{}; - if (input.size() > 0) { - std::memcpy(¶ms, input.data(), input.size()); - } params.slot = 0x07; params.mask = 0x01; - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(IoctlZcullGetCtxSize& params) { LOG_DEBUG(Service_NVDRV, "called"); - - IoctlZcullGetCtxSize params{}; - if (input.size() > 0) { - std::memcpy(¶ms, input.data(), input.size()); - } params.size = 0x1; - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) { LOG_DEBUG(Service_NVDRV, "called"); - - IoctlNvgpuGpuZcullGetInfoArgs params{}; - - if (input.size() > 0) { - std::memcpy(¶ms, input.data(), input.size()); - } - params.width_align_pixels = 0x20; params.height_align_pixels = 0x20; params.pixel_squares_by_aliquots = 0x400; @@ -243,53 +216,28 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span input, std::span params.subregion_width_align_pixels = 0x20; params.subregion_height_align_pixels = 0x40; params.subregion_count = 0x10; - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) { LOG_WARNING(Service_NVDRV, "(STUBBED) called"); - - IoctlZbcSetTable params{}; - std::memcpy(¶ms, input.data(), input.size()); // TODO(ogniK): What does this even actually do? - - // Prevent null pointer being passed as arg 1 - if (output.empty()) { - LOG_WARNING(Service_NVDRV, "Avoiding passing null pointer to memcpy"); - } else { - std::memcpy(output.data(), ¶ms, output.size()); - } return NvResult::Success; } -NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) { LOG_WARNING(Service_NVDRV, "(STUBBED) called"); - - IoctlZbcQueryTable params{}; - std::memcpy(¶ms, input.data(), input.size()); - // TODO : To implement properly - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::FlushL2(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::FlushL2(IoctlFlushL2& params) { LOG_WARNING(Service_NVDRV, "(STUBBED) called"); - - IoctlFlushL2 params{}; - std::memcpy(¶ms, input.data(), input.size()); - // TODO : To implement properly - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetGpuTime(std::span input, std::span output) { +NvResult nvhost_ctrl_gpu::GetGpuTime(IoctlGetGpuTime& params) { LOG_DEBUG(Service_NVDRV, "called"); - - IoctlGetGpuTime params{}; - std::memcpy(¶ms, input.data(), input.size()); params.gpu_time = static_cast(system.CoreTiming().GetGlobalTimeNs().count()); - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } 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 97995551c..e1977a6b5 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -151,21 +151,19 @@ private: }; static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); - NvResult GetCharacteristics(std::span input, std::span output); - NvResult GetCharacteristics(std::span input, std::span output, - std::span inline_output); + NvResult GetCharacteristics1(IoctlCharacteristics& params); + NvResult GetCharacteristics3(IoctlCharacteristics& params, std::span inline_output); - NvResult GetTPCMasks(std::span input, std::span output); - NvResult GetTPCMasks(std::span input, std::span output, - std::span inline_output); + NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params); + NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span inline_output); - NvResult GetActiveSlotMask(std::span input, std::span output); - NvResult ZCullGetCtxSize(std::span input, std::span output); - NvResult ZCullGetInfo(std::span input, std::span output); - NvResult ZBCSetTable(std::span input, std::span output); - NvResult ZBCQueryTable(std::span input, std::span output); - NvResult FlushL2(std::span input, std::span output); - NvResult GetGpuTime(std::span input, std::span output); + NvResult GetActiveSlotMask(IoctlActiveSlotMask& params); + NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params); + NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params); + NvResult ZBCSetTable(IoctlZbcSetTable& params); + NvResult ZBCQueryTable(IoctlZbcQueryTable& params); + NvResult FlushL2(IoctlFlushL2& params); + NvResult GetGpuTime(IoctlGetGpuTime& params); EventInterface& events_interface; From 789d9c8af931490efd8647f286e136faaf062989 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 13:03:46 -0400 Subject: [PATCH 3/8] nvdrv: convert nvhost_ctrl --- .../hle/service/nvdrv/devices/nvhost_ctrl.cpp | 42 +++++++------------ .../hle/service/nvdrv/devices/nvhost_ctrl.h | 21 +++++++--- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 4d55554b4..8cefff6d1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -14,6 +14,7 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/syncpoint_manager.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" #include "video_core/gpu.h" #include "video_core/host1x/host1x.h" @@ -40,19 +41,19 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span inp case 0x0: switch (command.cmd) { case 0x1b: - return NvOsGetConfigU32(input, output); + return Wrap1(&nvhost_ctrl::NvOsGetConfigU32, input, output); case 0x1c: - return IocCtrlClearEventWait(input, output); + return Wrap1(&nvhost_ctrl::IocCtrlClearEventWait, input, output); case 0x1d: - return IocCtrlEventWait(input, output, true); + return Wrap1(&nvhost_ctrl::IocCtrlEventWaitWithAllocation, input, output); case 0x1e: - return IocCtrlEventWait(input, output, false); + return Wrap1(&nvhost_ctrl::IocCtrlEventWaitNotAllocation, input, output); case 0x1f: - return IocCtrlEventRegister(input, output); + return Wrap1(&nvhost_ctrl::IocCtrlEventRegister, input, output); case 0x20: - return IocCtrlEventUnregister(input, output); + return Wrap1(&nvhost_ctrl::IocCtrlEventUnregister, input, output); case 0x21: - return IocCtrlEventUnregisterBatch(input, output); + return Wrap1(&nvhost_ctrl::IocCtrlEventUnregisterBatch, input, output); } break; default: @@ -79,25 +80,19 @@ void nvhost_ctrl::OnOpen(DeviceFD fd) {} void nvhost_ctrl::OnClose(DeviceFD fd) {} -NvResult nvhost_ctrl::NvOsGetConfigU32(std::span input, std::span output) { - IocGetConfigParams params{}; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvhost_ctrl::NvOsGetConfigU32(IocGetConfigParams& params) { LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), params.param_str.data()); return NvResult::ConfigVarNotFound; // Returns error on production mode } -NvResult nvhost_ctrl::IocCtrlEventWait(std::span input, std::span output, - bool is_allocation) { - IocCtrlEventWaitParams params{}; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvhost_ctrl::IocCtrlEventWaitImpl(IocCtrlEventWaitParams& params, bool is_allocation) { LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_allocation={}", params.fence.id, params.fence.value, params.timeout, is_allocation); bool must_unmark_fail = !is_allocation; const u32 event_id = params.value.raw; SCOPE_EXIT({ - std::memcpy(output.data(), ¶ms, sizeof(params)); if (must_unmark_fail) { events[event_id].fails = 0; } @@ -231,9 +226,7 @@ NvResult nvhost_ctrl::FreeEvent(u32 slot) { return NvResult::Success; } -NvResult nvhost_ctrl::IocCtrlEventRegister(std::span input, std::span output) { - IocCtrlEventRegisterParams params{}; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvhost_ctrl::IocCtrlEventRegister(IocCtrlEventRegisterParams& params) { const u32 event_id = params.user_event_id; LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id); if (event_id >= MaxNvEvents) { @@ -252,9 +245,7 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(std::span input, std::span< return NvResult::Success; } -NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span input, std::span output) { - IocCtrlEventUnregisterParams params{}; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvhost_ctrl::IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params) { const u32 event_id = params.user_event_id & 0x00FF; LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id); @@ -262,9 +253,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span input, std::spa return FreeEvent(event_id); } -NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span input, std::span output) { - IocCtrlEventUnregisterBatchParams params{}; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params) { u64 event_mask = params.user_events; LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask); @@ -280,10 +269,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span input, std return NvResult::Success; } -NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span input, std::span output) { - IocCtrlEventClearParams params{}; - std::memcpy(¶ms, input.data(), sizeof(params)); - +NvResult nvhost_ctrl::IocCtrlClearEventWait(IocCtrlEventClearParams& params) { u32 event_id = params.event_id.slot; LOG_DEBUG(Service_NVDRV, "called, event_id: {:X}", event_id); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 2efed4862..6913c61ac 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -186,15 +186,24 @@ private: static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, "IocCtrlEventKill is incorrect size"); - NvResult NvOsGetConfigU32(std::span input, std::span output); - NvResult IocCtrlEventWait(std::span input, std::span output, bool is_allocation); - NvResult IocCtrlEventRegister(std::span input, std::span output); - NvResult IocCtrlEventUnregister(std::span input, std::span output); - NvResult IocCtrlEventUnregisterBatch(std::span input, std::span output); - NvResult IocCtrlClearEventWait(std::span input, std::span output); + NvResult NvOsGetConfigU32(IocGetConfigParams& params); + NvResult IocCtrlEventRegister(IocCtrlEventRegisterParams& params); + NvResult IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params); + NvResult IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params); + NvResult IocCtrlClearEventWait(IocCtrlEventClearParams& params); NvResult FreeEvent(u32 slot); + // TODO: these are not the correct names + NvResult IocCtrlEventWaitNotAllocation(IocCtrlEventWaitParams& params) { + return this->IocCtrlEventWaitImpl(params, false); + } + NvResult IocCtrlEventWaitWithAllocation(IocCtrlEventWaitParams& params) { + return this->IocCtrlEventWaitImpl(params, true); + } + + NvResult IocCtrlEventWaitImpl(IocCtrlEventWaitParams& params, bool is_allocation); + EventInterface& events_interface; NvCore::Container& core; NvCore::SyncpointManager& syncpoint_manager; From 7a84a1a9748d01961e91ad612ed338abf9ec844c Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 13:19:54 -0400 Subject: [PATCH 4/8] nvdrv: convert nvhost_gpu --- .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 93 +++++++------------ .../hle/service/nvdrv/devices/nvhost_gpu.h | 32 ++++--- 2 files changed, 49 insertions(+), 76 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 804157ce3..3abba25de 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -8,6 +8,7 @@ #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/nvmap.h" #include "core/hle/service/nvdrv/core/syncpoint_manager.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/memory.h" @@ -52,7 +53,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 0x0: switch (command.cmd) { case 0x3: - return GetWaitbase(input, output); + return Wrap1(&nvhost_gpu::GetWaitbase, input, output); default: break; } @@ -60,25 +61,25 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1: - return SetNVMAPfd(input, output); + return Wrap1(&nvhost_gpu::SetNVMAPfd, input, output); case 0x3: - return ChannelSetTimeout(input, output); + return Wrap1(&nvhost_gpu::ChannelSetTimeout, input, output); case 0x8: - return SubmitGPFIFOBase(input, output, false); + return SubmitGPFIFOBase1(input, output, false); case 0x9: - return AllocateObjectContext(input, output); + return Wrap1(&nvhost_gpu::AllocateObjectContext, input, output); case 0xb: - return ZCullBind(input, output); + return Wrap1(&nvhost_gpu::ZCullBind, input, output); case 0xc: - return SetErrorNotifier(input, output); + return Wrap1(&nvhost_gpu::SetErrorNotifier, input, output); case 0xd: - return SetChannelPriority(input, output); + return Wrap1(&nvhost_gpu::SetChannelPriority, input, output); case 0x1a: - return AllocGPFIFOEx2(input, output); + return Wrap1(&nvhost_gpu::AllocGPFIFOEx2, input, output); case 0x1b: - return SubmitGPFIFOBase(input, output, true); + return SubmitGPFIFOBase1(input, output, true); case 0x1d: - return ChannelSetTimeslice(input, output); + return Wrap1(&nvhost_gpu::ChannelSetTimeslice, input, output); default: break; } @@ -86,9 +87,9 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 'G': switch (command.cmd) { case 0x14: - return SetClientData(input, output); + return Wrap1(&nvhost_gpu::SetClientData, input, output); case 0x15: - return GetClientData(input, output); + return Wrap1(&nvhost_gpu::GetClientData, input, output); default: break; } @@ -104,7 +105,7 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1b: - return SubmitGPFIFOBase(input, inline_input, output); + return SubmitGPFIFOBase2(input, inline_input, output); } break; } @@ -121,63 +122,45 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span inpu void nvhost_gpu::OnOpen(DeviceFD fd) {} void nvhost_gpu::OnClose(DeviceFD fd) {} -NvResult nvhost_gpu::SetNVMAPfd(std::span input, std::span output) { - IoctlSetNvmapFD params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_fd = params.nvmap_fd; return NvResult::Success; } -NvResult nvhost_gpu::SetClientData(std::span input, std::span output) { +NvResult nvhost_gpu::SetClientData(IoctlClientData& params) { LOG_DEBUG(Service_NVDRV, "called"); - - IoctlClientData params{}; - std::memcpy(¶ms, input.data(), std::min(sizeof(IoctlClientData), input.size())); user_data = params.data; return NvResult::Success; } -NvResult nvhost_gpu::GetClientData(std::span input, std::span output) { +NvResult nvhost_gpu::GetClientData(IoctlClientData& params) { LOG_DEBUG(Service_NVDRV, "called"); - - IoctlClientData params{}; - std::memcpy(¶ms, input.data(), std::min(sizeof(IoctlClientData), input.size())); params.data = user_data; - std::memcpy(output.data(), ¶ms, std::min(sizeof(IoctlClientData), output.size())); return NvResult::Success; } -NvResult nvhost_gpu::ZCullBind(std::span input, std::span output) { - std::memcpy(&zcull_params, input.data(), input.size()); +NvResult nvhost_gpu::ZCullBind(IoctlZCullBind& params) { + zcull_params = params; LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, zcull_params.mode); - - std::memcpy(output.data(), &zcull_params, output.size()); return NvResult::Success; } -NvResult nvhost_gpu::SetErrorNotifier(std::span input, std::span output) { - IoctlSetErrorNotifier params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_gpu::SetErrorNotifier(IoctlSetErrorNotifier& params) { LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, params.size, params.mem); - - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_gpu::SetChannelPriority(std::span input, std::span output) { - std::memcpy(&channel_priority, input.data(), input.size()); +NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) { + channel_priority = params.priority; LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); - return NvResult::Success; } -NvResult nvhost_gpu::AllocGPFIFOEx2(std::span input, std::span output) { - IoctlAllocGpfifoEx2 params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { LOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " "unk1={:X}, unk2={:X}, unk3={:X}", @@ -193,18 +176,14 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(std::span input, std::span out params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_gpu::AllocateObjectContext(std::span input, std::span output) { - IoctlAllocObjCtx params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_gpu::AllocateObjectContext(IoctlAllocObjCtx& params) { LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, params.flags); params.obj_id = 0x0; - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } @@ -290,12 +269,11 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span o flags.raw = 0; - std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); return NvResult::Success; } -NvResult nvhost_gpu::SubmitGPFIFOBase(std::span input, std::span output, - bool kickoff) { +NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span input, std::span output, + bool kickoff) { if (input.size() < sizeof(IoctlSubmitGpfifo)) { UNIMPLEMENTED(); return NvResult::InvalidSize; @@ -315,8 +293,8 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span input, std::span o return SubmitGPFIFOImpl(params, output, std::move(entries)); } -NvResult nvhost_gpu::SubmitGPFIFOBase(std::span input, std::span input_inline, - std::span output) { +NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span input, std::span input_inline, + std::span output) { if (input.size() < sizeof(IoctlSubmitGpfifo)) { UNIMPLEMENTED(); return NvResult::InvalidSize; @@ -328,27 +306,20 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span input, std::span input, std::span output) { - IoctlGetWaitbase params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); +NvResult nvhost_gpu::GetWaitbase(IoctlGetWaitbase& params) { LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); params.value = 0; // Seems to be hard coded at 0 - std::memcpy(output.data(), ¶ms, output.size()); return NvResult::Success; } -NvResult nvhost_gpu::ChannelSetTimeout(std::span input, std::span output) { - IoctlChannelSetTimeout params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlChannelSetTimeout)); +NvResult nvhost_gpu::ChannelSetTimeout(IoctlChannelSetTimeout& params) { LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); return NvResult::Success; } -NvResult nvhost_gpu::ChannelSetTimeslice(std::span input, std::span output) { - IoctlSetTimeslice params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlSetTimeslice)); +NvResult nvhost_gpu::ChannelSetTimeslice(IoctlSetTimeslice& params) { LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); channel_timeslice = 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 529c20526..fba4232c4 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -186,23 +186,25 @@ private: u32_le channel_priority{}; u32_le channel_timeslice{}; - NvResult SetNVMAPfd(std::span input, std::span output); - NvResult SetClientData(std::span input, std::span output); - NvResult GetClientData(std::span input, std::span output); - NvResult ZCullBind(std::span input, std::span output); - NvResult SetErrorNotifier(std::span input, std::span output); - NvResult SetChannelPriority(std::span input, std::span output); - NvResult AllocGPFIFOEx2(std::span input, std::span output); - NvResult AllocateObjectContext(std::span input, std::span output); + NvResult SetNVMAPfd(IoctlSetNvmapFD& params); + NvResult SetClientData(IoctlClientData& params); + NvResult GetClientData(IoctlClientData& params); + NvResult ZCullBind(IoctlZCullBind& params); + NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); + NvResult SetChannelPriority(IoctlChannelSetPriority& params); + NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params); + NvResult AllocateObjectContext(IoctlAllocObjCtx& params); + NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span output, Tegra::CommandList&& entries); - NvResult SubmitGPFIFOBase(std::span input, std::span output, - bool kickoff = false); - NvResult SubmitGPFIFOBase(std::span input, std::span input_inline, - std::span output); - NvResult GetWaitbase(std::span input, std::span output); - NvResult ChannelSetTimeout(std::span input, std::span output); - NvResult ChannelSetTimeslice(std::span input, std::span output); + NvResult SubmitGPFIFOBase1(std::span input, std::span output, + bool kickoff = false); + NvResult SubmitGPFIFOBase2(std::span input, std::span input_inline, + std::span output); + + NvResult GetWaitbase(IoctlGetWaitbase& params); + NvResult ChannelSetTimeout(IoctlChannelSetTimeout& params); + NvResult ChannelSetTimeslice(IoctlSetTimeslice& params); EventInterface& events_interface; NvCore::Container& core; From efdb2e8f3dfc1106ee601a2e0cc479c35aa83698 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 13:30:35 -0400 Subject: [PATCH 5/8] nvdrv: convert codec devices --- .../service/nvdrv/devices/nvhost_nvdec.cpp | 9 +++--- .../nvdrv/devices/nvhost_nvdec_common.cpp | 30 ++++++++----------- .../nvdrv/devices/nvhost_nvdec_common.h | 8 ++--- .../service/nvdrv/devices/nvhost_nvjpg.cpp | 7 ++--- .../hle/service/nvdrv/devices/nvhost_nvjpg.h | 2 +- .../hle/service/nvdrv/devices/nvhost_vic.cpp | 7 +++-- 6 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index a174442a6..74790a7d8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -6,6 +6,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/core/container.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" #include "video_core/renderer_base.h" @@ -28,11 +29,11 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span in return Submit(fd, input, output); } case 0x2: - return GetSyncpoint(input, output); + return Wrap1(&nvhost_nvdec::GetSyncpoint, input, output); case 0x3: - return GetWaitbase(input, output); + return Wrap1(&nvhost_nvdec::GetWaitbase, input, output); case 0x7: - return SetSubmitTimeout(input, output); + return Wrap1(&nvhost_nvdec::SetSubmitTimeout, input, output); case 0x9: return MapBuffer(input, output); case 0xa: @@ -44,7 +45,7 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span in case 'H': switch (command.cmd) { case 0x1: - return SetNVMAPfd(input); + return Wrap1(&nvhost_nvdec::SetNVMAPfd, input, output); default: break; } 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 61649aa4a..51659934b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -63,9 +63,7 @@ nvhost_nvdec_common::~nvhost_nvdec_common() { core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint); } -NvResult nvhost_nvdec_common::SetNVMAPfd(std::span input) { - IoctlSetNvmapFD params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD)); +NvResult nvhost_nvdec_common::SetNVMAPfd(IoctlSetNvmapFD& params) { LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_fd = params.nvmap_fd; @@ -74,7 +72,7 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(std::span input) { NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span input, std::span output) { IoctlSubmit params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); + std::memcpy(¶ms, input.data(), std::min(input.size(), sizeof(IoctlSubmit))); LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); // Instantiate param buffers @@ -120,24 +118,15 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span input, std return NvResult::Success; } -NvResult nvhost_nvdec_common::GetSyncpoint(std::span input, std::span output) { - IoctlGetSyncpoint params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); +NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) { LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); - - // const u32 id{NvCore::SyncpointManager::channel_syncpoints[static_cast(channel_type)]}; params.value = channel_syncpoint; - std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); - return NvResult::Success; } -NvResult nvhost_nvdec_common::GetWaitbase(std::span input, std::span output) { - IoctlGetWaitbase params{}; +NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); - std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); params.value = 0; // Seems to be hard coded at 0 - std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); return NvResult::Success; } @@ -151,6 +140,12 @@ NvResult nvhost_nvdec_common::MapBuffer(std::span input, std::span for (auto& cmd_buffer : cmd_buffer_handles) { cmd_buffer.map_address = nvmap.PinHandle(cmd_buffer.map_handle); } + + if (output.size() < + sizeof(IoctlMapBuffer) + cmd_buffer_handles.size() * sizeof(MapBufferEntry)) { + return NvResult::InvalidSize; + } + std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); std::memcpy(output.data() + sizeof(IoctlMapBuffer), cmd_buffer_handles.data(), cmd_buffer_handles.size() * sizeof(MapBufferEntry)); @@ -160,7 +155,7 @@ NvResult nvhost_nvdec_common::MapBuffer(std::span input, std::span NvResult nvhost_nvdec_common::UnmapBuffer(std::span input, std::span output) { IoctlMapBuffer params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); + std::memcpy(¶ms, input.data(), std::min(input.size(), sizeof(IoctlMapBuffer))); std::vector cmd_buffer_handles(params.num_entries); SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); @@ -172,8 +167,7 @@ NvResult nvhost_nvdec_common::UnmapBuffer(std::span input, std::span input, std::span output) { - std::memcpy(&submit_timeout, input.data(), input.size()); +NvResult nvhost_nvdec_common::SetSubmitTimeout(u32 timeout) { LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 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 9bb573bfe..cc988b897 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h @@ -107,13 +107,13 @@ protected: static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); /// Ioctl command implementations - NvResult SetNVMAPfd(std::span input); + NvResult SetNVMAPfd(IoctlSetNvmapFD&); NvResult Submit(DeviceFD fd, std::span input, std::span output); - NvResult GetSyncpoint(std::span input, std::span output); - NvResult GetWaitbase(std::span input, std::span output); + NvResult GetSyncpoint(IoctlGetSyncpoint& params); + NvResult GetWaitbase(IoctlGetWaitbase& params); NvResult MapBuffer(std::span input, std::span output); NvResult UnmapBuffer(std::span input, std::span output); - NvResult SetSubmitTimeout(std::span input, std::span output); + NvResult SetSubmitTimeout(u32 timeout); Kernel::KEvent* QueryEvent(u32 event_id) override; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index a05c8cdae..23a57c4d5 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "common/logging/log.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" namespace Service::Nvidia::Devices { @@ -18,7 +19,7 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span in case 'H': switch (command.cmd) { case 0x1: - return SetNVMAPfd(input, output); + return Wrap1(&nvhost_nvjpg::SetNVMAPfd, input, output); default: break; } @@ -46,9 +47,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span in void nvhost_nvjpg::OnOpen(DeviceFD fd) {} void nvhost_nvjpg::OnClose(DeviceFD fd) {} -NvResult nvhost_nvjpg::SetNVMAPfd(std::span input, std::span output) { - IoctlSetNvmapFD params{}; - std::memcpy(¶ms, input.data(), input.size()); +NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) { LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); nvmap_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 5623e0d47..790c97f6a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h @@ -33,7 +33,7 @@ private: s32_le nvmap_fd{}; - NvResult SetNVMAPfd(std::span input, std::span output); + NvResult SetNVMAPfd(IoctlSetNvmapFD& params); }; } // 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 c0b8684c3..20af75872 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -5,6 +5,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/core/container.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvhost_vic.h" #include "video_core/renderer_base.h" @@ -28,9 +29,9 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu return Submit(fd, input, output); } case 0x2: - return GetSyncpoint(input, output); + return Wrap1(&nvhost_vic::GetSyncpoint, input, output); case 0x3: - return GetWaitbase(input, output); + return Wrap1(&nvhost_vic::GetWaitbase, input, output); case 0x9: return MapBuffer(input, output); case 0xa: @@ -42,7 +43,7 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1: - return SetNVMAPfd(input); + return Wrap1(&nvhost_vic::SetNVMAPfd, input, output); default: break; } From 18450ebd7877d1832307545ee7b9225bb00e7884 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 13:36:57 -0400 Subject: [PATCH 6/8] nvdrv: convert nvmap --- src/core/hle/service/nvdrv/devices/nvmap.cpp | 47 +++++-------------- src/core/hle/service/nvdrv/devices/nvmap.h | 12 ++--- .../nvnflinger/fb_share_buffer_manager.cpp | 27 +++-------- 3 files changed, 26 insertions(+), 60 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 968eaa175..94286e295 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -13,6 +13,7 @@ #include "core/hle/kernel/k_process.h" #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/nvmap.h" +#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/nvmap.h" #include "core/memory.h" @@ -31,17 +32,17 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span input, case 0x1: switch (command.cmd) { case 0x1: - return IocCreate(input, output); + return Wrap1(&nvmap::IocCreate, input, output); case 0x3: - return IocFromId(input, output); + return Wrap1(&nvmap::IocFromId, input, output); case 0x4: - return IocAlloc(input, output); + return Wrap1(&nvmap::IocAlloc, input, output); case 0x5: - return IocFree(input, output); + return Wrap1(&nvmap::IocFree, input, output); case 0x9: - return IocParam(input, output); + return Wrap1(&nvmap::IocParam, input, output); case 0xe: - return IocGetId(input, output); + return Wrap1(&nvmap::IocGetId, input, output); default: break; } @@ -69,9 +70,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span input, st void nvmap::OnOpen(DeviceFD fd) {} void nvmap::OnClose(DeviceFD fd) {} -NvResult nvmap::IocCreate(std::span input, std::span output) { - IocCreateParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvmap::IocCreate(IocCreateParams& params) { LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); std::shared_ptr handle_description{}; @@ -85,13 +84,10 @@ NvResult nvmap::IocCreate(std::span input, std::span output) { params.handle = handle_description->id; LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size); - std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; } -NvResult nvmap::IocAlloc(std::span input, std::span output) { - IocAllocParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); +NvResult nvmap::IocAlloc(IocAllocParams& params) { LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); if (!params.handle) { @@ -133,14 +129,10 @@ NvResult nvmap::IocAlloc(std::span input, std::span output) { handle_description->size, Kernel::KMemoryPermission::None, true, false) .IsSuccess()); - std::memcpy(output.data(), ¶ms, sizeof(params)); return result; } -NvResult nvmap::IocGetId(std::span input, std::span output) { - IocGetIdParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); - +NvResult nvmap::IocGetId(IocGetIdParams& params) { LOG_DEBUG(Service_NVDRV, "called"); // See the comment in FromId for extra info on this function @@ -157,14 +149,10 @@ NvResult nvmap::IocGetId(std::span input, std::span output) { } params.id = handle_description->id; - std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; } -NvResult nvmap::IocFromId(std::span input, std::span output) { - IocFromIdParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); - +NvResult nvmap::IocFromId(IocFromIdParams& params) { LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id); // Handles and IDs are always the same value in nvmap however IDs can be used globally given the @@ -188,16 +176,12 @@ NvResult nvmap::IocFromId(std::span input, std::span output) { return result; } params.handle = handle_description->id; - std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; } -NvResult nvmap::IocParam(std::span input, std::span output) { +NvResult nvmap::IocParam(IocParamParams& params) { enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; - IocParamParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_DEBUG(Service_NVDRV, "called type={}", params.param); if (!params.handle) { @@ -237,14 +221,10 @@ NvResult nvmap::IocParam(std::span input, std::span output) { return NvResult::BadValue; } - std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; } -NvResult nvmap::IocFree(std::span input, std::span output) { - IocFreeParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); - +NvResult nvmap::IocFree(IocFreeParams& params) { LOG_DEBUG(Service_NVDRV, "called"); if (!params.handle) { @@ -267,7 +247,6 @@ NvResult nvmap::IocFree(std::span input, std::span output) { // This is possible when there's internal dups or other duplicates. } - std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; } diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index 4c0cc71cd..049c11028 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h @@ -99,12 +99,12 @@ public: }; static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); - NvResult IocCreate(std::span input, std::span output); - NvResult IocAlloc(std::span input, std::span output); - NvResult IocGetId(std::span input, std::span output); - NvResult IocFromId(std::span input, std::span output); - NvResult IocParam(std::span input, std::span output); - NvResult IocFree(std::span input, std::span output); + NvResult IocCreate(IocCreateParams& params); + NvResult IocAlloc(IocAllocParams& params); + NvResult IocGetId(IocGetIdParams& params); + NvResult IocFromId(IocFromIdParams& params); + NvResult IocParam(IocParamParams& params); + NvResult IocFree(IocFreeParams& params); private: /// Id to use for the next handle that is created. diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp index 2e29bc848..6dc327b8b 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp +++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp @@ -71,24 +71,17 @@ Result AllocateIoForProcessAddressSpace(Common::ProcessAddress* out_map_address, R_SUCCEED(); } -template -std::span SerializeIoc(T& params) { - return std::span(reinterpret_cast(std::addressof(params)), sizeof(T)); -} - Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, u32 size) { // Create a handle. - Nvidia::Devices::nvmap::IocCreateParams create_in_params{ + Nvidia::Devices::nvmap::IocCreateParams create_params{ .size = size, .handle = 0, }; - Nvidia::Devices::nvmap::IocCreateParams create_out_params{}; - R_UNLESS(nvmap.IocCreate(SerializeIoc(create_in_params), SerializeIoc(create_out_params)) == - Nvidia::NvResult::Success, + R_UNLESS(nvmap.IocCreate(create_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); // Assign the output handle. - *out_nv_map_handle = create_out_params.handle; + *out_nv_map_handle = create_params.handle; // We succeeded. R_SUCCEED(); @@ -96,13 +89,10 @@ Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { // Free the handle. - Nvidia::Devices::nvmap::IocFreeParams free_in_params{ + Nvidia::Devices::nvmap::IocFreeParams free_params{ .handle = handle, }; - Nvidia::Devices::nvmap::IocFreeParams free_out_params{}; - R_UNLESS(nvmap.IocFree(SerializeIoc(free_in_params), SerializeIoc(free_out_params)) == - Nvidia::NvResult::Success, - VI::ResultOperationFailed); + R_UNLESS(nvmap.IocFree(free_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); // We succeeded. R_SUCCEED(); @@ -111,7 +101,7 @@ Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, u32 size) { // Assign the allocated memory to the handle. - Nvidia::Devices::nvmap::IocAllocParams alloc_in_params{ + Nvidia::Devices::nvmap::IocAllocParams alloc_params{ .handle = handle, .heap_mask = 0, .flags = {}, @@ -119,10 +109,7 @@ Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::Proce .kind = 0, .address = GetInteger(buffer), }; - Nvidia::Devices::nvmap::IocAllocParams alloc_out_params{}; - R_UNLESS(nvmap.IocAlloc(SerializeIoc(alloc_in_params), SerializeIoc(alloc_out_params)) == - Nvidia::NvResult::Success, - VI::ResultOperationFailed); + R_UNLESS(nvmap.IocAlloc(alloc_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); // We succeeded. R_SUCCEED(); From 94b7ac50bb5283caf20989341e27d77ec2c57bef Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 24 Oct 2023 13:41:48 -0400 Subject: [PATCH 7/8] nvdrv: fix up remaining copy calls --- .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 20 +++++++++---------- .../hle/service/nvdrv/devices/nvhost_gpu.h | 9 +++------ .../nvdrv/devices/nvhost_nvdec_common.cpp | 10 ++++++++++ 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 3abba25de..2d67acc6a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -65,7 +65,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 0x3: return Wrap1(&nvhost_gpu::ChannelSetTimeout, input, output); case 0x8: - return SubmitGPFIFOBase1(input, output, false); + return SubmitGPFIFOBase1(input, false); case 0x9: return Wrap1(&nvhost_gpu::AllocateObjectContext, input, output); case 0xb: @@ -77,7 +77,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 0x1a: return Wrap1(&nvhost_gpu::AllocGPFIFOEx2, input, output); case 0x1b: - return SubmitGPFIFOBase1(input, output, true); + return SubmitGPFIFOBase1(input, true); case 0x1d: return Wrap1(&nvhost_gpu::ChannelSetTimeslice, input, output); default: @@ -105,7 +105,7 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1b: - return SubmitGPFIFOBase2(input, inline_input, output); + return SubmitGPFIFOBase2(input, inline_input); } break; } @@ -227,8 +227,7 @@ static boost::container::small_vector BuildIncrementW return result; } -NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span output, - Tegra::CommandList&& entries) { +NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries) { LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, params.num_entries, params.flags.raw); @@ -272,8 +271,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span o return NvResult::Success; } -NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span input, std::span output, - bool kickoff) { +NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span input, bool kickoff) { if (input.size() < sizeof(IoctlSubmitGpfifo)) { UNIMPLEMENTED(); return NvResult::InvalidSize; @@ -290,11 +288,11 @@ NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span input, std::span params.num_entries * sizeof(Tegra::CommandListHeader)); } - return SubmitGPFIFOImpl(params, output, std::move(entries)); + return SubmitGPFIFOImpl(params, std::move(entries)); } -NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span input, std::span input_inline, - std::span output) { +NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span input, + std::span input_inline) { if (input.size() < sizeof(IoctlSubmitGpfifo)) { UNIMPLEMENTED(); return NvResult::InvalidSize; @@ -303,7 +301,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span input, std::span output, - Tegra::CommandList&& entries); - NvResult SubmitGPFIFOBase1(std::span input, std::span output, - bool kickoff = false); - NvResult SubmitGPFIFOBase2(std::span input, std::span input_inline, - std::span output); + NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); + NvResult SubmitGPFIFOBase1(std::span input, bool kickoff = false); + NvResult SubmitGPFIFOBase2(std::span input, std::span input_inline); NvResult GetWaitbase(IoctlGetWaitbase& params); NvResult ChannelSetTimeout(IoctlChannelSetTimeout& params); 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 51659934b..3fdf383f0 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -29,6 +29,9 @@ std::size_t SliceVectors(std::span input, std::vector& dst, std::si return 0; } const size_t bytes_copied = count * sizeof(T); + if (input.size() < offset + bytes_copied) { + return 0; + } std::memcpy(dst.data(), input.data() + offset, bytes_copied); return bytes_copied; } @@ -41,6 +44,9 @@ std::size_t WriteVectors(std::span dst, const std::vector& src, std::size return 0; } const size_t bytes_copied = src.size() * sizeof(T); + if (dst.size() < offset + bytes_copied) { + return 0; + } std::memcpy(dst.data() + offset, src.data(), bytes_copied); return bytes_copied; } @@ -71,6 +77,10 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(IoctlSetNvmapFD& params) { } NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span input, std::span output) { + if (input.size() < sizeof(IoctlSubmit) || output.size() < sizeof(IoctlSubmit)) { + UNIMPLEMENTED(); + return NvResult::InvalidSize; + } IoctlSubmit params{}; std::memcpy(¶ms, input.data(), std::min(input.size(), sizeof(IoctlSubmit))); LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); From 723df0f3685f01ce5a0330d567932136a9de7a8f Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 25 Oct 2023 00:34:40 -0400 Subject: [PATCH 8/8] nvdrv: rework to remove memcpy --- .../nvdrv/devices/ioctl_serialization.h | 180 +++++++++++------- src/core/hle/service/nvdrv/devices/nvdevice.h | 12 -- .../service/nvdrv/devices/nvhost_as_gpu.cpp | 26 +-- .../hle/service/nvdrv/devices/nvhost_as_gpu.h | 2 +- .../hle/service/nvdrv/devices/nvhost_ctrl.cpp | 16 +- .../hle/service/nvdrv/devices/nvhost_ctrl.h | 11 +- .../service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 41 ++-- .../service/nvdrv/devices/nvhost_ctrl_gpu.h | 5 +- .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 52 ++--- .../hle/service/nvdrv/devices/nvhost_gpu.h | 6 +- .../service/nvdrv/devices/nvhost_nvdec.cpp | 14 +- .../nvdrv/devices/nvhost_nvdec_common.cpp | 71 +++---- .../nvdrv/devices/nvhost_nvdec_common.h | 6 +- .../service/nvdrv/devices/nvhost_nvjpg.cpp | 2 +- .../hle/service/nvdrv/devices/nvhost_vic.cpp | 12 +- src/core/hle/service/nvdrv/devices/nvmap.cpp | 12 +- 16 files changed, 243 insertions(+), 225 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/ioctl_serialization.h b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h index c560974f1..b12bcd138 100644 --- a/src/core/hle/service/nvdrv/devices/ioctl_serialization.h +++ b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h @@ -11,97 +11,149 @@ namespace Service::Nvidia::Devices { -struct Ioctl1Traits { - template - static T GetClassImpl(R (T::*)(A)); - - template - static A GetArgImpl(R (T::*)(A)); +struct IoctlOneArgTraits { + template + static A GetFirstArgImpl(R (T::*)(A, B...)); }; -struct Ioctl23Traits { - template - static T GetClassImpl(R (T::*)(A, B)); +struct IoctlTwoArgTraits { + template + static A GetFirstArgImpl(R (T::*)(A, B, C...)); - template - static A GetArgImpl(R (T::*)(A, B)); + template + static B GetSecondArgImpl(R (T::*)(A, B, C...)); }; -template -struct ContainerType { - using ValueType = T; -}; +struct Null {}; -template -struct ContainerType { - using ValueType = T::value_type; -}; +// clang-format off -template -NvResult Wrap(std::span input, std::span output, Self* self, F&& callable, - Rest&&... rest) { - using Arg = ContainerType::ValueType; - constexpr bool ArgumentIsContainer = Common::IsContiguousContainer; +template +NvResult WrapGeneric(F&& callable, std::span input, std::span inline_input, std::span output, std::span inline_output) { + constexpr bool HasFixedArg = !std::is_same_v; + constexpr bool HasVarArg = !std::is_same_v; + constexpr bool HasInlInVarArg = !std::is_same_v; + constexpr bool HasInlOutVarArg = !std::is_same_v; - // Verify that the input and output sizes are valid. - const size_t in_params = input.size() / sizeof(Arg); - const size_t out_params = output.size() / sizeof(Arg); - if (in_params * sizeof(Arg) != input.size()) { - return NvResult::InvalidSize; - } - if (out_params * sizeof(Arg) != output.size()) { - return NvResult::InvalidSize; - } - if (in_params == 0 && out_params == 0 && !ArgumentIsContainer) { - return NvResult::InvalidSize; + // Declare the fixed-size input value. + FixedArg fixed{}; + size_t var_offset = 0; + + if constexpr (HasFixedArg) { + // Read the fixed-size input value. + var_offset = std::min(sizeof(FixedArg), input.size()); + if (var_offset > 0) { + std::memcpy(&fixed, input.data(), var_offset); + } } - // Copy inputs, if needed. - std::vector params(std::max(in_params, out_params)); - if (in_params > 0) { - std::memcpy(params.data(), input.data(), input.size()); + // Read the variable-sized inputs. + const size_t num_var_args = HasVarArg ? ((input.size() - var_offset) / sizeof(VarArg)) : 0; + std::vector var_args(num_var_args); + if constexpr (HasVarArg) { + if (num_var_args > 0) { + std::memcpy(var_args.data(), input.data() + var_offset, num_var_args * sizeof(VarArg)); + } } + const size_t num_inl_in_var_args = HasInlInVarArg ? (inline_input.size() / sizeof(InlInVarArg)) : 0; + std::vector inl_in_var_args(num_inl_in_var_args); + if constexpr (HasInlInVarArg) { + if (num_inl_in_var_args > 0) { + std::memcpy(inl_in_var_args.data(), inline_input.data(), num_inl_in_var_args * sizeof(InlInVarArg)); + } + } + + // Construct inline output data. + const size_t num_inl_out_var_args = HasInlOutVarArg ? (inline_output.size() / sizeof(InlOutVarArg)) : 0; + std::vector inl_out_var_args(num_inl_out_var_args); + // Perform the call. - NvResult result; - if constexpr (ArgumentIsContainer) { - result = (self->*callable)(params, std::forward(rest)...); - } else { - result = (self->*callable)(params.front(), std::forward(rest)...); + NvResult result = callable(fixed, var_args, inl_in_var_args, inl_out_var_args); + + // Copy outputs. + if constexpr (HasFixedArg) { + if (output.size() > 0) { + std::memcpy(output.data(), &fixed, std::min(output.size(), sizeof(FixedArg))); + } } - // Copy outputs, if needed. - if (out_params > 0) { - std::memcpy(output.data(), params.data(), output.size()); + if constexpr (HasVarArg) { + if (num_var_args > 0 && output.size() > var_offset) { + const size_t max_var_size = output.size() - var_offset; + std::memcpy(output.data() + var_offset, var_args.data(), std::min(max_var_size, num_var_args * sizeof(VarArg))); + } } + // Copy inline outputs. + if constexpr (HasInlOutVarArg) { + if (num_inl_out_var_args > 0) { + std::memcpy(inline_output.data(), inl_out_var_args.data(), num_inl_out_var_args * sizeof(InlOutVarArg)); + } + } + + // We're done. return result; } -template -NvResult nvdevice::Wrap1(F&& callable, std::span input, std::span output) { - using Self = decltype(Ioctl1Traits::GetClassImpl(callable)); - using InnerArg = std::remove_reference_t; +template +NvResult WrapFixed(Self* self, F&& callable, std::span input, std::span output, Rest&&... rest) { + using FixedArg = typename std::remove_reference_t; - return Wrap(input, output, static_cast(this), callable); + const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { + return (self->*callable)(fixed, std::forward(rest)...); + }; + + return WrapGeneric(std::move(Callable), input, {}, output, {}); } -template -NvResult nvdevice::Wrap2(F&& callable, std::span input, std::span inline_input, - std::span output) { - using Self = decltype(Ioctl23Traits::GetClassImpl(callable)); - using InnerArg = std::remove_reference_t; +template +NvResult WrapFixedInlOut(Self* self, F&& callable, std::span input, std::span output, std::span inline_output, Rest&&... rest) { + using FixedArg = typename std::remove_reference_t; + using InlOutVarArg = typename std::remove_reference_t::value_type; - return Wrap(input, output, static_cast(this), callable, inline_input); + const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { + return (self->*callable)(fixed, inl_out, std::forward(rest)...); + }; + + return WrapGeneric(std::move(Callable), input, {}, output, inline_output); } -template -NvResult nvdevice::Wrap3(F&& callable, std::span input, std::span output, - std::span inline_output) { - using Self = decltype(Ioctl23Traits::GetClassImpl(callable)); - using InnerArg = std::remove_reference_t; +template +NvResult WrapVariable(Self* self, F&& callable, std::span input, std::span output, Rest&&... rest) { + using VarArg = typename std::remove_reference_t::value_type; - return Wrap(input, output, static_cast(this), callable, inline_output); + const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { + return (self->*callable)(var, std::forward(rest)...); + }; + + return WrapGeneric(std::move(Callable), input, {}, output, {}); } +template +NvResult WrapFixedVariable(Self* self, F&& callable, std::span input, std::span output, Rest&&... rest) { + using FixedArg = typename std::remove_reference_t; + using VarArg = typename std::remove_reference_t::value_type; + + const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { + return (self->*callable)(fixed, var, std::forward(rest)...); + }; + + return WrapGeneric(std::move(Callable), input, {}, output, {}); +} + +template +NvResult WrapFixedInlIn(Self* self, F&& callable, std::span input, std::span inline_input, std::span output, Rest&&... rest) { + using FixedArg = typename std::remove_reference_t; + using InlInVarArg = typename std::remove_reference_t::value_type; + + const auto Callable = [&](auto& fixed, auto& var, auto& inl_in, auto& inl_out) -> NvResult { + return (self->*callable)(fixed, inl_in, std::forward(rest)...); + }; + + return WrapGeneric(std::move(Callable), input, inline_input, output, {}); +} + +// clang-format on + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index af766f320..a04538d5d 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -74,18 +74,6 @@ public: return nullptr; } -protected: - template - NvResult Wrap1(F&& callable, std::span input, std::span output); - - template - NvResult Wrap2(F&& callable, std::span input, std::span inline_input, - std::span output); - - template - NvResult Wrap3(F&& callable, std::span input, std::span output, - std::span inline_output); - protected: Core::System& system; }; 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 484001071..6b3639008 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -34,21 +34,21 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span i case 'A': switch (command.cmd) { case 0x1: - return Wrap1(&nvhost_as_gpu::BindChannel, input, output); + return WrapFixed(this, &nvhost_as_gpu::BindChannel, input, output); case 0x2: - return Wrap1(&nvhost_as_gpu::AllocateSpace, input, output); + return WrapFixed(this, &nvhost_as_gpu::AllocateSpace, input, output); case 0x3: - return Wrap1(&nvhost_as_gpu::FreeSpace, input, output); + return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); case 0x5: - return Wrap1(&nvhost_as_gpu::UnmapBuffer, input, output); + return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output); case 0x6: - return Wrap1(&nvhost_as_gpu::MapBufferEx, input, output); + return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output); case 0x8: - return Wrap1(&nvhost_as_gpu::GetVARegions1, input, output); + return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); case 0x9: - return Wrap1(&nvhost_as_gpu::AllocAsEx, input, output); + return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); case 0x14: - return Wrap1(&nvhost_as_gpu::Remap, input, output); + return WrapVariable(this, &nvhost_as_gpu::Remap, input, output); default: break; } @@ -73,7 +73,8 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span i case 'A': switch (command.cmd) { case 0x8: - return Wrap3(&nvhost_as_gpu::GetVARegions3, input, output, inline_output); + return WrapFixedInlOut(this, &nvhost_as_gpu::GetVARegions3, input, output, + inline_output); default: break; } @@ -482,7 +483,7 @@ NvResult nvhost_as_gpu::GetVARegions1(IoctlGetVaRegions& params) { return NvResult::Success; } -NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span inline_output) { +NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span regions) { LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, params.buf_size); @@ -494,7 +495,10 @@ NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span i GetVARegionsImpl(params); - std::memcpy(inline_output.data(), params.regions.data(), 2 * sizeof(VaRegion)); + const size_t num_regions = std::min(params.regions.size(), regions.size()); + for (size_t i = 0; i < num_regions; i++) { + regions[i] = params.regions[i]; + } return NvResult::Success; } 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 bc041f215..932997e75 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -149,7 +149,7 @@ private: void GetVARegionsImpl(IoctlGetVaRegions& params); NvResult GetVARegions1(IoctlGetVaRegions& params); - NvResult GetVARegions3(IoctlGetVaRegions& params, std::span inline_output); + NvResult GetVARegions3(IoctlGetVaRegions& params, std::span regions); void FreeMappingLocked(u64 offset); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 8cefff6d1..b8dd34e24 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -41,19 +41,19 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span inp case 0x0: switch (command.cmd) { case 0x1b: - return Wrap1(&nvhost_ctrl::NvOsGetConfigU32, input, output); + return WrapFixed(this, &nvhost_ctrl::NvOsGetConfigU32, input, output); case 0x1c: - return Wrap1(&nvhost_ctrl::IocCtrlClearEventWait, input, output); + return WrapFixed(this, &nvhost_ctrl::IocCtrlClearEventWait, input, output); case 0x1d: - return Wrap1(&nvhost_ctrl::IocCtrlEventWaitWithAllocation, input, output); + return WrapFixed(this, &nvhost_ctrl::IocCtrlEventWait, input, output, true); case 0x1e: - return Wrap1(&nvhost_ctrl::IocCtrlEventWaitNotAllocation, input, output); + return WrapFixed(this, &nvhost_ctrl::IocCtrlEventWait, input, output, false); case 0x1f: - return Wrap1(&nvhost_ctrl::IocCtrlEventRegister, input, output); + return WrapFixed(this, &nvhost_ctrl::IocCtrlEventRegister, input, output); case 0x20: - return Wrap1(&nvhost_ctrl::IocCtrlEventUnregister, input, output); + return WrapFixed(this, &nvhost_ctrl::IocCtrlEventUnregister, input, output); case 0x21: - return Wrap1(&nvhost_ctrl::IocCtrlEventUnregisterBatch, input, output); + return WrapFixed(this, &nvhost_ctrl::IocCtrlEventUnregisterBatch, input, output); } break; default: @@ -86,7 +86,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(IocGetConfigParams& params) { return NvResult::ConfigVarNotFound; // Returns error on production mode } -NvResult nvhost_ctrl::IocCtrlEventWaitImpl(IocCtrlEventWaitParams& params, bool is_allocation) { +NvResult nvhost_ctrl::IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_allocation) { LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_allocation={}", params.fence.id, params.fence.value, params.timeout, is_allocation); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 6913c61ac..992124b60 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -190,20 +190,11 @@ private: NvResult IocCtrlEventRegister(IocCtrlEventRegisterParams& params); NvResult IocCtrlEventUnregister(IocCtrlEventUnregisterParams& params); NvResult IocCtrlEventUnregisterBatch(IocCtrlEventUnregisterBatchParams& params); + NvResult IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_allocation); NvResult IocCtrlClearEventWait(IocCtrlEventClearParams& params); NvResult FreeEvent(u32 slot); - // TODO: these are not the correct names - NvResult IocCtrlEventWaitNotAllocation(IocCtrlEventWaitParams& params) { - return this->IocCtrlEventWaitImpl(params, false); - } - NvResult IocCtrlEventWaitWithAllocation(IocCtrlEventWaitParams& params) { - return this->IocCtrlEventWaitImpl(params, true); - } - - NvResult IocCtrlEventWaitImpl(IocCtrlEventWaitParams& params, bool is_allocation); - EventInterface& events_interface; NvCore::Container& core; NvCore::SyncpointManager& syncpoint_manager; 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 92e677b3d..61a2df121 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -28,23 +28,23 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span case 'G': switch (command.cmd) { case 0x1: - return Wrap1(&nvhost_ctrl_gpu::ZCullGetCtxSize, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::ZCullGetCtxSize, input, output); case 0x2: - return Wrap1(&nvhost_ctrl_gpu::ZCullGetInfo, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::ZCullGetInfo, input, output); case 0x3: - return Wrap1(&nvhost_ctrl_gpu::ZBCSetTable, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::ZBCSetTable, input, output); case 0x4: - return Wrap1(&nvhost_ctrl_gpu::ZBCQueryTable, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::ZBCQueryTable, input, output); case 0x5: - return Wrap1(&nvhost_ctrl_gpu::GetCharacteristics1, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::GetCharacteristics1, input, output); case 0x6: - return Wrap1(&nvhost_ctrl_gpu::GetTPCMasks1, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::GetTPCMasks1, input, output); case 0x7: - return Wrap1(&nvhost_ctrl_gpu::FlushL2, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output); case 0x14: - return Wrap1(&nvhost_ctrl_gpu::GetActiveSlotMask, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output); case 0x1c: - return Wrap1(&nvhost_ctrl_gpu::GetGpuTime, input, output); + return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output); default: break; } @@ -66,9 +66,11 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span case 'G': switch (command.cmd) { case 0x5: - return Wrap3(&nvhost_ctrl_gpu::GetCharacteristics3, input, output, inline_output); + return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetCharacteristics3, input, output, + inline_output); case 0x6: - return Wrap3(&nvhost_ctrl_gpu::GetTPCMasks3, input, output, inline_output); + return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetTPCMasks3, input, output, + inline_output); default: break; } @@ -125,8 +127,8 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) { return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetCharacteristics3(IoctlCharacteristics& params, - std::span inline_output) { +NvResult nvhost_ctrl_gpu::GetCharacteristics3( + IoctlCharacteristics& params, std::span gpu_characteristics) { LOG_DEBUG(Service_NVDRV, "called"); params.gc.arch = 0x120; @@ -166,8 +168,9 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics3(IoctlCharacteristics& params, params.gc.gr_compbit_store_base_hw = 0x0; params.gpu_characteristics_buf_size = 0xA0; params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) - std::memcpy(inline_output.data(), ¶ms.gc, - std::min(sizeof(params.gc), inline_output.size())); + if (!gpu_characteristics.empty()) { + gpu_characteristics.front() = params.gc; + } return NvResult::Success; } @@ -179,14 +182,14 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params) { return NvResult::Success; } -NvResult nvhost_ctrl_gpu::GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, - std::span inline_output) { +NvResult nvhost_ctrl_gpu::GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span tpc_mask) { LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); if (params.mask_buffer_size != 0) { params.tcp_mask = 3; } - std::memcpy(inline_output.data(), ¶ms.tcp_mask, - std::min(sizeof(params.tcp_mask), inline_output.size())); + if (!tpc_mask.empty()) { + tpc_mask.front() = params.tcp_mask; + } return NvResult::Success; } 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 e1977a6b5..d170299bd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -152,10 +152,11 @@ private: static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); NvResult GetCharacteristics1(IoctlCharacteristics& params); - NvResult GetCharacteristics3(IoctlCharacteristics& params, std::span inline_output); + NvResult GetCharacteristics3(IoctlCharacteristics& params, + std::span gpu_characteristics); NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params); - NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span inline_output); + NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span tpc_mask); NvResult GetActiveSlotMask(IoctlActiveSlotMask& params); NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 2d67acc6a..b0395c2f0 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -53,7 +53,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 0x0: switch (command.cmd) { case 0x3: - return Wrap1(&nvhost_gpu::GetWaitbase, input, output); + return WrapFixed(this, &nvhost_gpu::GetWaitbase, input, output); default: break; } @@ -61,25 +61,25 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1: - return Wrap1(&nvhost_gpu::SetNVMAPfd, input, output); + return WrapFixed(this, &nvhost_gpu::SetNVMAPfd, input, output); case 0x3: - return Wrap1(&nvhost_gpu::ChannelSetTimeout, input, output); + return WrapFixed(this, &nvhost_gpu::ChannelSetTimeout, input, output); case 0x8: - return SubmitGPFIFOBase1(input, false); + return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, false); case 0x9: - return Wrap1(&nvhost_gpu::AllocateObjectContext, input, output); + return WrapFixed(this, &nvhost_gpu::AllocateObjectContext, input, output); case 0xb: - return Wrap1(&nvhost_gpu::ZCullBind, input, output); + return WrapFixed(this, &nvhost_gpu::ZCullBind, input, output); case 0xc: - return Wrap1(&nvhost_gpu::SetErrorNotifier, input, output); + return WrapFixed(this, &nvhost_gpu::SetErrorNotifier, input, output); case 0xd: - return Wrap1(&nvhost_gpu::SetChannelPriority, input, output); + return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); case 0x1a: - return Wrap1(&nvhost_gpu::AllocGPFIFOEx2, input, output); + return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output); case 0x1b: - return SubmitGPFIFOBase1(input, true); + return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); case 0x1d: - return Wrap1(&nvhost_gpu::ChannelSetTimeslice, input, output); + return WrapFixed(this, &nvhost_gpu::ChannelSetTimeslice, input, output); default: break; } @@ -87,9 +87,9 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 'G': switch (command.cmd) { case 0x14: - return Wrap1(&nvhost_gpu::SetClientData, input, output); + return WrapFixed(this, &nvhost_gpu::SetClientData, input, output); case 0x15: - return Wrap1(&nvhost_gpu::GetClientData, input, output); + return WrapFixed(this, &nvhost_gpu::GetClientData, input, output); default: break; } @@ -105,7 +105,8 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1b: - return SubmitGPFIFOBase2(input, inline_input); + return WrapFixedInlIn(this, &nvhost_gpu::SubmitGPFIFOBase2, input, inline_input, + output); } break; } @@ -271,36 +272,35 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandL return NvResult::Success; } -NvResult nvhost_gpu::SubmitGPFIFOBase1(std::span input, bool kickoff) { - if (input.size() < sizeof(IoctlSubmitGpfifo)) { +NvResult nvhost_gpu::SubmitGPFIFOBase1(IoctlSubmitGpfifo& params, + std::span commands, bool kickoff) { + if (params.num_entries > commands.size()) { UNIMPLEMENTED(); return NvResult::InvalidSize; } - IoctlSubmitGpfifo params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); - Tegra::CommandList entries(params.num_entries); + Tegra::CommandList entries(params.num_entries); if (kickoff) { system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(), params.num_entries * sizeof(Tegra::CommandListHeader)); } else { - std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)], + std::memcpy(entries.command_lists.data(), commands.data(), params.num_entries * sizeof(Tegra::CommandListHeader)); } return SubmitGPFIFOImpl(params, std::move(entries)); } -NvResult nvhost_gpu::SubmitGPFIFOBase2(std::span input, - std::span input_inline) { - if (input.size() < sizeof(IoctlSubmitGpfifo)) { +NvResult nvhost_gpu::SubmitGPFIFOBase2(IoctlSubmitGpfifo& params, + std::span commands) { + if (params.num_entries > commands.size()) { UNIMPLEMENTED(); return NvResult::InvalidSize; } - IoctlSubmitGpfifo params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); + Tegra::CommandList entries(params.num_entries); - std::memcpy(entries.command_lists.data(), input_inline.data(), input_inline.size()); + std::memcpy(entries.command_lists.data(), commands.data(), + params.num_entries * sizeof(Tegra::CommandListHeader)); return SubmitGPFIFOImpl(params, std::move(entries)); } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 703079a54..88fd228ff 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -196,8 +196,10 @@ private: NvResult AllocateObjectContext(IoctlAllocObjCtx& params); NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); - NvResult SubmitGPFIFOBase1(std::span input, bool kickoff = false); - NvResult SubmitGPFIFOBase2(std::span input, std::span input_inline); + NvResult SubmitGPFIFOBase1(IoctlSubmitGpfifo& params, + std::span commands, bool kickoff = false); + NvResult SubmitGPFIFOBase2(IoctlSubmitGpfifo& params, + std::span commands); NvResult GetWaitbase(IoctlGetWaitbase& params); NvResult ChannelSetTimeout(IoctlChannelSetTimeout& params); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 74790a7d8..f43914e1b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -26,18 +26,18 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span in if (!host1x_file.fd_to_id.contains(fd)) { host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++; } - return Submit(fd, input, output); + return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd); } case 0x2: - return Wrap1(&nvhost_nvdec::GetSyncpoint, input, output); + return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output); case 0x3: - return Wrap1(&nvhost_nvdec::GetWaitbase, input, output); + return WrapFixed(this, &nvhost_nvdec::GetWaitbase, input, output); case 0x7: - return Wrap1(&nvhost_nvdec::SetSubmitTimeout, input, output); + return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); case 0x9: - return MapBuffer(input, output); + return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output); case 0xa: - return UnmapBuffer(input, output); + return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); default: break; } @@ -45,7 +45,7 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span in case 'H': switch (command.cmd) { case 0x1: - return Wrap1(&nvhost_nvdec::SetNVMAPfd, input, output); + return WrapFixed(this, &nvhost_nvdec::SetNVMAPfd, input, output); default: break; } 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 3fdf383f0..74c701b95 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -76,13 +76,7 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(IoctlSetNvmapFD& params) { return NvResult::Success; } -NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span input, std::span output) { - if (input.size() < sizeof(IoctlSubmit) || output.size() < sizeof(IoctlSubmit)) { - UNIMPLEMENTED(); - return NvResult::InvalidSize; - } - IoctlSubmit params{}; - std::memcpy(¶ms, input.data(), std::min(input.size(), sizeof(IoctlSubmit))); +NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span data, DeviceFD fd) { LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); // Instantiate param buffers @@ -93,12 +87,12 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span input, std std::vector fence_thresholds(params.fence_count); // Slice input into their respective buffers - std::size_t offset = sizeof(IoctlSubmit); - offset += SliceVectors(input, command_buffers, params.cmd_buffer_count, offset); - offset += SliceVectors(input, relocs, params.relocation_count, offset); - offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset); - offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset); - offset += SliceVectors(input, fence_thresholds, params.fence_count, offset); + std::size_t offset = 0; + offset += SliceVectors(data, command_buffers, params.cmd_buffer_count, offset); + offset += SliceVectors(data, relocs, params.relocation_count, offset); + offset += SliceVectors(data, reloc_shifts, params.relocation_count, offset); + offset += SliceVectors(data, syncpt_increments, params.syncpoint_count, offset); + offset += SliceVectors(data, fence_thresholds, params.fence_count, offset); auto& gpu = system.GPU(); if (gpu.UseNvdec()) { @@ -116,14 +110,13 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span input, std cmdlist.size() * sizeof(u32)); gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); } - std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); // Some games expect command_buffers to be written back - offset = sizeof(IoctlSubmit); - offset += WriteVectors(output, command_buffers, offset); - offset += WriteVectors(output, relocs, offset); - offset += WriteVectors(output, reloc_shifts, offset); - offset += WriteVectors(output, syncpt_increments, offset); - offset += WriteVectors(output, fence_thresholds, offset); + offset = 0; + offset += WriteVectors(data, command_buffers, offset); + offset += WriteVectors(data, relocs, offset); + offset += WriteVectors(data, reloc_shifts, offset); + offset += WriteVectors(data, syncpt_increments, offset); + offset += WriteVectors(data, fence_thresholds, offset); return NvResult::Success; } @@ -140,40 +133,24 @@ NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { return NvResult::Success; } -NvResult nvhost_nvdec_common::MapBuffer(std::span input, std::span output) { - IoctlMapBuffer params{}; - std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); - std::vector cmd_buffer_handles(params.num_entries); - - SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); - - for (auto& cmd_buffer : cmd_buffer_handles) { - cmd_buffer.map_address = nvmap.PinHandle(cmd_buffer.map_handle); +NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span entries) { + const size_t num_entries = std::min(params.num_entries, static_cast(entries.size())); + for (size_t i = 0; i < num_entries; i++) { + entries[i].map_address = nvmap.PinHandle(entries[i].map_handle); } - if (output.size() < - sizeof(IoctlMapBuffer) + cmd_buffer_handles.size() * sizeof(MapBufferEntry)) { - return NvResult::InvalidSize; - } - - std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); - std::memcpy(output.data() + sizeof(IoctlMapBuffer), cmd_buffer_handles.data(), - cmd_buffer_handles.size() * sizeof(MapBufferEntry)); - return NvResult::Success; } -NvResult nvhost_nvdec_common::UnmapBuffer(std::span input, std::span output) { - IoctlMapBuffer params{}; - std::memcpy(¶ms, input.data(), std::min(input.size(), sizeof(IoctlMapBuffer))); - std::vector cmd_buffer_handles(params.num_entries); - - SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); - for (auto& cmd_buffer : cmd_buffer_handles) { - nvmap.UnpinHandle(cmd_buffer.map_handle); +NvResult nvhost_nvdec_common::UnmapBuffer(IoctlMapBuffer& params, + std::span entries) { + const size_t num_entries = std::min(params.num_entries, static_cast(entries.size())); + for (size_t i = 0; i < num_entries; i++) { + nvmap.UnpinHandle(entries[i].map_handle); + entries[i] = {}; } - std::memset(output.data(), 0, output.size()); + params = {}; 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 cc988b897..7ce748e18 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h @@ -108,11 +108,11 @@ protected: /// Ioctl command implementations NvResult SetNVMAPfd(IoctlSetNvmapFD&); - NvResult Submit(DeviceFD fd, std::span input, std::span output); + NvResult Submit(IoctlSubmit& params, std::span input, DeviceFD fd); NvResult GetSyncpoint(IoctlGetSyncpoint& params); NvResult GetWaitbase(IoctlGetWaitbase& params); - NvResult MapBuffer(std::span input, std::span output); - NvResult UnmapBuffer(std::span input, std::span output); + NvResult MapBuffer(IoctlMapBuffer& params, std::span entries); + NvResult UnmapBuffer(IoctlMapBuffer& params, std::span entries); NvResult SetSubmitTimeout(u32 timeout); Kernel::KEvent* QueryEvent(u32 event_id) override; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index 23a57c4d5..9e6b86458 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp @@ -19,7 +19,7 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span in case 'H': switch (command.cmd) { case 0x1: - return Wrap1(&nvhost_nvjpg::SetNVMAPfd, input, output); + return WrapFixed(this, &nvhost_nvjpg::SetNVMAPfd, input, output); default: break; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 20af75872..87f8d7c22 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -26,16 +26,16 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu if (!host1x_file.fd_to_id.contains(fd)) { host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++; } - return Submit(fd, input, output); + return WrapFixedVariable(this, &nvhost_vic::Submit, input, output, fd); } case 0x2: - return Wrap1(&nvhost_vic::GetSyncpoint, input, output); + return WrapFixed(this, &nvhost_vic::GetSyncpoint, input, output); case 0x3: - return Wrap1(&nvhost_vic::GetWaitbase, input, output); + return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output); case 0x9: - return MapBuffer(input, output); + return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output); case 0xa: - return UnmapBuffer(input, output); + return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output); default: break; } @@ -43,7 +43,7 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span inpu case 'H': switch (command.cmd) { case 0x1: - return Wrap1(&nvhost_vic::SetNVMAPfd, input, output); + return WrapFixed(this, &nvhost_vic::SetNVMAPfd, input, output); default: break; } diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 94286e295..71b2e62ec 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -32,17 +32,17 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span input, case 0x1: switch (command.cmd) { case 0x1: - return Wrap1(&nvmap::IocCreate, input, output); + return WrapFixed(this, &nvmap::IocCreate, input, output); case 0x3: - return Wrap1(&nvmap::IocFromId, input, output); + return WrapFixed(this, &nvmap::IocFromId, input, output); case 0x4: - return Wrap1(&nvmap::IocAlloc, input, output); + return WrapFixed(this, &nvmap::IocAlloc, input, output); case 0x5: - return Wrap1(&nvmap::IocFree, input, output); + return WrapFixed(this, &nvmap::IocFree, input, output); case 0x9: - return Wrap1(&nvmap::IocParam, input, output); + return WrapFixed(this, &nvmap::IocParam, input, output); case 0xe: - return Wrap1(&nvmap::IocGetId, input, output); + return WrapFixed(this, &nvmap::IocGetId, input, output); default: break; }