Serenity Operating System
at master 166 lines 5.0 kB view raw
1/* 2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/AtomicRefCounted.h> 10#include <AK/Function.h> 11#include <Kernel/Interrupts/IRQHandler.h> 12#include <Kernel/Time/TimeManagement.h> 13 14namespace Kernel { 15 16enum class HardwareTimerType { 17 i8253 = 0x1, /* PIT */ 18 RTC = 0x2, /* Real Time Clock */ 19 HighPrecisionEventTimer = 0x3, /* also known as IA-PC HPET */ 20 LocalAPICTimer = 0x4, /* Local APIC */ 21#if ARCH(AARCH64) 22 RPiTimer = 0x5 23#endif 24}; 25 26template<typename InterruptHandlerType> 27class HardwareTimer; 28 29class HardwareTimerBase : public AtomicRefCounted<HardwareTimerBase> { 30public: 31 virtual ~HardwareTimerBase() = default; 32 33 // We need to create a virtual will_be_destroyed here because we derive 34 // from RefCounted<HardwareTimerBase> here, which means that RefCounted<> 35 // will only call will_be_destroyed if we define it here. The derived 36 // classes then should forward this to e.g. GenericInterruptHandler. 37 virtual void will_be_destroyed() = 0; 38 39 virtual StringView model() const = 0; 40 virtual HardwareTimerType timer_type() const = 0; 41 virtual Function<void(RegisterState const&)> set_callback(Function<void(RegisterState const&)>) = 0; 42 43 virtual bool is_periodic() const = 0; 44 virtual bool is_periodic_capable() const = 0; 45 virtual void set_periodic() = 0; 46 virtual void set_non_periodic() = 0; 47 virtual void disable() = 0; 48 virtual u32 frequency() const = 0; 49 virtual bool can_query_raw() const { return false; } 50 virtual u64 current_raw() const { return 0; } 51 virtual u64 raw_to_ns(u64) const { return 0; } 52 53 virtual size_t ticks_per_second() const = 0; 54 55 virtual void reset_to_default_ticks_per_second() = 0; 56 virtual bool try_to_set_frequency(size_t frequency) = 0; 57 virtual bool is_capable_of_frequency(size_t frequency) const = 0; 58 virtual size_t calculate_nearest_possible_frequency(size_t frequency) const = 0; 59}; 60 61template<> 62class HardwareTimer<IRQHandler> 63 : public HardwareTimerBase 64 , public IRQHandler { 65public: 66 virtual void will_be_destroyed() override 67 { 68 IRQHandler::will_be_destroyed(); 69 } 70 71 virtual StringView purpose() const override 72 { 73 if (TimeManagement::the().is_system_timer(*this)) 74 return "System Timer"sv; 75 return model(); 76 } 77 78 virtual Function<void(RegisterState const&)> set_callback(Function<void(RegisterState const&)> callback) override 79 { 80 disable_irq(); 81 auto previous_callback = move(m_callback); 82 m_callback = move(callback); 83 enable_irq(); 84 return previous_callback; 85 } 86 87 virtual u32 frequency() const override { return (u32)m_frequency; } 88 89protected: 90 HardwareTimer(u8 irq_number, Function<void(RegisterState const&)> callback = nullptr) 91 : IRQHandler(irq_number) 92 , m_callback(move(callback)) 93 { 94 } 95 96 virtual bool handle_irq(RegisterState const& regs) override 97 { 98 // Note: if we have an IRQ on this line, it's going to be the timer always 99 if (m_callback) { 100 m_callback(regs); 101 return true; 102 } 103 return false; 104 } 105 106 u64 m_frequency { OPTIMAL_TICKS_PER_SECOND_RATE }; 107 108private: 109 Function<void(RegisterState const&)> m_callback; 110}; 111 112template<> 113class HardwareTimer<GenericInterruptHandler> 114 : public HardwareTimerBase 115 , public GenericInterruptHandler { 116public: 117 virtual void will_be_destroyed() override 118 { 119 GenericInterruptHandler::will_be_destroyed(); 120 } 121 122 virtual StringView purpose() const override 123 { 124 return model(); 125 } 126 127 virtual Function<void(RegisterState const&)> set_callback(Function<void(RegisterState const&)> callback) override 128 { 129 auto previous_callback = move(m_callback); 130 m_callback = move(callback); 131 return previous_callback; 132 } 133 134 virtual size_t sharing_devices_count() const override { return 0; } 135 virtual bool is_shared_handler() const override { return false; } 136 virtual bool is_sharing_with_others() const override { return false; } 137 virtual HandlerType type() const override { return HandlerType::IRQHandler; } 138 virtual StringView controller() const override { return {}; } 139 virtual bool eoi() override; 140 141 virtual u32 frequency() const override { return (u32)m_frequency; } 142 143protected: 144 HardwareTimer(u8 irq_number, Function<void(RegisterState const&)> callback = nullptr) 145 : GenericInterruptHandler(irq_number) 146 , m_callback(move(callback)) 147 { 148 } 149 150 virtual bool handle_interrupt(RegisterState const& regs) override 151 { 152 // Note: if we have an IRQ on this line, it's going to be the timer always 153 if (m_callback) { 154 m_callback(regs); 155 return true; 156 } 157 return false; 158 } 159 160 u64 m_frequency { OPTIMAL_TICKS_PER_SECOND_RATE }; 161 162private: 163 Function<void(RegisterState const&)> m_callback; 164}; 165 166}