3 # Copyright (C) 2016 Google, Inc
4 # Written by Simon Glass <sjg@chromium.org>
6 # SPDX-License-Identifier: GPL-2.0+
11 from fdt import Fdt, NodeBase, PropBase
15 # This deals with a device tree, presenting it as a list of Node and Prop
16 # objects, representing nodes and properties, respectively.
18 # This implementation uses the fdtget tool to access the device tree, so it
19 # is not very efficient for larger trees. The tool is called once for each
20 # node and property in the tree.
23 """A device tree property
26 name: Property name (as per the device tree)
27 value: Property value as a string of bytes, or a list of strings of
31 def __init__(self, node, name, byte_list_str):
32 PropBase.__init__(self, node, 0, name)
33 if not byte_list_str.strip():
34 self.type = fdt.TYPE_BOOL
36 self.bytes = [chr(int(byte, 16))
37 for byte in byte_list_str.strip().split(' ')]
38 self.type, self.value = self.BytesToValue(''.join(self.bytes))
45 name: Device tree node tname
46 path: Full path to node, along with the node name itself
47 _fdt: Device tree object
48 subnodes: A list of subnodes for this node, each a Node object
49 props: A dict of properties for this node, each a Prop object.
50 Keyed by property name
52 def __init__(self, fdt, offset, name, path):
53 NodeBase.__init__(self, fdt, offset, name, path)
56 """Scan a node's properties and subnodes
58 This fills in the props and subnodes properties, recursively
59 searching into subnodes so that the entire tree is built.
61 for name, byte_list_str in self._fdt.GetProps(self.path).iteritems():
62 prop = Prop(self, name, byte_list_str)
63 self.props[name] = prop
65 for name in self._fdt.GetSubNodes(self.path):
66 sep = '' if self.path[-1] == '/' else '/'
67 path = self.path + sep + name
68 node = Node(self._fdt, 0, name, path)
69 self.subnodes.append(node)
74 class FdtFallback(Fdt):
75 """Provides simple access to a flat device tree blob using fdtget/fdtput
81 def __init__(self, fname):
82 Fdt.__init__(self, fname)
85 """Scan a device tree, building up a tree of Node objects
87 This fills in the self._root property
89 self._root = Node(self, 0, '/', '/')
93 """Get the root Node of the device tree
100 def GetSubNodes(self, node):
101 """Returns a list of sub-nodes of a given node
104 node: Node name to return children from
107 List of children in the node (each a string node name)
110 CmdError: if the node does not exist.
112 out = command.Output('fdtget', self._fname, '-l', node)
113 return out.strip().splitlines()
115 def GetProps(self, node, convert_dashes=False):
116 """Get all properties from a node
119 node: full path to node name to look in
120 convert_dashes: True to convert - to _ in node names
123 A dictionary containing all the properties, indexed by node name.
124 The entries are simply strings - no decoding of lists or numbers
128 CmdError: if the node does not exist.
130 out = command.Output('fdtget', self._fname, node, '-p')
131 props = out.strip().splitlines()
136 prop = re.sub('-', '_', prop)
137 props_dict[prop] = self.GetProp(node, name)
140 def GetProp(self, node, prop, default=None, typespec=None):
141 """Get a property from a device tree.
143 This looks up the given node and property, and returns the value as a
146 If the node or property does not exist, this will return the default
150 node: Full path to node to look up.
151 prop: Property name to look up.
152 default: Default value to return if nothing is present in the fdt,
153 or None to raise in this case. This will be converted to a
155 typespec: Type character to use (None for default, 's' for string)
158 string containing the property value.
161 CmdError: if the property does not exist and no default is provided.
163 args = [self._fname, node, prop, '-t', 'bx']
164 if default is not None:
165 args += ['-d', str(default)]
166 if typespec is not None:
167 args += ['-t%s' % typespec]
168 out = command.Output('fdtget', *args)
172 def Node(self, fdt, offset, name, path):
175 This is used by Fdt.Scan() to create a new node using the correct
180 offset: Offset of node
182 path: Full path to node
184 node = Node(fdt, offset, name, path)