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