mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
71 lines
1.7 KiB
Rust
71 lines
1.7 KiB
Rust
use crate::{
|
||
driver::open_firmware::fdt::open_firmware_fdt_driver,
|
||
kinfo,
|
||
time::{clocksource::HZ, TimeArch},
|
||
};
|
||
pub struct RiscV64TimeArch;
|
||
|
||
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
||
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
||
|
||
static mut TIME_FREQ: usize = 0;
|
||
|
||
/// 获取CPU的time寄存器频率
|
||
///
|
||
/// todo: 支持从acpi中获取
|
||
fn init_time_freq() {
|
||
let fdt = open_firmware_fdt_driver().fdt_ref();
|
||
if fdt.is_err() {
|
||
panic!("init_time_freq: failed to get fdt");
|
||
}
|
||
let fdt = fdt.unwrap();
|
||
let cpu_node = fdt.find_node("/cpus");
|
||
if cpu_node.is_none() {
|
||
panic!("init_time_freq: failed to find /cpus node");
|
||
}
|
||
|
||
let cpu_node = cpu_node.unwrap();
|
||
let time_freq = cpu_node
|
||
.property("timebase-frequency")
|
||
.map(|prop| prop.as_usize())
|
||
.flatten();
|
||
if time_freq.is_none() {
|
||
panic!("init_time_freq: failed to get timebase-frequency");
|
||
}
|
||
|
||
let time_freq: usize = time_freq.unwrap();
|
||
kinfo!("init_time_freq: timebase-frequency: {}", time_freq);
|
||
unsafe {
|
||
TIME_FREQ = time_freq;
|
||
}
|
||
}
|
||
|
||
pub fn time_init() {
|
||
// 初始化cpu time register频率
|
||
init_time_freq();
|
||
}
|
||
|
||
impl TimeArch for RiscV64TimeArch {
|
||
fn get_cycles() -> usize {
|
||
riscv::register::time::read()
|
||
}
|
||
|
||
fn cal_expire_cycles(ns: usize) -> usize {
|
||
Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000
|
||
}
|
||
|
||
/// 将CPU的时钟周期数转换为纳秒
|
||
#[inline(always)]
|
||
fn cycles2ns(cycles: usize) -> usize {
|
||
if unsafe { TIME_FREQ == 0 } {
|
||
return 0;
|
||
}
|
||
|
||
cycles * 1000000000 / unsafe { TIME_FREQ }
|
||
}
|
||
}
|
||
|
||
pub fn riscv_time_base_freq() -> usize {
|
||
unsafe { TIME_FREQ }
|
||
}
|