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