diff --git a/src/arch/x86_64/multiboot.rs b/src/arch/x86_64/multiboot.rs index 5e83136..a97f3a8 100644 --- a/src/arch/x86_64/multiboot.rs +++ b/src/arch/x86_64/multiboot.rs @@ -1,4 +1,3 @@ -use alloc::format; use core::ptr::write_bytes; use core::{mem, ptr, slice}; @@ -8,14 +7,15 @@ use hermit_entry::boot_info::{ }; use hermit_entry::elf::LoadedKernel; use log::info; -use multiboot::information::{MemoryManagement, MemoryType, Multiboot, PAddr}; +use multiboot::information::{MemoryManagement, Multiboot, PAddr}; use sptr::Strict; -use vm_fdt::{FdtWriter, FdtWriterResult}; +use vm_fdt::FdtWriterResult; use x86_64::structures::paging::{PageSize, PageTableFlags, Size2MiB, Size4KiB}; use super::paging; use super::physicalmem::PhysAlloc; use crate::arch::x86_64::{KERNEL_STACK_SIZE, SERIAL_IO_PORT}; +use crate::fdt::Fdt; use crate::BootInfoExt; extern "C" { @@ -55,36 +55,16 @@ impl DeviceTree { let mut mem = Mem; let multiboot = unsafe { Multiboot::from_ptr(mb_info as u64, &mut mem).unwrap() }; - let all_regions = multiboot + let memory_regions = multiboot .memory_regions() .expect("Could not find a memory map in the Multiboot information"); - let ram_regions = all_regions.filter(|m| m.memory_type() == MemoryType::Available); - let mut fdt = FdtWriter::new()?; - - let root_node = fdt.begin_node("")?; - fdt.property_string("compatible", "linux,dummy-virt")?; - fdt.property_u32("#address-cells", 0x2)?; - fdt.property_u32("#size-cells", 0x2)?; + let mut fdt = Fdt::new("multiboot")?.memory_regions(memory_regions)?; if let Some(cmdline) = multiboot.command_line() { - let chosen_node = fdt.begin_node("chosen")?; - fdt.property_string("bootargs", cmdline)?; - fdt.end_node(chosen_node)?; + fdt = fdt.bootargs(cmdline)?; } - for m in ram_regions { - let start_address = m.base_address(); - let length = m.length(); - - let memory_node = fdt.begin_node(format!("memory@{:x}", start_address).as_str())?; - fdt.property_string("device_type", "memory")?; - fdt.property_array_u64("reg", &[start_address, length])?; - fdt.end_node(memory_node)?; - } - - fdt.end_node(root_node)?; - let fdt = fdt.finish()?; Ok(fdt.leak()) diff --git a/src/fdt.rs b/src/fdt.rs index b2dc6df..1f49212 100644 --- a/src/fdt.rs +++ b/src/fdt.rs @@ -48,6 +48,7 @@ impl<'a> Fdt<'a> { Ok(self) } + #[cfg_attr(all(target_arch = "x86_64", not(target_os = "uefi")), expect(unused))] pub fn rsdp(mut self, rsdp: u64) -> FdtWriterResult { let rsdp_node = self.writer.begin_node(&format!("hermit,rsdp@{rsdp:x}"))?; self.writer.property_array_u64("reg", &[rsdp, 1])?; @@ -69,6 +70,31 @@ impl<'a> Fdt<'a> { } } +#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(feature = "fc")))] +mod x86_64 { + use multiboot::information::{MemoryMapIter, MemoryType}; + use vm_fdt::FdtWriterResult; + + impl super::Fdt<'_> { + pub fn memory_regions( + mut self, + memory_regions: MemoryMapIter<'_, '_>, + ) -> FdtWriterResult { + let memory_regions = + memory_regions.filter(|m| m.memory_type() == MemoryType::Available); + + for memory_region in memory_regions { + self = self.memory( + memory_region.base_address() + ..memory_region.base_address() + memory_region.length(), + )?; + } + + Ok(self) + } + } +} + #[cfg(target_os = "uefi")] mod uefi { use core::fmt; diff --git a/src/main.rs b/src/main.rs index a082fcd..89f8d77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ mod macros; mod arch; mod bump_allocator; -#[cfg(target_os = "uefi")] +#[cfg(any(target_os = "uefi", all(target_arch = "x86_64", not(feature = "fc"))))] mod fdt; mod log; mod os;