]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - tools/dtoc/fdt_normal.py
dtoc: Move a few more common functions into fdt.py
[karo-tx-uboot.git] / tools / dtoc / fdt_normal.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 struct
10 import sys
11
12 import fdt
13 from fdt import Fdt, NodeBase, PropBase
14 import fdt_util
15 import libfdt
16
17 # This deals with a device tree, presenting it as a list of Node and Prop
18 # objects, representing nodes and properties, respectively.
19 #
20 # This implementation uses a libfdt Python library to access the device tree,
21 # so it is fairly efficient.
22
23 class Prop(PropBase):
24     """A device tree property
25
26     Properties:
27         name: Property name (as per the device tree)
28         value: Property value as a string of bytes, or a list of strings of
29             bytes
30         type: Value type
31     """
32     def __init__(self, node, offset, name, bytes):
33         PropBase.__init__(self, node, offset, name)
34         self.bytes = bytes
35         if not bytes:
36             self.type = fdt.TYPE_BOOL
37             self.value = True
38             return
39         self.type, self.value = self.BytesToValue(bytes)
40
41 class Node(NodeBase):
42     """A device tree node
43
44     Properties:
45         offset: Integer offset in the device tree
46         name: Device tree node tname
47         path: Full path to node, along with the node name itself
48         _fdt: Device tree object
49         subnodes: A list of subnodes for this node, each a Node object
50         props: A dict of properties for this node, each a Prop object.
51             Keyed by property name
52     """
53     def __init__(self, fdt, offset, name, path):
54         NodeBase.__init__(self, fdt, offset, name, path)
55
56     def Scan(self):
57         """Scan a node's properties and subnodes
58
59         This fills in the props and subnodes properties, recursively
60         searching into subnodes so that the entire tree is built.
61         """
62         self.props = self._fdt.GetProps(self.path)
63
64         offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self._offset)
65         while offset >= 0:
66             sep = '' if self.path[-1] == '/' else '/'
67             name = libfdt.Name(self._fdt.GetFdt(), offset)
68             path = self.path + sep + name
69             node = Node(self._fdt, offset, name, path)
70             self.subnodes.append(node)
71
72             node.Scan()
73             offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
74
75
76 class FdtNormal(Fdt):
77     """Provides simple access to a flat device tree blob using libfdt.
78
79     Properties:
80         _fdt: Device tree contents (bytearray)
81         _cached_offsets: True if all the nodes have a valid _offset property,
82             False if something has changed to invalidate the offsets
83     """
84     def __init__(self, fname):
85         Fdt.__init__(self, fname)
86         with open(self._fname) as fd:
87             self._fdt = fd.read()
88
89     def GetFdt(self):
90         """Get the contents of the FDT
91
92         Returns:
93             The FDT contents as a string of bytes
94         """
95         return self._fdt
96
97     def GetProps(self, node):
98         """Get all properties from a node.
99
100         Args:
101             node: Full path to node name to look in.
102
103         Returns:
104             A dictionary containing all the properties, indexed by node name.
105             The entries are Prop objects.
106
107         Raises:
108             ValueError: if the node does not exist.
109         """
110         offset = libfdt.fdt_path_offset(self._fdt, node)
111         if offset < 0:
112             libfdt.Raise(offset)
113         props_dict = {}
114         poffset = libfdt.fdt_first_property_offset(self._fdt, offset)
115         while poffset >= 0:
116             dprop, plen = libfdt.fdt_get_property_by_offset(self._fdt, poffset)
117             prop = Prop(node, poffset, libfdt.String(self._fdt, dprop.nameoff),
118                         libfdt.Data(dprop))
119             props_dict[prop.name] = prop
120
121             poffset = libfdt.fdt_next_property_offset(self._fdt, poffset)
122         return props_dict
123
124     @classmethod
125     def Node(self, fdt, offset, name, path):
126         """Create a new node
127
128         This is used by Fdt.Scan() to create a new node using the correct
129         class.
130
131         Args:
132             fdt: Fdt object
133             offset: Offset of node
134             name: Node name
135             path: Full path to node
136         """
137         node = Node(fdt, offset, name, path)
138         return node