1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Wrapper around libfdt library. Provides parsing/generating functionality
16 //! to a bare-metal environment.
17 
18 #![no_std]
19 
20 mod iterators;
21 mod libfdt;
22 mod result;
23 mod safe_types;
24 
25 pub use iterators::{
26     AddressRange, CellIterator, CompatibleIterator, DescendantsIterator, MemRegIterator,
27     PropertyIterator, RangesIterator, Reg, RegIterator, SubnodeIterator,
28 };
29 pub use result::{FdtError, Result};
30 pub use safe_types::{FdtHeader, NodeOffset, Phandle, PropOffset, StringOffset};
31 
32 use core::ffi::{c_void, CStr};
33 use core::ops::Range;
34 use cstr::cstr;
35 use libfdt::get_slice_at_ptr;
36 use zerocopy::AsBytes as _;
37 
38 use crate::libfdt::{Libfdt, LibfdtMut};
39 
40 /// Value of a #address-cells property.
41 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
42 enum AddrCells {
43     Single = 1,
44     Double = 2,
45     Triple = 3,
46 }
47 
48 impl TryFrom<usize> for AddrCells {
49     type Error = FdtError;
50 
try_from(value: usize) -> Result<Self>51     fn try_from(value: usize) -> Result<Self> {
52         match value {
53             x if x == Self::Single as _ => Ok(Self::Single),
54             x if x == Self::Double as _ => Ok(Self::Double),
55             x if x == Self::Triple as _ => Ok(Self::Triple),
56             _ => Err(FdtError::BadNCells),
57         }
58     }
59 }
60 
61 /// Value of a #size-cells property.
62 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
63 enum SizeCells {
64     None = 0,
65     Single = 1,
66     Double = 2,
67 }
68 
69 impl TryFrom<usize> for SizeCells {
70     type Error = FdtError;
71 
try_from(value: usize) -> Result<Self>72     fn try_from(value: usize) -> Result<Self> {
73         match value {
74             x if x == Self::None as _ => Ok(Self::None),
75             x if x == Self::Single as _ => Ok(Self::Single),
76             x if x == Self::Double as _ => Ok(Self::Double),
77             _ => Err(FdtError::BadNCells),
78         }
79     }
80 }
81 
82 /// DT property wrapper to abstract endianess changes
83 #[repr(transparent)]
84 #[derive(Debug)]
85 struct FdtPropertyStruct(libfdt_bindgen::fdt_property);
86 
87 impl AsRef<FdtPropertyStruct> for libfdt_bindgen::fdt_property {
as_ref(&self) -> &FdtPropertyStruct88     fn as_ref(&self) -> &FdtPropertyStruct {
89         let ptr = self as *const _ as *const _;
90         // SAFETY: Types have the same layout (transparent) so the valid reference remains valid.
91         unsafe { &*ptr }
92     }
93 }
94 
95 impl FdtPropertyStruct {
from_offset(fdt: &Fdt, offset: PropOffset) -> Result<&Self>96     fn from_offset(fdt: &Fdt, offset: PropOffset) -> Result<&Self> {
97         Ok(fdt.get_property_by_offset(offset)?.as_ref())
98     }
99 
name_offset(&self) -> StringOffset100     fn name_offset(&self) -> StringOffset {
101         StringOffset(u32::from_be(self.0.nameoff).try_into().unwrap())
102     }
103 
data_len(&self) -> usize104     fn data_len(&self) -> usize {
105         u32::from_be(self.0.len).try_into().unwrap()
106     }
107 
data_ptr(&self) -> *const c_void108     fn data_ptr(&self) -> *const c_void {
109         self.0.data.as_ptr().cast()
110     }
111 }
112 
113 /// DT property.
114 #[derive(Clone, Copy, Debug)]
115 pub struct FdtProperty<'a> {
116     fdt: &'a Fdt,
117     offset: PropOffset,
118     property: &'a FdtPropertyStruct,
119 }
120 
121 impl<'a> FdtProperty<'a> {
new(fdt: &'a Fdt, offset: PropOffset) -> Result<Self>122     fn new(fdt: &'a Fdt, offset: PropOffset) -> Result<Self> {
123         let property = FdtPropertyStruct::from_offset(fdt, offset)?;
124         Ok(Self { fdt, offset, property })
125     }
126 
127     /// Returns the property name
name(&self) -> Result<&'a CStr>128     pub fn name(&self) -> Result<&'a CStr> {
129         self.fdt.string(self.property.name_offset())
130     }
131 
132     /// Returns the property value
value(&self) -> Result<&'a [u8]>133     pub fn value(&self) -> Result<&'a [u8]> {
134         self.fdt.get_from_ptr(self.property.data_ptr(), self.property.data_len())
135     }
136 
next_property(&self) -> Result<Option<Self>>137     fn next_property(&self) -> Result<Option<Self>> {
138         if let Some(offset) = self.fdt.next_property_offset(self.offset)? {
139             Ok(Some(Self::new(self.fdt, offset)?))
140         } else {
141             Ok(None)
142         }
143     }
144 }
145 
146 /// DT node.
147 #[derive(Clone, Copy, Debug)]
148 pub struct FdtNode<'a> {
149     fdt: &'a Fdt,
150     offset: NodeOffset,
151 }
152 
153 impl<'a> FdtNode<'a> {
154     /// Returns parent node.
parent(&self) -> Result<Self>155     pub fn parent(&self) -> Result<Self> {
156         let offset = self.fdt.parent_offset(self.offset)?;
157 
158         Ok(Self { fdt: self.fdt, offset })
159     }
160 
161     /// Returns supernode with depth. Note that root is at depth 0.
supernode_at_depth(&self, depth: usize) -> Result<Self>162     pub fn supernode_at_depth(&self, depth: usize) -> Result<Self> {
163         let offset = self.fdt.supernode_atdepth_offset(self.offset, depth)?;
164 
165         Ok(Self { fdt: self.fdt, offset })
166     }
167 
168     /// Returns the standard (deprecated) device_type <string> property.
device_type(&self) -> Result<Option<&CStr>>169     pub fn device_type(&self) -> Result<Option<&CStr>> {
170         self.getprop_str(cstr!("device_type"))
171     }
172 
173     /// Returns the standard reg <prop-encoded-array> property.
reg(&self) -> Result<Option<RegIterator<'a>>>174     pub fn reg(&self) -> Result<Option<RegIterator<'a>>> {
175         if let Some(cells) = self.getprop_cells(cstr!("reg"))? {
176             let parent = self.parent()?;
177 
178             let addr_cells = parent.address_cells()?;
179             let size_cells = parent.size_cells()?;
180 
181             Ok(Some(RegIterator::new(cells, addr_cells, size_cells)))
182         } else {
183             Ok(None)
184         }
185     }
186 
187     /// Returns the standard ranges property.
ranges<A, P, S>(&self) -> Result<Option<RangesIterator<'a, A, P, S>>>188     pub fn ranges<A, P, S>(&self) -> Result<Option<RangesIterator<'a, A, P, S>>> {
189         if let Some(cells) = self.getprop_cells(cstr!("ranges"))? {
190             let parent = self.parent()?;
191             let addr_cells = self.address_cells()?;
192             let parent_addr_cells = parent.address_cells()?;
193             let size_cells = self.size_cells()?;
194             Ok(Some(RangesIterator::<A, P, S>::new(
195                 cells,
196                 addr_cells,
197                 parent_addr_cells,
198                 size_cells,
199             )))
200         } else {
201             Ok(None)
202         }
203     }
204 
205     /// Returns the node name.
name(&self) -> Result<&'a CStr>206     pub fn name(&self) -> Result<&'a CStr> {
207         let name = self.fdt.get_name(self.offset)?;
208         CStr::from_bytes_with_nul(name).map_err(|_| FdtError::Internal)
209     }
210 
211     /// Returns the value of a given <string> property.
getprop_str(&self, name: &CStr) -> Result<Option<&CStr>>212     pub fn getprop_str(&self, name: &CStr) -> Result<Option<&CStr>> {
213         if let Some(bytes) = self.getprop(name)? {
214             Ok(Some(CStr::from_bytes_with_nul(bytes).map_err(|_| FdtError::BadValue)?))
215         } else {
216             Ok(None)
217         }
218     }
219 
220     /// Returns the value of a given property as an array of cells.
getprop_cells(&self, name: &CStr) -> Result<Option<CellIterator<'a>>>221     pub fn getprop_cells(&self, name: &CStr) -> Result<Option<CellIterator<'a>>> {
222         if let Some(cells) = self.getprop(name)? {
223             Ok(Some(CellIterator::new(cells)))
224         } else {
225             Ok(None)
226         }
227     }
228 
229     /// Returns the value of a given <u32> property.
getprop_u32(&self, name: &CStr) -> Result<Option<u32>>230     pub fn getprop_u32(&self, name: &CStr) -> Result<Option<u32>> {
231         if let Some(bytes) = self.getprop(name)? {
232             Ok(Some(u32::from_be_bytes(bytes.try_into().map_err(|_| FdtError::BadValue)?)))
233         } else {
234             Ok(None)
235         }
236     }
237 
238     /// Returns the value of a given <u64> property.
getprop_u64(&self, name: &CStr) -> Result<Option<u64>>239     pub fn getprop_u64(&self, name: &CStr) -> Result<Option<u64>> {
240         if let Some(bytes) = self.getprop(name)? {
241             Ok(Some(u64::from_be_bytes(bytes.try_into().map_err(|_| FdtError::BadValue)?)))
242         } else {
243             Ok(None)
244         }
245     }
246 
247     /// Returns the value of a given property.
getprop(&self, name: &CStr) -> Result<Option<&'a [u8]>>248     pub fn getprop(&self, name: &CStr) -> Result<Option<&'a [u8]>> {
249         self.fdt.getprop_namelen(self.offset, name.to_bytes())
250     }
251 
252     /// Returns reference to the containing device tree.
fdt(&self) -> &Fdt253     pub fn fdt(&self) -> &Fdt {
254         self.fdt
255     }
256 
257     /// Returns the compatible node of the given name that is next after this node.
next_compatible(self, compatible: &CStr) -> Result<Option<Self>>258     pub fn next_compatible(self, compatible: &CStr) -> Result<Option<Self>> {
259         let offset = self.fdt.node_offset_by_compatible(self.offset, compatible)?;
260 
261         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
262     }
263 
264     /// Returns the first range of `reg` in this node.
first_reg(&self) -> Result<Reg<u64>>265     pub fn first_reg(&self) -> Result<Reg<u64>> {
266         self.reg()?.ok_or(FdtError::NotFound)?.next().ok_or(FdtError::NotFound)
267     }
268 
address_cells(&self) -> Result<AddrCells>269     fn address_cells(&self) -> Result<AddrCells> {
270         self.fdt.address_cells(self.offset)?.try_into()
271     }
272 
size_cells(&self) -> Result<SizeCells>273     fn size_cells(&self) -> Result<SizeCells> {
274         self.fdt.size_cells(self.offset)?.try_into()
275     }
276 
277     /// Returns an iterator of subnodes
subnodes(&self) -> Result<SubnodeIterator<'a>>278     pub fn subnodes(&self) -> Result<SubnodeIterator<'a>> {
279         SubnodeIterator::new(self)
280     }
281 
first_subnode(&self) -> Result<Option<Self>>282     fn first_subnode(&self) -> Result<Option<Self>> {
283         let offset = self.fdt.first_subnode(self.offset)?;
284 
285         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
286     }
287 
next_subnode(&self) -> Result<Option<Self>>288     fn next_subnode(&self) -> Result<Option<Self>> {
289         let offset = self.fdt.next_subnode(self.offset)?;
290 
291         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
292     }
293 
294     /// Returns an iterator of descendants
descendants(&self) -> DescendantsIterator<'a>295     pub fn descendants(&self) -> DescendantsIterator<'a> {
296         DescendantsIterator::new(self)
297     }
298 
next_node(&self, depth: usize) -> Result<Option<(Self, usize)>>299     fn next_node(&self, depth: usize) -> Result<Option<(Self, usize)>> {
300         if let Some((offset, depth)) = self.fdt.next_node(self.offset, depth)? {
301             Ok(Some((Self { fdt: self.fdt, offset }, depth)))
302         } else {
303             Ok(None)
304         }
305     }
306 
307     /// Returns an iterator of properties
properties(&'a self) -> Result<PropertyIterator<'a>>308     pub fn properties(&'a self) -> Result<PropertyIterator<'a>> {
309         PropertyIterator::new(self)
310     }
311 
first_property(&self) -> Result<Option<FdtProperty<'a>>>312     fn first_property(&self) -> Result<Option<FdtProperty<'a>>> {
313         if let Some(offset) = self.fdt.first_property_offset(self.offset)? {
314             Ok(Some(FdtProperty::new(self.fdt, offset)?))
315         } else {
316             Ok(None)
317         }
318     }
319 
320     /// Returns the phandle
get_phandle(&self) -> Result<Option<Phandle>>321     pub fn get_phandle(&self) -> Result<Option<Phandle>> {
322         // This rewrites the fdt_get_phandle() because it doesn't return error code.
323         if let Some(prop) = self.getprop_u32(cstr!("phandle"))? {
324             Ok(Some(prop.try_into()?))
325         } else if let Some(prop) = self.getprop_u32(cstr!("linux,phandle"))? {
326             Ok(Some(prop.try_into()?))
327         } else {
328             Ok(None)
329         }
330     }
331 
332     /// Returns the subnode of the given name. The name doesn't need to be nul-terminated.
subnode(&self, name: &CStr) -> Result<Option<Self>>333     pub fn subnode(&self, name: &CStr) -> Result<Option<Self>> {
334         let name = name.to_bytes();
335         let offset = self.fdt.subnode_offset_namelen(self.offset, name)?;
336 
337         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
338     }
339 
340     /// Returns the subnode of the given name bytes
subnode_with_name_bytes(&self, name: &[u8]) -> Result<Option<Self>>341     pub fn subnode_with_name_bytes(&self, name: &[u8]) -> Result<Option<Self>> {
342         let offset = self.fdt.subnode_offset_namelen(self.offset, name)?;
343 
344         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
345     }
346 }
347 
348 impl<'a> PartialEq for FdtNode<'a> {
eq(&self, other: &Self) -> bool349     fn eq(&self, other: &Self) -> bool {
350         self.fdt.as_ptr() == other.fdt.as_ptr() && self.offset == other.offset
351     }
352 }
353 
354 /// Mutable FDT node.
355 #[derive(Debug)]
356 pub struct FdtNodeMut<'a> {
357     fdt: &'a mut Fdt,
358     offset: NodeOffset,
359 }
360 
361 impl<'a> FdtNodeMut<'a> {
362     /// Appends a property name-value (possibly empty) pair to the given node.
appendprop<T: AsRef<[u8]>>(&mut self, name: &CStr, value: &T) -> Result<()>363     pub fn appendprop<T: AsRef<[u8]>>(&mut self, name: &CStr, value: &T) -> Result<()> {
364         self.fdt.appendprop(self.offset, name, value.as_ref())
365     }
366 
367     /// Appends a (address, size) pair property to the given node.
appendprop_addrrange(&mut self, name: &CStr, addr: u64, size: u64) -> Result<()>368     pub fn appendprop_addrrange(&mut self, name: &CStr, addr: u64, size: u64) -> Result<()> {
369         let parent = self.parent()?.offset;
370         self.fdt.appendprop_addrrange(parent, self.offset, name, addr, size)
371     }
372 
373     /// Sets a property name-value pair to the given node.
374     ///
375     /// This may create a new prop or replace existing value.
setprop(&mut self, name: &CStr, value: &[u8]) -> Result<()>376     pub fn setprop(&mut self, name: &CStr, value: &[u8]) -> Result<()> {
377         self.fdt.setprop(self.offset, name, value)
378     }
379 
380     /// Sets the value of the given property with the given value, and ensure that the given
381     /// value has the same length as the current value length.
382     ///
383     /// This can only be used to replace existing value.
setprop_inplace(&mut self, name: &CStr, value: &[u8]) -> Result<()>384     pub fn setprop_inplace(&mut self, name: &CStr, value: &[u8]) -> Result<()> {
385         self.fdt.setprop_inplace(self.offset, name, value)
386     }
387 
388     /// Sets the value of the given (address, size) pair property with the given value, and
389     /// ensure that the given value has the same length as the current value length.
390     ///
391     /// This can only be used to replace existing value.
setprop_addrrange_inplace(&mut self, name: &CStr, addr: u64, size: u64) -> Result<()>392     pub fn setprop_addrrange_inplace(&mut self, name: &CStr, addr: u64, size: u64) -> Result<()> {
393         let pair = [addr.to_be(), size.to_be()];
394         self.fdt.setprop_inplace(self.offset, name, pair.as_bytes())
395     }
396 
397     /// Sets a flag-like empty property.
398     ///
399     /// This may create a new prop or replace existing value.
setprop_empty(&mut self, name: &CStr) -> Result<()>400     pub fn setprop_empty(&mut self, name: &CStr) -> Result<()> {
401         self.fdt.setprop(self.offset, name, &[])
402     }
403 
404     /// Deletes the given property.
delprop(&mut self, name: &CStr) -> Result<()>405     pub fn delprop(&mut self, name: &CStr) -> Result<()> {
406         self.fdt.delprop(self.offset, name)
407     }
408 
409     /// Deletes the given property effectively from DT, by setting it with FDT_NOP.
nop_property(&mut self, name: &CStr) -> Result<()>410     pub fn nop_property(&mut self, name: &CStr) -> Result<()> {
411         self.fdt.nop_property(self.offset, name)
412     }
413 
414     /// Trims the size of the given property to new_size.
trimprop(&mut self, name: &CStr, new_size: usize) -> Result<()>415     pub fn trimprop(&mut self, name: &CStr, new_size: usize) -> Result<()> {
416         let prop = self.as_node().getprop(name)?.ok_or(FdtError::NotFound)?;
417 
418         match prop.len() {
419             x if x == new_size => Ok(()),
420             x if x < new_size => Err(FdtError::NoSpace),
421             _ => self.fdt.setprop_placeholder(self.offset, name, new_size).map(|_| ()),
422         }
423     }
424 
425     /// Returns reference to the containing device tree.
fdt(&mut self) -> &mut Fdt426     pub fn fdt(&mut self) -> &mut Fdt {
427         self.fdt
428     }
429 
430     /// Returns immutable FdtNode of this node.
as_node(&self) -> FdtNode431     pub fn as_node(&self) -> FdtNode {
432         FdtNode { fdt: self.fdt, offset: self.offset }
433     }
434 
435     /// Adds new subnodes to the given node.
add_subnodes(self, names: &[&CStr]) -> Result<()>436     pub fn add_subnodes(self, names: &[&CStr]) -> Result<()> {
437         for name in names {
438             self.fdt.add_subnode_namelen(self.offset, name.to_bytes())?;
439         }
440         Ok(())
441     }
442 
443     /// Adds a new subnode to the given node and return it as a FdtNodeMut on success.
add_subnode(self, name: &CStr) -> Result<Self>444     pub fn add_subnode(self, name: &CStr) -> Result<Self> {
445         let name = name.to_bytes();
446         let offset = self.fdt.add_subnode_namelen(self.offset, name)?;
447 
448         Ok(Self { fdt: self.fdt, offset })
449     }
450 
451     /// Adds a new subnode to the given node with name and namelen, and returns it as a FdtNodeMut
452     /// on success.
add_subnode_with_namelen(self, name: &CStr, namelen: usize) -> Result<Self>453     pub fn add_subnode_with_namelen(self, name: &CStr, namelen: usize) -> Result<Self> {
454         let name = &name.to_bytes()[..namelen];
455         let offset = self.fdt.add_subnode_namelen(self.offset, name)?;
456 
457         Ok(Self { fdt: self.fdt, offset })
458     }
459 
460     /// Returns the first subnode of this
first_subnode(self) -> Result<Option<Self>>461     pub fn first_subnode(self) -> Result<Option<Self>> {
462         let offset = self.fdt.first_subnode(self.offset)?;
463 
464         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
465     }
466 
467     /// Returns the next subnode that shares the same parent with this
next_subnode(self) -> Result<Option<Self>>468     pub fn next_subnode(self) -> Result<Option<Self>> {
469         let offset = self.fdt.next_subnode(self.offset)?;
470 
471         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
472     }
473 
474     /// Deletes the current node and returns the next subnode
delete_and_next_subnode(self) -> Result<Option<Self>>475     pub fn delete_and_next_subnode(self) -> Result<Option<Self>> {
476         let next_offset = self.fdt.next_subnode(self.offset)?;
477 
478         self.delete_and_next(next_offset)
479     }
480 
481     /// Returns the next node. Use this API to travel descendant of a node.
482     ///
483     /// Returned depth is relative to the initial node that had called with any of next node APIs.
484     /// Returns None if end of FDT reached or depth becomes negative.
485     ///
486     /// See also: [`next_node_skip_subnodes`], and [`delete_and_next_node`]
next_node(self, depth: usize) -> Result<Option<(Self, usize)>>487     pub fn next_node(self, depth: usize) -> Result<Option<(Self, usize)>> {
488         let next = self.fdt.next_node(self.offset, depth)?;
489 
490         Ok(next.map(|(offset, depth)| (Self { fdt: self.fdt, offset }, depth)))
491     }
492 
493     /// Returns the next node skipping subnodes. Use this API to travel descendants of a node while
494     /// ignoring certain node.
495     ///
496     /// Returned depth is relative to the initial node that had called with any of next node APIs.
497     /// Returns None if end of FDT reached or depth becomes negative.
498     ///
499     /// See also: [`next_node`], and [`delete_and_next_node`]
next_node_skip_subnodes(self, depth: usize) -> Result<Option<(Self, usize)>>500     pub fn next_node_skip_subnodes(self, depth: usize) -> Result<Option<(Self, usize)>> {
501         let next = self.fdt.next_node_skip_subnodes(self.offset, depth)?;
502 
503         Ok(next.map(|(offset, depth)| (Self { fdt: self.fdt, offset }, depth)))
504     }
505 
506     /// Deletes this and returns the next node. Use this API to travel descendants of a node while
507     /// removing certain node.
508     ///
509     /// Returned depth is relative to the initial node that had called with any of next node APIs.
510     /// Returns None if end of FDT reached or depth becomes negative.
511     ///
512     /// See also: [`next_node`], and [`next_node_skip_subnodes`]
delete_and_next_node(self, depth: usize) -> Result<Option<(Self, usize)>>513     pub fn delete_and_next_node(self, depth: usize) -> Result<Option<(Self, usize)>> {
514         let next_node = self.fdt.next_node_skip_subnodes(self.offset, depth)?;
515         if let Some((offset, depth)) = next_node {
516             let next_node = self.delete_and_next(Some(offset))?.unwrap();
517             Ok(Some((next_node, depth)))
518         } else {
519             self.delete_and_next(None)?;
520             Ok(None)
521         }
522     }
523 
parent(&'a self) -> Result<FdtNode<'a>>524     fn parent(&'a self) -> Result<FdtNode<'a>> {
525         self.as_node().parent()
526     }
527 
528     /// Returns the compatible node of the given name that is next after this node.
next_compatible(self, compatible: &CStr) -> Result<Option<Self>>529     pub fn next_compatible(self, compatible: &CStr) -> Result<Option<Self>> {
530         let offset = self.fdt.node_offset_by_compatible(self.offset, compatible)?;
531 
532         Ok(offset.map(|offset| Self { fdt: self.fdt, offset }))
533     }
534 
535     /// Deletes the node effectively by overwriting this node and its subtree with nop tags.
536     /// Returns the next compatible node of the given name.
537     // Side note: without this, filterint out excessive compatible nodes from the DT is impossible.
538     // The reason is that libfdt ensures that the node from where the search for the next
539     // compatible node is started is always a valid one -- except for the special case of offset =
540     // -1 which is to find the first compatible node. So, we can't delete a node and then find the
541     // next compatible node from it.
542     //
543     // We can't do in the opposite direction either. If we call next_compatible to find the next
544     // node, and delete the current node, the Rust borrow checker kicks in. The next node has a
545     // mutable reference to DT, so we can't use current node (which also has a mutable reference to
546     // DT).
delete_and_next_compatible(self, compatible: &CStr) -> Result<Option<Self>>547     pub fn delete_and_next_compatible(self, compatible: &CStr) -> Result<Option<Self>> {
548         let next_offset = self.fdt.node_offset_by_compatible(self.offset, compatible)?;
549 
550         self.delete_and_next(next_offset)
551     }
552 
delete_and_next(self, next_offset: Option<NodeOffset>) -> Result<Option<Self>>553     fn delete_and_next(self, next_offset: Option<NodeOffset>) -> Result<Option<Self>> {
554         if Some(self.offset) == next_offset {
555             return Err(FdtError::Internal);
556         }
557 
558         self.fdt.nop_node(self.offset)?;
559 
560         Ok(next_offset.map(|offset| Self { fdt: self.fdt, offset }))
561     }
562 
563     /// Deletes this node effectively from DT, by setting it with FDT_NOP
nop(self) -> Result<()>564     pub fn nop(self) -> Result<()> {
565         self.fdt.nop_node(self.offset)
566     }
567 }
568 
569 /// Wrapper around low-level libfdt functions.
570 #[derive(Debug)]
571 #[repr(transparent)]
572 pub struct Fdt {
573     buffer: [u8],
574 }
575 
576 // SAFETY: Fdt calls check_full() before safely returning a &Self, making it impossible for trait
577 // methods to be called on invalid device trees.
578 unsafe impl Libfdt for Fdt {
as_fdt_slice(&self) -> &[u8]579     fn as_fdt_slice(&self) -> &[u8] {
580         &self.buffer[..self.totalsize()]
581     }
582 }
583 
584 // SAFETY: Fdt calls check_full() before safely returning a &Self, making it impossible for trait
585 // methods to be called on invalid device trees.
586 unsafe impl LibfdtMut for Fdt {
as_fdt_slice_mut(&mut self) -> &mut [u8]587     fn as_fdt_slice_mut(&mut self) -> &mut [u8] {
588         &mut self.buffer
589     }
590 }
591 
592 impl Fdt {
593     /// Wraps a slice containing a Flattened Device Tree.
594     ///
595     /// Fails if the FDT does not pass validation.
from_slice(fdt: &[u8]) -> Result<&Self>596     pub fn from_slice(fdt: &[u8]) -> Result<&Self> {
597         libfdt::check_full(fdt)?;
598         // SAFETY: The FDT was validated.
599         let fdt = unsafe { Self::unchecked_from_slice(fdt) };
600 
601         Ok(fdt)
602     }
603 
604     /// Wraps a mutable slice containing a Flattened Device Tree.
605     ///
606     /// Fails if the FDT does not pass validation.
from_mut_slice(fdt: &mut [u8]) -> Result<&mut Self>607     pub fn from_mut_slice(fdt: &mut [u8]) -> Result<&mut Self> {
608         libfdt::check_full(fdt)?;
609         // SAFETY: The FDT was validated.
610         let fdt = unsafe { Self::unchecked_from_mut_slice(fdt) };
611 
612         Ok(fdt)
613     }
614 
615     /// Creates an empty Flattened Device Tree with a mutable slice.
create_empty_tree(fdt: &mut [u8]) -> Result<&mut Self>616     pub fn create_empty_tree(fdt: &mut [u8]) -> Result<&mut Self> {
617         libfdt::create_empty_tree(fdt)?;
618 
619         Self::from_mut_slice(fdt)
620     }
621 
622     /// Wraps a slice containing a Flattened Device Tree.
623     ///
624     /// # Safety
625     ///
626     /// It is undefined to call this function on a slice that does not contain a valid device tree.
unchecked_from_slice(fdt: &[u8]) -> &Self627     pub unsafe fn unchecked_from_slice(fdt: &[u8]) -> &Self {
628         let self_ptr = fdt as *const _ as *const _;
629         // SAFETY: The pointer is non-null, dereferenceable, and points to allocated memory.
630         unsafe { &*self_ptr }
631     }
632 
633     /// Wraps a mutable slice containing a Flattened Device Tree.
634     ///
635     /// # Safety
636     ///
637     /// It is undefined to call this function on a slice that does not contain a valid device tree.
unchecked_from_mut_slice(fdt: &mut [u8]) -> &mut Self638     pub unsafe fn unchecked_from_mut_slice(fdt: &mut [u8]) -> &mut Self {
639         let self_mut_ptr = fdt as *mut _ as *mut _;
640         // SAFETY: The pointer is non-null, dereferenceable, and points to allocated memory.
641         unsafe { &mut *self_mut_ptr }
642     }
643 
644     /// Updates this FDT from another FDT.
clone_from(&mut self, other: &Self) -> Result<()>645     pub fn clone_from(&mut self, other: &Self) -> Result<()> {
646         let new_len = other.buffer.len();
647         if self.buffer.len() < new_len {
648             return Err(FdtError::NoSpace);
649         }
650 
651         let zeroed_len = self.totalsize().checked_sub(new_len);
652         let (cloned, zeroed) = self.buffer.split_at_mut(new_len);
653 
654         cloned.clone_from_slice(&other.buffer);
655         if let Some(len) = zeroed_len {
656             zeroed[..len].fill(0);
657         }
658 
659         Ok(())
660     }
661 
662     /// Unpacks the DT to cover the whole slice it is contained in.
unpack(&mut self) -> Result<()>663     pub fn unpack(&mut self) -> Result<()> {
664         self.open_into_self()
665     }
666 
667     /// Packs the DT to take a minimum amount of memory.
668     ///
669     /// Doesn't shrink the underlying memory slice.
pack(&mut self) -> Result<()>670     pub fn pack(&mut self) -> Result<()> {
671         LibfdtMut::pack(self)
672     }
673 
674     /// Applies a DT overlay on the base DT.
675     ///
676     /// # Safety
677     ///
678     /// As libfdt corrupts the input DT on failure, `self` should be discarded on error:
679     ///
680     ///     let fdt = fdt.apply_overlay(overlay)?;
681     ///
682     /// Furthermore, `overlay` is _always_ corrupted by libfdt and will never refer to a valid
683     /// `Fdt` after this function returns and must therefore be discarded by the caller.
apply_overlay<'a>(&'a mut self, overlay: &mut Fdt) -> Result<&'a mut Self>684     pub unsafe fn apply_overlay<'a>(&'a mut self, overlay: &mut Fdt) -> Result<&'a mut Self> {
685         // SAFETY: Our caller will properly discard overlay and/or self as needed.
686         unsafe { self.overlay_apply(overlay) }?;
687 
688         Ok(self)
689     }
690 
691     /// Returns an iterator of memory banks specified the "/memory" node.
692     /// Throws an error when the "/memory" is not found in the device tree.
693     ///
694     /// NOTE: This does not support individual "/memory@XXXX" banks.
memory(&self) -> Result<MemRegIterator>695     pub fn memory(&self) -> Result<MemRegIterator> {
696         let node = self.root().subnode(cstr!("memory"))?.ok_or(FdtError::NotFound)?;
697         if node.device_type()? != Some(cstr!("memory")) {
698             return Err(FdtError::BadValue);
699         }
700         node.reg()?.ok_or(FdtError::BadValue).map(MemRegIterator::new)
701     }
702 
703     /// Returns the first memory range in the `/memory` node.
first_memory_range(&self) -> Result<Range<usize>>704     pub fn first_memory_range(&self) -> Result<Range<usize>> {
705         self.memory()?.next().ok_or(FdtError::NotFound)
706     }
707 
708     /// Returns the standard /chosen node.
chosen(&self) -> Result<Option<FdtNode>>709     pub fn chosen(&self) -> Result<Option<FdtNode>> {
710         self.root().subnode(cstr!("chosen"))
711     }
712 
713     /// Returns the standard /chosen node as mutable.
chosen_mut(&mut self) -> Result<Option<FdtNodeMut>>714     pub fn chosen_mut(&mut self) -> Result<Option<FdtNodeMut>> {
715         self.node_mut(cstr!("/chosen"))
716     }
717 
718     /// Returns the root node of the tree.
root(&self) -> FdtNode719     pub fn root(&self) -> FdtNode {
720         FdtNode { fdt: self, offset: NodeOffset::ROOT }
721     }
722 
723     /// Returns the standard /__symbols__ node.
symbols(&self) -> Result<Option<FdtNode>>724     pub fn symbols(&self) -> Result<Option<FdtNode>> {
725         self.root().subnode(cstr!("__symbols__"))
726     }
727 
728     /// Returns the standard /__symbols__ node as mutable
symbols_mut(&mut self) -> Result<Option<FdtNodeMut>>729     pub fn symbols_mut(&mut self) -> Result<Option<FdtNodeMut>> {
730         self.node_mut(cstr!("/__symbols__"))
731     }
732 
733     /// Returns a tree node by its full path.
node(&self, path: &CStr) -> Result<Option<FdtNode>>734     pub fn node(&self, path: &CStr) -> Result<Option<FdtNode>> {
735         let offset = self.path_offset_namelen(path.to_bytes())?;
736 
737         Ok(offset.map(|offset| FdtNode { fdt: self, offset }))
738     }
739 
740     /// Iterate over nodes with a given compatible string.
compatible_nodes<'a>(&'a self, compatible: &'a CStr) -> Result<CompatibleIterator<'a>>741     pub fn compatible_nodes<'a>(&'a self, compatible: &'a CStr) -> Result<CompatibleIterator<'a>> {
742         CompatibleIterator::new(self, compatible)
743     }
744 
745     /// Returns max phandle in the tree.
max_phandle(&self) -> Result<Phandle>746     pub fn max_phandle(&self) -> Result<Phandle> {
747         self.find_max_phandle()
748     }
749 
750     /// Returns a node with the phandle
node_with_phandle(&self, phandle: Phandle) -> Result<Option<FdtNode>>751     pub fn node_with_phandle(&self, phandle: Phandle) -> Result<Option<FdtNode>> {
752         let offset = self.node_offset_by_phandle(phandle)?;
753 
754         Ok(offset.map(|offset| FdtNode { fdt: self, offset }))
755     }
756 
757     /// Returns a mutable node with the phandle
node_mut_with_phandle(&mut self, phandle: Phandle) -> Result<Option<FdtNodeMut>>758     pub fn node_mut_with_phandle(&mut self, phandle: Phandle) -> Result<Option<FdtNodeMut>> {
759         let offset = self.node_offset_by_phandle(phandle)?;
760 
761         Ok(offset.map(|offset| FdtNodeMut { fdt: self, offset }))
762     }
763 
764     /// Returns the mutable root node of the tree.
root_mut(&mut self) -> FdtNodeMut765     pub fn root_mut(&mut self) -> FdtNodeMut {
766         FdtNodeMut { fdt: self, offset: NodeOffset::ROOT }
767     }
768 
769     /// Returns a mutable tree node by its full path.
node_mut(&mut self, path: &CStr) -> Result<Option<FdtNodeMut>>770     pub fn node_mut(&mut self, path: &CStr) -> Result<Option<FdtNodeMut>> {
771         let offset = self.path_offset_namelen(path.to_bytes())?;
772 
773         Ok(offset.map(|offset| FdtNodeMut { fdt: self, offset }))
774     }
775 
next_node_skip_subnodes( &self, node: NodeOffset, depth: usize, ) -> Result<Option<(NodeOffset, usize)>>776     fn next_node_skip_subnodes(
777         &self,
778         node: NodeOffset,
779         depth: usize,
780     ) -> Result<Option<(NodeOffset, usize)>> {
781         let mut iter = self.next_node(node, depth)?;
782         while let Some((offset, next_depth)) = iter {
783             if next_depth <= depth {
784                 return Ok(Some((offset, next_depth)));
785             }
786             iter = self.next_node(offset, next_depth)?;
787         }
788 
789         Ok(None)
790     }
791 
792     /// Returns the device tree as a slice (may be smaller than the containing buffer).
as_slice(&self) -> &[u8]793     pub fn as_slice(&self) -> &[u8] {
794         self.as_fdt_slice()
795     }
796 
get_from_ptr(&self, ptr: *const c_void, len: usize) -> Result<&[u8]>797     fn get_from_ptr(&self, ptr: *const c_void, len: usize) -> Result<&[u8]> {
798         get_slice_at_ptr(self.as_fdt_slice(), ptr.cast(), len).ok_or(FdtError::Internal)
799     }
800 
801     /// Returns a shared pointer to the device tree.
as_ptr(&self) -> *const c_void802     pub fn as_ptr(&self) -> *const c_void {
803         self.buffer.as_ptr().cast()
804     }
805 
header(&self) -> &FdtHeader806     fn header(&self) -> &FdtHeader {
807         let p = self.as_ptr().cast::<libfdt_bindgen::fdt_header>();
808         // SAFETY: A valid FDT (verified by constructor) must contain a valid fdt_header.
809         let header = unsafe { &*p };
810         header.as_ref()
811     }
812 
totalsize(&self) -> usize813     fn totalsize(&self) -> usize {
814         self.header().totalsize.get().try_into().unwrap()
815     }
816 }
817