fdt_raw/
fdt.rs

1use core::fmt;
2
3use crate::{
4    Chosen, FdtError, Memory, MemoryReservation, Node, data::Bytes, header::Header, iter::FdtIter,
5};
6
7/// Memory reservation block iterator
8pub struct MemoryReservationIter<'a> {
9    data: &'a [u8],
10    offset: usize,
11}
12
13impl<'a> Iterator for MemoryReservationIter<'a> {
14    type Item = MemoryReservation;
15
16    fn next(&mut self) -> Option<Self::Item> {
17        // 确保我们有足够的数据来读取地址和大小(各8字节)
18        if self.offset + 16 > self.data.len() {
19            return None;
20        }
21
22        // 读取地址(8字节,大端序)
23        let address_bytes = &self.data[self.offset..self.offset + 8];
24        let address = u64::from_be_bytes(address_bytes.try_into().unwrap());
25        self.offset += 8;
26
27        // 读取大小(8字节,大端序)
28        let size_bytes = &self.data[self.offset..self.offset + 8];
29        let size = u64::from_be_bytes(size_bytes.try_into().unwrap());
30        self.offset += 8;
31
32        // 检查是否到达终止符(地址和大小都为0)
33        if address == 0 && size == 0 {
34            return None;
35        }
36
37        Some(MemoryReservation { address, size })
38    }
39}
40
41/// 写入缩进(使用空格)
42fn write_indent(f: &mut fmt::Formatter<'_>, count: usize, ch: &str) -> fmt::Result {
43    for _ in 0..count {
44        write!(f, "{}", ch)?;
45    }
46    Ok(())
47}
48
49#[derive(Clone)]
50pub struct Fdt<'a> {
51    header: Header,
52    pub(crate) data: Bytes<'a>,
53}
54
55impl<'a> Fdt<'a> {
56    /// Create a new `Fdt` from byte slice.
57    pub fn from_bytes(data: &'a [u8]) -> Result<Fdt<'a>, FdtError> {
58        let header = Header::from_bytes(data)?;
59        if data.len() < header.totalsize as usize {
60            return Err(FdtError::BufferTooSmall {
61                pos: header.totalsize as usize,
62            });
63        }
64        let buffer = Bytes::new(data);
65
66        Ok(Fdt {
67            header,
68            data: buffer,
69        })
70    }
71
72    /// Create a new `Fdt` from a raw pointer and size in bytes.
73    ///
74    /// # Safety
75    ///
76    /// The caller must ensure that the pointer is valid and points to a
77    /// memory region of at least `size` bytes that contains a valid device tree
78    /// blob.
79    pub unsafe fn from_ptr(ptr: *mut u8) -> Result<Fdt<'a>, FdtError> {
80        let header = unsafe { Header::from_ptr(ptr)? };
81
82        let data_slice = unsafe { core::slice::from_raw_parts(ptr, header.totalsize as _) };
83        let data = Bytes::new(data_slice);
84
85        Ok(Fdt { header, data })
86    }
87
88    pub fn header(&self) -> &Header {
89        &self.header
90    }
91
92    pub fn as_slice(&self) -> &'a [u8] {
93        self.data.as_slice()
94    }
95
96    pub fn all_nodes(&self) -> FdtIter<'a> {
97        FdtIter::new(self.clone())
98    }
99
100    pub fn find_by_path(&self, path: &str) -> Option<Node<'a>> {
101        let path = self.normalize_path(path)?;
102        let split = path.trim_matches('/').split('/');
103
104        let mut current_iter = self.all_nodes();
105        let mut found_node: Option<Node<'a>> = None;
106
107        for part in split {
108            let mut found = false;
109            for node in current_iter.by_ref() {
110                let node_name = node.name();
111                if node_name == part {
112                    found = true;
113                    found_node = Some(node);
114                    break;
115                }
116            }
117            if !found {
118                return None;
119            }
120        }
121
122        found_node
123    }
124
125    fn resolve_alias(&self, alias: &str) -> Option<&'a str> {
126        let aliases_node = self.find_by_path("/aliases")?;
127        aliases_node.find_property_str(alias)
128    }
129
130    fn normalize_path(&self, path: &'a str) -> Option<&'a str> {
131        if path.starts_with('/') {
132            Some(path)
133        } else {
134            self.resolve_alias(path)
135        }
136    }
137
138    /// Translate device address to CPU physical address.
139    ///
140    /// This function implements address translation similar to Linux's of_translate_address.
141    /// It walks up the device tree hierarchy, applying each parent's ranges property to
142    /// translate the child address space to parent address space, ultimately obtaining
143    /// the CPU physical address.
144    ///
145    /// # Arguments
146    /// * `path` - Node path (absolute path starting with '/' or alias name)
147    /// * `address` - Device address from the node's reg property
148    ///
149    /// # Returns
150    /// The translated CPU physical address. If translation fails, returns the original address.
151    pub fn translate_address(&self, path: &'a str, address: u64) -> u64 {
152        let path = match self.normalize_path(path) {
153            Some(p) => p,
154            None => return address,
155        };
156
157        // 分割路径为各级节点名称
158        let path_parts: heapless::Vec<&str, 16> = path
159            .trim_matches('/')
160            .split('/')
161            .filter(|s| !s.is_empty())
162            .collect();
163
164        if path_parts.is_empty() {
165            return address;
166        }
167
168        let mut current_address = address;
169
170        // 从最深层的节点向上遍历,对每一层应用 ranges 转换
171        // 注意:我们需要从倒数第二层开始(因为最后一层是目标节点本身)
172        for depth in (0..path_parts.len()).rev() {
173            // 构建到当前层的路径
174            let parent_parts = &path_parts[..depth];
175            if parent_parts.is_empty() {
176                // 已经到达根节点,不需要继续转换
177                break;
178            }
179
180            // 查找父节点
181            let mut parent_path = heapless::String::<256>::new();
182            parent_path.push('/').ok();
183            for (i, part) in parent_parts.iter().enumerate() {
184                if i > 0 {
185                    parent_path.push('/').ok();
186                }
187                parent_path.push_str(part).ok();
188            }
189
190            let parent_node = match self.find_by_path(parent_path.as_str()) {
191                Some(node) => node,
192                None => continue,
193            };
194
195            // 获取父节点的 ranges 属性
196            let ranges = match parent_node.ranges() {
197                Some(r) => r,
198                None => {
199                    // 没有 ranges 属性,停止转换
200                    break;
201                }
202            };
203
204            // 在 ranges 中查找匹配的转换规则
205            let mut found = false;
206            for range in ranges.iter() {
207                // 检查地址是否在当前 range 的范围内
208                if current_address >= range.child_address
209                    && current_address < range.child_address + range.length
210                {
211                    // 计算在 child address space 中的偏移
212                    let offset = current_address - range.child_address;
213                    // 转换到 parent address space
214                    current_address = range.parent_address + offset;
215                    found = true;
216                    break;
217                }
218            }
219
220            if !found {
221                // 如果在 ranges 中没有找到匹配项,保持当前地址不变
222                // 这通常意味着地址转换失败,但我们继续尝试上层
223            }
224        }
225
226        current_address
227    }
228
229    /// Get an iterator over memory reservation entries
230    pub fn memory_reservations(&self) -> MemoryReservationIter<'a> {
231        MemoryReservationIter {
232            data: self.data.as_slice(),
233            offset: self.header.off_mem_rsvmap as usize,
234        }
235    }
236
237    pub fn chosen(&self) -> Option<Chosen<'a>> {
238        for node in self.all_nodes() {
239            if let Node::Chosen(c) = node {
240                return Some(c);
241            }
242        }
243        None
244    }
245
246    pub fn memory(&self) -> Option<Memory<'a>> {
247        for node in self.all_nodes() {
248            if let Node::Memory(m) = node {
249                return Some(m);
250            }
251        }
252        None
253    }
254}
255
256impl fmt::Display for Fdt<'_> {
257    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258        writeln!(f, "/dts-v1/;")?;
259        writeln!(f)?;
260
261        let mut prev_level = 0;
262
263        for node in self.all_nodes() {
264            let level = node.level();
265
266            // 关闭前一层级的节点
267            while prev_level > level {
268                prev_level -= 1;
269                write_indent(f, prev_level, "    ")?;
270                writeln!(f, "}};\n")?;
271            }
272
273            write_indent(f, level, "    ")?;
274            let name = if node.name().is_empty() {
275                "/"
276            } else {
277                node.name()
278            };
279
280            // 打印节点头部
281            writeln!(f, "{} {{", name)?;
282
283            // 打印属性
284            for prop in node.properties() {
285                write_indent(f, level + 1, "    ")?;
286                writeln!(f, "{};", prop)?;
287            }
288
289            prev_level = level + 1;
290        }
291
292        // 关闭剩余的节点
293        while prev_level > 0 {
294            prev_level -= 1;
295            write_indent(f, prev_level, "    ")?;
296            writeln!(f, "}};\n")?;
297        }
298
299        Ok(())
300    }
301}
302
303impl fmt::Debug for Fdt<'_> {
304    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305        writeln!(f, "Fdt {{")?;
306        writeln!(f, "\theader: {:?}", self.header)?;
307        writeln!(f, "\tnodes:")?;
308
309        for node in self.all_nodes() {
310            let level = node.level();
311            // 基础缩进 2 个 tab,每层再加 1 个 tab
312            write_indent(f, level + 2, "\t")?;
313
314            let name = if node.name().is_empty() {
315                "/"
316            } else {
317                node.name()
318            };
319
320            // 打印节点名称和基本信息
321            writeln!(
322                f,
323                "[{}] address_cells={}, size_cells={}",
324                name, node.address_cells, node.size_cells
325            )?;
326
327            // 打印属性
328            for prop in node.properties() {
329                write_indent(f, level + 3, "\t")?;
330                if let Some(v) = prop.as_address_cells() {
331                    writeln!(f, "#address-cells: {}", v)?;
332                } else if let Some(v) = prop.as_size_cells() {
333                    writeln!(f, "#size-cells: {}", v)?;
334                } else if let Some(v) = prop.as_interrupt_cells() {
335                    writeln!(f, "#interrupt-cells: {}", v)?;
336                } else if let Some(s) = prop.as_status() {
337                    writeln!(f, "status: {:?}", s)?;
338                } else if let Some(p) = prop.as_phandle() {
339                    writeln!(f, "phandle: {}", p)?;
340                } else {
341                    // 默认处理未知属性
342                    if prop.is_empty() {
343                        writeln!(f, "{}", prop.name())?;
344                    } else if let Some(s) = prop.as_str() {
345                        writeln!(f, "{}: \"{}\"", prop.name(), s)?;
346                    } else if prop.len() == 4 {
347                        let v = u32::from_be_bytes(prop.data().as_slice().try_into().unwrap());
348                        writeln!(f, "{}: {:#x}", prop.name(), v)?;
349                    } else {
350                        writeln!(f, "{}: <{} bytes>", prop.name(), prop.len())?;
351                    }
352                }
353            }
354        }
355
356        writeln!(f, "}}")
357    }
358}
359
360#[cfg(test)]
361mod tests {
362    use super::*;
363    use heapless::Vec;
364
365    #[test]
366    fn test_memory_reservation_iterator() {
367        // 创建一个简单的测试数据:一个内存保留条目 + 终止符
368        let mut test_data = [0u8; 32];
369
370        // 地址: 0x80000000, 大小: 0x10000000 (256MB)
371        test_data[0..8].copy_from_slice(&0x80000000u64.to_be_bytes());
372        test_data[8..16].copy_from_slice(&0x10000000u64.to_be_bytes());
373        // 终止符: address=0, size=0
374        test_data[16..24].copy_from_slice(&0u64.to_be_bytes());
375        test_data[24..32].copy_from_slice(&0u64.to_be_bytes());
376
377        let iter = MemoryReservationIter {
378            data: &test_data,
379            offset: 0,
380        };
381
382        let reservations: Vec<MemoryReservation, 4> = iter.collect();
383        assert_eq!(reservations.len(), 1);
384        assert_eq!(reservations[0].address, 0x80000000);
385        assert_eq!(reservations[0].size, 0x10000000);
386    }
387
388    #[test]
389    fn test_empty_memory_reservation_iterator() {
390        // 只有终止符
391        let mut test_data = [0u8; 16];
392        test_data[0..8].copy_from_slice(&0u64.to_be_bytes());
393        test_data[8..16].copy_from_slice(&0u64.to_be_bytes());
394
395        let iter = MemoryReservationIter {
396            data: &test_data,
397            offset: 0,
398        };
399
400        let reservations: Vec<MemoryReservation, 4> = iter.collect();
401        assert_eq!(reservations.len(), 0);
402    }
403}