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 pub address: u64,
76 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#[derive(Clone)]
98pub struct FdtRange<'a> {
99 data_child: Raw<'a>,
100 data_parent: Raw<'a>,
101 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}