u_boot_dtb_with_ucode.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 U-Boot device tree with the microcode removed
  6. #
  7. from entry import Entry
  8. from blob_dtb import Entry_blob_dtb
  9. import tools
  10. class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
  11. """A U-Boot device tree file, with the microcode removed
  12. Properties / Entry arguments:
  13. - filename: Filename of u-boot.dtb (default 'u-boot.dtb')
  14. See Entry_u_boot_ucode for full details of the three entries involved in
  15. this process. This entry provides the U-Boot device-tree file, which
  16. contains the microcode. If the microcode is not being collated into one
  17. place then the offset and size of the microcode is recorded by this entry,
  18. for use by u_boot_with_ucode_ptr. If it is being collated, then this
  19. entry deletes the microcode from the device tree (to save space) and makes
  20. it available to u_boot_ucode.
  21. """
  22. def __init__(self, section, etype, node):
  23. # Put this here to allow entry-docs and help to work without libfdt
  24. global state
  25. import state
  26. Entry_blob_dtb.__init__(self, section, etype, node)
  27. self.ucode_data = b''
  28. self.collate = False
  29. self.ucode_offset = None
  30. self.ucode_size = None
  31. self.ucode = None
  32. self.ready = False
  33. def GetDefaultFilename(self):
  34. return 'u-boot.dtb'
  35. def GetFdtEtype(self):
  36. return 'u-boot-dtb'
  37. def ProcessFdt(self, fdt):
  38. # So the module can be loaded without it
  39. import fdt
  40. # If the section does not need microcode, there is nothing to do
  41. ucode_dest_entry = self.section.FindEntryType(
  42. 'u-boot-spl-with-ucode-ptr')
  43. if not ucode_dest_entry or not ucode_dest_entry.target_offset:
  44. ucode_dest_entry = self.section.FindEntryType(
  45. 'u-boot-tpl-with-ucode-ptr')
  46. if not ucode_dest_entry or not ucode_dest_entry.target_offset:
  47. ucode_dest_entry = self.section.FindEntryType(
  48. 'u-boot-with-ucode-ptr')
  49. if not ucode_dest_entry or not ucode_dest_entry.target_offset:
  50. return True
  51. # Remove the microcode
  52. etype = self.GetFdtEtype()
  53. fdt = state.GetFdtForEtype(etype)
  54. self.ucode = fdt.GetNode('/microcode')
  55. if not self.ucode:
  56. raise self.Raise("No /microcode node found in '%s'" % etype)
  57. # There's no need to collate it (move all microcode into one place)
  58. # if we only have one chunk of microcode.
  59. self.collate = len(self.ucode.subnodes) > 1
  60. for node in self.ucode.subnodes:
  61. data_prop = node.props.get('data')
  62. if data_prop:
  63. self.ucode_data += data_prop.bytes
  64. if self.collate:
  65. node.DeleteProp('data')
  66. return True
  67. def ObtainContents(self):
  68. # Call the base class just in case it does something important.
  69. Entry_blob_dtb.ObtainContents(self)
  70. if self.ucode and not self.collate:
  71. for node in self.ucode.subnodes:
  72. data_prop = node.props.get('data')
  73. if data_prop:
  74. # Find the offset in the device tree of the ucode data
  75. self.ucode_offset = data_prop.GetOffset() + 12
  76. self.ucode_size = len(data_prop.bytes)
  77. self.ready = True
  78. else:
  79. self.ready = True
  80. return self.ready