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