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 pub fn bootargs(&self) -> Option<&'a str> {
14 self.node.find_property("bootargs").map(|p| p.str())
15 }
16
17 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}