Skip to main content

fdt_raw/node/
memory.rs

1//! Memory node type for physical memory layout.
2//!
3//! This module provides the `Memory` type which represents memory nodes
4//! in the device tree, describing the physical memory layout of the system.
5
6use core::ops::Deref;
7
8use super::NodeBase;
9
10/// Memory region information.
11///
12/// Represents a contiguous region of physical memory with its base address
13/// and size.
14#[derive(Debug, Clone, Copy)]
15pub struct MemoryRegion {
16    /// Base address of the memory region
17    pub address: u64,
18    /// Size of the memory region in bytes
19    pub size: u64,
20}
21
22/// Memory node describing physical memory layout.
23///
24/// This node type represents memory nodes in the device tree, which describe
25/// the physical memory layout available to the system. The `reg` property
26/// contains one or more memory regions.
27#[derive(Clone)]
28pub struct Memory<'a> {
29    node: NodeBase<'a>,
30}
31
32impl<'a> Memory<'a> {
33    /// Creates a new Memory wrapper from a NodeBase.
34    pub(crate) fn new(node: NodeBase<'a>) -> Self {
35        Self { node }
36    }
37
38    /// Returns an iterator over memory regions.
39    ///
40    /// The `reg` property of a memory node describes the physical memory
41    /// layout, with each entry specifying a base address and size.
42    pub fn regions(&self) -> impl Iterator<Item = MemoryRegion> + 'a {
43        self.node.reg().into_iter().flat_map(|reg| {
44            reg.map(|info| MemoryRegion {
45                address: info.address,
46                size: info.size.unwrap_or(0),
47            })
48        })
49    }
50
51    /// Returns all memory regions as a fixed-size array.
52    ///
53    /// This is useful for no_std environments where heap allocation is not
54    /// available. Returns a `heapless::Vec` with at most N entries.
55    pub fn regions_array<const N: usize>(&self) -> heapless::Vec<MemoryRegion, N> {
56        let mut result = heapless::Vec::new();
57        for region in self.regions() {
58            if result.push(region).is_err() {
59                break;
60            }
61        }
62        result
63    }
64
65    /// Returns the total memory size across all regions.
66    pub fn total_size(&self) -> u64 {
67        self.regions().map(|r| r.size).sum()
68    }
69}
70
71impl<'a> Deref for Memory<'a> {
72    type Target = NodeBase<'a>;
73
74    fn deref(&self) -> &Self::Target {
75        &self.node
76    }
77}
78
79impl core::fmt::Debug for Memory<'_> {
80    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81        let mut st = f.debug_struct("Memory");
82        st.field("name", &self.node.name());
83        for region in self.regions() {
84            st.field("region", &region);
85        }
86        st.finish()
87    }
88}