mirror of
https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
synced 2025-12-20 12:32:40 +00:00
NVDRV: Implement QueryEvent.
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -255,4 +255,27 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& 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<u32>(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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<u8>& input,
|
||||
@@ -286,4 +291,17 @@ NvResult nvhost_ctrl_gpu::GetGpuTime(const std::vector<u8>& input, std::vector<u
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) {
|
||||
switch (event_id) {
|
||||
case 1:
|
||||
return error_notifier_event;
|
||||
case 2:
|
||||
return unknown_event;
|
||||
default: {
|
||||
LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -10,11 +10,15 @@
|
||||
#include "common/swap.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvdevice.h"
|
||||
|
||||
namespace Service::Nvidia {
|
||||
class EventInterface;
|
||||
}
|
||||
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
class nvhost_ctrl_gpu final : public nvdevice {
|
||||
public:
|
||||
explicit nvhost_ctrl_gpu(Core::System& system_);
|
||||
explicit nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_);
|
||||
~nvhost_ctrl_gpu() override;
|
||||
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& 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<u8>& input, std::vector<u8>& output);
|
||||
NvResult FlushL2(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
NvResult GetGpuTime(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
|
||||
EventInterface& events_interface;
|
||||
|
||||
// Events
|
||||
Kernel::KEvent* error_notifier_event;
|
||||
Kernel::KEvent* unknown_event;
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -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> 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<u8>& 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
|
||||
|
||||
@@ -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> nvmap_dev_,
|
||||
SyncpointManager& syncpoint_manager_);
|
||||
EventInterface& events_interface_, SyncpointManager& syncpoint_manager_);
|
||||
~nvhost_gpu() override;
|
||||
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& 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<u8>& input, std::vector<u8>& output);
|
||||
|
||||
std::shared_ptr<nvmap> 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
|
||||
|
||||
Reference in New Issue
Block a user