1 use crate::{ 2 driver::open_firmware::fdt::open_firmware_fdt_driver, 3 kdebug, 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 kdebug!("init_time_freq: init"); 18 let fdt = open_firmware_fdt_driver().fdt_ref(); 19 if fdt.is_err() { 20 panic!("init_time_freq: failed to get fdt"); 21 } 22 kdebug!("init_time_freq: get fdt"); 23 let fdt = fdt.unwrap(); 24 let cpu_node = fdt.find_node("/cpus"); 25 if cpu_node.is_none() { 26 panic!("init_time_freq: failed to find /cpus node"); 27 } 28 29 let cpu_node = cpu_node.unwrap(); 30 let time_freq = cpu_node 31 .property("timebase-frequency") 32 .map(|prop| prop.as_usize()) 33 .flatten(); 34 if time_freq.is_none() { 35 panic!("init_time_freq: failed to get timebase-frequency"); 36 } 37 38 let time_freq: usize = time_freq.unwrap(); 39 kinfo!("init_time_freq: timebase-frequency: {}", time_freq); 40 unsafe { 41 TIME_FREQ = time_freq; 42 } 43 } 44 45 pub fn time_init() { 46 // 初始化cpu time register频率 47 init_time_freq(); 48 } 49 50 impl TimeArch for RiscV64TimeArch { 51 fn get_cycles() -> usize { 52 riscv::register::time::read() 53 } 54 55 fn cal_expire_cycles(ns: usize) -> usize { 56 Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000 57 } 58 59 /// 将CPU的时钟周期数转换为纳秒 60 #[inline(always)] 61 fn cycles2ns(cycles: usize) -> usize { 62 if unsafe { TIME_FREQ == 0 } { 63 return 0; 64 } 65 66 cycles * 1000000000 / unsafe { TIME_FREQ } 67 } 68 } 69 70 pub fn riscv_time_base_freq() -> usize { 71 unsafe { TIME_FREQ } 72 } 73