@@ -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 GetMemoryMapMeta {
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 < GetMemoryMapMeta > {
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 ( || GetMemoryMapMeta {
277
+ map_size,
278
+ desc_size,
279
+ map_key,
280
+ desc_version,
276
281
} )
277
282
}
278
283
@@ -1676,13 +1681,22 @@ 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 ) ;
1680
1685
1681
- Ok ( Self ( slice) )
1686
+ Self ( slice)
1687
+ }
1688
+
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
1685
1698
/// especially created with exiting boot services in mind.
1699
+ #[ must_use]
1686
1700
pub fn allocation_size_hint ( mms : GetMemoryMapMeta ) -> usize {
1687
1701
let GetMemoryMapMeta {
1688
1702
desc_size,
@@ -1711,8 +1725,15 @@ impl MemoryMapBackingMemory {
1711
1725
map_size + extra_size
1712
1726
}
1713
1727
1714
- /// Returns the raw pointer to the beginning of the allocation.
1715
- 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 {
1716
1737
self . 0 . as_ptr ( ) . cast ( )
1717
1738
}
1718
1739
@@ -1770,31 +1791,34 @@ pub struct GetMemoryMapMeta {
1770
1791
///
1771
1792
/// [0]: https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
1772
1793
#[ derive( Debug ) ]
1773
- pub struct MemoryMap < ' buf > {
1794
+ pub struct MemoryMap {
1795
+ /// Backing memory, properly initialized at this point.
1796
+ buf : MemoryMapBackingMemory ,
1774
1797
key : MemoryMapKey ,
1775
- buf : & ' buf mut [ u8 ] ,
1776
1798
/// Usually bound to the size of a [`MemoryDescriptor`] but can indicate if
1777
1799
/// this field is ever extended by a new UEFI standard.
1778
1800
desc_size : usize ,
1779
1801
len : usize ,
1780
1802
}
1781
1803
1782
- impl < ' buf > MemoryMap < ' buf > {
1783
- /// Creates a [`MemoryMap`] from the given buffer and entry size.
1784
- /// The entry size is usually bound to the size of a [`MemoryDescriptor`]
1785
- /// but can indicate if this field is ever extended by a new UEFI standard.
1786
- ///
1787
- /// This allows parsing a memory map provided by a kernel after boot
1788
- /// services have already exited.
1789
- pub fn from_raw ( buf : & ' buf mut [ u8 ] , desc_size : usize ) -> Self {
1790
- assert ! ( !buf. is_empty( ) ) ;
1791
- assert_eq ! (
1792
- buf. len( ) % desc_size,
1793
- 0 ,
1794
- "The buffer length must be a multiple of the desc_size"
1795
- ) ;
1804
+ impl MemoryMap {
1805
+ /*pub fn new() -> Self {
1806
+
1807
+ }*/
1808
+
1809
+ /// Creates a [`MemoryMap`] from the give initialized memory map behind
1810
+ /// the buffer and the reported `desc_size` from UEFI.
1811
+ pub ( crate ) fn from_initialized_mem (
1812
+ buf : MemoryMapBackingMemory ,
1813
+ props : GetMemoryMapMeta ,
1814
+ ) -> Self {
1815
+ let GetMemoryMapMeta {
1816
+ map_size,
1817
+ desc_size,
1818
+ ..
1819
+ } = props;
1796
1820
assert ! ( desc_size >= mem:: size_of:: <MemoryDescriptor >( ) ) ;
1797
- let len = buf . len ( ) / desc_size;
1821
+ let len = map_size / desc_size;
1798
1822
MemoryMap {
1799
1823
key : MemoryMapKey ( 0 ) ,
1800
1824
buf,
@@ -1803,6 +1827,20 @@ impl<'buf> MemoryMap<'buf> {
1803
1827
}
1804
1828
}
1805
1829
1830
+ #[ cfg( test) ]
1831
+ fn from_raw ( buf : & mut [ u8 ] , desc_size : usize ) -> Self {
1832
+ let mem = MemoryMapBackingMemory :: from_slice ( buf) ;
1833
+ Self :: from_initialized_mem (
1834
+ mem,
1835
+ GetMemoryMapMeta {
1836
+ map_size : buf. len ( ) ,
1837
+ desc_size,
1838
+ map_key : MemoryMapKey ( 0 ) ,
1839
+ desc_version : MemoryDescriptor :: VERSION ,
1840
+ } ,
1841
+ )
1842
+ }
1843
+
1806
1844
#[ must_use]
1807
1845
/// Returns the unique [`MemoryMapKey`] associated with the memory map.
1808
1846
pub fn key ( & self ) -> MemoryMapKey {
@@ -1897,7 +1935,7 @@ impl<'buf> MemoryMap<'buf> {
1897
1935
1898
1936
/// Returns a reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1899
1937
#[ must_use]
1900
- pub fn get ( & self , index : usize ) -> Option < & ' buf MemoryDescriptor > {
1938
+ pub fn get ( & self , index : usize ) -> Option < & MemoryDescriptor > {
1901
1939
if index >= self . len {
1902
1940
return None ;
1903
1941
}
@@ -1915,7 +1953,7 @@ impl<'buf> MemoryMap<'buf> {
1915
1953
1916
1954
/// Returns a mut reference to the [`MemoryDescriptor`] at `index` or `None` if out of bounds.
1917
1955
#[ must_use]
1918
- pub fn get_mut ( & mut self , index : usize ) -> Option < & ' buf mut MemoryDescriptor > {
1956
+ pub fn get_mut ( & mut self , index : usize ) -> Option < & mut MemoryDescriptor > {
1919
1957
if index >= self . len {
1920
1958
return None ;
1921
1959
}
@@ -1932,15 +1970,15 @@ impl<'buf> MemoryMap<'buf> {
1932
1970
}
1933
1971
}
1934
1972
1935
- impl core:: ops:: Index < usize > for MemoryMap < ' _ > {
1973
+ impl core:: ops:: Index < usize > for MemoryMap {
1936
1974
type Output = MemoryDescriptor ;
1937
1975
1938
1976
fn index ( & self , index : usize ) -> & Self :: Output {
1939
1977
self . get ( index) . unwrap ( )
1940
1978
}
1941
1979
}
1942
1980
1943
- impl core:: ops:: IndexMut < usize > for MemoryMap < ' _ > {
1981
+ impl core:: ops:: IndexMut < usize > for MemoryMap {
1944
1982
fn index_mut ( & mut self , index : usize ) -> & mut Self :: Output {
1945
1983
self . get_mut ( index) . unwrap ( )
1946
1984
}
@@ -1949,13 +1987,13 @@ impl core::ops::IndexMut<usize> for MemoryMap<'_> {
1949
1987
/// An iterator of [`MemoryDescriptor`]. The underlying memory map is always
1950
1988
/// associated with a unique [`MemoryMapKey`].
1951
1989
#[ derive( Debug , Clone ) ]
1952
- pub struct MemoryMapIter < ' buf > {
1953
- memory_map : & ' buf MemoryMap < ' buf > ,
1990
+ pub struct MemoryMapIter < ' a > {
1991
+ memory_map : & ' a MemoryMap ,
1954
1992
index : usize ,
1955
1993
}
1956
1994
1957
- impl < ' buf > Iterator for MemoryMapIter < ' buf > {
1958
- type Item = & ' buf MemoryDescriptor ;
1995
+ impl < ' a > Iterator for MemoryMapIter < ' a > {
1996
+ type Item = & ' a MemoryDescriptor ;
1959
1997
1960
1998
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1961
1999
let sz = self . memory_map . len - self . index ;
@@ -2206,7 +2244,7 @@ mod tests {
2206
2244
}
2207
2245
2208
2246
// Added for debug purposes on test failure
2209
- impl core:: fmt:: Display for MemoryMap < ' _ > {
2247
+ impl core:: fmt:: Display for MemoryMap {
2210
2248
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
2211
2249
writeln ! ( f) ?;
2212
2250
for desc in self . entries ( ) {
0 commit comments