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 68 pub fn riscv_time_base_freq() -> usize { 69 unsafe { TIME_FREQ } 70 } 71