1mod clock;
9mod generic;
10mod intc;
11mod memory;
12mod pci;
13
14use core::fmt::Display;
15
16use alloc::{borrow::ToOwned, string::String, vec::Vec};
17use enum_dispatch::enum_dispatch;
18use fdt_raw::Phandle;
19
20use crate::{Fdt, Node, NodeId, Property, RangesEntry};
21
22pub use clock::{ClockNodeView, ClockNodeViewMut, ClockRef, ClockType, FixedClock};
24pub use generic::{NodeGeneric, NodeGenericMut};
25pub use intc::{IntcNodeView, IntcNodeViewMut};
26pub use memory::{MemoryNodeView, MemoryNodeViewMut};
27pub use pci::{PciInterruptInfo, PciInterruptMap, PciNodeView, PciNodeViewMut, PciRange, PciSpace};
28
29#[enum_dispatch]
30pub(crate) trait ViewOp<'a> {
31 fn as_view(&self) -> NodeView<'a>;
32 fn display(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 self.as_view().fmt(f)
34 }
35}
36
37pub(crate) trait ViewMutOp<'a> {
38 fn new(node: NodeGenericMut<'a>) -> Self;
39}
40
41#[derive(Clone, Copy)]
50pub(crate) struct NodeView<'a> {
51 fdt: *mut Fdt,
52 id: NodeId,
53 _marker: core::marker::PhantomData<&'a ()>, }
55
56unsafe impl<'a> Send for NodeView<'a> {}
57
58impl<'a> NodeView<'a> {
59 pub(crate) fn new(fdt: &'a Fdt, id: NodeId) -> Self {
61 Self {
62 fdt: fdt as *const Fdt as *mut Fdt,
63 id,
64 _marker: core::marker::PhantomData,
65 }
66 }
67
68 pub fn name(&self) -> &'a str {
69 self.as_node().name()
70 }
71
72 pub fn id(&self) -> NodeId {
74 self.id
75 }
76
77 pub fn as_node(&self) -> &'a Node {
79 self.fdt()
80 .node(self.id)
81 .expect("NodeView references a valid node")
82 }
83
84 pub fn as_node_mut(&mut self) -> &'a mut Node {
85 self.fdt_mut()
86 .node_mut(self.id)
87 .expect("NodeViewMut references a valid node")
88 }
89
90 pub fn fdt(&self) -> &'a Fdt {
92 unsafe { &*self.fdt }
93 }
94
95 pub fn fdt_mut(&mut self) -> &'a mut Fdt {
96 unsafe { &mut *self.fdt }
97 }
98
99 pub fn path(&self) -> String {
100 self.fdt().path_of(self.id)
101 }
102
103 pub fn parent(&self) -> Option<NodeType<'a>> {
104 self.fdt()
105 .parent_of(self.id)
106 .map(|pid| NodeView::new(self.fdt(), pid).classify())
107 }
108
109 #[allow(dead_code)]
110 pub fn parent_mut(&mut self) -> Option<NodeTypeMut<'a>> {
111 let parent = self.fdt().parent_of(self.id)?;
112 let mut parent_view = NodeView::new(self.fdt(), parent);
113 let cl = parent_view.classify_mut();
114 Some(cl)
115 }
116
117 pub fn address_cells(&self) -> Option<u32> {
118 self.as_node().address_cells()
119 }
120
121 pub fn size_cells(&self) -> Option<u32> {
122 self.as_node().size_cells()
123 }
124
125 pub fn interrupt_parent(&self) -> Option<Phandle> {
127 let mut current = Some(self.id);
128
129 while let Some(node_id) = current {
130 let node = self.fdt().node(node_id)?;
131 if let Some(phandle) = node.interrupt_parent() {
132 return Some(phandle);
133 }
134 current = self.fdt().parent_of(node_id);
135 }
136
137 None
138 }
139
140 pub fn clocks(&self) -> Vec<ClockRef> {
145 let Some(prop) = self.as_node().get_property("clocks") else {
146 return Vec::new();
147 };
148
149 let clock_names: Vec<String> = self
150 .as_node()
151 .get_property("clock-names")
152 .map(|prop| prop.as_str_iter().map(|s| s.to_owned()).collect())
153 .unwrap_or_default();
154
155 let mut reader = prop.as_reader();
156 let mut refs = Vec::new();
157 let mut index = 0;
158
159 while let Some(phandle_raw) = reader.read_u32() {
160 let phandle = Phandle::from(phandle_raw);
161 let clock_cells = self
162 .fdt()
163 .get_by_phandle(phandle)
164 .and_then(|provider| provider.as_node().get_property("#clock-cells"))
165 .and_then(|prop| prop.get_u32())
166 .unwrap_or(1);
167
168 let mut specifier = Vec::with_capacity(clock_cells as usize);
169 let mut complete = true;
170 for _ in 0..clock_cells {
171 if let Some(value) = reader.read_u32() {
172 specifier.push(value);
173 } else {
174 complete = false;
175 break;
176 }
177 }
178
179 if !complete {
180 break;
181 }
182
183 refs.push(ClockRef::with_name(
184 clock_names.get(index).cloned(),
185 phandle,
186 clock_cells,
187 specifier,
188 ));
189 index += 1;
190 }
191
192 refs
193 }
194
195 pub fn regs(&self) -> Vec<RegFixed> {
199 let node = self.as_node();
200 let reg = match node.get_property("reg") {
201 Some(p) => p,
202 None => return Vec::new(),
203 };
204
205 let (addr_cells, size_cells) = self.parent_cells();
207
208 let ranges = self.parent_ranges();
210
211 let mut reader = reg.as_reader();
212 let mut results = Vec::new();
213
214 while let Some(child_bus_address) = reader.read_cells(addr_cells) {
215 let size = if size_cells > 0 {
216 reader.read_cells(size_cells)
217 } else {
218 None
219 };
220
221 let mut address = child_bus_address;
223 if let Some(ref ranges) = ranges {
224 for r in ranges {
225 if child_bus_address >= r.child_bus_address
226 && child_bus_address < r.child_bus_address + r.length
227 {
228 address = child_bus_address - r.child_bus_address + r.parent_bus_address;
229 break;
230 }
231 }
232 }
233
234 results.push(RegFixed {
235 address,
236 child_bus_address,
237 size,
238 });
239 }
240
241 results
242 }
243
244 fn parent_cells(&self) -> (usize, usize) {
246 if let Some(parent) = self.parent() {
247 let ac = parent.as_view().address_cells().unwrap_or(2) as usize;
248 let sc = parent.as_view().size_cells().unwrap_or(1) as usize;
249 (ac, sc)
250 } else {
251 (2, 1)
252 }
253 }
254
255 fn parent_ranges(&self) -> Option<Vec<RangesEntry>> {
257 self.parent().and_then(|p| {
258 let view = p.as_view();
259 let parent_addr_cells = p
261 .parent()
262 .and_then(|gp| gp.as_view().address_cells())
263 .unwrap_or(2);
264 view.as_node().ranges(parent_addr_cells)
265 })
266 }
267
268 pub fn set_regs(&mut self, regs: &[fdt_raw::RegInfo]) {
273 let (addr_cells, size_cells) = self.parent_cells();
275
276 let ranges = self.parent_ranges();
278
279 let mut data = Vec::new();
280
281 for reg in regs {
282 let mut bus_address = reg.address;
284 if let Some(ref ranges) = ranges {
285 for r in ranges {
286 if reg.address >= r.parent_bus_address
288 && reg.address < r.parent_bus_address + r.length
289 {
290 bus_address = reg.address - r.parent_bus_address + r.child_bus_address;
292 break;
293 }
294 }
295 }
296
297 match addr_cells {
299 1 => data.extend_from_slice(&(bus_address as u32).to_be_bytes()),
300 2 => {
301 data.extend_from_slice(&((bus_address >> 32) as u32).to_be_bytes());
302 data.extend_from_slice(&((bus_address & 0xFFFF_FFFF) as u32).to_be_bytes());
303 }
304 n => {
305 for i in 0..n {
307 let shift = (n - 1 - i) * 32;
308 data.extend_from_slice(&(((bus_address >> shift) as u32).to_be_bytes()));
309 }
310 }
311 }
312
313 let size = reg.size.unwrap_or(0);
315 match size_cells {
316 1 => data.extend_from_slice(&(size as u32).to_be_bytes()),
317 2 => {
318 data.extend_from_slice(&((size >> 32) as u32).to_be_bytes());
319 data.extend_from_slice(&((size & 0xFFFF_FFFF) as u32).to_be_bytes());
320 }
321 n => {
322 for i in 0..n {
323 let shift = (n - 1 - i) * 32;
324 data.extend_from_slice(&(((size >> shift) as u32).to_be_bytes()));
325 }
326 }
327 }
328 }
329
330 let prop = Property::new("reg", data);
331 self.as_node_mut().set_property(prop);
332 }
333
334 pub(crate) fn classify(&self) -> NodeType<'a> {
335 if let Some(node) = ClockNodeView::try_from_view(*self) {
336 return NodeType::Clock(node);
337 }
338
339 if let Some(node) = PciNodeView::try_from_view(*self) {
340 return NodeType::Pci(node);
341 }
342
343 if let Some(node) = MemoryNodeView::try_from_view(*self) {
344 return NodeType::Memory(node);
345 }
346
347 if let Some(node) = IntcNodeView::try_from_view(*self) {
348 return NodeType::InterruptController(node);
349 }
350
351 NodeType::Generic(NodeGeneric { inner: *self })
352 }
353
354 pub(crate) fn classify_mut(&mut self) -> NodeTypeMut<'a> {
355 if let Some(node) = ClockNodeViewMut::try_from_view(*self) {
356 return NodeTypeMut::Clock(node);
357 }
358
359 if let Some(node) = PciNodeViewMut::try_from_view(*self) {
360 return NodeTypeMut::Pci(node);
361 }
362
363 if let Some(node) = MemoryNodeViewMut::try_from_view(*self) {
364 return NodeTypeMut::Memory(node);
365 }
366
367 if let Some(node) = IntcNodeViewMut::try_from_view(*self) {
368 return NodeTypeMut::InterruptController(node);
369 }
370
371 NodeTypeMut::Generic(NodeGenericMut { inner: *self })
372 }
373}
374
375impl core::fmt::Display for NodeView<'_> {
376 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
377 write!(f, "{}", self.path())?;
378 for prop in self.as_node().properties() {
379 write!(f, "\n {} = ", prop.name())?;
380 if prop.name() == "compatible" {
381 write!(f, "[")?;
382 let strs: Vec<&str> = prop.as_str_iter().collect();
383 for (i, s) in strs.iter().enumerate() {
384 write!(f, "\"{}\"", s)?;
385 if i < strs.len() - 1 {
386 write!(f, ", ")?;
387 }
388 }
389 write!(f, "]")?;
390 continue;
391 }
392 if let Some(s) = prop.as_str() {
393 write!(f, "\"{}\";", s)?;
394 } else {
395 for cell in prop.get_u32_iter() {
396 write!(f, "{:#x} ", cell)?;
397 }
398 write!(f, ";")?;
399 }
400 }
401 Ok(())
402 }
403}
404
405#[enum_dispatch(ViewOp)]
410pub enum NodeType<'a> {
412 Clock(ClockNodeView<'a>),
414 Memory(MemoryNodeView<'a>),
416 InterruptController(IntcNodeView<'a>),
418 Pci(PciNodeView<'a>),
420 Generic(NodeGeneric<'a>),
422}
423
424impl<'a> NodeType<'a> {
425 pub fn as_node(&self) -> &'a Node {
427 self.as_view().as_node()
428 }
429
430 pub fn path(&self) -> String {
432 self.as_view().path()
433 }
434
435 pub fn parent(&self) -> Option<NodeType<'a>> {
436 self.as_view().parent()
437 }
438
439 pub fn id(&self) -> NodeId {
441 self.as_view().id()
442 }
443
444 pub fn name(&self) -> &'a str {
446 self.as_view().name()
447 }
448
449 pub fn regs(&self) -> Vec<RegFixed> {
451 self.as_view().regs()
452 }
453
454 pub fn interrupt_parent(&self) -> Option<Phandle> {
456 self.as_view().interrupt_parent()
457 }
458
459 pub fn clocks(&self) -> Vec<ClockRef> {
461 self.as_view().clocks()
462 }
463}
464
465impl core::fmt::Display for NodeType<'_> {
466 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
467 self.display(f)
468 }
469}
470
471#[enum_dispatch(ViewOp)]
477pub enum NodeTypeMut<'a> {
478 Clock(ClockNodeViewMut<'a>),
479 Memory(MemoryNodeViewMut<'a>),
480 InterruptController(IntcNodeViewMut<'a>),
481 Pci(PciNodeViewMut<'a>),
482 Generic(NodeGenericMut<'a>),
483}
484
485impl<'a> NodeTypeMut<'a> {
486 pub fn id(&self) -> NodeId {
488 self.as_view().id()
489 }
490
491 pub fn set_regs(&mut self, regs: &[fdt_raw::RegInfo]) {
496 self.as_view().set_regs(regs);
497 }
498}
499
500impl Fdt {
505 fn view(&self, id: NodeId) -> Option<NodeView<'_>> {
507 if self.node(id).is_some() {
508 Some(NodeView::new(self, id))
509 } else {
510 None
511 }
512 }
513
514 pub fn view_typed(&self, id: NodeId) -> Option<NodeType<'_>> {
516 self.view(id).map(|v| v.classify())
517 }
518
519 pub fn view_typed_mut(&mut self, id: NodeId) -> Option<NodeTypeMut<'_>> {
521 self.view(id).map(|mut v| v.classify_mut())
522 }
523}
524
525impl<'a> NodeGenericMut<'a> {
526 pub fn add_child_memory(&mut self, name: &str) -> MemoryNodeViewMut<'a> {
527 self.add_child(name)
528 }
529
530 pub fn add_child_interrupt_controller(&mut self, name: &str) -> IntcNodeViewMut<'a> {
531 self.add_child(name)
532 }
533}
534
535#[derive(Clone, Copy, Debug)]
536pub struct RegFixed {
537 pub address: u64,
538 pub child_bus_address: u64,
539 pub size: Option<u64>,
540}