fdt_parser/
chosen.rs

1use crate::node::Node;
2
3pub struct Chosen<'a> {
4    node: Node<'a>,
5}
6
7impl<'a> Chosen<'a> {
8    pub fn new(node: Node<'a>) -> Self {
9        Chosen { node }
10    }
11
12    /// Contains the bootargs, if they exist
13    pub fn bootargs(&self) -> Option<&'a str> {
14        self.node.find_property("bootargs").map(|p| p.str())
15    }
16
17    /// Searches for the node representing `stdout`, if the property exists,
18    /// attempting to resolve aliases if the node name doesn't exist as-is
19    pub fn stdout(&self) -> Option<Stdout<'a>> {
20        let path = self.node.find_property("stdout-path")?.str();
21        let mut sp = path.split(':');
22        let name = sp.next()?;
23        let params = sp.next();
24        let node = self.node.fdt.find_nodes(name).next()?;
25        Some(Stdout { params, node })
26    }
27
28    pub fn debugcon(&self) -> Option<Node<'a>> {
29        if let Some(node) = self.stdout() {
30            Some(node.node)
31        } else {
32            fdt_bootargs_find_debugcon_node(self)
33        }
34    }
35}
36
37pub struct Stdout<'a> {
38    pub params: Option<&'a str>,
39    pub node: Node<'a>,
40}
41
42fn fdt_bootargs_find_debugcon_node<'a>(chosen: &Chosen<'a>) -> Option<Node<'a>> {
43    let bootargs = chosen.bootargs()?;
44
45    let earlycon = bootargs
46        .split_ascii_whitespace()
47        .find(|&arg| arg.contains("earlycon"))?;
48
49    let mut tmp = earlycon.split('=');
50    let _ = tmp.next()?;
51    let values = tmp.next()?;
52
53    let mut values = values.split(',');
54
55    let name = values.next()?;
56
57    if !name.contains("uart") {
58        return None;
59    }
60
61    let param2 = values.next()?;
62    let addr_str = if param2.contains("0x") {
63        param2
64    } else {
65        values.next()?
66    };
67
68    let mmio = u64::from_str_radix(addr_str.trim_start_matches("0x"), 16).ok()?;
69
70    for node in chosen.node.fdt.all_nodes() {
71        if let Some(regs) = node.reg() {
72            for reg in regs {
73                if reg.address.eq(&mmio) {
74                    return Some(node);
75                }
76            }
77        }
78    }
79
80    None
81}