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