xref: /DragonOS/kernel/src/time/jiffies.rs (revision 03746da3d9f3ea616cecdb6e581414002075f866)
1 use alloc::{
2     string::ToString,
3     sync::{Arc, Weak},
4 };
5 use log::{error, info};
6 use system_error::SystemError;
7 
8 use crate::{arch::time::CLOCK_TICK_RATE, libs::spinlock::SpinLock};
9 
10 use super::{
11     clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ},
12     timer::clock,
13     NSEC_PER_SEC,
14 };
15 lazy_static! {
16     pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new();
17 }
18 
19 pub const JIFFIES_SHIFT: u32 = 8;
20 pub const LATCH: u32 = (CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32;
21 pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8);
22 pub const TICK_NESC: u32 = (NSEC_PER_SEC + (HZ as u32) / 2) / HZ as u32;
23 //TODO 编写测试,保证始终跳动间隔与现实一致(两种时钟源进行对拍)
24 pub const NSEC_PER_JIFFY: u32 = (((NSEC_PER_SEC as u64) << 8) / ACTHZ as u64) as u32;
25 pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 {
26     (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den)
27 }
28 
29 #[derive(Debug)]
30 pub struct ClocksourceJiffies(SpinLock<InnerJiffies>);
31 
32 #[derive(Debug)]
33 pub struct InnerJiffies {
34     data: ClocksourceData,
35     self_ref: Weak<ClocksourceJiffies>,
36 }
37 
38 impl Clocksource for ClocksourceJiffies {
39     fn read(&self) -> CycleNum {
40         CycleNum::new(clock())
41     }
42 
43     fn clocksource_data(&self) -> ClocksourceData {
44         let inner = self.0.lock_irqsave();
45         return inner.data.clone();
46     }
47 
48     fn clocksource(&self) -> Arc<dyn Clocksource> {
49         self.0.lock_irqsave().self_ref.upgrade().unwrap()
50     }
51     fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
52         let d = &mut self.0.lock_irqsave().data;
53         d.set_flags(_data.flags);
54         d.set_mask(_data.mask);
55         d.set_max_idle_ns(_data.max_idle_ns);
56         d.set_mult(_data.mult);
57         d.set_name(_data.name);
58         d.set_rating(_data.rating);
59         d.set_shift(_data.shift);
60         d.watchdog_last = _data.watchdog_last;
61         return Ok(());
62     }
63 
64     fn enable(&self) -> Result<i32, SystemError> {
65         return Ok(0);
66     }
67 }
68 impl ClocksourceJiffies {
69     pub fn new() -> Arc<Self> {
70         let data = ClocksourceData {
71             name: "jiffies".to_string(),
72             rating: 1,
73             mask: ClocksourceMask::new(0xffffffff),
74             mult: NSEC_PER_JIFFY << JIFFIES_SHIFT,
75             shift: JIFFIES_SHIFT,
76             max_idle_ns: Default::default(),
77             flags: ClocksourceFlags::new(0),
78             watchdog_last: CycleNum::new(0),
79             uncertainty_margin: 0,
80             maxadj: 0,
81         };
82         let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies {
83             data,
84             self_ref: Default::default(),
85         })));
86         jiffies.0.lock().self_ref = Arc::downgrade(&jiffies);
87 
88         return jiffies;
89     }
90 }
91 pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> {
92     DEFAULT_CLOCK.clone()
93 }
94 
95 pub fn jiffies_init() {
96     //注册jiffies
97     let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>;
98     match jiffies.register(1, 0) {
99         Ok(_) => {
100             info!("jiffies_init sccessfully");
101         }
102         Err(_) => {
103             error!("jiffies_init failed, no default clock running");
104         }
105     };
106 }
107 
108 #[no_mangle]
109 pub extern "C" fn rs_jiffies_init() {
110     jiffies_init();
111 }
112