xref: /DragonOS/kernel/src/driver/timers/hpet/mod.rs (revision 3959e94df38073fdb80b199777015f95611ba05f)
1 use core::ptr::NonNull;
2 
3 use crate::libs::volatile::Volatile;
4 
5 #[repr(C, packed)]
6 pub struct HpetRegisters {
7     capabilties: Volatile<u32>,
8     period: Volatile<u32>,
9     _reserved0: Volatile<u64>,
10     general_config: Volatile<u64>,
11     _reserved1: Volatile<u64>,
12     general_intr_status: Volatile<u64>,
13     _reserved2: [Volatile<u64>; 25],
14     main_counter_value: Volatile<u64>,
15     _reserved3: Volatile<u64>,
16     // 这里后面跟着各个定时器的寄存器(数量由capabilties决定)
17 }
18 
19 impl HpetRegisters {
20     /// 获取 HPET Timer 的数量
21     pub fn timers_num(&self) -> usize {
22         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
23         let cap = unsafe { volread!(p, capabilties) };
24         (cap >> 8) as usize & 0x1f
25     }
26 
27     /// 获取 HPET 计数器的周期
28     pub fn counter_clock_period(&self) -> u64 {
29         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
30         let period = unsafe { volread!(p, period) };
31         period as u64
32     }
33 
34     /// 获取 HPET 计数器的频率
35     pub fn frequency(&self) -> u64 {
36         1_000_000_000_000_000 / self.counter_clock_period()
37     }
38 
39     pub fn main_counter_value(&self) -> u64 {
40         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
41         let main_counter_value = unsafe { volread!(p, main_counter_value) };
42         main_counter_value
43     }
44 
45     pub unsafe fn write_main_counter_value(&mut self, value: u64) {
46         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
47         volwrite!(p, main_counter_value, value);
48     }
49 
50     #[allow(dead_code)]
51     pub fn general_config(&self) -> u64 {
52         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
53         unsafe { volread!(p, general_config) }
54     }
55 
56     pub unsafe fn write_general_config(&mut self, value: u64) {
57         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
58         volwrite!(p, general_config, value);
59     }
60 
61     #[allow(dead_code)]
62     pub fn general_intr_status(&self) -> u64 {
63         let p = NonNull::new(self as *const HpetRegisters as *mut HpetRegisters).unwrap();
64         unsafe { volread!(p, general_intr_status) }
65     }
66 }
67 
68 #[repr(C, packed)]
69 pub struct HpetTimerRegisters {
70     pub config: Volatile<u64>,
71     pub comparator_value: Volatile<u64>,
72     pub fsb_interrupt_route: [Volatile<u64>; 2],
73 }
74