@@ -217,37 +217,46 @@ impl BootServices {
217
217
}
218
218
}
219
219
220
- /// Stores the current UEFI memory map in the provided buffer.
221
- ///
222
- /// The allocated buffer must be at least aligned to a [`MemoryDescriptor`]
223
- /// and should be big enough to store the whole map. To estimating how big
224
- /// the map will be, you can call [`Self::memory_map_size`].
225
- ///
226
- /// The memory map contains entries of type [`MemoryDescriptor`]. However,
227
- /// the relevant step size is always the reported `desc_size` but never
228
- /// `size_of::<MemoryDescriptor>()`.
229
- ///
230
- /// The returned key is a unique identifier of the current configuration of
231
- /// memory. Any allocations or such will change the memory map's key.
232
- ///
233
- /// If you want to store the resulting memory map without having to keep
234
- /// the buffer around, you can use `.copied().collect()` on the iterator.
235
- /// Note that this will change the current memory map again, if the UEFI
236
- /// allocator is used under the hood.
220
+ /// Stores the current UEFI memory map in an UEFI-heap allocated buffer
221
+ /// and returns a [`MemoryMap`].
237
222
///
238
223
/// # Errors
239
224
///
240
- /// See section `EFI_BOOT_SERVICES.GetMemoryMap()` in the UEFI Specification for more details.
225
+ /// See section `EFI_BOOT_SERVICES.GetMemoryMap()` in the UEFI Specification
226
+ /// for more details.
241
227
///
242
228
/// * [`uefi::Status::BUFFER_TOO_SMALL`]
243
229
/// * [`uefi::Status::INVALID_PARAMETER`]
244
- pub fn memory_map < ' buf > ( & self , buffer : & ' buf mut [ u8 ] ) -> Result < MemoryMap < ' buf > > {
245
- let mut map_size = buffer. len ( ) ;
246
- MemoryDescriptor :: assert_aligned ( buffer) ;
247
- let map_buffer = buffer. as_mut_ptr ( ) . cast :: < MemoryDescriptor > ( ) ;
230
+ pub fn memory_map ( & self , mt : MemoryType ) -> Result < MemoryMap > {
231
+ let mut buffer = MemoryMapBackingMemory :: new ( mt) ?;
232
+
233
+ let MemoryMapMeta {
234
+ map_size,
235
+ map_key,
236
+ desc_size,
237
+ desc_version,
238
+ } = self . get_memory_map ( buffer. as_mut_slice ( ) ) ?;
239
+
240
+ let len = map_size / desc_size;
241
+ assert_eq ! ( map_size % desc_size, 0 ) ;
242
+ assert_eq ! ( desc_version, MemoryDescriptor :: VERSION ) ;
243
+ Ok ( MemoryMap {
244
+ key : map_key,
245
+ buf : buffer,
246
+ desc_size,
247
+ len,
248
+ } )
249
+ }
250
+
251
+ /// Calls the underlying `GetMemoryMap` function of UEFI. On success,
252
+ /// the buffer is mutated and contains the map. The map might be shorter
253
+ /// than the buffer, which is reflected by the return value.
254
+ pub ( crate ) fn get_memory_map ( & self , buf : & mut [ u8 ] ) -> Result < MemoryMapMeta > {
255
+ let mut map_size = buf. len ( ) ;
256
+ let map_buffer = buf. as_mut_ptr ( ) . cast :: < MemoryDescriptor > ( ) ;
248
257
let mut map_key = MemoryMapKey ( 0 ) ;
249
258
let mut desc_size = 0 ;
250
- let mut entry_version = 0 ;
259
+ let mut desc_version = 0 ;
251
260
252
261
assert_eq ! (
253
262
( map_buffer as usize ) % mem:: align_of:: <MemoryDescriptor >( ) ,
@@ -261,18 +270,14 @@ impl BootServices {
261
270
map_buffer,
262
271
& mut map_key. 0 ,
263
272
& mut desc_size,
264
- & mut entry_version ,
273
+ & mut desc_version ,
265
274
)
266
275
}
267
- . to_result_with_val ( move || {
268
- let len = map_size / desc_size;
269
-
270
- MemoryMap {
271
- key : map_key,
272
- buf : buffer,
273
- desc_size,
274
- len,
275
- }
276
+ . to_result_with_val ( || MemoryMapMeta {
277
+ map_size,
278
+ desc_size,
279
+ map_key,
280
+ desc_version,
276
281
} )
277
282
}
278
283
@@ -1676,9 +1681,17 @@ impl MemoryMapBackingMemory {
1676
1681
assert_eq ! ( ptr. align_offset( mem:: align_of:: <MemoryDescriptor >( ) ) , 0 ) ;
1677
1682
1678
1683
let ptr = NonNull :: new ( ptr) . expect ( "UEFI should never return a null ptr. An error should have been reflected via an Err earlier." ) ;
1679
- let slice = NonNull :: slice_from_raw_parts ( ptr, alloc_size) ;
1684
+ let slice = NonNull :: slice_from_raw_parts ( ptr, len) ;
1685
+
1686
+ Self ( slice)
1687
+ }
1680
1688
1681
- Ok ( Self ( slice) )
1689
+ /// Creates an instance from the provided memory, which is not necessarily
1690
+ /// on the UEFI heap.
1691
+ #[ cfg( test) ]
1692
+ fn from_slice ( buffer : & mut [ u8 ] ) -> Self {
1693
+ let len = buffer. len ( ) ;
1694
+ Self :: from_raw ( buffer. as_mut_ptr ( ) , len)
1682
1695
}
1683
1696
1684
1697
/// Returns a best-effort size hint of the memory map size. This is
@@ -1712,8 +1725,15 @@ impl MemoryMapBackingMemory {
1712
1725
map_size + extra_size
1713
1726
}
1714
1727
1715
- /// Returns the raw pointer to the beginning of the allocation.
1716
- pub fn as_ptr_mut ( & mut self ) -> * mut u8 {
1728
+ /// Returns a raw pointer to the beginning of the allocation.
1729
+ #[ must_use]
1730
+ pub fn as_ptr ( & self ) -> * const u8 {
1731
+ self . 0 . as_ptr ( ) . cast ( )
1732
+ }
1733
+
1734
+ /// Returns a mutable raw pointer to the beginning of the allocation.
1735
+ #[ must_use]
1736
+ pub fn as_mut_ptr ( & mut self ) -> * mut u8 {
1717
1737
self . 0 . as_ptr ( ) . cast ( )
1718
1738
}
1719
1739
@@ -1782,31 +1802,27 @@ impl MemoryMapMeta {
1782
1802
///
1783
1803
/// [0]: https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
1784
1804
#[ derive( Debug ) ]
1785
- pub struct MemoryMap < ' buf > {
1805
+ pub struct MemoryMap {
1806
+ /// Backing memory, properly initialized at this point.
1807
+ buf : MemoryMapBackingMemory ,
1786
1808
key : MemoryMapKey ,
1787
- buf : & ' buf mut [ u8 ] ,
1788
1809
/// Usually bound to the size of a [`MemoryDescriptor`] but can indicate if
1789
1810
/// this field is ever extended by a new UEFI standard.
1790
1811
desc_size : usize ,
1791
1812
len : usize ,
1792
1813
}
1793
1814
1794
- impl < ' buf > MemoryMap < ' buf > {
1795
- /// Creates a [`MemoryMap`] from the given buffer and entry size.
1796
- /// The entry size is usually bound to the size of a [`MemoryDescriptor`]
1797
- /// but can indicate if this field is ever extended by a new UEFI standard.
1798
- ///
1799
- /// This allows parsing a memory map provided by a kernel after boot
1800
- /// services have already exited.
1801
- pub fn from_raw ( buf : & ' buf mut [ u8 ] , desc_size : usize ) -> Self {
1802
- assert ! ( !buf. is_empty( ) ) ;
1803
- assert_eq ! (
1804
- buf. len( ) % desc_size,
1805
- 0 ,
1806
- "The buffer length must be a multiple of the desc_size"
1807
- ) ;
1815
+ impl MemoryMap {
1816
+ /// Creates a [`MemoryMap`] from the give initialized memory map behind
1817
+ /// the buffer and the reported `desc_size` from UEFI.
1818
+ pub ( crate ) fn from_initialized_mem ( buf : MemoryMapBackingMemory , meta : MemoryMapMeta ) -> Self {
1819
+ let MemoryMapMeta {
1820
+ map_size,
1821
+ desc_size,
1822
+ ..
1823
+ } = meta;
1808
1824
assert ! ( desc_size >= mem:: size_of:: <MemoryDescriptor >( ) ) ;
1809
- let len = buf . len ( ) / desc_size;
1825
+ let len = map_size / desc_size;
1810
1826
MemoryMap {
1811
1827
key : MemoryMapKey ( 0 ) ,
1812
1828
buf,
@@ -1815,6 +1831,20 @@ impl<'buf> MemoryMap<'buf> {
1815
1831
}
1816
1832
}
1817
1833
1834
+ #[ cfg( test) ]
1835
+ fn from_raw ( buf : & mut [ u8 ] , desc_size : usize ) -> Self {
1836
+ let mem = MemoryMapBackingMemory :: from_slice ( buf) ;
1837
+ Self :: from_initialized_mem (
1838
+ mem,
1839
+ MemoryMapMeta {
1840
+ map_size : buf. len ( ) ,
1841
+ desc_size,
1842
+ map_key : MemoryMapKey ( 0 ) ,
1843
+ desc_version : MemoryDescriptor :: VERSION ,
1844
+ } ,
1845
+ )
1846
+ }
1847
+
1818
1848
#[ must_use]
1819
1849
/// Returns the unique [`MemoryMapKey`] associated with the memory map.
1820
1850
pub fn key ( & self ) -> MemoryMapKey {
@@ -1909,7 +1939,7 @@ impl<'buf> MemoryMap<'buf> {
1909
1939
1910
1940
/// Returns a reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1911
1941
#[ must_use]
1912
- pub fn get ( & self , index : usize ) -> Option < & ' buf MemoryDescriptor > {
1942
+ pub fn get ( & self , index : usize ) -> Option < & MemoryDescriptor > {
1913
1943
if index >= self . len {
1914
1944
return None ;
1915
1945
}
@@ -1927,7 +1957,7 @@ impl<'buf> MemoryMap<'buf> {
1927
1957
1928
1958
/// Returns a mut reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1929
1959
#[ must_use]
1930
- pub fn get_mut ( & mut self , index : usize ) -> Option < & ' buf mut MemoryDescriptor > {
1960
+ pub fn get_mut ( & mut self , index : usize ) -> Option < & mut MemoryDescriptor > {
1931
1961
if index >= self . len {
1932
1962
return None ;
1933
1963
}
@@ -1944,15 +1974,15 @@ impl<'buf> MemoryMap<'buf> {
1944
1974
}
1945
1975
}
1946
1976
1947
- impl core:: ops:: Index < usize > for MemoryMap < ' _ > {
1977
+ impl core:: ops:: Index < usize > for MemoryMap {
1948
1978
type Output = MemoryDescriptor ;
1949
1979
1950
1980
fn index ( & self , index : usize ) -> & Self :: Output {
1951
1981
self . get ( index) . unwrap ( )
1952
1982
}
1953
1983
}
1954
1984
1955
- impl core:: ops:: IndexMut < usize > for MemoryMap < ' _ > {
1985
+ impl core:: ops:: IndexMut < usize > for MemoryMap {
1956
1986
fn index_mut ( & mut self , index : usize ) -> & mut Self :: Output {
1957
1987
self . get_mut ( index) . unwrap ( )
1958
1988
}
@@ -1961,13 +1991,13 @@ impl core::ops::IndexMut<usize> for MemoryMap<'_> {
1961
1991
/// An iterator of [`MemoryDescriptor`]. The underlying memory map is always
1962
1992
/// associated with a unique [`MemoryMapKey`].
1963
1993
#[ derive( Debug , Clone ) ]
1964
- pub struct MemoryMapIter < ' buf > {
1965
- memory_map : & ' buf MemoryMap < ' buf > ,
1994
+ pub struct MemoryMapIter < ' a > {
1995
+ memory_map : & ' a MemoryMap ,
1966
1996
index : usize ,
1967
1997
}
1968
1998
1969
- impl < ' buf > Iterator for MemoryMapIter < ' buf > {
1970
- type Item = & ' buf MemoryDescriptor ;
1999
+ impl < ' a > Iterator for MemoryMapIter < ' a > {
2000
+ type Item = & ' a MemoryDescriptor ;
1971
2001
1972
2002
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1973
2003
let sz = self . memory_map . len - self . index ;
@@ -2218,7 +2248,7 @@ mod tests {
2218
2248
}
2219
2249
2220
2250
// Added for debug purposes on test failure
2221
- impl core:: fmt:: Display for MemoryMap < ' _ > {
2251
+ impl core:: fmt:: Display for MemoryMap {
2222
2252
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
2223
2253
writeln ! ( f) ?;
2224
2254
for desc in self . entries ( ) {
0 commit comments