136fd0130Shoumkh use alloc::{ 236fd0130Shoumkh string::ToString, 336fd0130Shoumkh sync::{Arc, Weak}, 436fd0130Shoumkh }; 591e9d4abSLoGin use system_error::SystemError; 636fd0130Shoumkh 7b8ed3825SDonkey Kane use crate::{arch::time::CLOCK_TICK_RATE, 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 } 17b8ed3825SDonkey Kane 1836fd0130Shoumkh pub const JIFFIES_SHIFT: u32 = 8; 19840045afSLoGin pub const LATCH: u32 = (CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32; 2036fd0130Shoumkh pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8); 21*f0c87a89SGnoCiYeH pub const TICK_NESC: u32 = (NSEC_PER_SEC + (HZ as u32) / 2) / HZ as u32; 22b8ed3825SDonkey Kane //TODO 编写测试,保证始终跳动间隔与现实一致(两种时钟源进行对拍) 23b8ed3825SDonkey Kane pub const NSEC_PER_JIFFY: u32 = (((NSEC_PER_SEC as u64) << 8) / ACTHZ as u64) as u32; 2436fd0130Shoumkh pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 { 2536fd0130Shoumkh (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den) 2636fd0130Shoumkh } 2736fd0130Shoumkh 2836fd0130Shoumkh #[derive(Debug)] 2936fd0130Shoumkh pub struct ClocksourceJiffies(SpinLock<InnerJiffies>); 3036fd0130Shoumkh 3136fd0130Shoumkh #[derive(Debug)] 3236fd0130Shoumkh pub struct InnerJiffies { 3336fd0130Shoumkh data: ClocksourceData, 3436fd0130Shoumkh self_ref: Weak<ClocksourceJiffies>, 3536fd0130Shoumkh } 3636fd0130Shoumkh 3736fd0130Shoumkh impl Clocksource for ClocksourceJiffies { 3836fd0130Shoumkh fn read(&self) -> CycleNum { 39b8ed3825SDonkey Kane CycleNum::new(clock()) 4036fd0130Shoumkh } 4136fd0130Shoumkh 4236fd0130Shoumkh fn clocksource_data(&self) -> ClocksourceData { 43b8ed3825SDonkey Kane let inner = self.0.lock_irqsave(); 4436fd0130Shoumkh return inner.data.clone(); 4536fd0130Shoumkh } 4636fd0130Shoumkh 4736fd0130Shoumkh fn clocksource(&self) -> Arc<dyn Clocksource> { 48b8ed3825SDonkey Kane self.0.lock_irqsave().self_ref.upgrade().unwrap() 4936fd0130Shoumkh } 5036fd0130Shoumkh fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> { 51b8ed3825SDonkey Kane let d = &mut self.0.lock_irqsave().data; 5236fd0130Shoumkh d.set_flags(_data.flags); 5336fd0130Shoumkh d.set_mask(_data.mask); 5436fd0130Shoumkh d.set_max_idle_ns(_data.max_idle_ns); 5536fd0130Shoumkh d.set_mult(_data.mult); 5636fd0130Shoumkh d.set_name(_data.name); 5736fd0130Shoumkh d.set_rating(_data.rating); 5836fd0130Shoumkh d.set_shift(_data.shift); 59b8ed3825SDonkey Kane d.watchdog_last = _data.watchdog_last; 6036fd0130Shoumkh return Ok(()); 6136fd0130Shoumkh } 6236fd0130Shoumkh 6336fd0130Shoumkh fn enable(&self) -> Result<i32, SystemError> { 6436fd0130Shoumkh return Ok(0); 6536fd0130Shoumkh } 6636fd0130Shoumkh } 6736fd0130Shoumkh impl ClocksourceJiffies { 6836fd0130Shoumkh pub fn new() -> Arc<Self> { 6936fd0130Shoumkh let data = ClocksourceData { 7036fd0130Shoumkh name: "jiffies".to_string(), 7136fd0130Shoumkh rating: 1, 7236fd0130Shoumkh mask: ClocksourceMask::new(0xffffffff), 7336fd0130Shoumkh mult: NSEC_PER_JIFFY << JIFFIES_SHIFT, 7436fd0130Shoumkh shift: JIFFIES_SHIFT, 7536fd0130Shoumkh max_idle_ns: Default::default(), 7636fd0130Shoumkh flags: ClocksourceFlags::new(0), 77b8ed3825SDonkey Kane watchdog_last: CycleNum::new(0), 7836fd0130Shoumkh }; 79b8ed3825SDonkey Kane let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies { 8036fd0130Shoumkh data, 8136fd0130Shoumkh self_ref: Default::default(), 8236fd0130Shoumkh }))); 83b8ed3825SDonkey Kane jiffies.0.lock().self_ref = Arc::downgrade(&jiffies); 8436fd0130Shoumkh 85b8ed3825SDonkey Kane return jiffies; 8636fd0130Shoumkh } 8736fd0130Shoumkh } 8836fd0130Shoumkh pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> { 8936fd0130Shoumkh DEFAULT_CLOCK.clone() 9036fd0130Shoumkh } 9136fd0130Shoumkh 9236fd0130Shoumkh pub fn jiffies_init() { 9336fd0130Shoumkh //注册jiffies 9436fd0130Shoumkh let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>; 9536fd0130Shoumkh match jiffies.register() { 9640fe15e0SLoGin Ok(_) => { 9740fe15e0SLoGin kinfo!("jiffies_init sccessfully"); 9836fd0130Shoumkh } 9940fe15e0SLoGin Err(_) => { 10040fe15e0SLoGin kerror!("jiffies_init failed, no default clock running"); 10140fe15e0SLoGin } 10240fe15e0SLoGin }; 10336fd0130Shoumkh } 10436fd0130Shoumkh 10536fd0130Shoumkh #[no_mangle] 10636fd0130Shoumkh pub extern "C" fn rs_jiffies_init() { 10736fd0130Shoumkh jiffies_init(); 10836fd0130Shoumkh } 109