kernel/devices/clock/hardware_timer/
mod.rs1use alloc::sync::Arc;
7use hpet::Hpet;
8use pit::Pit;
9use tracing::warn;
10
11use crate::{acpi, cmdline, sync::spin::mutex::Mutex};
12
13use super::ClockDevice;
14
15mod hpet;
16mod pit;
17
18pub enum HardwareTimer {
19 Hpet(Arc<Mutex<Hpet>>),
20 Pit(Arc<Pit>),
21}
22impl HardwareTimer {
23 pub fn init(hpet_table: Option<&acpi::tables::Hpet>) -> Arc<dyn ClockDevice> {
24 Arc::new(match hpet_table {
25 Some(hpet_table) if cmdline::cmdline().allow_hpet => {
26 HardwareTimer::Hpet(hpet::init(hpet_table))
27 }
28 Some(_) => HardwareTimer::Pit(pit::init()),
29 None => {
30 warn!("HPET clock not found, falling back to PIT");
31 HardwareTimer::Pit(pit::init())
32 }
33 })
34 }
35}
36
37impl ClockDevice for HardwareTimer {
38 fn name(&self) -> &'static str {
39 match self {
40 HardwareTimer::Hpet(t) => t.name(),
41 HardwareTimer::Pit(t) => t.name(),
42 }
43 }
44
45 fn get_time(&self) -> super::ClockTime {
46 match self {
47 HardwareTimer::Hpet(t) => t.get_time(),
48 HardwareTimer::Pit(t) => t.get_time(),
49 }
50 }
51
52 fn granularity(&self) -> u64 {
53 match self {
54 HardwareTimer::Hpet(t) => t.granularity(),
55 HardwareTimer::Pit(t) => t.granularity(),
56 }
57 }
58
59 fn require_calibration(&self) -> bool {
60 match self {
61 HardwareTimer::Hpet(t) => t.require_calibration(),
62 HardwareTimer::Pit(t) => t.require_calibration(),
63 }
64 }
65
66 fn rating(&self) -> u64 {
67 match self {
68 HardwareTimer::Hpet(t) => t.rating(),
69 HardwareTimer::Pit(t) => t.rating(),
70 }
71 }
72}