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