@@ -302,6 +302,11 @@ where
302
302
. ok_or ( AcpiError :: TableMissing ( T :: SIGNATURE ) )
303
303
}
304
304
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
+
305
310
/// Finds and returns the DSDT AML table, if it exists.
306
311
pub fn dsdt ( & self ) -> AcpiResult < AmlTable > {
307
312
self . find_table :: < fadt:: Fadt > ( ) . and_then ( |fadt| {
@@ -446,3 +451,37 @@ where
446
451
} )
447
452
}
448
453
}
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