1use core::fmt;
2
3use alloc::vec::Vec;
4
5use crate::{
6 ClockType, Node, NodeKind, NodeMut, NodeRef, NodeRefClock, NodeRefInterruptController,
7 NodeRefMemory, Property,
8};
9
10pub 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 let address_cells = 2; let size_cells = 1; 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 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 writeln!(f, "/ {{")?;
163 } else {
164 write!(f, "{}", self.node.name)?;
166
167 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 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 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 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
227pub 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 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}