Skip to content

Commit 30db89e

Browse files
Merge pull request #966 from JarlEvanson/main
Allow indexing of `MemoryMap`.
2 parents 7e36d22 + de463d9 commit 30db89e

File tree

2 files changed

+130
-38
lines changed

2 files changed

+130
-38
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## uefi - [Unreleased]
44

5+
### Added
6+
- Implemented `Index`, `IndexMut`, `get`, and `get_mut` on `MemoryMap`.
7+
58
### Changed
69
- We fixed a memory leak in `GraphicsOutput::query_mode`. As a consequence, we
710
had to add `&BootServices` as additional parameter.

uefi/src/table/boot.rs

+127-38
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,10 @@ pub struct MemoryMapSize {
16251625
pub map_size: usize,
16261626
}
16271627

1628-
/// An iterator of [`MemoryDescriptor`] that is always associated with the
1628+
/// An accessory to the memory map that can be either iterated or
1629+
/// indexed like an array.
1630+
///
1631+
/// A [`MemoryMap`] is always associated with the
16291632
/// unique [`MemoryMapKey`] contained in the struct.
16301633
///
16311634
/// To iterate over the entries, call [`MemoryMap::entries`]. To get a sorted
@@ -1720,55 +1723,91 @@ impl<'buf> MemoryMap<'buf> {
17201723
#[must_use]
17211724
pub fn entries(&self) -> MemoryMapIter {
17221725
MemoryMapIter {
1723-
buffer: self.buf,
1724-
entry_size: self.entry_size,
1726+
memory_map: self,
17251727
index: 0,
1726-
len: self.len,
17271728
}
17281729
}
1730+
1731+
/// Returns a reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1732+
#[must_use]
1733+
pub fn get(&self, index: usize) -> Option<&'buf MemoryDescriptor> {
1734+
if index >= self.len {
1735+
return None;
1736+
}
1737+
1738+
let desc = unsafe {
1739+
&*self
1740+
.buf
1741+
.as_ptr()
1742+
.add(self.entry_size * index)
1743+
.cast::<MemoryDescriptor>()
1744+
};
1745+
1746+
Some(desc)
1747+
}
1748+
1749+
/// Returns a mut reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1750+
#[must_use]
1751+
pub fn get_mut(&mut self, index: usize) -> Option<&'buf mut MemoryDescriptor> {
1752+
if index >= self.len {
1753+
return None;
1754+
}
1755+
1756+
let desc = unsafe {
1757+
&mut *self
1758+
.buf
1759+
.as_mut_ptr()
1760+
.add(self.entry_size * index)
1761+
.cast::<MemoryDescriptor>()
1762+
};
1763+
1764+
Some(desc)
1765+
}
1766+
}
1767+
1768+
impl core::ops::Index<usize> for MemoryMap<'_> {
1769+
type Output = MemoryDescriptor;
1770+
1771+
fn index(&self, index: usize) -> &Self::Output {
1772+
self.get(index).unwrap()
1773+
}
1774+
}
1775+
1776+
impl core::ops::IndexMut<usize> for MemoryMap<'_> {
1777+
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1778+
self.get_mut(index).unwrap()
1779+
}
17291780
}
17301781

17311782
/// An iterator of [`MemoryDescriptor`]. The underlying memory map is always
17321783
/// associated with a unique [`MemoryMapKey`].
17331784
#[derive(Debug, Clone)]
17341785
pub struct MemoryMapIter<'buf> {
1735-
buffer: &'buf [u8],
1736-
entry_size: usize,
1786+
memory_map: &'buf MemoryMap<'buf>,
17371787
index: usize,
1738-
len: usize,
17391788
}
17401789

17411790
impl<'buf> Iterator for MemoryMapIter<'buf> {
17421791
type Item = &'buf MemoryDescriptor;
17431792

17441793
fn size_hint(&self) -> (usize, Option<usize>) {
1745-
let sz = self.len - self.index;
1794+
let sz = self.memory_map.len - self.index;
17461795

17471796
(sz, Some(sz))
17481797
}
17491798

17501799
fn next(&mut self) -> Option<Self::Item> {
1751-
if self.index < self.len {
1752-
let descriptor = unsafe {
1753-
&*self
1754-
.buffer
1755-
.as_ptr()
1756-
.add(self.entry_size * self.index)
1757-
.cast::<MemoryDescriptor>()
1758-
};
1759-
1760-
self.index += 1;
1761-
1762-
Some(descriptor)
1763-
} else {
1764-
None
1765-
}
1800+
let desc = self.memory_map.get(self.index)?;
1801+
1802+
self.index += 1;
1803+
1804+
Some(desc)
17661805
}
17671806
}
17681807

17691808
impl ExactSizeIterator for MemoryMapIter<'_> {
17701809
fn len(&self) -> usize {
1771-
self.len
1810+
self.memory_map.len
17721811
}
17731812
}
17741813

@@ -1905,6 +1944,23 @@ mod tests {
19051944

19061945
use super::{MemoryDescriptor, MemoryMapIter};
19071946

1947+
fn buffer_to_map(buffer: &mut [MemoryDescriptor]) -> MemoryMap {
1948+
let desc_count = buffer.len();
1949+
1950+
let byte_buffer = {
1951+
let size = desc_count * size_of::<MemoryDescriptor>();
1952+
unsafe { core::slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut u8, size) }
1953+
};
1954+
1955+
MemoryMap {
1956+
// Key doesn't matter
1957+
key: MemoryMapKey(0),
1958+
len: desc_count,
1959+
buf: byte_buffer,
1960+
entry_size: size_of::<MemoryDescriptor>(),
1961+
}
1962+
}
1963+
19081964
#[test]
19091965
fn mem_map_sorting() {
19101966
// Doesn't matter what type it is.
@@ -1934,20 +1990,7 @@ mod tests {
19341990
},
19351991
];
19361992

1937-
let desc_count = buffer.len();
1938-
1939-
let byte_buffer = {
1940-
let size = desc_count * size_of::<MemoryDescriptor>();
1941-
unsafe { core::slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut u8, size) }
1942-
};
1943-
1944-
let mut mem_map = MemoryMap {
1945-
// Key doesn't matter
1946-
key: MemoryMapKey(0),
1947-
len: desc_count,
1948-
buf: byte_buffer,
1949-
entry_size: size_of::<MemoryDescriptor>(),
1950-
};
1993+
let mut mem_map = buffer_to_map(&mut buffer);
19511994

19521995
mem_map.sort();
19531996

@@ -1956,6 +1999,52 @@ mod tests {
19561999
}
19572000
}
19582001

2002+
#[test]
2003+
fn mem_map_get() {
2004+
// Doesn't matter what type it is.
2005+
const TY: MemoryType = MemoryType::RESERVED;
2006+
2007+
const BASE: MemoryDescriptor = MemoryDescriptor {
2008+
ty: TY,
2009+
phys_start: 0,
2010+
virt_start: 0,
2011+
page_count: 0,
2012+
att: MemoryAttribute::empty(),
2013+
};
2014+
2015+
const BUFFER: [MemoryDescriptor; 4] = [
2016+
MemoryDescriptor {
2017+
phys_start: 2000,
2018+
..BASE
2019+
},
2020+
MemoryDescriptor {
2021+
phys_start: 3000,
2022+
..BASE
2023+
},
2024+
BASE,
2025+
MemoryDescriptor {
2026+
phys_start: 1000,
2027+
..BASE
2028+
},
2029+
];
2030+
2031+
let mut buffer = BUFFER;
2032+
2033+
let mut mem_map = buffer_to_map(&mut buffer);
2034+
2035+
for index in 0..3 {
2036+
assert_eq!(mem_map.get(index), BUFFER.get(index))
2037+
}
2038+
2039+
let mut_desc = mem_map.get_mut(2).unwrap();
2040+
2041+
mut_desc.phys_start = 300;
2042+
2043+
let desc = mem_map.get(2).unwrap();
2044+
2045+
assert_ne!(*desc, BUFFER[2]);
2046+
}
2047+
19592048
// Added for debug purposes on test failure
19602049
impl core::fmt::Display for MemoryMap<'_> {
19612050
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {

0 commit comments

Comments
 (0)