Home | History | Annotate | Download | only in etype
      1 # SPDX-License-Identifier: GPL-2.0+
      2 # Copyright (c) 2016 Google, Inc
      3 # Written by Simon Glass <sjg (at] chromium.org>
      4 #
      5 # Entry-type module for U-Boot device tree with the microcode removed
      6 #
      7 
      8 import fdt
      9 from entry import Entry
     10 from blob import Entry_blob
     11 import tools
     12 
     13 class Entry_u_boot_dtb_with_ucode(Entry_blob):
     14     """A U-Boot device tree file, with the microcode removed
     15 
     16     See Entry_u_boot_ucode for full details of the 3 entries involved in this
     17     process.
     18     """
     19     def __init__(self, section, etype, node):
     20         Entry_blob.__init__(self, section, etype, node)
     21         self.ucode_data = ''
     22         self.collate = False
     23         self.ucode_offset = None
     24         self.ucode_size = None
     25 
     26     def GetDefaultFilename(self):
     27         return 'u-boot.dtb'
     28 
     29     def ObtainContents(self):
     30         Entry_blob.ObtainContents(self)
     31 
     32         # If the section does not need microcode, there is nothing to do
     33         ucode_dest_entry = self.section.FindEntryType(
     34             'u-boot-spl-with-ucode-ptr')
     35         if not ucode_dest_entry or not ucode_dest_entry.target_pos:
     36             ucode_dest_entry = self.section.FindEntryType(
     37                 'u-boot-with-ucode-ptr')
     38         if not ucode_dest_entry or not ucode_dest_entry.target_pos:
     39             return True
     40 
     41         # Create a new file to hold the copied device tree
     42         dtb_name = 'u-boot-dtb-with-ucode.dtb'
     43         fname = tools.GetOutputFilename(dtb_name)
     44         with open(fname, 'wb') as fd:
     45             fd.write(self.data)
     46 
     47         # Remove the microcode
     48         dtb = fdt.FdtScan(fname)
     49         ucode = dtb.GetNode('/microcode')
     50         if not ucode:
     51             raise self.Raise("No /microcode node found in '%s'" % fname)
     52 
     53         # There's no need to collate it (move all microcode into one place)
     54         # if we only have one chunk of microcode.
     55         self.collate = len(ucode.subnodes) > 1
     56         for node in ucode.subnodes:
     57             data_prop = node.props.get('data')
     58             if data_prop:
     59                 self.ucode_data += ''.join(data_prop.bytes)
     60                 if self.collate:
     61                     prop = node.DeleteProp('data')
     62                 else:
     63                     # Find the offset in the device tree of the ucode data
     64                     self.ucode_offset = data_prop.GetOffset() + 12
     65                     self.ucode_size = len(data_prop.bytes)
     66         if self.collate:
     67             dtb.Pack()
     68             dtb.Flush()
     69 
     70             # Make this file the contents of this entry
     71             self._pathname = fname
     72             self.ReadContents()
     73         return True
     74