//! Syscalls for time use super::*; use crate::arch::consts::USEC_PER_TICK; use crate::arch::driver::rtc_cmos; use lazy_static::lazy_static; use core::time::Duration; lazy_static! { pub static ref EPOCH_BASE: u64 = unsafe { rtc_cmos::read_epoch() }; pub static ref TICK_BASE: u64 = unsafe { crate::trap::TICK as u64 }; } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TimeVal { sec: u64, usec: u64, } impl TimeVal { pub fn to_msec(&self) -> u64 { self.sec * 1000 + self.usec / 1000 } pub fn to_usec(&self) -> u64 { self.sec * 1000_000 + self.usec } } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TimeSpec { sec: u64, nsec: u64, } impl TimeSpec { pub fn to_duration(&self) -> Duration { Duration::new(self.sec, self.nsec as u32) } } pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult { info!("gettimeofday: tv: {:?}, tz: {:?}", tv, tz); if tz as usize != 0 { return Err(SysError::EINVAL); } let mut proc = process(); proc.memory_set.check_mut_ptr(tv)?; let tick_base = *TICK_BASE; let epoch_base = *EPOCH_BASE; let tick = unsafe { crate::trap::TICK as u64 }; let usec = (tick - tick_base) * USEC_PER_TICK as u64; let sec = epoch_base + usec / 1_000_000; let timeval = TimeVal { sec, usec: usec % 1_000_000, }; unsafe { *tv = timeval; } Ok(0) } pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult { info!("clock_gettime: clock: {:?}, ts: {:?}", clock, ts); let mut proc = process(); proc.memory_set.check_mut_ptr(ts)?; let tick_base = *TICK_BASE; let epoch_base = *EPOCH_BASE; let tick = unsafe { crate::trap::TICK as u64 }; let usec = (tick - tick_base) * USEC_PER_TICK as u64; let sec = epoch_base + usec / 1_000_000; let timespec = TimeSpec { sec, nsec: (usec % 1_000_000) * 1000, }; unsafe { *ts = timespec; } Ok(0) } pub fn sys_time(time: *mut u64) -> SysResult { let tick_base = *TICK_BASE; let epoch_base = *EPOCH_BASE; let tick = unsafe { crate::trap::TICK as u64 }; let usec = (tick - tick_base) * USEC_PER_TICK as u64; let sec = epoch_base + usec / 1_000_000; if time as usize != 0 { let mut proc = process(); proc.memory_set.check_mut_ptr(time)?; unsafe { time.write(sec as u64); } } Ok(sec as usize) }