1use core::{
2 fmt::{Debug, Display},
3 ptr::NonNull,
4};
5
6use crate::{
7 error::*,
8 read::{FdtReader, U32Array},
9};
10
11#[derive(Debug, PartialEq, Eq, Clone, Copy)]
12pub enum Token {
13 BeginNode,
14 EndNode,
15 Prop,
16 Nop,
17 End,
18 Data,
19}
20impl From<u32> for Token {
21 fn from(value: u32) -> Self {
22 match value {
23 0x1 => Token::BeginNode,
24 0x2 => Token::EndNode,
25 0x3 => Token::Prop,
26 0x4 => Token::Nop,
27 0x9 => Token::End,
28 _ => Token::Data,
29 }
30 }
31}
32
33#[derive(Debug, Clone, Copy)]
34#[repr(transparent)]
35pub struct Fdt32([u8; 4]);
36
37impl Fdt32 {
38 pub const fn new() -> Self {
39 Self([0; 4])
40 }
41
42 pub fn get(self) -> u32 {
43 u32::from_be_bytes(self.0)
44 }
45}
46
47impl From<&[u8]> for Fdt32 {
48 fn from(value: &[u8]) -> Self {
49 Fdt32(value.get(..4).unwrap().try_into().unwrap())
50 }
51}
52
53impl Default for Fdt32 {
54 fn default() -> Self {
55 Self::new()
56 }
57}
58
59#[derive(Debug, Clone, Copy)]
60#[repr(transparent)]
61pub struct Fdt64([u8; 8]);
62
63impl Fdt64 {
64 pub const fn new() -> Self {
65 Self([0; 8])
66 }
67
68 pub fn get(&self) -> u64 {
69 u64::from_be_bytes(self.0)
70 }
71}
72impl From<&[u8]> for Fdt64 {
73 fn from(value: &[u8]) -> Self {
74 Self(value.get(..8).unwrap().try_into().unwrap())
75 }
76}
77impl Default for Fdt64 {
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq)]
85pub struct RawReg<'a> {
86 pub address: &'a [u8],
89 pub size: &'a [u8],
92}
93#[derive(Debug, Clone, Copy)]
94#[repr(C)]
95pub struct FdtHeader {
96 pub magic: Fdt32,
98 pub totalsize: Fdt32,
100 pub off_dt_struct: Fdt32,
102 pub off_dt_strings: Fdt32,
104 pub off_mem_rsvmap: Fdt32,
107 pub version: Fdt32,
109 pub last_comp_version: Fdt32,
111 pub boot_cpuid_phys: Fdt32,
113 pub size_dt_strings: Fdt32,
115 pub size_dt_struct: Fdt32,
117}
118
119impl FdtHeader {
120 pub(crate) fn valid_magic(&self) -> FdtResult<'static> {
121 if self.magic.get() == 0xd00dfeed {
122 Ok(())
123 } else {
124 Err(FdtError::BadMagic)
125 }
126 }
127
128 pub(crate) fn struct_range(&self) -> core::ops::Range<usize> {
129 let start = self.off_dt_struct.get() as usize;
130 let end = start + self.size_dt_struct.get() as usize;
131
132 start..end
133 }
134
135 pub(crate) fn strings_range(&self) -> core::ops::Range<usize> {
136 let start = self.off_dt_strings.get() as usize;
137 let end = start + self.size_dt_strings.get() as usize;
138 start..end
139 }
140
141 pub fn from_bytes(bytes: &[u8]) -> FdtResult<'static, Self> {
142 if bytes.len() < size_of::<FdtHeader>() {
143 return Err(FdtError::Eof);
144 }
145
146 unsafe {
147 let ptr: *const FdtHeader = bytes.as_ptr().cast();
148 Ok(ptr.read())
149 }
150 }
151
152 pub fn from_ptr(ptr: NonNull<u8>) -> FdtResult<'static, Self> {
153 let ptr: NonNull<FdtHeader> = ptr.cast();
154 unsafe { Ok(*ptr.as_ref()) }
155 }
156}
157
158impl Display for FdtHeader {
159 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
160 f.debug_struct("FdtHeader")
161 .field("size", &self.totalsize.get())
162 .field("version", &self.version.get())
163 .field("last_comp_version", &self.last_comp_version.get())
164 .finish()
165 }
166}
167
168#[repr(C)]
169pub(crate) struct FdtReserveEntry {
170 pub address: u64,
171 pub size: u64,
172}
173impl FdtReserveEntry {
174 pub fn new(address: u64, size: u64) -> Self {
175 Self { address, size }
176 }
177}
178
179impl From<FdtReserveEntry> for MemoryRegion {
180 fn from(value: FdtReserveEntry) -> Self {
181 Self {
182 address: value.address as usize as _,
183 size: value.size as _,
184 }
185 }
186}
187
188#[derive(Clone, Copy)]
189pub struct MemoryRegion {
190 pub address: *mut u8,
191 pub size: usize,
192}
193
194impl Debug for MemoryRegion {
195 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
196 f.write_fmt(format_args!(
197 "MemoryRegion {{ address: {:p}, size: {:#x} }}",
198 self.address, self.size
199 ))
200 }
201}
202
203#[derive(Clone, Copy)]
204pub struct FdtReg {
205 pub address: u64,
207 pub child_bus_address: u64,
209 pub size: Option<usize>,
210}
211
212impl Debug for FdtReg {
213 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
214 f.write_fmt(format_args!("<{:#x}", self.address))?;
215 if self.child_bus_address != self.address {
216 f.write_fmt(format_args!("({:#x})", self.child_bus_address))?;
217 }
218 f.write_fmt(format_args!(", "))?;
219 if let Some(s) = self.size {
220 f.write_fmt(format_args!("{:#x}>", s))
221 } else {
222 f.write_str("None>")
223 }
224 }
225}
226
227#[derive(Clone)]
229pub struct FdtRange<'a> {
230 data_child: &'a [u8],
231 data_parent: &'a [u8],
232 pub size: u64,
234}
235
236impl<'a> FdtRange<'a> {
237 pub fn child_bus_address(&self) -> U32Array<'a> {
238 U32Array::new(self.data_child)
239 }
240
241 pub fn parent_bus_address(&self) -> U32Array<'a> {
242 U32Array::new(self.data_parent)
243 }
244}
245
246impl Debug for FdtRange<'_> {
247 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
248 f.write_str("Range {{ child_bus_address: [ ")?;
249 for addr in self.child_bus_address() {
250 f.write_fmt(format_args!("{:#x} ", addr))?;
251 }
252 f.write_str("], parent_bus_address: [ ")?;
253 for addr in self.parent_bus_address() {
254 f.write_fmt(format_args!("{:#x} ", addr))?;
255 }
256 f.write_fmt(format_args!("], size: {:#x}", self.size))
257 }
258}
259
260#[derive(Clone)]
261pub struct FdtRangeSilce<'a> {
262 address_cell: u8,
263 address_cell_parent: u8,
264 size_cell: u8,
265 reader: FdtReader<'a>,
266}
267
268impl<'a> FdtRangeSilce<'a> {
269 pub(crate) fn new(
270 address_cell: u8,
271 address_cell_parent: u8,
272 size_cell: u8,
273 reader: FdtReader<'a>,
274 ) -> Self {
275 Self {
276 address_cell,
277 address_cell_parent,
278 size_cell,
279 reader,
280 }
281 }
282
283 pub fn iter(&self) -> FdtRangeIter<'a> {
284 FdtRangeIter { s: self.clone() }
285 }
286}
287#[derive(Clone)]
288pub struct FdtRangeIter<'a> {
289 s: FdtRangeSilce<'a>,
290}
291
292impl<'a> Iterator for FdtRangeIter<'a> {
293 type Item = FdtRange<'a>;
294
295 fn next(&mut self) -> Option<Self::Item> {
296 let child_address_bytes = self.s.address_cell as usize * size_of::<u32>();
297 let data_child = self.s.reader.take(child_address_bytes)?;
298
299 let parent_address_bytes = self.s.address_cell_parent as usize * size_of::<u32>();
300 let data_parent = self.s.reader.take(parent_address_bytes)?;
301
302 let size = self.s.reader.take_by_cell_size(self.s.size_cell)?;
308 Some(FdtRange {
309 size,
310 data_child,
311 data_parent,
312 })
313 }
314}
315
316#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
317#[repr(transparent)]
318pub struct Phandle(u32);
319
320impl From<u32> for Phandle {
321 fn from(value: u32) -> Self {
322 Self(value)
323 }
324}
325impl Phandle {
326 pub fn as_usize(&self) -> usize {
327 self.0 as usize
328 }
329}
330
331impl Display for Phandle {
332 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
333 write!(f, "<{:#x}>", self.0)
334 }
335}