|
16 | 16 | //! [Flattened Device Tree (FDT)]: https://devicetree-specification.readthedocs.io/en/latest/chapter5-flattened-format.html |
17 | 17 |
|
18 | 18 | use crate::error::{FdtError, FdtErrorKind}; |
| 19 | +use crate::memreserve::MemoryReservation; |
19 | 20 | mod node; |
20 | 21 | mod property; |
21 | 22 | use core::ffi::CStr; |
@@ -312,6 +313,34 @@ impl<'a> Fdt<'a> { |
312 | 313 | self.header().boot_cpuid_phys() |
313 | 314 | } |
314 | 315 |
|
| 316 | + /// Returns an iterator over the memory reservation block. |
| 317 | + pub fn memory_reservations( |
| 318 | + &self, |
| 319 | + ) -> impl Iterator<Item = Result<MemoryReservation, FdtError>> + '_ { |
| 320 | + let mut offset = self.header().off_mem_rsvmap() as usize; |
| 321 | + core::iter::from_fn(move || { |
| 322 | + if offset >= self.header().off_dt_struct() as usize { |
| 323 | + return Some(Err(FdtError::new( |
| 324 | + FdtErrorKind::MemReserveNotTerminated, |
| 325 | + offset, |
| 326 | + ))); |
| 327 | + } |
| 328 | + |
| 329 | + let reservation = match MemoryReservation::ref_from_prefix(&self.data[offset..]) |
| 330 | + .map_err(|_| FdtError::new(FdtErrorKind::MemReserveInvalid, offset)) |
| 331 | + { |
| 332 | + Ok((reservation, _)) => *reservation, |
| 333 | + Err(e) => return Some(Err(e)), |
| 334 | + }; |
| 335 | + offset += size_of::<MemoryReservation>(); |
| 336 | + |
| 337 | + if reservation == MemoryReservation::TERMINATOR { |
| 338 | + return None; |
| 339 | + } |
| 340 | + Some(Ok(reservation)) |
| 341 | + }) |
| 342 | + } |
| 343 | + |
315 | 344 | /// Returns the root node of the device tree. |
316 | 345 | /// |
317 | 346 | /// # Errors |
@@ -498,6 +527,15 @@ impl<'a> Fdt<'a> { |
498 | 527 | impl fmt::Display for Fdt<'_> { |
499 | 528 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
500 | 529 | writeln!(f, "/dts-v1/;")?; |
| 530 | + for reservation in self.memory_reservations() { |
| 531 | + let reservation = reservation.map_err(|_| fmt::Error)?; |
| 532 | + writeln!( |
| 533 | + f, |
| 534 | + "/memreserve/ {:#x} {:#x};", |
| 535 | + reservation.address(), |
| 536 | + reservation.size() |
| 537 | + )?; |
| 538 | + } |
501 | 539 | writeln!(f)?; |
502 | 540 | let root = self.root().map_err(|_| fmt::Error)?; |
503 | 541 | root.fmt_recursive(f, 0) |
|
0 commit comments