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;
sh_div(nom: u32, den: u32, lsh: u32) -> u3225 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 {
read(&self) -> CycleNum39 fn read(&self) -> CycleNum {
40 CycleNum::new(clock())
41 }
42
clocksource_data(&self) -> ClocksourceData43 fn clocksource_data(&self) -> ClocksourceData {
44 let inner = self.0.lock_irqsave();
45 return inner.data.clone();
46 }
47
clocksource(&self) -> Arc<dyn Clocksource>48 fn clocksource(&self) -> Arc<dyn Clocksource> {
49 self.0.lock_irqsave().self_ref.upgrade().unwrap()
50 }
update_clocksource_data(&self, data: ClocksourceData) -> Result<(), SystemError>51 fn update_clocksource_data(&self, data: ClocksourceData) -> Result<(), SystemError> {
52 let d = &mut self.0.lock_irqsave().data;
53 d.set_name(data.name);
54 d.set_rating(data.rating);
55 d.set_mask(data.mask);
56 d.set_mult(data.mult);
57 d.set_shift(data.shift);
58 d.set_max_idle_ns(data.max_idle_ns);
59 d.set_flags(data.flags);
60 d.watchdog_last = data.watchdog_last;
61 d.cs_last = data.cs_last;
62 d.set_uncertainty_margin(data.uncertainty_margin);
63 d.set_maxadj(data.maxadj);
64 d.cycle_last = data.cycle_last;
65 return Ok(());
66 }
67
enable(&self) -> Result<i32, SystemError>68 fn enable(&self) -> Result<i32, SystemError> {
69 return Ok(0);
70 }
71 }
72 impl ClocksourceJiffies {
new() -> Arc<Self>73 pub fn new() -> Arc<Self> {
74 let data = ClocksourceData {
75 name: "jiffies".to_string(),
76 rating: 1,
77 mask: ClocksourceMask::new(0xffffffff),
78 mult: NSEC_PER_JIFFY << JIFFIES_SHIFT,
79 shift: JIFFIES_SHIFT,
80 max_idle_ns: Default::default(),
81 flags: ClocksourceFlags::new(0),
82 watchdog_last: CycleNum::new(0),
83 cs_last: CycleNum::new(0),
84 uncertainty_margin: 0,
85 maxadj: 0,
86 cycle_last: CycleNum::new(0),
87 };
88 let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies {
89 data,
90 self_ref: Default::default(),
91 })));
92 jiffies.0.lock().self_ref = Arc::downgrade(&jiffies);
93
94 return jiffies;
95 }
96 }
clocksource_default_clock() -> Arc<ClocksourceJiffies>97 pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> {
98 DEFAULT_CLOCK.clone()
99 }
100
jiffies_init()101 pub fn jiffies_init() {
102 //注册jiffies
103 let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>;
104 match jiffies.register(1, 0) {
105 Ok(_) => {
106 info!("jiffies_init sccessfully");
107 }
108 Err(_) => {
109 error!("jiffies_init failed, no default clock running");
110 }
111 };
112 }
113
114 #[no_mangle]
rs_jiffies_init()115 pub extern "C" fn rs_jiffies_init() {
116 jiffies_init();
117 }
118