From b6844bec608ed82511738e9f3911e72aeb05243a Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 16 Jun 2019 11:43:41 -0400 Subject: NVServices: Correct CtrlEventWaitSync to block the ipc until timeout. --- src/core/hle/service/nvdrv/devices/nvdevice.h | 4 +++- .../hle/service/nvdrv/devices/nvdisp_disp0.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | 3 ++- .../hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 22 +++++++++++++++++----- src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | 6 ++++-- .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 3 ++- .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_gpu.h | 3 ++- .../hle/service/nvdrv/devices/nvhost_nvdec.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | 3 ++- .../hle/service/nvdrv/devices/nvhost_nvjpg.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvhost_vic.h | 3 ++- src/core/hle/service/nvdrv/devices/nvmap.cpp | 3 ++- src/core/hle/service/nvdrv/devices/nvmap.h | 3 ++- 19 files changed, 56 insertions(+), 24 deletions(-) (limited to 'src/core/hle/service/nvdrv/devices') diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index ed606cd15..fae69eb19 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -8,6 +8,7 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" +#include "core/hle/service/nvdrv/nvdata.h" namespace Core { class System; @@ -37,7 +38,8 @@ public: * @param output A buffer where the output data will be written to. * @returns The result code of the ioctl. */ - virtual u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) = 0; + virtual u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) = 0; protected: 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 3336b2080..c918b4225 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -17,7 +17,8 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr nvmap_de : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} nvdisp_disp0 ::~nvdisp_disp0() = default; -u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index 812967bdf..e79e490ff 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h @@ -20,7 +20,8 @@ public: explicit nvdisp_disp0(Core::System& system, std::shared_ptr nvmap_dev); ~nvdisp_disp0() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; /// Performs a screen flip, drawing the buffer pointed to by the handle. 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 eccc3f1d9..24ab3f2e9 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -26,7 +26,8 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr nvmap_ : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} nvhost_as_gpu::~nvhost_as_gpu() = default; -u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); 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 e45d4f1ff..30ca5f4c3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -20,7 +20,8 @@ public: explicit nvhost_as_gpu(Core::System& system, std::shared_ptr nvmap_dev); ~nvhost_as_gpu() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: 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 d41274616..e46e6b94c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -19,7 +19,8 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventsInterface& events_interface : nvdevice(system), events_interface{events_interface} {} nvhost_ctrl::~nvhost_ctrl() = default; -u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); @@ -27,9 +28,9 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector& input, std::vector< case IoctlCommand::IocGetConfigCommand: return NvOsGetConfigU32(input, output); case IoctlCommand::IocCtrlEventWaitCommand: - return IocCtrlEventWait(input, output, false); + return IocCtrlEventWait(input, output, false, ctrl); case IoctlCommand::IocCtrlEventWaitAsyncCommand: - return IocCtrlEventWait(input, output, true); + return IocCtrlEventWait(input, output, true, ctrl); case IoctlCommand::IocCtrlEventRegisterCommand: return IocCtrlEventRegister(input, output); case IoctlCommand::IocCtrlEventUnregisterCommand: @@ -50,7 +51,7 @@ u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector& input, std::vector& } u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& output, - bool is_async) { + bool is_async, IoctlCtrl& ctrl) { IocCtrlEventWaitParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}", @@ -94,7 +95,11 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& return NvResult::BadParameter; } } else { - event_id = events_interface.GetFreeEvent(); + if (ctrl.fresh_call) { + event_id = events_interface.GetFreeEvent(); + } else { + event_id = ctrl.event_id; + } } EventState status = events_interface.status[event_id]; @@ -110,6 +115,13 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector& params.value |= event_id; events_interface.events[event_id].writable->Clear(); gpu.RegisterSyncptInterrupt(params.syncpt_id, params.threshold); + if (!is_async && ctrl.fresh_call) { + ctrl.must_delay = true; + ctrl.timeout = params.timeout; + ctrl.event_id = event_id; + gpu.Guard(false); + return NvResult::Timeout; + } std::memcpy(output.data(), ¶ms, sizeof(params)); gpu.Guard(false); return NvResult::Timeout; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 6cbf75f89..7cb41aa54 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -17,7 +17,8 @@ public: nvhost_ctrl(Core::System& system, EventsInterface& events_interface); ~nvhost_ctrl() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: enum class IoctlCommand : u32_le { @@ -133,7 +134,8 @@ private: u32 NvOsGetConfigU32(const std::vector& input, std::vector& output); - u32 IocCtrlEventWait(const std::vector& input, std::vector& output, bool is_async); + u32 IocCtrlEventWait(const std::vector& input, std::vector& output, bool is_async, + IoctlCtrl& ctrl); u32 IocCtrlEventRegister(const std::vector& input, std::vector& 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 c139f2ceb..e3d2b4470 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -15,7 +15,8 @@ namespace Service::Nvidia::Devices { nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system){}; nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; -u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); 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 65eac47d1..de36cb014 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -16,7 +16,8 @@ public: nvhost_ctrl_gpu(Core::System& system); ~nvhost_ctrl_gpu() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: enum class IoctlCommand : u32_le { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 13e80bfad..b9e13fae9 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -17,7 +17,8 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr nvmap_dev) : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} nvhost_gpu::~nvhost_gpu() = default; -u32 nvhost_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_gpu::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 106359f87..edc37ff3a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -23,7 +23,8 @@ public: explicit nvhost_gpu(Core::System& system, std::shared_ptr nvmap_dev); ~nvhost_gpu() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: enum class IoctlCommand : 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 3bfcb8423..f464328f3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -13,7 +13,8 @@ namespace Service::Nvidia::Devices { nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system){}; nvhost_nvdec::~nvhost_nvdec() = default; -u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index febfd4cc4..c2b7a22f6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h @@ -16,7 +16,8 @@ public: nvhost_nvdec(Core::System& system); ~nvhost_nvdec() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: 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 16c683b47..d4d67fc72 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp @@ -13,7 +13,8 @@ namespace Service::Nvidia::Devices { nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system){}; nvhost_nvjpg::~nvhost_nvjpg() = default; -u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 33b149bb7..4bf280d67 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h @@ -16,7 +16,8 @@ public: nvhost_nvjpg(Core::System& system); ~nvhost_nvjpg() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: 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 853136dea..24e38d31a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -13,7 +13,8 @@ namespace Service::Nvidia::Devices { nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system){}; nvhost_vic::~nvhost_vic() = default; -u32 nvhost_vic::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvhost_vic::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", command.raw, input.size(), output.size()); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index b71816ba1..3d0934a78 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h @@ -16,7 +16,8 @@ public: nvhost_vic(Core::System& system); ~nvhost_vic() override; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; private: 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 a75ff334b..349454685 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -28,7 +28,8 @@ VAddr nvmap::GetObjectAddress(u32 handle) const { return object->addr; } -u32 nvmap::ioctl(Ioctl command, const std::vector& input, std::vector& output) { +u32 nvmap::ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) { switch (static_cast(command.raw)) { case IoctlCommand::Create: 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 623c9b232..b79ed736c 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h @@ -22,7 +22,8 @@ public: /// Returns the allocated address of an nvmap object given its handle. VAddr GetObjectAddress(u32 handle) const; - u32 ioctl(Ioctl command, const std::vector& input, std::vector& output) override; + u32 ioctl(Ioctl command, const std::vector& input, std::vector& output, + IoctlCtrl& ctrl) override; /// Represents an nvmap object. struct Object { -- cgit v1.2.3