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