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 children: Vec<Node>,
45 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) -> &[Node] {
68 &self.children
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 if let Some(child) = self.children.get(index) {
91 return Some(child);
92 }
93 }
94
95 self.children.iter().find(|c| c.name == name)
97 }
98
99 pub fn get_child_mut(&mut self, name: &str) -> Option<&mut Node> {
100 if let Some(&index) = self.name_cache.get(name) {
101 if index < self.children.len() && self.children[index].name == name {
102 return self.children.get_mut(index);
103 }
104 }
105
106 let pos = self.children.iter().position(|c| c.name == name)?;
108 self.rebuild_name_cache();
109 self.children.get_mut(pos)
110 }
111
112 pub fn remove_child(&mut self, name: &str) -> Option<Node> {
113 let index = self
114 .name_cache
115 .get(name)
116 .copied()
117 .filter(|&idx| self.children.get(idx).map(|c| c.name.as_str()) == Some(name))
118 .or_else(|| self.children.iter().position(|c| c.name == name));
119
120 let Some(idx) = index else { return None };
121
122 let removed = self.children.remove(idx);
123 self.rebuild_name_cache();
124 Some(removed)
125 }
126
127 pub fn set_property(&mut self, prop: Property) {
128 let name = prop.name.clone();
129 if let Some(&idx) = self.prop_cache.get(&name) {
130 self.properties[idx] = prop;
132 } else {
133 let idx = self.properties.len();
135 self.prop_cache.insert(name, idx);
136 self.properties.push(prop);
137 }
138 }
139
140 pub fn get_property(&self, name: &str) -> Option<&Property> {
141 self.prop_cache.get(name).map(|&idx| &self.properties[idx])
142 }
143
144 pub fn get_property_mut(&mut self, name: &str) -> Option<&mut Property> {
145 self.prop_cache
146 .get(name)
147 .map(|&idx| &mut self.properties[idx])
148 }
149
150 pub fn remove_property(&mut self, name: &str) -> Option<Property> {
151 if let Some(&idx) = self.prop_cache.get(name) {
152 self.prop_cache.remove(name);
153 let prop = self.properties.remove(idx);
155 for (_, v) in self.prop_cache.iter_mut() {
156 if *v > idx {
157 *v -= 1;
158 }
159 }
160 Some(prop)
161 } else {
162 None
163 }
164 }
165
166 pub fn address_cells(&self) -> Option<u32> {
167 self.get_property("#address-cells")
168 .and_then(|prop| prop.get_u32())
169 }
170
171 pub fn size_cells(&self) -> Option<u32> {
172 self.get_property("#size-cells")
173 .and_then(|prop| prop.get_u32())
174 }
175
176 pub fn phandle(&self) -> Option<Phandle> {
177 self.get_property("phandle")
178 .and_then(|prop| prop.get_u32())
179 .map(Phandle::from)
180 }
181
182 pub fn interrupt_parent(&self) -> Option<Phandle> {
183 self.get_property("interrupt-parent")
184 .and_then(|prop| prop.get_u32())
185 .map(Phandle::from)
186 }
187
188 pub fn status(&self) -> Option<Status> {
189 let prop = self.get_property("status")?;
190 let s = prop.as_str()?;
191 match s {
192 "okay" => Some(Status::Okay),
193 "disabled" => Some(Status::Disabled),
194 _ => None,
195 }
196 }
197
198 pub fn ranges(&self, parent_address_cells: u32) -> Option<Vec<RangesEntry>> {
199 let prop = self.get_property("ranges")?;
200 let mut entries = Vec::new();
201 let mut reader = prop.as_reader();
202
203 let child_address_cells = self.address_cells().unwrap_or(2) as usize;
205 let parent_addr_cells = parent_address_cells as usize;
207 let size_cells = self.size_cells().unwrap_or(1) as usize;
209
210 while let (Some(child_addr), Some(parent_addr), Some(size)) = (
211 reader.read_cells(child_address_cells),
212 reader.read_cells(parent_addr_cells),
213 reader.read_cells(size_cells),
214 ) {
215 entries.push(RangesEntry {
216 child_bus_address: child_addr,
217 parent_bus_address: parent_addr,
218 length: size,
219 });
220 }
221
222 Some(entries)
223 }
224
225 fn rebuild_name_cache(&mut self) {
226 self.name_cache.clear();
227 for (idx, child) in self.children.iter().enumerate() {
228 self.name_cache.insert(child.name.clone(), idx);
229 }
230 }
231
232 pub fn compatible(&self) -> Option<StrIter<'_>> {
233 let prop = self.get_property("compatible")?;
234 Some(prop.as_str_iter())
235 }
236
237 pub fn compatibles(&self) -> impl Iterator<Item = &str> {
238 self.get_property("compatible")
239 .map(|prop| prop.as_str_iter())
240 .into_iter()
241 .flatten()
242 }
243
244 pub fn device_type(&self) -> Option<&str> {
245 let prop = self.get_property("device_type")?;
246 prop.as_str()
247 }
248
249 pub fn remove_by_path(&mut self, path: &str) -> Result<Option<Node>, fdt_raw::FdtError> {
274 let normalized_path = path.trim_start_matches('/');
275 if normalized_path.is_empty() {
276 return Err(fdt_raw::FdtError::InvalidInput);
277 }
278
279 let parts: Vec<&str> = normalized_path.split('/').collect();
280 if parts.is_empty() {
281 return Err(fdt_raw::FdtError::InvalidInput);
282 }
283 if parts.len() == 1 {
284 let child_name = parts[0];
286 Ok(self.remove_child(child_name))
287 } else {
288 self.remove_child_recursive(&parts, 0)
290 }
291 }
292
293 fn remove_child_recursive(
296 &mut self,
297 parts: &[&str],
298 index: usize,
299 ) -> Result<Option<Node>, fdt_raw::FdtError> {
300 if index >= parts.len() - 1 {
301 let child_name_to_remove = parts[index];
303 Ok(self.remove_child(child_name_to_remove))
304 } else {
305 let current_part = parts[index];
307
308 if let Some(&child_index) = self.name_cache.get(current_part) {
310 self.children[child_index].remove_child_recursive(parts, index + 1)
311 } else {
312 Ok(None)
314 }
315 }
316 }
317}
318
319impl From<&fdt_raw::Node<'_>> for Node {
320 fn from(raw: &fdt_raw::Node<'_>) -> Self {
321 let mut new_node = Node::new(raw.name());
322 for raw_prop in raw.properties() {
324 let prop = Property::from(&raw_prop);
325 new_node.set_property(prop);
326 }
327 new_node
328 }
329}