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