From efdb2e8f3dfc1106ee601a2e0cc479c35aa83698 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 24 Oct 2023 13:30:35 -0400
Subject: [PATCH] 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 a174442a6c..74790a7d8a 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<const u8> 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<const u8> 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 61649aa4a0..51659934b7 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<const u8> input) {
-    IoctlSetNvmapFD params{};
-    std::memcpy(&params, 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<const u8> input) {
 
 NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output) {
     IoctlSubmit params{};
-    std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
+    std::memcpy(&params, 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<const u8> input, std
     return NvResult::Success;
 }
 
-NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::span<u8> output) {
-    IoctlGetSyncpoint params{};
-    std::memcpy(&params, 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<u32>(channel_type)]};
     params.value = channel_syncpoint;
-    std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
-
     return NvResult::Success;
 }
 
-NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::span<u8> output) {
-    IoctlGetWaitbase params{};
+NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) {
     LOG_CRITICAL(Service_NVDRV, "called WAITBASE");
-    std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
     params.value = 0; // Seems to be hard coded at 0
-    std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
     return NvResult::Success;
 }
 
@@ -151,6 +140,12 @@ NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::span<u8>
     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(), &params, 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<const u8> input, std::span<u8>
 
 NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::span<u8> output) {
     IoctlMapBuffer params{};
-    std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
+    std::memcpy(&params, input.data(), std::min(input.size(), sizeof(IoctlMapBuffer)));
     std::vector<MapBufferEntry> 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<const u8> input, std::span<u
     return NvResult::Success;
 }
 
-NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::span<u8> 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 9bb573bfee..cc988b897e 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<const u8> input);
+    NvResult SetNVMAPfd(IoctlSetNvmapFD&);
     NvResult Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output);
-    NvResult GetSyncpoint(std::span<const u8> input, std::span<u8> output);
-    NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output);
+    NvResult GetSyncpoint(IoctlGetSyncpoint& params);
+    NvResult GetWaitbase(IoctlGetWaitbase& params);
     NvResult MapBuffer(std::span<const u8> input, std::span<u8> output);
     NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output);
-    NvResult SetSubmitTimeout(std::span<const u8> input, std::span<u8> 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 a05c8cdaef..23a57c4d5c 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<const u8> 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<const u8> in
 void nvhost_nvjpg::OnOpen(DeviceFD fd) {}
 void nvhost_nvjpg::OnClose(DeviceFD fd) {}
 
-NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) {
-    IoctlSetNvmapFD params{};
-    std::memcpy(&params, 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 5623e0d473..790c97f6aa 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<const u8> input, std::span<u8> 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 c0b8684c38..20af758727 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<const u8> 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<const u8> inpu
     case 'H':
         switch (command.cmd) {
         case 0x1:
-            return SetNVMAPfd(input);
+            return Wrap1(&nvhost_vic::SetNVMAPfd, input, output);
         default:
             break;
         }