Merge changes I2866f412,Ia99044e8

* changes:
  Add iterator over ranges property.
  Move iterators to new module.
diff --git a/libs/libfdt/src/iterators.rs b/libs/libfdt/src/iterators.rs
new file mode 100644
index 0000000..41fd492
--- /dev/null
+++ b/libs/libfdt/src/iterators.rs
@@ -0,0 +1,207 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Iterators over cells, and various layers on top of them.
+
+use crate::{AddrCells, SizeCells};
+use core::marker::PhantomData;
+use core::{mem::size_of, ops::Range, slice::ChunksExact};
+
+/// Iterator over cells of a DT property.
+#[derive(Debug)]
+pub struct CellIterator<'a> {
+    chunks: ChunksExact<'a, u8>,
+}
+
+impl<'a> CellIterator<'a> {
+    pub(crate) fn new(bytes: &'a [u8]) -> Self {
+        const CHUNK_SIZE: usize = size_of::<<CellIterator as Iterator>::Item>();
+
+        Self { chunks: bytes.chunks_exact(CHUNK_SIZE) }
+    }
+}
+
+impl<'a> Iterator for CellIterator<'a> {
+    type Item = u32;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        Some(Self::Item::from_be_bytes(self.chunks.next()?.try_into().ok()?))
+    }
+}
+
+/// Iterator over a 'reg' property of a DT node.
+#[derive(Debug)]
+pub struct RegIterator<'a> {
+    cells: CellIterator<'a>,
+    addr_cells: AddrCells,
+    size_cells: SizeCells,
+}
+
+/// Represents a contiguous region within the address space defined by the parent bus.
+/// Commonly means the offsets and lengths of MMIO blocks, but may have a different meaning on some
+/// bus types. Addresses in the address space defined by the root node are CPU real addresses.
+#[derive(Copy, Clone, Debug)]
+pub struct Reg<T> {
+    /// Base address of the region.
+    pub addr: T,
+    /// Size of the region (optional).
+    pub size: Option<T>,
+}
+
+impl<'a> RegIterator<'a> {
+    pub(crate) fn new(
+        cells: CellIterator<'a>,
+        addr_cells: AddrCells,
+        size_cells: SizeCells,
+    ) -> Self {
+        Self { cells, addr_cells, size_cells }
+    }
+}
+
+impl<'a> Iterator for RegIterator<'a> {
+    type Item = Reg<u64>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let addr = FromAddrCells::from_addr_cells(&mut self.cells, self.addr_cells)?;
+        // If the parent node specifies a value of 0 for #size-cells, 'size' shall be omitted.
+        let size = if self.size_cells == SizeCells::None {
+            None
+        } else {
+            Some(FromSizeCells::from_size_cells(&mut self.cells, self.size_cells)?)
+        };
+
+        Some(Self::Item { addr, size })
+    }
+}
+
+/// Iterator over the address ranges defined by the /memory/ node.
+#[derive(Debug)]
+pub struct MemRegIterator<'a> {
+    reg: RegIterator<'a>,
+}
+
+impl<'a> MemRegIterator<'a> {
+    pub(crate) fn new(reg: RegIterator<'a>) -> Self {
+        Self { reg }
+    }
+}
+
+impl<'a> Iterator for MemRegIterator<'a> {
+    type Item = Range<usize>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let next = self.reg.next()?;
+        let addr = usize::try_from(next.addr).ok()?;
+        let size = usize::try_from(next.size?).ok()?;
+
+        Some(addr..addr.checked_add(size)?)
+    }
+}
+
+/// Iterator over the 'ranges' property of a DT node.
+#[derive(Debug)]
+pub struct RangesIterator<'a, A, P, S> {
+    cells: CellIterator<'a>,
+    addr_cells: AddrCells,
+    parent_addr_cells: AddrCells,
+    size_cells: SizeCells,
+    _addr: PhantomData<A>,
+    _parent_addr: PhantomData<P>,
+    _size: PhantomData<S>,
+}
+
+/// An address range from the 'ranges' property of a DT node.
+#[derive(Clone, Debug)]
+pub struct AddressRange<A, P, S> {
+    /// The physical address of the range within the child bus's address space.
+    pub addr: A,
+    /// The physical address of the range in the parent bus's address space.
+    pub parent_addr: P,
+    /// The size of the range in the child's address space.
+    pub size: S,
+}
+
+impl<'a, A, P, S> RangesIterator<'a, A, P, S> {
+    pub(crate) fn new(
+        cells: CellIterator<'a>,
+        addr_cells: AddrCells,
+        parent_addr_cells: AddrCells,
+        size_cells: SizeCells,
+    ) -> Self {
+        Self {
+            cells,
+            addr_cells,
+            parent_addr_cells,
+            size_cells,
+            _addr: Default::default(),
+            _parent_addr: Default::default(),
+            _size: Default::default(),
+        }
+    }
+}
+
+impl<'a, A: FromAddrCells, P: FromAddrCells, S: FromSizeCells> Iterator
+    for RangesIterator<'a, A, P, S>
+{
+    type Item = AddressRange<A, P, S>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let addr = FromAddrCells::from_addr_cells(&mut self.cells, self.addr_cells)?;
+        let parent_addr = FromAddrCells::from_addr_cells(&mut self.cells, self.parent_addr_cells)?;
+        let size = FromSizeCells::from_size_cells(&mut self.cells, self.size_cells)?;
+        Some(AddressRange { addr, parent_addr, size })
+    }
+}
+
+trait FromAddrCells: Sized {
+    fn from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self>;
+}
+
+impl FromAddrCells for u64 {
+    fn from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self> {
+        Some(match cell_count {
+            AddrCells::Single => cells.next()?.into(),
+            AddrCells::Double => (cells.next()? as Self) << 32 | cells.next()? as Self,
+            _ => panic!("Invalid addr_cells {:?} for u64", cell_count),
+        })
+    }
+}
+
+impl FromAddrCells for u128 {
+    fn from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self> {
+        Some(match cell_count {
+            AddrCells::Single => cells.next()?.into(),
+            AddrCells::Double => (cells.next()? as Self) << 32 | cells.next()? as Self,
+            AddrCells::Triple => {
+                (cells.next()? as Self) << 64
+                    | (cells.next()? as Self) << 32
+                    | cells.next()? as Self
+            }
+        })
+    }
+}
+
+trait FromSizeCells: Sized {
+    fn from_size_cells(cells: &mut CellIterator, cell_count: SizeCells) -> Option<Self>;
+}
+
+impl FromSizeCells for u64 {
+    fn from_size_cells(cells: &mut CellIterator, cell_count: SizeCells) -> Option<Self> {
+        Some(match cell_count {
+            SizeCells::Single => cells.next()?.into(),
+            SizeCells::Double => (cells.next()? as Self) << 32 | cells.next()? as Self,
+            _ => panic!("Invalid size_cells {:?} for u64", cell_count),
+        })
+    }
+}
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index ff1db63..64e6746 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -18,12 +18,14 @@
 #![no_std]
 #![feature(let_else)] // Stabilized in 1.65.0
 
+mod iterators;
+
+pub use iterators::{AddressRange, CellIterator, MemRegIterator, RangesIterator, Reg, RegIterator};
+
 use core::ffi::{c_int, c_void, CStr};
 use core::fmt;
 use core::mem;
-use core::ops::Range;
 use core::result;
-use core::slice;
 
 /// Error type corresponding to libfdt error codes.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -146,10 +148,11 @@
 }
 
 /// Value of a #address-cells property.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 enum AddrCells {
     Single = 1,
     Double = 2,
+    Triple = 3,
 }
 
 impl TryFrom<c_int> for AddrCells {
@@ -159,13 +162,14 @@
         match fdt_err(res)? {
             x if x == Self::Single as c_int => Ok(Self::Single),
             x if x == Self::Double as c_int => Ok(Self::Double),
+            x if x == Self::Triple as c_int => Ok(Self::Triple),
             _ => Err(FdtError::BadNCells),
         }
     }
 }
 
 /// Value of a #size-cells property.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 enum SizeCells {
     None = 0,
     Single = 1,
@@ -185,98 +189,6 @@
     }
 }
 
-/// Iterator over cells of a DT property.
-#[derive(Debug)]
-pub struct CellIterator<'a> {
-    chunks: slice::ChunksExact<'a, u8>,
-}
-
-impl<'a> CellIterator<'a> {
-    fn new(bytes: &'a [u8]) -> Self {
-        const CHUNK_SIZE: usize = mem::size_of::<<CellIterator as Iterator>::Item>();
-
-        Self { chunks: bytes.chunks_exact(CHUNK_SIZE) }
-    }
-}
-
-impl<'a> Iterator for CellIterator<'a> {
-    type Item = u32;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        Some(Self::Item::from_be_bytes(self.chunks.next()?.try_into().ok()?))
-    }
-}
-
-/// Iterator over a 'reg' property of a DT node.
-#[derive(Debug)]
-pub struct RegIterator<'a> {
-    cells: CellIterator<'a>,
-    addr_cells: AddrCells,
-    size_cells: SizeCells,
-}
-
-/// Represents a contiguous region within the address space defined by the parent bus.
-/// Commonly means the offsets and lengths of MMIO blocks, but may have a different meaning on some
-/// bus types. Addresses in the address space defined by the root node are CPU real addresses.
-#[derive(Copy, Clone, Debug)]
-pub struct Reg<T> {
-    /// Base address of the region.
-    pub addr: T,
-    /// Size of the region (optional).
-    pub size: Option<T>,
-}
-
-impl<'a> RegIterator<'a> {
-    fn new(cells: CellIterator<'a>, addr_cells: AddrCells, size_cells: SizeCells) -> Self {
-        Self { cells, addr_cells, size_cells }
-    }
-}
-
-impl<'a> Iterator for RegIterator<'a> {
-    type Item = Reg<u64>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let make_double = |a, b| (u64::from(a) << 32) | u64::from(b);
-
-        let addr = match self.addr_cells {
-            AddrCells::Single => self.cells.next()?.into(),
-            AddrCells::Double => make_double(self.cells.next()?, self.cells.next()?),
-        };
-        // If the parent node specifies a value of 0 for #size-cells, 'size' shall be omitted.
-        let size = match self.size_cells {
-            SizeCells::None => None,
-            SizeCells::Single => Some(self.cells.next()?.into()),
-            SizeCells::Double => Some(make_double(self.cells.next()?, self.cells.next()?)),
-        };
-
-        Some(Self::Item { addr, size })
-    }
-}
-
-/// Iterator over the address ranges defined by the /memory/ node.
-#[derive(Debug)]
-pub struct MemRegIterator<'a> {
-    reg: RegIterator<'a>,
-}
-
-impl<'a> MemRegIterator<'a> {
-    fn new(reg: RegIterator<'a>) -> Self {
-        Self { reg }
-    }
-}
-
-impl<'a> Iterator for MemRegIterator<'a> {
-    type Item = Range<usize>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let next = self.reg.next()?;
-        let addr = usize::try_from(next.addr).ok()?;
-        let size = usize::try_from(next.size?).ok()?;
-
-        Some(addr..addr.checked_add(size)?)
-    }
-}
-
 /// DT node.
 #[derive(Clone, Copy)]
 pub struct FdtNode<'a> {
@@ -314,6 +226,25 @@
         }
     }
 
+    /// Retrieves the standard ranges property.
+    pub fn ranges<A, P, S>(&self) -> Result<Option<RangesIterator<'a, A, P, S>>> {
+        let ranges = CStr::from_bytes_with_nul(b"ranges\0").unwrap();
+        if let Some(cells) = self.getprop_cells(ranges)? {
+            let parent = self.parent()?;
+            let addr_cells = self.address_cells()?;
+            let parent_addr_cells = parent.address_cells()?;
+            let size_cells = self.size_cells()?;
+            Ok(Some(RangesIterator::<A, P, S>::new(
+                cells,
+                addr_cells,
+                parent_addr_cells,
+                size_cells,
+            )))
+        } else {
+            Ok(None)
+        }
+    }
+
     /// Retrieve the value of a given <string> property.
     pub fn getprop_str(&self, name: &CStr) -> Result<Option<&CStr>> {
         let value = if let Some(bytes) = self.getprop(name)? {