diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 3afc560..4dd67d6 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -462,6 +462,8 @@ both SPL and the device tree). Entry: u-boot-spl-with-ucode-ptr: U-Boot SPL with embedded microcode pointer ---------------------------------------------------------------------------- +This is used when SPL must set up the microcode for U-Boot. + See Entry_u_boot_ucode for full details of the entries involved in this process. @@ -503,6 +505,24 @@ to activate. +Entry: u-boot-tpl-dtb-with-ucode: U-Boot TPL with embedded microcode pointer +---------------------------------------------------------------------------- + +This is used when TPL must set up the microcode for U-Boot. + +See Entry_u_boot_ucode for full details of the entries involved in this +process. + + + +Entry: u-boot-tpl-with-ucode-ptr: U-Boot TPL with embedded microcode pointer +---------------------------------------------------------------------------- + +See Entry_u_boot_ucode for full details of the entries involved in this +process. + + + Entry: u-boot-ucode: U-Boot microcode block ------------------------------------------- diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py index 73f5fbf..444c51b 100644 --- a/tools/binman/etype/u_boot_dtb_with_ucode.py +++ b/tools/binman/etype/u_boot_dtb_with_ucode.py @@ -45,6 +45,9 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): 'u-boot-spl-with-ucode-ptr') if not ucode_dest_entry or not ucode_dest_entry.target_offset: ucode_dest_entry = self.section.FindEntryType( + 'u-boot-tpl-with-ucode-ptr') + if not ucode_dest_entry or not ucode_dest_entry.target_offset: + ucode_dest_entry = self.section.FindEntryType( 'u-boot-with-ucode-ptr') if not ucode_dest_entry or not ucode_dest_entry.target_offset: return True @@ -70,14 +73,14 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): def ObtainContents(self): # Call the base class just in case it does something important. Entry_blob_dtb.ObtainContents(self) - self._pathname = state.GetFdtPath(self._filename) - self.ReadBlobContents() - if self.ucode: + if self.ucode and not self.collate: for node in self.ucode.subnodes: data_prop = node.props.get('data') - if data_prop and not self.collate: + if data_prop: # Find the offset in the device tree of the ucode data self.ucode_offset = data_prop.GetOffset() + 12 self.ucode_size = len(data_prop.bytes) - self.ready = True - return True + self.ready = True + else: + self.ready = True + return self.ready diff --git a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py index 0dfe268..b650cf0 100644 --- a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py @@ -16,6 +16,8 @@ import tools class Entry_u_boot_spl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): """U-Boot SPL with embedded microcode pointer + This is used when SPL must set up the microcode for U-Boot. + See Entry_u_boot_ucode for full details of the entries involved in this process. """ diff --git a/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py b/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py new file mode 100644 index 0000000..71e04fc --- /dev/null +++ b/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for U-Boot device tree with the microcode removed +# + +import control +from entry import Entry +from u_boot_dtb_with_ucode import Entry_u_boot_dtb_with_ucode +import tools + +class Entry_u_boot_tpl_dtb_with_ucode(Entry_u_boot_dtb_with_ucode): + """U-Boot TPL with embedded microcode pointer + + This is used when TPL must set up the microcode for U-Boot. + + See Entry_u_boot_ucode for full details of the entries involved in this + process. + """ + def __init__(self, section, etype, node): + Entry_u_boot_dtb_with_ucode.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'tpl/u-boot-tpl.dtb' diff --git a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py new file mode 100644 index 0000000..8d94dde --- /dev/null +++ b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for an TPL binary with an embedded microcode pointer +# + +import struct + +import command +from entry import Entry +from blob import Entry_blob +from u_boot_with_ucode_ptr import Entry_u_boot_with_ucode_ptr +import tools + +class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): + """U-Boot TPL with embedded microcode pointer + + See Entry_u_boot_ucode for full details of the entries involved in this + process. + """ + def __init__(self, section, etype, node): + Entry_u_boot_with_ucode_ptr.__init__(self, section, etype, node) + self.elf_fname = 'tpl/u-boot-tpl' + + def GetDefaultFilename(self): + return 'tpl/u-boot-tpl-nodtb.bin' diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py index 6acf94d..a00e530 100644 --- a/tools/binman/etype/u_boot_ucode.py +++ b/tools/binman/etype/u_boot_ucode.py @@ -62,19 +62,24 @@ class Entry_u_boot_ucode(Entry_blob): def ObtainContents(self): # If the section does not need microcode, there is nothing to do - ucode_dest_entry = self.section.FindEntryType('u-boot-with-ucode-ptr') - ucode_dest_entry_spl = self.section.FindEntryType( - 'u-boot-spl-with-ucode-ptr') - if ((not ucode_dest_entry or not ucode_dest_entry.target_offset) and - (not ucode_dest_entry_spl or not ucode_dest_entry_spl.target_offset)): + found = False + for suffix in ['', '-spl', '-tpl']: + name = 'u-boot%s-with-ucode-ptr' % suffix + entry = self.section.FindEntryType(name) + if entry and entry.target_offset: + found = True + if not found: self.data = '' return True - # Get the microcode from the device tree entry. If it is not available # yet, return False so we will be called later. If the section simply # doesn't exist, then we may as well return True, since we are going to # get an error anyway. - fdt_entry = self.section.FindEntryType('u-boot-dtb-with-ucode') + for suffix in ['', '-spl', '-tpl']: + name = 'u-boot%s-dtb-with-ucode' % suffix + fdt_entry = self.section.FindEntryType(name) + if fdt_entry: + break if not fdt_entry: return True if not fdt_entry.ready: @@ -86,12 +91,9 @@ class Entry_u_boot_ucode(Entry_blob): return True # Write it out to a file - dtb_name = 'u-boot-ucode.bin' - fname = tools.GetOutputFilename(dtb_name) - with open(fname, 'wb') as fd: - fd.write(fdt_entry.ucode_data) + self._pathname = tools.GetOutputFilename('u-boot-ucode.bin') + tools.WriteFile(self._pathname, fdt_entry.ucode_data) - self._pathname = fname self.ReadBlobContents() return True diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py index c850b59..01f3513 100644 --- a/tools/binman/etype/u_boot_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_with_ucode_ptr.py @@ -74,13 +74,16 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob): # Get the microcode, either from u-boot-ucode or u-boot-dtb-with-ucode. # If we have left the microcode in the device tree, then it will be - # in the former. If we extracted the microcode from the device tree - # and collated it in one place, it will be in the latter. + # in the latter. If we extracted the microcode from the device tree + # and collated it in one place, it will be in the former. if ucode_entry.size: offset, size = ucode_entry.offset, ucode_entry.size else: dtb_entry = self.section.FindEntryType('u-boot-dtb-with-ucode') - if not dtb_entry or not dtb_entry.ready: + if not dtb_entry: + dtb_entry = self.section.FindEntryType( + 'u-boot-tpl-dtb-with-ucode') + if not dtb_entry: self.Raise('Cannot find microcode region u-boot-dtb-with-ucode') offset = dtb_entry.offset + dtb_entry.ucode_offset size = dtb_entry.ucode_size diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index c46a065..f8faef1 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -44,6 +44,7 @@ X86_START16_SPL_DATA = 'start16spl' X86_START16_TPL_DATA = 'start16tpl' U_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here' U_BOOT_SPL_NODTB_DATA = 'splnodtb with microcode pointer somewhere in here' +U_BOOT_TPL_NODTB_DATA = 'tplnodtb with microcode pointer somewhere in here' FSP_DATA = 'fsp' CMC_DATA = 'cmc' VBT_DATA = 'vbt' @@ -103,6 +104,8 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA) TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin', U_BOOT_SPL_NODTB_DATA) + TestFunctional._MakeInputFile('tpl/u-boot-tpl-nodtb.bin', + U_BOOT_TPL_NODTB_DATA) TestFunctional._MakeInputFile('fsp.bin', FSP_DATA) TestFunctional._MakeInputFile('cmc.bin', CMC_DATA) TestFunctional._MakeInputFile('vbt.bin', VBT_DATA) @@ -1644,6 +1647,22 @@ class TestFunctional(unittest.TestCase): m.update(16 * 'a') self.assertEqual(m.digest(), ''.join(hash_node.value)) + def testPackUBootTplMicrocode(self): + """Test that x86 microcode can be handled correctly in TPL + + We expect to see the following in the image, in order: + u-boot-tpl-nodtb.bin with a microcode pointer inserted at the correct + place + u-boot-tpl.dtb with the microcode removed + the microcode + """ + with open(self.TestFile('u_boot_ucode_ptr')) as fd: + TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) + first, pos_and_size = self._RunMicrocodeTest('93_x86_tpl_ucode.dts', + U_BOOT_TPL_NODTB_DATA) + self.assertEqual('tplnodtb with microc' + pos_and_size + + 'ter somewhere in here', first) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/93_x86_tpl_ucode.dts b/tools/binman/test/93_x86_tpl_ucode.dts new file mode 100644 index 0000000..d7ed9fc --- /dev/null +++ b/tools/binman/test/93_x86_tpl_ucode.dts @@ -0,0 +1,29 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + sort-by-offset; + end-at-4gb; + size = <0x200>; + u-boot-tpl-with-ucode-ptr { + }; + + u-boot-tpl-dtb-with-ucode { + }; + + u-boot-ucode { + }; + }; + + microcode { + update@0 { + data = <0x12345678 0x12345679>; + }; + update@1 { + data = <0xabcd0000 0x78235609>; + }; + }; +};