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, InterruptRef};
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 interrupts(&self) -> Vec<InterruptRef> {
200 let Some(prop) = self.as_node().get_property("interrupts") else {
201 return Vec::new();
202 };
203
204 let Some(interrupt_parent) = self.interrupt_parent() else {
205 return Vec::new();
206 };
207
208 let cells = self
209 .fdt()
210 .get_by_phandle(interrupt_parent)
211 .and_then(|provider| provider.as_node().get_property("#interrupt-cells"))
212 .and_then(|prop| prop.get_u32())
213 .unwrap_or(1);
214
215 if cells == 0 {
216 return Vec::new();
217 }
218
219 let interrupt_names: Vec<String> = self
220 .as_node()
221 .get_property("interrupt-names")
222 .map(|prop| prop.as_str_iter().map(|s| s.to_owned()).collect())
223 .unwrap_or_default();
224
225 let mut reader = prop.as_reader();
226 let mut refs = Vec::new();
227 let mut index = 0;
228
229 while let Some(first) = reader.read_u32() {
230 let mut specifier = Vec::with_capacity(cells as usize);
231 specifier.push(first);
232
233 let mut complete = true;
234 for _ in 1..cells {
235 if let Some(value) = reader.read_u32() {
236 specifier.push(value);
237 } else {
238 complete = false;
239 break;
240 }
241 }
242
243 if !complete {
244 break;
245 }
246
247 refs.push(InterruptRef::with_name(
248 interrupt_names.get(index).cloned(),
249 interrupt_parent,
250 cells,
251 specifier,
252 ));
253 index += 1;
254 }
255
256 refs
257 }
258
259 pub fn regs(&self) -> Vec<RegFixed> {
263 let node = self.as_node();
264 let reg = match node.get_property("reg") {
265 Some(p) => p,
266 None => return Vec::new(),
267 };
268
269 let (addr_cells, size_cells) = self.parent_cells();
271
272 let ranges = self.parent_ranges();
274
275 let mut reader = reg.as_reader();
276 let mut results = Vec::new();
277
278 while let Some(child_bus_address) = reader.read_cells(addr_cells) {
279 let size = if size_cells > 0 {
280 reader.read_cells(size_cells)
281 } else {
282 None
283 };
284
285 let mut address = child_bus_address;
287 if let Some(ref ranges) = ranges {
288 for r in ranges {
289 if child_bus_address >= r.child_bus_address
290 && child_bus_address < r.child_bus_address + r.length
291 {
292 address = child_bus_address - r.child_bus_address + r.parent_bus_address;
293 break;
294 }
295 }
296 }
297
298 results.push(RegFixed {
299 address,
300 child_bus_address,
301 size,
302 });
303 }
304
305 results
306 }
307
308 fn parent_cells(&self) -> (usize, usize) {
310 if let Some(parent) = self.parent() {
311 let ac = parent.as_view().address_cells().unwrap_or(2) as usize;
312 let sc = parent.as_view().size_cells().unwrap_or(1) as usize;
313 (ac, sc)
314 } else {
315 (2, 1)
316 }
317 }
318
319 fn parent_ranges(&self) -> Option<Vec<RangesEntry>> {
321 self.parent().and_then(|p| {
322 let view = p.as_view();
323 let parent_addr_cells = p
325 .parent()
326 .and_then(|gp| gp.as_view().address_cells())
327 .unwrap_or(2);
328 view.as_node().ranges(parent_addr_cells)
329 })
330 }
331
332 pub fn set_regs(&mut self, regs: &[fdt_raw::RegInfo]) {
337 let (addr_cells, size_cells) = self.parent_cells();
339
340 let ranges = self.parent_ranges();
342
343 let mut data = Vec::new();
344
345 for reg in regs {
346 let mut bus_address = reg.address;
348 if let Some(ref ranges) = ranges {
349 for r in ranges {
350 if reg.address >= r.parent_bus_address
352 && reg.address < r.parent_bus_address + r.length
353 {
354 bus_address = reg.address - r.parent_bus_address + r.child_bus_address;
356 break;
357 }
358 }
359 }
360
361 match addr_cells {
363 1 => data.extend_from_slice(&(bus_address as u32).to_be_bytes()),
364 2 => {
365 data.extend_from_slice(&((bus_address >> 32) as u32).to_be_bytes());
366 data.extend_from_slice(&((bus_address & 0xFFFF_FFFF) as u32).to_be_bytes());
367 }
368 n => {
369 for i in 0..n {
371 let shift = (n - 1 - i) * 32;
372 data.extend_from_slice(&(((bus_address >> shift) as u32).to_be_bytes()));
373 }
374 }
375 }
376
377 let size = reg.size.unwrap_or(0);
379 match size_cells {
380 1 => data.extend_from_slice(&(size as u32).to_be_bytes()),
381 2 => {
382 data.extend_from_slice(&((size >> 32) as u32).to_be_bytes());
383 data.extend_from_slice(&((size & 0xFFFF_FFFF) as u32).to_be_bytes());
384 }
385 n => {
386 for i in 0..n {
387 let shift = (n - 1 - i) * 32;
388 data.extend_from_slice(&(((size >> shift) as u32).to_be_bytes()));
389 }
390 }
391 }
392 }
393
394 let prop = Property::new("reg", data);
395 self.as_node_mut().set_property(prop);
396 }
397
398 pub(crate) fn classify(&self) -> NodeType<'a> {
399 if let Some(node) = ClockNodeView::try_from_view(*self) {
400 return NodeType::Clock(node);
401 }
402
403 if let Some(node) = PciNodeView::try_from_view(*self) {
404 return NodeType::Pci(node);
405 }
406
407 if let Some(node) = MemoryNodeView::try_from_view(*self) {
408 return NodeType::Memory(node);
409 }
410
411 if let Some(node) = IntcNodeView::try_from_view(*self) {
412 return NodeType::InterruptController(node);
413 }
414
415 NodeType::Generic(NodeGeneric { inner: *self })
416 }
417
418 pub(crate) fn classify_mut(&mut self) -> NodeTypeMut<'a> {
419 if let Some(node) = ClockNodeViewMut::try_from_view(*self) {
420 return NodeTypeMut::Clock(node);
421 }
422
423 if let Some(node) = PciNodeViewMut::try_from_view(*self) {
424 return NodeTypeMut::Pci(node);
425 }
426
427 if let Some(node) = MemoryNodeViewMut::try_from_view(*self) {
428 return NodeTypeMut::Memory(node);
429 }
430
431 if let Some(node) = IntcNodeViewMut::try_from_view(*self) {
432 return NodeTypeMut::InterruptController(node);
433 }
434
435 NodeTypeMut::Generic(NodeGenericMut { inner: *self })
436 }
437}
438
439impl core::fmt::Display for NodeView<'_> {
440 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
441 write!(f, "{}", self.path())?;
442 for prop in self.as_node().properties() {
443 write!(f, "\n {} = ", prop.name())?;
444 if prop.name() == "compatible" {
445 write!(f, "[")?;
446 let strs: Vec<&str> = prop.as_str_iter().collect();
447 for (i, s) in strs.iter().enumerate() {
448 write!(f, "\"{}\"", s)?;
449 if i < strs.len() - 1 {
450 write!(f, ", ")?;
451 }
452 }
453 write!(f, "]")?;
454 continue;
455 }
456 if let Some(s) = prop.as_str() {
457 write!(f, "\"{}\";", s)?;
458 } else {
459 for cell in prop.get_u32_iter() {
460 write!(f, "{:#x} ", cell)?;
461 }
462 write!(f, ";")?;
463 }
464 }
465 Ok(())
466 }
467}
468
469#[enum_dispatch(ViewOp)]
474#[derive(Clone, Copy)]
475pub enum NodeType<'a> {
477 Clock(ClockNodeView<'a>),
479 Memory(MemoryNodeView<'a>),
481 InterruptController(IntcNodeView<'a>),
483 Pci(PciNodeView<'a>),
485 Generic(NodeGeneric<'a>),
487}
488
489impl<'a> NodeType<'a> {
490 pub fn as_node(&self) -> &'a Node {
492 self.as_view().as_node()
493 }
494
495 pub fn path(&self) -> String {
497 self.as_view().path()
498 }
499
500 pub fn parent(&self) -> Option<NodeType<'a>> {
501 self.as_view().parent()
502 }
503
504 pub fn id(&self) -> NodeId {
506 self.as_view().id()
507 }
508
509 pub fn name(&self) -> &'a str {
511 self.as_view().name()
512 }
513
514 pub fn regs(&self) -> Vec<RegFixed> {
516 self.as_view().regs()
517 }
518
519 pub fn interrupt_parent(&self) -> Option<Phandle> {
521 self.as_view().interrupt_parent()
522 }
523
524 pub fn interrupts(&self) -> Vec<InterruptRef> {
526 self.as_view().interrupts()
527 }
528
529 pub fn clocks(&self) -> Vec<ClockRef> {
531 self.as_view().clocks()
532 }
533}
534
535impl core::fmt::Display for NodeType<'_> {
536 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
537 self.display(f)
538 }
539}
540
541#[enum_dispatch(ViewOp)]
547pub enum NodeTypeMut<'a> {
548 Clock(ClockNodeViewMut<'a>),
549 Memory(MemoryNodeViewMut<'a>),
550 InterruptController(IntcNodeViewMut<'a>),
551 Pci(PciNodeViewMut<'a>),
552 Generic(NodeGenericMut<'a>),
553}
554
555impl<'a> NodeTypeMut<'a> {
556 pub fn id(&self) -> NodeId {
558 self.as_view().id()
559 }
560
561 pub fn set_regs(&mut self, regs: &[fdt_raw::RegInfo]) {
566 self.as_view().set_regs(regs);
567 }
568}
569
570impl Fdt {
575 fn view(&self, id: NodeId) -> Option<NodeView<'_>> {
577 if self.node(id).is_some() {
578 Some(NodeView::new(self, id))
579 } else {
580 None
581 }
582 }
583
584 pub fn view_typed(&self, id: NodeId) -> Option<NodeType<'_>> {
586 self.view(id).map(|v| v.classify())
587 }
588
589 pub fn view_typed_mut(&mut self, id: NodeId) -> Option<NodeTypeMut<'_>> {
591 self.view(id).map(|mut v| v.classify_mut())
592 }
593}
594
595impl<'a> NodeGenericMut<'a> {
596 pub fn add_child_memory(&mut self, name: &str) -> MemoryNodeViewMut<'a> {
597 self.add_child(name)
598 }
599
600 pub fn add_child_interrupt_controller(&mut self, name: &str) -> IntcNodeViewMut<'a> {
601 self.add_child(name)
602 }
603}
604
605#[derive(Clone, Copy, Debug)]
606pub struct RegFixed {
607 pub address: u64,
608 pub child_bus_address: u64,
609 pub size: Option<u64>,
610}