|
1 | 1 | #![allow(dead_code)]
|
2 | 2 |
|
3 | 3 | use {
|
4 |
| - crate::println, |
5 |
| - core::alloc::Layout, |
| 4 | + crate::{print, println}, |
| 5 | + core::{alloc::Layout, mem::size_of, ptr::read_unaligned}, |
6 | 6 | fdt_rs::{
|
7 |
| - base::DevTree, |
8 |
| - error::DevTreeError, |
| 7 | + base::{iters::StringPropIter, DevTree}, |
| 8 | + error::{DevTreeError, Result as DevTreeResult}, |
9 | 9 | index::{DevTreeIndex, DevTreeIndexNode, DevTreeIndexProp},
|
10 |
| - prelude::PropReader, |
| 10 | + prelude::{PropReader, *}, |
11 | 11 | },
|
12 | 12 | shrinkwraprs::Shrinkwrap,
|
13 | 13 | };
|
@@ -54,7 +54,7 @@ pub fn get_size_cells<'a, 'i: 'a, 'dt: 'i>(node: DevTreeIndexNode<'a, 'i, 'dt>)
|
54 | 54 | /// This requires allocation of a single buffer, which is done at boot time via bump allocator.
|
55 | 55 | /// This means we can only parse the tree after bump allocator is initialized.
|
56 | 56 | #[derive(Shrinkwrap)]
|
57 |
| -pub struct DeviceTree<'a>(DevTreeIndex<'a, 'a>); |
| 57 | +pub struct DeviceTree<'a>(pub DevTreeIndex<'a, 'a>); |
58 | 58 |
|
59 | 59 | impl<'a> DeviceTree<'a> {
|
60 | 60 | pub fn layout(tree: DevTree<'a>) -> Result<Layout, DevTreeError> {
|
@@ -149,6 +149,7 @@ impl<'a, 'i: 'a, 'dt: 'i> Iterator for PayloadPairsIter<'a, 'i, 'dt> {
|
149 | 149 | /// Return a pair of (address, size) values on each iteration.
|
150 | 150 | type Item = (u64, u64);
|
151 | 151 | fn next(&mut self) -> Option<Self::Item> {
|
| 152 | + println!("Offset {}, total {}", self.offset, self.total); |
152 | 153 | if self.offset >= self.total {
|
153 | 154 | return None;
|
154 | 155 | }
|
@@ -354,3 +355,128 @@ mod tests {
|
354 | 355 | assert_eq!(path.move_next(), false);
|
355 | 356 | }
|
356 | 357 | }
|
| 358 | + |
| 359 | +//================================================================================================= |
| 360 | +// Dump the entire FDT |
| 361 | +// From https://github.com/rs-embedded/fdtdump/blob/master/src/main.rs |
| 362 | +//================================================================================================= |
| 363 | + |
| 364 | +fn are_printable_strings(mut prop_iter: StringPropIter) -> bool { |
| 365 | + loop { |
| 366 | + match prop_iter.next() { |
| 367 | + Ok(Some(s_ref)) => { |
| 368 | + if s_ref.is_empty() { |
| 369 | + return false; |
| 370 | + } |
| 371 | + } |
| 372 | + Ok(None) => return true, |
| 373 | + Err(_) => return false, |
| 374 | + } |
| 375 | + } |
| 376 | +} |
| 377 | + |
| 378 | +pub struct FdtDumper { |
| 379 | + pub indent: usize, |
| 380 | +} |
| 381 | + |
| 382 | +impl<'i, 'dt> FdtDumper { |
| 383 | + fn push_indent(&mut self) { |
| 384 | + for _ in 0..self.indent { |
| 385 | + print!(" "); |
| 386 | + } |
| 387 | + } |
| 388 | + |
| 389 | + fn dump_node_name(&mut self, name: &str) { |
| 390 | + self.push_indent(); |
| 391 | + print!("{}", name); |
| 392 | + println!(" {{"); |
| 393 | + } |
| 394 | + |
| 395 | + fn dump_node(&mut self, node: &DevTreeIndexNode) -> DevTreeResult<()> { |
| 396 | + let mut name = node.name()?; |
| 397 | + if name.is_empty() { |
| 398 | + name = "/"; |
| 399 | + } else { |
| 400 | + name = node.name()?; |
| 401 | + } |
| 402 | + self.dump_node_name(name); |
| 403 | + Ok(()) |
| 404 | + } |
| 405 | + |
| 406 | + fn dump_property(&mut self, prop: DevTreeIndexProp) -> DevTreeResult<()> { |
| 407 | + self.push_indent(); |
| 408 | + |
| 409 | + print!("{}", prop.name()?); |
| 410 | + |
| 411 | + if prop.length() == 0 { |
| 412 | + println!(";"); |
| 413 | + return Ok(()); |
| 414 | + } |
| 415 | + print!(" = "); |
| 416 | + |
| 417 | + // Unsafe Ok - we're reinterpreting the data as expected. |
| 418 | + unsafe { |
| 419 | + // First try to parse as an array of strings |
| 420 | + if are_printable_strings(prop.iter_str()) { |
| 421 | + let mut iter = prop.iter_str(); |
| 422 | + while let Some(s) = iter.next()? { |
| 423 | + print!("\"{}\", ", s); |
| 424 | + } |
| 425 | + // let _ = self.dump.pop(); |
| 426 | + // let _ = self.dump.pop(); |
| 427 | + } else if prop.propbuf().len() % size_of::<u32>() == 0 { |
| 428 | + print!("<"); |
| 429 | + for val in prop.propbuf().chunks_exact(size_of::<u32>()) { |
| 430 | + // We use read_unaligned |
| 431 | + #[allow(clippy::cast_ptr_alignment)] |
| 432 | + let v = read_unaligned::<u32>(val.as_ptr() as *const u32); |
| 433 | + let v = u32::from_be(v); |
| 434 | + print!("{:#010x} ", v); |
| 435 | + } |
| 436 | + // let _ = self.dump.pop(); // Pop off extra space |
| 437 | + print!(">"); |
| 438 | + } else { |
| 439 | + print!("["); |
| 440 | + for val in prop.propbuf() { |
| 441 | + print!("{:02x} ", val); |
| 442 | + } |
| 443 | + // let _ = self.dump.pop(); // Pop off extra space |
| 444 | + print!("]"); |
| 445 | + } |
| 446 | + } |
| 447 | + |
| 448 | + println!(";"); |
| 449 | + Ok(()) |
| 450 | + } |
| 451 | + |
| 452 | + pub fn dump_level(&mut self, node: &DevTreeIndexNode) -> DevTreeResult<()> { |
| 453 | + self.dump_node(node)?; |
| 454 | + self.indent += 1; |
| 455 | + for prop in node.props() { |
| 456 | + let _ = self.dump_property(prop)?; |
| 457 | + } |
| 458 | + for child in node.children() { |
| 459 | + let _ = self.dump_level(&child)?; |
| 460 | + } |
| 461 | + self.indent -= 1; |
| 462 | + self.push_indent(); |
| 463 | + println!("}};"); |
| 464 | + Ok(()) |
| 465 | + } |
| 466 | + |
| 467 | + pub fn dump_metadata(&mut self, index: &DevTreeIndex) { |
| 468 | + let fdt = index.fdt(); |
| 469 | + println!("// magic:\t\t{:#x}", fdt.magic()); |
| 470 | + let s = fdt.totalsize(); |
| 471 | + println!("// totalsize:\t\t{:#x} ({})", s, s); |
| 472 | + println!("// off_dt_struct:\t{:#x}", fdt.off_dt_struct()); |
| 473 | + println!("// off_dt_strings:\t{:#x}", fdt.off_dt_strings()); |
| 474 | + println!("// off_mem_rsvmap:\t{:#x}", fdt.off_mem_rsvmap()); |
| 475 | + println!("// version:\t\t{:}", fdt.version()); |
| 476 | + println!("// last_comp_version:\t{:}", fdt.last_comp_version()); |
| 477 | + println!("// boot_cpuid_phys:\t{:#x}", fdt.boot_cpuid_phys()); |
| 478 | + println!("// size_dt_strings:\t{:#x}", fdt.size_dt_strings()); |
| 479 | + println!("// size_dt_struct:\t{:#x}", fdt.size_dt_struct()); |
| 480 | + println!(); |
| 481 | + } |
| 482 | +} |
0 commit comments