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