1 use alloc::{ 2 string::ToString, 3 sync::{Arc, Weak}, 4 }; 5 use log::{error, info}; 6 use system_error::SystemError; 7 8 use crate::{arch::time::CLOCK_TICK_RATE, libs::spinlock::SpinLock}; 9 10 use super::{ 11 clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ}, 12 timer::clock, 13 NSEC_PER_SEC, 14 }; 15 lazy_static! { 16 pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new(); 17 } 18 19 pub const JIFFIES_SHIFT: u32 = 8; 20 pub const LATCH: u32 = (CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32; 21 pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8); 22 pub const TICK_NESC: u32 = (NSEC_PER_SEC + (HZ as u32) / 2) / HZ as u32; 23 //TODO 编写测试,保证始终跳动间隔与现实一致(两种时钟源进行对拍) 24 pub const NSEC_PER_JIFFY: u32 = (((NSEC_PER_SEC as u64) << 8) / ACTHZ as u64) as u32; 25 pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 { 26 (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den) 27 } 28 29 #[derive(Debug)] 30 pub struct ClocksourceJiffies(SpinLock<InnerJiffies>); 31 32 #[derive(Debug)] 33 pub struct InnerJiffies { 34 data: ClocksourceData, 35 self_ref: Weak<ClocksourceJiffies>, 36 } 37 38 impl Clocksource for ClocksourceJiffies { 39 fn read(&self) -> CycleNum { 40 CycleNum::new(clock()) 41 } 42 43 fn clocksource_data(&self) -> ClocksourceData { 44 let inner = self.0.lock_irqsave(); 45 return inner.data.clone(); 46 } 47 48 fn clocksource(&self) -> Arc<dyn Clocksource> { 49 self.0.lock_irqsave().self_ref.upgrade().unwrap() 50 } 51 fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> { 52 let d = &mut self.0.lock_irqsave().data; 53 d.set_flags(_data.flags); 54 d.set_mask(_data.mask); 55 d.set_max_idle_ns(_data.max_idle_ns); 56 d.set_mult(_data.mult); 57 d.set_name(_data.name); 58 d.set_rating(_data.rating); 59 d.set_shift(_data.shift); 60 d.watchdog_last = _data.watchdog_last; 61 return Ok(()); 62 } 63 64 fn enable(&self) -> Result<i32, SystemError> { 65 return Ok(0); 66 } 67 } 68 impl ClocksourceJiffies { 69 pub fn new() -> Arc<Self> { 70 let data = ClocksourceData { 71 name: "jiffies".to_string(), 72 rating: 1, 73 mask: ClocksourceMask::new(0xffffffff), 74 mult: NSEC_PER_JIFFY << JIFFIES_SHIFT, 75 shift: JIFFIES_SHIFT, 76 max_idle_ns: Default::default(), 77 flags: ClocksourceFlags::new(0), 78 watchdog_last: CycleNum::new(0), 79 uncertainty_margin: 0, 80 maxadj: 0, 81 }; 82 let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies { 83 data, 84 self_ref: Default::default(), 85 }))); 86 jiffies.0.lock().self_ref = Arc::downgrade(&jiffies); 87 88 return jiffies; 89 } 90 } 91 pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> { 92 DEFAULT_CLOCK.clone() 93 } 94 95 pub fn jiffies_init() { 96 //注册jiffies 97 let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>; 98 match jiffies.register(1, 0) { 99 Ok(_) => { 100 info!("jiffies_init sccessfully"); 101 } 102 Err(_) => { 103 error!("jiffies_init failed, no default clock running"); 104 } 105 }; 106 } 107 108 #[no_mangle] 109 pub extern "C" fn rs_jiffies_init() { 110 jiffies_init(); 111 } 112