136fd0130Shoumkh use alloc::{ 236fd0130Shoumkh string::ToString, 336fd0130Shoumkh sync::{Arc, Weak}, 436fd0130Shoumkh }; 5*2eab6dd7S曾俊 use log::{error, info}; 691e9d4abSLoGin use system_error::SystemError; 736fd0130Shoumkh 8*2eab6dd7S曾俊 use crate::{arch::time::CLOCK_TICK_RATE, libs::spinlock::SpinLock}; 936fd0130Shoumkh 1036fd0130Shoumkh use super::{ 1136fd0130Shoumkh clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ}, 1236fd0130Shoumkh timer::clock, 1336fd0130Shoumkh NSEC_PER_SEC, 1436fd0130Shoumkh }; 1536fd0130Shoumkh lazy_static! { 1636fd0130Shoumkh pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new(); 1736fd0130Shoumkh } 18b8ed3825SDonkey Kane 1936fd0130Shoumkh pub const JIFFIES_SHIFT: u32 = 8; 20840045afSLoGin pub const LATCH: u32 = (CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32; 2136fd0130Shoumkh pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8); 22f0c87a89SGnoCiYeH pub const TICK_NESC: u32 = (NSEC_PER_SEC + (HZ as u32) / 2) / HZ as u32; 23b8ed3825SDonkey Kane //TODO 编写测试,保证始终跳动间隔与现实一致(两种时钟源进行对拍) 24b8ed3825SDonkey Kane pub const NSEC_PER_JIFFY: u32 = (((NSEC_PER_SEC as u64) << 8) / ACTHZ as u64) as u32; 2536fd0130Shoumkh pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 { 2636fd0130Shoumkh (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den) 2736fd0130Shoumkh } 2836fd0130Shoumkh 2936fd0130Shoumkh #[derive(Debug)] 3036fd0130Shoumkh pub struct ClocksourceJiffies(SpinLock<InnerJiffies>); 3136fd0130Shoumkh 3236fd0130Shoumkh #[derive(Debug)] 3336fd0130Shoumkh pub struct InnerJiffies { 3436fd0130Shoumkh data: ClocksourceData, 3536fd0130Shoumkh self_ref: Weak<ClocksourceJiffies>, 3636fd0130Shoumkh } 3736fd0130Shoumkh 3836fd0130Shoumkh impl Clocksource for ClocksourceJiffies { 3936fd0130Shoumkh fn read(&self) -> CycleNum { 40b8ed3825SDonkey Kane CycleNum::new(clock()) 4136fd0130Shoumkh } 4236fd0130Shoumkh 4336fd0130Shoumkh fn clocksource_data(&self) -> ClocksourceData { 44b8ed3825SDonkey Kane let inner = self.0.lock_irqsave(); 4536fd0130Shoumkh return inner.data.clone(); 4636fd0130Shoumkh } 4736fd0130Shoumkh 4836fd0130Shoumkh fn clocksource(&self) -> Arc<dyn Clocksource> { 49b8ed3825SDonkey Kane self.0.lock_irqsave().self_ref.upgrade().unwrap() 5036fd0130Shoumkh } 5136fd0130Shoumkh fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> { 52b8ed3825SDonkey Kane let d = &mut self.0.lock_irqsave().data; 5336fd0130Shoumkh d.set_flags(_data.flags); 5436fd0130Shoumkh d.set_mask(_data.mask); 5536fd0130Shoumkh d.set_max_idle_ns(_data.max_idle_ns); 5636fd0130Shoumkh d.set_mult(_data.mult); 5736fd0130Shoumkh d.set_name(_data.name); 5836fd0130Shoumkh d.set_rating(_data.rating); 5936fd0130Shoumkh d.set_shift(_data.shift); 60b8ed3825SDonkey Kane d.watchdog_last = _data.watchdog_last; 6136fd0130Shoumkh return Ok(()); 6236fd0130Shoumkh } 6336fd0130Shoumkh 6436fd0130Shoumkh fn enable(&self) -> Result<i32, SystemError> { 6536fd0130Shoumkh return Ok(0); 6636fd0130Shoumkh } 6736fd0130Shoumkh } 6836fd0130Shoumkh impl ClocksourceJiffies { 6936fd0130Shoumkh pub fn new() -> Arc<Self> { 7036fd0130Shoumkh let data = ClocksourceData { 7136fd0130Shoumkh name: "jiffies".to_string(), 7236fd0130Shoumkh rating: 1, 7336fd0130Shoumkh mask: ClocksourceMask::new(0xffffffff), 7436fd0130Shoumkh mult: NSEC_PER_JIFFY << JIFFIES_SHIFT, 7536fd0130Shoumkh shift: JIFFIES_SHIFT, 7636fd0130Shoumkh max_idle_ns: Default::default(), 7736fd0130Shoumkh flags: ClocksourceFlags::new(0), 78b8ed3825SDonkey Kane watchdog_last: CycleNum::new(0), 79dd8e74efSMingtao Huang uncertainty_margin: 0, 80dd8e74efSMingtao Huang maxadj: 0, 8136fd0130Shoumkh }; 82b8ed3825SDonkey Kane let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies { 8336fd0130Shoumkh data, 8436fd0130Shoumkh self_ref: Default::default(), 8536fd0130Shoumkh }))); 86b8ed3825SDonkey Kane jiffies.0.lock().self_ref = Arc::downgrade(&jiffies); 8736fd0130Shoumkh 88b8ed3825SDonkey Kane return jiffies; 8936fd0130Shoumkh } 9036fd0130Shoumkh } 9136fd0130Shoumkh pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> { 9236fd0130Shoumkh DEFAULT_CLOCK.clone() 9336fd0130Shoumkh } 9436fd0130Shoumkh 9536fd0130Shoumkh pub fn jiffies_init() { 9636fd0130Shoumkh //注册jiffies 9736fd0130Shoumkh let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>; 98dd8e74efSMingtao Huang match jiffies.register(1, 0) { 9940fe15e0SLoGin Ok(_) => { 100*2eab6dd7S曾俊 info!("jiffies_init sccessfully"); 10136fd0130Shoumkh } 10240fe15e0SLoGin Err(_) => { 103*2eab6dd7S曾俊 error!("jiffies_init failed, no default clock running"); 10440fe15e0SLoGin } 10540fe15e0SLoGin }; 10636fd0130Shoumkh } 10736fd0130Shoumkh 10836fd0130Shoumkh #[no_mangle] 10936fd0130Shoumkh pub extern "C" fn rs_jiffies_init() { 11036fd0130Shoumkh jiffies_init(); 11136fd0130Shoumkh } 112