3
3
//! These functions will panic if called after exiting boot services.
4
4
5
5
use crate :: data_types:: PhysicalAddress ;
6
+ use crate :: mem:: memory_map:: { MemoryMapBackingMemory , MemoryMapKey , MemoryMapMeta , MemoryMapOwned } ;
6
7
use crate :: proto:: device_path:: DevicePath ;
7
8
use crate :: proto:: { Protocol , ProtocolPointer } ;
8
9
use crate :: util:: opt_nonnull_to_ptr;
@@ -24,7 +25,7 @@ pub use uefi::table::boot::{
24
25
AllocateType , EventNotifyFn , LoadImageSource , OpenProtocolAttributes , OpenProtocolParams ,
25
26
SearchType , TimerTrigger ,
26
27
} ;
27
- pub use uefi_raw:: table:: boot:: { EventType , MemoryType , Tpl } ;
28
+ pub use uefi_raw:: table:: boot:: { EventType , MemoryAttribute , MemoryDescriptor , MemoryType , Tpl } ;
28
29
29
30
/// Global image handle. This is only set by [`set_image_handle`], and it is
30
31
/// only read by [`image_handle`].
@@ -165,6 +166,63 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
165
166
unsafe { ( bt. free_pool ) ( ptr. as_ptr ( ) ) } . to_result ( )
166
167
}
167
168
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
+
168
226
/// Creates an event.
169
227
///
170
228
/// This function creates a new event of the specified type and returns it.
0 commit comments