use alloc::vec::Vec;
use align_ext::AlignExt;
use crate::{boot::memory_region::MemoryRegionType, io::IoMemAllocatorBuilder};
pub(crate) mod io_mem;
#[cfg(feature = "cvm_guest")]
pub(crate) mod cvm;
pub(super) unsafe fn construct_io_mem_allocator_builder() -> IoMemAllocatorBuilder {
let regions = &crate::boot::EARLY_INFO.get().unwrap().memory_regions;
let mut ranges = Vec::with_capacity(2);
let reserved_filter = regions.iter().filter(|r| {
r.typ() != MemoryRegionType::Unknown
&& r.typ() != MemoryRegionType::Reserved
&& r.typ() != MemoryRegionType::Framebuffer
});
const LOW_MMIO_TOP: usize = 0x1_0000_0000; const LOW_MMIO_ALIGN: usize = 0x10_0000; let (lower_half_base, lower_half_len) = reserved_filter
.clone()
.filter(|r| r.base() < LOW_MMIO_TOP)
.max_by(|a, b| a.base().cmp(&b.base()))
.map(|reg| (reg.base(), reg.len()))
.unwrap();
let mmio_start_addr = (lower_half_base + lower_half_len).align_up(LOW_MMIO_ALIGN);
assert!(mmio_start_addr < LOW_MMIO_TOP);
ranges.push(mmio_start_addr..LOW_MMIO_TOP);
const HIGH_MMIO_TOP: usize = 0x10_0000_0000_0000; const HIGH_MMIO_ALIGN: usize = 0x10_0000; let (upper_half_base, upper_half_len) = reserved_filter
.filter(|r| r.base() >= LOW_MMIO_TOP)
.max_by(|a, b| a.base().cmp(&b.base()))
.map(|reg| (reg.base(), reg.len()))
.unwrap_or((LOW_MMIO_TOP, 0));
let mmio_start_addr = (upper_half_base + upper_half_len).align_up(HIGH_MMIO_ALIGN);
assert!(mmio_start_addr < HIGH_MMIO_TOP);
ranges.push(mmio_start_addr..HIGH_MMIO_TOP);
unsafe { IoMemAllocatorBuilder::new(ranges) }
}
pub const MAX_IO_PORT: u16 = u16::MAX;