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