fdt_raw/node/prop/reg.rs
1//! Reg property parser for device register addresses.
2//!
3//! This module provides types for parsing the `reg` property, which describes
4//! memory-mapped registers and address ranges for devices.
5//!
6//! The `reg` property format is:
7//! ```text
8//! reg = <address1 size1 address2 size2 ...>;
9//! ```
10//! where each address and size uses `#address-cells` and `#size-cells`
11//! u32 values respectively, inherited from the parent node.
12
13use crate::data::Reader;
14
15/// Reg entry information.
16///
17/// Represents a single entry in a `reg` property, describing an address
18/// range for a device's registers or memory.
19///
20/// # Fields
21///
22/// * `address` - The base address of the register range or memory region
23/// * `size` - The size of the range (may be `None` if `#size-cells` is 0)
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct RegInfo {
26 /// Base address of the register/memory range
27 pub address: u64,
28 /// Size of the range (None if #size-cells is 0)
29 pub size: Option<u64>,
30}
31
32impl RegInfo {
33 /// Creates a new RegInfo with the given address and optional size.
34 pub const fn new(address: u64, size: Option<u64>) -> Self {
35 Self { address, size }
36 }
37}
38
39/// Reg property iterator.
40///
41/// Iterates over entries in a `reg` property, parsing address and size
42/// values based on the parent node's #address-cells and #size-cells values.
43///
44/// # Cell Values
45///
46/// - `#address-cells` determines how many u32 values form each address
47/// - `#size-cells` determines how many u32 values form each size
48/// - Common values: 1 for 32-bit addresses, 2 for 64-bit addresses
49///
50/// # Examples
51///
52/// ```ignore
53/// // Assuming #address-cells = 2, #size-cells = 1
54/// for reg in node.reg() {
55/// println!("Address: {:#x}, Size: {:#x}", reg.address, reg.size.unwrap_or(0));
56/// }
57/// ```
58#[derive(Clone)]
59pub struct RegIter<'a> {
60 reader: Reader<'a>,
61 address_cells: u8,
62 size_cells: u8,
63}
64
65impl<'a> RegIter<'a> {
66 /// Creates a new Reg iterator.
67 pub(crate) fn new(reader: Reader<'a>, address_cells: u8, size_cells: u8) -> RegIter<'a> {
68 RegIter {
69 reader,
70 address_cells,
71 size_cells,
72 }
73 }
74}
75
76impl Iterator for RegIter<'_> {
77 type Item = RegInfo;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 let address;
81 let size;
82
83 // Read address based on address_cells
84 if self.address_cells == 1 {
85 address = self.reader.read_u32().map(|addr| addr as u64)?;
86 } else if self.address_cells == 2 {
87 address = self.reader.read_u64()?;
88 } else {
89 return None;
90 }
91
92 // Read size based on size_cells
93 if self.size_cells == 0 {
94 size = None;
95 } else if self.size_cells == 1 {
96 size = self.reader.read_u32().map(|s| s as u64);
97 } else if self.size_cells == 2 {
98 size = self.reader.read_u64();
99 } else {
100 // Unsupported size_cells value
101 return None;
102 }
103
104 Some(RegInfo::new(address, size))
105 }
106}