From b0099142081b201c922c9f090913d68544b169f8 Mon Sep 17 00:00:00 2001 From: Yu Duan Date: Mon, 5 Feb 2024 19:26:29 +0000 Subject: [PATCH] Create devicetree for x86_64 Pass memory region infomation from devicetree --- Cargo.lock | 58 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/arch/x86_64/fdt.rs | 50 ++++++++++++++++++++++++++++++++++++ src/arch/x86_64/mod.rs | 12 +++++++-- src/main.rs | 1 + 5 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 src/arch/x86_64/fdt.rs diff --git a/Cargo.lock b/Cargo.lock index d32e6b1e..22fbfb34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,18 @@ dependencies = [ "tock-registers", ] +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "align-address" version = "0.1.0" @@ -252,6 +264,16 @@ dependencies = [ "scroll 0.12.0", ] +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + [[package]] name = "heck" version = "0.4.1" @@ -302,6 +324,7 @@ dependencies = [ "uart_16550", "uefi", "uefi-services", + "vm-fdt", "x86_64", ] @@ -683,6 +706,21 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vm-fdt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e21282841a059bb62627ce8441c491f09603622cd5a21c43bfedc85a2952f23" +dependencies = [ + "hashbrown", +] + [[package]] name = "volatile" version = "0.4.6" @@ -844,3 +882,23 @@ dependencies = [ "sysinfo", "xshell", ] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] diff --git a/Cargo.toml b/Cargo.toml index 389b2989..00abbc0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ align-address = "0.1" hermit-entry = { version = "0.9", features = ["loader"] } log = "0.4" sptr = "0.3" +vm-fdt = { version = "0.3", default-features = false, features = ["alloc"] } [features] default = [] diff --git a/src/arch/x86_64/fdt.rs b/src/arch/x86_64/fdt.rs new file mode 100644 index 00000000..b4058c1f --- /dev/null +++ b/src/arch/x86_64/fdt.rs @@ -0,0 +1,50 @@ +extern crate alloc; +use alloc::format; + +use multiboot::information::{MemoryType, Multiboot}; +use vm_fdt::{Error as FdtError, FdtWriter}; + +use super::{mb_info, MEM}; + +pub struct DeviceTree; + +impl DeviceTree { + #[cfg(all(target_os = "none", not(feature = "fc")))] + pub fn new() -> Result<&'static [u8], FdtError> { + let multiboot = unsafe { Multiboot::from_ptr(mb_info as u64, &mut MEM).unwrap() }; + + let all_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)?; + + if let Some(cmdline) = multiboot.command_line() { + let chosen_node = fdt.begin_node("chosen")?; + fdt.property_string("bootargs", cmdline)?; + fdt.end_node(chosen_node)?; + } + + 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/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index ebad4280..5a6cca48 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -1,3 +1,5 @@ +#[cfg(all(target_os = "none", not(feature = "fc")))] +mod fdt; mod paging; mod physicalmem; @@ -10,7 +12,9 @@ use core::ptr::write_bytes; use core::slice; use align_address::Align; -use hermit_entry::boot_info::{BootInfo, HardwareInfo, PlatformInfo, RawBootInfo, SerialPortBase}; +use hermit_entry::boot_info::{ + BootInfo, DeviceTreeAddress, HardwareInfo, PlatformInfo, RawBootInfo, SerialPortBase, +}; use hermit_entry::elf::LoadedKernel; #[cfg(all(target_os = "none", feature = "fc"))] use hermit_entry::fc::{ @@ -27,6 +31,8 @@ use multiboot::information::{Multiboot, PAddr}; use uart_16550::SerialPort; use x86_64::structures::paging::{PageSize, PageTableFlags, Size2MiB, Size4KiB}; +#[cfg(all(target_os = "none", not(feature = "fc")))] +use self::fdt::DeviceTree; use self::physicalmem::PhysAlloc; #[cfg(target_os = "none")] @@ -463,6 +469,8 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { ); } + let device_tree = DeviceTree::new().expect("Unable to create devicetree!"); + static mut BOOT_INFO: Option = None; let boot_info = { @@ -470,7 +478,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { hardware_info: HardwareInfo { phys_addr_range: 0..0, serial_port_base: SerialPortBase::new(SERIAL_IO_PORT), - device_tree: None, + device_tree: DeviceTreeAddress::new(device_tree.as_ptr() as u64), }, load_info, platform_info: PlatformInfo::Multiboot { diff --git a/src/main.rs b/src/main.rs index fe4bf1c0..3d502c44 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ #![warn(unsafe_op_in_unsafe_fn)] #![allow(unstable_name_collisions)] #![allow(clippy::missing_safety_doc)] +#![allow(clippy::new_ret_no_self)] #[macro_use] mod macros;