use core::slice;
use os_bootinfo::{E820MemoryRegion, MemoryMap, MemoryRegion, MemoryRegionType};
use usize_conversions::usize_from;
use x86_64::VirtAddr;
pub(crate) fn create_from(memory_map_addr: VirtAddr, entry_count: u64) -> MemoryMap {
let memory_map_start_ptr = usize_from(memory_map_addr.as_u64()) as *const E820MemoryRegion;
let e820_memory_map =
unsafe { slice::from_raw_parts(memory_map_start_ptr, usize_from(entry_count)) };
let mut memory_map = MemoryMap::new();
for region in e820_memory_map {
memory_map.add_region(MemoryRegion::from(*region));
}
memory_map.sort();
let mut iter = memory_map.iter_mut().peekable();
while let Some(region) = iter.next() {
if let Some(next) = iter.peek() {
if region.range.end_frame_number > next.range.start_frame_number {
if region.region_type == MemoryRegionType::Usable {
region.range.end_frame_number = next.range.start_frame_number;
} else {
panic!("two non-usable regions overlap: {:?} {:?}", region, next);
}
}
}
}
memory_map
}