diff --git a/src/driver/acpi/hpet.rs b/src/driver/acpi/hpet.rs index cffca1975d2763ff97f712360c6d9375f55ad939..4c024d128481b51be5f9b0cc51943b1500e6f561 100644 --- a/src/driver/acpi/hpet.rs +++ b/src/driver/acpi/hpet.rs @@ -20,7 +20,14 @@ pub static HPET: Lazy<Hpet> = Lazy::new(Hpet::init); #[derive(Debug)] pub struct Hpet { addr: u64, - // regs: Mutex<&'static mut HpetRegs>, + + /// HPET period in femtoseconds + period: u32, + // vendor_id: u16, + // leg_rt_cap: bool, + // count_size_cap: bool, + timers: u8, + // rev_id: u8, } #[derive(Debug)] @@ -31,6 +38,12 @@ pub struct HpetRegs { // main_counter_value: Reg<1, ReadWrite, MainCounterValue>, } +#[derive(Debug)] +pub struct TimerN<'a> { + hpet: &'a mut Hpet, + offs: u64, +} + #[derive(Debug, Clone, Copy)] pub enum HpetError { Sdt(SdtError), @@ -65,44 +78,60 @@ impl Hpet { regs.get_mut().general_config.read(); */ - Ok(Self { addr }) + let mut res = Self { + addr, + period: 0, + timers: 0, + }; + + let caps = res.caps(); + res.period = caps.period() as u32; + res.timers = caps.num_tim_cap() as u8; + + Ok(res) } - pub fn general_caps(&mut self) -> GeneralCaps { + // + + pub fn timer(&mut self, n: u8) -> TimerN { + assert!(n <= self.timers); + TimerN { + hpet: self, + offs: 0x100 + 0x20 * n as u64, + } + } + + // + + pub fn caps(&mut self) -> GeneralCaps { GeneralCaps(self.read_reg(0x000)) } - pub fn general_config(&mut self) -> GeneralConfig { + pub fn config(&mut self) -> GeneralConfig { GeneralConfig(self.read_reg(0x010)) } - pub fn set_general_config(&mut self, config: GeneralConfig) { + pub fn set_config(&mut self, config: GeneralConfig) { self.write_reg(0x010, config.0) } - pub fn general_interrupt_status(&mut self) -> GeneralInterruptStatus { + pub fn interrupt_status(&mut self) -> GeneralInterruptStatus { GeneralInterruptStatus(self.read_reg(0x020)) } - pub fn set_general_interrupt_status(&mut self, status: GeneralInterruptStatus) { + pub fn set_interrupt_status(&mut self, status: GeneralInterruptStatus) { self.write_reg(0x020, status.0) } - pub fn main_counter_value(&mut self) -> MainCounterValue { + pub fn main_counter_value(&mut self) -> CounterValue { self.read_reg(0x030) } - pub fn set_main_counter_value(&mut self, val: MainCounterValue) { + pub fn set_main_counter_value(&mut self, val: CounterValue) { self.write_reg(0x0F0, val) } - /* pub fn timer_n_config_and_caps(&mut self) -> TimerNConfigAndCaps { - self.read_reg(0x030) - } - - pub fn set_timer_n_config_and_caps(&mut self, val: MainCounterValue) { - self.write_reg(0x0F0, val) - } */ + // fn read_reg(&mut self, reg: u64) -> u64 { unsafe { read_volatile((self.addr + reg) as *const u64) } @@ -120,6 +149,24 @@ impl Hpet { } } +impl TimerN<'_> { + pub fn config_and_caps(&mut self) -> TimerNConfigAndCaps { + TimerNConfigAndCaps(self.hpet.read_reg(self.offs)) + } + + pub fn set_config_and_caps(&mut self, val: TimerNConfigAndCaps) { + self.hpet.write_reg(self.offs, val.0) + } + + pub fn counter_value(&mut self) -> CounterValue { + self.hpet.read_reg(self.offs + 0x8) + } + + pub fn set_counter_value(&mut self, val: CounterValue) { + self.hpet.write_reg(self.offs + 0x8, val) + } +} + impl From<SdtError> for HpetError { fn from(value: SdtError) -> Self { Self::Sdt(value) @@ -196,7 +243,7 @@ impl GeneralInterruptStatus { } } -pub type MainCounterValue = u64; +pub type CounterValue = u64; #[derive(Debug, Clone, Copy)] #[repr(packed, C)]