1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright 2018 Google, Inc
3 # Written by Simon Glass <sjg@chromium.org>
5 # Holds and modifies the state information held by binman
15 # Records the device-tree files known to binman, keyed by filename (e.g.
19 # Arguments passed to binman to provide arguments to entries
22 # True to use fake device-tree files for testing (see U_BOOT_DTB_DATA in
26 # Set of all device tree files references by images
29 # Same as above, but excluding the main one
32 # The DTB which contains the full image information
36 """Get the Fdt object for a particular device-tree filename
38 Binman keeps track of at least one device-tree file called u-boot.dtb but
39 can also have others (e.g. for SPL). This function looks up the given
40 filename and returns the associated Fdt object.
43 fname: Filename to look up (e.g. 'u-boot.dtb').
46 Fdt object associated with the filename
48 return fdt_files[fname]
50 def GetFdtPath(fname):
51 """Get the full pathname of a particular Fdt object
53 Similar to GetFdt() but returns the pathname associated with the Fdt.
56 fname: Filename to look up (e.g. 'u-boot.dtb').
59 Full path name to the associated Fdt
61 return fdt_files[fname]._fname
63 def GetFdtContents(fname):
64 """Looks up the FDT pathname and contents
66 This is used to obtain the Fdt pathname and contents when needed by an
67 entry. It supports a 'fake' dtb, allowing tests to substitute test data for
71 fname: Filename to look up (e.g. 'u-boot.dtb').
78 if fname in fdt_files and not use_fake_dtb:
79 pathname = GetFdtPath(fname)
80 data = GetFdt(fname).GetContents()
82 pathname = tools.GetInputFilename(fname)
83 data = tools.ReadFile(pathname)
86 def SetEntryArgs(args):
87 """Set the value of the entry args
89 This sets up the entry_args dict which is used to supply entry arguments to
93 args: List of entry arguments, each in the format "name=value"
100 m = re.match('([^=]*)=(.*)', arg)
102 raise ValueError("Invalid entry arguemnt '%s'" % arg)
103 entry_args[m.group(1)] = m.group(2)
105 def GetEntryArg(name):
106 """Get the value of an entry argument
109 name: Name of argument to retrieve
112 String value of argument
114 return entry_args.get(name)
116 def Prepare(images, dtb):
117 """Get device tree files ready for use
119 This sets up a set of device tree files that can be retrieved by GetFdts().
120 At present there is only one, that for U-Boot proper.
123 images: List of images being used
126 global fdt_set, fdt_subset, fdt_files, main_dtb
127 # Import these here in case libfdt.py is not available, in which case
128 # the above help option still works.
132 # If we are updating the DTBs we need to put these updated versions
133 # where Entry_blob_dtb can find them. We can ignore 'u-boot.dtb'
134 # since it is assumed to be the one passed in with options.dt, and
135 # was handled just above.
138 fdt_files['u-boot.dtb'] = dtb
141 for image in images.values():
142 fdt_subset.update(image.GetFdtSet())
143 fdt_subset.discard('u-boot.dtb')
144 for other_fname in fdt_subset:
145 infile = tools.GetInputFilename(other_fname)
146 other_fname_dtb = fdt_util.EnsureCompiled(infile)
147 out_fname = tools.GetOutputFilename('%s.out' %
148 os.path.split(other_fname)[1])
149 tools.WriteFile(out_fname, tools.ReadFile(other_fname_dtb))
150 other_dtb = fdt.FdtScan(out_fname)
151 fdt_files[other_fname] = other_dtb
154 """Yield all device tree files being used by binman
157 Device trees being used (U-Boot proper, SPL, TPL)
160 for other_fname in fdt_subset:
161 yield fdt_files[other_fname]
163 def GetUpdateNodes(node):
164 """Yield all the nodes that need to be updated in all device trees
166 The property referenced by this node is added to any device trees which
167 have the given node. Due to removable of unwanted notes, SPL and TPL may
171 node: Node object in the main device tree to look up
174 Node objects in each device tree that is in use (U-Boot proper, which
175 is node, SPL and TPL)
178 for dtb in fdt_files.values():
179 if dtb != node.GetFdt():
180 other_node = dtb.GetNode(node.path)
184 def AddZeroProp(node, prop):
185 """Add a new property to affected device trees with an integer value of 0.
188 prop_name: Name of property
190 for n in GetUpdateNodes(node):
193 def AddSubnode(node, name):
194 """Add a new subnode to a node in affected device trees
198 name: name of node to add
201 New subnode that was created in main tree
204 for n in GetUpdateNodes(node):
205 subnode = n.AddSubnode(name)
210 def AddString(node, prop, value):
211 """Add a new string property to affected device trees
214 prop_name: Name of property
215 value: String value (which will be \0-terminated in the DT)
217 for n in GetUpdateNodes(node):
218 n.AddString(prop, value)
220 def SetInt(node, prop, value):
221 """Update an integer property in affected device trees with an integer value
223 This is not allowed to change the size of the FDT.
226 prop_name: Name of property
228 for n in GetUpdateNodes(node):
229 n.SetInt(prop, value)
231 def CheckAddHashProp(node):
232 hash_node = node.FindNode('hash')
234 algo = hash_node.props.get('algo')
236 return "Missing 'algo' property for hash node"
237 if algo.value == 'sha256':
240 return "Unknown hash algorithm '%s'" % algo
241 for n in GetUpdateNodes(hash_node):
242 n.AddEmptyProp('value', size)
244 def CheckSetHashValue(node, get_data_func):
245 hash_node = node.FindNode('hash')
247 algo = hash_node.props.get('algo').value
250 m.update(get_data_func())
252 for n in GetUpdateNodes(hash_node):
253 n.SetData('value', data)