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