Skip to content

Commit

Permalink
riscv: fix the timer and cpu frequency are not related
Browse files Browse the repository at this point in the history
Signed-off-by: rayylee <[email protected]>
  • Loading branch information
hbuxiaofei committed Apr 30, 2024
1 parent ff27196 commit 4317548
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
1 change: 1 addition & 0 deletions modules/axhal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ raw-cpuid = "11.0"
[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies]
riscv = "0.10"
sbi-rt = { version = "0.0.2", features = ["legacy"] }
of = { path = "../../crates/of"}

[target.'cfg(target_arch = "aarch64")'.dependencies]
aarch64-cpu = "9.3"
Expand Down
18 changes: 18 additions & 0 deletions modules/axhal/src/platform/riscv64_qemu_virt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,35 @@ pub mod irq;
#[cfg(feature = "smp")]
pub mod mp;

use of;

extern "C" {
fn trap_vector_base();
fn rust_main(cpu_id: usize, dtb: usize);
#[cfg(feature = "smp")]
fn rust_main_secondary(cpu_id: usize);
}

fn init_board_info(dtb: usize) {
unsafe {
of::init_fdt_ptr(dtb as *const u8);
}
let mut of_cpus = of::cpus();
let freq = {
if let Some(cpu) = of_cpus.nth(0) {
cpu.timebase_frequency()
} else {
axconfig::TIMER_FREQUENCY
}
};
self::time::init_cpu_freq(freq as u64);
}

unsafe extern "C" fn rust_entry(cpu_id: usize, dtb: usize) {
crate::mem::clear_bss();
crate::cpu::init_primary(cpu_id);
crate::arch::set_trap_vector_base(trap_vector_base as usize);
init_board_info(dtb);
rust_main(cpu_id, dtb);
}

Expand Down
32 changes: 30 additions & 2 deletions modules/axhal/src/platform/riscv64_qemu_virt/time.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
use lazy_init::LazyInit;
use riscv::register::time;

static CPU_FREQ: LazyInit<u64> = LazyInit::new();
static LOOPS_PRE_TICK: LazyInit<u64> = LazyInit::new();
const NANOS_PER_TICK: u64 = crate::time::NANOS_PER_SEC / axconfig::TIMER_FREQUENCY as u64;

// Initializes the frequency of cpu.
#[inline]
pub fn init_cpu_freq(freq: u64) {
if !CPU_FREQ.is_init() {
CPU_FREQ.init_by(freq);
}

if !LOOPS_PRE_TICK.is_init() {
LOOPS_PRE_TICK.init_by(freq / axconfig::TIMER_FREQUENCY as u64);
}
}

/// Returns the frequency of cpu.
#[inline]
#[allow(unused)]
pub fn cpu_freq() -> u64 {
*CPU_FREQ
}

/// Returns loops per tick.
#[inline]
pub fn loops_pre_tick() -> u64 {
*LOOPS_PRE_TICK
}

/// Returns the current clock time in hardware ticks.
#[inline]
pub fn current_ticks() -> u64 {
time::read() as u64
time::read() as u64 / loops_pre_tick()
}

/// Converts hardware ticks to nanoseconds.
Expand All @@ -25,7 +53,7 @@ pub const fn nanos_to_ticks(nanos: u64) -> u64 {
/// A timer interrupt will be triggered at the given deadline (in nanoseconds).
#[cfg(feature = "irq")]
pub fn set_oneshot_timer(deadline_ns: u64) {
sbi_rt::set_timer(nanos_to_ticks(deadline_ns));
sbi_rt::set_timer(nanos_to_ticks(deadline_ns) * loops_pre_tick());
}

pub(super) fn init_percpu() {
Expand Down

0 comments on commit 4317548

Please sign in to comment.