1use core::ptr::NonNull;
2
3use crate::FdtError;
4
5#[repr(align(4))]
6struct AlignedHeader([u8; size_of::<Header>()]);
7
8#[derive(Debug, Clone)]
9pub struct Header {
10 pub magic: u32,
12 pub totalsize: u32,
14 pub off_dt_struct: u32,
16 pub off_dt_strings: u32,
18 pub off_mem_rsvmap: u32,
21 pub version: u32,
23 pub last_comp_version: u32,
25 pub boot_cpuid_phys: u32,
27 pub size_dt_strings: u32,
29 pub size_dt_struct: u32,
31}
32
33impl Header {
34 pub fn from_bytes(data: &[u8]) -> Result<Self, FdtError> {
37 if data.len() < core::mem::size_of::<Header>() {
38 return Err(FdtError::BufferTooSmall {
39 pos: core::mem::size_of::<Header>(),
40 });
41 }
42 let ptr = NonNull::new(data.as_ptr() as *mut u8).ok_or(FdtError::InvalidPtr)?;
43 unsafe { Self::from_ptr(ptr.as_ptr()) }
44 }
45
46 pub unsafe fn from_ptr(ptr: *mut u8) -> Result<Self, FdtError> {
55 if !(ptr as usize).is_multiple_of(core::mem::align_of::<Header>()) {
56 let mut aligned = AlignedHeader([0u8; core::mem::size_of::<Header>()]);
59 unsafe {
60 core::ptr::copy_nonoverlapping(
61 ptr,
62 aligned.0.as_mut_ptr(),
63 core::mem::size_of::<Header>(),
64 );
65 }
66 Self::from_aligned_ptr(aligned.0.as_mut_ptr())
67 } else {
68 Self::from_aligned_ptr(ptr)
70 }
71 }
72
73 fn from_aligned_ptr(ptr: *mut u8) -> Result<Self, FdtError> {
74 let ptr = NonNull::new(ptr).ok_or(FdtError::InvalidPtr)?;
75
76 let raw = unsafe { &*(ptr.cast::<Header>().as_ptr()) };
81
82 let magic = u32::from_be(raw.magic);
83 if magic != crate::FDT_MAGIC {
84 return Err(FdtError::InvalidMagic(magic));
85 }
86
87 Ok(Header {
88 magic,
89 totalsize: u32::from_be(raw.totalsize),
90 off_dt_struct: u32::from_be(raw.off_dt_struct),
91 off_dt_strings: u32::from_be(raw.off_dt_strings),
92 off_mem_rsvmap: u32::from_be(raw.off_mem_rsvmap),
93 version: u32::from_be(raw.version),
94 last_comp_version: u32::from_be(raw.last_comp_version),
95 boot_cpuid_phys: u32::from_be(raw.boot_cpuid_phys),
96 size_dt_strings: u32::from_be(raw.size_dt_strings),
97 size_dt_struct: u32::from_be(raw.size_dt_struct),
98 })
99 }
100}