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 ObtainContents(self): 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 40 return Entry_blob.ObtainContents(self) 41 42 def ProcessContents(self): 43 # If the image does not need microcode, there is nothing to do 44 if not self.target_pos: 45 return 46 47 # Get the position of the microcode 48 ucode_entry = self.section.FindEntryType('u-boot-ucode') 49 if not ucode_entry: 50 self.Raise('Cannot find microcode region u-boot-ucode') 51 52 # Check the target pos is in the section. If it is not, then U-Boot is 53 # being linked incorrectly, or is being placed at the wrong position 54 # in the section. 55 # 56 # The section must be set up so that U-Boot is placed at the 57 # flash address to which it is linked. For example, if 58 # CONFIG_SYS_TEXT_BASE is 0xfff00000, and the ROM is 8MB, then 59 # the U-Boot region must start at position 7MB in the section. In this 60 # case the ROM starts at 0xff800000, so the position of the first 61 # entry in the section corresponds to that. 62 if (self.target_pos < self.pos or 63 self.target_pos >= self.pos + self.size): 64 self.Raise('Microcode pointer _dt_ucode_base_size at %08x is ' 65 'outside the section ranging from %08x to %08x' % 66 (self.target_pos, self.pos, self.pos + self.size)) 67 68 # Get the microcode, either from u-boot-ucode or u-boot-dtb-with-ucode. 69 # If we have left the microcode in the device tree, then it will be 70 # in the former. If we extracted the microcode from the device tree 71 # and collated it in one place, it will be in the latter. 72 if ucode_entry.size: 73 pos, size = ucode_entry.pos, ucode_entry.size 74 else: 75 dtb_entry = self.section.FindEntryType('u-boot-dtb-with-ucode') 76 if not dtb_entry: 77 self.Raise('Cannot find microcode region u-boot-dtb-with-ucode') 78 pos = dtb_entry.pos + dtb_entry.ucode_offset 79 size = dtb_entry.ucode_size 80 81 # Write the microcode position and size into the entry 82 pos_and_size = struct.pack('<2L', pos, size) 83 self.target_pos -= self.pos 84 self.data = (self.data[:self.target_pos] + pos_and_size + 85 self.data[self.target_pos + 8:]) 86