136fd0130Shoumkh use alloc::{
236fd0130Shoumkh string::ToString,
336fd0130Shoumkh sync::{Arc, Weak},
436fd0130Shoumkh };
52eab6dd7S曾俊 use log::{error, info};
691e9d4abSLoGin use system_error::SystemError;
736fd0130Shoumkh
82eab6dd7S曾俊 use crate::{arch::time::CLOCK_TICK_RATE, libs::spinlock::SpinLock};
936fd0130Shoumkh
1036fd0130Shoumkh use super::{
1136fd0130Shoumkh clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ},
1236fd0130Shoumkh timer::clock,
1336fd0130Shoumkh NSEC_PER_SEC,
1436fd0130Shoumkh };
1536fd0130Shoumkh lazy_static! {
1636fd0130Shoumkh pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new();
1736fd0130Shoumkh }
18b8ed3825SDonkey Kane
1936fd0130Shoumkh pub const JIFFIES_SHIFT: u32 = 8;
20840045afSLoGin pub const LATCH: u32 = (CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32;
2136fd0130Shoumkh pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8);
22f0c87a89SGnoCiYeH pub const TICK_NESC: u32 = (NSEC_PER_SEC + (HZ as u32) / 2) / HZ as u32;
23b8ed3825SDonkey Kane //TODO 编写测试,保证始终跳动间隔与现实一致(两种时钟源进行对拍)
24b8ed3825SDonkey Kane 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) -> u322536fd0130Shoumkh pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 {
2636fd0130Shoumkh (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den)
2736fd0130Shoumkh }
2836fd0130Shoumkh
2936fd0130Shoumkh #[derive(Debug)]
3036fd0130Shoumkh pub struct ClocksourceJiffies(SpinLock<InnerJiffies>);
3136fd0130Shoumkh
3236fd0130Shoumkh #[derive(Debug)]
3336fd0130Shoumkh pub struct InnerJiffies {
3436fd0130Shoumkh data: ClocksourceData,
3536fd0130Shoumkh self_ref: Weak<ClocksourceJiffies>,
3636fd0130Shoumkh }
3736fd0130Shoumkh
3836fd0130Shoumkh impl Clocksource for ClocksourceJiffies {
read(&self) -> CycleNum3936fd0130Shoumkh fn read(&self) -> CycleNum {
40b8ed3825SDonkey Kane CycleNum::new(clock())
4136fd0130Shoumkh }
4236fd0130Shoumkh
clocksource_data(&self) -> ClocksourceData4336fd0130Shoumkh fn clocksource_data(&self) -> ClocksourceData {
44b8ed3825SDonkey Kane let inner = self.0.lock_irqsave();
4536fd0130Shoumkh return inner.data.clone();
4636fd0130Shoumkh }
4736fd0130Shoumkh
clocksource(&self) -> Arc<dyn Clocksource>4836fd0130Shoumkh fn clocksource(&self) -> Arc<dyn Clocksource> {
49b8ed3825SDonkey Kane self.0.lock_irqsave().self_ref.upgrade().unwrap()
5036fd0130Shoumkh }
update_clocksource_data(&self, data: ClocksourceData) -> Result<(), SystemError>51*af097f9fS黄铭涛 fn update_clocksource_data(&self, data: ClocksourceData) -> Result<(), SystemError> {
52b8ed3825SDonkey Kane let d = &mut self.0.lock_irqsave().data;
53*af097f9fS黄铭涛 d.set_name(data.name);
54*af097f9fS黄铭涛 d.set_rating(data.rating);
55*af097f9fS黄铭涛 d.set_mask(data.mask);
56*af097f9fS黄铭涛 d.set_mult(data.mult);
57*af097f9fS黄铭涛 d.set_shift(data.shift);
58*af097f9fS黄铭涛 d.set_max_idle_ns(data.max_idle_ns);
59*af097f9fS黄铭涛 d.set_flags(data.flags);
60*af097f9fS黄铭涛 d.watchdog_last = data.watchdog_last;
61*af097f9fS黄铭涛 d.cs_last = data.cs_last;
62*af097f9fS黄铭涛 d.set_uncertainty_margin(data.uncertainty_margin);
63*af097f9fS黄铭涛 d.set_maxadj(data.maxadj);
64*af097f9fS黄铭涛 d.cycle_last = data.cycle_last;
6536fd0130Shoumkh return Ok(());
6636fd0130Shoumkh }
6736fd0130Shoumkh
enable(&self) -> Result<i32, SystemError>6836fd0130Shoumkh fn enable(&self) -> Result<i32, SystemError> {
6936fd0130Shoumkh return Ok(0);
7036fd0130Shoumkh }
7136fd0130Shoumkh }
7236fd0130Shoumkh impl ClocksourceJiffies {
new() -> Arc<Self>7336fd0130Shoumkh pub fn new() -> Arc<Self> {
7436fd0130Shoumkh let data = ClocksourceData {
7536fd0130Shoumkh name: "jiffies".to_string(),
7636fd0130Shoumkh rating: 1,
7736fd0130Shoumkh mask: ClocksourceMask::new(0xffffffff),
7836fd0130Shoumkh mult: NSEC_PER_JIFFY << JIFFIES_SHIFT,
7936fd0130Shoumkh shift: JIFFIES_SHIFT,
8036fd0130Shoumkh max_idle_ns: Default::default(),
8136fd0130Shoumkh flags: ClocksourceFlags::new(0),
82b8ed3825SDonkey Kane watchdog_last: CycleNum::new(0),
83*af097f9fS黄铭涛 cs_last: CycleNum::new(0),
84dd8e74efSMingtao Huang uncertainty_margin: 0,
85dd8e74efSMingtao Huang maxadj: 0,
86*af097f9fS黄铭涛 cycle_last: CycleNum::new(0),
8736fd0130Shoumkh };
88b8ed3825SDonkey Kane let jiffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies {
8936fd0130Shoumkh data,
9036fd0130Shoumkh self_ref: Default::default(),
9136fd0130Shoumkh })));
92b8ed3825SDonkey Kane jiffies.0.lock().self_ref = Arc::downgrade(&jiffies);
9336fd0130Shoumkh
94b8ed3825SDonkey Kane return jiffies;
9536fd0130Shoumkh }
9636fd0130Shoumkh }
clocksource_default_clock() -> Arc<ClocksourceJiffies>9736fd0130Shoumkh pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> {
9836fd0130Shoumkh DEFAULT_CLOCK.clone()
9936fd0130Shoumkh }
10036fd0130Shoumkh
jiffies_init()10136fd0130Shoumkh pub fn jiffies_init() {
10236fd0130Shoumkh //注册jiffies
10336fd0130Shoumkh let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>;
104dd8e74efSMingtao Huang match jiffies.register(1, 0) {
10540fe15e0SLoGin Ok(_) => {
1062eab6dd7S曾俊 info!("jiffies_init sccessfully");
10736fd0130Shoumkh }
10840fe15e0SLoGin Err(_) => {
1092eab6dd7S曾俊 error!("jiffies_init failed, no default clock running");
11040fe15e0SLoGin }
11140fe15e0SLoGin };
11236fd0130Shoumkh }
11336fd0130Shoumkh
11436fd0130Shoumkh #[no_mangle]
rs_jiffies_init()11536fd0130Shoumkh pub extern "C" fn rs_jiffies_init() {
11636fd0130Shoumkh jiffies_init();
11736fd0130Shoumkh }
118