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 get_child(&self, name: &str) -> Option<&Node> {
82 if let Some(&index) = self.name_cache.get(name) {
83 self.children.get(index)
84 } else {
85 None
86 }
87 }
88
89 pub fn get_child_mut(&mut self, name: &str) -> Option<&mut Node> {
90 if let Some(&index) = self.name_cache.get(name) {
91 self.children.get_mut(index)
92 } else {
93 None
94 }
95 }
96
97 pub fn remove_child(&mut self, name: &str) -> Option<Node> {
98 if let Some(&index) = self.name_cache.get(name) {
99 self.name_cache.remove(name);
100 Some(self.children.remove(index))
101 } else {
102 None
103 }
104 }
105
106 pub fn set_property(&mut self, prop: Property) {
107 let name = prop.name.clone();
108 if let Some(&idx) = self.prop_cache.get(&name) {
109 self.properties[idx] = prop;
111 } else {
112 let idx = self.properties.len();
114 self.prop_cache.insert(name, idx);
115 self.properties.push(prop);
116 }
117 }
118
119 pub fn get_property(&self, name: &str) -> Option<&Property> {
120 self.prop_cache.get(name).map(|&idx| &self.properties[idx])
121 }
122
123 pub fn get_property_mut(&mut self, name: &str) -> Option<&mut Property> {
124 self.prop_cache
125 .get(name)
126 .map(|&idx| &mut self.properties[idx])
127 }
128
129 pub fn remove_property(&mut self, name: &str) -> Option<Property> {
130 if let Some(&idx) = self.prop_cache.get(name) {
131 self.prop_cache.remove(name);
132 let prop = self.properties.remove(idx);
134 for (_, v) in self.prop_cache.iter_mut() {
135 if *v > idx {
136 *v -= 1;
137 }
138 }
139 Some(prop)
140 } else {
141 None
142 }
143 }
144
145 pub fn address_cells(&self) -> Option<u32> {
146 self.get_property("#address-cells")
147 .and_then(|prop| prop.get_u32())
148 }
149
150 pub fn size_cells(&self) -> Option<u32> {
151 self.get_property("#size-cells")
152 .and_then(|prop| prop.get_u32())
153 }
154
155 pub fn phandle(&self) -> Option<Phandle> {
156 self.get_property("phandle")
157 .and_then(|prop| prop.get_u32())
158 .map(Phandle::from)
159 }
160
161 pub fn interrupt_parent(&self) -> Option<Phandle> {
162 self.get_property("interrupt-parent")
163 .and_then(|prop| prop.get_u32())
164 .map(Phandle::from)
165 }
166
167 pub fn status(&self) -> Option<Status> {
168 let prop = self.get_property("status")?;
169 let s = prop.as_str()?;
170 match s {
171 "okay" => Some(Status::Okay),
172 "disabled" => Some(Status::Disabled),
173 _ => None,
174 }
175 }
176
177 pub fn ranges(&self, parent_address_cells: u32) -> Option<Vec<RangesEntry>> {
178 let prop = self.get_property("ranges")?;
179 let mut entries = Vec::new();
180 let mut reader = prop.as_reader();
181
182 let child_address_cells = self.address_cells().unwrap_or(2) as usize;
184 let parent_addr_cells = parent_address_cells as usize;
186 let size_cells = self.size_cells().unwrap_or(1) as usize;
188
189 while let (Some(child_addr), Some(parent_addr), Some(size)) = (
190 reader.read_cells(child_address_cells),
191 reader.read_cells(parent_addr_cells),
192 reader.read_cells(size_cells),
193 ) {
194 entries.push(RangesEntry {
195 child_bus_address: child_addr,
196 parent_bus_address: parent_addr,
197 length: size,
198 });
199 }
200
201 Some(entries)
202 }
203
204 pub fn compatible(&self) -> Option<StrIter<'_>> {
205 let prop = self.get_property("compatible")?;
206 Some(prop.as_str_iter())
207 }
208
209 pub fn compatibles(&self) -> impl Iterator<Item = &str> {
210 self.get_property("compatible")
211 .map(|prop| prop.as_str_iter())
212 .into_iter()
213 .flatten()
214 }
215
216 pub fn device_type(&self) -> Option<&str> {
217 let prop = self.get_property("device_type")?;
218 prop.as_str()
219 }
220
221 pub fn remove_by_path(&mut self, path: &str) -> Result<Option<Node>, fdt_raw::FdtError> {
246 let normalized_path = path.trim_start_matches('/');
247 if normalized_path.is_empty() {
248 return Err(fdt_raw::FdtError::InvalidInput);
249 }
250
251 let parts: Vec<&str> = normalized_path.split('/').collect();
252 if parts.is_empty() {
253 return Err(fdt_raw::FdtError::InvalidInput);
254 }
255
256 if parts.len() == 1 {
257 let child_name = parts[0];
259 Ok(self.remove_child_exact(child_name))
260 } else {
261 self.remove_child_recursive(&parts, 0)
263 }
264 }
265
266 fn remove_child_recursive(
269 &mut self,
270 parts: &[&str],
271 index: usize,
272 ) -> Result<Option<Node>, fdt_raw::FdtError> {
273 if index >= parts.len() - 1 {
274 let child_name_to_remove = parts[index];
276 Ok(self.remove_child_exact(child_name_to_remove))
277 } else {
278 let current_part = parts[index];
280
281 if let Some(&child_index) = self.name_cache.get(current_part) {
283 self.children[child_index].remove_child_recursive(parts, index + 1)
284 } else {
285 Ok(None)
287 }
288 }
289 }
290
291 fn remove_child_exact(&mut self, name: &str) -> Option<Node> {
293 if let Some(&index) = self.name_cache.get(name) {
294 let child = self.children.remove(index);
295 self.name_cache.remove(name);
296 Some(child)
297 } else {
298 None
299 }
300 }
301}
302
303impl From<&fdt_raw::Node<'_>> for Node {
304 fn from(raw: &fdt_raw::Node<'_>) -> Self {
305 let mut new_node = Node::new(raw.name());
306 for raw_prop in raw.properties() {
308 let prop = Property::from(&raw_prop);
309 new_node.set_property(prop);
310 }
311 new_node
312 }
313}