|
|
@ -6,11 +6,30 @@ use crate::arch::driver::rtc_cmos;
|
|
|
|
use core::time::Duration;
|
|
|
|
use core::time::Duration;
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// should be initialized together
|
|
|
|
lazy_static! {
|
|
|
|
lazy_static! {
|
|
|
|
pub static ref EPOCH_BASE: u64 = unsafe { rtc_cmos::read_epoch() };
|
|
|
|
pub static ref EPOCH_BASE: u64 = rtc_cmos::read_epoch();
|
|
|
|
pub static ref TICK_BASE: u64 = unsafe { crate::trap::TICK as u64 };
|
|
|
|
pub static ref TICK_BASE: u64 = unsafe { crate::trap::TICK as u64 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1ms msec
|
|
|
|
|
|
|
|
// 1us usec
|
|
|
|
|
|
|
|
// 1ns nsec
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const USEC_PER_SEC: u64 = 1_000_000;
|
|
|
|
|
|
|
|
const MSEC_PER_SEC: u64 = 1_000;
|
|
|
|
|
|
|
|
const USEC_PER_MSEC: u64 = 1_000;
|
|
|
|
|
|
|
|
const NSEC_PER_USEC: u64 = 1_000;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Get time since epoch in usec
|
|
|
|
|
|
|
|
fn get_epoch_usec() -> u64 {
|
|
|
|
|
|
|
|
let tick_base = *TICK_BASE;
|
|
|
|
|
|
|
|
let epoch_base = *EPOCH_BASE;
|
|
|
|
|
|
|
|
let tick = unsafe { crate::trap::TICK as u64 };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(tick - tick_base) * USEC_PER_TICK as u64 + epoch_base * USEC_PER_SEC
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
pub struct TimeVal {
|
|
|
|
pub struct TimeVal {
|
|
|
@ -20,11 +39,15 @@ pub struct TimeVal {
|
|
|
|
|
|
|
|
|
|
|
|
impl TimeVal {
|
|
|
|
impl TimeVal {
|
|
|
|
pub fn to_msec(&self) -> u64 {
|
|
|
|
pub fn to_msec(&self) -> u64 {
|
|
|
|
self.sec * 1000 + self.usec / 1000
|
|
|
|
self.sec * MSEC_PER_SEC + self.usec / USEC_PER_MSEC
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn to_usec(&self) -> u64 {
|
|
|
|
pub fn get_epoch() -> Self {
|
|
|
|
self.sec * 1000_000 + self.usec
|
|
|
|
let usec = get_epoch_usec();
|
|
|
|
|
|
|
|
TimeVal {
|
|
|
|
|
|
|
|
sec: usec / USEC_PER_SEC,
|
|
|
|
|
|
|
|
usec: usec % USEC_PER_SEC,
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -39,6 +62,14 @@ impl TimeSpec {
|
|
|
|
pub fn to_duration(&self) -> Duration {
|
|
|
|
pub fn to_duration(&self) -> Duration {
|
|
|
|
Duration::new(self.sec, self.nsec as u32)
|
|
|
|
Duration::new(self.sec, self.nsec as u32)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn get_epoch() -> Self {
|
|
|
|
|
|
|
|
let usec = get_epoch_usec();
|
|
|
|
|
|
|
|
TimeSpec {
|
|
|
|
|
|
|
|
sec: usec / USEC_PER_SEC,
|
|
|
|
|
|
|
|
nsec: usec % USEC_PER_SEC * NSEC_PER_USEC,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
|
|
|
|
pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
|
|
|
@ -50,16 +81,7 @@ pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
|
|
|
|
let proc = process();
|
|
|
|
let proc = process();
|
|
|
|
proc.memory_set.check_mut_ptr(tv)?;
|
|
|
|
proc.memory_set.check_mut_ptr(tv)?;
|
|
|
|
|
|
|
|
|
|
|
|
let tick_base = *TICK_BASE;
|
|
|
|
let timeval = TimeVal::get_epoch();
|
|
|
|
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 {
|
|
|
|
unsafe {
|
|
|
|
*tv = timeval;
|
|
|
|
*tv = timeval;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -72,16 +94,7 @@ pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult {
|
|
|
|
let proc = process();
|
|
|
|
let proc = process();
|
|
|
|
proc.memory_set.check_mut_ptr(ts)?;
|
|
|
|
proc.memory_set.check_mut_ptr(ts)?;
|
|
|
|
|
|
|
|
|
|
|
|
let tick_base = *TICK_BASE;
|
|
|
|
let timespec = TimeSpec::get_epoch();
|
|
|
|
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 {
|
|
|
|
unsafe {
|
|
|
|
*ts = timespec;
|
|
|
|
*ts = timespec;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -89,12 +102,7 @@ pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn sys_time(time: *mut u64) -> SysResult {
|
|
|
|
pub fn sys_time(time: *mut u64) -> SysResult {
|
|
|
|
let tick_base = *TICK_BASE;
|
|
|
|
let sec = get_epoch_usec() / USEC_PER_SEC;
|
|
|
|
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 {
|
|
|
|
if time as usize != 0 {
|
|
|
|
let proc = process();
|
|
|
|
let proc = process();
|
|
|
|
proc.memory_set.check_mut_ptr(time)?;
|
|
|
|
proc.memory_set.check_mut_ptr(time)?;
|
|
|
|