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