dtb_parser/
device_tree.rs1#[cfg(not(feature = "std"))]
2use alloc::{collections::VecDeque, string::String, vec, vec::Vec};
3#[cfg(not(feature = "std"))]
4use core::fmt::{Display, Formatter};
5#[cfg(feature = "std")]
6use std::fmt::{Display, Formatter};
7#[cfg(feature = "std")]
8use std::{collections::VecDeque, string::String, vec, vec::Vec};
9
10use crate::error::{DeviceTreeError, Result};
11use crate::header::DeviceTreeHeader;
12use crate::node::DeviceTreeNode;
13use crate::traits::HasNamedChildNode;
14
15pub struct DeviceTree {
19 header: DeviceTreeHeader,
20 root: DeviceTreeNode,
21}
22
23impl DeviceTree {
24 pub fn from_bytes(data: &[u8]) -> Result<Self> {
27 let magic = &data[0..4];
28 if magic != [0xd0, 0x0d, 0xfe, 0xed] {
29 return Err(DeviceTreeError::InvalidMagicNumber);
30 }
31
32 let header = DeviceTreeHeader::from_bytes(data)?;
33
34 let root = DeviceTreeNode::from_bytes(
35 data,
36 &header,
37 header.off_dt_struct as usize,
38 InheritedValues::new(),
39 )?;
40
41 Ok(Self { header, root })
42 }
43
44 #[cfg(not(feature = "std"))]
45 pub fn from_address(addr: usize) -> Result<Self> {
47 let header_bytes = unsafe { core::slice::from_raw_parts(addr as *const u8, 40) };
48 let magic = &header_bytes[0..4];
49 if magic != [0xd0, 0x0d, 0xfe, 0xed] {
50 return Err(DeviceTreeError::InvalidMagicNumber);
51 }
52 let header = DeviceTreeHeader::from_bytes(header_bytes)?;
53 let data =
54 unsafe { core::slice::from_raw_parts(addr as *const u8, header.total_size as usize) };
55 Self::from_bytes(data)
56 }
57
58 pub fn magic(&self) -> usize {
60 self.header.magic as usize
61 }
62
63 pub fn total_size(&self) -> usize {
65 self.header.total_size as usize
66 }
67
68 pub fn off_dt_struct(&self) -> usize {
70 self.header.off_dt_struct as usize
71 }
72
73 pub fn off_dt_strings(&self) -> usize {
75 self.header.off_dt_strings as usize
76 }
77
78 pub fn off_mem_reserved(&self) -> usize {
80 self.header.off_mem_reserved as usize
81 }
82
83 pub fn version(&self) -> usize {
85 self.header.version as usize
86 }
87
88 pub fn last_comp_version(&self) -> usize {
90 self.header.last_comp_version as usize
91 }
92
93 pub fn boot_cpu_id(&self) -> usize {
95 self.header.boot_cpu_id as usize
96 }
97
98 pub fn size_dt_strings(&self) -> usize {
100 self.header.size_dt_strings as usize
101 }
102
103 pub fn size_dt_struct(&self) -> usize {
105 self.header.size_dt_struct as usize
106 }
107
108 pub fn root(&self) -> &DeviceTreeNode {
110 &self.root
111 }
112
113 pub fn find_node(&self, path: &str) -> Option<&DeviceTreeNode> {
115 let mut slices = path.split('/');
116 if let Some("") = slices.next() {
117 let mut first = &self.root;
118 for i in slices {
119 if let Some(node) = first.find_child(i) {
120 first = node;
121 } else {
122 return None;
123 }
124 }
125 Some(first)
126 } else {
127 None
128 }
129 }
130
131 pub fn find_along_path(&self, path: &str) -> Option<Vec<&DeviceTreeNode>> {
133 let mut slices: Vec<&str> = path.split('/').collect();
134 let mut container = Vec::<&DeviceTreeNode>::new();
135 if slices.len() > 0 && self.root.name() == slices[0] {
136 container.push(&self.root);
137 if Self::find_along_path_internal(&self.root, &mut slices, 1, &mut container) {
138 Some(container)
139 } else {
140 None
141 }
142 } else {
143 None
144 }
145 }
146
147 fn find_along_path_internal<'tree>(
148 node: &'tree DeviceTreeNode,
149 slices: &mut [&str],
150 index: usize,
151 container: &mut Vec<&'tree DeviceTreeNode>,
152 ) -> bool {
153 if index == slices.len() {
154 return true;
155 }
156 let name = slices[index];
157 for node in node.nodes() {
158 if node.name() == name {
159 container.push(node);
160 return Self::find_along_path_internal(node, slices, index + 1, container);
161 }
162 }
163 return false;
164 }
165}
166
167pub struct DeviceTreeNodeIter<'a> {
169 queue: VecDeque<&'a DeviceTreeNode>,
170}
171
172impl<'a> Iterator for DeviceTreeNodeIter<'a> {
173 type Item = &'a DeviceTreeNode;
174
175 fn next(&mut self) -> Option<Self::Item> {
176 let res = self.queue.pop_front();
177 match res {
178 Some(node) if node.has_children() => {
179 for i in node.nodes() {
180 self.queue.push_back(i);
181 }
182 }
183 _ => {}
184 }
185 res
186 }
187}
188
189impl Display for DeviceTree {
190 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
191 writeln!(f, "{}", self.root)
192 }
193}
194
195impl<'a> IntoIterator for &'a DeviceTree {
196 type Item = &'a DeviceTreeNode;
197 type IntoIter = DeviceTreeNodeIter<'a>;
198
199 fn into_iter(self) -> Self::IntoIter {
200 DeviceTreeNodeIter {
201 queue: VecDeque::from([self.root()]),
202 }
203 }
204}
205
206#[derive(Clone)]
207pub(crate) struct InheritedValues(Vec<(String, u64)>);
208
209impl InheritedValues {
210 pub const fn new() -> Self {
211 InheritedValues(vec![])
212 }
213
214 pub fn find(&self, name: &str) -> Option<u64> {
215 for i in &self.0 {
216 if i.0.as_str() == name {
217 return Some(i.1);
218 }
219 }
220 None
221 }
222
223 pub fn insert(&mut self, name: String, value: u64) {
224 self.0.push((name, value));
225 }
226}