libfdt: Move phandle functions and 0-cost Phandle

Move Phandle to its own module, intended to contain all the zero-cost
abstractions used by our Rust-safe wrapper around libfdt in place of the
c_ints expected by the C code.

Move the functions dealing with phandles to the LibFdt* traits.

Reduce the unsafe blocks to the strict minimum (i.e. the FFI calls).

Test: m pvmfw
Test: atest liblibfdt.integration_test
Change-Id: I548c7436f94bd7a902943eaea5bf1f0195e52366
diff --git a/libs/libfdt/src/libfdt.rs b/libs/libfdt/src/libfdt.rs
index 7e3b65a..0614a5e 100644
--- a/libs/libfdt/src/libfdt.rs
+++ b/libs/libfdt/src/libfdt.rs
@@ -21,7 +21,7 @@
 use core::ffi::{c_int, CStr};
 use core::ptr;
 
-use crate::{fdt_err, fdt_err_expect_zero, fdt_err_or_option, FdtError, Result};
+use crate::{fdt_err, fdt_err_expect_zero, fdt_err_or_option, FdtError, Phandle, Result};
 
 // Function names are the C function names without the `fdt_` prefix.
 
@@ -78,6 +78,16 @@
         fdt_err_or_option(ret)
     }
 
+    /// Safe wrapper around `fdt_node_offset_by_phandle()` (C function).
+    fn node_offset_by_phandle(&self, phandle: Phandle) -> Result<Option<c_int>> {
+        let fdt = self.as_fdt_slice().as_ptr().cast();
+        let phandle = phandle.into();
+        // SAFETY: Accesses are constrained to the DT totalsize.
+        let ret = unsafe { libfdt_bindgen::fdt_node_offset_by_phandle(fdt, phandle) };
+
+        fdt_err_or_option(ret)
+    }
+
     /// Safe wrapper around `fdt_node_offset_by_compatible()` (C function).
     fn node_offset_by_compatible(&self, prev: c_int, compatible: &CStr) -> Result<Option<c_int>> {
         let fdt = self.as_fdt_slice().as_ptr().cast();
@@ -175,6 +185,18 @@
 
         Ok(fdt_err(ret)?.try_into().unwrap())
     }
+
+    /// Safe wrapper around `fdt_find_max_phandle()` (C function).
+    fn find_max_phandle(&self) -> Result<Phandle> {
+        let fdt = self.as_fdt_slice().as_ptr().cast();
+        let mut phandle = 0;
+        // SAFETY: Accesses (read-only) are constrained to the DT totalsize.
+        let ret = unsafe { libfdt_bindgen::fdt_find_max_phandle(fdt, &mut phandle) };
+
+        fdt_err_expect_zero(ret)?;
+
+        phandle.try_into()
+    }
 }
 
 /// Wrapper for the read-write libfdt.h functions.