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