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
34 # Allow entries to expand after they have been packed. This is detected and
35 # forces a re-pack. If not allowed, any attempted expansion causes an error in
36 # Entry.ProcessContentsUpdate()
37 allow_entry_expansion = True
40 """Get the Fdt object for a particular device-tree filename
42 Binman keeps track of at least one device-tree file called u-boot.dtb but
43 can also have others (e.g. for SPL). This function looks up the given
44 filename and returns the associated Fdt object.
47 fname: Filename to look up (e.g. 'u-boot.dtb').
50 Fdt object associated with the filename
52 return fdt_files[fname]
54 def GetFdtPath(fname):
55 """Get the full pathname of a particular Fdt object
57 Similar to GetFdt() but returns the pathname associated with the Fdt.
60 fname: Filename to look up (e.g. 'u-boot.dtb').
63 Full path name to the associated Fdt
65 return fdt_files[fname]._fname
67 def GetFdtContents(fname='u-boot.dtb'):
68 """Looks up the FDT pathname and contents
70 This is used to obtain the Fdt pathname and contents when needed by an
71 entry. It supports a 'fake' dtb, allowing tests to substitute test data for
75 fname: Filename to look up (e.g. 'u-boot.dtb').
82 if fname in fdt_files and not use_fake_dtb:
83 pathname = GetFdtPath(fname)
84 data = GetFdt(fname).GetContents()
86 pathname = tools.GetInputFilename(fname)
87 data = tools.ReadFile(pathname)
90 def SetEntryArgs(args):
91 """Set the value of the entry args
93 This sets up the entry_args dict which is used to supply entry arguments to
97 args: List of entry arguments, each in the format "name=value"
104 m = re.match('([^=]*)=(.*)', arg)
106 raise ValueError("Invalid entry arguemnt '%s'" % arg)
107 entry_args[m.group(1)] = m.group(2)
109 def GetEntryArg(name):
110 """Get the value of an entry argument
113 name: Name of argument to retrieve
116 String value of argument
118 return entry_args.get(name)
120 def Prepare(images, dtb):
121 """Get device tree files ready for use
123 This sets up a set of device tree files that can be retrieved by GetFdts().
124 At present there is only one, that for U-Boot proper.
127 images: List of images being used
130 global fdt_set, fdt_subset, fdt_files, main_dtb
131 # Import these here in case libfdt.py is not available, in which case
132 # the above help option still works.
136 # If we are updating the DTBs we need to put these updated versions
137 # where Entry_blob_dtb can find them. We can ignore 'u-boot.dtb'
138 # since it is assumed to be the one passed in with options.dt, and
139 # was handled just above.
142 fdt_files['u-boot.dtb'] = dtb
145 for image in images.values():
146 fdt_subset.update(image.GetFdtSet())
147 fdt_subset.discard('u-boot.dtb')
148 for other_fname in fdt_subset:
149 infile = tools.GetInputFilename(other_fname)
150 other_fname_dtb = fdt_util.EnsureCompiled(infile)
151 out_fname = tools.GetOutputFilename('%s.out' %
152 os.path.split(other_fname)[1])
153 tools.WriteFile(out_fname, tools.ReadFile(other_fname_dtb))
154 other_dtb = fdt.FdtScan(out_fname)
155 fdt_files[other_fname] = other_dtb
158 """Yield all device tree files being used by binman
161 Device trees being used (U-Boot proper, SPL, TPL)
164 for other_fname in fdt_subset:
165 yield fdt_files[other_fname]
167 def GetUpdateNodes(node):
168 """Yield all the nodes that need to be updated in all device trees
170 The property referenced by this node is added to any device trees which
171 have the given node. Due to removable of unwanted notes, SPL and TPL may
175 node: Node object in the main device tree to look up
178 Node objects in each device tree that is in use (U-Boot proper, which
179 is node, SPL and TPL)
182 for dtb in fdt_files.values():
183 if dtb != node.GetFdt():
184 other_node = dtb.GetNode(node.path)
188 def AddZeroProp(node, prop):
189 """Add a new property to affected device trees with an integer value of 0.
192 prop_name: Name of property
194 for n in GetUpdateNodes(node):
197 def AddSubnode(node, name):
198 """Add a new subnode to a node in affected device trees
202 name: name of node to add
205 New subnode that was created in main tree
208 for n in GetUpdateNodes(node):
209 subnode = n.AddSubnode(name)
214 def AddString(node, prop, value):
215 """Add a new string property to affected device trees
218 prop_name: Name of property
219 value: String value (which will be \0-terminated in the DT)
221 for n in GetUpdateNodes(node):
222 n.AddString(prop, value)
224 def SetInt(node, prop, value):
225 """Update an integer property in affected device trees with an integer value
227 This is not allowed to change the size of the FDT.
230 prop_name: Name of property
232 for n in GetUpdateNodes(node):
233 n.SetInt(prop, value)
235 def CheckAddHashProp(node):
236 hash_node = node.FindNode('hash')
238 algo = hash_node.props.get('algo')
240 return "Missing 'algo' property for hash node"
241 if algo.value == 'sha256':
244 return "Unknown hash algorithm '%s'" % algo
245 for n in GetUpdateNodes(hash_node):
246 n.AddEmptyProp('value', size)
248 def CheckSetHashValue(node, get_data_func):
249 hash_node = node.FindNode('hash')
251 algo = hash_node.props.get('algo').value
254 m.update(get_data_func())
256 for n in GetUpdateNodes(hash_node):
257 n.SetData('value', data)
259 def SetAllowEntryExpansion(allow):
260 """Set whether post-pack expansion of entries is allowed
263 allow: True to allow expansion, False to raise an exception
265 global allow_entry_expansion
267 allow_entry_expansion = allow
269 def AllowEntryExpansion():
270 """Check whether post-pack expansion of entries is allowed
273 True if expansion should be allowed, False if an exception should be
276 return allow_entry_expansion