@@ -221,37 +221,46 @@ impl BootServices {
221221 mmm
222222 }
223223
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`].
241226 ///
242227 /// # Errors
243228 ///
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.
245231 ///
246232 /// * [`uefi::Status::BUFFER_TOO_SMALL`]
247233 /// * [`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 > ( ) ;
252261 let mut map_key = MemoryMapKey ( 0 ) ;
253262 let mut desc_size = 0 ;
254- let mut entry_version = 0 ;
263+ let mut desc_version = 0 ;
255264
256265 assert_eq ! (
257266 ( map_buffer as usize ) % mem:: align_of:: <MemoryDescriptor >( ) ,
@@ -265,18 +274,14 @@ impl BootServices {
265274 map_buffer,
266275 & mut map_key. 0 ,
267276 & mut desc_size,
268- & mut entry_version ,
277+ & mut desc_version ,
269278 )
270279 }
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,
280285 } )
281286 }
282287
@@ -1689,6 +1694,14 @@ impl MemoryMapBackingMemory {
16891694 Self ( slice)
16901695 }
16911696
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+
16921705 /// Returns a "safe" best-effort size hint for the memory map size with
16931706 /// some additional bytes in buffer compared to the [`MemoryMapMeta`].
16941707 /// This helps
@@ -1703,8 +1716,15 @@ impl MemoryMapBackingMemory {
17031716 mmm. map_size + extra_size
17041717 }
17051718
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 {
17081728 self . 0 . as_ptr ( ) . cast ( )
17091729 }
17101730
@@ -1788,31 +1808,27 @@ impl MemoryMapMeta {
17881808///
17891809/// [0]: https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
17901810#[ derive( Debug ) ]
1791- pub struct MemoryMap < ' buf > {
1811+ pub struct MemoryMap {
1812+ /// Backing memory, properly initialized at this point.
1813+ buf : MemoryMapBackingMemory ,
17921814 key : MemoryMapKey ,
1793- buf : & ' buf mut [ u8 ] ,
17941815 /// Usually bound to the size of a [`MemoryDescriptor`] but can indicate if
17951816 /// this field is ever extended by a new UEFI standard.
17961817 desc_size : usize ,
17971818 len : usize ,
17981819}
17991820
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;
18141830 assert ! ( desc_size >= mem:: size_of:: <MemoryDescriptor >( ) ) ;
1815- let len = buf . len ( ) / desc_size;
1831+ let len = map_size / desc_size;
18161832 MemoryMap {
18171833 key : MemoryMapKey ( 0 ) ,
18181834 buf,
@@ -1821,6 +1837,20 @@ impl<'buf> MemoryMap<'buf> {
18211837 }
18221838 }
18231839
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+
18241854 #[ must_use]
18251855 /// Returns the unique [`MemoryMapKey`] associated with the memory map.
18261856 pub fn key ( & self ) -> MemoryMapKey {
@@ -1915,7 +1945,7 @@ impl<'buf> MemoryMap<'buf> {
19151945
19161946 /// Returns a reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
19171947 #[ must_use]
1918- pub fn get ( & self , index : usize ) -> Option < & ' buf MemoryDescriptor > {
1948+ pub fn get ( & self , index : usize ) -> Option < & MemoryDescriptor > {
19191949 if index >= self . len {
19201950 return None ;
19211951 }
@@ -1933,7 +1963,7 @@ impl<'buf> MemoryMap<'buf> {
19331963
19341964 /// Returns a mut reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
19351965 #[ 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 > {
19371967 if index >= self . len {
19381968 return None ;
19391969 }
@@ -1950,15 +1980,15 @@ impl<'buf> MemoryMap<'buf> {
19501980 }
19511981}
19521982
1953- impl core:: ops:: Index < usize > for MemoryMap < ' _ > {
1983+ impl core:: ops:: Index < usize > for MemoryMap {
19541984 type Output = MemoryDescriptor ;
19551985
19561986 fn index ( & self , index : usize ) -> & Self :: Output {
19571987 self . get ( index) . unwrap ( )
19581988 }
19591989}
19601990
1961- impl core:: ops:: IndexMut < usize > for MemoryMap < ' _ > {
1991+ impl core:: ops:: IndexMut < usize > for MemoryMap {
19621992 fn index_mut ( & mut self , index : usize ) -> & mut Self :: Output {
19631993 self . get_mut ( index) . unwrap ( )
19641994 }
@@ -1967,13 +1997,13 @@ impl core::ops::IndexMut<usize> for MemoryMap<'_> {
19671997/// An iterator of [`MemoryDescriptor`]. The underlying memory map is always
19681998/// associated with a unique [`MemoryMapKey`].
19691999#[ derive( Debug , Clone ) ]
1970- pub struct MemoryMapIter < ' buf > {
1971- memory_map : & ' buf MemoryMap < ' buf > ,
2000+ pub struct MemoryMapIter < ' a > {
2001+ memory_map : & ' a MemoryMap ,
19722002 index : usize ,
19732003}
19742004
1975- impl < ' buf > Iterator for MemoryMapIter < ' buf > {
1976- type Item = & ' buf MemoryDescriptor ;
2005+ impl < ' a > Iterator for MemoryMapIter < ' a > {
2006+ type Item = & ' a MemoryDescriptor ;
19772007
19782008 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
19792009 let sz = self . memory_map . len - self . index ;
@@ -2224,7 +2254,7 @@ mod tests {
22242254 }
22252255
22262256 // Added for debug purposes on test failure
2227- impl core:: fmt:: Display for MemoryMap < ' _ > {
2257+ impl core:: fmt:: Display for MemoryMap {
22282258 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
22292259 writeln ! ( f) ?;
22302260 for desc in self . entries ( ) {
0 commit comments