1fbe6becdSLoGin use core::{ 2fbe6becdSLoGin intrinsics::unlikely, 3fbe6becdSLoGin mem::size_of, 4fbe6becdSLoGin ptr::NonNull, 5fbe6becdSLoGin sync::atomic::{AtomicBool, Ordering}, 6fbe6becdSLoGin }; 7fbe6becdSLoGin 8fbe6becdSLoGin use acpi::HpetInfo; 9e2841179SLoGin use alloc::{string::ToString, sync::Arc}; 1091e9d4abSLoGin use system_error::SystemError; 11fbe6becdSLoGin 12fbe6becdSLoGin use crate::{ 130d6cf65aSLoGin arch::CurrentIrqArch, 14fbe6becdSLoGin driver::{ 15fbe6becdSLoGin acpi::acpi_manager, 16fbe6becdSLoGin timers::hpet::{HpetRegisters, HpetTimerRegisters}, 17fbe6becdSLoGin }, 180d6cf65aSLoGin exception::{ 19e2841179SLoGin irqdata::IrqHandlerData, 20e2841179SLoGin irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn}, 21e2841179SLoGin manage::irq_manager, 220d6cf65aSLoGin softirq::{softirq_vectors, SoftirqNumber}, 23e2841179SLoGin InterruptArch, IrqNumber, 240d6cf65aSLoGin }, 25fbe6becdSLoGin kdebug, kerror, kinfo, 26fbe6becdSLoGin libs::{ 27fbe6becdSLoGin rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, 28fbe6becdSLoGin volatile::volwrite, 29fbe6becdSLoGin }, 30fbe6becdSLoGin mm::{ 31fbe6becdSLoGin mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 32fbe6becdSLoGin PhysAddr, 33fbe6becdSLoGin }, 34b8ed3825SDonkey Kane time::{ 35b8ed3825SDonkey Kane jiffies::NSEC_PER_JIFFY, 36b8ed3825SDonkey Kane timer::{clock, timer_get_first_expire, update_timer_jiffies}, 37b8ed3825SDonkey Kane }, 38fbe6becdSLoGin }; 39fbe6becdSLoGin 40fbe6becdSLoGin static mut HPET_INSTANCE: Option<Hpet> = None; 41fbe6becdSLoGin 42fbe6becdSLoGin #[inline(always)] 43fbe6becdSLoGin pub fn hpet_instance() -> &'static Hpet { 44fbe6becdSLoGin unsafe { HPET_INSTANCE.as_ref().unwrap() } 45fbe6becdSLoGin } 46fbe6becdSLoGin 47*dd8e74efSMingtao Huang #[inline(always)] 48*dd8e74efSMingtao Huang pub fn is_hpet_enabled() -> bool { 49*dd8e74efSMingtao Huang if unsafe { HPET_INSTANCE.as_ref().is_some() } { 50*dd8e74efSMingtao Huang return unsafe { HPET_INSTANCE.as_ref().unwrap().enabled() }; 51*dd8e74efSMingtao Huang } 52*dd8e74efSMingtao Huang return false; 53*dd8e74efSMingtao Huang } 54*dd8e74efSMingtao Huang 55fbe6becdSLoGin pub struct Hpet { 56fbe6becdSLoGin info: HpetInfo, 57fbe6becdSLoGin _mmio_guard: MMIOSpaceGuard, 58fbe6becdSLoGin inner: RwLock<InnerHpet>, 59fbe6becdSLoGin enabled: AtomicBool, 60fbe6becdSLoGin } 61fbe6becdSLoGin 62fbe6becdSLoGin struct InnerHpet { 63fbe6becdSLoGin registers_ptr: NonNull<HpetRegisters>, 64fbe6becdSLoGin timer_registers_ptr: NonNull<HpetTimerRegisters>, 65fbe6becdSLoGin } 66fbe6becdSLoGin 67fbe6becdSLoGin impl Hpet { 68b8ed3825SDonkey Kane /// HPET0 中断间隔 69b8ed3825SDonkey Kane pub const HPET0_INTERVAL_USEC: u64 = NSEC_PER_JIFFY as u64 / 1000; 70fbe6becdSLoGin 71e2841179SLoGin const HPET0_IRQ: IrqNumber = IrqNumber::new(34); 72e2841179SLoGin 73fbe6becdSLoGin fn new(mut hpet_info: HpetInfo) -> Result<Self, SystemError> { 74fbe6becdSLoGin let paddr = PhysAddr::new(hpet_info.base_address); 75fbe6becdSLoGin let map_size = size_of::<HpetRegisters>(); 76fbe6becdSLoGin let mmio = mmio_pool().create_mmio(map_size)?; 77fbe6becdSLoGin unsafe { mmio.map_phys(paddr, map_size)? }; 78fbe6becdSLoGin let hpet = unsafe { 79fbe6becdSLoGin (mmio.vaddr().data() as *const HpetRegisters) 80fbe6becdSLoGin .as_ref() 81fbe6becdSLoGin .unwrap() 82fbe6becdSLoGin }; 83fbe6becdSLoGin let tm_num = hpet.timers_num(); 84b8ed3825SDonkey Kane kdebug!("HPET0_INTERVAL_USEC: {}", Self::HPET0_INTERVAL_USEC); 85fbe6becdSLoGin kinfo!("HPET has {} timers", tm_num); 86fbe6becdSLoGin hpet_info.hpet_number = tm_num as u8; 871a72a751SLoGin 88fbe6becdSLoGin drop(mmio); 89fbe6becdSLoGin if tm_num == 0 { 90fbe6becdSLoGin return Err(SystemError::ENODEV); 91fbe6becdSLoGin } 92fbe6becdSLoGin 93fbe6becdSLoGin let bytes_to_map = size_of::<HpetRegisters>() 94fbe6becdSLoGin + hpet_info.hpet_number as usize * size_of::<HpetTimerRegisters>(); 95fbe6becdSLoGin let mmio = mmio_pool().create_mmio(bytes_to_map)?; 96fbe6becdSLoGin 97fbe6becdSLoGin unsafe { mmio.map_phys(paddr, bytes_to_map)? }; 98fbe6becdSLoGin let ptr = NonNull::new(mmio.vaddr().data() as *mut HpetRegisters).unwrap(); 99fbe6becdSLoGin let timer_ptr = NonNull::new( 100fbe6becdSLoGin (mmio.vaddr().data() + size_of::<HpetRegisters>()) as *mut HpetTimerRegisters, 101fbe6becdSLoGin ) 102fbe6becdSLoGin .unwrap(); 103fbe6becdSLoGin 104fbe6becdSLoGin let hpet = Hpet { 105fbe6becdSLoGin info: hpet_info, 106fbe6becdSLoGin _mmio_guard: mmio, 107fbe6becdSLoGin inner: RwLock::new(InnerHpet { 108fbe6becdSLoGin registers_ptr: ptr, 109fbe6becdSLoGin timer_registers_ptr: timer_ptr, 110fbe6becdSLoGin }), 111fbe6becdSLoGin enabled: AtomicBool::new(false), 112fbe6becdSLoGin }; 113fbe6becdSLoGin 114fbe6becdSLoGin return Ok(hpet); 115fbe6becdSLoGin } 116fbe6becdSLoGin 117fbe6becdSLoGin pub fn enabled(&self) -> bool { 118fbe6becdSLoGin self.enabled.load(Ordering::SeqCst) 119fbe6becdSLoGin } 120fbe6becdSLoGin 121fbe6becdSLoGin /// 使能HPET 1225b59005fSLoGin pub fn hpet_enable(&self) -> Result<(), SystemError> { 123e2841179SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 124e2841179SLoGin 125fbe6becdSLoGin // !!!这里是临时糊代码的,需要在apic重构的时候修改!!! 126fbe6becdSLoGin let (inner_guard, regs) = unsafe { self.hpet_regs_mut() }; 127fbe6becdSLoGin let freq = regs.frequency(); 128fbe6becdSLoGin kdebug!("HPET frequency: {} Hz", freq); 129fbe6becdSLoGin let ticks = Self::HPET0_INTERVAL_USEC * freq / 1000000; 130b5b571e0SLoGin if ticks == 0 || ticks > freq * 8 { 131fbe6becdSLoGin kerror!("HPET enable: ticks '{ticks}' is invalid"); 132fbe6becdSLoGin return Err(SystemError::EINVAL); 133fbe6becdSLoGin } 134fbe6becdSLoGin if unlikely(regs.timers_num() == 0) { 135fbe6becdSLoGin return Err(SystemError::ENODEV); 136fbe6becdSLoGin } 137fbe6becdSLoGin 138fbe6becdSLoGin unsafe { regs.write_main_counter_value(0) }; 139fbe6becdSLoGin 140fbe6becdSLoGin drop(inner_guard); 141fbe6becdSLoGin 142fbe6becdSLoGin let (inner_guard, timer_reg) = unsafe { self.timer_mut(0).ok_or(SystemError::ENODEV) }?; 143fbe6becdSLoGin 144fbe6becdSLoGin let timer_reg = NonNull::new(timer_reg as *mut HpetTimerRegisters).unwrap(); 145fbe6becdSLoGin 146fbe6becdSLoGin unsafe { 147fbe6becdSLoGin // 设置定时器0为周期定时,边沿触发,默认投递到IO APIC的2号引脚(看conf寄存器的高32bit,哪一位被置1,则可以投递到哪一个I/O apic引脚) 148fbe6becdSLoGin volwrite!(timer_reg, config, 0x004c); 149fbe6becdSLoGin volwrite!(timer_reg, comparator_value, ticks); 150fbe6becdSLoGin } 151fbe6becdSLoGin drop(inner_guard); 152fbe6becdSLoGin 153e2841179SLoGin irq_manager().request_irq( 154e2841179SLoGin Self::HPET0_IRQ, 155e2841179SLoGin "HPET0".to_string(), 156e2841179SLoGin &HpetIrqHandler, 157e2841179SLoGin IrqHandleFlags::IRQF_TRIGGER_RISING, 158e2841179SLoGin None, 159e2841179SLoGin )?; 160e2841179SLoGin 161fbe6becdSLoGin self.enabled.store(true, Ordering::SeqCst); 162fbe6becdSLoGin 163fbe6becdSLoGin let (inner_guard, regs) = unsafe { self.hpet_regs_mut() }; 164fbe6becdSLoGin 165fbe6becdSLoGin // 置位旧设备中断路由兼容标志位、定时器组使能标志位 166fbe6becdSLoGin unsafe { regs.write_general_config(3) }; 167fbe6becdSLoGin 168fbe6becdSLoGin drop(inner_guard); 169fbe6becdSLoGin 170fbe6becdSLoGin kinfo!("HPET enabled"); 171e2841179SLoGin 172e2841179SLoGin drop(irq_guard); 173fbe6becdSLoGin return Ok(()); 174fbe6becdSLoGin } 175fbe6becdSLoGin 176fbe6becdSLoGin fn inner(&self) -> RwLockReadGuard<InnerHpet> { 177fbe6becdSLoGin self.inner.read() 178fbe6becdSLoGin } 179fbe6becdSLoGin 180fbe6becdSLoGin fn inner_mut(&self) -> RwLockWriteGuard<InnerHpet> { 181fbe6becdSLoGin self.inner.write() 182fbe6becdSLoGin } 183fbe6becdSLoGin 184fbe6becdSLoGin #[allow(dead_code)] 185fbe6becdSLoGin fn timer(&self, index: u8) -> Option<(RwLockReadGuard<InnerHpet>, &HpetTimerRegisters)> { 186fbe6becdSLoGin let inner = self.inner(); 187fbe6becdSLoGin if index >= self.info.hpet_number { 188fbe6becdSLoGin return None; 189fbe6becdSLoGin } 190fbe6becdSLoGin let timer_regs = unsafe { 191fbe6becdSLoGin inner 192fbe6becdSLoGin .timer_registers_ptr 193fbe6becdSLoGin .as_ptr() 194fbe6becdSLoGin .add(index as usize) 195fbe6becdSLoGin .as_ref() 196fbe6becdSLoGin .unwrap() 197fbe6becdSLoGin }; 198fbe6becdSLoGin return Some((inner, timer_regs)); 199fbe6becdSLoGin } 200fbe6becdSLoGin 201fbe6becdSLoGin unsafe fn timer_mut( 202fbe6becdSLoGin &self, 203fbe6becdSLoGin index: u8, 204fbe6becdSLoGin ) -> Option<(RwLockWriteGuard<InnerHpet>, &mut HpetTimerRegisters)> { 205fbe6becdSLoGin let inner = self.inner_mut(); 206fbe6becdSLoGin if index >= self.info.hpet_number { 207fbe6becdSLoGin return None; 208fbe6becdSLoGin } 209fbe6becdSLoGin let timer_regs = unsafe { 210fbe6becdSLoGin inner 211fbe6becdSLoGin .timer_registers_ptr 212fbe6becdSLoGin .as_ptr() 213fbe6becdSLoGin .add(index as usize) 214fbe6becdSLoGin .as_mut() 215fbe6becdSLoGin .unwrap() 216fbe6becdSLoGin }; 217fbe6becdSLoGin return Some((inner, timer_regs)); 218fbe6becdSLoGin } 219fbe6becdSLoGin 220fbe6becdSLoGin unsafe fn hpet_regs(&self) -> (RwLockReadGuard<InnerHpet>, &HpetRegisters) { 221fbe6becdSLoGin let inner = self.inner(); 222fbe6becdSLoGin let regs = unsafe { inner.registers_ptr.as_ref() }; 223fbe6becdSLoGin return (inner, regs); 224fbe6becdSLoGin } 225fbe6becdSLoGin 226fbe6becdSLoGin unsafe fn hpet_regs_mut(&self) -> (RwLockWriteGuard<InnerHpet>, &mut HpetRegisters) { 227fbe6becdSLoGin let mut inner = self.inner_mut(); 228fbe6becdSLoGin let regs = unsafe { inner.registers_ptr.as_mut() }; 229fbe6becdSLoGin return (inner, regs); 230fbe6becdSLoGin } 231fbe6becdSLoGin 232fbe6becdSLoGin pub fn main_counter_value(&self) -> u64 { 233fbe6becdSLoGin let (inner_guard, regs) = unsafe { self.hpet_regs() }; 234fbe6becdSLoGin let value = regs.main_counter_value(); 2351a72a751SLoGin 236fbe6becdSLoGin drop(inner_guard); 237fbe6becdSLoGin return value; 238fbe6becdSLoGin } 239fbe6becdSLoGin 240fbe6becdSLoGin pub fn period(&self) -> u64 { 241fbe6becdSLoGin let (inner_guard, regs) = unsafe { self.hpet_regs() }; 242fbe6becdSLoGin let period = regs.counter_clock_period(); 243fbe6becdSLoGin kdebug!("HPET period: {}", period); 2441a72a751SLoGin 245fbe6becdSLoGin drop(inner_guard); 246fbe6becdSLoGin return period; 247fbe6becdSLoGin } 248fbe6becdSLoGin 249fbe6becdSLoGin /// 处理HPET的中断 250fbe6becdSLoGin pub(super) fn handle_irq(&self, timer_num: u32) { 251fbe6becdSLoGin if timer_num == 0 { 252b5b571e0SLoGin assert!(!CurrentIrqArch::is_irq_enabled()); 253b8ed3825SDonkey Kane update_timer_jiffies(1, Self::HPET0_INTERVAL_USEC as i64); 254fbe6becdSLoGin 255fbe6becdSLoGin if let Ok(first_expire) = timer_get_first_expire() { 256fbe6becdSLoGin if first_expire <= clock() { 257fbe6becdSLoGin softirq_vectors().raise_softirq(SoftirqNumber::TIMER); 258fbe6becdSLoGin } 259fbe6becdSLoGin } 260fbe6becdSLoGin } 261fbe6becdSLoGin } 262fbe6becdSLoGin } 263fbe6becdSLoGin 264fbe6becdSLoGin pub fn hpet_init() -> Result<(), SystemError> { 265*dd8e74efSMingtao Huang let hpet_info = 266*dd8e74efSMingtao Huang HpetInfo::new(acpi_manager().tables().unwrap()).map_err(|_| SystemError::ENODEV)?; 267fbe6becdSLoGin 268fbe6becdSLoGin let hpet_instance = Hpet::new(hpet_info)?; 269fbe6becdSLoGin unsafe { 270fbe6becdSLoGin HPET_INSTANCE = Some(hpet_instance); 271fbe6becdSLoGin } 272fbe6becdSLoGin 273fbe6becdSLoGin return Ok(()); 274fbe6becdSLoGin } 275e2841179SLoGin 276e2841179SLoGin #[derive(Debug)] 277e2841179SLoGin struct HpetIrqHandler; 278e2841179SLoGin 279e2841179SLoGin impl IrqHandler for HpetIrqHandler { 280e2841179SLoGin fn handle( 281e2841179SLoGin &self, 282e2841179SLoGin _irq: IrqNumber, 283e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>, 284e2841179SLoGin _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 285e2841179SLoGin ) -> Result<IrqReturn, SystemError> { 286e2841179SLoGin hpet_instance().handle_irq(0); 287e2841179SLoGin return Ok(IrqReturn::Handled); 288e2841179SLoGin } 289e2841179SLoGin } 290