1# Copyright (c) 2016 Google, Inc 2# Written by Simon Glass <sjg@chromium.org> 3# 4# SPDX-License-Identifier: GPL-2.0+ 5# 6# Entry-type module for a U-Boot binary with an embedded microcode pointer 7# 8 9import struct 10 11import command 12import elf 13from entry import Entry 14from blob import Entry_blob 15import fdt_util 16import tools 17 18class Entry_u_boot_with_ucode_ptr(Entry_blob): 19 """U-Boot with embedded microcode pointer 20 21 See Entry_u_boot_ucode for full details of the 3 entries involved in this 22 process. 23 """ 24 def __init__(self, image, etype, node): 25 Entry_blob.__init__(self, image, etype, node) 26 self.elf_fname = 'u-boot' 27 self.target_pos = None 28 29 def GetDefaultFilename(self): 30 return 'u-boot-nodtb.bin' 31 32 def ObtainContents(self): 33 # Figure out where to put the microcode pointer 34 fname = tools.GetInputFilename(self.elf_fname) 35 sym = elf.GetSymbolAddress(fname, '_dt_ucode_base_size') 36 if sym: 37 self.target_pos = sym 38 elif not fdt_util.GetBool(self._node, 'optional-ucode'): 39 self.Raise('Cannot locate _dt_ucode_base_size symbol in u-boot') 40 41 return Entry_blob.ObtainContents(self) 42 43 def ProcessContents(self): 44 # If the image does not need microcode, there is nothing to do 45 if not self.target_pos: 46 return 47 48 # Get the position of the microcode 49 ucode_entry = self.image.FindEntryType('u-boot-ucode') 50 if not ucode_entry: 51 self.Raise('Cannot find microcode region u-boot-ucode') 52 53 # Check the target pos is in the image. If it is not, then U-Boot is 54 # being linked incorrectly, or is being placed at the wrong position 55 # in the image. 56 # 57 # The image must be set up so that U-Boot is placed at the 58 # flash address to which it is linked. For example, if 59 # CONFIG_SYS_TEXT_BASE is 0xfff00000, and the ROM is 8MB, then 60 # the U-Boot region must start at position 7MB in the image. In this 61 # case the ROM starts at 0xff800000, so the position of the first 62 # entry in the image corresponds to that. 63 if (self.target_pos < self.pos or 64 self.target_pos >= self.pos + self.size): 65 self.Raise('Microcode pointer _dt_ucode_base_size at %08x is ' 66 'outside the image ranging from %08x to %08x' % 67 (self.target_pos, self.pos, self.pos + self.size)) 68 69 # Get the microcode, either from u-boot-ucode or u-boot-dtb-with-ucode. 70 # If we have left the microcode in the device tree, then it will be 71 # in the former. If we extracted the microcode from the device tree 72 # and collated it in one place, it will be in the latter. 73 if ucode_entry.size: 74 pos, size = ucode_entry.pos, ucode_entry.size 75 else: 76 dtb_entry = self.image.FindEntryType('u-boot-dtb-with-ucode') 77 if not dtb_entry: 78 self.Raise('Cannot find microcode region u-boot-dtb-with-ucode') 79 pos = dtb_entry.pos + dtb_entry.ucode_offset 80 size = dtb_entry.ucode_size 81 82 # Write the microcode position and size into the entry 83 pos_and_size = struct.pack('<2L', pos, size) 84 self.target_pos -= self.pos 85 self.data = (self.data[:self.target_pos] + pos_and_size + 86 self.data[self.target_pos + 8:]) 87