summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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::
22 switch (static_cast<IoctlCommand>(command.raw)) { 22 switch (static_cast<IoctlCommand>(command.raw)) {
23 case IoctlCommand::IocSetNVMAPfdCommand: 23 case IoctlCommand::IocSetNVMAPfdCommand:
24 return SetNVMAPfd(input, output); 24 return SetNVMAPfd(input, output);
25 case IoctlCommand::IocSubmit:
26 return Submit(input, output);
27 case IoctlCommand::IocGetSyncpoint:
28 return GetSyncpoint(input, output);
29 case IoctlCommand::IocGetWaitbase:
30 return GetWaitbase(input, output);
31 case IoctlCommand::IocMapBuffer:
32 return MapBuffer(input, output);
33 case IoctlCommand::IocMapBufferEx:
34 return MapBufferEx(input, output);
35 case IoctlCommand::IocUnmapBufferEx:
36 return UnmapBufferEx(input, output);
25 } 37 }
26 38
27 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 39 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
30 42
31u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 43u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
32 IoctlSetNvmapFD params{}; 44 IoctlSetNvmapFD params{};
33 std::memcpy(&params, input.data(), input.size()); 45 std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
34 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 46 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
35 47
36 nvmap_fd = params.nvmap_fd; 48 nvmap_fd = params.nvmap_fd;
37 return 0; 49 return 0;
38} 50}
39 51
52u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
53 IoctlSubmit params{};
54 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
55 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
56 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
57 return 0;
58}
59
60u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
61 IoctlGetSyncpoint params{};
62 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
63 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
64 params.value = 0; // Seems to be hard coded at 0
65 std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
66 return 0;
67}
68
69u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
70 IoctlGetWaitbase params{};
71 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
72 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
73 params.value = 0; // Seems to be hard coded at 0
74 std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
75 return 0;
76}
77
78u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
79 IoctlMapBuffer params{};
80 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
81 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
82 params.address_1);
83 params.address_1 = 0;
84 params.address_2 = 0;
85 std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
86 return 0;
87}
88
89u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
90 IoctlMapBufferEx params{};
91 std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
92 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
93 params.address_1);
94 params.address_1 = 0;
95 params.address_2 = 0;
96 std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
97 return 0;
98}
99
100u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
101 IoctlUnmapBufferEx params{};
102 std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
103 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
104 std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
105 return 0;
106}
107
40} // namespace Service::Nvidia::Devices 108} // 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:
23private: 23private:
24 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
25 IocSetNVMAPfdCommand = 0x40044801, 25 IocSetNVMAPfdCommand = 0x40044801,
26 IocSubmit = 0xC0400001,
27 IocGetSyncpoint = 0xC0080002,
28 IocGetWaitbase = 0xC0080003,
29 IocMapBuffer = 0xC01C0009,
30 IocMapBufferEx = 0xC0A40009,
31 IocUnmapBufferEx = 0xC0A4000A,
26 }; 32 };
27 33
28 struct IoctlSetNvmapFD { 34 struct IoctlSetNvmapFD {
29 u32_le nvmap_fd; 35 u32_le nvmap_fd;
30 }; 36 };
31 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); 37 static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size");
38
39 struct IoctlSubmit {
40 INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure
41 };
42 static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size");
43
44 struct IoctlGetSyncpoint {
45 u32 unknown; // seems to be ignored? Nintendo added this
46 u32 value;
47 };
48 static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size");
49
50 struct IoctlGetWaitbase {
51 u32 unknown; // seems to be ignored? Nintendo added this
52 u32 value;
53 };
54 static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size");
55
56 struct IoctlMapBuffer {
57 u32 unknown;
58 u32 address_1;
59 u32 address_2;
60 INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
61 };
62 static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
63
64 struct IoctlMapBufferEx {
65 u32 unknown;
66 u32 address_1;
67 u32 address_2;
68 INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure
69 };
70 static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size");
71
72 struct IoctlUnmapBufferEx {
73 INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure
74 };
75 static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size");
32 76
33 u32_le nvmap_fd{}; 77 u32_le nvmap_fd{};
34 78
35 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); 79 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
80 u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
81 u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
82 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
83 u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
84 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
85 u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
36}; 86};
37 87
38} // namespace Service::Nvidia::Devices 88} // 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
22 switch (static_cast<IoctlCommand>(command.raw)) { 22 switch (static_cast<IoctlCommand>(command.raw)) {
23 case IoctlCommand::IocSetNVMAPfdCommand: 23 case IoctlCommand::IocSetNVMAPfdCommand:
24 return SetNVMAPfd(input, output); 24 return SetNVMAPfd(input, output);
25 case IoctlCommand::IocSubmit:
26 return Submit(input, output);
27 case IoctlCommand::IocGetSyncpoint:
28 return GetSyncpoint(input, output);
29 case IoctlCommand::IocGetWaitbase:
30 return GetWaitbase(input, output);
31 case IoctlCommand::IocMapBuffer:
32 return MapBuffer(input, output);
33 case IoctlCommand::IocMapBufferEx:
34 return MapBuffer(input, output);
35 case IoctlCommand::IocUnmapBufferEx:
36 return UnmapBufferEx(input, output);
25 } 37 }
26 38
27 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 39 UNIMPLEMENTED_MSG("Unimplemented ioctl");
@@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
30 42
31u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 43u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
32 IoctlSetNvmapFD params{}; 44 IoctlSetNvmapFD params{};
33 std::memcpy(&params, input.data(), input.size()); 45 std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
34 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 46 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
35 47
36 nvmap_fd = params.nvmap_fd; 48 nvmap_fd = params.nvmap_fd;
37 return 0; 49 return 0;
38} 50}
39 51
52u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
53 IoctlSubmit params{};
54 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
55 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
56
57 // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU
58 params.command_buffer = {};
59
60 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
61 return 0;
62}
63
64u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
65 IoctlGetSyncpoint params{};
66 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
67 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
68 params.value = 0; // Seems to be hard coded at 0
69 std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
70 return 0;
71}
72
73u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
74 IoctlGetWaitbase params{};
75 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
76 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
77 params.value = 0; // Seems to be hard coded at 0
78 std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
79 return 0;
80}
81
82u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
83 IoctlMapBuffer params{};
84 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
85 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
86 params.address_1);
87 params.address_1 = 0;
88 params.address_2 = 0;
89 std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
90 return 0;
91}
92
93u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
94 IoctlMapBufferEx params{};
95 std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
96 LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
97 params.address_1);
98 params.address_1 = 0;
99 params.address_2 = 0;
100 std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
101 return 0;
102}
103
104u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
105 IoctlUnmapBufferEx params{};
106 std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
107 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
108 std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
109 return 0;
110}
111
40} // namespace Service::Nvidia::Devices 112} // 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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <vector> 8#include <vector>
8#include "common/common_types.h" 9#include "common/common_types.h"
9#include "common/swap.h" 10#include "common/swap.h"
@@ -23,6 +24,12 @@ public:
23private: 24private:
24 enum class IoctlCommand : u32_le { 25 enum class IoctlCommand : u32_le {
25 IocSetNVMAPfdCommand = 0x40044801, 26 IocSetNVMAPfdCommand = 0x40044801,
27 IocSubmit = 0xC0400001,
28 IocGetSyncpoint = 0xC0080002,
29 IocGetWaitbase = 0xC0080003,
30 IocMapBuffer = 0xC01C0009,
31 IocMapBufferEx = 0xC03C0009,
32 IocUnmapBufferEx = 0xC03C000A,
26 }; 33 };
27 34
28 struct IoctlSetNvmapFD { 35 struct IoctlSetNvmapFD {
@@ -30,9 +37,65 @@ private:
30 }; 37 };
31 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); 38 static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size");
32 39
40 struct IoctlSubmitCommandBuffer {
41 u32 id;
42 u32 offset;
43 u32 count;
44 };
45 static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC,
46 "IoctlSubmitCommandBuffer is incorrect size");
47
48 struct IoctlSubmit {
49 u32 command_buffer_count;
50 u32 relocations_count;
51 u32 syncpt_count;
52 u32 wait_count;
53 std::array<IoctlSubmitCommandBuffer, 4> command_buffer;
54 };
55 static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size");
56
57 struct IoctlGetSyncpoint {
58 u32 unknown; // seems to be ignored? Nintendo added this
59 u32 value;
60 };
61 static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size");
62
63 struct IoctlGetWaitbase {
64 u32 unknown; // seems to be ignored? Nintendo added this
65 u32 value;
66 };
67 static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size");
68
69 struct IoctlMapBuffer {
70 u32 unknown;
71 u32 address_1;
72 u32 address_2;
73 INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure
74 };
75 static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size");
76
77 struct IoctlMapBufferEx {
78 u32 unknown;
79 u32 address_1;
80 u32 address_2;
81 INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure
82 };
83 static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size");
84
85 struct IoctlUnmapBufferEx {
86 INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure
87 };
88 static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size");
89
33 u32_le nvmap_fd{}; 90 u32_le nvmap_fd{};
34 91
35 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); 92 u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output);
93 u32 Submit(const std::vector<u8>& input, std::vector<u8>& output);
94 u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
95 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
96 u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
97 u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
98 u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
36}; 99};
37 100
38} // namespace Service::Nvidia::Devices 101} // namespace Service::Nvidia::Devices