Skip to main content

fdt_edit/node/view/
memory.rs

1//! Memory node view specialization.
2
3use core::ops::Deref;
4
5use alloc::vec::Vec;
6use fdt_raw::MemoryRegion;
7
8use super::NodeView;
9use crate::{NodeGeneric, NodeGenericMut, Property, ViewMutOp, ViewOp};
10
11// ---------------------------------------------------------------------------
12// MemoryNodeView
13// ---------------------------------------------------------------------------
14
15/// Specialized view for memory nodes.
16///
17/// Provides methods for parsing `reg` into memory regions.
18#[derive(Clone, Copy)]
19pub struct MemoryNodeView<'a> {
20    pub(super) inner: NodeGeneric<'a>,
21}
22
23impl<'a> Deref for MemoryNodeView<'a> {
24    type Target = NodeGeneric<'a>;
25    fn deref(&self) -> &Self::Target {
26        &self.inner
27    }
28}
29
30// Implement ViewOp for all specialized view types that have `inner: NodeView<'a>`
31impl<'a> ViewOp<'a> for MemoryNodeView<'a> {
32    fn as_view(&self) -> NodeView<'a> {
33        self.inner.as_view()
34    }
35}
36
37impl<'a> MemoryNodeView<'a> {
38    pub(crate) fn try_from_view(view: NodeView<'a>) -> Option<Self> {
39        if view.as_node().is_memory() {
40            Some(Self {
41                inner: NodeGeneric { inner: view },
42            })
43        } else {
44            None
45        }
46    }
47
48    /// Iterates over memory regions parsed from the `reg` property.
49    ///
50    /// Uses the parent node's `ranges` for address translation, converting
51    /// bus addresses to CPU physical addresses.
52    pub fn regions(&self) -> Vec<MemoryRegion> {
53        // Use NodeView::regs() to get address-translated regions
54        let regs = self.as_view().regs();
55        regs.into_iter()
56            .map(|r| MemoryRegion {
57                address: r.address, // Use the CPU-translated address
58                size: r.size.unwrap_or(0),
59            })
60            .collect()
61    }
62
63    /// Total size across all memory regions.
64    pub fn total_size(&self) -> u64 {
65        self.regions().iter().map(|r| r.size).sum()
66    }
67}
68
69// ---------------------------------------------------------------------------
70// MemoryNodeViewMut
71// ---------------------------------------------------------------------------
72
73/// Mutable view for memory nodes.
74pub struct MemoryNodeViewMut<'a> {
75    pub(super) inner: NodeGenericMut<'a>,
76}
77
78impl<'a> Deref for MemoryNodeViewMut<'a> {
79    type Target = NodeGenericMut<'a>;
80    fn deref(&self) -> &Self::Target {
81        &self.inner
82    }
83}
84
85impl<'a> ViewOp<'a> for MemoryNodeViewMut<'a> {
86    fn as_view(&self) -> NodeView<'a> {
87        self.inner.as_view()
88    }
89}
90
91impl<'a> ViewMutOp<'a> for MemoryNodeViewMut<'a> {
92    fn new(node: NodeGenericMut<'a>) -> Self {
93        let mut s = Self { inner: node };
94        let n = s.inner.inner.as_node_mut();
95        n.set_property(Property::new("device_type", b"memory\0".to_vec()));
96        s
97    }
98}
99
100impl<'a> MemoryNodeViewMut<'a> {
101    pub(crate) fn try_from_view(view: NodeView<'a>) -> Option<Self> {
102        if view.as_node().is_memory() {
103            Some(Self {
104                inner: NodeGenericMut { inner: view },
105            })
106        } else {
107            None
108        }
109    }
110}