fdt_raw/node/
mod.rs

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