fdt_parser/
define.rs

1use core::fmt::{Debug, Display};
2
3use crate::data::{Buffer, Raw, U32Iter};
4
5pub const FDT_MAGIC: u32 = 0xd00dfeed;
6
7#[derive(Debug, PartialEq, Eq, Clone, Copy)]
8pub(crate) enum Token {
9    BeginNode,
10    EndNode,
11    Prop,
12    Nop,
13    End,
14    Data,
15}
16
17impl From<u32> for Token {
18    fn from(value: u32) -> Self {
19        match value {
20            0x1 => Token::BeginNode,
21            0x2 => Token::EndNode,
22            0x3 => Token::Prop,
23            0x4 => Token::Nop,
24            0x9 => Token::End,
25            _ => Token::Data,
26        }
27    }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
31pub enum Status {
32    Okay,
33    Disabled,
34}
35
36#[derive(Clone, Copy)]
37pub struct MemoryRegion {
38    pub address: *mut u8,
39    pub size: usize,
40}
41
42impl Debug for MemoryRegion {
43    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
44        f.write_fmt(format_args!(
45            "MemoryRegion {{ address: {:p}, size: {:#x} }}",
46            self.address, self.size
47        ))
48    }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
52#[repr(transparent)]
53pub struct Phandle(u32);
54
55impl From<u32> for Phandle {
56    fn from(value: u32) -> Self {
57        Self(value)
58    }
59}
60impl Phandle {
61    pub fn as_usize(&self) -> usize {
62        self.0 as usize
63    }
64}
65
66impl Display for Phandle {
67    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
68        write!(f, "<{:#x}>", self.0)
69    }
70}
71
72#[derive(Clone, Copy)]
73pub struct FdtReg {
74    /// parent bus address
75    pub address: u64,
76    /// child bus address
77    pub child_bus_address: u64,
78    pub size: Option<usize>,
79}
80
81impl Debug for FdtReg {
82    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83        f.write_fmt(format_args!("<{:#x}", self.address))?;
84        if self.child_bus_address != self.address {
85            f.write_fmt(format_args!("({:#x})", self.child_bus_address))?;
86        }
87        f.write_fmt(format_args!(", "))?;
88        if let Some(s) = self.size {
89            f.write_fmt(format_args!("{:#x}>", s))
90        } else {
91            f.write_str("None>")
92        }
93    }
94}
95
96/// Range mapping child bus addresses to parent bus addresses
97#[derive(Clone)]
98pub struct FdtRange<'a> {
99    data_child: Raw<'a>,
100    data_parent: Raw<'a>,
101    /// Size of range
102    pub size: u64,
103}
104
105impl<'a> FdtRange<'a> {
106    pub fn child_bus_address(&self) -> U32Iter<'a> {
107        U32Iter::new(self.data_child)
108    }
109
110    pub fn parent_bus_address(&self) -> U32Iter<'a> {
111        U32Iter::new(self.data_parent)
112    }
113}
114
115impl core::fmt::Debug for FdtRange<'_> {
116    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117        f.write_str("Range {{ child_bus_address: [ ")?;
118        for addr in self.child_bus_address() {
119            f.write_fmt(format_args!("{:#x} ", addr))?;
120        }
121        f.write_str("], parent_bus_address: [ ")?;
122        for addr in self.parent_bus_address() {
123            f.write_fmt(format_args!("{:#x} ", addr))?;
124        }
125        f.write_fmt(format_args!("], size: {:#x}", self.size))
126    }
127}
128
129#[derive(Clone)]
130pub struct FdtRangeSilce<'a> {
131    address_cell: u8,
132    address_cell_parent: u8,
133    size_cell: u8,
134    reader: Buffer<'a>,
135}
136
137impl<'a> FdtRangeSilce<'a> {
138    pub(crate) fn new(
139        address_cell: u8,
140        address_cell_parent: u8,
141        size_cell: u8,
142        raw: &Raw<'a>,
143    ) -> Self {
144        Self {
145            address_cell,
146            address_cell_parent,
147            size_cell,
148            reader: raw.buffer(),
149        }
150    }
151
152    pub fn iter(&self) -> FdtRangeIter<'a> {
153        FdtRangeIter { s: self.clone() }
154    }
155}
156#[derive(Clone)]
157pub struct FdtRangeIter<'a> {
158    s: FdtRangeSilce<'a>,
159}
160
161impl<'a> Iterator for FdtRangeIter<'a> {
162    type Item = FdtRange<'a>;
163
164    fn next(&mut self) -> Option<Self::Item> {
165        let child_address_bytes = self.s.address_cell as usize * size_of::<u32>();
166        let data_child = self.s.reader.take(child_address_bytes).ok()?;
167
168        let parent_address_bytes = self.s.address_cell_parent as usize * size_of::<u32>();
169        let data_parent = self.s.reader.take(parent_address_bytes).ok()?;
170
171        let size = self.s.reader.take_by_cell_size(self.s.size_cell)?;
172        Some(FdtRange {
173            size,
174            data_child,
175            data_parent,
176        })
177    }
178}