]> git.sur5r.net Git - u-boot/blob - tools/binman/etype/u_boot_ucode.py
Merge git://git.denx.de/u-boot-sunxi
[u-boot] / tools / binman / etype / u_boot_ucode.py
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 from entry import Entry
10 from blob import Entry_blob
11 import tools
12
13 class Entry_u_boot_ucode(Entry_blob):
14     """U-Boot microcode block
15
16     U-Boot on x86 needs a single block of microcode. This is collected from
17     the various microcode update nodes in the device tree. It is also unable
18     to read the microcode from the device tree on platforms that use FSP
19     (Firmware Support Package) binaries, because the API requires that the
20     microcode is supplied before there is any SRAM available to use (i.e.
21     the FSP sets up the SRAM / cache-as-RAM but does so in the call that
22     requires the microcode!). To keep things simple, all x86 platforms handle
23     microcode the same way in U-Boot (even non-FSP platforms). This is that
24     a table is placed at _dt_ucode_base_size containing the base address and
25     size of the microcode. This is either passed to the FSP (for FSP
26     platforms), or used to set up the microcode (for non-FSP platforms).
27     This all happens in the build system since it is the only way to get
28     the microcode into a single blob and accessible without SRAM.
29
30     There are two cases to handle. If there is only one microcode blob in
31     the device tree, then the ucode pointer it set to point to that. This
32     entry (u-boot-ucode) is empty. If there is more than one update, then
33     this entry holds the concatenation of all updates, and the device tree
34     entry (u-boot-dtb-with-ucode) is updated to remove the microcode. This
35     last step ensures that that the microcode appears in one contiguous
36     block in the image and is not unnecessarily duplicated in the device
37     tree. It is referred to as 'collation' here.
38
39     Entry types that have a part to play in handling microcode:
40
41         Entry_u_boot_with_ucode_ptr:
42             Contains u-boot-nodtb.bin (i.e. U-Boot without the device tree).
43             It updates it with the address and size of the microcode so that
44             U-Boot can find it early on start-up.
45         Entry_u_boot_dtb_with_ucode:
46             Contains u-boot.dtb. It stores the microcode in a
47             'self.ucode_data' property, which is then read by this class to
48             obtain the microcode if needed. If collation is performed, it
49             removes the microcode from the device tree.
50         Entry_u_boot_ucode:
51             This class. If collation is enabled it reads the microcode from
52             the Entry_u_boot_dtb_with_ucode entry, and uses it as the
53             contents of this entry.
54     """
55     def __init__(self, image, etype, node):
56         Entry_blob.__init__(self, image, etype, node)
57
58     def ObtainContents(self):
59         # If the image does not need microcode, there is nothing to do
60         ucode_dest_entry = self.image.FindEntryType('u-boot-with-ucode-ptr')
61         ucode_dest_entry_spl = self.image.FindEntryType(
62             'u-boot-spl-with-ucode-ptr')
63         if ((not ucode_dest_entry or not ucode_dest_entry.target_pos) and
64             (not ucode_dest_entry_spl or not ucode_dest_entry_spl.target_pos)):
65             self.data = ''
66             return True
67
68         # Get the microcode from the device tree entry
69         fdt_entry = self.image.FindEntryType('u-boot-dtb-with-ucode')
70         if not fdt_entry or not fdt_entry.ucode_data:
71             return False
72
73         if not fdt_entry.collate:
74             # This section can be empty
75             self.data = ''
76             return True
77
78         # Write it out to a file
79         dtb_name = 'u-boot-ucode.bin'
80         fname = tools.GetOutputFilename(dtb_name)
81         with open(fname, 'wb') as fd:
82             fd.write(fdt_entry.ucode_data)
83
84         self._pathname = fname
85         self.ReadContents()
86
87         return True