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
14 # Records the device-tree files known to binman, keyed by filename (e.g.
18 # Arguments passed to binman to provide arguments to entries
21 # True to use fake device-tree files for testing (see U_BOOT_DTB_DATA in
25 # Set of all device tree files references by images
28 # Same as above, but excluding the main one
31 # The DTB which contains the full image information
35 """Get the Fdt object for a particular device-tree filename
37 Binman keeps track of at least one device-tree file called u-boot.dtb but
38 can also have others (e.g. for SPL). This function looks up the given
39 filename and returns the associated Fdt object.
42 fname: Filename to look up (e.g. 'u-boot.dtb').
45 Fdt object associated with the filename
47 return fdt_files[fname]
49 def GetFdtPath(fname):
50 """Get the full pathname of a particular Fdt object
52 Similar to GetFdt() but returns the pathname associated with the Fdt.
55 fname: Filename to look up (e.g. 'u-boot.dtb').
58 Full path name to the associated Fdt
60 return fdt_files[fname]._fname
62 def GetFdtContents(fname):
63 """Looks up the FDT pathname and contents
65 This is used to obtain the Fdt pathname and contents when needed by an
66 entry. It supports a 'fake' dtb, allowing tests to substitute test data for
70 fname: Filename to look up (e.g. 'u-boot.dtb').
77 if fname in fdt_files and not use_fake_dtb:
78 pathname = GetFdtPath(fname)
79 data = GetFdt(fname).GetContents()
81 pathname = tools.GetInputFilename(fname)
82 data = tools.ReadFile(pathname)
85 def SetEntryArgs(args):
86 """Set the value of the entry args
88 This sets up the entry_args dict which is used to supply entry arguments to
92 args: List of entry arguments, each in the format "name=value"
99 m = re.match('([^=]*)=(.*)', arg)
101 raise ValueError("Invalid entry arguemnt '%s'" % arg)
102 entry_args[m.group(1)] = m.group(2)
104 def GetEntryArg(name):
105 """Get the value of an entry argument
108 name: Name of argument to retrieve
111 String value of argument
113 return entry_args.get(name)
115 def Prepare(images, dtb):
116 """Get device tree files ready for use
118 This sets up a set of device tree files that can be retrieved by GetFdts().
119 At present there is only one, that for U-Boot proper.
122 images: List of images being used
125 global fdt_set, fdt_subset, fdt_files, main_dtb
126 # Import these here in case libfdt.py is not available, in which case
127 # the above help option still works.
131 # If we are updating the DTBs we need to put these updated versions
132 # where Entry_blob_dtb can find them. We can ignore 'u-boot.dtb'
133 # since it is assumed to be the one passed in with options.dt, and
134 # was handled just above.
137 fdt_files['u-boot.dtb'] = dtb
140 for image in images.values():
141 fdt_subset.update(image.GetFdtSet())
142 fdt_subset.discard('u-boot.dtb')
143 for other_fname in fdt_subset:
144 infile = tools.GetInputFilename(other_fname)
145 other_fname_dtb = fdt_util.EnsureCompiled(infile)
146 out_fname = tools.GetOutputFilename('%s.out' %
147 os.path.split(other_fname)[1])
148 tools.WriteFile(out_fname, tools.ReadFile(other_fname_dtb))
149 other_dtb = fdt.FdtScan(out_fname)
150 fdt_files[other_fname] = other_dtb
153 """Yield all device tree files being used by binman
156 Device trees being used (U-Boot proper, SPL, TPL)
159 for other_fname in fdt_subset:
160 yield fdt_files[other_fname]
162 def GetUpdateNodes(node):
163 """Yield all the nodes that need to be updated in all device trees
165 The property referenced by this node is added to any device trees which
166 have the given node. Due to removable of unwanted notes, SPL and TPL may
170 node: Node object in the main device tree to look up
173 Node objects in each device tree that is in use (U-Boot proper, which
174 is node, SPL and TPL)
177 for dtb in fdt_files.values():
178 if dtb != node.GetFdt():
179 other_node = dtb.GetNode(node.path)
183 def AddZeroProp(node, prop):
184 """Add a new property to affected device trees with an integer value of 0.
187 prop_name: Name of property
189 for n in GetUpdateNodes(node):
192 def AddSubnode(node, name):
193 """Add a new subnode to a node in affected device trees
197 name: name of node to add
200 New subnode that was created in main tree
203 for n in GetUpdateNodes(node):
204 subnode = n.AddSubnode(name)
209 def AddString(node, prop, value):
210 """Add a new string property to affected device trees
213 prop_name: Name of property
214 value: String value (which will be \0-terminated in the DT)
216 for n in GetUpdateNodes(node):
217 n.AddString(prop, value)
219 def SetInt(node, prop, value):
220 """Update an integer property in affected device trees with an integer value
222 This is not allowed to change the size of the FDT.
225 prop_name: Name of property
227 for n in GetUpdateNodes(node):
228 n.SetInt(prop, value)
230 def CheckAddHashProp(node):
231 hash_node = node.FindNode('hash')
233 algo = hash_node.props.get('algo')
235 return "Missing 'algo' property for hash node"
236 if algo.value == 'sha256':
239 return "Unknown hash algorithm '%s'" % algo
240 for n in GetUpdateNodes(hash_node):
241 n.AddEmptyProp('value', size)
243 def CheckSetHashValue(node, get_data_func):
244 hash_node = node.FindNode('hash')
246 algo = hash_node.props.get('algo').value
249 m.update(get_data_func())
251 for n in GetUpdateNodes(hash_node):
252 n.SetData('value', data)