Skip to content

Commit

Permalink
Add SdtHeaderIterator to get all headers.
Browse files Browse the repository at this point in the history
  • Loading branch information
fslongjin authored and IsaacWoods committed Mar 13, 2024
1 parent 7db4539 commit f5f6c96
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions acpi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@ where
.ok_or(AcpiError::TableMissing(T::SIGNATURE))
}

/// Iterates through all of the table headers.
pub fn headers(&self) -> SdtHeaderIterator<'_, H> {
SdtHeaderIterator { tables_phys_ptrs: self.tables_phys_ptrs(), handler: self.handler.clone() }
}

/// Finds and returns the DSDT AML table, if it exists.
pub fn dsdt(&self) -> AcpiResult<AmlTable> {
self.find_table::<fadt::Fadt>().and_then(|fadt| {
Expand Down Expand Up @@ -446,3 +451,37 @@ where
})
}
}

pub struct SdtHeaderIterator<'t, H>
where
H: AcpiHandler,
{
tables_phys_ptrs: TablesPhysPtrsIter<'t>,
handler: H,
}

impl<'t, H> Iterator for SdtHeaderIterator<'t, H>
where
H: AcpiHandler,
{
type Item = SdtHeader;

fn next(&mut self) -> Option<Self::Item> {
loop {
let table_phys_ptr = self.tables_phys_ptrs.next()?;
// SAFETY: `address` needs to be valid for the size of `SdtHeader`, or the ACPI tables are malformed (not a
// software issue).
let header_mapping = unsafe {
self.handler.map_physical_region::<SdtHeader>(table_phys_ptr as usize, mem::size_of::<SdtHeader>())
};
let r = header_mapping.validate(header_mapping.signature);
if r.is_err() {
log::warn!("Found invalid SSDT at physical address {:p}: {:?}", table_phys_ptr, r);
continue;
}
let result = header_mapping.clone();
drop(header_mapping);
return Some(result);
}
}
}

0 comments on commit f5f6c96

Please sign in to comment.