fdt_edit/node/
memory.rs

1use core::ops::Deref;
2
3use alloc::{
4    string::{String, ToString},
5    vec::Vec,
6};
7use fdt_raw::MemoryRegion;
8
9use crate::node::gerneric::NodeRefGen;
10
11/// Memory 节点,描述物理内存布局
12#[derive(Clone, Debug)]
13pub struct NodeMemory {
14    pub name: String,
15}
16
17impl NodeMemory {
18    pub fn new(name: &str) -> Self {
19        Self {
20            name: name.to_string(),
21        }
22    }
23
24    /// 获取节点名称
25    pub fn name(&self) -> &str {
26        &self.name
27    }
28
29    /// 获取内存区域列表
30    /// 注意:这是一个简单的实现,实际使用时需要从实际的 FDT 节点中解析
31    pub fn regions(&self) -> Vec<MemoryRegion> {
32        // 这个方法在测试中主要用来检查是否为空
33        Vec::new()
34    }
35
36    /// 获取 device_type 属性
37    /// 注意:这是一个简单的实现,返回 "memory"
38    pub fn device_type(&self) -> Option<&str> {
39        Some("memory")
40    }
41}
42
43/// Memory 节点引用
44#[derive(Clone)]
45pub struct NodeRefMemory<'a> {
46    pub node: NodeRefGen<'a>,
47}
48
49impl<'a> NodeRefMemory<'a> {
50    pub fn try_from(node: NodeRefGen<'a>) -> Result<Self, NodeRefGen<'a>> {
51        if !is_memory_node(&node) {
52            return Err(node);
53        }
54        Ok(Self { node })
55    }
56
57    /// 获取内存区域列表
58    pub fn regions(&self) -> Vec<MemoryRegion> {
59        let mut regions = Vec::new();
60        if let Some(reg_prop) = self.find_property("reg") {
61            let mut reader = reg_prop.as_reader();
62
63            // 获取 parent 的 address-cells 和 size-cells
64            let address_cells = self.ctx.parent_address_cells() as usize;
65            let size_cells = self.ctx.parent_size_cells() as usize;
66
67            while let (Some(address), Some(size)) = (
68                reader.read_cells(address_cells),
69                reader.read_cells(size_cells),
70            ) {
71                regions.push(MemoryRegion { address, size });
72            }
73        }
74        regions
75    }
76
77    /// 获取 device_type 属性
78    pub fn device_type(&self) -> Option<&str> {
79        self.find_property("device_type")
80            .and_then(|prop| prop.as_str())
81    }
82}
83
84impl<'a> Deref for NodeRefMemory<'a> {
85    type Target = NodeRefGen<'a>;
86
87    fn deref(&self) -> &Self::Target {
88        &self.node
89    }
90}
91
92/// 检查节点是否是 memory 节点
93fn is_memory_node(node: &NodeRefGen) -> bool {
94    // 检查 device_type 属性是否为 "memory"
95    if let Some(device_type) = node.device_type()
96        && device_type == "memory"
97    {
98        return true;
99    }
100
101    // 或者节点名以 "memory" 开头
102    node.name().starts_with("memory")
103}