@@ -314,6 +314,23 @@ impl EFIMemoryMapTag {
314314 phantom : PhantomData ,
315315 }
316316 }
317+
318+ #[ cfg( feature = "builder" ) ]
319+ /// Return an iterator over ALL marked memory areas, mutably.
320+ ///
321+ /// This differs from `MemoryMapTag` as for UEFI, the OS needs some non-
322+ /// available memory areas for tables and such.
323+ pub fn memory_areas_mut ( & mut self ) -> EFIMemoryAreaIterMut {
324+ let self_ptr = self as * const EFIMemoryMapTag ;
325+ let start_area = ( & self . descs [ 0 ] ) as * const EFIMemoryDesc ;
326+ EFIMemoryAreaIterMut {
327+ current_area : start_area as u64 ,
328+ // NOTE: `last_area` is only a bound, it doesn't necessarily point exactly to the last element
329+ last_area : ( self_ptr as * const ( ) as u64 + self . size as u64 ) ,
330+ entry_size : self . desc_size ,
331+ phantom : PhantomData ,
332+ }
333+ }
317334}
318335
319336impl TagTrait for EFIMemoryMapTag {
@@ -532,3 +549,25 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> {
532549 }
533550 }
534551}
552+
553+ /// An iterator over ALL EFI memory areas, mutably.
554+ #[ derive( Clone , Debug ) ]
555+ pub struct EFIMemoryAreaIterMut < ' a > {
556+ current_area : u64 ,
557+ last_area : u64 ,
558+ entry_size : u32 ,
559+ phantom : PhantomData < & ' a mut EFIMemoryDesc > ,
560+ }
561+
562+ impl < ' a > Iterator for EFIMemoryAreaIterMut < ' a > {
563+ type Item = & ' a mut EFIMemoryDesc ;
564+ fn next ( & mut self ) -> Option < & ' a mut EFIMemoryDesc > {
565+ if self . current_area > self . last_area {
566+ None
567+ } else {
568+ let area = unsafe { & mut * ( self . current_area as * mut EFIMemoryDesc ) } ;
569+ self . current_area += self . entry_size as u64 ;
570+ Some ( area)
571+ }
572+ }
573+ }
0 commit comments