@@ -302,6 +302,11 @@ where
302302 . ok_or ( AcpiError :: TableMissing ( T :: SIGNATURE ) )
303303 }
304304
305+ /// Iterates through all of the table headers.
306+ pub fn headers ( & self ) -> SdtHeaderIterator < ' _ , H > {
307+ SdtHeaderIterator { tables_phys_ptrs : self . tables_phys_ptrs ( ) , handler : self . handler . clone ( ) }
308+ }
309+
305310 /// Finds and returns the DSDT AML table, if it exists.
306311 pub fn dsdt ( & self ) -> AcpiResult < AmlTable > {
307312 self . find_table :: < fadt:: Fadt > ( ) . and_then ( |fadt| {
@@ -446,3 +451,37 @@ where
446451 } )
447452 }
448453}
454+
455+ pub struct SdtHeaderIterator < ' t , H >
456+ where
457+ H : AcpiHandler ,
458+ {
459+ tables_phys_ptrs : TablesPhysPtrsIter < ' t > ,
460+ handler : H ,
461+ }
462+
463+ impl < ' t , H > Iterator for SdtHeaderIterator < ' t , H >
464+ where
465+ H : AcpiHandler ,
466+ {
467+ type Item = SdtHeader ;
468+
469+ fn next ( & mut self ) -> Option < Self :: Item > {
470+ loop {
471+ let table_phys_ptr = self . tables_phys_ptrs . next ( ) ?;
472+ // SAFETY: `address` needs to be valid for the size of `SdtHeader`, or the ACPI tables are malformed (not a
473+ // software issue).
474+ let header_mapping = unsafe {
475+ self . handler . map_physical_region :: < SdtHeader > ( table_phys_ptr as usize , mem:: size_of :: < SdtHeader > ( ) )
476+ } ;
477+ let r = header_mapping. validate ( header_mapping. signature ) ;
478+ if r. is_err ( ) {
479+ log:: warn!( "Found invalid SSDT at physical address {:p}: {:?}" , table_phys_ptr, r) ;
480+ continue ;
481+ }
482+ let result = header_mapping. clone ( ) ;
483+ drop ( header_mapping) ;
484+ return Some ( result) ;
485+ }
486+ }
487+ }
0 commit comments