use core::cell::LazyCell;
static TIMER_FREQ: TimerFreq = TimerFreq {
timer_freq: LazyCell::new(timer_freq),
};
struct TimerFreq {
timer_freq: LazyCell<u64>,
}
unsafe impl Sync for TimerFreq {}
#[must_use = "Has no effect if the result is unused"]
fn timer_tick() -> u64 {
#[cfg(target_arch = "x86")]
unsafe {
core::arch::x86::_rdtsc()
}
#[cfg(target_arch = "x86_64")]
unsafe {
core::arch::x86_64::_rdtsc()
}
#[cfg(target_arch = "aarch64")]
unsafe {
let mut ticks: u64;
core::arch::asm!("mrs {}, cntvct_el0", out(reg) ticks);
ticks
}
}
#[must_use = "Has no effect if the result is unused"]
fn timer_freq() -> u64 {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
let start = timer_tick();
uefi::boot::stall(1000);
let end = timer_tick();
(end - start) * 1000
}
#[cfg(target_arch = "aarch64")]
unsafe {
let mut freq: u64;
core::arch::asm!("mrs {}, cntfrq_el0", out(reg) freq);
freq
}
}
#[must_use = "Has no effect if the result is unused"]
pub fn timer_usec() -> u64 {
1000 * 1000 * timer_tick() / *TIMER_FREQ.timer_freq
}