xref: /DragonOS/kernel/src/time/jiffies.rs (revision 40fe15e0953f989ccfeb74826d61621d43dea6bb)
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