From 67c0d714c5b6e93ddb00d0807147b5673c011ac6 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 18 Dec 2022 16:37:19 -0500 Subject: kernel: add KHardwareTimer --- src/core/hle/kernel/k_hardware_timer.cpp | 75 ++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/core/hle/kernel/k_hardware_timer.cpp (limited to 'src/core/hle/kernel/k_hardware_timer.cpp') diff --git a/src/core/hle/kernel/k_hardware_timer.cpp b/src/core/hle/kernel/k_hardware_timer.cpp new file mode 100644 index 000000000..afa777f9a --- /dev/null +++ b/src/core/hle/kernel/k_hardware_timer.cpp @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core.h" +#include "core/core_timing.h" +#include "core/hle/kernel/k_hardware_timer.h" +#include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/time_manager.h" + +namespace Kernel { + +void KHardwareTimer::Initialize() { + // Create the timing callback to register with CoreTiming. + m_event_type = Core::Timing::CreateEvent( + "KHardwareTimer::Callback", + [this](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) { + reinterpret_cast(timer_handle)->DoTask(); + return std::nullopt; + }); +} + +void KHardwareTimer::Finalize() { + this->DisableInterrupt(); +} + +void KHardwareTimer::DoTask() { + // Handle the interrupt. + { + KScopedSchedulerLock slk{m_kernel}; + KScopedSpinLock lk(this->GetLock()); + + //! Ignore this event if needed. + if (!this->GetInterruptEnabled()) { + return; + } + + // Disable the timer interrupt while we handle this. + this->DisableInterrupt(); + + if (const s64 next_time = this->DoInterruptTaskImpl(GetTick()); + 0 < next_time && next_time <= m_wakeup_time) { + // We have a next time, so we should set the time to interrupt and turn the interrupt + // on. + this->EnableInterrupt(next_time); + } + } + + // Clear the timer interrupt. + // Kernel::GetInterruptManager().ClearInterrupt(KInterruptName_NonSecurePhysicalTimer, + // GetCurrentCoreId()); +} + +void KHardwareTimer::EnableInterrupt(s64 wakeup_time) { + this->DisableInterrupt(); + + m_wakeup_time = wakeup_time; + m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time}, + m_event_type, reinterpret_cast(this), + true); +} + +void KHardwareTimer::DisableInterrupt() { + m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast(this)); + m_wakeup_time = std::numeric_limits::max(); +} + +s64 KHardwareTimer::GetTick() { + return m_kernel.System().CoreTiming().GetGlobalTimeNs().count(); +} + +bool KHardwareTimer::GetInterruptEnabled() { + return m_wakeup_time != std::numeric_limits::max(); +} + +} // namespace Kernel -- cgit v1.2.3 From c770f25ccb4755f6a6861037fbfdfdac55191348 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 18 Dec 2022 16:50:02 -0500 Subject: kernel: remove TimeManager --- src/core/hle/kernel/k_hardware_timer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/k_hardware_timer.cpp') diff --git a/src/core/hle/kernel/k_hardware_timer.cpp b/src/core/hle/kernel/k_hardware_timer.cpp index afa777f9a..6bba79ea0 100644 --- a/src/core/hle/kernel/k_hardware_timer.cpp +++ b/src/core/hle/kernel/k_hardware_timer.cpp @@ -5,15 +5,13 @@ #include "core/core_timing.h" #include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_scheduler.h" -#include "core/hle/kernel/time_manager.h" namespace Kernel { void KHardwareTimer::Initialize() { // Create the timing callback to register with CoreTiming. m_event_type = Core::Timing::CreateEvent( - "KHardwareTimer::Callback", - [this](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) { + "KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) { reinterpret_cast(timer_handle)->DoTask(); return std::nullopt; }); @@ -21,6 +19,7 @@ void KHardwareTimer::Initialize() { void KHardwareTimer::Finalize() { this->DisableInterrupt(); + m_event_type.reset(); } void KHardwareTimer::DoTask() { @@ -64,7 +63,7 @@ void KHardwareTimer::DisableInterrupt() { m_wakeup_time = std::numeric_limits::max(); } -s64 KHardwareTimer::GetTick() { +s64 KHardwareTimer::GetTick() const { return m_kernel.System().CoreTiming().GetGlobalTimeNs().count(); } -- cgit v1.2.3