summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp70
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h52
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp74
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h63
4 files changed, 256 insertions, 3 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index bdae8b887..fcb612864 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 cbdac8069..4332db118 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 c695b8863..9da19ad56 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,71 @@ 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");
+
+ // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU
+ params.command_buffer = {};
+
+ 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 bec32bea1..a7bb7bbd5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -4,6 +4,7 @@
#pragma once
+#include <array>
#include <vector>
#include "common/common_types.h"
#include "common/swap.h"
@@ -23,6 +24,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 +37,65 @@ private:
};
static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
+ struct IoctlSubmitCommandBuffer {
+ u32 id;
+ u32 offset;
+ u32 count;
+ };
+ static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC,
+ "IoctlSubmitCommandBuffer is incorrect size");
+
+ struct IoctlSubmit {
+ u32 command_buffer_count;
+ u32 relocations_count;
+ u32 syncpt_count;
+ u32 wait_count;
+ std::array<IoctlSubmitCommandBuffer, 4> command_buffer;
+ };
+ 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