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