use core::arch::asm;
pub struct CycleCounter(());
impl CycleCounter {
#[cfg(target_arch = "aarch64")]
pub fn enable() -> Self {
unsafe {
let mut pmcr: u64;
asm!("mrs {}, pmcr_el0", out(reg) pmcr);
pmcr = (pmcr & !(1 << 3)) | (1 << 0) | (1 << 2);
asm!("msr pmcr_el0, {}", in(reg) pmcr);
asm!("msr pmcntenset_el0, {}", in(reg) 1u64 << 31);
}
Self(())
}
#[cfg(target_arch = "arm")]
pub fn enable() -> Self {
unsafe {
let mut pmcr: u32;
asm!("mrc p15, 0, {}, c9, c12, 0", out(reg) pmcr);
pmcr = (pmcr & !(1 << 3)) | (1 << 0) | (1 << 2);
asm!("mcr p15, 0, {}, c9, c12, 0", in(reg) pmcr);
asm!("mcr p15, 0, {}, c9, c12, 1", in(reg) 1u32 << 31);
}
Self(())
}
pub fn read(&self) -> u64 {
#[cfg(target_arch = "aarch64")]
{
let cycles: u64;
unsafe { asm!("mrs {}, pmccntr_el0", out(reg) cycles, options(nomem, nostack)) };
cycles
}
#[cfg(target_arch = "arm")]
{
let cycles: u32;
unsafe { asm!("mrc p15, 0, {}, c9, c13, 0", out(reg) cycles, options(nomem, nostack)) };
cycles as u64
}
}
}