]> git.sur5r.net Git - u-boot/blob - tools/dtoc/fdt.py
dtoc: Move BytesToValue() and GetEmpty() into PropBase
[u-boot] / tools / dtoc / fdt.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_util
13
14 # This deals with a device tree, presenting it as an assortment of Node and
15 # Prop objects, representing nodes and properties, respectively. This file
16 # contains the base classes and defines the high-level API. Most of the
17 # implementation is in the FdtFallback and FdtNormal subclasses. See
18 # fdt_select.py for how to create an Fdt object.
19
20 # A list of types we support
21 (TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4)
22
23 def CheckErr(errnum, msg):
24     if errnum:
25         raise ValueError('Error %d: %s: %s' %
26             (errnum, libfdt.fdt_strerror(errnum), msg))
27
28 class PropBase:
29     """A device tree property
30
31     Properties:
32         name: Property name (as per the device tree)
33         value: Property value as a string of bytes, or a list of strings of
34             bytes
35         type: Value type
36     """
37     def __init__(self, node, offset, name):
38         self._node = node
39         self._offset = offset
40         self.name = name
41         self.value = None
42
43     def BytesToValue(self, bytes):
44         """Converts a string of bytes into a type and value
45
46         Args:
47             A string containing bytes
48
49         Return:
50             A tuple:
51                 Type of data
52                 Data, either a single element or a list of elements. Each element
53                 is one of:
54                     TYPE_STRING: string value from the property
55                     TYPE_INT: a byte-swapped integer stored as a 4-byte string
56                     TYPE_BYTE: a byte stored as a single-byte string
57         """
58         size = len(bytes)
59         strings = bytes.split('\0')
60         is_string = True
61         count = len(strings) - 1
62         if count > 0 and not strings[-1]:
63             for string in strings[:-1]:
64                 if not string:
65                     is_string = False
66                     break
67                 for ch in string:
68                     if ch < ' ' or ch > '~':
69                         is_string = False
70                         break
71         else:
72             is_string = False
73         if is_string:
74             if count == 1:
75                 return TYPE_STRING, strings[0]
76             else:
77                 return TYPE_STRING, strings[:-1]
78         if size % 4:
79             if size == 1:
80                 return TYPE_BYTE, bytes[0]
81             else:
82                 return TYPE_BYTE, list(bytes)
83         val = []
84         for i in range(0, size, 4):
85             val.append(bytes[i:i + 4])
86         if size == 4:
87             return TYPE_INT, val[0]
88         else:
89             return TYPE_INT, val
90
91     def GetEmpty(self, type):
92         """Get an empty / zero value of the given type
93
94         Returns:
95             A single value of the given type
96         """
97         if type == TYPE_BYTE:
98             return chr(0)
99         elif type == TYPE_INT:
100             return struct.pack('<I', 0);
101         elif type == TYPE_STRING:
102             return ''
103         else:
104             return True
105
106 class NodeBase:
107     """A device tree node
108
109     Properties:
110         offset: Integer offset in the device tree
111         name: Device tree node tname
112         path: Full path to node, along with the node name itself
113         _fdt: Device tree object
114         subnodes: A list of subnodes for this node, each a Node object
115         props: A dict of properties for this node, each a Prop object.
116             Keyed by property name
117     """
118     def __init__(self, fdt, offset, name, path):
119         self._fdt = fdt
120         self._offset = offset
121         self.name = name
122         self.path = path
123         self.subnodes = []
124         self.props = {}
125
126 class Fdt:
127     """Provides simple access to a flat device tree blob.
128
129     Properties:
130       fname: Filename of fdt
131       _root: Root of device tree (a Node object)
132     """
133     def __init__(self, fname):
134         self._fname = fname