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