]> git.ipfire.org Git - thirdparty/u-boot.git/blame - tools/binman/etype/u_boot_with_ucode_ptr.py
binman: Support x86 microcode in TPL
[thirdparty/u-boot.git] / tools / binman / etype / u_boot_with_ucode_ptr.py
CommitLineData
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
8import struct
9
10import command
b50e5611 11import elf
e0ff8551
SG
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
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:])