@@ -4,6 +4,7 @@ use alloc::vec::Vec;
4
4
use core:: arch:: asm;
5
5
use core:: str;
6
6
7
+ use arm_pl031:: Rtc ;
7
8
use hermit_dtb:: Dtb ;
8
9
use hermit_sync:: OnceCell ;
9
10
use memory_addresses:: arch:: aarch64:: { PhysAddr , VirtAddr } ;
@@ -13,38 +14,9 @@ use crate::arch::aarch64::mm::paging::{self, BasePageSize, PageSize, PageTableEn
13
14
use crate :: env;
14
15
use crate :: mm:: virtualmem;
15
16
16
- static PL031_ADDRESS : OnceCell < VirtAddr > = OnceCell :: new ( ) ;
17
+ static RTC_PL031 : OnceCell < Rtc > = OnceCell :: new ( ) ;
17
18
static BOOT_TIME : OnceCell < u64 > = OnceCell :: new ( ) ;
18
19
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
-
48
20
pub fn init ( ) {
49
21
let dtb = unsafe {
50
22
Dtb :: from_raw ( core:: ptr:: with_exposed_provenance (
@@ -71,8 +43,6 @@ pub fn init() {
71
43
BasePageSize :: SIZE . try_into ( ) . unwrap ( ) ,
72
44
)
73
45
. unwrap ( ) ;
74
- PL031_ADDRESS . set ( pl031_address) . unwrap ( ) ;
75
- debug ! ( "Mapping RTC to virtual address {pl031_address:p}" , ) ;
76
46
77
47
let mut flags = PageTableEntryFlags :: empty ( ) ;
78
48
flags. device ( ) . writable ( ) . execute_disable ( ) ;
@@ -83,20 +53,27 @@ pub fn init() {
83
53
flags,
84
54
) ;
85
55
56
+ debug ! ( "Mapping RTC to virtual address {pl031_address:p}" ) ;
57
+
58
+ let rtc = unsafe { Rtc :: new ( pl031_address. as_mut_ptr ( ) ) } ;
86
59
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 ( ) ;
88
61
info ! ( "Hermit booted on {boot_time}" ) ;
89
62
90
63
let micros = u64:: try_from ( boot_time. unix_timestamp_nanos ( ) / 1000 ) . unwrap ( ) ;
91
64
let current_ticks = super :: processor:: get_timer_ticks ( ) ;
92
- BOOT_TIME . set ( micros - current_ticks) . unwrap ( ) ;
65
+
66
+ assert ! (
67
+ BOOT_TIME . set( micros - current_ticks) . is_err( ) ,
68
+ "Unable to set BOOT_TIME"
69
+ ) ;
70
+ assert ! ( RTC_PL031 . set( rtc) . is_err( ) , "Unable to set RTC_PL031" ) ;
93
71
94
72
return ;
95
73
}
96
74
}
97
75
}
98
76
99
- PL031_ADDRESS . set ( VirtAddr :: zero ( ) ) . unwrap ( ) ;
100
77
BOOT_TIME . set ( 0 ) . unwrap ( ) ;
101
78
}
102
79
0 commit comments