diff --git a/src/arch/aarch64/start/hermit_entry.rs b/src/arch/aarch64/start/hermit_entry.rs index c03577bea5..a0290654e6 100644 --- a/src/arch/aarch64/start/hermit_entry.rs +++ b/src/arch/aarch64/start/hermit_entry.rs @@ -91,7 +91,7 @@ pub unsafe extern "C" fn pre_init(boot_info: Option<&'static RawBootInfo>, cpu_i dsb(SY); if cpu_id == 0 { - env::set_boot_info(*boot_info.unwrap()); + env::set_start_info(*boot_info.unwrap()); crate::rt::boot_processor_main() } else { #[cfg(not(feature = "smp"))] diff --git a/src/arch/riscv64/start/hermit_entry.rs b/src/arch/riscv64/start/hermit_entry.rs index d60f9ff257..7888c85a5f 100644 --- a/src/arch/riscv64/start/hermit_entry.rs +++ b/src/arch/riscv64/start/hermit_entry.rs @@ -53,7 +53,7 @@ unsafe extern "C" fn pre_init(hart_id: usize, boot_info: Option<&'static RawBoot if CPU_ONLINE.load(Ordering::Acquire) == 0 { crate::logging::KERNEL_LOGGER.set_time(true); - env::set_boot_info(*boot_info.unwrap()); + env::set_start_info(*boot_info.unwrap()); let fdt = env::fdt().unwrap(); // Init HART_MASK let mut hart_mask = 0; diff --git a/src/arch/x86_64/kernel/acpi.rs b/src/arch/x86_64/kernel/acpi.rs index 4c93a375d0..b7b35c6525 100644 --- a/src/arch/x86_64/kernel/acpi.rs +++ b/src/arch/x86_64/kernel/acpi.rs @@ -291,10 +291,10 @@ fn detect_rsdp(start_address: PhysAddr, end_address: PhysAddr) -> Result<&'stati /// Detects ACPI support of the computer system. /// Returns a reference to the ACPI RSDP within the Ok() if successful or an empty Err() on failure. fn detect_acpi() -> Result<&'static AcpiRsdp, ()> { - if let Some(rsdp) = env::rsdp() { - trace!("RSDP detected successfully at {rsdp:#x?}"); + if let Some(rsdp_addr) = env::rsdp_addr() { + trace!("RSDP detected successfully at {rsdp_addr:#x?}"); let rsdp = unsafe { - ptr::with_exposed_provenance::(rsdp.get()) + ptr::with_exposed_provenance::(rsdp_addr.get()) .as_ref() .unwrap() }; diff --git a/src/arch/x86_64/start/hermit_entry.rs b/src/arch/x86_64/start/hermit_entry.rs index c05b13fe02..1858fdac79 100644 --- a/src/arch/x86_64/start/hermit_entry.rs +++ b/src/arch/x86_64/start/hermit_entry.rs @@ -76,7 +76,7 @@ unsafe extern "C" fn pre_init(boot_info: Option<&'static RawBootInfo>, cpu_id: u } if cpu_id == 0 { - env::set_boot_info(*boot_info.unwrap()); + env::set_start_info(*boot_info.unwrap()); crate::rt::boot_processor_main() } else { diff --git a/src/env.rs b/src/env/mod.rs similarity index 63% rename from src/env.rs rename to src/env/mod.rs index 1864ae2631..cc682749e2 100644 --- a/src/env.rs +++ b/src/env/mod.rs @@ -1,29 +1,19 @@ //! Inspection and manipulation of the kernel's environment. +mod start_info; + use alloc::borrow::ToOwned; use alloc::string::String; use alloc::vec::Vec; -use core::num::NonZero; -use core::{ptr, str}; +use core::str; use ahash::RandomState; -use fdt::Fdt; use hashbrown::HashMap; use hashbrown::hash_map::Iter; -use hermit_entry::boot_info::{BootInfo, RawBootInfo}; use hermit_sync::OnceCell; use shlex::Shlex; -static BOOT_INFO: OnceCell = OnceCell::new(); - -pub fn boot_info() -> &'static BootInfo { - BOOT_INFO.get().unwrap() -} - -pub fn set_boot_info(raw_boot_info: RawBootInfo) { - let boot_info = BootInfo::from(raw_boot_info); - BOOT_INFO.set(boot_info).unwrap(); -} +pub use self::start_info::*; static CLI: OnceCell = OnceCell::new(); @@ -43,71 +33,6 @@ struct Cli { mmio: Vec, } -/// Whether Hermit is running under the "uhyve" hypervisor. -#[cfg(feature = "uhyve")] -pub fn is_uhyve() -> bool { - use hermit_entry::boot_info::PlatformInfo; - - matches!(boot_info().platform_info, PlatformInfo::Uhyve { .. }) -} - -#[cfg_attr(target_arch = "riscv64", expect(dead_code))] -#[cfg(feature = "uhyve")] -pub fn uhyve_boot_time() -> Option { - use hermit_entry::boot_info::PlatformInfo; - - match boot_info().platform_info { - PlatformInfo::Uhyve { boot_time, .. } => Some(boot_time), - _ => None, - } -} - -#[cfg_attr( - any(not(target_arch = "x86_64"), not(feature = "smp")), - expect(dead_code) -)] -#[cfg(feature = "uhyve")] -pub fn uhyve_num_cpus() -> Option> { - use hermit_entry::boot_info::PlatformInfo; - - match boot_info().platform_info { - PlatformInfo::Uhyve { num_cpus, .. } => { - Some(NonZero::new(num_cpus.get() as usize).unwrap()) - } - _ => None, - } -} - -pub fn fdt_addr() -> Option> { - boot_info() - .hardware_info - .device_tree - .map(|fdt| NonZero::new(fdt.get() as usize).unwrap()) -} - -pub fn fdt() -> Option> { - fdt_addr().map(|fdt| { - let ptr = ptr::with_exposed_provenance(fdt.get()); - unsafe { Fdt::from_ptr(ptr).unwrap() } - }) -} - -/// Returns the RSDP physical address if available. -#[cfg(all(target_arch = "x86_64", feature = "acpi"))] -pub fn rsdp() -> Option> { - let rsdp = fdt()? - .find_node("/hermit,rsdp")? - .reg()? - .next()? - .starting_address - .addr(); - NonZero::new(rsdp) -} - -pub fn fdt_args() -> Option<&'static str> { - fdt().and_then(|fdt| fdt.chosen().bootargs()) -} - impl Default for Cli { fn default() -> Self { let mut image_path = None; @@ -117,7 +42,7 @@ impl Default for Cli { RandomState::with_seeds(0, 0, 0, 0), ); - let args = fdt_args().unwrap_or_default(); + let args = bootargs().unwrap_or_default(); info!("bootargs = {args}"); let mut words = Shlex::new(args); diff --git a/src/env/start_info.rs b/src/env/start_info.rs new file mode 100644 index 0000000000..61effb5e68 --- /dev/null +++ b/src/env/start_info.rs @@ -0,0 +1,89 @@ +use core::num::NonZero; +use core::ptr; + +use fdt::Fdt; +use hermit_entry::boot_info::{BootInfo, RawBootInfo}; +use hermit_sync::OnceCell; + +static START_INFO: OnceCell = OnceCell::new(); + +pub fn start_info() -> &'static BootInfo { + START_INFO.get().unwrap() +} + +pub fn set_start_info(raw_boot_info: RawBootInfo) { + let start_info = BootInfo::from(raw_boot_info); + START_INFO.set(start_info).unwrap(); +} + +/// Whether Hermit is running under the "uhyve" hypervisor. +#[cfg(feature = "uhyve")] +pub fn is_uhyve() -> bool { + use hermit_entry::boot_info::PlatformInfo; + + matches!(start_info().platform_info, PlatformInfo::Uhyve { .. }) +} + +#[cfg_attr(target_arch = "riscv64", expect(dead_code))] +#[cfg(feature = "uhyve")] +pub fn uhyve_boot_time() -> Option { + use hermit_entry::boot_info::PlatformInfo; + + match start_info().platform_info { + PlatformInfo::Uhyve { boot_time, .. } => Some(boot_time), + _ => None, + } +} + +#[cfg_attr( + any(not(target_arch = "x86_64"), not(feature = "smp")), + expect(dead_code) +)] +#[cfg(feature = "uhyve")] +pub fn uhyve_num_cpus() -> Option> { + use hermit_entry::boot_info::PlatformInfo; + + match start_info().platform_info { + PlatformInfo::Uhyve { num_cpus, .. } => { + Some(NonZero::new(num_cpus.get() as usize).unwrap()) + } + _ => None, + } +} + +pub fn fdt_addr() -> Option> { + start_info() + .hardware_info + .device_tree + .map(|fdt| NonZero::new(fdt.get() as usize).unwrap()) +} + +pub fn fdt() -> Option> { + fdt_addr().map(|fdt| { + let ptr = ptr::with_exposed_provenance(fdt.get()); + unsafe { Fdt::from_ptr(ptr).unwrap() } + }) +} + +/// Returns the RSDP physical address if available. +#[cfg_attr( + any( + not(feature = "acpi"), + target_arch = "aarch64", + target_arch = "riscv64" + ), + expect(dead_code) +)] +pub fn rsdp_addr() -> Option> { + let rsdp_addr = fdt()? + .find_node("/hermit,rsdp")? + .reg()? + .next()? + .starting_address + .addr(); + NonZero::new(rsdp_addr) +} + +pub fn bootargs() -> Option<&'static str> { + fdt().and_then(|fdt| fdt.chosen().bootargs()) +}