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