@@ -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
@@ -1780,31 +1800,27 @@ impl MemoryMapMeta {
1780
1800
///
1781
1801
/// [0]: https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
1782
1802
#[ derive( Debug ) ]
1783
- pub struct MemoryMap < ' buf > {
1803
+ pub struct MemoryMap {
1804
+ /// Backing memory, properly initialized at this point.
1805
+ buf : MemoryMapBackingMemory ,
1784
1806
key : MemoryMapKey ,
1785
- buf : & ' buf mut [ u8 ] ,
1786
1807
/// Usually bound to the size of a [`MemoryDescriptor`] but can indicate if
1787
1808
/// this field is ever extended by a new UEFI standard.
1788
1809
desc_size : usize ,
1789
1810
len : usize ,
1790
1811
}
1791
1812
1792
- impl < ' buf > MemoryMap < ' buf > {
1793
- /// Creates a [`MemoryMap`] from the given buffer and entry size.
1794
- /// The entry size is usually bound to the size of a [`MemoryDescriptor`]
1795
- /// but can indicate if this field is ever extended by a new UEFI standard.
1796
- ///
1797
- /// This allows parsing a memory map provided by a kernel after boot
1798
- /// services have already exited.
1799
- pub fn from_raw ( buf : & ' buf mut [ u8 ] , desc_size : usize ) -> Self {
1800
- assert ! ( !buf. is_empty( ) ) ;
1801
- assert_eq ! (
1802
- buf. len( ) % desc_size,
1803
- 0 ,
1804
- "The buffer length must be a multiple of the desc_size"
1805
- ) ;
1813
+ impl MemoryMap {
1814
+ /// Creates a [`MemoryMap`] from the give initialized memory map behind
1815
+ /// the buffer and the reported `desc_size` from UEFI.
1816
+ pub ( crate ) fn from_initialized_mem ( buf : MemoryMapBackingMemory , meta : MemoryMapMeta ) -> Self {
1817
+ let MemoryMapMeta {
1818
+ map_size,
1819
+ desc_size,
1820
+ ..
1821
+ } = meta;
1806
1822
assert ! ( desc_size >= mem:: size_of:: <MemoryDescriptor >( ) ) ;
1807
- let len = buf . len ( ) / desc_size;
1823
+ let len = map_size / desc_size;
1808
1824
MemoryMap {
1809
1825
key : MemoryMapKey ( 0 ) ,
1810
1826
buf,
@@ -1813,6 +1829,20 @@ impl<'buf> MemoryMap<'buf> {
1813
1829
}
1814
1830
}
1815
1831
1832
+ #[ cfg( test) ]
1833
+ fn from_raw ( buf : & mut [ u8 ] , desc_size : usize ) -> Self {
1834
+ let mem = MemoryMapBackingMemory :: from_slice ( buf) ;
1835
+ Self :: from_initialized_mem (
1836
+ mem,
1837
+ MemoryMapMeta {
1838
+ map_size : buf. len ( ) ,
1839
+ desc_size,
1840
+ map_key : MemoryMapKey ( 0 ) ,
1841
+ desc_version : MemoryDescriptor :: VERSION ,
1842
+ } ,
1843
+ )
1844
+ }
1845
+
1816
1846
#[ must_use]
1817
1847
/// Returns the unique [`MemoryMapKey`] associated with the memory map.
1818
1848
pub fn key ( & self ) -> MemoryMapKey {
@@ -1907,7 +1937,7 @@ impl<'buf> MemoryMap<'buf> {
1907
1937
1908
1938
/// Returns a reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1909
1939
#[ must_use]
1910
- pub fn get ( & self , index : usize ) -> Option < & ' buf MemoryDescriptor > {
1940
+ pub fn get ( & self , index : usize ) -> Option < & MemoryDescriptor > {
1911
1941
if index >= self . len {
1912
1942
return None ;
1913
1943
}
@@ -1925,7 +1955,7 @@ impl<'buf> MemoryMap<'buf> {
1925
1955
1926
1956
/// Returns a mut reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1927
1957
#[ must_use]
1928
- pub fn get_mut ( & mut self , index : usize ) -> Option < & ' buf mut MemoryDescriptor > {
1958
+ pub fn get_mut ( & mut self , index : usize ) -> Option < & mut MemoryDescriptor > {
1929
1959
if index >= self . len {
1930
1960
return None ;
1931
1961
}
@@ -1942,15 +1972,15 @@ impl<'buf> MemoryMap<'buf> {
1942
1972
}
1943
1973
}
1944
1974
1945
- impl core:: ops:: Index < usize > for MemoryMap < ' _ > {
1975
+ impl core:: ops:: Index < usize > for MemoryMap {
1946
1976
type Output = MemoryDescriptor ;
1947
1977
1948
1978
fn index ( & self , index : usize ) -> & Self :: Output {
1949
1979
self . get ( index) . unwrap ( )
1950
1980
}
1951
1981
}
1952
1982
1953
- impl core:: ops:: IndexMut < usize > for MemoryMap < ' _ > {
1983
+ impl core:: ops:: IndexMut < usize > for MemoryMap {
1954
1984
fn index_mut ( & mut self , index : usize ) -> & mut Self :: Output {
1955
1985
self . get_mut ( index) . unwrap ( )
1956
1986
}
@@ -1959,13 +1989,13 @@ impl core::ops::IndexMut<usize> for MemoryMap<'_> {
1959
1989
/// An iterator of [`MemoryDescriptor`]. The underlying memory map is always
1960
1990
/// associated with a unique [`MemoryMapKey`].
1961
1991
#[ derive( Debug , Clone ) ]
1962
- pub struct MemoryMapIter < ' buf > {
1963
- memory_map : & ' buf MemoryMap < ' buf > ,
1992
+ pub struct MemoryMapIter < ' a > {
1993
+ memory_map : & ' a MemoryMap ,
1964
1994
index : usize ,
1965
1995
}
1966
1996
1967
- impl < ' buf > Iterator for MemoryMapIter < ' buf > {
1968
- type Item = & ' buf MemoryDescriptor ;
1997
+ impl < ' a > Iterator for MemoryMapIter < ' a > {
1998
+ type Item = & ' a MemoryDescriptor ;
1969
1999
1970
2000
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1971
2001
let sz = self . memory_map . len - self . index ;
@@ -2216,7 +2246,7 @@ mod tests {
2216
2246
}
2217
2247
2218
2248
// Added for debug purposes on test failure
2219
- impl core:: fmt:: Display for MemoryMap < ' _ > {
2249
+ impl core:: fmt:: Display for MemoryMap {
2220
2250
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
2221
2251
writeln ! ( f) ?;
2222
2252
for desc in self . entries ( ) {
0 commit comments