blob: f96026d099a326c5defdc047482d2b9659c61380 [file]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
#![no_main]
#![no_std]
use kernel_config::{KernelConfig, KernelConfigInterface};
use pw_status::Result;
use registers::rv_timer::RvTimer;
use userspace::{entry, syscall};
#[cfg(feature = "silicon")]
const IO_CLOCK_HZ: u64 = 24_000_000;
#[cfg(feature = "fpga")]
const IO_CLOCK_HZ: u64 = 6_000_000;
#[cfg(feature = "verilator")]
const IO_CLOCK_HZ: u64 = 125_000;
#[cfg(feature = "qemu")]
const IO_CLOCK_HZ: u64 = 24_000_000;
#[inline(always)]
fn rv_timer_value(rv_timer: &RvTimer) -> u64 {
let regs = rv_timer.regs();
loop {
let hi1 = regs.timer_v_upper0().read();
let low = regs.timer_v_lower0().read();
let hi2 = regs.timer_v_upper0().read();
if hi1 == hi2 {
return ((hi1 as u64) << 32) | (low as u64);
}
}
}
fn measure_nop_syscall(rv_timer: &RvTimer, n: usize) -> Result<()> {
let mut total = 0u64;
for _ in 0..n {
let t0 = rv_timer_value(&rv_timer);
syscall::debug_nop()?;
let t1 = rv_timer_value(&rv_timer);
total += t1 - t0;
}
pw_log::info!(
"Performed {} syscalls in {} rv_timer ticks.",
n as usize,
total as u64,
);
let average = total / (n as u64);
pw_log::info!("Average latency: {} rv_timer ticks", average as u64);
let cpu_clocks = average * KernelConfig::SYSTEM_CLOCK_HZ / IO_CLOCK_HZ;
pw_log::info!("Average latency: {} cpu clocks", cpu_clocks as u64);
Ok(())
}
#[entry]
fn entry() -> Result<()> {
let rv_timer = unsafe { RvTimer::new() };
measure_nop_syscall(&rv_timer, 100)
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
pw_log::error!("PANIC: syscall latency");
loop {}
}