xref: /DragonOS/kernel/src/arch/riscv64/time.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
1*2eab6dd7S曾俊 use log::{debug, info};
2*2eab6dd7S曾俊 
323ef2b33SLoGin use crate::{
423ef2b33SLoGin     driver::open_firmware::fdt::open_firmware_fdt_driver,
523ef2b33SLoGin     time::{clocksource::HZ, TimeArch},
623ef2b33SLoGin };
74fda81ceSLoGin pub struct RiscV64TimeArch;
84fda81ceSLoGin 
9b8ed3825SDonkey Kane /// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
10b8ed3825SDonkey Kane pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
11b8ed3825SDonkey Kane 
1223ef2b33SLoGin static mut TIME_FREQ: usize = 0;
1323ef2b33SLoGin 
1423ef2b33SLoGin /// 获取CPU的time寄存器频率
1523ef2b33SLoGin ///
1623ef2b33SLoGin /// todo: 支持从acpi中获取
init_time_freq()1723ef2b33SLoGin fn init_time_freq() {
18*2eab6dd7S曾俊     debug!("init_time_freq: init");
1923ef2b33SLoGin     let fdt = open_firmware_fdt_driver().fdt_ref();
2023ef2b33SLoGin     if fdt.is_err() {
2123ef2b33SLoGin         panic!("init_time_freq: failed to get fdt");
2223ef2b33SLoGin     }
23*2eab6dd7S曾俊     debug!("init_time_freq: get fdt");
2423ef2b33SLoGin     let fdt = fdt.unwrap();
2523ef2b33SLoGin     let cpu_node = fdt.find_node("/cpus");
2623ef2b33SLoGin     if cpu_node.is_none() {
2723ef2b33SLoGin         panic!("init_time_freq: failed to find /cpus node");
2823ef2b33SLoGin     }
2923ef2b33SLoGin 
3023ef2b33SLoGin     let cpu_node = cpu_node.unwrap();
3123ef2b33SLoGin     let time_freq = cpu_node
3223ef2b33SLoGin         .property("timebase-frequency")
3323ef2b33SLoGin         .map(|prop| prop.as_usize())
3423ef2b33SLoGin         .flatten();
3523ef2b33SLoGin     if time_freq.is_none() {
3623ef2b33SLoGin         panic!("init_time_freq: failed to get timebase-frequency");
3723ef2b33SLoGin     }
3823ef2b33SLoGin 
3923ef2b33SLoGin     let time_freq: usize = time_freq.unwrap();
40*2eab6dd7S曾俊     info!("init_time_freq: timebase-frequency: {}", time_freq);
4123ef2b33SLoGin     unsafe {
4223ef2b33SLoGin         TIME_FREQ = time_freq;
4323ef2b33SLoGin     }
4423ef2b33SLoGin }
4523ef2b33SLoGin 
time_init()4623ef2b33SLoGin pub fn time_init() {
4723ef2b33SLoGin     // 初始化cpu time register频率
4823ef2b33SLoGin     init_time_freq();
4923ef2b33SLoGin }
5023ef2b33SLoGin 
514fda81ceSLoGin impl TimeArch for RiscV64TimeArch {
get_cycles() -> usize524fda81ceSLoGin     fn get_cycles() -> usize {
5323ef2b33SLoGin         riscv::register::time::read()
544fda81ceSLoGin     }
558cb2e9b3SLoGin 
cal_expire_cycles(ns: usize) -> usize568cb2e9b3SLoGin     fn cal_expire_cycles(ns: usize) -> usize {
5723ef2b33SLoGin         Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000
588cb2e9b3SLoGin     }
5923ef2b33SLoGin 
60b8ed3825SDonkey Kane     /// 将CPU的时钟周期数转换为纳秒
61b8ed3825SDonkey Kane     #[inline(always)]
cycles2ns(cycles: usize) -> usize62b8ed3825SDonkey Kane     fn cycles2ns(cycles: usize) -> usize {
6323ef2b33SLoGin         if unsafe { TIME_FREQ == 0 } {
6423ef2b33SLoGin             return 0;
6523ef2b33SLoGin         }
6623ef2b33SLoGin 
6723ef2b33SLoGin         cycles * 1000000000 / unsafe { TIME_FREQ }
68b8ed3825SDonkey Kane     }
694fda81ceSLoGin }
70f049d1afSLoGin 
riscv_time_base_freq() -> usize71f049d1afSLoGin pub fn riscv_time_base_freq() -> usize {
72f049d1afSLoGin     unsafe { TIME_FREQ }
73f049d1afSLoGin }
74