diff options
Diffstat (limited to 'src')
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 | ||
| 59 | protected: | 60 | protected: |
| 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)) {} |
| 19 | nvdisp_disp0 ::~nvdisp_disp0() = default; | 19 | nvdisp_disp0 ::~nvdisp_disp0() = default; |
| 20 | 20 | ||
| 21 | NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input, | 21 | NvResult 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 | ||
| 27 | NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input, | 27 | NvResult 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 | ||
| 33 | NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 34 | NvResult 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)) {} |
| 22 | nvhost_as_gpu::~nvhost_as_gpu() = default; | 22 | nvhost_as_gpu::~nvhost_as_gpu() = default; |
| 23 | 23 | ||
| 24 | NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, | 24 | NvResult 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 | ||
| 57 | NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, | 57 | NvResult 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 | ||
| 63 | NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 64 | NvResult 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 | ||
| 39 | private: | 41 | private: |
| 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} {} |
| 21 | nvhost_ctrl::~nvhost_ctrl() = default; | 21 | nvhost_ctrl::~nvhost_ctrl() = default; |
| 22 | 22 | ||
| 23 | NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 23 | NvResult 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 | ||
| 49 | NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input, | 50 | NvResult 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 | ||
| 55 | NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 57 | NvResult 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 | ||
| 69 | NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, | 71 | NvResult 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(¶ms, input.data(), sizeof(params)); | 74 | std::memcpy(¶ms, 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(), ¶ms, sizeof(params)); | 150 | std::memcpy(output.data(), ¶ms, 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 | ||
| 27 | private: | 29 | private: |
| 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) {} | |||
| 16 | nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; | 16 | nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; |
| 17 | 17 | ||
| 18 | NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, | 18 | NvResult 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 | ||
| 50 | NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, | 50 | NvResult 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 | ||
| 56 | NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, | 57 | NvResult 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(), ¶ms, output.size()); |
| 166 | std::memcpy(inline_output.data(), ¶ms.gc, inline_output.size()); | 168 | std::memcpy(inline_output.data(), ¶ms.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 | ||
| 25 | private: | 27 | private: |
| 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 | ||
| 24 | nvhost_gpu::~nvhost_gpu() = default; | 24 | nvhost_gpu::~nvhost_gpu() = default; |
| 25 | 25 | ||
| 26 | NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 26 | NvResult 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 | ||
| 77 | NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, | 78 | NvResult 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 | ||
| 91 | NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 93 | NvResult 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 | ||
| 35 | private: | 37 | private: |
| 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)) {} |
| 16 | nvhost_nvdec::~nvhost_nvdec() = default; | 16 | nvhost_nvdec::~nvhost_nvdec() = default; |
| 17 | 17 | ||
| 18 | NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, | 18 | NvResult 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 | ||
| 60 | NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input, | 60 | NvResult 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 | ||
| 66 | NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 67 | NvResult 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 | ||
| 53 | protected: | 54 | protected: |
| 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 { | |||
| 13 | nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} | 13 | nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} |
| 14 | nvhost_nvjpg::~nvhost_nvjpg() = default; | 14 | nvhost_nvjpg::~nvhost_nvjpg() = default; |
| 15 | 15 | ||
| 16 | NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, | 16 | NvResult 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 | ||
| 35 | NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input, | 35 | NvResult 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 | ||
| 41 | NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 42 | NvResult 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 | ||
| 25 | private: | 27 | private: |
| 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 | ||
| 16 | nvhost_vic::~nvhost_vic() = default; | 16 | nvhost_vic::~nvhost_vic() = default; |
| 17 | 17 | ||
| 18 | NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 18 | NvResult 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 | ||
| 52 | NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input, | 53 | NvResult 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 | ||
| 58 | NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 60 | NvResult 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 | ||
| 20 | nvmap::~nvmap() = default; | 20 | nvmap::~nvmap() = default; |
| 21 | 21 | ||
| 22 | NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 22 | NvResult 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 | ||
| 50 | NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input, | 51 | NvResult 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 | ||
| 56 | NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 58 | NvResult 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 | ||
| 100 | struct 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 | ||
| 93 | NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, | 93 | NvResult 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 | ||
| 110 | NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, | 110 | NvResult 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 | ||
| 127 | NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, | 128 | NvResult 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 | ||
| 144 | NvResult Module::Close(DeviceFD fd) { | 145 | NvResult 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); |