Skip to content

Commit f5f6c96

Browse files
fslongjinIsaacWoods
authored andcommitted
Add SdtHeaderIterator to get all headers.
1 parent 7db4539 commit f5f6c96

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

acpi/src/lib.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)