From 2c62563ab58a70236a39571149f8370f3fdfb2a3 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 7 Nov 2021 14:17:32 +0100 Subject: NVHOST_CTRl: Implement missing method and fix some stuffs. --- src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 30 +++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp') diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index abde2a6d3..0e22d9273 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -52,6 +52,8 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector& return IocCtrlEventRegister(input, output); case 0x20: return IocCtrlEventUnregister(input, output); + case 0x21: + return IocCtrlEventUnregisterBatch(input, output); } break; default: @@ -249,6 +251,25 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector& input, return FreeEvent(event_id); } +NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector& input, + std::vector& output) { + IocCtrlEventUnregisterBatchParams params{}; + std::memcpy(¶ms, input.data(), sizeof(params)); + u64 event_mask = params.user_events; + LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask); + + auto lock = NvEventsLock(); + while (event_mask != 0) { + const u64 event_id = std::countr_zero(event_mask); + event_mask &= ~(1ULL << event_id); + const auto result = FreeEvent(static_cast(event_id)); + if (result != NvResult::Success) { + return result; + } + } + return NvResult::Success; +} + NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector& input, std::vector& output) { IocCtrlEventClearParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); @@ -362,10 +383,11 @@ u32 nvhost_ctrl::FindFreeNvEvent(u32 syncpoint_id) { } void nvhost_ctrl::SignalNvEvent(u32 syncpoint_id, u32 value) { - const u32 max = MaxNvEvents - std::countl_zero(events_mask); - const u32 min = std::countr_zero(events_mask); - for (u32 i = min; i < max; i++) { - auto& event = events[i]; + u64 signal_mask = events_mask; + while (signal_mask != 0) { + const u64 event_id = std::countr_zero(signal_mask); + signal_mask &= ~(1ULL << event_id); + auto& event = events[event_id]; if (event.assigned_syncpt != syncpoint_id || event.assigned_value != value) { continue; } -- cgit v1.2.3