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#[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 pub fn name(&self) -> &str {
26 &self.name
27 }
28
29 pub fn regions(&self) -> Vec<MemoryRegion> {
32 Vec::new()
34 }
35
36 pub fn device_type(&self) -> Option<&str> {
39 Some("memory")
40 }
41}
42
43#[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 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 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 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
92fn is_memory_node(node: &NodeRefGen) -> bool {
94 if let Some(device_type) = node.device_type()
96 && device_type == "memory"
97 {
98 return true;
99 }
100
101 node.name().starts_with("memory")
103}