pie_boot_if/
memregions.rs

1use core::{fmt, ops, slice};
2
3#[derive(Clone, Copy)]
4pub struct MemoryRegion {
5    /// The physical start address of the region.
6    pub start: usize,
7    /// The physical end address (exclusive) of the region.
8    pub end: usize,
9    /// The memory type of the memory region.
10    ///
11    /// Only [`Usable`][MemoryRegionKind::Usable] regions can be freely used.
12    pub kind: MemoryRegionKind,
13}
14
15impl fmt::Debug for MemoryRegion {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        f.debug_struct("MemoryRegion")
18            .field("start", &(self.start as *const u8))
19            .field("end", &(self.end as *const u8))
20            .field("kind", &self.kind)
21            .finish()
22    }
23}
24
25/// Represents the different types of memory.
26#[derive(Debug, Copy, Clone, Eq, PartialEq)]
27#[non_exhaustive]
28#[repr(C)]
29pub enum MemoryRegionKind {
30    /// Physical memory
31    Ram,
32    /// Reserved memory
33    Reserved,
34    /// Memory mappings created by the bootloader, including the page table and boot info mappings.
35    ///
36    /// This memory should _not_ be used by the kernel.
37    Bootloader,
38    /// An unknown memory region reported by the UEFI firmware.
39    ///
40    /// Contains the UEFI memory type tag.
41    UnknownUefi(u32),
42    /// An unknown memory region reported by the BIOS firmware.
43    ///
44    /// Contains the E820 memory type.
45    UnknownBios(u32),
46}
47
48/// FFI-safe slice of [`MemoryRegion`] structs, semantically equivalent to
49/// `&'static mut [MemoryRegion]`.
50///
51/// This type implements the [`Deref`][core::ops::Deref] and [`DerefMut`][core::ops::DerefMut]
52/// traits, so it can be used like a `&mut [MemoryRegion]` slice. It also implements [`From`]
53/// and [`Into`] for easy conversions from and to `&'static mut [MemoryRegion]`.
54#[derive(Clone)]
55#[repr(C)]
56pub struct MemoryRegions {
57    pub(crate) ptr: *mut MemoryRegion,
58    pub(crate) len: usize,
59}
60
61impl ops::Deref for MemoryRegions {
62    type Target = [MemoryRegion];
63
64    fn deref(&self) -> &Self::Target {
65        unsafe { slice::from_raw_parts(self.ptr, self.len) }
66    }
67}
68
69impl ops::DerefMut for MemoryRegions {
70    fn deref_mut(&mut self) -> &mut Self::Target {
71        unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
72    }
73}
74
75impl From<&'static mut [MemoryRegion]> for MemoryRegions {
76    fn from(regions: &'static mut [MemoryRegion]) -> Self {
77        MemoryRegions {
78            ptr: regions.as_mut_ptr(),
79            len: regions.len(),
80        }
81    }
82}
83
84impl From<MemoryRegions> for &'static mut [MemoryRegion] {
85    fn from(regions: MemoryRegions) -> &'static mut [MemoryRegion] {
86        unsafe { slice::from_raw_parts_mut(regions.ptr, regions.len) }
87    }
88}
89
90impl fmt::Debug for MemoryRegions {
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        writeln!(f, "MemoryRegions [")?;
93        if !self.ptr.is_null() {
94            for region in self.iter() {
95                writeln!(f, "{region:?}")?;
96            }
97        }
98        writeln!(f, "]")
99    }
100}
101
102unsafe impl Send for MemoryRegions {}
103unsafe impl Sync for MemoryRegions {}