From d30b885d713fa2b9393aeb3c515f4d881bf838f2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 1 Nov 2021 15:02:47 +0100 Subject: NVDRV: Implement QueryEvent. --- src/core/hle/service/nvdrv/devices/nvdevice.h | 8 +++++++ src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 23 +++++++++++++++++++ src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | 2 ++ .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 20 ++++++++++++++++- .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | 14 +++++++++++- src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 26 ++++++++++++++++++++-- src/core/hle/service/nvdrv/devices/nvhost_gpu.h | 13 +++++++++-- 7 files changed, 100 insertions(+), 6 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 696e8121e..204b0e757 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -11,6 +11,10 @@ namespace Core { class System; } +namespace Kernel { +class KEvent; +} + namespace Service::Nvidia::Devices { /// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to @@ -64,6 +68,10 @@ public: */ virtual void OnClose(DeviceFD fd) = 0; + virtual Kernel::KEvent* QueryEvent(u32 event_id) { + return nullptr; + } + protected: Core::System& system; }; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index f2b015c8f..9b393521a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -255,4 +255,27 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector& input, std::v return NvResult::Success; } +Kernel::KEvent* nvhost_ctrl::QueryEvent(u32 event_id) { + const auto event = SyncpointEventValue{.raw = event_id}; + + const bool allocated = event.event_allocated.Value() != 0; + const u32 slot{allocated ? event.partial_slot.Value() : static_cast(event.slot)}; + if (slot >= MaxNvEvents) { + ASSERT(false); + return nullptr; + } + + const u32 syncpoint_id{allocated ? event.syncpoint_id_for_allocation.Value() + : event.syncpoint_id.Value()}; + + auto lock = events_interface.Lock(); + + if (events_interface.registered[slot] && + events_interface.assigned_syncpt[slot] == syncpoint_id) { + ASSERT(events_interface.events[slot]); + return events_interface.events[slot]; + } + return nullptr; +} + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 0471c09b2..d548a7827 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -28,6 +28,8 @@ public: void OnOpen(DeviceFD fd) override; void OnClose(DeviceFD fd) override; + Kernel::KEvent* QueryEvent(u32 event_id) override; + union SyncpointEventValue { u32 raw; 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 2b3b7efea..e353408eb 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -7,10 +7,15 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" +#include "core/hle/service/nvdrv/nvdrv.h" namespace Service::Nvidia::Devices { -nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system_) : nvdevice{system_} {} +nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_) + : nvdevice{system_}, events_interface{events_interface_} { + error_notifier_event = events_interface.CreateNonCtrlEvent("CtrlGpuErrorNotifier"); + unknown_event = events_interface.CreateNonCtrlEvent("CtrlGpuUknownEvent"); +} nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector& input, @@ -286,4 +291,17 @@ NvResult nvhost_ctrl_gpu::GetGpuTime(const std::vector& input, std::vector& input, @@ -27,6 +31,8 @@ public: void OnOpen(DeviceFD fd) override; void OnClose(DeviceFD fd) override; + Kernel::KEvent* QueryEvent(u32 event_id) override; + private: struct IoctlGpuCharacteristics { u32_le arch; // 0x120 (NVGPU_GPU_ARCH_GM200) @@ -160,6 +166,12 @@ private: NvResult ZBCQueryTable(const std::vector& input, std::vector& output); NvResult FlushL2(const std::vector& input, std::vector& output); NvResult GetGpuTime(const std::vector& input, std::vector& output); + + EventInterface& events_interface; + + // Events + Kernel::KEvent* error_notifier_event; + Kernel::KEvent* unknown_event; }; } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index b98e63011..e87fa5992 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -6,6 +6,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" +#include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvdrv/syncpoint_manager.h" #include "core/memory.h" #include "video_core/gpu.h" @@ -21,10 +22,16 @@ Tegra::CommandHeader BuildFenceAction(Tegra::GPU::FenceOperation op, u32 syncpoi } // namespace nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr nvmap_dev_, - SyncpointManager& syncpoint_manager_) - : nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)}, syncpoint_manager{syncpoint_manager_} { + EventInterface& events_interface_, SyncpointManager& syncpoint_manager_) + : nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)}, events_interface{events_interface_}, + syncpoint_manager{syncpoint_manager_} { channel_fence.id = syncpoint_manager_.AllocateSyncpoint(); channel_fence.value = system_.GPU().GetSyncpointValue(channel_fence.id); + sm_exception_breakpoint_int_report_event = + events_interface.CreateNonCtrlEvent("GpuChannelSMExceptionBreakpointInt"); + sm_exception_breakpoint_pause_report_event = + events_interface.CreateNonCtrlEvent("GpuChannelSMExceptionBreakpointPause"); + error_notifier_event = events_interface.CreateNonCtrlEvent("GpuChannelErrorNotifier"); } nvhost_gpu::~nvhost_gpu() = default; @@ -328,4 +335,19 @@ NvResult nvhost_gpu::ChannelSetTimeslice(const std::vector& input, std::vect return NvResult::Success; } +Kernel::KEvent* nvhost_gpu::QueryEvent(u32 event_id) { + switch (event_id) { + case 1: + return sm_exception_breakpoint_int_report_event; + case 2: + return sm_exception_breakpoint_pause_report_event; + case 3: + return error_notifier_event; + default: { + LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); + } + } + return nullptr; +} + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 8a9f7775a..eb4936df0 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -15,7 +15,8 @@ namespace Service::Nvidia { class SyncpointManager; -} +class EventInterface; +} // namespace Service::Nvidia namespace Service::Nvidia::Devices { @@ -23,7 +24,7 @@ class nvmap; class nvhost_gpu final : public nvdevice { public: explicit nvhost_gpu(Core::System& system_, std::shared_ptr nvmap_dev_, - SyncpointManager& syncpoint_manager_); + EventInterface& events_interface_, SyncpointManager& syncpoint_manager_); ~nvhost_gpu() override; NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector& input, @@ -36,6 +37,8 @@ public: void OnOpen(DeviceFD fd) override; void OnClose(DeviceFD fd) override; + Kernel::KEvent* QueryEvent(u32 event_id) override; + private: enum class CtxObjects : u32_le { Ctx2D = 0x902D, @@ -192,8 +195,14 @@ private: NvResult ChannelSetTimeslice(const std::vector& input, std::vector& output); std::shared_ptr nvmap_dev; + EventInterface& events_interface; SyncpointManager& syncpoint_manager; NvFence channel_fence; + + // Events + Kernel::KEvent* sm_exception_breakpoint_int_report_event; + Kernel::KEvent* sm_exception_breakpoint_pause_report_event; + Kernel::KEvent* error_notifier_event; }; } // namespace Service::Nvidia::Devices -- cgit v1.2.3