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