fdt_edit/node/
display.rs

1use core::fmt;
2
3use alloc::vec::Vec;
4
5use crate::{
6    ClockType, Node, NodeKind, NodeMut, NodeRef, NodeRefClock, NodeRefInterruptController,
7    NodeRefMemory, Property,
8};
9
10/// Node 的 DTS 显示格式化器
11pub struct NodeDisplay<'a> {
12    node: &'a Node,
13    indent: usize,
14    show_address: bool,
15    show_size: bool,
16}
17
18impl<'a> NodeDisplay<'a> {
19    pub fn new(node: &'a Node) -> Self {
20        Self {
21            node,
22            indent: 0,
23            show_address: true,
24            show_size: true,
25        }
26    }
27
28    pub fn indent(mut self, indent: usize) -> Self {
29        self.indent = indent;
30        self
31    }
32
33    pub fn show_address(mut self, show: bool) -> Self {
34        self.show_address = show;
35        self
36    }
37
38    pub fn show_size(mut self, show: bool) -> Self {
39        self.show_size = show;
40        self
41    }
42
43    fn format_indent(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        for _ in 0..self.indent {
45            write!(f, "    ")?;
46        }
47        Ok(())
48    }
49
50    fn format_property(&self, prop: &Property, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        self.format_indent(f)?;
52        match prop.name() {
53            "reg" => {
54                if self.show_address || self.show_size {
55                    write!(f, "reg = ")?;
56                    self.format_reg_values(prop, f)?;
57                } else {
58                    write!(f, "reg;")?;
59                }
60            }
61            "compatible" => {
62                write!(f, "compatible = ")?;
63                self.format_string_list(prop, f)?;
64            }
65            "clock-names" | "pinctrl-names" | "reg-names" => {
66                write!(f, "{} = ", prop.name())?;
67                self.format_string_list(prop, f)?;
68            }
69            "interrupt-controller"
70            | "#address-cells"
71            | "#size-cells"
72            | "#interrupt-cells"
73            | "#clock-cells"
74            | "phandle" => {
75                write!(f, "{};", prop.name())?;
76            }
77            _ => {
78                write!(f, "{} = ", prop.name())?;
79                self.format_property_value(prop, f)?;
80            }
81        }
82        writeln!(f)
83    }
84
85    fn format_reg_values(&self, prop: &Property, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        let mut reader = prop.as_reader();
87        let mut first = true;
88        write!(f, "<")?;
89
90        // 获取 parent 的 address-cells 和 size-cells
91        // 这里需要从上下文获取,暂时使用默认值
92        let address_cells = 2; // 默认值
93        let size_cells = 1; // 默认值
94
95        while let (Some(addr), Some(size)) = (
96            reader.read_cells(address_cells),
97            reader.read_cells(size_cells),
98        ) {
99            if !first {
100                write!(f, " ")?;
101            }
102            first = false;
103
104            if self.show_address {
105                write!(f, "0x{:x}", addr)?;
106            }
107            if self.show_size && size > 0 {
108                if self.show_address {
109                    write!(f, " ")?;
110                }
111                write!(f, "0x{:x}", size)?;
112            }
113        }
114
115        write!(f, ">;")
116    }
117
118    fn format_string_list(&self, prop: &Property, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119        let iter = prop.as_str_iter();
120        let mut first = true;
121        write!(f, "\"")?;
122        for s in iter {
123            if !first {
124                write!(f, "\", \"")?;
125            }
126            first = false;
127            write!(f, "{}", s)?;
128        }
129        write!(f, "\";")
130    }
131
132    fn format_property_value(&self, prop: &Property, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133        if let Some(s) = prop.as_str() {
134            write!(f, "\"{}\";", s)
135        } else if let Some(u32_val) = prop.get_u32() {
136            write!(f, "<0x{:x}>;", u32_val)
137        } else if let Some(u64_val) = prop.get_u64() {
138            write!(f, "<0x{:x}>;", u64_val)
139        } else {
140            // 尝试格式化为字节数组
141            let mut reader = prop.as_reader();
142            let mut first = true;
143            write!(f, "<")?;
144            while let Some(val) = reader.read_u32() {
145                if !first {
146                    write!(f, " ")?;
147                }
148                first = false;
149                write!(f, "0x{:02x}", val)?;
150            }
151            write!(f, ">;")
152        }
153    }
154}
155
156impl<'a> fmt::Display for NodeDisplay<'a> {
157    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158        self.format_indent(f)?;
159
160        if self.node.name.is_empty() {
161            // 根节点
162            writeln!(f, "/ {{")?;
163        } else {
164            // 普通节点
165            write!(f, "{}", self.node.name)?;
166
167            // 检查是否有地址和大小属性需要显示
168            let mut props = Vec::new();
169            for prop in self.node.properties() {
170                if prop.name() != "reg" {
171                    props.push(prop);
172                }
173            }
174
175            if !props.is_empty() {
176                writeln!(f, " {{")?;
177            } else {
178                writeln!(f, ";")?;
179                return Ok(());
180            }
181        }
182
183        // 输出属性
184        for prop in self.node.properties() {
185            if prop.name() != "reg" || self.show_address || self.show_size {
186                self.format_property(prop, f)?;
187            }
188        }
189
190        // 输出子节点
191        for child in self.node.children() {
192            let child_display = NodeDisplay::new(child)
193                .indent(self.indent + 1)
194                .show_address(self.show_address)
195                .show_size(self.show_size);
196            write!(f, "{}", child_display)?;
197        }
198
199        // 关闭节点
200        self.format_indent(f)?;
201        writeln!(f, "}};")?;
202
203        Ok(())
204    }
205}
206
207impl fmt::Display for Node {
208    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209        let display = NodeDisplay::new(self);
210        write!(f, "{}", display)
211    }
212}
213
214impl fmt::Debug for Node {
215    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216        f.debug_struct("Node")
217            .field("name", &self.name)
218            .field("children_count", &self.children.len())
219            .field("properties_count", &self.properties.len())
220            .field("phandle", &self.phandle())
221            .field("address_cells", &self.address_cells())
222            .field("size_cells", &self.size_cells())
223            .finish()
224    }
225}
226
227/// NodeRef 的显示格式化器
228pub struct NodeRefDisplay<'a> {
229    node_ref: &'a NodeRef<'a>,
230    indent: usize,
231    show_details: bool,
232}
233
234impl<'a> NodeRefDisplay<'a> {
235    pub fn new(node_ref: &'a NodeRef<'a>) -> Self {
236        Self {
237            node_ref,
238            indent: 0,
239            show_details: true,
240        }
241    }
242
243    pub fn indent(mut self, indent: usize) -> Self {
244        self.indent = indent;
245        self
246    }
247
248    pub fn show_details(mut self, show: bool) -> Self {
249        self.show_details = show;
250        self
251    }
252
253    fn format_type_info(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254        match self.node_ref.as_ref() {
255            NodeKind::Clock(clock) => {
256                write!(f, "Clock Node: ")?;
257                if let ClockType::Fixed(fixed) = &clock.kind {
258                    write!(f, "Fixed Clock (freq={}Hz", fixed.frequency)?;
259                    if let Some(accuracy) = fixed.accuracy {
260                        write!(f, ", accuracy={})", accuracy)?;
261                    }
262                    write!(f, ")")?;
263                } else {
264                    write!(f, "Clock Provider")?;
265                }
266                if !clock.clock_output_names.is_empty() {
267                    write!(f, ", outputs: {:?}", clock.clock_output_names)?;
268                }
269                write!(f, ", cells={}", clock.clock_cells)?;
270            }
271            NodeKind::Pci(pci) => {
272                write!(f, "PCI Node")?;
273                if let Some(bus_range) = pci.bus_range() {
274                    write!(f, " (bus range: {:?})", bus_range)?;
275                }
276                write!(f, ", interrupt-cells={}", pci.interrupt_cells())?;
277            }
278            NodeKind::InterruptController(ic) => {
279                write!(f, "Interrupt Controller")?;
280                if let Some(cells) = ic.interrupt_cells() {
281                    write!(f, " (interrupt-cells={})", cells)?;
282                }
283                let compatibles = ic.compatibles();
284                if !compatibles.is_empty() {
285                    write!(f, ", compatible: {:?}", compatibles)?;
286                }
287            }
288            NodeKind::Memory(mem) => {
289                write!(f, "Memory Node")?;
290                let regions = mem.regions();
291                if !regions.is_empty() {
292                    write!(f, " ({} regions)", regions.len())?;
293                    for (i, region) in regions.iter().take(3).enumerate() {
294                        write!(
295                            f,
296                            "\n    [{}]: 0x{:x}-0x{:x}",
297                            i,
298                            region.address,
299                            region.address + region.size
300                        )?;
301                    }
302                }
303                if let Some(dt) = mem.device_type() {
304                    write!(f, ", device_type={}", dt)?;
305                }
306            }
307            NodeKind::Generic(_) => {
308                write!(f, "Generic Node")?;
309            }
310        }
311        Ok(())
312    }
313}
314
315impl<'a> fmt::Display for NodeRefDisplay<'a> {
316    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317        for _ in 0..self.indent {
318            write!(f, "    ")?;
319        }
320
321        if self.show_details {
322            write!(f, "{}: ", self.node_ref.name())?;
323            self.format_type_info(f)?;
324            writeln!(f)?;
325
326            // 添加缩进并显示 DTS
327            let dts_display = NodeDisplay::new(self.node_ref).indent(self.indent + 1);
328            write!(f, "{}", dts_display)?;
329        } else {
330            write!(f, "{}", self.node_ref.name())?;
331        }
332
333        Ok(())
334    }
335}
336
337impl fmt::Display for NodeRef<'_> {
338    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339        let display = NodeRefDisplay::new(self);
340        write!(f, "{}", display)
341    }
342}
343
344impl fmt::Debug for NodeRef<'_> {
345    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346        f.debug_struct("NodeRef")
347            .field("name", &self.name())
348            .field("path", &self.path())
349            .field(
350                "node_type",
351                &match self.as_ref() {
352                    NodeKind::Clock(_) => "Clock",
353                    NodeKind::Pci(_) => "PCI",
354                    NodeKind::InterruptController(_) => "InterruptController",
355                    NodeKind::Memory(_) => "Memory",
356                    NodeKind::Generic(_) => "Generic",
357                },
358            )
359            .field("phandle", &self.phandle())
360            .finish()
361    }
362}
363
364impl fmt::Debug for NodeRefClock<'_> {
365    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366        f.debug_struct("NodeRefClock")
367            .field("name", &self.name())
368            .field("clock_cells", &self.clock_cells)
369            .field("clock_type", &self.kind)
370            .field("output_names", &self.clock_output_names)
371            .field("phandle", &self.phandle())
372            .finish()
373    }
374}
375
376impl fmt::Debug for NodeRefInterruptController<'_> {
377    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378        f.debug_struct("NodeRefInterruptController")
379            .field("name", &self.name())
380            .field("interrupt_cells", &self.interrupt_cells())
381            .field("interrupt_address_cells", &self.interrupt_address_cells())
382            .field("is_interrupt_controller", &self.is_interrupt_controller())
383            .field("compatibles", &self.compatibles())
384            .field("phandle", &self.phandle())
385            .finish()
386    }
387}
388
389impl fmt::Debug for NodeRefMemory<'_> {
390    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391        f.debug_struct("NodeRefMemory")
392            .field("name", &self.name())
393            .field("regions_count", &self.regions().len())
394            .field("device_type", &self.device_type())
395            .field("phandle", &self.phandle())
396            .finish()
397    }
398}
399
400impl fmt::Display for NodeRefClock<'_> {
401    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402        let node_ref = crate::NodeRef::Clock(self.clone());
403        let display = NodeRefDisplay::new(&node_ref);
404        write!(f, "{}", display)
405    }
406}
407
408impl fmt::Display for NodeRefInterruptController<'_> {
409    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410        let node_ref = crate::NodeRef::InterruptController(self.clone());
411        let display = NodeRefDisplay::new(&node_ref);
412        write!(f, "{}", display)
413    }
414}
415
416impl fmt::Display for NodeRefMemory<'_> {
417    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
418        let node_ref = crate::NodeRef::Memory(self.clone());
419        let display = NodeRefDisplay::new(&node_ref);
420        write!(f, "{}", display)
421    }
422}
423
424impl fmt::Display for NodeMut<'_> {
425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426        match self {
427            NodeMut::Gerneric(generic) => {
428                let display = NodeDisplay::new(generic.node);
429                write!(f, "{}", display)
430            }
431        }
432    }
433}
434
435impl fmt::Debug for NodeMut<'_> {
436    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
437        f.debug_struct("NodeMut")
438            .field(
439                "name",
440                &match self {
441                    NodeMut::Gerneric(generic) => generic.node.name(),
442                },
443            )
444            .field("node_type", &"Generic")
445            .field(
446                "children_count",
447                &match self {
448                    NodeMut::Gerneric(generic) => generic.node.children.len(),
449                },
450            )
451            .field(
452                "properties_count",
453                &match self {
454                    NodeMut::Gerneric(generic) => generic.node.properties.len(),
455                },
456            )
457            .finish()
458    }
459}