136fd0130Shoumkh use alloc::{ 236fd0130Shoumkh string::ToString, 336fd0130Shoumkh sync::{Arc, Weak}, 436fd0130Shoumkh }; 5*91e9d4abSLoGin use system_error::SystemError; 636fd0130Shoumkh 7*91e9d4abSLoGin use crate::{kerror, kinfo, libs::spinlock::SpinLock}; 836fd0130Shoumkh 936fd0130Shoumkh use super::{ 1036fd0130Shoumkh clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ}, 1136fd0130Shoumkh timer::clock, 1236fd0130Shoumkh NSEC_PER_SEC, 1336fd0130Shoumkh }; 1436fd0130Shoumkh lazy_static! { 1536fd0130Shoumkh pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new(); 1636fd0130Shoumkh } 1736fd0130Shoumkh pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 100000; 1836fd0130Shoumkh pub const JIFFIES_SHIFT: u32 = 8; 1936fd0130Shoumkh pub const LATCH: u32 = ((CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32) as u32; 2036fd0130Shoumkh pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8); 2136fd0130Shoumkh pub const NSEC_PER_JIFFY: u32 = ((NSEC_PER_SEC << 8) / ACTHZ) as u32; 2236fd0130Shoumkh pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 { 2336fd0130Shoumkh (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den) 2436fd0130Shoumkh } 2536fd0130Shoumkh 2636fd0130Shoumkh #[derive(Debug)] 2736fd0130Shoumkh pub struct ClocksourceJiffies(SpinLock<InnerJiffies>); 2836fd0130Shoumkh 2936fd0130Shoumkh #[derive(Debug)] 3036fd0130Shoumkh pub struct InnerJiffies { 3136fd0130Shoumkh data: ClocksourceData, 3236fd0130Shoumkh self_ref: Weak<ClocksourceJiffies>, 3336fd0130Shoumkh } 3436fd0130Shoumkh 3536fd0130Shoumkh impl Clocksource for ClocksourceJiffies { 3636fd0130Shoumkh fn read(&self) -> CycleNum { 3736fd0130Shoumkh CycleNum(clock()) 3836fd0130Shoumkh } 3936fd0130Shoumkh 4036fd0130Shoumkh fn clocksource_data(&self) -> ClocksourceData { 4136fd0130Shoumkh let inner = self.0.lock(); 4236fd0130Shoumkh return inner.data.clone(); 4336fd0130Shoumkh } 4436fd0130Shoumkh 4536fd0130Shoumkh fn clocksource(&self) -> Arc<dyn Clocksource> { 4636fd0130Shoumkh self.0.lock().self_ref.upgrade().unwrap() 4736fd0130Shoumkh } 4836fd0130Shoumkh fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> { 4936fd0130Shoumkh let d = &mut self.0.lock().data; 5036fd0130Shoumkh d.set_flags(_data.flags); 5136fd0130Shoumkh d.set_mask(_data.mask); 5236fd0130Shoumkh d.set_max_idle_ns(_data.max_idle_ns); 5336fd0130Shoumkh d.set_mult(_data.mult); 5436fd0130Shoumkh d.set_name(_data.name); 5536fd0130Shoumkh d.set_rating(_data.rating); 5636fd0130Shoumkh d.set_shift(_data.shift); 5736fd0130Shoumkh return Ok(()); 5836fd0130Shoumkh } 5936fd0130Shoumkh 6036fd0130Shoumkh fn enable(&self) -> Result<i32, SystemError> { 6136fd0130Shoumkh return Ok(0); 6236fd0130Shoumkh } 6336fd0130Shoumkh } 6436fd0130Shoumkh impl ClocksourceJiffies { 6536fd0130Shoumkh pub fn new() -> Arc<Self> { 6636fd0130Shoumkh let data = ClocksourceData { 6736fd0130Shoumkh name: "jiffies".to_string(), 6836fd0130Shoumkh rating: 1, 6936fd0130Shoumkh mask: ClocksourceMask::new(0xffffffff), 7036fd0130Shoumkh mult: NSEC_PER_JIFFY << JIFFIES_SHIFT, 7136fd0130Shoumkh shift: JIFFIES_SHIFT, 7236fd0130Shoumkh max_idle_ns: Default::default(), 7336fd0130Shoumkh flags: ClocksourceFlags::new(0), 7436fd0130Shoumkh watchdog_last: CycleNum(0), 7536fd0130Shoumkh }; 7636fd0130Shoumkh let jieffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies { 7736fd0130Shoumkh data, 7836fd0130Shoumkh self_ref: Default::default(), 7936fd0130Shoumkh }))); 8036fd0130Shoumkh jieffies.0.lock().self_ref = Arc::downgrade(&jieffies); 8136fd0130Shoumkh 8236fd0130Shoumkh return jieffies; 8336fd0130Shoumkh } 8436fd0130Shoumkh } 8536fd0130Shoumkh pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> { 8636fd0130Shoumkh DEFAULT_CLOCK.clone() 8736fd0130Shoumkh } 8836fd0130Shoumkh 8936fd0130Shoumkh pub fn jiffies_init() { 9036fd0130Shoumkh //注册jiffies 9136fd0130Shoumkh let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>; 9236fd0130Shoumkh match jiffies.register() { 9340fe15e0SLoGin Ok(_) => { 9440fe15e0SLoGin kinfo!("jiffies_init sccessfully"); 9536fd0130Shoumkh } 9640fe15e0SLoGin Err(_) => { 9740fe15e0SLoGin kerror!("jiffies_init failed, no default clock running"); 9840fe15e0SLoGin } 9940fe15e0SLoGin }; 10036fd0130Shoumkh } 10136fd0130Shoumkh 10236fd0130Shoumkh #[no_mangle] 10336fd0130Shoumkh pub extern "C" fn rs_jiffies_init() { 10436fd0130Shoumkh jiffies_init(); 10536fd0130Shoumkh } 106