diff options
27 files changed, 184 insertions, 91 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index da50a0bbc..e6f38d600 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -107,6 +107,11 @@ Stream::State AudioRenderer::GetStreamState() const { | |||
| 107 | return stream->GetState(); | 107 | return stream->GetState(); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static constexpr u32 VersionFromRevision(u32_le rev) { | ||
| 111 | // "REV7" -> 7 | ||
| 112 | return ((rev >> 24) & 0xff) - 0x30; | ||
| 113 | } | ||
| 114 | |||
| 110 | std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) { | 115 | std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) { |
| 111 | // Copy UpdateDataHeader struct | 116 | // Copy UpdateDataHeader struct |
| 112 | UpdateDataHeader config{}; | 117 | UpdateDataHeader config{}; |
| @@ -166,6 +171,11 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ | |||
| 166 | // Copy output header | 171 | // Copy output header |
| 167 | UpdateDataHeader response_data{worker_params}; | 172 | UpdateDataHeader response_data{worker_params}; |
| 168 | std::vector<u8> output_params(response_data.total_size); | 173 | std::vector<u8> output_params(response_data.total_size); |
| 174 | const auto audren_revision = VersionFromRevision(config.revision); | ||
| 175 | if (audren_revision >= 5) { | ||
| 176 | response_data.frame_count = 0x10; | ||
| 177 | response_data.total_size += 0x10; | ||
| 178 | } | ||
| 169 | std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); | 179 | std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); |
| 170 | 180 | ||
| 171 | // Copy output memory pool entries | 181 | // Copy output memory pool entries |
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 45afbe759..4f14b91cd 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h | |||
| @@ -194,21 +194,24 @@ struct UpdateDataHeader { | |||
| 194 | mixes_size = 0x0; | 194 | mixes_size = 0x0; |
| 195 | sinks_size = config.sink_count * 0x20; | 195 | sinks_size = config.sink_count * 0x20; |
| 196 | performance_manager_size = 0x10; | 196 | performance_manager_size = 0x10; |
| 197 | frame_count = 0; | ||
| 197 | total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + | 198 | total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + |
| 198 | effects_size + sinks_size + performance_manager_size; | 199 | effects_size + sinks_size + performance_manager_size; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| 201 | u32_le revision; | 202 | u32_le revision{}; |
| 202 | u32_le behavior_size; | 203 | u32_le behavior_size{}; |
| 203 | u32_le memory_pools_size; | 204 | u32_le memory_pools_size{}; |
| 204 | u32_le voices_size; | 205 | u32_le voices_size{}; |
| 205 | u32_le voice_resource_size; | 206 | u32_le voice_resource_size{}; |
| 206 | u32_le effects_size; | 207 | u32_le effects_size{}; |
| 207 | u32_le mixes_size; | 208 | u32_le mixes_size{}; |
| 208 | u32_le sinks_size; | 209 | u32_le sinks_size{}; |
| 209 | u32_le performance_manager_size; | 210 | u32_le performance_manager_size{}; |
| 210 | INSERT_PADDING_WORDS(6); | 211 | INSERT_PADDING_WORDS(1); |
| 211 | u32_le total_size; | 212 | u32_le frame_count{}; |
| 213 | INSERT_PADDING_WORDS(4); | ||
| 214 | u32_le total_size{}; | ||
| 212 | }; | 215 | }; |
| 213 | static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); | 216 | static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); |
| 214 | 217 | ||
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index a7c55e116..0c0f7ed6e 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -70,7 +70,7 @@ public: | |||
| 70 | 70 | ||
| 71 | protected: | 71 | protected: |
| 72 | void Get(Kernel::HLERequestContext& ctx) { | 72 | void Get(Kernel::HLERequestContext& ctx) { |
| 73 | LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); | 73 | LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); |
| 74 | ProfileBase profile_base{}; | 74 | ProfileBase profile_base{}; |
| 75 | ProfileData data{}; | 75 | ProfileData data{}; |
| 76 | if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { | 76 | if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { |
| @@ -89,7 +89,7 @@ protected: | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | void GetBase(Kernel::HLERequestContext& ctx) { | 91 | void GetBase(Kernel::HLERequestContext& ctx) { |
| 92 | LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); | 92 | LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); |
| 93 | ProfileBase profile_base{}; | 93 | ProfileBase profile_base{}; |
| 94 | if (profile_manager.GetProfileBase(user_id, profile_base)) { | 94 | if (profile_manager.GetProfileBase(user_id, profile_base)) { |
| 95 | IPC::ResponseBuilder rb{ctx, 16}; | 95 | IPC::ResponseBuilder rb{ctx, 16}; |
| @@ -263,7 +263,7 @@ private: | |||
| 263 | }; | 263 | }; |
| 264 | 264 | ||
| 265 | void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { | 265 | void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { |
| 266 | LOG_INFO(Service_ACC, "called"); | 266 | LOG_DEBUG(Service_ACC, "called"); |
| 267 | IPC::ResponseBuilder rb{ctx, 3}; | 267 | IPC::ResponseBuilder rb{ctx, 3}; |
| 268 | rb.Push(RESULT_SUCCESS); | 268 | rb.Push(RESULT_SUCCESS); |
| 269 | rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount())); | 269 | rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount())); |
| @@ -272,7 +272,7 @@ void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { | |||
| 272 | void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { | 272 | void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { |
| 273 | IPC::RequestParser rp{ctx}; | 273 | IPC::RequestParser rp{ctx}; |
| 274 | Common::UUID user_id = rp.PopRaw<Common::UUID>(); | 274 | Common::UUID user_id = rp.PopRaw<Common::UUID>(); |
| 275 | LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); | 275 | LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); |
| 276 | 276 | ||
| 277 | IPC::ResponseBuilder rb{ctx, 3}; | 277 | IPC::ResponseBuilder rb{ctx, 3}; |
| 278 | rb.Push(RESULT_SUCCESS); | 278 | rb.Push(RESULT_SUCCESS); |
| @@ -280,21 +280,21 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { | |||
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { | 282 | void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { |
| 283 | LOG_INFO(Service_ACC, "called"); | 283 | LOG_DEBUG(Service_ACC, "called"); |
| 284 | ctx.WriteBuffer(profile_manager->GetAllUsers()); | 284 | ctx.WriteBuffer(profile_manager->GetAllUsers()); |
| 285 | IPC::ResponseBuilder rb{ctx, 2}; | 285 | IPC::ResponseBuilder rb{ctx, 2}; |
| 286 | rb.Push(RESULT_SUCCESS); | 286 | rb.Push(RESULT_SUCCESS); |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { | 289 | void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { |
| 290 | LOG_INFO(Service_ACC, "called"); | 290 | LOG_DEBUG(Service_ACC, "called"); |
| 291 | ctx.WriteBuffer(profile_manager->GetOpenUsers()); | 291 | ctx.WriteBuffer(profile_manager->GetOpenUsers()); |
| 292 | IPC::ResponseBuilder rb{ctx, 2}; | 292 | IPC::ResponseBuilder rb{ctx, 2}; |
| 293 | rb.Push(RESULT_SUCCESS); | 293 | rb.Push(RESULT_SUCCESS); |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { | 296 | void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { |
| 297 | LOG_INFO(Service_ACC, "called"); | 297 | LOG_DEBUG(Service_ACC, "called"); |
| 298 | IPC::ResponseBuilder rb{ctx, 6}; | 298 | IPC::ResponseBuilder rb{ctx, 6}; |
| 299 | rb.Push(RESULT_SUCCESS); | 299 | rb.Push(RESULT_SUCCESS); |
| 300 | rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser()); | 300 | rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index 5b8248433..1b52511a5 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 11 | #include "core/hle/service/nvdrv/nvdata.h" | 11 | #include "core/hle/service/nvdrv/nvdata.h" |
| 12 | #include "core/hle/service/service.h" | ||
| 12 | 13 | ||
| 13 | namespace Core { | 14 | namespace Core { |
| 14 | class System; | 15 | class System; |
| @@ -38,8 +39,9 @@ public: | |||
| 38 | * @param output A buffer where the output data will be written to. | 39 | * @param output A buffer where the output data will be written to. |
| 39 | * @returns The result code of the ioctl. | 40 | * @returns The result code of the ioctl. |
| 40 | */ | 41 | */ |
| 41 | virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 42 | virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 42 | IoctlCtrl& ctrl) = 0; | 43 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 44 | IoctlVersion version) = 0; | ||
| 43 | 45 | ||
| 44 | protected: | 46 | protected: |
| 45 | Core::System& system; | 47 | 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 926a1285d..f764388bc 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -17,8 +17,9 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de | |||
| 17 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} | 17 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} |
| 18 | nvdisp_disp0 ::~nvdisp_disp0() = default; | 18 | nvdisp_disp0 ::~nvdisp_disp0() = default; |
| 19 | 19 | ||
| 20 | u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 20 | u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 21 | IoctlCtrl& ctrl) { | 21 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 22 | IoctlVersion version) { | ||
| 22 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); | 23 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 23 | return 0; | 24 | return 0; |
| 24 | } | 25 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index e79e490ff..6fcdeee84 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -20,8 +20,9 @@ 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 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 24 | IoctlCtrl& ctrl) override; | 24 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 25 | IoctlVersion version) override; | ||
| 25 | 26 | ||
| 26 | /// Performs a screen flip, drawing the buffer pointed to by the handle. | 27 | /// Performs a screen flip, drawing the buffer pointed to by the handle. |
| 27 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, | 28 | 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 24ab3f2e9..6bc053f27 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -26,8 +26,9 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_ | |||
| 26 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} | 26 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} |
| 27 | nvhost_as_gpu::~nvhost_as_gpu() = default; | 27 | nvhost_as_gpu::~nvhost_as_gpu() = default; |
| 28 | 28 | ||
| 29 | u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 29 | u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 30 | IoctlCtrl& ctrl) { | 30 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 31 | IoctlVersion version) { | ||
| 31 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 32 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 32 | command.raw, input.size(), output.size()); | 33 | command.raw, input.size(), output.size()); |
| 33 | 34 | ||
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 30ca5f4c3..169fb8f0e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -20,8 +20,9 @@ public: | |||
| 20 | explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); | 20 | explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); |
| 21 | ~nvhost_as_gpu() override; | 21 | ~nvhost_as_gpu() override; |
| 22 | 22 | ||
| 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 24 | IoctlCtrl& ctrl) override; | 24 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 25 | IoctlVersion version) override; | ||
| 25 | 26 | ||
| 26 | private: | 27 | private: |
| 27 | enum class IoctlCommand : u32_le { | 28 | enum class IoctlCommand : u32_le { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 9a66a5f88..ff6b1abae 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -19,8 +19,9 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface) | |||
| 19 | : nvdevice(system), events_interface{events_interface} {} | 19 | : nvdevice(system), events_interface{events_interface} {} |
| 20 | nvhost_ctrl::~nvhost_ctrl() = default; | 20 | nvhost_ctrl::~nvhost_ctrl() = default; |
| 21 | 21 | ||
| 22 | u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 22 | u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 23 | IoctlCtrl& ctrl) { | 23 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 24 | IoctlVersion version) { | ||
| 24 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 25 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 25 | command.raw, input.size(), output.size()); | 26 | command.raw, input.size(), output.size()); |
| 26 | 27 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 14e6e7e57..9898623de 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -17,8 +17,9 @@ public: | |||
| 17 | explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface); | 17 | explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface); |
| 18 | ~nvhost_ctrl() override; | 18 | ~nvhost_ctrl() override; |
| 19 | 19 | ||
| 20 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 20 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 21 | IoctlCtrl& ctrl) override; | 21 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 22 | IoctlVersion version) override; | ||
| 22 | 23 | ||
| 23 | private: | 24 | private: |
| 24 | enum class IoctlCommand : u32_le { | 25 | enum class IoctlCommand : u32_le { |
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 988effd90..389ace76f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -15,14 +15,15 @@ namespace Service::Nvidia::Devices { | |||
| 15 | nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {} | 15 | 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 | u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 18 | u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, |
| 19 | IoctlCtrl& ctrl) { | 19 | const std::vector<u8>& input2, std::vector<u8>& output, |
| 20 | std::vector<u8>& output2, IoctlCtrl& ctrl, IoctlVersion version) { | ||
| 20 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 21 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 21 | command.raw, input.size(), output.size()); | 22 | command.raw, input.size(), output.size()); |
| 22 | 23 | ||
| 23 | switch (static_cast<IoctlCommand>(command.raw)) { | 24 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 24 | case IoctlCommand::IocGetCharacteristicsCommand: | 25 | case IoctlCommand::IocGetCharacteristicsCommand: |
| 25 | return GetCharacteristics(input, output); | 26 | return GetCharacteristics(input, output, output2, version); |
| 26 | case IoctlCommand::IocGetTPCMasksCommand: | 27 | case IoctlCommand::IocGetTPCMasksCommand: |
| 27 | return GetTPCMasks(input, output); | 28 | return GetTPCMasks(input, output); |
| 28 | case IoctlCommand::IocGetActiveSlotMaskCommand: | 29 | case IoctlCommand::IocGetActiveSlotMaskCommand: |
| @@ -44,7 +45,8 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec | |||
| 44 | return 0; | 45 | return 0; |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { | 48 | u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output, |
| 49 | std::vector<u8>& output2, IoctlVersion version) { | ||
| 48 | LOG_DEBUG(Service_NVDRV, "called"); | 50 | LOG_DEBUG(Service_NVDRV, "called"); |
| 49 | IoctlCharacteristics params{}; | 51 | IoctlCharacteristics params{}; |
| 50 | std::memcpy(¶ms, input.data(), input.size()); | 52 | std::memcpy(¶ms, input.data(), input.size()); |
| @@ -85,7 +87,13 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto | |||
| 85 | params.gc.gr_compbit_store_base_hw = 0x0; | 87 | params.gc.gr_compbit_store_base_hw = 0x0; |
| 86 | params.gpu_characteristics_buf_size = 0xA0; | 88 | params.gpu_characteristics_buf_size = 0xA0; |
| 87 | params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) | 89 | params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) |
| 88 | std::memcpy(output.data(), ¶ms, output.size()); | 90 | |
| 91 | if (version == IoctlVersion::Version3) { | ||
| 92 | std::memcpy(output.data(), input.data(), output.size()); | ||
| 93 | std::memcpy(output2.data(), ¶ms.gc, output2.size()); | ||
| 94 | } else { | ||
| 95 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 96 | } | ||
| 89 | return 0; | 97 | return 0; |
| 90 | } | 98 | } |
| 91 | 99 | ||
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 2b035ae3f..642b0a2cb 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | |||
| @@ -16,8 +16,9 @@ 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 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 20 | IoctlCtrl& ctrl) override; | 20 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 21 | IoctlVersion version) override; | ||
| 21 | 22 | ||
| 22 | private: | 23 | private: |
| 23 | enum class IoctlCommand : u32_le { | 24 | enum class IoctlCommand : u32_le { |
| @@ -162,7 +163,8 @@ private: | |||
| 162 | }; | 163 | }; |
| 163 | static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size"); | 164 | static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size"); |
| 164 | 165 | ||
| 165 | u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output); | 166 | u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output, |
| 167 | std::vector<u8>& output2, IoctlVersion version); | ||
| 166 | u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output); | 168 | u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output); |
| 167 | u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output); | 169 | u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output); |
| 168 | u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output); | 170 | u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index b4ee2a255..2b8d1bef6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -17,8 +17,9 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev) | |||
| 17 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} | 17 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} |
| 18 | nvhost_gpu::~nvhost_gpu() = default; | 18 | nvhost_gpu::~nvhost_gpu() = default; |
| 19 | 19 | ||
| 20 | u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 20 | u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 21 | IoctlCtrl& ctrl) { | 21 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 22 | IoctlVersion version) { | ||
| 22 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 23 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 23 | command.raw, input.size(), output.size()); | 24 | command.raw, input.size(), output.size()); |
| 24 | 25 | ||
| @@ -50,7 +51,7 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u | |||
| 50 | return SubmitGPFIFO(input, output); | 51 | return SubmitGPFIFO(input, output); |
| 51 | } | 52 | } |
| 52 | if (command.cmd == NVGPU_IOCTL_CHANNEL_KICKOFF_PB) { | 53 | if (command.cmd == NVGPU_IOCTL_CHANNEL_KICKOFF_PB) { |
| 53 | return KickoffPB(input, output); | 54 | return KickoffPB(input, output, input2, version); |
| 54 | } | 55 | } |
| 55 | } | 56 | } |
| 56 | 57 | ||
| @@ -173,7 +174,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 173 | return 0; | 174 | return 0; |
| 174 | } | 175 | } |
| 175 | 176 | ||
| 176 | u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) { | 177 | u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output, |
| 178 | const std::vector<u8>& input2, IoctlVersion version) { | ||
| 177 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { | 179 | if (input.size() < sizeof(IoctlSubmitGpfifo)) { |
| 178 | UNIMPLEMENTED(); | 180 | UNIMPLEMENTED(); |
| 179 | } | 181 | } |
| @@ -183,9 +185,13 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) | |||
| 183 | params.num_entries, params.flags.raw); | 185 | params.num_entries, params.flags.raw); |
| 184 | 186 | ||
| 185 | Tegra::CommandList entries(params.num_entries); | 187 | Tegra::CommandList entries(params.num_entries); |
| 186 | Memory::ReadBlock(params.address, entries.data(), | 188 | if (version == IoctlVersion::Version2) { |
| 187 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 189 | std::memcpy(entries.data(), input2.data(), |
| 188 | 190 | params.num_entries * sizeof(Tegra::CommandListHeader)); | |
| 191 | } else { | ||
| 192 | Memory::ReadBlock(params.address, entries.data(), | ||
| 193 | params.num_entries * sizeof(Tegra::CommandListHeader)); | ||
| 194 | } | ||
| 189 | UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); | 195 | UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); |
| 190 | UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); | 196 | UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); |
| 191 | 197 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index d2e8fbae9..d056dd046 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -24,8 +24,9 @@ public: | |||
| 24 | explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); | 24 | explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); |
| 25 | ~nvhost_gpu() override; | 25 | ~nvhost_gpu() override; |
| 26 | 26 | ||
| 27 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 27 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 28 | IoctlCtrl& ctrl) override; | 28 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 29 | IoctlVersion version) override; | ||
| 29 | 30 | ||
| 30 | private: | 31 | private: |
| 31 | enum class IoctlCommand : u32_le { | 32 | enum class IoctlCommand : u32_le { |
| @@ -183,7 +184,8 @@ private: | |||
| 183 | u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); | 184 | u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); |
| 184 | u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); | 185 | u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); |
| 185 | u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output); | 186 | u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output); |
| 186 | u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output); | 187 | u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output, |
| 188 | const std::vector<u8>& input2, IoctlVersion version); | ||
| 187 | u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); | 189 | u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); |
| 188 | u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); | 190 | u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); |
| 189 | 191 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index f572ad30f..bdae8b887 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices { | |||
| 13 | nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {} | 13 | nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {} |
| 14 | nvhost_nvdec::~nvhost_nvdec() = default; | 14 | nvhost_nvdec::~nvhost_nvdec() = default; |
| 15 | 15 | ||
| 16 | u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 16 | u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 17 | IoctlCtrl& ctrl) { | 17 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 18 | IoctlVersion version) { | ||
| 18 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 19 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 19 | command.raw, input.size(), output.size()); | 20 | command.raw, input.size(), output.size()); |
| 20 | 21 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 2710f0511..cbdac8069 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -16,8 +16,9 @@ public: | |||
| 16 | explicit nvhost_nvdec(Core::System& system); | 16 | explicit nvhost_nvdec(Core::System& system); |
| 17 | ~nvhost_nvdec() override; | 17 | ~nvhost_nvdec() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 20 | IoctlCtrl& ctrl) override; | 20 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 21 | IoctlVersion version) override; | ||
| 21 | 22 | ||
| 22 | private: | 23 | private: |
| 23 | enum class IoctlCommand : u32_le { | 24 | enum class IoctlCommand : u32_le { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index 38282956f..96e7b7dab 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp | |||
| @@ -13,8 +13,9 @@ 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 | u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 16 | u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 17 | IoctlCtrl& ctrl) { | 17 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 18 | IoctlVersion version) { | ||
| 18 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 19 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 19 | command.raw, input.size(), output.size()); | 20 | command.raw, input.size(), output.size()); |
| 20 | 21 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 379766693..98dcac52f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h | |||
| @@ -16,8 +16,9 @@ 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 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 20 | IoctlCtrl& ctrl) override; | 20 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 21 | IoctlVersion version) override; | ||
| 21 | 22 | ||
| 22 | private: | 23 | private: |
| 23 | enum class IoctlCommand : u32_le { | 24 | enum class IoctlCommand : u32_le { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 70e8091db..c695b8863 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices { | |||
| 13 | nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {} | 13 | nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {} |
| 14 | nvhost_vic::~nvhost_vic() = default; | 14 | nvhost_vic::~nvhost_vic() = default; |
| 15 | 15 | ||
| 16 | u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 16 | u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 17 | IoctlCtrl& ctrl) { | 17 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 18 | IoctlVersion version) { | ||
| 18 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 19 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 19 | command.raw, input.size(), output.size()); | 20 | command.raw, input.size(), output.size()); |
| 20 | 21 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index 7d111977e..bec32bea1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -16,8 +16,9 @@ public: | |||
| 16 | explicit nvhost_vic(Core::System& system); | 16 | explicit nvhost_vic(Core::System& system); |
| 17 | ~nvhost_vic() override; | 17 | ~nvhost_vic() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 20 | IoctlCtrl& ctrl) override; | 20 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 21 | IoctlVersion version) override; | ||
| 21 | 22 | ||
| 22 | private: | 23 | private: |
| 23 | enum class IoctlCommand : u32_le { | 24 | enum class IoctlCommand : u32_le { |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 223b496b7..8c742316c 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -28,8 +28,9 @@ VAddr nvmap::GetObjectAddress(u32 handle) const { | |||
| 28 | return object->addr; | 28 | return object->addr; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 31 | u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 32 | IoctlCtrl& ctrl) { | 32 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 33 | IoctlVersion version) { | ||
| 33 | switch (static_cast<IoctlCommand>(command.raw)) { | 34 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 34 | case IoctlCommand::Create: | 35 | case IoctlCommand::Create: |
| 35 | return IocCreate(input, output); | 36 | return IocCreate(input, output); |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index bf4a101c2..73c2e8809 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -22,8 +22,9 @@ public: | |||
| 22 | /// Returns the allocated address of an nvmap object given its handle. | 22 | /// Returns the allocated address of an nvmap object given its handle. |
| 23 | VAddr GetObjectAddress(u32 handle) const; | 23 | VAddr GetObjectAddress(u32 handle) const; |
| 24 | 24 | ||
| 25 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, | 25 | u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 26 | IoctlCtrl& ctrl) override; | 26 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 27 | IoctlVersion version) override; | ||
| 27 | 28 | ||
| 28 | /// Represents an nvmap object. | 29 | /// Represents an nvmap object. |
| 29 | struct Object { | 30 | struct Object { |
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index d5be64ed2..5e0c23602 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -33,42 +33,77 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) { | |||
| 33 | rb.Push<u32>(0); | 33 | rb.Push<u32>(0); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { | 36 | void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) { |
| 37 | LOG_DEBUG(Service_NVDRV, "called"); | ||
| 38 | |||
| 39 | IPC::RequestParser rp{ctx}; | 37 | IPC::RequestParser rp{ctx}; |
| 40 | u32 fd = rp.Pop<u32>(); | 38 | u32 fd = rp.Pop<u32>(); |
| 41 | u32 command = rp.Pop<u32>(); | 39 | u32 command = rp.Pop<u32>(); |
| 42 | 40 | ||
| 43 | std::vector<u8> output(ctx.GetWriteBufferSize()); | 41 | /// Ioctl 3 has 2 outputs, first in the input params, second is the result |
| 42 | std::vector<u8> output(ctx.GetWriteBufferSize(0)); | ||
| 43 | std::vector<u8> output2; | ||
| 44 | if (version == IoctlVersion::Version3) { | ||
| 45 | output2.resize((ctx.GetWriteBufferSize(1))); | ||
| 46 | } | ||
| 47 | |||
| 48 | /// Ioctl2 has 2 inputs. It's used to pass data directly instead of providing a pointer. | ||
| 49 | /// KickOfPB uses this | ||
| 50 | auto input = ctx.ReadBuffer(0); | ||
| 51 | |||
| 52 | std::vector<u8> input2; | ||
| 53 | if (version == IoctlVersion::Version2) { | ||
| 54 | input2 = ctx.ReadBuffer(1); | ||
| 55 | } | ||
| 44 | 56 | ||
| 45 | IoctlCtrl ctrl{}; | 57 | IoctlCtrl ctrl{}; |
| 46 | 58 | ||
| 47 | u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl); | 59 | u32 result = nvdrv->Ioctl(fd, command, input, input2, output, output2, ctrl, version); |
| 48 | 60 | ||
| 49 | if (ctrl.must_delay) { | 61 | if (ctrl.must_delay) { |
| 50 | ctrl.fresh_call = false; | 62 | ctrl.fresh_call = false; |
| 51 | ctx.SleepClientThread( | 63 | ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout, |
| 52 | "NVServices::DelayedResponse", ctrl.timeout, | 64 | [=](Kernel::SharedPtr<Kernel::Thread> thread, |
| 53 | [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, | 65 | Kernel::HLERequestContext& ctx, |
| 54 | Kernel::ThreadWakeupReason reason) { | 66 | Kernel::ThreadWakeupReason reason) { |
| 55 | IoctlCtrl ctrl2{ctrl}; | 67 | IoctlCtrl ctrl2{ctrl}; |
| 56 | std::vector<u8> output2 = output; | 68 | std::vector<u8> tmp_output = output; |
| 57 | u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output2, ctrl2); | 69 | std::vector<u8> tmp_output2 = output2; |
| 58 | ctx.WriteBuffer(output2); | 70 | u32 result = nvdrv->Ioctl(fd, command, input, input2, tmp_output, |
| 59 | IPC::ResponseBuilder rb{ctx, 3}; | 71 | tmp_output2, ctrl2, version); |
| 60 | rb.Push(RESULT_SUCCESS); | 72 | ctx.WriteBuffer(tmp_output, 0); |
| 61 | rb.Push(result); | 73 | if (version == IoctlVersion::Version3) { |
| 62 | }, | 74 | ctx.WriteBuffer(tmp_output2, 1); |
| 63 | nvdrv->GetEventWriteable(ctrl.event_id)); | 75 | } |
| 76 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 77 | rb.Push(RESULT_SUCCESS); | ||
| 78 | rb.Push(result); | ||
| 79 | }, | ||
| 80 | nvdrv->GetEventWriteable(ctrl.event_id)); | ||
| 64 | } else { | 81 | } else { |
| 65 | ctx.WriteBuffer(output); | 82 | ctx.WriteBuffer(output); |
| 83 | if (version == IoctlVersion::Version3) { | ||
| 84 | ctx.WriteBuffer(output2, 1); | ||
| 85 | } | ||
| 66 | } | 86 | } |
| 67 | IPC::ResponseBuilder rb{ctx, 3}; | 87 | IPC::ResponseBuilder rb{ctx, 3}; |
| 68 | rb.Push(RESULT_SUCCESS); | 88 | rb.Push(RESULT_SUCCESS); |
| 69 | rb.Push(result); | 89 | rb.Push(result); |
| 70 | } | 90 | } |
| 71 | 91 | ||
| 92 | void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { | ||
| 93 | LOG_DEBUG(Service_NVDRV, "called"); | ||
| 94 | IoctlBase(ctx, IoctlVersion::Version1); | ||
| 95 | } | ||
| 96 | |||
| 97 | void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) { | ||
| 98 | LOG_DEBUG(Service_NVDRV, "called"); | ||
| 99 | IoctlBase(ctx, IoctlVersion::Version2); | ||
| 100 | } | ||
| 101 | |||
| 102 | void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) { | ||
| 103 | LOG_DEBUG(Service_NVDRV, "called"); | ||
| 104 | IoctlBase(ctx, IoctlVersion::Version3); | ||
| 105 | } | ||
| 106 | |||
| 72 | void NVDRV::Close(Kernel::HLERequestContext& ctx) { | 107 | void NVDRV::Close(Kernel::HLERequestContext& ctx) { |
| 73 | LOG_DEBUG(Service_NVDRV, "called"); | 108 | LOG_DEBUG(Service_NVDRV, "called"); |
| 74 | 109 | ||
| @@ -154,8 +189,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) | |||
| 154 | {8, &NVDRV::SetClientPID, "SetClientPID"}, | 189 | {8, &NVDRV::SetClientPID, "SetClientPID"}, |
| 155 | {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"}, | 190 | {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"}, |
| 156 | {10, nullptr, "InitializeDevtools"}, | 191 | {10, nullptr, "InitializeDevtools"}, |
| 157 | {11, &NVDRV::Ioctl, "Ioctl2"}, | 192 | {11, &NVDRV::Ioctl2, "Ioctl2"}, |
| 158 | {12, nullptr, "Ioctl3"}, | 193 | {12, &NVDRV::Ioctl3, "Ioctl3"}, |
| 159 | {13, &NVDRV::FinishInitialize, "FinishInitialize"}, | 194 | {13, &NVDRV::FinishInitialize, "FinishInitialize"}, |
| 160 | }; | 195 | }; |
| 161 | RegisterHandlers(functions); | 196 | RegisterHandlers(functions); |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 10a0ecd52..9269ce00c 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -24,6 +24,8 @@ public: | |||
| 24 | private: | 24 | private: |
| 25 | void Open(Kernel::HLERequestContext& ctx); | 25 | void Open(Kernel::HLERequestContext& ctx); |
| 26 | void Ioctl(Kernel::HLERequestContext& ctx); | 26 | void Ioctl(Kernel::HLERequestContext& ctx); |
| 27 | void Ioctl2(Kernel::HLERequestContext& ctx); | ||
| 28 | void Ioctl3(Kernel::HLERequestContext& ctx); | ||
| 27 | void Close(Kernel::HLERequestContext& ctx); | 29 | void Close(Kernel::HLERequestContext& ctx); |
| 28 | void Initialize(Kernel::HLERequestContext& ctx); | 30 | void Initialize(Kernel::HLERequestContext& ctx); |
| 29 | void QueryEvent(Kernel::HLERequestContext& ctx); | 31 | void QueryEvent(Kernel::HLERequestContext& ctx); |
| @@ -31,6 +33,7 @@ private: | |||
| 31 | void FinishInitialize(Kernel::HLERequestContext& ctx); | 33 | void FinishInitialize(Kernel::HLERequestContext& ctx); |
| 32 | void GetStatus(Kernel::HLERequestContext& ctx); | 34 | void GetStatus(Kernel::HLERequestContext& ctx); |
| 33 | void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); | 35 | void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); |
| 36 | void IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version); | ||
| 34 | 37 | ||
| 35 | std::shared_ptr<Module> nvdrv; | 38 | std::shared_ptr<Module> nvdrv; |
| 36 | 39 | ||
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h index ac03cbc23..529b03471 100644 --- a/src/core/hle/service/nvdrv/nvdata.h +++ b/src/core/hle/service/nvdrv/nvdata.h | |||
| @@ -34,6 +34,12 @@ enum class EventState { | |||
| 34 | Busy = 3, | 34 | Busy = 3, |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | enum class IoctlVersion : u32 { | ||
| 38 | Version1, | ||
| 39 | Version2, | ||
| 40 | Version3, | ||
| 41 | }; | ||
| 42 | |||
| 37 | struct IoctlCtrl { | 43 | struct IoctlCtrl { |
| 38 | // First call done to the servioce for services that call itself again after a call. | 44 | // First call done to the servioce for services that call itself again after a call. |
| 39 | bool fresh_call{true}; | 45 | bool fresh_call{true}; |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 2011a226a..307a7e928 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -71,13 +71,14 @@ u32 Module::Open(const std::string& device_name) { | |||
| 71 | return fd; | 71 | return fd; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output, | 74 | u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 75 | IoctlCtrl& ctrl) { | 75 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 76 | IoctlVersion version) { | ||
| 76 | auto itr = open_files.find(fd); | 77 | auto itr = open_files.find(fd); |
| 77 | ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); | 78 | ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); |
| 78 | 79 | ||
| 79 | auto& device = itr->second; | 80 | auto& device = itr->second; |
| 80 | return device->ioctl({command}, input, output, ctrl); | 81 | return device->ioctl({command}, input, input2, output, output2, ctrl, version); |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | ResultCode Module::Close(u32 fd) { | 84 | ResultCode Module::Close(u32 fd) { |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index a339ab672..f8bb28969 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -106,8 +106,9 @@ public: | |||
| 106 | /// Opens a device node and returns a file descriptor to it. | 106 | /// Opens a device node and returns a file descriptor to it. |
| 107 | u32 Open(const std::string& device_name); | 107 | u32 Open(const std::string& device_name); |
| 108 | /// Sends an ioctl command to the specified file descriptor. | 108 | /// Sends an ioctl command to the specified file descriptor. |
| 109 | u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output, | 109 | u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2, |
| 110 | IoctlCtrl& ctrl); | 110 | std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl, |
| 111 | IoctlVersion version); | ||
| 111 | /// Closes a device file descriptor and returns operation success. | 112 | /// Closes a device file descriptor and returns operation success. |
| 112 | ResultCode Close(u32 fd); | 113 | ResultCode Close(u32 fd); |
| 113 | 114 | ||