u_boot_ucode.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. from binman.entry import Entry
  8. from binman.etype.blob import Entry_blob
  9. from patman import tools
  10. class Entry_u_boot_ucode(Entry_blob):
  11. """U-Boot microcode block
  12. Properties / Entry arguments:
  13. None
  14. The contents of this entry are filled in automatically by other entries
  15. which must also be in the image.
  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. There are two cases to handle. If there is only one microcode blob in
  30. the device tree, then the ucode pointer it set to point to that. This
  31. entry (u-boot-ucode) is empty. If there is more than one update, then
  32. this entry holds the concatenation of all updates, and the device tree
  33. entry (u-boot-dtb-with-ucode) is updated to remove the microcode. This
  34. last step ensures that that the microcode appears in one contiguous
  35. block in the image and is not unnecessarily duplicated in the device
  36. tree. It is referred to as 'collation' here.
  37. Entry types that have a part to play in handling microcode:
  38. Entry_u_boot_with_ucode_ptr:
  39. Contains u-boot-nodtb.bin (i.e. U-Boot without the device tree).
  40. It updates it with the address and size of the microcode so that
  41. U-Boot can find it early on start-up.
  42. Entry_u_boot_dtb_with_ucode:
  43. Contains u-boot.dtb. It stores the microcode in a
  44. 'self.ucode_data' property, which is then read by this class to
  45. obtain the microcode if needed. If collation is performed, it
  46. removes the microcode from the device tree.
  47. Entry_u_boot_ucode:
  48. This class. If collation is enabled it reads the microcode from
  49. the Entry_u_boot_dtb_with_ucode entry, and uses it as the
  50. contents of this entry.
  51. """
  52. def __init__(self, section, etype, node):
  53. Entry_blob.__init__(self, section, etype, node)
  54. def ObtainContents(self):
  55. # If the section does not need microcode, there is nothing to do
  56. found = False
  57. for suffix in ['', '-spl', '-tpl']:
  58. name = 'u-boot%s-with-ucode-ptr' % suffix
  59. entry = self.section.FindEntryType(name)
  60. if entry and entry.target_offset:
  61. found = True
  62. if not found:
  63. self.data = b''
  64. return True
  65. # Get the microcode from the device tree entry. If it is not available
  66. # yet, return False so we will be called later. If the section simply
  67. # doesn't exist, then we may as well return True, since we are going to
  68. # get an error anyway.
  69. for suffix in ['', '-spl', '-tpl']:
  70. name = 'u-boot%s-dtb-with-ucode' % suffix
  71. fdt_entry = self.section.FindEntryType(name)
  72. if fdt_entry:
  73. break
  74. if not fdt_entry:
  75. return True
  76. if not fdt_entry.ready:
  77. return False
  78. if not fdt_entry.collate:
  79. # This binary can be empty
  80. self.data = b''
  81. return True
  82. # Write it out to a file
  83. self._pathname = tools.GetOutputFilename('u-boot-ucode.bin')
  84. tools.WriteFile(self._pathname, fdt_entry.ucode_data)
  85. self.ReadBlobContents()
  86. return True