fdt_parser/
node.rs

1use core::iter;
2
3use crate::{
4    clocks::{ClockRef, ClocksIter},
5    error::{FdtError, FdtResult},
6    interrupt::InterruptController,
7    meta::MetaData,
8    pci::Pci,
9    property::Property,
10    read::{FdtReader, U32Array2D},
11    Fdt, FdtRangeSilce, FdtReg, Phandle, Status, Token,
12};
13
14#[derive(Clone)]
15pub struct Node<'a> {
16    pub level: usize,
17    pub name: &'a str,
18    pub(crate) fdt: &'a Fdt<'a>,
19    /// 父节点的元数据
20    pub(crate) meta_parents: MetaData<'a>,
21    /// 当前节点的元数据
22    pub(crate) meta: MetaData<'a>,
23    body: FdtReader<'a>,
24}
25
26impl<'a> Node<'a> {
27    pub(crate) fn new(
28        fdt: &'a Fdt<'a>,
29        level: usize,
30        name: &'a str,
31        reader: FdtReader<'a>,
32        meta_parents: MetaData<'a>,
33        meta: MetaData<'a>,
34    ) -> Self {
35        Self {
36            fdt,
37            level,
38            body: reader,
39            name,
40            meta,
41            meta_parents,
42        }
43    }
44
45    pub fn name(&self) -> &'a str {
46        self.name
47    }
48
49    pub fn propertys(&self) -> impl Iterator<Item = Property<'a>> + '_ {
50        let reader = self.body.clone();
51        PropIter {
52            reader,
53            fdt: self.fdt,
54        }
55    }
56
57    pub fn find_property(&self, name: &str) -> Option<Property<'a>> {
58        self.propertys().find(|x| x.name.eq(name))
59    }
60
61    pub fn reg(&self) -> Option<impl Iterator<Item = FdtReg> + 'a> {
62        let mut iter = self.propertys();
63        let reg = iter.find(|x| x.name.eq("reg"))?;
64
65        Some(RegIter {
66            size_cell: self.meta_parents.size_cells.unwrap(),
67            address_cell: self.meta_parents.address_cells.unwrap(),
68            prop: reg,
69            ranges: self.meta_parents.range.clone(),
70        })
71    }
72
73    pub(crate) fn node_ranges(&self) -> Option<FdtRangeSilce<'a>> {
74        let prop = self.find_property("ranges")?;
75
76        Some(FdtRangeSilce::new(
77            self.meta.address_cells.unwrap(),
78            self.meta_parents.address_cells.unwrap(),
79            self.meta.size_cells.unwrap(),
80            prop.data.clone(),
81        ))
82    }
83
84    pub(crate) fn node_interrupt_parent(&self) -> Option<Phandle> {
85        let prop = self.find_property("interrupt-parent")?;
86        Some(prop.u32().into())
87    }
88
89    /// Find [InterruptController] from current node or its parent
90    pub fn interrupt_parent(&self) -> Option<InterruptController<'a>> {
91        let phandle = if let Some(p) = self.meta.interrupt_parent {
92            Some(p)
93        } else {
94            self.meta_parents.interrupt_parent
95        }?;
96
97        self.fdt
98            .get_node_by_phandle(phandle)
99            .map(|node| InterruptController { node })
100    }
101
102    pub fn compatible(&self) -> Option<impl Iterator<Item = FdtResult<'a, &'a str>> + 'a> {
103        let prop = self.find_property("compatible")?;
104        let mut value = prop.data.clone();
105
106        Some(iter::from_fn(move || {
107            let s = value.take_str();
108            match s {
109                Ok(s) => {
110                    if s.is_empty() {
111                        None
112                    } else {
113                        Some(Ok(s))
114                    }
115                }
116                Err(e) => match e {
117                    FdtError::Eof => None,
118                    _ => Some(Err(e)),
119                },
120            }
121        }))
122    }
123
124    /// Get all compatible ignoring errors
125    pub fn compatibles(&self) -> impl Iterator<Item = &'a str> + 'a {
126        let mut cap_raw = self.compatible();
127
128        iter::from_fn(move || {
129            if let Some(caps) = &mut cap_raw {
130                let cap = caps.next()?.ok()?;
131                Some(cap)
132            } else {
133                None
134            }
135        })
136    }
137
138    pub fn phandle(&self) -> Option<Phandle> {
139        let prop = self.find_property("phandle")?;
140        Some(prop.u32().into())
141    }
142
143    pub fn interrupts(&self) -> Option<impl Iterator<Item = impl Iterator<Item = u32> + 'a> + 'a> {
144        let prop = self.find_property("interrupts")?;
145        let cell_size = self.interrupt_parent()?.interrupt_cells();
146
147        Some(U32Array2D::new(prop.raw_value(), cell_size))
148    }
149
150    pub fn clocks(&'a self) -> impl Iterator<Item = ClockRef<'a>> + 'a {
151        ClocksIter::new(self)
152    }
153
154    pub fn clock_frequency(&self) -> Option<u32> {
155        let prop = self.find_property("clock-frequency")?;
156        Some(prop.u32())
157    }
158
159    pub fn into_pci(self) -> Option<Pci<'a>> {
160        if self.name.contains("pci") {
161            Some(Pci { node: self })
162        } else {
163            None
164        }
165    }
166
167    pub fn status(&self) -> Option<Status> {
168        let prop = self.find_property("status")?;
169        let s = prop.str();
170
171        if s.contains("disabled") {
172            return Some(Status::Disabled);
173        }
174
175        if s.contains("okay") {
176            return Some(Status::Okay);
177        }
178
179        None
180    }
181}
182
183struct RegIter<'a> {
184    size_cell: u8,
185    address_cell: u8,
186    prop: Property<'a>,
187    ranges: Option<FdtRangeSilce<'a>>,
188}
189impl Iterator for RegIter<'_> {
190    type Item = FdtReg;
191
192    fn next(&mut self) -> Option<Self::Item> {
193        let child_bus_address = self.prop.data.take_by_cell_size(self.address_cell)?;
194
195        let mut address = child_bus_address;
196
197        if let Some(ranges) = &self.ranges {
198            for one in ranges.iter() {
199                let range_child_bus_address = one.child_bus_address().as_u64();
200                let range_parent_bus_address = one.parent_bus_address().as_u64();
201
202                if child_bus_address >= range_child_bus_address
203                    && child_bus_address < range_child_bus_address + one.size
204                {
205                    address =
206                        child_bus_address - range_child_bus_address + range_parent_bus_address;
207                    break;
208                }
209            }
210        }
211
212        let size = if self.size_cell > 0 {
213            Some(self.prop.data.take_by_cell_size(self.size_cell)? as usize)
214        } else {
215            None
216        };
217        Some(FdtReg {
218            address,
219            child_bus_address,
220            size,
221        })
222    }
223}
224
225struct PropIter<'a> {
226    fdt: &'a Fdt<'a>,
227    reader: FdtReader<'a>,
228}
229
230impl<'a> Iterator for PropIter<'a> {
231    type Item = Property<'a>;
232
233    fn next(&mut self) -> Option<Self::Item> {
234        loop {
235            match self.reader.take_token() {
236                Some(token) => match token {
237                    Token::Prop => break,
238                    Token::Nop => {}
239                    _ => return None,
240                },
241                None => return None,
242            }
243        }
244        self.reader.take_prop(self.fdt)
245    }
246}
247
248// #[derive(Clone)]
249// pub struct MemoryRegionSilce<'a> {
250//     address_cell: u8,
251//     size_cell: u8,
252//     reader: FdtReader<'a>,
253// }
254
255// impl<'a> MemoryRegionSilce<'a> {
256//     pub fn iter(&self) -> impl Iterator<Item = FdtRange> + 'a {
257//         MemoryRegionIter {
258//             address_cell: self.address_cell,
259//             size_cell: self.size_cell,
260//             reader: self.reader.clone(),
261//         }
262//     }
263// }
264
265// struct MemoryRegionIter<'a> {
266//     address_cell: u8,
267//     size_cell: u8,
268//     reader: FdtReader<'a>,
269// }
270
271// impl<'a> Iterator for MemoryRegionIter<'a> {
272//     type Item = FdtRange;
273
274//     fn next(&mut self) -> Option<Self::Item> {
275//         todo!()
276//     }
277// }