From cd3f444c59b54b614b06fb592246e0fa56c0a83c Mon Sep 17 00:00:00 2001
From: yuzubot <yuzu@yuzu-emu.org>
Date: Tue, 26 Nov 2019 13:01:21 +0000
Subject: "Merge Tagged PR 1703"

---
 .../hle/service/nvdrv/devices/nvhost_nvdec.cpp     | 70 +++++++++++++++++++++-
 src/core/hle/service/nvdrv/devices/nvhost_nvdec.h  | 52 +++++++++++++++-
 src/core/hle/service/nvdrv/devices/nvhost_vic.cpp  | 70 +++++++++++++++++++++-
 src/core/hle/service/nvdrv/devices/nvhost_vic.h    | 50 ++++++++++++++++
 4 files changed, 239 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index bdae8b8875..fcb612864c 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
     switch (static_cast<IoctlCommand>(command.raw)) {
     case IoctlCommand::IocSetNVMAPfdCommand:
         return SetNVMAPfd(input, output);
+    case IoctlCommand::IocSubmit:
+        return Submit(input, output);
+    case IoctlCommand::IocGetSyncpoint:
+        return GetSyncpoint(input, output);
+    case IoctlCommand::IocGetWaitbase:
+        return GetWaitbase(input, output);
+    case IoctlCommand::IocMapBuffer:
+        return MapBuffer(input, output);
+    case IoctlCommand::IocMapBufferEx:
+        return MapBufferEx(input, output);
+    case IoctlCommand::IocUnmapBufferEx:
+        return UnmapBufferEx(input, output);
     }
 
     UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
 
 u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
     IoctlSetNvmapFD params{};
-    std::memcpy(&params, input.data(), input.size());
+    std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
     LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
 
     nvmap_fd = params.nvmap_fd;
     return 0;
 }
 
+u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlSubmit params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called");
+    std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
+    return 0;
+}
+
+u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlGetSyncpoint params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
+    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
+    params.value = 0; // Seems to be hard coded at 0
+    std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
+    return 0;
+}
+
+u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlGetWaitbase params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
+    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
+    params.value = 0; // Seems to be hard coded at 0
+    std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
+    return 0;
+}
+
+u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlMapBuffer params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
+                params.address_1);
+    params.address_1 = 0;
+    params.address_2 = 0;
+    std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
+    return 0;
+}
+
+u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlMapBufferEx params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
+                params.address_1);
+    params.address_1 = 0;
+    params.address_2 = 0;
+    std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
+    return 0;
+}
+
+u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlUnmapBufferEx params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called");
+    std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
+    return 0;
+}
+
 } // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index cbdac8069d..4332db118b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -23,16 +23,66 @@ public:
 private:
     enum class IoctlCommand : u32_le {
         IocSetNVMAPfdCommand = 0x40044801,
+        IocSubmit = 0xC0400001,
+        IocGetSyncpoint = 0xC0080002,
+        IocGetWaitbase = 0xC0080003,
+        IocMapBuffer = 0xC01C0009,
+        IocMapBufferEx = 0xC0A40009,
+        IocUnmapBufferEx = 0xC0A4000A,
     };
 
     struct IoctlSetNvmapFD {
         u32_le nvmap_fd;
     };
-    static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
+    static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
+
+    struct IoctlSubmit {
+        INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
+
+    struct IoctlGetSyncpoint {
+        u32 unknown; // seems to be ignored? Nintendo added this
+        u32 value;
+    };
+    static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
+
+    struct IoctlGetWaitbase {
+        u32 unknown; // seems to be ignored? Nintendo added this
+        u32 value;
+    };
+    static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
+
+    struct IoctlMapBuffer {
+        u32 unknown;
+        u32 address_1;
+        u32 address_2;
+        INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
+
+    struct IoctlMapBufferEx {
+        u32 unknown;
+        u32 address_1;
+        u32 address_2;
+        INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
+
+    struct IoctlUnmapBufferEx {
+        INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
 
     u32_le nvmap_fd{};
 
     u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
 };
 
 } // 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 c695b88632..fea363a53a 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
     switch (static_cast<IoctlCommand>(command.raw)) {
     case IoctlCommand::IocSetNVMAPfdCommand:
         return SetNVMAPfd(input, output);
+    case IoctlCommand::IocSubmit:
+        return Submit(input, output);
+    case IoctlCommand::IocGetSyncpoint:
+        return GetSyncpoint(input, output);
+    case IoctlCommand::IocGetWaitbase:
+        return GetWaitbase(input, output);
+    case IoctlCommand::IocMapBuffer:
+        return MapBuffer(input, output);
+    case IoctlCommand::IocMapBufferEx:
+        return MapBuffer(input, output);
+    case IoctlCommand::IocUnmapBufferEx:
+        return UnmapBufferEx(input, output);
     }
 
     UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,67 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
 
 u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
     IoctlSetNvmapFD params{};
-    std::memcpy(&params, input.data(), input.size());
+    std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
     LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
 
     nvmap_fd = params.nvmap_fd;
     return 0;
 }
 
+u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlSubmit params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called");
+    std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
+    return 0;
+}
+
+u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlGetSyncpoint params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
+    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
+    params.value = 0; // Seems to be hard coded at 0
+    std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
+    return 0;
+}
+
+u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlGetWaitbase params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
+    LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
+    params.value = 0; // Seems to be hard coded at 0
+    std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
+    return 0;
+}
+
+u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlMapBuffer params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
+                params.address_1);
+    params.address_1 = 0;
+    params.address_2 = 0;
+    std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
+    return 0;
+}
+
+u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlMapBufferEx params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
+                params.address_1);
+    params.address_1 = 0;
+    params.address_2 = 0;
+    std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
+    return 0;
+}
+
+u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlUnmapBufferEx params{};
+    std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
+    LOG_WARNING(Service_NVDRV, "(STUBBED) called");
+    std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
+    return 0;
+}
+
 } // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index bec32bea15..6854f26dd8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -23,6 +23,12 @@ public:
 private:
     enum class IoctlCommand : u32_le {
         IocSetNVMAPfdCommand = 0x40044801,
+        IocSubmit = 0xC0400001,
+        IocGetSyncpoint = 0xC0080002,
+        IocGetWaitbase = 0xC0080003,
+        IocMapBuffer = 0xC01C0009,
+        IocMapBufferEx = 0xC03C0009,
+        IocUnmapBufferEx = 0xC03C000A,
     };
 
     struct IoctlSetNvmapFD {
@@ -30,9 +36,53 @@ private:
     };
     static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
 
+    struct IoctlSubmit {
+        INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
+
+    struct IoctlGetSyncpoint {
+        u32 unknown; // seems to be ignored? Nintendo added this
+        u32 value;
+    };
+    static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
+
+    struct IoctlGetWaitbase {
+        u32 unknown; // seems to be ignored? Nintendo added this
+        u32 value;
+    };
+    static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
+
+    struct IoctlMapBuffer {
+        u32 unknown;
+        u32 address_1;
+        u32 address_2;
+        INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
+
+    struct IoctlMapBufferEx {
+        u32 unknown;
+        u32 address_1;
+        u32 address_2;
+        INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
+
+    struct IoctlUnmapBufferEx {
+        INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
+    };
+    static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
+
     u32_le nvmap_fd{};
 
     u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
+    u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
 };
 
 } // namespace Service::Nvidia::Devices
-- 
cgit v1.2.3-70-g09d2