1use core::fmt::Debug;
2
3use alloc::{
4 collections::BTreeMap,
5 string::{String, ToString},
6 vec::Vec,
7};
8use fdt_raw::data::StrIter;
9
10use crate::{Phandle, Property, RangesEntry, Status, node::gerneric::NodeRefGen};
11
12mod clock;
13mod display;
14mod gerneric;
15mod interrupt_controller;
16mod iter;
17mod memory;
18mod pci;
19
20pub use clock::*;
21pub use display::*;
22pub use interrupt_controller::*;
23pub use iter::*;
24pub use memory::*;
25pub use pci::*;
26
27#[derive(Clone, Debug)]
29pub enum NodeKind<'a> {
30 Clock(NodeRefClock<'a>),
31 Pci(NodeRefPci<'a>),
32 InterruptController(NodeRefInterruptController<'a>),
33 Memory(NodeRefMemory<'a>),
34 Generic(NodeRefGen<'a>),
35}
36
37#[derive(Clone)]
38pub struct Node {
39 pub name: String,
40 pub(crate) properties: Vec<Property>,
42 pub(crate) prop_cache: BTreeMap<String, usize>,
44 pub(crate) children: Vec<Node>,
45 pub(crate) name_cache: BTreeMap<String, usize>,
46}
47
48impl Node {
49 pub fn new(name: &str) -> Self {
50 Self {
51 name: name.to_string(),
52 properties: Vec::new(),
53 prop_cache: BTreeMap::new(),
54 children: Vec::new(),
55 name_cache: BTreeMap::new(),
56 }
57 }
58
59 pub fn name(&self) -> &str {
60 &self.name
61 }
62
63 pub fn properties(&self) -> impl Iterator<Item = &Property> {
64 self.properties.iter()
65 }
66
67 pub fn children(&self) -> impl Iterator<Item = &Node> {
68 self.children.iter()
69 }
70
71 pub fn children_mut(&mut self) -> impl Iterator<Item = &mut Node> {
72 self.children.iter_mut()
73 }
74
75 pub fn add_child(&mut self, child: Node) {
76 let index = self.children.len();
77 self.name_cache.insert(child.name.clone(), index);
78 self.children.push(child);
79 }
80
81 pub fn add_property(&mut self, prop: Property) {
82 let name = prop.name.clone();
83 let index = self.properties.len();
84 self.prop_cache.insert(name, index);
85 self.properties.push(prop);
86 }
87
88 pub fn get_child(&self, name: &str) -> Option<&Node> {
89 if let Some(&index) = self.name_cache.get(name) {
90 self.children.get(index)
91 } else {
92 None
93 }
94 }
95
96 pub fn get_child_mut(&mut self, name: &str) -> Option<&mut Node> {
97 if let Some(&index) = self.name_cache.get(name) {
98 self.children.get_mut(index)
99 } else {
100 None
101 }
102 }
103
104 pub fn remove_child(&mut self, name: &str) -> Option<Node> {
105 if let Some(&index) = self.name_cache.get(name) {
106 self.name_cache.remove(name);
107 Some(self.children.remove(index))
108 } else {
109 None
110 }
111 }
112
113 pub fn set_property(&mut self, prop: Property) {
114 let name = prop.name.clone();
115 if let Some(&idx) = self.prop_cache.get(&name) {
116 self.properties[idx] = prop;
118 } else {
119 let idx = self.properties.len();
121 self.prop_cache.insert(name, idx);
122 self.properties.push(prop);
123 }
124 }
125
126 pub fn get_property(&self, name: &str) -> Option<&Property> {
127 self.prop_cache.get(name).map(|&idx| &self.properties[idx])
128 }
129
130 pub fn get_property_mut(&mut self, name: &str) -> Option<&mut Property> {
131 self.prop_cache
132 .get(name)
133 .map(|&idx| &mut self.properties[idx])
134 }
135
136 pub fn remove_property(&mut self, name: &str) -> Option<Property> {
137 if let Some(&idx) = self.prop_cache.get(name) {
138 self.prop_cache.remove(name);
139 let prop = self.properties.remove(idx);
141 for (_, v) in self.prop_cache.iter_mut() {
142 if *v > idx {
143 *v -= 1;
144 }
145 }
146 Some(prop)
147 } else {
148 None
149 }
150 }
151
152 pub fn address_cells(&self) -> Option<u32> {
153 self.get_property("#address-cells")
154 .and_then(|prop| prop.get_u32())
155 }
156
157 pub fn size_cells(&self) -> Option<u32> {
158 self.get_property("#size-cells")
159 .and_then(|prop| prop.get_u32())
160 }
161
162 pub fn phandle(&self) -> Option<Phandle> {
163 self.get_property("phandle")
164 .and_then(|prop| prop.get_u32())
165 .map(Phandle::from)
166 }
167
168 pub fn interrupt_parent(&self) -> Option<Phandle> {
169 self.get_property("interrupt-parent")
170 .and_then(|prop| prop.get_u32())
171 .map(Phandle::from)
172 }
173
174 pub fn status(&self) -> Option<Status> {
175 let prop = self.get_property("status")?;
176 let s = prop.as_str()?;
177 match s {
178 "okay" => Some(Status::Okay),
179 "disabled" => Some(Status::Disabled),
180 _ => None,
181 }
182 }
183
184 pub fn ranges(&self, parent_address_cells: u32) -> Option<Vec<RangesEntry>> {
185 let prop = self.get_property("ranges")?;
186 let mut entries = Vec::new();
187 let mut reader = prop.as_reader();
188
189 let child_address_cells = self.address_cells().unwrap_or(2) as usize;
191 let parent_addr_cells = parent_address_cells as usize;
193 let size_cells = self.size_cells().unwrap_or(1) as usize;
195
196 while let (Some(child_addr), Some(parent_addr), Some(size)) = (
197 reader.read_cells(child_address_cells),
198 reader.read_cells(parent_addr_cells),
199 reader.read_cells(size_cells),
200 ) {
201 entries.push(RangesEntry {
202 child_bus_address: child_addr,
203 parent_bus_address: parent_addr,
204 length: size,
205 });
206 }
207
208 Some(entries)
209 }
210
211 pub fn compatible(&self) -> Option<StrIter<'_>> {
212 let prop = self.get_property("compatible")?;
213 Some(prop.as_str_iter())
214 }
215
216 pub fn compatibles(&self) -> impl Iterator<Item = &str> {
217 self.get_property("compatible")
218 .map(|prop| prop.as_str_iter())
219 .into_iter()
220 .flatten()
221 }
222
223 pub fn device_type(&self) -> Option<&str> {
224 let prop = self.get_property("device_type")?;
225 prop.as_str()
226 }
227
228 pub fn remove_by_path(&mut self, path: &str) -> Result<Option<Node>, fdt_raw::FdtError> {
253 let normalized_path = path.trim_start_matches('/');
254 if normalized_path.is_empty() {
255 return Err(fdt_raw::FdtError::InvalidInput);
256 }
257
258 let parts: Vec<&str> = normalized_path.split('/').collect();
259 if parts.is_empty() {
260 return Err(fdt_raw::FdtError::InvalidInput);
261 }
262
263 if parts.len() == 1 {
264 let child_name = parts[0];
266 Ok(self.remove_child_exact(child_name))
267 } else {
268 self.remove_child_recursive(&parts, 0)
270 }
271 }
272
273 fn remove_child_recursive(
276 &mut self,
277 parts: &[&str],
278 index: usize,
279 ) -> Result<Option<Node>, fdt_raw::FdtError> {
280 if index >= parts.len() - 1 {
281 let child_name_to_remove = parts[index];
283 Ok(self.remove_child_exact(child_name_to_remove))
284 } else {
285 let current_part = parts[index];
287
288 if let Some(&child_index) = self.name_cache.get(current_part) {
290 self.children[child_index].remove_child_recursive(parts, index + 1)
291 } else {
292 Ok(None)
294 }
295 }
296 }
297
298 fn remove_child_exact(&mut self, name: &str) -> Option<Node> {
300 if let Some(&index) = self.name_cache.get(name) {
301 let child = self.children.remove(index);
302 self.name_cache.remove(name);
303 Some(child)
304 } else {
305 None
306 }
307 }
308}
309
310impl From<&fdt_raw::Node<'_>> for Node {
311 fn from(raw: &fdt_raw::Node<'_>) -> Self {
312 let mut new_node = Node::new(raw.name());
313 for raw_prop in raw.properties() {
315 let prop = Property::from(&raw_prop);
316 new_node.set_property(prop);
317 }
318 new_node
319 }
320}