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