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