ostd/arch/x86/timer/mod.rs
1// SPDX-License-Identifier: MPL-2.0
2//! The timer support.
3use vstd::prelude::*;
4
5verus! {
6
7/*
8mod apic;
9mod hpet;
10pub(crate) mod pit;
11
12use core::sync::atomic::Ordering;
13
14use spin::Once;
15
16use super::trap::TrapFrame;
17use crate::{
18 arch::kernel,
19 cpu::{CpuId, PinCurrentCpu},
20 timer::INTERRUPT_CALLBACKS,
21 trap::{self, irq::IrqLine},
22};
23*/
24/// The timer frequency (Hz).
25///
26/// Here we choose 1000Hz since 1000Hz is easier for unit conversion and
27/// convenient for timer. What's more, the frequency cannot be set too high or
28/// too low, 1000Hz is a modest choice.
29///
30/// For system performance reasons, this rate cannot be set too high, otherwise
31/// most of the time is spent executing timer code.
32///
33/// Due to hardware limitations, this value cannot be set too low; for example,
34/// PIT cannot accept frequencies lower than 19Hz = 1193182 / 65536 (Timer rate
35/// / Divider)
36pub const TIMER_FREQ: u64 = 1000;
37
38/*
39static TIMER_IRQ: Once<IrqLine> = Once::new();
40
41/// Initializes the timer state and enable timer interrupts on BSP.
42pub(super) fn init_bsp() {
43 let mut timer_irq = if kernel::apic::exists() {
44 apic::init_bsp()
45 } else {
46 pit::init(pit::OperatingMode::SquareWaveGenerator);
47
48 /// In PIT mode, channel 0 is connected directly to IRQ0, which is
49 /// the `IrqLine` with the `irq_num` 32 (0-31 `IrqLine`s are reserved).
50 ///
51 /// Ref: https://wiki.osdev.org/Programmable_Interval_Timer#Outputs.
52 const PIT_MODE_TIMER_IRQ_NUM: u8 = 32;
53
54 IrqLine::alloc_specific(PIT_MODE_TIMER_IRQ_NUM).unwrap()
55 };
56
57 timer_irq.on_active(timer_callback);
58 TIMER_IRQ.call_once(|| timer_irq);
59}
60
61/// Enables timer interrupt on this AP.
62pub(super) fn init_ap() {
63 if kernel::apic::exists() {
64 apic::init_ap(TIMER_IRQ.get().unwrap());
65 }
66}
67
68fn timer_callback(_: &TrapFrame) {
69 let irq_guard = trap::irq::disable_local();
70 if irq_guard.current_cpu() == CpuId::bsp() {
71 crate::timer::jiffies::ELAPSED.fetch_add(1, Ordering::SeqCst);
72 }
73
74 let callbacks_guard = INTERRUPT_CALLBACKS.get_with(&irq_guard);
75 for callback in callbacks_guard.borrow().iter() {
76 (callback)();
77 }
78 drop(callbacks_guard);
79
80 apic::timer_callback();
81}
82*/
83} // verus!