@@ -6,75 +6,79 @@ use core::str;
6
6
7
7
use arm_pl031:: Rtc ;
8
8
use hermit_dtb:: Dtb ;
9
+ use hermit_entry:: boot_info:: PlatformInfo ;
9
10
use hermit_sync:: OnceCell ;
10
11
use memory_addresses:: arch:: aarch64:: { PhysAddr , VirtAddr } ;
11
12
use time:: OffsetDateTime ;
12
13
13
14
use crate :: arch:: aarch64:: mm:: paging:: { self , BasePageSize , PageSize , PageTableEntryFlags } ;
14
15
use crate :: env;
16
+ use crate :: env:: is_uhyve;
15
17
use crate :: mm:: virtualmem;
18
+ use crate :: syscalls:: interfaces:: uhyve:: uhyve_hypercall;
16
19
17
- static RTC_PL031 : OnceCell < Rtc > = OnceCell :: new ( ) ;
18
20
static BOOT_TIME : OnceCell < u64 > = OnceCell :: new ( ) ;
19
21
20
22
pub fn init ( ) {
21
- let dtb = unsafe {
22
- Dtb :: from_raw ( core:: ptr:: with_exposed_provenance (
23
- env:: boot_info ( ) . hardware_info . device_tree . unwrap ( ) . get ( ) as usize ,
24
- ) )
25
- . expect ( ".dtb file has invalid header" )
26
- } ;
27
-
28
- for node in dtb. enum_subnodes ( "/" ) {
29
- let parts: Vec < _ > = node. split ( '@' ) . collect ( ) ;
30
-
31
- if let Some ( compatible) = dtb. get_property ( parts. first ( ) . unwrap ( ) , "compatible" ) {
32
- if str:: from_utf8 ( compatible) . unwrap ( ) . contains ( "pl031" ) {
33
- let reg = dtb. get_property ( parts. first ( ) . unwrap ( ) , "reg" ) . unwrap ( ) ;
34
- let ( slice, residual_slice) = reg. split_at ( core:: mem:: size_of :: < u64 > ( ) ) ;
35
- let addr = PhysAddr :: new ( u64:: from_be_bytes ( slice. try_into ( ) . unwrap ( ) ) ) ;
36
- let ( slice, _residual_slice) = residual_slice. split_at ( core:: mem:: size_of :: < u64 > ( ) ) ;
37
- let size = u64:: from_be_bytes ( slice. try_into ( ) . unwrap ( ) ) ;
38
-
39
- debug ! ( "Found RTC at {addr:p} (size {size:#X})" ) ;
40
-
41
- let pl031_address = virtualmem:: allocate_aligned (
42
- size. try_into ( ) . unwrap ( ) ,
43
- BasePageSize :: SIZE . try_into ( ) . unwrap ( ) ,
44
- )
45
- . unwrap ( ) ;
46
-
47
- let mut flags = PageTableEntryFlags :: empty ( ) ;
48
- flags. device ( ) . writable ( ) . execute_disable ( ) ;
49
- paging:: map :: < BasePageSize > (
50
- pl031_address,
51
- addr,
52
- ( size / BasePageSize :: SIZE ) . try_into ( ) . unwrap ( ) ,
53
- flags,
54
- ) ;
55
-
56
- debug ! ( "Mapping RTC to virtual address {pl031_address:p}" ) ;
57
-
58
- let rtc = unsafe { Rtc :: new ( pl031_address. as_mut_ptr ( ) ) } ;
59
- let boot_time =
60
- OffsetDateTime :: from_unix_timestamp ( rtc. get_unix_timestamp ( ) . into ( ) ) . unwrap ( ) ;
61
- info ! ( "Hermit booted on {boot_time}" ) ;
62
-
63
- let micros = u64:: try_from ( boot_time. unix_timestamp_nanos ( ) / 1000 ) . unwrap ( ) ;
64
- let current_ticks = super :: processor:: get_timer_ticks ( ) ;
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" ) ;
71
-
72
- return ;
23
+ let boot_time = match env:: boot_info ( ) . platform_info {
24
+ PlatformInfo :: Uhyve { boot_time, .. } => boot_time,
25
+ _ => {
26
+ let mut offset = OffsetDateTime :: UNIX_EPOCH ;
27
+ let dtb = unsafe {
28
+ Dtb :: from_raw ( core:: ptr:: with_exposed_provenance (
29
+ env:: boot_info ( ) . hardware_info . device_tree . unwrap ( ) . get ( ) as usize ,
30
+ ) )
31
+ . expect ( ".dtb file has invalid header" )
32
+ } ;
33
+
34
+ for node in dtb. enum_subnodes ( "/" ) {
35
+ let parts: Vec < _ > = node. split ( '@' ) . collect ( ) ;
36
+
37
+ if let Some ( compatible) = dtb. get_property ( parts. first ( ) . unwrap ( ) , "compatible" ) {
38
+ if str:: from_utf8 ( compatible) . unwrap ( ) . contains ( "pl031" ) {
39
+ let reg = dtb. get_property ( parts. first ( ) . unwrap ( ) , "reg" ) . unwrap ( ) ;
40
+ let ( slice, residual_slice) = reg. split_at ( core:: mem:: size_of :: < u64 > ( ) ) ;
41
+ let addr = PhysAddr :: new ( u64:: from_be_bytes ( slice. try_into ( ) . unwrap ( ) ) ) ;
42
+ let ( slice, _residual_slice) =
43
+ residual_slice. split_at ( core:: mem:: size_of :: < u64 > ( ) ) ;
44
+ let size = u64:: from_be_bytes ( slice. try_into ( ) . unwrap ( ) ) ;
45
+
46
+ debug ! ( "Found RTC at {addr:p} (size {size:#X})" ) ;
47
+
48
+ let pl031_address = virtualmem:: allocate_aligned (
49
+ size. try_into ( ) . unwrap ( ) ,
50
+ BasePageSize :: SIZE . try_into ( ) . unwrap ( ) ,
51
+ )
52
+ . unwrap ( ) ;
53
+
54
+ let mut flags = PageTableEntryFlags :: empty ( ) ;
55
+ flags. device ( ) . writable ( ) . execute_disable ( ) ;
56
+ paging:: map :: < BasePageSize > (
57
+ pl031_address,
58
+ addr,
59
+ ( size / BasePageSize :: SIZE ) . try_into ( ) . unwrap ( ) ,
60
+ flags,
61
+ ) ;
62
+
63
+ debug ! ( "Mapping RTC to virtual address {pl031_address:p}" ) ;
64
+
65
+ let rtc = unsafe { Rtc :: new ( pl031_address. as_mut_ptr ( ) ) } ;
66
+ offset =
67
+ OffsetDateTime :: from_unix_timestamp ( rtc. get_unix_timestamp ( ) . into ( ) )
68
+ . unwrap ( ) ;
69
+
70
+ break ;
71
+ }
72
+ }
73
73
}
74
+
75
+ offset
74
76
}
75
- }
77
+ } ;
78
+ info ! ( "Hermit booted on {boot_time}" ) ;
76
79
77
- BOOT_TIME . set ( 0 ) . unwrap ( ) ;
80
+ let micros = u64:: try_from ( boot_time. unix_timestamp_nanos ( ) / 1000 ) . unwrap ( ) ;
81
+ BOOT_TIME . set ( micros) . unwrap ( ) ;
78
82
}
79
83
80
84
/// Returns the current time in microseconds since UNIX epoch.
0 commit comments