Skip to main content

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!