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