xref: /DragonOS/kernel/src/arch/riscv64/time.rs (revision 23ef2b33d1e3cfd2506eb7449a33df4ec42f11d3)
1*23ef2b33SLoGin use crate::{
2*23ef2b33SLoGin     driver::open_firmware::fdt::open_firmware_fdt_driver,
3*23ef2b33SLoGin     kinfo,
4*23ef2b33SLoGin     time::{clocksource::HZ, TimeArch},
5*23ef2b33SLoGin };
64fda81ceSLoGin pub struct RiscV64TimeArch;
74fda81ceSLoGin 
8b8ed3825SDonkey Kane /// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
9b8ed3825SDonkey Kane pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
10b8ed3825SDonkey Kane 
11*23ef2b33SLoGin static mut TIME_FREQ: usize = 0;
12*23ef2b33SLoGin 
13*23ef2b33SLoGin /// 获取CPU的time寄存器频率
14*23ef2b33SLoGin ///
15*23ef2b33SLoGin /// todo: 支持从acpi中获取
16*23ef2b33SLoGin fn init_time_freq() {
17*23ef2b33SLoGin     let fdt = open_firmware_fdt_driver().fdt_ref();
18*23ef2b33SLoGin     if fdt.is_err() {
19*23ef2b33SLoGin         panic!("init_time_freq: failed to get fdt");
20*23ef2b33SLoGin     }
21*23ef2b33SLoGin     let fdt = fdt.unwrap();
22*23ef2b33SLoGin     let cpu_node = fdt.find_node("/cpus");
23*23ef2b33SLoGin     if cpu_node.is_none() {
24*23ef2b33SLoGin         panic!("init_time_freq: failed to find /cpus node");
25*23ef2b33SLoGin     }
26*23ef2b33SLoGin 
27*23ef2b33SLoGin     let cpu_node = cpu_node.unwrap();
28*23ef2b33SLoGin     let time_freq = cpu_node
29*23ef2b33SLoGin         .property("timebase-frequency")
30*23ef2b33SLoGin         .map(|prop| prop.as_usize())
31*23ef2b33SLoGin         .flatten();
32*23ef2b33SLoGin     if time_freq.is_none() {
33*23ef2b33SLoGin         panic!("init_time_freq: failed to get timebase-frequency");
34*23ef2b33SLoGin     }
35*23ef2b33SLoGin 
36*23ef2b33SLoGin     let time_freq: usize = time_freq.unwrap();
37*23ef2b33SLoGin     kinfo!("init_time_freq: timebase-frequency: {}", time_freq);
38*23ef2b33SLoGin     unsafe {
39*23ef2b33SLoGin         TIME_FREQ = time_freq;
40*23ef2b33SLoGin     }
41*23ef2b33SLoGin }
42*23ef2b33SLoGin 
43*23ef2b33SLoGin pub fn time_init() {
44*23ef2b33SLoGin     // 初始化cpu time register频率
45*23ef2b33SLoGin     init_time_freq();
46*23ef2b33SLoGin }
47*23ef2b33SLoGin 
484fda81ceSLoGin impl TimeArch for RiscV64TimeArch {
494fda81ceSLoGin     fn get_cycles() -> usize {
50*23ef2b33SLoGin         riscv::register::time::read()
514fda81ceSLoGin     }
528cb2e9b3SLoGin 
538cb2e9b3SLoGin     fn cal_expire_cycles(ns: usize) -> usize {
54*23ef2b33SLoGin         Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000
558cb2e9b3SLoGin     }
56*23ef2b33SLoGin 
57b8ed3825SDonkey Kane     /// 将CPU的时钟周期数转换为纳秒
58b8ed3825SDonkey Kane     #[inline(always)]
59b8ed3825SDonkey Kane     fn cycles2ns(cycles: usize) -> usize {
60*23ef2b33SLoGin         if unsafe { TIME_FREQ == 0 } {
61*23ef2b33SLoGin             return 0;
62*23ef2b33SLoGin         }
63*23ef2b33SLoGin 
64*23ef2b33SLoGin         cycles * 1000000000 / unsafe { TIME_FREQ }
65b8ed3825SDonkey Kane     }
664fda81ceSLoGin }
67