xref: /DragonOS/kernel/src/arch/riscv64/time.rs (revision f049d1af01da7b92f312245ed411b22475b76065)
123ef2b33SLoGin use crate::{
223ef2b33SLoGin     driver::open_firmware::fdt::open_firmware_fdt_driver,
323ef2b33SLoGin     kinfo,
423ef2b33SLoGin     time::{clocksource::HZ, TimeArch},
523ef2b33SLoGin };
64fda81ceSLoGin pub struct RiscV64TimeArch;
74fda81ceSLoGin 
8b8ed3825SDonkey Kane /// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
9b8ed3825SDonkey Kane pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
10b8ed3825SDonkey Kane 
1123ef2b33SLoGin static mut TIME_FREQ: usize = 0;
1223ef2b33SLoGin 
1323ef2b33SLoGin /// 获取CPU的time寄存器频率
1423ef2b33SLoGin ///
1523ef2b33SLoGin /// todo: 支持从acpi中获取
1623ef2b33SLoGin fn init_time_freq() {
1723ef2b33SLoGin     let fdt = open_firmware_fdt_driver().fdt_ref();
1823ef2b33SLoGin     if fdt.is_err() {
1923ef2b33SLoGin         panic!("init_time_freq: failed to get fdt");
2023ef2b33SLoGin     }
2123ef2b33SLoGin     let fdt = fdt.unwrap();
2223ef2b33SLoGin     let cpu_node = fdt.find_node("/cpus");
2323ef2b33SLoGin     if cpu_node.is_none() {
2423ef2b33SLoGin         panic!("init_time_freq: failed to find /cpus node");
2523ef2b33SLoGin     }
2623ef2b33SLoGin 
2723ef2b33SLoGin     let cpu_node = cpu_node.unwrap();
2823ef2b33SLoGin     let time_freq = cpu_node
2923ef2b33SLoGin         .property("timebase-frequency")
3023ef2b33SLoGin         .map(|prop| prop.as_usize())
3123ef2b33SLoGin         .flatten();
3223ef2b33SLoGin     if time_freq.is_none() {
3323ef2b33SLoGin         panic!("init_time_freq: failed to get timebase-frequency");
3423ef2b33SLoGin     }
3523ef2b33SLoGin 
3623ef2b33SLoGin     let time_freq: usize = time_freq.unwrap();
3723ef2b33SLoGin     kinfo!("init_time_freq: timebase-frequency: {}", time_freq);
3823ef2b33SLoGin     unsafe {
3923ef2b33SLoGin         TIME_FREQ = time_freq;
4023ef2b33SLoGin     }
4123ef2b33SLoGin }
4223ef2b33SLoGin 
4323ef2b33SLoGin pub fn time_init() {
4423ef2b33SLoGin     // 初始化cpu time register频率
4523ef2b33SLoGin     init_time_freq();
4623ef2b33SLoGin }
4723ef2b33SLoGin 
484fda81ceSLoGin impl TimeArch for RiscV64TimeArch {
494fda81ceSLoGin     fn get_cycles() -> usize {
5023ef2b33SLoGin         riscv::register::time::read()
514fda81ceSLoGin     }
528cb2e9b3SLoGin 
538cb2e9b3SLoGin     fn cal_expire_cycles(ns: usize) -> usize {
5423ef2b33SLoGin         Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000
558cb2e9b3SLoGin     }
5623ef2b33SLoGin 
57b8ed3825SDonkey Kane     /// 将CPU的时钟周期数转换为纳秒
58b8ed3825SDonkey Kane     #[inline(always)]
59b8ed3825SDonkey Kane     fn cycles2ns(cycles: usize) -> usize {
6023ef2b33SLoGin         if unsafe { TIME_FREQ == 0 } {
6123ef2b33SLoGin             return 0;
6223ef2b33SLoGin         }
6323ef2b33SLoGin 
6423ef2b33SLoGin         cycles * 1000000000 / unsafe { TIME_FREQ }
65b8ed3825SDonkey Kane     }
664fda81ceSLoGin }
67*f049d1afSLoGin 
68*f049d1afSLoGin pub fn riscv_time_base_freq() -> usize {
69*f049d1afSLoGin     unsafe { TIME_FREQ }
70*f049d1afSLoGin }
71