33//! These functions will panic if called after exiting boot services.
44
55use crate :: data_types:: PhysicalAddress ;
6+ use crate :: mem:: memory_map:: { MemoryMapBackingMemory , MemoryMapKey , MemoryMapMeta , MemoryMapOwned } ;
67use crate :: proto:: device_path:: DevicePath ;
78use crate :: proto:: { Protocol , ProtocolPointer } ;
89use crate :: util:: opt_nonnull_to_ptr;
@@ -24,7 +25,7 @@ pub use uefi::table::boot::{
2425 AllocateType , EventNotifyFn , LoadImageSource , OpenProtocolAttributes , OpenProtocolParams ,
2526 SearchType , TimerTrigger ,
2627} ;
27- pub use uefi_raw:: table:: boot:: { EventType , MemoryType , Tpl } ;
28+ pub use uefi_raw:: table:: boot:: { EventType , MemoryAttribute , MemoryDescriptor , MemoryType , Tpl } ;
2829
2930/// Global image handle. This is only set by [`set_image_handle`], and it is
3031/// only read by [`image_handle`].
@@ -165,6 +166,63 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
165166 unsafe { ( bt. free_pool ) ( ptr. as_ptr ( ) ) } . to_result ( )
166167}
167168
169+ /// Stores the current UEFI memory map in an UEFI-heap allocated buffer
170+ /// and returns a [`MemoryMapOwned`].
171+ ///
172+ /// # Parameters
173+ ///
174+ /// - `mt`: The memory type for the backing memory on the UEFI heap.
175+ /// Usually, this is [`MemoryType::LOADER_DATA`]. You can also use a
176+ /// custom type.
177+ ///
178+ /// # Errors
179+ ///
180+ /// * [`Status::BUFFER_TOO_SMALL`]
181+ /// * [`Status::INVALID_PARAMETER`]
182+ pub fn memory_map ( mt : MemoryType ) -> Result < MemoryMapOwned > {
183+ let mut buffer = MemoryMapBackingMemory :: new ( mt) ?;
184+
185+ let meta = get_memory_map ( buffer. as_mut_slice ( ) ) ?;
186+
187+ Ok ( MemoryMapOwned :: from_initialized_mem ( buffer, meta) )
188+ }
189+
190+ /// Calls the underlying `GetMemoryMap` function of UEFI. On success,
191+ /// the buffer is mutated and contains the map. The map might be shorter
192+ /// than the buffer, which is reflected by the return value.
193+ pub ( crate ) fn get_memory_map ( buf : & mut [ u8 ] ) -> Result < MemoryMapMeta > {
194+ let bt = boot_services_raw_panicking ( ) ;
195+ let bt = unsafe { bt. as_ref ( ) } ;
196+
197+ let mut map_size = buf. len ( ) ;
198+ let map_buffer = buf. as_mut_ptr ( ) . cast :: < MemoryDescriptor > ( ) ;
199+ let mut map_key = MemoryMapKey ( 0 ) ;
200+ let mut desc_size = 0 ;
201+ let mut desc_version = 0 ;
202+
203+ assert_eq ! (
204+ ( map_buffer as usize ) % mem:: align_of:: <MemoryDescriptor >( ) ,
205+ 0 ,
206+ "Memory map buffers must be aligned like a MemoryDescriptor"
207+ ) ;
208+
209+ unsafe {
210+ ( bt. get_memory_map ) (
211+ & mut map_size,
212+ map_buffer,
213+ & mut map_key. 0 ,
214+ & mut desc_size,
215+ & mut desc_version,
216+ )
217+ }
218+ . to_result_with_val ( || MemoryMapMeta {
219+ map_size,
220+ desc_size,
221+ map_key,
222+ desc_version,
223+ } )
224+ }
225+
168226/// Creates an event.
169227///
170228/// This function creates a new event of the specified type and returns it.
0 commit comments