xref: /DragonOS/kernel/src/arch/x86_64/driver/hpet.rs (revision fbe6becd6dd3cd72643707e0088f20364ac1b166)
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