Move iterators to new module.
The main module is getting rather big.
Bug: 237249743
Test: m vmbase_example_bin pvmfw_bin
Change-Id: Ia99044e8c833bd3fb4f6230bd123d95eb71f0b66
diff --git a/libs/libfdt/src/iterators.rs b/libs/libfdt/src/iterators.rs
new file mode 100644
index 0000000..a80aa1b
--- /dev/null
+++ b/libs/libfdt/src/iterators.rs
@@ -0,0 +1,114 @@
+// 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::{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 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> {
+ 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)?)
+ }
+}
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index ff1db63..0cc781e 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::{CellIterator, MemRegIterator, 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)]
@@ -185,98 +187,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> {