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 10000_0000_0000_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