libfdt: Add phandle APIs
This CL adds following APIs
- Fdt::max_phandle(): Returns the max phandle
- Fdt::node_with_phandle(): Returns the node with phandle
Bug: 277993056
Test: atest liblibfdt.integration_test
Change-Id: I155242718b09897e832834a621f9e244ed2d9807
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 5a7bd14..2a547e8 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -499,6 +499,27 @@
}
}
+/// Phandle of a FDT node
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct Phandle(u32);
+
+impl Phandle {
+ /// Creates a new Phandle
+ pub fn new(value: u32) -> Result<Self> {
+ if value == 0 || value > libfdt_bindgen::FDT_MAX_PHANDLE {
+ return Err(FdtError::BadPhandle);
+ }
+ Ok(Self(value))
+ }
+}
+
+impl From<Phandle> for u32 {
+ fn from(phandle: Phandle) -> u32 {
+ phandle.0
+ }
+}
+
/// Mutable FDT node.
pub struct FdtNodeMut<'a> {
fdt: &'a mut Fdt,
@@ -879,6 +900,23 @@
CompatibleIterator::new(self, compatible)
}
+ /// Returns max phandle in the tree.
+ pub fn max_phandle(&self) -> Result<Phandle> {
+ let mut phandle: u32 = 0;
+ // SAFETY: Accesses (read-only) are constrained to the DT totalsize.
+ let ret = unsafe { libfdt_bindgen::fdt_find_max_phandle(self.as_ptr(), &mut phandle) };
+
+ fdt_err_expect_zero(ret)?;
+ Phandle::new(phandle)
+ }
+
+ /// Returns a node with the phandle
+ pub fn node_with_phandle(&self, phandle: Phandle) -> Result<Option<FdtNode>> {
+ // SAFETY: Accesses (read-only) are constrained to the DT totalsize.
+ let ret = unsafe { libfdt_bindgen::fdt_node_offset_by_phandle(self.as_ptr(), phandle.0) };
+ Ok(fdt_err_or_option(ret)?.map(|offset| FdtNode { fdt: self, offset }))
+ }
+
/// Returns the mutable root node of the tree.
pub fn root_mut(&mut self) -> Result<FdtNodeMut> {
self.node_mut(CStr::from_bytes_with_nul(b"/\0").unwrap())?.ok_or(FdtError::Internal)