Skip to content

Commit 2cb3ff0

Browse files
committed
uefi: mem: add public constructors for MemoryMapRef and MemoryMapRefMut
There is no public constructor for MemoryMapOwned, as the construction of it is quite complicated and therefore hidden behind BootServices::memory_map() respectively SystemTable::exit_boot_services. The real-world use case for the public constructors for the other types is when parsing the UEFI memory map from kernels after a bootloader, such as GRUB or Limine, passed the UEFI memory map via the corresponding boot information.
1 parent e81dac9 commit 2cb3ff0

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

uefi/src/mem/memory_map/impl_.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,60 @@
33
44
use super::*;
55
use crate::table::system_table_boot;
6+
use core::fmt::{Debug, Display, Formatter};
67
use core::ops::{Index, IndexMut};
78
use core::ptr::NonNull;
89
use core::{mem, ptr};
910
use uefi_raw::PhysicalAddress;
1011

12+
/// Errors that may happen when constructing a [`MemoryMapRef`] or
13+
/// [`MemoryMapRefMut`].
14+
#[derive(Copy, Clone, Debug)]
15+
pub enum MemoryMapError {
16+
/// The buffer is not 8-byte aligned.
17+
Misaligned,
18+
/// The memory map size is invalid.
19+
InvalidSize,
20+
}
21+
22+
impl Display for MemoryMapError {
23+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
24+
Debug::fmt(self, f)
25+
}
26+
}
27+
28+
#[cfg(feature = "unstable")]
29+
impl core::error::Error for MemoryMapError {}
30+
1131
/// Implementation of [`MemoryMap`] for the given buffer.
1232
#[derive(Debug)]
13-
#[allow(dead_code)] // TODO: github.com/rust-osdev/uefi-rs/issues/1247
1433
pub struct MemoryMapRef<'a> {
1534
buf: &'a [u8],
1635
meta: MemoryMapMeta,
1736
len: usize,
1837
}
1938

39+
impl<'a> MemoryMapRef<'a> {
40+
/// Constructs a new [`MemoryMapRef`].
41+
///
42+
/// The underlying memory might contain an invalid/malformed memory map
43+
/// which can't be checked during construction of this type. The entry
44+
/// iterator might yield unexpected results.
45+
pub fn new(buffer: &'a [u8], meta: MemoryMapMeta) -> Result<Self, MemoryMapError> {
46+
if buffer.as_ptr().align_offset(8) != 0 {
47+
return Err(MemoryMapError::Misaligned);
48+
}
49+
if buffer.len() < meta.map_size {
50+
return Err(MemoryMapError::InvalidSize);
51+
}
52+
Ok(Self {
53+
buf: buffer,
54+
meta,
55+
len: meta.entry_count(),
56+
})
57+
}
58+
}
59+
2060
impl<'a> MemoryMap for MemoryMapRef<'a> {
2161
fn meta(&self) -> MemoryMapMeta {
2262
self.meta
@@ -58,6 +98,27 @@ pub struct MemoryMapRefMut<'a> {
5898
len: usize,
5999
}
60100

101+
impl<'a> MemoryMapRefMut<'a> {
102+
/// Constructs a new [`MemoryMapRefMut`].
103+
///
104+
/// The underlying memory might contain an invalid/malformed memory map
105+
/// which can't be checked during construction of this type. The entry
106+
/// iterator might yield unexpected results.
107+
pub fn new(buffer: &'a mut [u8], meta: MemoryMapMeta) -> Result<Self, MemoryMapError> {
108+
if buffer.as_ptr().align_offset(8) != 0 {
109+
return Err(MemoryMapError::Misaligned);
110+
}
111+
if buffer.len() < meta.map_size {
112+
return Err(MemoryMapError::InvalidSize);
113+
}
114+
Ok(Self {
115+
buf: buffer,
116+
meta,
117+
len: meta.entry_count(),
118+
})
119+
}
120+
}
121+
61122
impl<'a> MemoryMap for MemoryMapRefMut<'a> {
62123
fn meta(&self) -> MemoryMapMeta {
63124
self.meta

0 commit comments

Comments
 (0)