summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp19
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h11
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h8
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp93
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h11
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp13
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h6
24 files changed, 214 insertions, 91 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index 5681599ba..44a8bc060 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -31,8 +31,8 @@ public:
31 * @param output A buffer where the output data will be written to. 31 * @param output A buffer where the output data will be written to.
32 * @returns The result code of the ioctl. 32 * @returns The result code of the ioctl.
33 */ 33 */
34 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, 34 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
35 std::vector<u8>& output) = 0; 35 IoctlCtrl& ctrl) = 0;
36 36
37 /** 37 /**
38 * Handles an ioctl2 request. 38 * Handles an ioctl2 request.
@@ -43,7 +43,8 @@ public:
43 * @returns The result code of the ioctl. 43 * @returns The result code of the ioctl.
44 */ 44 */
45 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 45 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
46 const std::vector<u8>& inline_input, std::vector<u8>& output) = 0; 46 const std::vector<u8>& inline_input, std::vector<u8>& output,
47 IoctlCtrl& ctrl) = 0;
47 48
48 /** 49 /**
49 * Handles an ioctl3 request. 50 * Handles an ioctl3 request.
@@ -54,7 +55,7 @@ public:
54 * @returns The result code of the ioctl. 55 * @returns The result code of the ioctl.
55 */ 56 */
56 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 57 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
57 std::vector<u8>& inline_output) = 0; 58 std::vector<u8>& inline_output, IoctlCtrl& ctrl) = 0;
58 59
59protected: 60protected:
60 Core::System& system; 61 Core::System& system;
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index ce615c758..170a7c9a0 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -18,20 +18,21 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de
18 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 18 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
19nvdisp_disp0 ::~nvdisp_disp0() = default; 19nvdisp_disp0 ::~nvdisp_disp0() = default;
20 20
21NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input, 21NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
22 std::vector<u8>& output) { 22 IoctlCtrl& ctrl) {
23 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 23 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
24 return NvResult::NotImplemented; 24 return NvResult::NotImplemented;
25} 25}
26 26
27NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input, 27NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input,
28 const std::vector<u8>& inline_input, std::vector<u8>& output) { 28 const std::vector<u8>& inline_input, std::vector<u8>& output,
29 IoctlCtrl& ctrl) {
29 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 30 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
30 return NvResult::NotImplemented; 31 return NvResult::NotImplemented;
31} 32}
32 33
33NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 34NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
34 std::vector<u8>& inline_output) { 35 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
35 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 36 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
36 return NvResult::NotImplemented; 37 return NvResult::NotImplemented;
37} 38}
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index 55a33b7e4..eb7575e40 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -20,11 +20,13 @@ public:
20 explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 20 explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
21 ~nvdisp_disp0() override; 21 ~nvdisp_disp0() override;
22 22
23 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 23 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
24 IoctlCtrl& ctrl) override;
24 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 25 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
25 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 26 const std::vector<u8>& inline_input, std::vector<u8>& output,
27 IoctlCtrl& ctrl) override;
26 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 28 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
27 std::vector<u8>& inline_output) override; 29 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
28 30
29 /// Performs a screen flip, drawing the buffer pointed to by the handle. 31 /// Performs a screen flip, drawing the buffer pointed to by the handle.
30 void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, 32 void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
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 6b062e10e..4e0652c39 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -21,8 +21,8 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_
21 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 21 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
22nvhost_as_gpu::~nvhost_as_gpu() = default; 22nvhost_as_gpu::~nvhost_as_gpu() = default;
23 23
24NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, 24NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
25 std::vector<u8>& output) { 25 IoctlCtrl& ctrl) {
26 switch (command.group) { 26 switch (command.group) {
27 case 'A': 27 case 'A':
28 switch (command.cmd) { 28 switch (command.cmd) {
@@ -55,13 +55,14 @@ NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
55} 55}
56 56
57NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, 57NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
58 const std::vector<u8>& inline_input, std::vector<u8>& output) { 58 const std::vector<u8>& inline_input, std::vector<u8>& output,
59 IoctlCtrl& ctrl) {
59 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
60 return NvResult::NotImplemented; 61 return NvResult::NotImplemented;
61} 62}
62 63
63NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 64NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
64 std::vector<u8>& inline_output) { 65 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
65 switch (command.group) { 66 switch (command.group) {
66 case 'A': 67 case 'A':
67 switch (command.cmd) { 68 switch (command.cmd) {
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 08035fa0e..2bd355af9 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -30,11 +30,13 @@ public:
30 explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 30 explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
31 ~nvhost_as_gpu() override; 31 ~nvhost_as_gpu() override;
32 32
33 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 33 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
34 IoctlCtrl& ctrl) override;
34 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 35 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
35 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 36 const std::vector<u8>& inline_input, std::vector<u8>& output,
37 IoctlCtrl& ctrl) override;
36 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 38 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
37 std::vector<u8>& inline_output) override; 39 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
38 40
39private: 41private:
40 class BufferMap final { 42 class BufferMap final {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index d90cf90a8..92d31b620 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -20,7 +20,8 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface,
20 : nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {} 20 : nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {}
21nvhost_ctrl::~nvhost_ctrl() = default; 21nvhost_ctrl::~nvhost_ctrl() = default;
22 22
23NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 23NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
24 IoctlCtrl& ctrl) {
24 switch (command.group) { 25 switch (command.group) {
25 case 0x0: 26 case 0x0:
26 switch (command.cmd) { 27 switch (command.cmd) {
@@ -29,9 +30,9 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
29 case 0x1c: 30 case 0x1c:
30 return IocCtrlClearEventWait(input, output); 31 return IocCtrlClearEventWait(input, output);
31 case 0x1d: 32 case 0x1d:
32 return IocCtrlEventWait(input, output, false); 33 return IocCtrlEventWait(input, output, false, ctrl);
33 case 0x1e: 34 case 0x1e:
34 return IocCtrlEventWait(input, output, true); 35 return IocCtrlEventWait(input, output, true, ctrl);
35 case 0x1f: 36 case 0x1f:
36 return IocCtrlEventRegister(input, output); 37 return IocCtrlEventRegister(input, output);
37 case 0x20: 38 case 0x20:
@@ -47,13 +48,14 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
47} 48}
48 49
49NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input, 50NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input,
50 const std::vector<u8>& inline_input, std::vector<u8>& output) { 51 const std::vector<u8>& inline_input, std::vector<u8>& output,
52 IoctlCtrl& ctrl) {
51 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 53 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
52 return NvResult::NotImplemented; 54 return NvResult::NotImplemented;
53} 55}
54 56
55NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 57NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
56 std::vector<u8>& inline_output) { 58 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
57 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 59 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
58 return NvResult::NotImplemented; 60 return NvResult::NotImplemented;
59} 61}
@@ -67,7 +69,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector
67} 69}
68 70
69NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, 71NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
70 bool is_async) { 72 bool is_async, IoctlCtrl& ctrl) {
71 IocCtrlEventWaitParams params{}; 73 IocCtrlEventWaitParams params{};
72 std::memcpy(&params, input.data(), sizeof(params)); 74 std::memcpy(&params, input.data(), sizeof(params));
73 LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}", 75 LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}",
@@ -139,7 +141,10 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
139 params.value |= event_id; 141 params.value |= event_id;
140 event.event.writable->Clear(); 142 event.event.writable->Clear();
141 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); 143 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
142 if (!is_async) { 144 if (!is_async && ctrl.fresh_call) {
145 ctrl.must_delay = true;
146 ctrl.timeout = params.timeout;
147 ctrl.event_id = event_id;
143 return NvResult::Timeout; 148 return NvResult::Timeout;
144 } 149 }
145 std::memcpy(output.data(), &params, sizeof(params)); 150 std::memcpy(output.data(), &params, sizeof(params));
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index c5aa1362a..107168e21 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -18,11 +18,13 @@ public:
18 SyncpointManager& syncpoint_manager); 18 SyncpointManager& syncpoint_manager);
19 ~nvhost_ctrl() override; 19 ~nvhost_ctrl() override;
20 20
21 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 21 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
22 IoctlCtrl& ctrl) override;
22 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 23 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
23 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 24 const std::vector<u8>& inline_input, std::vector<u8>& output,
25 IoctlCtrl& ctrl) override;
24 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 26 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
25 std::vector<u8>& inline_output) override; 27 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
26 28
27private: 29private:
28 struct IocSyncptReadParams { 30 struct IocSyncptReadParams {
@@ -121,7 +123,8 @@ private:
121 static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size"); 123 static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size");
122 124
123 NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output); 125 NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output);
124 NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, bool is_async); 126 NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, bool is_async,
127 IoctlCtrl& ctrl);
125 NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output); 128 NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output);
126 NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); 129 NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output);
127 NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); 130 NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output);
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 2d7ea433c..647f5907e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -16,7 +16,7 @@ nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
16nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; 16nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
17 17
18NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, 18NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
19 std::vector<u8>& output) { 19 std::vector<u8>& output, IoctlCtrl& ctrl) {
20 switch (command.group) { 20 switch (command.group) {
21 case 'G': 21 case 'G':
22 switch (command.cmd) { 22 switch (command.cmd) {
@@ -48,13 +48,15 @@ NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
48} 48}
49 49
50NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, 50NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
51 const std::vector<u8>& inline_input, std::vector<u8>& output) { 51 const std::vector<u8>& inline_input, std::vector<u8>& output,
52 IoctlCtrl& ctrl) {
52 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 53 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
53 return NvResult::NotImplemented; 54 return NvResult::NotImplemented;
54} 55}
55 56
56NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, 57NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input,
57 std::vector<u8>& output, std::vector<u8>& inline_output) { 58 std::vector<u8>& output, std::vector<u8>& inline_output,
59 IoctlCtrl& ctrl) {
58 switch (command.group) { 60 switch (command.group) {
59 case 'G': 61 case 'G':
60 switch (command.cmd) { 62 switch (command.cmd) {
@@ -162,7 +164,7 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::
162 params.gpu_characteristics_buf_size = 0xA0; 164 params.gpu_characteristics_buf_size = 0xA0;
163 params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) 165 params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED)
164 166
165 std::memcpy(output.data(), input.data(), output.size()); 167 std::memcpy(output.data(), &params, output.size());
166 std::memcpy(inline_output.data(), &params.gc, inline_output.size()); 168 std::memcpy(inline_output.data(), &params.gc, inline_output.size());
167 return NvResult::Success; 169 return NvResult::Success;
168} 170}
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 137b88238..c2fffe734 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -16,11 +16,13 @@ public:
16 explicit nvhost_ctrl_gpu(Core::System& system); 16 explicit nvhost_ctrl_gpu(Core::System& system);
17 ~nvhost_ctrl_gpu() override; 17 ~nvhost_ctrl_gpu() override;
18 18
19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
20 IoctlCtrl& ctrl) override;
20 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 21 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
21 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 22 const std::vector<u8>& inline_input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) override;
22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 24 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 std::vector<u8>& inline_output) override; 25 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
24 26
25private: 27private:
26 struct IoctlGpuCharacteristics { 28 struct IoctlGpuCharacteristics {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index af8b3d9f1..b0c2caba5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -23,7 +23,8 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev,
23 23
24nvhost_gpu::~nvhost_gpu() = default; 24nvhost_gpu::~nvhost_gpu() = default;
25 25
26NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 26NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
27 IoctlCtrl& ctrl) {
27 switch (command.group) { 28 switch (command.group) {
28 case 0x0: 29 case 0x0:
29 switch (command.cmd) { 30 switch (command.cmd) {
@@ -75,7 +76,8 @@ NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
75}; 76};
76 77
77NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, 78NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
78 const std::vector<u8>& inline_input, std::vector<u8>& output) { 79 const std::vector<u8>& inline_input, std::vector<u8>& output,
80 IoctlCtrl& ctrl) {
79 switch (command.group) { 81 switch (command.group) {
80 case 'H': 82 case 'H':
81 switch (command.cmd) { 83 switch (command.cmd) {
@@ -89,7 +91,7 @@ NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
89} 91}
90 92
91NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 93NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
92 std::vector<u8>& inline_output) { 94 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
93 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 95 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
94 return NvResult::NotImplemented; 96 return NvResult::NotImplemented;
95} 97}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index e0298b4fe..aa0048a9d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -26,11 +26,13 @@ public:
26 SyncpointManager& syncpoint_manager); 26 SyncpointManager& syncpoint_manager);
27 ~nvhost_gpu() override; 27 ~nvhost_gpu() override;
28 28
29 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 29 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
30 IoctlCtrl& ctrl) override;
30 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 31 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
31 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 32 const std::vector<u8>& inline_input, std::vector<u8>& output,
33 IoctlCtrl& ctrl) override;
32 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 34 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
33 std::vector<u8>& inline_output) override; 35 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
34 36
35private: 37private:
36 enum class CtxObjects : u32_le { 38 enum class CtxObjects : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index d8735491c..b8328c314 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -15,8 +15,8 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_de
15 : nvhost_nvdec_common(system, std::move(nvmap_dev)) {} 15 : nvhost_nvdec_common(system, std::move(nvmap_dev)) {}
16nvhost_nvdec::~nvhost_nvdec() = default; 16nvhost_nvdec::~nvhost_nvdec() = default;
17 17
18NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, 18NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
19 std::vector<u8>& output) { 19 IoctlCtrl& ctrl) {
20 switch (command.group) { 20 switch (command.group) {
21 case 0x0: 21 case 0x0:
22 switch (command.cmd) { 22 switch (command.cmd) {
@@ -58,13 +58,14 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input,
58} 58}
59 59
60NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input, 60NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input,
61 const std::vector<u8>& inline_input, std::vector<u8>& output) { 61 const std::vector<u8>& inline_input, std::vector<u8>& output,
62 IoctlCtrl& ctrl) {
62 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 63 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
63 return NvResult::NotImplemented; 64 return NvResult::NotImplemented;
64} 65}
65 66
66NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 67NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
67 std::vector<u8>& inline_output) { 68 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
68 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 69 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
69 return NvResult::NotImplemented; 70 return NvResult::NotImplemented;
70} 71}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 79b8b6de1..884ed6c5b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -14,11 +14,13 @@ public:
14 explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 14 explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
15 ~nvhost_nvdec() override; 15 ~nvhost_nvdec() override;
16 16
17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
18 IoctlCtrl& ctrl) override;
18 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 19 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
19 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 20 const std::vector<u8>& inline_input, std::vector<u8>& output,
21 IoctlCtrl& ctrl) override;
20 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
21 std::vector<u8>& inline_output) override; 23 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
22}; 24};
23 25
24} // namespace Service::Nvidia::Devices 26} // namespace Service::Nvidia::Devices
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 86ba3a4d1..ab152bf0e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -25,8 +25,8 @@ public:
25 * @param output A buffer where the output data will be written to. 25 * @param output A buffer where the output data will be written to.
26 * @returns The result code of the ioctl. 26 * @returns The result code of the ioctl.
27 */ 27 */
28 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, 28 virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
29 std::vector<u8>& output) = 0; 29 IoctlCtrl& ctrl) = 0;
30 30
31 /** 31 /**
32 * Handles an ioctl2 request. 32 * Handles an ioctl2 request.
@@ -37,7 +37,8 @@ public:
37 * @returns The result code of the ioctl. 37 * @returns The result code of the ioctl.
38 */ 38 */
39 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 39 virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
40 const std::vector<u8>& inline_input, std::vector<u8>& output) = 0; 40 const std::vector<u8>& inline_input, std::vector<u8>& output,
41 IoctlCtrl& ctrl) = 0;
41 42
42 /** 43 /**
43 * Handles an ioctl3 request. 44 * Handles an ioctl3 request.
@@ -48,7 +49,7 @@ public:
48 * @returns The result code of the ioctl. 49 * @returns The result code of the ioctl.
49 */ 50 */
50 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 51 virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
51 std::vector<u8>& inline_output) = 0; 52 std::vector<u8>& inline_output, IoctlCtrl& ctrl) = 0;
52 53
53protected: 54protected:
54 class BufferMap final { 55 class BufferMap final {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index 2d06955c0..6f4ab0ab3 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices {
13nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} 13nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
14nvhost_nvjpg::~nvhost_nvjpg() = default; 14nvhost_nvjpg::~nvhost_nvjpg() = default;
15 15
16NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, 16NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
17 std::vector<u8>& output) { 17 IoctlCtrl& ctrl) {
18 switch (command.group) { 18 switch (command.group) {
19 case 'H': 19 case 'H':
20 switch (command.cmd) { 20 switch (command.cmd) {
@@ -33,13 +33,14 @@ NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input,
33} 33}
34 34
35NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input, 35NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input,
36 const std::vector<u8>& inline_input, std::vector<u8>& output) { 36 const std::vector<u8>& inline_input, std::vector<u8>& output,
37 IoctlCtrl& ctrl) {
37 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 38 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
38 return NvResult::NotImplemented; 39 return NvResult::NotImplemented;
39} 40}
40 41
41NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 42NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
42 std::vector<u8>& inline_output) { 43 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
43 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 44 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
44 return NvResult::NotImplemented; 45 return NvResult::NotImplemented;
45} 46}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 43948d18d..6fb99d959 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -16,11 +16,13 @@ public:
16 explicit nvhost_nvjpg(Core::System& system); 16 explicit nvhost_nvjpg(Core::System& system);
17 ~nvhost_nvjpg() override; 17 ~nvhost_nvjpg() override;
18 18
19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 19 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
20 IoctlCtrl& ctrl) override;
20 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 21 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
21 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 22 const std::vector<u8>& inline_input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) override;
22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 24 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 std::vector<u8>& inline_output) override; 25 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
24 26
25private: 27private:
26 struct IoctlSetNvmapFD { 28 struct IoctlSetNvmapFD {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index 805fe86ae..55a17f423 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -15,7 +15,8 @@ nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev)
15 15
16nvhost_vic::~nvhost_vic() = default; 16nvhost_vic::~nvhost_vic() = default;
17 17
18NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 18NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
19 IoctlCtrl& ctrl) {
19 switch (command.group) { 20 switch (command.group) {
20 case 0x0: 21 case 0x0:
21 switch (command.cmd) { 22 switch (command.cmd) {
@@ -50,13 +51,14 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
50} 51}
51 52
52NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input, 53NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input,
53 const std::vector<u8>& inline_input, std::vector<u8>& output) { 54 const std::vector<u8>& inline_input, std::vector<u8>& output,
55 IoctlCtrl& ctrl) {
54 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 56 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
55 return NvResult::NotImplemented; 57 return NvResult::NotImplemented;
56} 58}
57 59
58NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 60NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
59 std::vector<u8>& inline_output) { 61 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 62 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
61 return NvResult::NotImplemented; 63 return NvResult::NotImplemented;
62} 64}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index b2e11f4d4..7f4858cd4 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -14,10 +14,12 @@ public:
14 explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 14 explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
15 ~nvhost_vic(); 15 ~nvhost_vic();
16 16
17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 17 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
18 IoctlCtrl& ctrl) override;
18 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 19 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
19 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 20 const std::vector<u8>& inline_input, std::vector<u8>& output,
21 IoctlCtrl& ctrl) override;
20 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 22 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
21 std::vector<u8>& inline_output) override; 23 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
22}; 24};
23} // namespace Service::Nvidia::Devices 25} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 4015a2740..910cfee51 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -19,7 +19,8 @@ nvmap::nvmap(Core::System& system) : nvdevice(system) {
19 19
20nvmap::~nvmap() = default; 20nvmap::~nvmap() = default;
21 21
22NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 22NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) {
23 switch (command.group) { 24 switch (command.group) {
24 case 0x1: 25 case 0x1:
25 switch (command.cmd) { 26 switch (command.cmd) {
@@ -48,13 +49,14 @@ NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<
48} 49}
49 50
50NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input, 51NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input,
51 const std::vector<u8>& inline_input, std::vector<u8>& output) { 52 const std::vector<u8>& inline_input, std::vector<u8>& output,
53 IoctlCtrl& ctrl) {
52 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 54 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
53 return NvResult::NotImplemented; 55 return NvResult::NotImplemented;
54} 56}
55 57
56NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 58NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
57 std::vector<u8>& inline_output) { 59 std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
58 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
59 return NvResult::NotImplemented; 61 return NvResult::NotImplemented;
60} 62}
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 4484bd79f..c0c2fa5eb 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -19,11 +19,13 @@ public:
19 explicit nvmap(Core::System& system); 19 explicit nvmap(Core::System& system);
20 ~nvmap() override; 20 ~nvmap() override;
21 21
22 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; 22 NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
23 IoctlCtrl& ctrl) override;
23 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, 24 NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
24 const std::vector<u8>& inline_input, std::vector<u8>& output) override; 25 const std::vector<u8>& inline_input, std::vector<u8>& output,
26 IoctlCtrl& ctrl) override;
25 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 27 NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
26 std::vector<u8>& inline_output) override; 28 std::vector<u8>& inline_output, IoctlCtrl& ctrl) override;
27 29
28 /// Returns the allocated address of an nvmap object given its handle. 30 /// Returns the allocated address of an nvmap object given its handle.
29 VAddr GetObjectAddress(u32 handle) const; 31 VAddr GetObjectAddress(u32 handle) const;
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index f6c38e853..7bfa5cac9 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -61,10 +61,32 @@ void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) {
61 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 61 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
62 const auto input_buffer = ctx.ReadBuffer(0); 62 const auto input_buffer = ctx.ReadBuffer(0);
63 63
64 const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer); 64 IoctlCtrl ctrl{};
65 65
66 if (command.is_out != 0) { 66 const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer, ctrl);
67 ctx.WriteBuffer(output_buffer); 67 if (ctrl.must_delay) {
68 ctrl.fresh_call = false;
69 ctx.SleepClientThread(
70 "NVServices::DelayedResponse", ctrl.timeout,
71 [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
72 Kernel::ThreadWakeupReason reason) {
73 IoctlCtrl ctrl2{ctrl};
74 std::vector<u8> tmp_output = output_buffer;
75 const auto nv_result2 = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output, ctrl2);
76
77 if (command.is_out != 0) {
78 ctx.WriteBuffer(tmp_output);
79 }
80
81 IPC::ResponseBuilder rb{ctx_, 3};
82 rb.Push(RESULT_SUCCESS);
83 rb.PushEnum(nv_result2);
84 },
85 nvdrv->GetEventWriteable(ctrl.event_id));
86 } else {
87 if (command.is_out != 0) {
88 ctx.WriteBuffer(output_buffer);
89 }
68 } 90 }
69 91
70 IPC::ResponseBuilder rb{ctx, 3}; 92 IPC::ResponseBuilder rb{ctx, 3};
@@ -88,8 +110,35 @@ void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
88 const auto input_inlined_buffer = ctx.ReadBuffer(1); 110 const auto input_inlined_buffer = ctx.ReadBuffer(1);
89 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 111 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
90 112
113 IoctlCtrl ctrl{};
114
91 const auto nv_result = 115 const auto nv_result =
92 nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer); 116 nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer, ctrl);
117 if (ctrl.must_delay) {
118 ctrl.fresh_call = false;
119 ctx.SleepClientThread(
120 "NVServices::DelayedResponse", ctrl.timeout,
121 [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
122 Kernel::ThreadWakeupReason reason) {
123 IoctlCtrl ctrl2{ctrl};
124 std::vector<u8> tmp_output = output_buffer;
125 const auto nv_result2 = nvdrv->Ioctl2(fd, command, input_buffer,
126 input_inlined_buffer, tmp_output, ctrl2);
127
128 if (command.is_out != 0) {
129 ctx.WriteBuffer(tmp_output);
130 }
131
132 IPC::ResponseBuilder rb{ctx_, 3};
133 rb.Push(RESULT_SUCCESS);
134 rb.PushEnum(nv_result2);
135 },
136 nvdrv->GetEventWriteable(ctrl.event_id));
137 } else {
138 if (command.is_out != 0) {
139 ctx.WriteBuffer(output_buffer);
140 }
141 }
93 142
94 if (command.is_out != 0) { 143 if (command.is_out != 0) {
95 ctx.WriteBuffer(output_buffer); 144 ctx.WriteBuffer(output_buffer);
@@ -116,12 +165,36 @@ void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
116 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 165 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
117 std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1)); 166 std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1));
118 167
168 IoctlCtrl ctrl{};
119 const auto nv_result = 169 const auto nv_result =
120 nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline); 170 nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline, ctrl);
121 171 if (ctrl.must_delay) {
122 if (command.is_out != 0) { 172 ctrl.fresh_call = false;
123 ctx.WriteBuffer(output_buffer, 0); 173 ctx.SleepClientThread(
124 ctx.WriteBuffer(output_buffer_inline, 1); 174 "NVServices::DelayedResponse", ctrl.timeout,
175 [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
176 Kernel::ThreadWakeupReason reason) {
177 IoctlCtrl ctrl2{ctrl};
178 std::vector<u8> tmp_output = output_buffer;
179 std::vector<u8> tmp_output2 = output_buffer;
180 const auto nv_result2 =
181 nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output2, ctrl2);
182
183 if (command.is_out != 0) {
184 ctx.WriteBuffer(tmp_output, 0);
185 ctx.WriteBuffer(tmp_output2, 1);
186 }
187
188 IPC::ResponseBuilder rb{ctx_, 3};
189 rb.Push(RESULT_SUCCESS);
190 rb.PushEnum(nv_result2);
191 },
192 nvdrv->GetEventWriteable(ctrl.event_id));
193 } else {
194 if (command.is_out != 0) {
195 ctx.WriteBuffer(output_buffer, 0);
196 ctx.WriteBuffer(output_buffer_inline, 1);
197 }
125 } 198 }
126 199
127 IPC::ResponseBuilder rb{ctx, 3}; 200 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
index 3294bc0e7..a3c4ecd85 100644
--- a/src/core/hle/service/nvdrv/nvdata.h
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -97,4 +97,15 @@ union Ioctl {
97 BitField<31, 1, u32> is_out; 97 BitField<31, 1, u32> is_out;
98}; 98};
99 99
100struct IoctlCtrl {
101 // First call done to the servioce for services that call itself again after a call.
102 bool fresh_call{true};
103 // Tells the Ioctl Wrapper that it must delay the IPC response and send the thread to sleep
104 bool must_delay{};
105 // Timeout for the delay
106 s64 timeout{};
107 // NV Event Id
108 s32 event_id{-1};
109};
110
100} // namespace Service::Nvidia 111} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index bdbbedd0d..56d927b12 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -91,7 +91,7 @@ DeviceFD Module::Open(const std::string& device_name) {
91} 91}
92 92
93NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 93NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
94 std::vector<u8>& output) { 94 std::vector<u8>& output, IoctlCtrl& ctrl) {
95 if (fd < 0) { 95 if (fd < 0) {
96 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 96 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
97 return NvResult::InvalidState; 97 return NvResult::InvalidState;
@@ -104,11 +104,12 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input
104 return NvResult::NotImplemented; 104 return NvResult::NotImplemented;
105 } 105 }
106 106
107 return itr->second->Ioctl1(command, input, output); 107 return itr->second->Ioctl1(command, input, output, ctrl);
108} 108}
109 109
110NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 110NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
111 const std::vector<u8>& inline_input, std::vector<u8>& output) { 111 const std::vector<u8>& inline_input, std::vector<u8>& output,
112 IoctlCtrl& ctrl) {
112 if (fd < 0) { 113 if (fd < 0) {
113 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 114 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
114 return NvResult::InvalidState; 115 return NvResult::InvalidState;
@@ -121,11 +122,11 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input
121 return NvResult::NotImplemented; 122 return NvResult::NotImplemented;
122 } 123 }
123 124
124 return itr->second->Ioctl2(command, input, inline_input, output); 125 return itr->second->Ioctl2(command, input, inline_input, output, ctrl);
125} 126}
126 127
127NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 128NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
128 std::vector<u8>& output, std::vector<u8>& inline_output) { 129 std::vector<u8>& output, std::vector<u8>& inline_output, IoctlCtrl& ctrl) {
129 if (fd < 0) { 130 if (fd < 0) {
130 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 131 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
131 return NvResult::InvalidState; 132 return NvResult::InvalidState;
@@ -138,7 +139,7 @@ NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input
138 return NvResult::NotImplemented; 139 return NvResult::NotImplemented;
139 } 140 }
140 141
141 return itr->second->Ioctl3(command, input, output, inline_output); 142 return itr->second->Ioctl3(command, input, output, inline_output, ctrl);
142} 143}
143 144
144NvResult Module::Close(DeviceFD fd) { 145NvResult Module::Close(DeviceFD fd) {
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 7654bb026..bfffc1e88 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -119,13 +119,13 @@ public:
119 119
120 /// Sends an ioctl command to the specified file descriptor. 120 /// Sends an ioctl command to the specified file descriptor.
121 NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 121 NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
122 std::vector<u8>& output); 122 std::vector<u8>& output, IoctlCtrl& ctrl);
123 123
124 NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 124 NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
125 const std::vector<u8>& inline_input, std::vector<u8>& output); 125 const std::vector<u8>& inline_input, std::vector<u8>& output, IoctlCtrl& ctrl);
126 126
127 NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, 127 NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
128 std::vector<u8>& output, std::vector<u8>& inline_output); 128 std::vector<u8>& output, std::vector<u8>& inline_output, IoctlCtrl& ctrl);
129 129
130 /// Closes a device file descriptor and returns operation success. 130 /// Closes a device file descriptor and returns operation success.
131 NvResult Close(DeviceFD fd); 131 NvResult Close(DeviceFD fd);