fdt_raw/node/
mod.rs

1use core::fmt;
2use core::ops::Deref;
3use core::{ffi::CStr, fmt::Debug};
4
5use crate::Fdt;
6use crate::{
7    FdtError, Token,
8    data::{Bytes, Reader},
9};
10
11mod chosen;
12mod memory;
13mod prop;
14
15pub use chosen::Chosen;
16pub use memory::{Memory, MemoryRegion};
17pub use prop::{PropIter, Property, RangeInfo, RegInfo, RegIter, VecRange};
18
19/// 节点上下文,保存从父节点继承的信息
20#[derive(Clone)]
21pub(crate) struct NodeContext {
22    /// 父节点的 #address-cells (用于解析当前节点的 reg)
23    pub address_cells: u8,
24    /// 父节点的 #size-cells (用于解析当前节点的 reg)
25    pub size_cells: u8,
26}
27
28impl Default for NodeContext {
29    fn default() -> Self {
30        NodeContext {
31            address_cells: 2,
32            size_cells: 1,
33        }
34    }
35}
36
37/// 基础节点结构
38#[derive(Clone)]
39pub struct NodeBase<'a> {
40    name: &'a str,
41    data: Bytes<'a>,
42    strings: Bytes<'a>,
43    level: usize,
44    _fdt: Fdt<'a>,
45    /// 当前节点的 #address-cells(用于子节点)
46    pub address_cells: u8,
47    /// 当前节点的 #size-cells(用于子节点)
48    pub size_cells: u8,
49    /// 继承的上下文(包含父节点的 cells 和累积的 ranges)
50    context: NodeContext,
51}
52
53impl<'a> NodeBase<'a> {
54    pub fn name(&self) -> &'a str {
55        self.name
56    }
57
58    pub fn level(&self) -> usize {
59        self.level
60    }
61
62    /// 获取节点属性迭代器
63    pub fn properties(&self) -> PropIter<'a> {
64        PropIter::new(self.data.reader(), self.strings.clone())
65    }
66
67    /// 查找指定名称的属性
68    pub fn find_property(&self, name: &str) -> Option<Property<'a>> {
69        self.properties().find(|p| p.name() == name)
70    }
71
72    /// 查找指定名称的字符串属性
73    pub fn find_property_str(&self, name: &str) -> Option<&'a str> {
74        let prop = self.find_property(name)?;
75
76        // 否则作为普通字符串处理
77        prop.as_str()
78    }
79
80    /// 查找并解析 reg 属性,返回 Reg 迭代器
81    pub fn reg(&self) -> Option<RegIter<'a>> {
82        let prop = self.find_property("reg")?;
83        Some(RegIter::new(
84            prop.data().reader(),
85            self.context.address_cells,
86            self.context.size_cells,
87        ))
88    }
89
90    /// 查找并解析 reg 属性,返回所有 RegInfo 条目
91    pub fn reg_array<const N: usize>(&self) -> heapless::Vec<RegInfo, N> {
92        let mut result = heapless::Vec::new();
93        if let Some(reg) = self.reg() {
94            for info in reg {
95                if result.push(info).is_err() {
96                    break; // 数组已满
97                }
98            }
99        }
100        result
101    }
102
103    /// 检查是否是 chosen 节点
104    fn is_chosen(&self) -> bool {
105        self.name == "chosen"
106    }
107
108    /// 检查是否是 memory 节点
109    fn is_memory(&self) -> bool {
110        self.name.starts_with("memory")
111    }
112
113    pub fn ranges(&self) -> Option<VecRange<'a>> {
114        let prop = self.find_property("ranges")?;
115        Some(VecRange::new(
116            self.address_cells as usize,
117            self.context.address_cells as usize,
118            self.context.size_cells as usize,
119            prop.data(),
120        ))
121    }
122
123    pub fn compatibles(&self) -> impl Iterator<Item = &'a str> {
124        self.find_property("compatible")
125            .into_iter()
126            .flat_map(|p| p.as_str_iter())
127    }
128}
129
130/// 写入缩进
131fn write_indent(f: &mut fmt::Formatter<'_>, count: usize, ch: &str) -> fmt::Result {
132    for _ in 0..count {
133        write!(f, "{}", ch)?;
134    }
135    Ok(())
136}
137
138impl fmt::Display for NodeBase<'_> {
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140        write_indent(f, self.level, "    ")?;
141        let name = if self.name.is_empty() { "/" } else { self.name };
142
143        writeln!(f, "{} {{", name)?;
144        for prop in self.properties() {
145            write_indent(f, self.level + 1, "    ")?;
146            writeln!(f, "{};", prop)?;
147        }
148        write_indent(f, self.level, "    ")?;
149        write!(f, "}}")
150    }
151}
152
153// ============================================================================
154// Node 枚举:支持特化节点类型
155// ============================================================================
156
157/// 节点枚举,支持 General、Chosen、Memory 等特化类型
158#[derive(Clone)]
159pub enum Node<'a> {
160    /// 通用节点
161    General(NodeBase<'a>),
162    /// Chosen 节点,包含启动参数
163    Chosen(Chosen<'a>),
164    /// Memory 节点,描述物理内存布局
165    Memory(Memory<'a>),
166}
167
168impl<'a> From<NodeBase<'a>> for Node<'a> {
169    fn from(node: NodeBase<'a>) -> Self {
170        if node.is_chosen() {
171            Node::Chosen(Chosen::new(node))
172        } else if node.is_memory() {
173            Node::Memory(Memory::new(node))
174        } else {
175            Node::General(node)
176        }
177    }
178}
179
180impl<'a> Deref for Node<'a> {
181    type Target = NodeBase<'a>;
182
183    fn deref(&self) -> &Self::Target {
184        match self {
185            Node::General(n) => n,
186            Node::Chosen(c) => c.deref(),
187            Node::Memory(m) => m.deref(),
188        }
189    }
190}
191
192impl fmt::Display for Node<'_> {
193    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194        Debug::fmt(self, f)
195    }
196}
197
198impl fmt::Debug for Node<'_> {
199    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200        match self {
201            Node::General(n) => f.debug_tuple("General").field(&n.name()).finish(),
202            Node::Chosen(c) => c.fmt(f),
203            Node::Memory(m) => m.fmt(f),
204        }
205    }
206}
207
208/// 解析属性时提取的关键信息
209#[derive(Debug, Clone, Default)]
210pub(crate) struct ParsedProps {
211    pub address_cells: Option<u8>,
212    pub size_cells: Option<u8>,
213}
214
215/// 单节点迭代状态
216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217pub(crate) enum OneNodeState {
218    /// 正在处理当前节点
219    Processing,
220    /// 遇到子节点的 BeginNode,需要回溯
221    ChildBegin,
222    /// 遇到 EndNode,当前节点处理完成
223    End,
224}
225
226/// An iterator over a single node's content.
227/// When encountering a child's BeginNode, it backtracks and signals FdtIter to handle it.
228pub(crate) struct OneNodeIter<'a> {
229    reader: Reader<'a>,
230    strings: Bytes<'a>,
231    state: OneNodeState,
232    level: usize,
233    context: NodeContext,
234    parsed_props: ParsedProps,
235    fdt: Fdt<'a>,
236}
237
238impl<'a> OneNodeIter<'a> {
239    pub fn new(
240        reader: Reader<'a>,
241        strings: Bytes<'a>,
242        level: usize,
243        context: NodeContext,
244        fdt: Fdt<'a>,
245    ) -> Self {
246        Self {
247            reader,
248            strings,
249            state: OneNodeState::Processing,
250            level,
251            context,
252            parsed_props: ParsedProps::default(),
253            fdt,
254        }
255    }
256
257    pub fn reader(&self) -> &Reader<'a> {
258        &self.reader
259    }
260
261    pub fn parsed_props(&self) -> &ParsedProps {
262        &self.parsed_props
263    }
264
265    /// 读取节点名称(在 BeginNode token 之后调用)
266    pub fn read_node_name(&mut self) -> Result<NodeBase<'a>, FdtError> {
267        // 读取以 null 结尾的名称字符串
268        let name = self.read_cstr()?;
269
270        // 对齐到 4 字节边界
271        self.align4();
272
273        let data = self.reader.remain();
274
275        Ok(NodeBase {
276            name,
277            data,
278            strings: self.strings.clone(),
279            level: self.level,
280            // 默认值,会在 process() 中更新
281            address_cells: 2,
282            size_cells: 1,
283            context: self.context.clone(),
284            _fdt: self.fdt.clone(),
285        })
286    }
287
288    fn read_cstr(&mut self) -> Result<&'a str, FdtError> {
289        let bytes = self.reader.remain();
290        let cstr = CStr::from_bytes_until_nul(bytes.as_slice())?;
291        let s = cstr.to_str()?;
292        // 跳过字符串内容 + null 终止符
293        let _ = self.reader.read_bytes(s.len() + 1);
294        Ok(s)
295    }
296
297    fn align4(&mut self) {
298        let pos = self.reader.position();
299        let aligned = (pos + 3) & !3;
300        let skip = aligned - pos;
301        if skip > 0 {
302            let _ = self.reader.read_bytes(skip);
303        }
304    }
305
306    /// 从 strings block 读取属性名
307    fn read_prop_name(&self, nameoff: u32) -> Result<&'a str, FdtError> {
308        let bytes = self.strings.slice(nameoff as usize..self.strings.len());
309        let cstr = CStr::from_bytes_until_nul(bytes.as_slice())?;
310        Ok(cstr.to_str()?)
311    }
312
313    /// 读取 u32 从大端字节
314    fn read_u32_be(data: &[u8], offset: usize) -> u64 {
315        u32::from_be_bytes(data[offset..offset + 4].try_into().unwrap()) as u64
316    }
317
318    /// 处理节点内容,解析关键属性,遇到子节点或结束时返回
319    pub fn process(&mut self) -> Result<OneNodeState, FdtError> {
320        loop {
321            let token = self.reader.read_token()?;
322            match token {
323                Token::BeginNode => {
324                    // 遇到子节点,回溯 token 并返回
325                    self.reader.backtrack(4);
326                    self.state = OneNodeState::ChildBegin;
327                    return Ok(OneNodeState::ChildBegin);
328                }
329                Token::EndNode => {
330                    self.state = OneNodeState::End;
331                    return Ok(OneNodeState::End);
332                }
333                Token::Prop => {
334                    // 读取属性:len 和 nameoff
335                    let len = self.reader.read_u32().ok_or(FdtError::BufferTooSmall {
336                        pos: self.reader.position(),
337                    })? as usize;
338
339                    let nameoff = self.reader.read_u32().ok_or(FdtError::BufferTooSmall {
340                        pos: self.reader.position(),
341                    })?;
342
343                    // 读取属性数据
344                    let prop_data = if len > 0 {
345                        self.reader
346                            .read_bytes(len)
347                            .ok_or(FdtError::BufferTooSmall {
348                                pos: self.reader.position(),
349                            })?
350                    } else {
351                        Bytes::new(&[])
352                    };
353
354                    // 解析关键属性
355                    if let Ok(prop_name) = self.read_prop_name(nameoff) {
356                        match prop_name {
357                            "#address-cells" if len == 4 => {
358                                self.parsed_props.address_cells =
359                                    Some(Self::read_u32_be(&prop_data, 0) as u8);
360                            }
361                            "#size-cells" if len == 4 => {
362                                self.parsed_props.size_cells =
363                                    Some(Self::read_u32_be(&prop_data, 0) as u8);
364                            }
365                            _ => {}
366                        }
367                    }
368
369                    // 对齐到 4 字节边界
370                    self.align4();
371                }
372                Token::Nop => {
373                    // 忽略 NOP
374                }
375                Token::End => {
376                    // 结构块结束
377                    self.state = OneNodeState::End;
378                    return Ok(OneNodeState::End);
379                }
380                Token::Data(_) => {
381                    // 非法 token
382                    return Err(FdtError::BufferTooSmall {
383                        pos: self.reader.position(),
384                    });
385                }
386            }
387        }
388    }
389}