HardwareTimer.h 4.9 KB

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