Skip to content

Commit f5dbc9a

Browse files
committed
determine time stamp relative to the boot time
1 parent 89d1570 commit f5dbc9a

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

src/arch/aarch64/kernel/processor.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ use core::{fmt, str};
33

44
use aarch64::regs::*;
55
use hermit_dtb::Dtb;
6-
use hermit_sync::{Lazy, without_interrupts};
6+
use hermit_sync::{Lazy, OnceCell, without_interrupts};
77

88
use crate::env;
99

10-
// System counter frequency in Hz
10+
// System counter frequency in KHz
1111
static CPU_FREQUENCY: Lazy<CpuFrequency> = Lazy::new(|| {
1212
let mut cpu_frequency = CpuFrequency::new();
1313
unsafe {
1414
cpu_frequency.detect();
1515
}
1616
cpu_frequency
1717
});
18+
// Value of CNTPCT_EL0 at boot time
19+
static BOOT_COUNTER: OnceCell<u64> = OnceCell::new();
1820

1921
enum CpuFrequencySources {
2022
Invalid,
@@ -133,18 +135,21 @@ pub fn shutdown(error_code: i32) -> ! {
133135
#[inline]
134136
pub fn get_timer_ticks() -> u64 {
135137
// We simulate a timer with a 1 microsecond resolution by taking the CPU timestamp
136-
// and dividing it by the CPU frequency in MHz.
137-
get_timestamp() / u64::from(get_frequency())
138+
// and dividing it by the CPU frequency (in KHz).
139+
140+
let freq: u64 = CPU_FREQUENCY.get().into(); // frequency in KHz
141+
1000 * get_timestamp() / freq
138142
}
139143

144+
/// Returns the timer frequency in MHz
140145
#[inline]
141146
pub fn get_frequency() -> u16 {
142147
(CPU_FREQUENCY.get() / 1_000).try_into().unwrap()
143148
}
144149

145150
#[inline]
146151
pub fn get_timestamp() -> u64 {
147-
CNTPCT_EL0.get()
152+
CNTPCT_EL0.get() - BOOT_COUNTER.get().unwrap()
148153
}
149154

150155
#[inline]
@@ -200,14 +205,16 @@ pub fn configure() {
200205
}
201206

202207
pub fn detect_frequency() {
208+
BOOT_COUNTER.set(CNTPCT_EL0.get()).unwrap();
203209
Lazy::force(&CPU_FREQUENCY);
204210
}
205211

206212
#[inline]
207213
fn __set_oneshot_timer(wakeup_time: Option<u64>) {
208214
if let Some(wt) = wakeup_time {
209215
// wt is the absolute wakeup time in microseconds based on processor::get_timer_ticks.
210-
let deadline = (wt * u64::from(get_frequency())) / 1000;
216+
let freq: u64 = CPU_FREQUENCY.get().into(); // frequency in KHz
217+
let deadline = (wt / 1000) * freq;
211218

212219
CNTP_CVAL_EL0.set(deadline);
213220
CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::SET);

src/arch/aarch64/kernel/systemtime.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ pub fn init() {
5050
match env::boot_info().platform_info {
5151
PlatformInfo::Uhyve { boot_time, .. } => {
5252
PL031_ADDRESS.set(VirtAddr::zero()).unwrap();
53-
let micros = u64::try_from(boot_time.unix_timestamp_nanos() / 1000).unwrap();
54-
let current_ticks = super::processor::get_timer_ticks();
55-
BOOT_TIME.set(micros - current_ticks).unwrap();
53+
BOOT_TIME.set(u64::try_from(boot_time.unix_timestamp_nanos() / 1000).unwrap());
5654
info!("Hermit booted on {boot_time}");
5755

5856
return;
@@ -100,10 +98,9 @@ pub fn init() {
10098
OffsetDateTime::from_unix_timestamp(rtc_read(RTC_DR).into()).unwrap();
10199
info!("Hermit booted on {boot_time}");
102100

103-
let micros =
104-
u64::try_from(boot_time.unix_timestamp_nanos() / 1000).unwrap();
105-
let current_ticks = super::processor::get_timer_ticks();
106-
BOOT_TIME.set(micros - current_ticks).unwrap();
101+
BOOT_TIME
102+
.set(u64::try_from(boot_time.unix_timestamp_nanos() / 1000).unwrap())
103+
.unwrap();
107104

108105
return;
109106
}

0 commit comments

Comments
 (0)