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