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)