]> git.sur5r.net Git - u-boot/blob - tools/dtoc/fdt_fallback.py
84a3db1e78fbf3ca04724a7531c0afb655a79360
[u-boot] / tools / dtoc / fdt_fallback.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2016 Google, Inc
4 # Written by Simon Glass <sjg@chromium.org>
5 #
6 # SPDX-License-Identifier:      GPL-2.0+
7 #
8
9 import command
10 import fdt
11 from fdt import Fdt, NodeBase, PropBase
12 import fdt_util
13 import sys
14
15 # This deals with a device tree, presenting it as a list of Node and Prop
16 # objects, representing nodes and properties, respectively.
17 #
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.
21
22 class Prop(PropBase):
23     """A device tree property
24
25     Properties:
26         name: Property name (as per the device tree)
27         value: Property value as a string of bytes, or a list of strings of
28             bytes
29         type: Value type
30     """
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
35             return
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))
39
40
41 class Node(NodeBase):
42     """A device tree node
43
44     Properties:
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
51     """
52     def __init__(self, fdt, offset, name, path):
53         NodeBase.__init__(self, fdt, offset, name, path)
54
55     def Scan(self):
56         """Scan a node's properties and subnodes
57
58         This fills in the props and subnodes properties, recursively
59         searching into subnodes so that the entire tree is built.
60         """
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
64
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)
70
71             node.Scan()
72
73
74 class FdtFallback(Fdt):
75     """Provides simple access to a flat device tree blob using fdtget/fdtput
76
77     Properties:
78         See superclass
79     """
80
81     def __init__(self, fname):
82         Fdt.__init__(self, fname)
83
84     def Scan(self):
85         """Scan a device tree, building up a tree of Node objects
86
87         This fills in the self._root property
88         """
89         self._root = Node(self, 0, '/', '/')
90         self._root.Scan()
91
92     def GetRoot(self):
93         """Get the root Node of the device tree
94
95         Returns:
96             The root Node object
97         """
98         return self._root
99
100     def GetSubNodes(self, node):
101         """Returns a list of sub-nodes of a given node
102
103         Args:
104             node: Node name to return children from
105
106         Returns:
107             List of children in the node (each a string node name)
108
109         Raises:
110             CmdError: if the node does not exist.
111         """
112         out = command.Output('fdtget', self._fname, '-l', node)
113         return out.strip().splitlines()
114
115     def GetProps(self, node, convert_dashes=False):
116         """Get all properties from a node
117
118         Args:
119             node: full path to node name to look in
120             convert_dashes: True to convert - to _ in node names
121
122         Returns:
123             A dictionary containing all the properties, indexed by node name.
124             The entries are simply strings - no decoding of lists or numbers
125             is done.
126
127         Raises:
128             CmdError: if the node does not exist.
129         """
130         out = command.Output('fdtget', self._fname, node, '-p')
131         props = out.strip().splitlines()
132         props_dict = {}
133         for prop in props:
134             name = prop
135             if convert_dashes:
136                 prop = re.sub('-', '_', prop)
137             props_dict[prop] = self.GetProp(node, name)
138         return props_dict
139
140     def GetProp(self, node, prop, default=None, typespec=None):
141         """Get a property from a device tree.
142
143         This looks up the given node and property, and returns the value as a
144         string,
145
146         If the node or property does not exist, this will return the default
147         value.
148
149         Args:
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
154                 string.
155             typespec: Type character to use (None for default, 's' for string)
156
157         Returns:
158             string containing the property value.
159
160         Raises:
161             CmdError: if the property does not exist and no default is provided.
162         """
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)
169         return out.strip()
170
171     @classmethod
172     def Node(self, fdt, offset, name, path):
173         """Create a new node
174
175         This is used by Fdt.Scan() to create a new node using the correct
176         class.
177
178         Args:
179             fdt: Fdt object
180             offset: Offset of node
181             name: Node name
182             path: Full path to node
183         """
184         node = Node(fdt, offset, name, path)
185         return node