Skip to content

Commit 934645e

Browse files
committed
switch to crate arm_pl031 to read the realtime clock
1 parent 9b7bb8d commit 934645e

File tree

3 files changed

+21
-34
lines changed

3 files changed

+21
-34
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ memory_addresses = { version = "0.2.2", default-features = false, features = [
171171
[target.'cfg(target_arch = "aarch64")'.dependencies]
172172
aarch64 = { version = "0.0.13", default-features = false }
173173
arm-gic = { version = "0.3" }
174+
arm_pl031 = {version = "0.2.1" }
174175
hermit-dtb = { version = "0.1" }
175176
semihosting = { version = "0.1", optional = true }
176177
memory_addresses = { version = "0.2.2", default-features = false, features = [

src/arch/aarch64/kernel/systemtime.rs

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use alloc::vec::Vec;
44
use core::arch::asm;
55
use core::str;
66

7+
use arm_pl031::Rtc;
78
use hermit_dtb::Dtb;
89
use hermit_sync::OnceCell;
910
use memory_addresses::arch::aarch64::{PhysAddr, VirtAddr};
@@ -13,38 +14,9 @@ use crate::arch::aarch64::mm::paging::{self, BasePageSize, PageSize, PageTableEn
1314
use crate::env;
1415
use crate::mm::virtualmem;
1516

16-
static PL031_ADDRESS: OnceCell<VirtAddr> = OnceCell::new();
17+
static RTC_PL031: OnceCell<Rtc> = OnceCell::new();
1718
static BOOT_TIME: OnceCell<u64> = OnceCell::new();
1819

19-
const RTC_DR: usize = 0x00;
20-
const RTC_MR: usize = 0x04;
21-
const RTC_LR: usize = 0x08;
22-
const RTC_CR: usize = 0x0c;
23-
/// Interrupt mask and set register
24-
const RTC_IRQ_MASK: usize = 0x10;
25-
/// Raw interrupt status
26-
const RTC_RAW_IRQ_STATUS: usize = 0x14;
27-
/// Masked interrupt status
28-
const RTC_MASK_IRQ_STATUS: usize = 0x18;
29-
/// Interrupt clear register
30-
const RTC_IRQ_CLEAR: usize = 0x1c;
31-
32-
#[inline]
33-
fn rtc_read(off: usize) -> u32 {
34-
let value: u32;
35-
36-
// we have to use inline assembly to guarantee 32bit memory access
37-
unsafe {
38-
asm!("ldar {value:w}, [{addr}]",
39-
value = out(reg) value,
40-
addr = in(reg) (PL031_ADDRESS.get().unwrap().as_usize() + off),
41-
options(nostack, readonly),
42-
);
43-
}
44-
45-
value
46-
}
47-
4820
pub fn init() {
4921
let dtb = unsafe {
5022
Dtb::from_raw(core::ptr::with_exposed_provenance(
@@ -71,8 +43,6 @@ pub fn init() {
7143
BasePageSize::SIZE.try_into().unwrap(),
7244
)
7345
.unwrap();
74-
PL031_ADDRESS.set(pl031_address).unwrap();
75-
debug!("Mapping RTC to virtual address {pl031_address:p}",);
7646

7747
let mut flags = PageTableEntryFlags::empty();
7848
flags.device().writable().execute_disable();
@@ -83,20 +53,26 @@ pub fn init() {
8353
flags,
8454
);
8555

56+
debug!("Mapping RTC to virtual address {pl031_address:p}");
57+
58+
let rtc = unsafe { Rtc::new(pl031_address.as_mut_ptr()) };
8659
let boot_time =
87-
OffsetDateTime::from_unix_timestamp(rtc_read(RTC_DR).into()).unwrap();
60+
OffsetDateTime::from_unix_timestamp(rtc.get_unix_timestamp().into()).unwrap();
8861
info!("Hermit booted on {boot_time}");
8962

9063
let micros = u64::try_from(boot_time.unix_timestamp_nanos() / 1000).unwrap();
9164
let current_ticks = super::processor::get_timer_ticks();
9265
BOOT_TIME.set(micros - current_ticks).unwrap();
9366

67+
if RTC_PL031.set(rtc).is_err() {
68+
panic!("Unable to set RTC_PL031");
69+
}
70+
9471
return;
9572
}
9673
}
9774
}
9875

99-
PL031_ADDRESS.set(VirtAddr::zero()).unwrap();
10076
BOOT_TIME.set(0).unwrap();
10177
}
10278

0 commit comments

Comments
 (0)