]>
Commit | Line | Data |
---|---|---|
e0ff8551 SG |
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 | ||
9 | import struct | |
10 | ||
11 | import command | |
b50e5611 | 12 | import elf |
e0ff8551 SG |
13 | from entry import Entry |
14 | from blob import Entry_blob | |
15 | import fdt_util | |
16 | import tools | |
17 | ||
18 | class 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) | |
b50e5611 SG |
35 | sym = elf.GetSymbolAddress(fname, '_dt_ucode_base_size') |
36 | if sym: | |
37 | self.target_pos = sym | |
e0ff8551 SG |
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:]) |