@@ -221,37 +221,46 @@ impl BootServices {
221
221
mmm
222
222
}
223
223
224
- /// Stores the current UEFI memory map in the provided buffer.
225
- ///
226
- /// The allocated buffer must be at least aligned to a [`MemoryDescriptor`]
227
- /// and should be big enough to store the whole map. To estimating how big
228
- /// the map will be, you can call [`Self::memory_map_size`].
229
- ///
230
- /// The memory map contains entries of type [`MemoryDescriptor`]. However,
231
- /// the relevant step size is always the reported `desc_size` but never
232
- /// `size_of::<MemoryDescriptor>()`.
233
- ///
234
- /// The returned key is a unique identifier of the current configuration of
235
- /// memory. Any allocations or such will change the memory map's key.
236
- ///
237
- /// If you want to store the resulting memory map without having to keep
238
- /// the buffer around, you can use `.copied().collect()` on the iterator.
239
- /// Note that this will change the current memory map again, if the UEFI
240
- /// allocator is used under the hood.
224
+ /// Stores the current UEFI memory map in an UEFI-heap allocated buffer
225
+ /// and returns a [`MemoryMap`].
241
226
///
242
227
/// # Errors
243
228
///
244
- /// See section `EFI_BOOT_SERVICES.GetMemoryMap()` in the UEFI Specification for more details.
229
+ /// See section `EFI_BOOT_SERVICES.GetMemoryMap()` in the UEFI Specification
230
+ /// for more details.
245
231
///
246
232
/// * [`uefi::Status::BUFFER_TOO_SMALL`]
247
233
/// * [`uefi::Status::INVALID_PARAMETER`]
248
- pub fn memory_map < ' buf > ( & self , buffer : & ' buf mut [ u8 ] ) -> Result < MemoryMap < ' buf > > {
249
- let mut map_size = buffer. len ( ) ;
250
- MemoryDescriptor :: assert_aligned ( buffer) ;
251
- let map_buffer = buffer. as_mut_ptr ( ) . cast :: < MemoryDescriptor > ( ) ;
234
+ pub fn memory_map ( & self , mt : MemoryType ) -> Result < MemoryMap > {
235
+ let mut buffer = MemoryMapBackingMemory :: new ( mt) ?;
236
+
237
+ let MemoryMapMeta {
238
+ map_size,
239
+ map_key,
240
+ desc_size,
241
+ desc_version,
242
+ } = self . get_memory_map ( buffer. as_mut_slice ( ) ) ?;
243
+
244
+ let len = map_size / desc_size;
245
+ assert_eq ! ( map_size % desc_size, 0 ) ;
246
+ assert_eq ! ( desc_version, MemoryDescriptor :: VERSION ) ;
247
+ Ok ( MemoryMap {
248
+ key : map_key,
249
+ buf : buffer,
250
+ desc_size,
251
+ len,
252
+ } )
253
+ }
254
+
255
+ /// Calls the underlying `GetMemoryMap` function of UEFI. On success,
256
+ /// the buffer is mutated and contains the map. The map might be shorter
257
+ /// than the buffer, which is reflected by the return value.
258
+ pub ( crate ) fn get_memory_map ( & self , buf : & mut [ u8 ] ) -> Result < MemoryMapMeta > {
259
+ let mut map_size = buf. len ( ) ;
260
+ let map_buffer = buf. as_mut_ptr ( ) . cast :: < MemoryDescriptor > ( ) ;
252
261
let mut map_key = MemoryMapKey ( 0 ) ;
253
262
let mut desc_size = 0 ;
254
- let mut entry_version = 0 ;
263
+ let mut desc_version = 0 ;
255
264
256
265
assert_eq ! (
257
266
( map_buffer as usize ) % mem:: align_of:: <MemoryDescriptor >( ) ,
@@ -265,18 +274,14 @@ impl BootServices {
265
274
map_buffer,
266
275
& mut map_key. 0 ,
267
276
& mut desc_size,
268
- & mut entry_version ,
277
+ & mut desc_version ,
269
278
)
270
279
}
271
- . to_result_with_val ( move || {
272
- let len = map_size / desc_size;
273
-
274
- MemoryMap {
275
- key : map_key,
276
- buf : buffer,
277
- desc_size,
278
- len,
279
- }
280
+ . to_result_with_val ( || MemoryMapMeta {
281
+ map_size,
282
+ desc_size,
283
+ map_key,
284
+ desc_version,
280
285
} )
281
286
}
282
287
@@ -1689,6 +1694,14 @@ impl MemoryMapBackingMemory {
1689
1694
Self ( slice)
1690
1695
}
1691
1696
1697
+ /// Creates an instance from the provided memory, which is not necessarily
1698
+ /// on the UEFI heap.
1699
+ #[ cfg( test) ]
1700
+ fn from_slice ( buffer : & mut [ u8 ] ) -> Self {
1701
+ let len = buffer. len ( ) ;
1702
+ unsafe { Self :: from_raw ( buffer. as_mut_ptr ( ) , len) }
1703
+ }
1704
+
1692
1705
/// Returns a "safe" best-effort size hint for the memory map size with
1693
1706
/// some additional bytes in buffer compared to the [`MemoryMapMeta`].
1694
1707
/// This helps
@@ -1703,8 +1716,15 @@ impl MemoryMapBackingMemory {
1703
1716
mmm. map_size + extra_size
1704
1717
}
1705
1718
1706
- /// Returns the raw pointer to the beginning of the allocation.
1707
- pub fn as_ptr_mut ( & mut self ) -> * mut u8 {
1719
+ /// Returns a raw pointer to the beginning of the allocation.
1720
+ #[ must_use]
1721
+ pub fn as_ptr ( & self ) -> * const u8 {
1722
+ self . 0 . as_ptr ( ) . cast ( )
1723
+ }
1724
+
1725
+ /// Returns a mutable raw pointer to the beginning of the allocation.
1726
+ #[ must_use]
1727
+ pub fn as_mut_ptr ( & mut self ) -> * mut u8 {
1708
1728
self . 0 . as_ptr ( ) . cast ( )
1709
1729
}
1710
1730
@@ -1788,31 +1808,27 @@ impl MemoryMapMeta {
1788
1808
///
1789
1809
/// [0]: https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
1790
1810
#[ derive( Debug ) ]
1791
- pub struct MemoryMap < ' buf > {
1811
+ pub struct MemoryMap {
1812
+ /// Backing memory, properly initialized at this point.
1813
+ buf : MemoryMapBackingMemory ,
1792
1814
key : MemoryMapKey ,
1793
- buf : & ' buf mut [ u8 ] ,
1794
1815
/// Usually bound to the size of a [`MemoryDescriptor`] but can indicate if
1795
1816
/// this field is ever extended by a new UEFI standard.
1796
1817
desc_size : usize ,
1797
1818
len : usize ,
1798
1819
}
1799
1820
1800
- impl < ' buf > MemoryMap < ' buf > {
1801
- /// Creates a [`MemoryMap`] from the given buffer and entry size.
1802
- /// The entry size is usually bound to the size of a [`MemoryDescriptor`]
1803
- /// but can indicate if this field is ever extended by a new UEFI standard.
1804
- ///
1805
- /// This allows parsing a memory map provided by a kernel after boot
1806
- /// services have already exited.
1807
- pub fn from_raw ( buf : & ' buf mut [ u8 ] , desc_size : usize ) -> Self {
1808
- assert ! ( !buf. is_empty( ) ) ;
1809
- assert_eq ! (
1810
- buf. len( ) % desc_size,
1811
- 0 ,
1812
- "The buffer length must be a multiple of the desc_size"
1813
- ) ;
1821
+ impl MemoryMap {
1822
+ /// Creates a [`MemoryMap`] from the give initialized memory map behind
1823
+ /// the buffer and the reported `desc_size` from UEFI.
1824
+ pub ( crate ) fn from_initialized_mem ( buf : MemoryMapBackingMemory , meta : MemoryMapMeta ) -> Self {
1825
+ let MemoryMapMeta {
1826
+ map_size,
1827
+ desc_size,
1828
+ ..
1829
+ } = meta;
1814
1830
assert ! ( desc_size >= mem:: size_of:: <MemoryDescriptor >( ) ) ;
1815
- let len = buf . len ( ) / desc_size;
1831
+ let len = map_size / desc_size;
1816
1832
MemoryMap {
1817
1833
key : MemoryMapKey ( 0 ) ,
1818
1834
buf,
@@ -1821,6 +1837,20 @@ impl<'buf> MemoryMap<'buf> {
1821
1837
}
1822
1838
}
1823
1839
1840
+ #[ cfg( test) ]
1841
+ fn from_raw ( buf : & mut [ u8 ] , desc_size : usize ) -> Self {
1842
+ let mem = MemoryMapBackingMemory :: from_slice ( buf) ;
1843
+ Self :: from_initialized_mem (
1844
+ mem,
1845
+ MemoryMapMeta {
1846
+ map_size : buf. len ( ) ,
1847
+ desc_size,
1848
+ map_key : MemoryMapKey ( 0 ) ,
1849
+ desc_version : MemoryDescriptor :: VERSION ,
1850
+ } ,
1851
+ )
1852
+ }
1853
+
1824
1854
#[ must_use]
1825
1855
/// Returns the unique [`MemoryMapKey`] associated with the memory map.
1826
1856
pub fn key ( & self ) -> MemoryMapKey {
@@ -1915,7 +1945,7 @@ impl<'buf> MemoryMap<'buf> {
1915
1945
1916
1946
/// Returns a reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1917
1947
#[ must_use]
1918
- pub fn get ( & self , index : usize ) -> Option < & ' buf MemoryDescriptor > {
1948
+ pub fn get ( & self , index : usize ) -> Option < & MemoryDescriptor > {
1919
1949
if index >= self . len {
1920
1950
return None ;
1921
1951
}
@@ -1933,7 +1963,7 @@ impl<'buf> MemoryMap<'buf> {
1933
1963
1934
1964
/// Returns a mut reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1935
1965
#[ must_use]
1936
- pub fn get_mut ( & mut self , index : usize ) -> Option < & ' buf mut MemoryDescriptor > {
1966
+ pub fn get_mut ( & mut self , index : usize ) -> Option < & mut MemoryDescriptor > {
1937
1967
if index >= self . len {
1938
1968
return None ;
1939
1969
}
@@ -1950,15 +1980,15 @@ impl<'buf> MemoryMap<'buf> {
1950
1980
}
1951
1981
}
1952
1982
1953
- impl core:: ops:: Index < usize > for MemoryMap < ' _ > {
1983
+ impl core:: ops:: Index < usize > for MemoryMap {
1954
1984
type Output = MemoryDescriptor ;
1955
1985
1956
1986
fn index ( & self , index : usize ) -> & Self :: Output {
1957
1987
self . get ( index) . unwrap ( )
1958
1988
}
1959
1989
}
1960
1990
1961
- impl core:: ops:: IndexMut < usize > for MemoryMap < ' _ > {
1991
+ impl core:: ops:: IndexMut < usize > for MemoryMap {
1962
1992
fn index_mut ( & mut self , index : usize ) -> & mut Self :: Output {
1963
1993
self . get_mut ( index) . unwrap ( )
1964
1994
}
@@ -1967,13 +1997,13 @@ impl core::ops::IndexMut<usize> for MemoryMap<'_> {
1967
1997
/// An iterator of [`MemoryDescriptor`]. The underlying memory map is always
1968
1998
/// associated with a unique [`MemoryMapKey`].
1969
1999
#[ derive( Debug , Clone ) ]
1970
- pub struct MemoryMapIter < ' buf > {
1971
- memory_map : & ' buf MemoryMap < ' buf > ,
2000
+ pub struct MemoryMapIter < ' a > {
2001
+ memory_map : & ' a MemoryMap ,
1972
2002
index : usize ,
1973
2003
}
1974
2004
1975
- impl < ' buf > Iterator for MemoryMapIter < ' buf > {
1976
- type Item = & ' buf MemoryDescriptor ;
2005
+ impl < ' a > Iterator for MemoryMapIter < ' a > {
2006
+ type Item = & ' a MemoryDescriptor ;
1977
2007
1978
2008
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1979
2009
let sz = self . memory_map . len - self . index ;
@@ -2224,7 +2254,7 @@ mod tests {
2224
2254
}
2225
2255
2226
2256
// Added for debug purposes on test failure
2227
- impl core:: fmt:: Display for MemoryMap < ' _ > {
2257
+ impl core:: fmt:: Display for MemoryMap {
2228
2258
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
2229
2259
writeln ! ( f) ?;
2230
2260
for desc in self . entries ( ) {
0 commit comments