1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (c) 2016 Google, Inc 3# Written by Simon Glass <sjg@chromium.org> 4# 5# Entry-type module for U-Boot device tree with the microcode removed 6# 7 8from binman.entry import Entry 9from binman.etype.blob_dtb import Entry_blob_dtb 10from patman import tools 11 12class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): 13 """A U-Boot device tree file, with the microcode removed 14 15 Properties / Entry arguments: 16 - filename: Filename of u-boot.dtb (default 'u-boot.dtb') 17 18 See Entry_u_boot_ucode for full details of the three entries involved in 19 this process. This entry provides the U-Boot device-tree file, which 20 contains the microcode. If the microcode is not being collated into one 21 place then the offset and size of the microcode is recorded by this entry, 22 for use by u-boot-with-ucode_ptr. If it is being collated, then this 23 entry deletes the microcode from the device tree (to save space) and makes 24 it available to u-boot-ucode. 25 """ 26 def __init__(self, section, etype, node): 27 # Put this here to allow entry-docs and help to work without libfdt 28 global state 29 from binman import state 30 31 super().__init__(section, etype, node) 32 self.ucode_data = b'' 33 self.collate = False 34 self.ucode_offset = None 35 self.ucode_size = None 36 self.ucode = None 37 self.ready = False 38 39 def GetDefaultFilename(self): 40 return 'u-boot.dtb' 41 42 def GetFdtEtype(self): 43 return 'u-boot-dtb' 44 45 def ProcessFdt(self, fdt): 46 # So the module can be loaded without it 47 from dtoc import fdt 48 49 # If the section does not need microcode, there is nothing to do 50 ucode_dest_entry = self.section.FindEntryType( 51 'u-boot-spl-with-ucode-ptr') 52 if not ucode_dest_entry or not ucode_dest_entry.target_offset: 53 ucode_dest_entry = self.section.FindEntryType( 54 'u-boot-tpl-with-ucode-ptr') 55 if not ucode_dest_entry or not ucode_dest_entry.target_offset: 56 ucode_dest_entry = self.section.FindEntryType( 57 'u-boot-with-ucode-ptr') 58 if not ucode_dest_entry or not ucode_dest_entry.target_offset: 59 return True 60 61 # Remove the microcode 62 etype = self.GetFdtEtype() 63 fdt = state.GetFdtForEtype(etype) 64 self.ucode = fdt.GetNode('/microcode') 65 if not self.ucode: 66 raise self.Raise("No /microcode node found in '%s'" % etype) 67 68 # There's no need to collate it (move all microcode into one place) 69 # if we only have one chunk of microcode. 70 self.collate = len(self.ucode.subnodes) > 1 71 for node in self.ucode.subnodes: 72 data_prop = node.props.get('data') 73 if data_prop: 74 self.ucode_data += data_prop.bytes 75 if self.collate: 76 node.DeleteProp('data') 77 return True 78 79 def ObtainContents(self): 80 # Call the base class just in case it does something important. 81 super().ObtainContents() 82 if self.ucode and not self.collate: 83 for node in self.ucode.subnodes: 84 data_prop = node.props.get('data') 85 if data_prop: 86 # Find the offset in the device tree of the ucode data 87 self.ucode_offset = data_prop.GetOffset() + 12 88 self.ucode_size = len(data_prop.bytes) 89 self.ready = True 90 else: 91 self.ready = True 92 return self.ready 93