Skip to content

Commit

Permalink
Detect memory from fdt
Browse files Browse the repository at this point in the history
  • Loading branch information
duanyu-yu committed Feb 19, 2024
1 parent 8dfeca1 commit bae3da1
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bitflags = "2.4"
cfg-if = "1"
crossbeam-utils = { version = "0.8", default-features = false }
dyn-clone = "1.0"
fdt = "0.1"
hashbrown = { version = "0.14", default-features = false }
hermit-entry = { version = "0.9", features = ["kernel"] }
hermit-sync = "0.1"
Expand Down Expand Up @@ -132,7 +133,6 @@ hermit-dtb = { version = "0.1" }
semihosting = { version = "0.1", optional = true }

[target.'cfg(target_arch = "riscv64")'.dependencies]
fdt = "0.1"
riscv = "0.11"
sbi = "0.2"
trapframe = "0.9"
Expand Down
4 changes: 4 additions & 0 deletions src/arch/x86_64/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ pub fn get_mbinfo() -> VirtAddr {
}
}

pub fn get_fdt() -> usize {
boot_info().hardware_info.device_tree.unwrap().get() as usize
}

#[cfg(feature = "smp")]
pub fn get_possible_cpus() -> u32 {
use core::cmp;
Expand Down
46 changes: 44 additions & 2 deletions src/arch/x86_64/mm/physicalmem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ::x86_64::structures::paging::{FrameAllocator, PhysFrame};
use hermit_sync::InterruptTicketMutex;
use multiboot::information::{MemoryType, Multiboot};

use crate::arch::x86_64::kernel::{get_limit, get_mbinfo};
use crate::arch::x86_64::kernel::{get_fdt, get_limit, get_mbinfo};
use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize};
use crate::arch::x86_64::mm::{MultibootMemory, PhysAddr, VirtAddr};
use crate::mm;
Expand All @@ -19,6 +19,47 @@ const KVM_32BIT_MAX_MEM_SIZE: usize = 1 << 32;
const KVM_32BIT_GAP_SIZE: usize = 768 << 20;
const KVM_32BIT_GAP_START: usize = KVM_32BIT_MAX_MEM_SIZE - KVM_32BIT_GAP_SIZE;

fn detect_from_fdt() -> Result<(), ()> {
let fdt = unsafe { fdt::Fdt::from_ptr(get_fdt() as *const u8).unwrap() };

let mems = fdt.find_all_nodes("/memory");
let all_regions = mems.map(|m| m.reg().unwrap().next().unwrap());

let mut found_ram = false;

for m in all_regions {
let start_address = m.starting_address as u64;
let size = m.size.unwrap() as u64;
let end_address = start_address + size;

if end_address <= mm::kernel_end_address().as_u64() {
continue;
}

found_ram = true;

let start_address = if start_address <= mm::kernel_start_address().as_u64() {
mm::kernel_end_address()
} else {
VirtAddr(start_address)
};

let entry = FreeListEntry::new(start_address.as_usize(), end_address as usize);
let _ = TOTAL_MEMORY.fetch_add(
(end_address - start_address.as_u64()) as usize,
Ordering::SeqCst,
);
PHYSICAL_FREE_LIST.lock().push(entry);
}

assert!(
found_ram,
"Could not find any available RAM in the Devicetree Memory Map"
);

Ok(())
}

fn detect_from_multiboot_info() -> Result<(), ()> {
let mb_info = get_mbinfo();
if mb_info.is_zero() {
Expand Down Expand Up @@ -91,7 +132,8 @@ fn detect_from_limits() -> Result<(), ()> {
}

pub fn init() {
detect_from_multiboot_info()
detect_from_fdt()
.or_else(|_e| detect_from_multiboot_info())
.or_else(|_e| detect_from_limits())
.unwrap();
}
Expand Down

0 comments on commit bae3da1

Please sign in to comment.