From 3b1c0b09c99bfd30355a6ba87a15e9d408a51109 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:41 -0600 Subject: [PATCH 01/61] patman: Drop binary parameter Since cros_subprocess use bytestrings now, this feature not needed. Drop it. Signed-off-by: Simon Glass --- tools/patman/cros_subprocess.py | 3 +-- tools/patman/tools.py | 15 +++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tools/patman/cros_subprocess.py b/tools/patman/cros_subprocess.py index 06be64cc2c..0f0d60dfb7 100644 --- a/tools/patman/cros_subprocess.py +++ b/tools/patman/cros_subprocess.py @@ -54,7 +54,7 @@ class Popen(subprocess.Popen): """ def __init__(self, args, stdin=None, stdout=PIPE_PTY, stderr=PIPE_PTY, - shell=False, cwd=None, env=None, binary=False, **kwargs): + shell=False, cwd=None, env=None, **kwargs): """Cut-down constructor Args: @@ -72,7 +72,6 @@ class Popen(subprocess.Popen): """ stdout_pty = None stderr_pty = None - self.binary = binary if stdout == PIPE_PTY: stdout_pty = pty.openpty() diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 0d4705db76..97441ca796 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -186,7 +186,7 @@ def PathHasFile(path_spec, fname): return True return False -def Run(name, *args, **kwargs): +def Run(name, *args): """Run a tool with some arguments This runs a 'tool', which is a program used by binman to process files and @@ -196,7 +196,6 @@ def Run(name, *args, **kwargs): Args: name: Command name to run args: Arguments to the tool - kwargs: Options to pass to command.run() Returns: CommandResult object @@ -206,8 +205,8 @@ def Run(name, *args, **kwargs): if tool_search_paths: env = dict(os.environ) env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH'] - return command.Run(name, *args, capture=True, - capture_stderr=True, env=env, **kwargs) + return command.Run(name, *args, capture=True, capture_stderr=True, + env=env) except: if env and not PathHasFile(env['PATH'], name): msg = "Please install tool '%s'" % name @@ -401,14 +400,14 @@ def Compress(indata, algo, with_header=True): fname = GetOutputFilename('%s.comp.tmp' % algo) WriteFile(fname, indata) if algo == 'lz4': - data = Run('lz4', '--no-frame-crc', '-c', fname, binary=True) + data = Run('lz4', '--no-frame-crc', '-c', fname) # cbfstool uses a very old version of lzma elif algo == 'lzma': outfname = GetOutputFilename('%s.comp.otmp' % algo) Run('lzma_alone', 'e', fname, outfname, '-lc1', '-lp0', '-pb0', '-d8') data = ReadFile(outfname) elif algo == 'gzip': - data = Run('gzip', '-c', fname, binary=True) + data = Run('gzip', '-c', fname) else: raise ValueError("Unknown algorithm '%s'" % algo) if with_header: @@ -441,13 +440,13 @@ def Decompress(indata, algo, with_header=True): with open(fname, 'wb') as fd: fd.write(indata) if algo == 'lz4': - data = Run('lz4', '-dc', fname, binary=True) + data = Run('lz4', '-dc', fname) elif algo == 'lzma': outfname = GetOutputFilename('%s.decomp.otmp' % algo) Run('lzma_alone', 'd', fname, outfname) data = ReadFile(outfname) elif algo == 'gzip': - data = Run('gzip', '-cd', fname, binary=True) + data = Run('gzip', '-cd', fname) else: raise ValueError("Unknown algorithm '%s'" % algo) return data From 6eace398072a62e74f10f412ffadfe51b7402395 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:42 -0600 Subject: [PATCH 02/61] patman: Update command.Run() to handle failure better At present tools are not expected to fail. If they do an exception is raised but there is no detail about what went wrong. This makes it hard to debug if something does actually go wrong. Fix this by outputting both stderr and stdout on failure. Signed-off-by: Simon Glass --- tools/patman/tools.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 97441ca796..0952681579 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -205,8 +205,14 @@ def Run(name, *args): if tool_search_paths: env = dict(os.environ) env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH'] - return command.Run(name, *args, capture=True, capture_stderr=True, - env=env) + all_args = (name,) + args + result = command.RunPipe([all_args], capture=True, capture_stderr=True, + env=env, raise_on_error=False) + if result.return_code: + raise Exception("Error %d running '%s': %s" % + (result.return_code,' '.join(all_args), + result.stderr)) + return result.stdout except: if env and not PathHasFile(env['PATH'], name): msg = "Please install tool '%s'" % name From b986b3bb192f772a7c81c69aafe59094df7d4b81 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:43 -0600 Subject: [PATCH 03/61] binman: Use cls instead of self for class methods It is more common to use the name 'cls' for the class object of a class method, to distinguish it from normal methods, which use 'self' Update the binman tests accordingly. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 54 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 0f3b70b3bb..acf361fa84 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -94,16 +94,16 @@ class TestFunctional(unittest.TestCase): the test/ diurectory. """ @classmethod - def setUpClass(self): + def setUpClass(cls): global entry import entry # Handle the case where argv[0] is 'python' - self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) - self._binman_pathname = os.path.join(self._binman_dir, 'binman') + cls._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) + cls._binman_pathname = os.path.join(cls._binman_dir, 'binman') # Create a temporary directory for input files - self._indir = tempfile.mkdtemp(prefix='binmant.') + cls._indir = tempfile.mkdtemp(prefix='binmant.') # Create some test files TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA) @@ -113,7 +113,7 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('blobfile', BLOB_DATA) TestFunctional._MakeInputFile('me.bin', ME_DATA) TestFunctional._MakeInputFile('vga.bin', VGA_DATA) - self._ResetDtbs() + cls._ResetDtbs() TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA) TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin', @@ -135,35 +135,35 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) # ELF file with a '_dt_ucode_base_size' symbol - with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd: + with open(cls.TestFile('u_boot_ucode_ptr'), 'rb') as fd: TestFunctional._MakeInputFile('u-boot', fd.read()) # Intel flash descriptor file - with open(self.TestFile('descriptor.bin'), 'rb') as fd: + with open(cls.TestFile('descriptor.bin'), 'rb') as fd: TestFunctional._MakeInputFile('descriptor.bin', fd.read()) - shutil.copytree(self.TestFile('files'), - os.path.join(self._indir, 'files')) + shutil.copytree(cls.TestFile('files'), + os.path.join(cls._indir, 'files')) TestFunctional._MakeInputFile('compress', COMPRESS_DATA) # Travis-CI may have an old lz4 - self.have_lz4 = True + cls.have_lz4 = True try: tools.Run('lz4', '--no-frame-crc', '-c', - os.path.join(self._indir, 'u-boot.bin')) + os.path.join(cls._indir, 'u-boot.bin')) except: - self.have_lz4 = False + cls.have_lz4 = False @classmethod - def tearDownClass(self): + def tearDownClass(cls): """Remove the temporary input directory and its contents""" - if self.preserve_indir: - print('Preserving input dir: %s' % self._indir) + if cls.preserve_indir: + print('Preserving input dir: %s' % cls._indir) else: - if self._indir: - shutil.rmtree(self._indir) - self._indir = None + if cls._indir: + shutil.rmtree(cls._indir) + cls._indir = None @classmethod def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False, @@ -226,7 +226,7 @@ class TestFunctional(unittest.TestCase): return tmpdir, updated_fname @classmethod - def _ResetDtbs(self): + def _ResetDtbs(cls): TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA) TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA) TestFunctional._MakeInputFile('tpl/u-boot-tpl.dtb', U_BOOT_TPL_DTB_DATA) @@ -432,7 +432,7 @@ class TestFunctional(unittest.TestCase): return self._DoReadFileDtb(fname, use_real_dtb)[0] @classmethod - def _MakeInputFile(self, fname, contents): + def _MakeInputFile(cls, fname, contents): """Create a new test input file, creating directories as needed Args: @@ -441,7 +441,7 @@ class TestFunctional(unittest.TestCase): Returns: Full pathname of file created """ - pathname = os.path.join(self._indir, fname) + pathname = os.path.join(cls._indir, fname) dirname = os.path.dirname(pathname) if dirname and not os.path.exists(dirname): os.makedirs(dirname) @@ -450,7 +450,7 @@ class TestFunctional(unittest.TestCase): return pathname @classmethod - def _MakeInputDir(self, dirname): + def _MakeInputDir(cls, dirname): """Create a new test input directory, creating directories as needed Args: @@ -459,24 +459,24 @@ class TestFunctional(unittest.TestCase): Returns: Full pathname of directory created """ - pathname = os.path.join(self._indir, dirname) + pathname = os.path.join(cls._indir, dirname) if not os.path.exists(pathname): os.makedirs(pathname) return pathname @classmethod - def _SetupSplElf(self, src_fname='bss_data'): + def _SetupSplElf(cls, src_fname='bss_data'): """Set up an ELF file with a '_dt_ucode_base_size' symbol Args: Filename of ELF file to use as SPL """ - with open(self.TestFile(src_fname), 'rb') as fd: + with open(cls.TestFile(src_fname), 'rb') as fd: TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) @classmethod - def TestFile(self, fname): - return os.path.join(self._binman_dir, 'test', fname) + def TestFile(cls, fname): + return os.path.join(cls._binman_dir, 'test', fname) def AssertInList(self, grep_list, target): """Assert that at least one of a list of things is in a target From 8dbb7444ebaa499b753269c88cdd76f12f0fa875 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:44 -0600 Subject: [PATCH 04/61] binman: Allow use of help and entry-docs without libfdt At present if libfdt is not available binman can't do anything much. Improve the situation a little. Ideally there should be a test to cover this, but I'm not quite sure how to fake this. Signed-off-by: Simon Glass (fixed up missing ReadChildData() enty test) --- tools/binman/control.py | 12 ++++++++++-- tools/binman/entry.py | 5 ++++- tools/binman/entry_test.py | 5 +++++ tools/binman/etype/blob.py | 1 - tools/binman/etype/blob_dtb.py | 6 ++++-- tools/binman/etype/cbfs.py | 5 ++++- tools/binman/etype/fdtmap.py | 13 +++++++++---- tools/binman/etype/files.py | 5 ++++- tools/binman/etype/u_boot_dtb_with_ucode.py | 5 ++++- 9 files changed, 44 insertions(+), 13 deletions(-) diff --git a/tools/binman/control.py b/tools/binman/control.py index cb51bc2dd4..8268eda37e 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -15,8 +15,6 @@ import tools import cbfs_util import command import elf -from image import Image -import state import tout # List of images we plan to create @@ -113,6 +111,9 @@ def ReadEntry(image_fname, entry_path, decomp=True): Returns: data extracted from the entry """ + global Image + from image import Image + image = Image.FromFile(image_fname) entry = image.FindEntryPath(entry_path) return entry.ReadData(decomp) @@ -459,6 +460,9 @@ def Binman(args): Args: args: Command line arguments Namespace object """ + global Image + global state + if args.full_help: pager = os.getenv('PAGER') if not pager: @@ -468,6 +472,10 @@ def Binman(args): command.Run(pager, fname) return 0 + # Put these here so that we can import this module without libfdt + from image import Image + import state + if args.cmd in ['ls', 'extract', 'replace']: try: tout.Init(args.verbosity) diff --git a/tools/binman/entry.py b/tools/binman/entry.py index fe8e1dd8a5..409c0dca93 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -21,7 +21,6 @@ import os import sys import fdt_util -import state import tools from tools import ToHex, ToHexSize import tout @@ -71,6 +70,10 @@ class Entry(object): orig_size: Original size value read from node """ def __init__(self, section, etype, node, name_prefix=''): + # Put this here to allow entry-docs and help to work without libfdt + global state + import state + self.section = section self.etype = etype self._node = node diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py index cc1fb795da..13f5864516 100644 --- a/tools/binman/entry_test.py +++ b/tools/binman/entry_test.py @@ -97,6 +97,11 @@ class TestEntry(unittest.TestCase): base = entry.Entry.Create(None, self.GetNode(), 'blob-dtb') self.assertTrue(base.WriteChildData(base)) + def testReadChildData(self): + """Test the ReadChildData() method of the base class""" + base = entry.Entry.Create(None, self.GetNode(), 'blob-dtb') + self.assertIsNone(base.ReadChildData(base)) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index d15d0789e5..d34c7b51bf 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -7,7 +7,6 @@ from entry import Entry import fdt_util -import state import tools import tout diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py index 5b559967d7..b2afa064c1 100644 --- a/tools/binman/etype/blob_dtb.py +++ b/tools/binman/etype/blob_dtb.py @@ -5,8 +5,6 @@ # Entry-type module for U-Boot device tree files # -import state - from entry import Entry from blob import Entry_blob @@ -18,6 +16,10 @@ class Entry_blob_dtb(Entry_blob): 'state' module. """ def __init__(self, section, etype, node): + # Put this here to allow entry-docs and help to work without libfdt + global state + import state + Entry_blob.__init__(self, section, etype, node) def ObtainContents(self): diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 28a9c81a8a..35b78370b2 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -11,7 +11,6 @@ import cbfs_util from cbfs_util import CbfsWriter from entry import Entry import fdt_util -import state class Entry_cbfs(Entry): """Entry containing a Coreboot Filesystem (CBFS) @@ -164,6 +163,10 @@ class Entry_cbfs(Entry): both of size 1MB. """ def __init__(self, section, etype, node): + # Put this here to allow entry-docs and help to work without libfdt + global state + import state + Entry.__init__(self, section, etype, node) self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86') self._cbfs_entries = OrderedDict() diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py index b1810b9ddb..5dc08b8289 100644 --- a/tools/binman/etype/fdtmap.py +++ b/tools/binman/etype/fdtmap.py @@ -8,11 +8,7 @@ This handles putting an FDT into the image with just the information about the image. """ -import libfdt - from entry import Entry -from fdt import Fdt -import state import tools import tout @@ -80,6 +76,15 @@ class Entry_fdtmap(Entry): added as necessary. See the binman README. """ def __init__(self, section, etype, node): + # Put these here to allow entry-docs and help to work without libfdt + global libfdt + global state + global Fdt + + import libfdt + import state + from fdt import Fdt + Entry.__init__(self, section, etype, node) def _GetFdtmap(self): diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py index 0068b305f7..3473a2b1ef 100644 --- a/tools/binman/etype/files.py +++ b/tools/binman/etype/files.py @@ -11,7 +11,6 @@ import os from section import Entry_section import fdt_util -import state import tools @@ -29,6 +28,10 @@ class Entry_files(Entry_section): at run-time so you can obtain the file positions. """ def __init__(self, section, etype, node): + # Put this here to allow entry-docs and help to work without libfdt + global state + import state + Entry_section.__init__(self, section, etype, node) self._pattern = fdt_util.GetString(self._node, 'pattern') if not self._pattern: diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py index cb6c3730d7..6efd24a9b3 100644 --- a/tools/binman/etype/u_boot_dtb_with_ucode.py +++ b/tools/binman/etype/u_boot_dtb_with_ucode.py @@ -7,7 +7,6 @@ from entry import Entry from blob_dtb import Entry_blob_dtb -import state import tools class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): @@ -25,6 +24,10 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): it available to u_boot_ucode. """ def __init__(self, section, etype, node): + # Put this here to allow entry-docs and help to work without libfdt + global state + import state + Entry_blob_dtb.__init__(self, section, etype, node) self.ucode_data = b'' self.collate = False From 9d44a7e6c67be9661e6d3dff3a2d5da31dd06cbc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:45 -0600 Subject: [PATCH 05/61] binman: Drop .note section from ELF Recent versions of binutils add a '.note.gnu.property' into the ELF file. This is not required and interferes with the expected output. Drop it. Also fix testMakeElf() to use a different file for input and output. Signed-off-by: Simon Glass --- tools/binman/elf.py | 3 +++ tools/binman/elf_test.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/binman/elf.py b/tools/binman/elf.py index af40024cea..c7ef74ce7d 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -221,6 +221,9 @@ SECTIONS .empty : { *(.empty) } :empty + /DISCARD/ : { + *(.note.gnu.property) + } .note : { *(.comment) } :note diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 416e43baf0..cc6e9c5128 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -148,7 +148,7 @@ class TestElf(unittest.TestCase): expected_text = b'1234' expected_data = b'wxyz' elf_fname = os.path.join(outdir, 'elf') - bin_fname = os.path.join(outdir, 'elf') + bin_fname = os.path.join(outdir, 'bin') # Make an Elf file and then convert it to a fkat binary file. This # should produce the original data. From 39c8e47d2ee38975b9377ee0049d2f88efc3edba Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:46 -0600 Subject: [PATCH 06/61] binman: Handle hidden symbols in ELF files Some versions of binutils generate hidden symbols which are currently not parsed by binman. Correct this. Signed-off-by: Simon Glass --- tools/binman/elf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/elf.py b/tools/binman/elf.py index c7ef74ce7d..66cfe796a2 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -72,7 +72,7 @@ def GetSymbols(fname, patterns): parts = rest[7:].split() section, size = parts[:2] if len(parts) > 2: - name = parts[2] + name = parts[2] if parts[2] != '.hidden' else parts[3] syms[name] = Symbol(section, int(value, 16), int(size,16), flags[1] == 'w') From 3da9ce8dd44399dfca4b0639101f5154dbbaa93f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:47 -0600 Subject: [PATCH 07/61] binman: Correct use of 'replace' in IFWI tests At present the Intel IFWI entry uses 'replace' without the 'ifwi-' prefix. This is a fairly generic name which might conflict with the main Entry base class at some point, if more features are added. Add a prefix. Signed-off-by: Simon Glass --- tools/binman/README.entries | 6 ++++++ tools/binman/etype/intel_ifwi.py | 8 +++++++- tools/binman/test/111_x86-rom-ifwi.dts | 2 +- tools/binman/test/112_x86-rom-ifwi-nodesc.dts | 2 +- tools/binman/test/113_x86-rom-ifwi-nodata.dts | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 0f0e367d02..11c55fd8c8 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -432,6 +432,12 @@ The contents of the IFWI are specified by the subnodes of the IFWI node. Each subnode describes an entry which is placed into the IFWFI with a given sub-partition (and optional entry name). +Properties for subnodes: + ifwi-subpart - sub-parition to put this entry into, e.g. "IBBP" + ifwi-entry - entry name t use, e.g. "IBBL" + ifwi-replace - if present, indicates that the item should be replaced + in the IFWI. Otherwise it is added. + See README.x86 for information about x86 binary blobs. diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index 9cbdf3698a..f3745f7a8c 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -36,6 +36,12 @@ class Entry_intel_ifwi(Entry_blob): Each subnode describes an entry which is placed into the IFWFI with a given sub-partition (and optional entry name). + Properties for subnodes: + ifwi-subpart - sub-parition to put this entry into, e.g. "IBBP" + ifwi-entry - entry name t use, e.g. "IBBL" + ifwi-replace - if present, indicates that the item should be replaced + in the IFWI. Otherwise it is added. + See README.x86 for information about x86 binary blobs. """ def __init__(self, section, etype, node): @@ -95,7 +101,7 @@ class Entry_intel_ifwi(Entry_blob): for node in self._node.subnodes: entry = Entry.Create(self.section, node) entry.ReadNode() - entry._ifwi_replace = fdt_util.GetBool(node, 'replace') + entry._ifwi_replace = fdt_util.GetBool(node, 'ifwi-replace') entry._ifwi_subpart = fdt_util.GetString(node, 'ifwi-subpart') entry._ifwi_entry_name = fdt_util.GetString(node, 'ifwi-entry') self._ifwi_entries[entry._ifwi_subpart] = entry diff --git a/tools/binman/test/111_x86-rom-ifwi.dts b/tools/binman/test/111_x86-rom-ifwi.dts index 63b5972cc8..c0ba4f2ea4 100644 --- a/tools/binman/test/111_x86-rom-ifwi.dts +++ b/tools/binman/test/111_x86-rom-ifwi.dts @@ -20,7 +20,7 @@ convert-fit; u-boot-tpl { - replace; + ifwi-replace; ifwi-subpart = "IBBP"; ifwi-entry = "IBBL"; }; diff --git a/tools/binman/test/112_x86-rom-ifwi-nodesc.dts b/tools/binman/test/112_x86-rom-ifwi-nodesc.dts index 21ec4654ff..0874440ab5 100644 --- a/tools/binman/test/112_x86-rom-ifwi-nodesc.dts +++ b/tools/binman/test/112_x86-rom-ifwi-nodesc.dts @@ -19,7 +19,7 @@ filename = "ifwi.bin"; u-boot-tpl { - replace; + ifwi-replace; ifwi-subpart = "IBBP"; ifwi-entry = "IBBL"; }; diff --git a/tools/binman/test/113_x86-rom-ifwi-nodata.dts b/tools/binman/test/113_x86-rom-ifwi-nodata.dts index 62486fd990..82a4bc8cdd 100644 --- a/tools/binman/test/113_x86-rom-ifwi-nodata.dts +++ b/tools/binman/test/113_x86-rom-ifwi-nodata.dts @@ -20,7 +20,7 @@ _testing { return-unknown-contents; - replace; + ifwi-replace; ifwi-subpart = "IBBP"; ifwi-entry = "IBBL"; }; From 2250ee6ee681564115d82f9f9c63497ccfb5fdd7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:48 -0600 Subject: [PATCH 08/61] binman: Add support for an x86 'reset' section At present binman has a single entry type for the 16-bit code code needed to start up an x86 processor. This entry is intended to include both the reset vector itself as well as the code to move to 32-bit mode. However this is not very flexible since in some cases other data needs to be included at the top of the SPI flash, in between these two pieces. For example Intel requires that a FIT (Firmware Image Table) pointer be placed 0x40 bytes before the end of the ROM. To deal with this, add a new reset entry for just the reset vector. A subsequent change will adjust the existing 'start16' entry. Signed-off-by: Simon Glass --- tools/binman/README.entries | 48 +++++++++++++++++++++++ tools/binman/etype/x86_reset16.py | 29 ++++++++++++++ tools/binman/etype/x86_reset16_spl.py | 29 ++++++++++++++ tools/binman/etype/x86_reset16_tpl.py | 29 ++++++++++++++ tools/binman/ftest.py | 30 +++++++++++++- tools/binman/test/144_x86_reset16.dts | 13 ++++++ tools/binman/test/145_x86_reset16_spl.dts | 13 ++++++ tools/binman/test/146_x86_reset16_tpl.dts | 13 ++++++ 8 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 tools/binman/etype/x86_reset16.py create mode 100644 tools/binman/etype/x86_reset16_spl.py create mode 100644 tools/binman/etype/x86_reset16_tpl.py create mode 100644 tools/binman/test/144_x86_reset16.dts create mode 100644 tools/binman/test/145_x86_reset16_spl.dts create mode 100644 tools/binman/test/146_x86_reset16_tpl.dts diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 11c55fd8c8..55e3fa0dcc 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -937,6 +937,54 @@ and kernel are genuine. +Entry: x86-reset16: x86 16-bit reset code for U-Boot +---------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of u-boot-x86-reset16.bin (default + 'u-boot-x86-reset16.bin') + +x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code +must be placed at a particular address. This entry holds that code. It is +typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible +for jumping to the x86-start16 code, which continues execution. + +For 64-bit U-Boot, the 'x86_reset16_spl' entry type is used instead. + + + +Entry: x86-reset16-spl: x86 16-bit reset code for U-Boot +-------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of u-boot-x86-reset16.bin (default + 'u-boot-x86-reset16.bin') + +x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code +must be placed at a particular address. This entry holds that code. It is +typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible +for jumping to the x86-start16 code, which continues execution. + +For 32-bit U-Boot, the 'x86_reset_spl' entry type is used instead. + + + +Entry: x86-reset16-tpl: x86 16-bit reset code for U-Boot +-------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of u-boot-x86-reset16.bin (default + 'u-boot-x86-reset16.bin') + +x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code +must be placed at a particular address. This entry holds that code. It is +typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible +for jumping to the x86-start16 code, which continues execution. + +For 32-bit U-Boot, the 'x86_reset_tpl' entry type is used instead. + + + Entry: x86-start16: x86 16-bit start-up code for U-Boot ------------------------------------------------------- diff --git a/tools/binman/etype/x86_reset16.py b/tools/binman/etype/x86_reset16.py new file mode 100644 index 0000000000..54eb814ea3 --- /dev/null +++ b/tools/binman/etype/x86_reset16.py @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for the 16-bit x86 reset code for U-Boot +# + +from entry import Entry +from blob import Entry_blob + +class Entry_x86_reset16(Entry_blob): + """x86 16-bit reset code for U-Boot + + Properties / Entry arguments: + - filename: Filename of u-boot-x86-reset16.bin (default + 'u-boot-x86-reset16.bin') + + x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code + must be placed at a particular address. This entry holds that code. It is + typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible + for jumping to the x86-start16 code, which continues execution. + + For 64-bit U-Boot, the 'x86_reset16_spl' entry type is used instead. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'u-boot-x86-reset16.bin' diff --git a/tools/binman/etype/x86_reset16_spl.py b/tools/binman/etype/x86_reset16_spl.py new file mode 100644 index 0000000000..699a0c6bcb --- /dev/null +++ b/tools/binman/etype/x86_reset16_spl.py @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for the 16-bit x86 reset code for U-Boot +# + +from entry import Entry +from blob import Entry_blob + +class Entry_x86_reset16_spl(Entry_blob): + """x86 16-bit reset code for U-Boot + + Properties / Entry arguments: + - filename: Filename of u-boot-x86-reset16.bin (default + 'u-boot-x86-reset16.bin') + + x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code + must be placed at a particular address. This entry holds that code. It is + typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible + for jumping to the x86-start16 code, which continues execution. + + For 32-bit U-Boot, the 'x86_reset_spl' entry type is used instead. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'spl/u-boot-x86-reset16-spl.bin' diff --git a/tools/binman/etype/x86_reset16_tpl.py b/tools/binman/etype/x86_reset16_tpl.py new file mode 100644 index 0000000000..4eedb8d601 --- /dev/null +++ b/tools/binman/etype/x86_reset16_tpl.py @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for the 16-bit x86 reset code for U-Boot +# + +from entry import Entry +from blob import Entry_blob + +class Entry_x86_reset16_tpl(Entry_blob): + """x86 16-bit reset code for U-Boot + + Properties / Entry arguments: + - filename: Filename of u-boot-x86-reset16.bin (default + 'u-boot-x86-reset16.bin') + + x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code + must be placed at a particular address. This entry holds that code. It is + typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible + for jumping to the x86-start16 code, which continues execution. + + For 32-bit U-Boot, the 'x86_reset_tpl' entry type is used instead. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'tpl/u-boot-x86-reset16-tpl.bin' diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index acf361fa84..77445814a7 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -49,6 +49,9 @@ U_BOOT_TPL_DTB_DATA = b'tpldtb' X86_START16_DATA = b'start16' X86_START16_SPL_DATA = b'start16spl' X86_START16_TPL_DATA = b'start16tpl' +X86_RESET16_DATA = b'reset16' +X86_RESET16_SPL_DATA = b'reset16spl' +X86_RESET16_TPL_DATA = b'reset16tpl' PPC_MPC85XX_BR_DATA = b'ppcmpc85xxbr' U_BOOT_NODTB_DATA = b'nodtb with microcode pointer somewhere in here' U_BOOT_SPL_NODTB_DATA = b'splnodtb with microcode pointer somewhere in here' @@ -114,12 +117,22 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('me.bin', ME_DATA) TestFunctional._MakeInputFile('vga.bin', VGA_DATA) cls._ResetDtbs() - TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) + TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA) + + TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin', X86_START16_SPL_DATA) TestFunctional._MakeInputFile('tpl/u-boot-x86-16bit-tpl.bin', X86_START16_TPL_DATA) + + TestFunctional._MakeInputFile('u-boot-x86-reset16.bin', + X86_RESET16_DATA) + TestFunctional._MakeInputFile('spl/u-boot-x86-reset16-spl.bin', + X86_RESET16_SPL_DATA) + TestFunctional._MakeInputFile('tpl/u-boot-x86-reset16-tpl.bin', + X86_RESET16_TPL_DATA) + TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA) TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin', U_BOOT_SPL_NODTB_DATA) @@ -3236,6 +3249,21 @@ class TestFunctional(unittest.TestCase): self.assertIn('Must specify exactly one entry path to write with -f', str(e.exception)) + def testPackReset16(self): + """Test that an image with an x86 reset16 region can be created""" + data = self._DoReadFile('144_x86_reset16.dts') + self.assertEqual(X86_RESET16_DATA, data[:len(X86_RESET16_DATA)]) + + def testPackReset16Spl(self): + """Test that an image with an x86 reset16-spl region can be created""" + data = self._DoReadFile('145_x86_reset16_spl.dts') + self.assertEqual(X86_RESET16_SPL_DATA, data[:len(X86_RESET16_SPL_DATA)]) + + def testPackReset16Tpl(self): + """Test that an image with an x86 reset16-tpl region can be created""" + data = self._DoReadFile('146_x86_reset16_tpl.dts') + self.assertEqual(X86_RESET16_TPL_DATA, data[:len(X86_RESET16_TPL_DATA)]) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/144_x86_reset16.dts b/tools/binman/test/144_x86_reset16.dts new file mode 100644 index 0000000000..ba90333b27 --- /dev/null +++ b/tools/binman/test/144_x86_reset16.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + x86-reset16 { + }; + }; +}; diff --git a/tools/binman/test/145_x86_reset16_spl.dts b/tools/binman/test/145_x86_reset16_spl.dts new file mode 100644 index 0000000000..cc8d97a7e6 --- /dev/null +++ b/tools/binman/test/145_x86_reset16_spl.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + x86-reset16-spl { + }; + }; +}; diff --git a/tools/binman/test/146_x86_reset16_tpl.dts b/tools/binman/test/146_x86_reset16_tpl.dts new file mode 100644 index 0000000000..041b16f3de --- /dev/null +++ b/tools/binman/test/146_x86_reset16_tpl.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + x86-reset16-tpl { + }; + }; +}; From 5e239183f62cc3740bf775e5204591cea5bf02ae Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:49 -0600 Subject: [PATCH 09/61] binman: x86: Separate out 16-bit reset and init code At present these two sections of code are linked together into a single 2KB chunk in a single file. Some Intel SoCs like to have a FIT (Firmware Interface Table) in the ROM and the pointer for this needs to go at 0xffffffc0 which is in the middle of these two sections. Make use of the new 'reset' entry and change the existing 16-bit entry to include just the 16-bit data. Signed-off-by: Simon Glass --- Makefile | 10 ++++-- arch/x86/dts/u-boot.dtsi | 9 ++++++ scripts/Makefile.spl | 22 +++++++++---- tools/binman/README.entries | 46 +++++++++++++++------------ tools/binman/etype/x86_start16.py | 15 +++++---- tools/binman/etype/x86_start16_spl.py | 19 +++++------ tools/binman/etype/x86_start16_tpl.py | 18 ++++++----- tools/binman/ftest.py | 6 ++-- 8 files changed, 88 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 6fda3268e7..66ba43601f 100644 --- a/Makefile +++ b/Makefile @@ -1458,14 +1458,18 @@ quiet_cmd_ldr = LD $@ cmd_ldr = $(LD) $(LDFLAGS_$(@F)) \ $(filter-out FORCE,$^) -o $@ -u-boot.rom: u-boot-x86-16bit.bin u-boot.bin \ +u-boot.rom: u-boot-x86-start16.bin u-boot-x86-reset16.bin u-boot.bin \ $(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \ $(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin) \ $(if $(CONFIG_HAVE_REFCODE),refcode.bin) FORCE $(call if_changed,binman) -OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec -u-boot-x86-16bit.bin: u-boot FORCE +OBJCOPYFLAGS_u-boot-x86-start16.bin := -O binary -j .start16 +u-boot-x86-start16.bin: u-boot FORCE + $(call if_changed,objcopy) + +OBJCOPYFLAGS_u-boot-x86-reset16.bin := -O binary -j .resetvec +u-boot-x86-reset16.bin: u-boot FORCE $(call if_changed,objcopy) endif diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi index daeb168b65..0e87b88e10 100644 --- a/arch/x86/dts/u-boot.dtsi +++ b/arch/x86/dts/u-boot.dtsi @@ -120,14 +120,23 @@ x86-start16-tpl { offset = ; }; + x86-reset16-tpl { + offset = ; + }; #elif defined(CONFIG_SPL) x86-start16-spl { offset = ; }; + x86-reset16-spl { + offset = ; + }; #else x86-start16 { offset = ; }; + x86-reset16 { + offset = ; + }; #endif }; #endif diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 7af6b120b6..0f3d89b215 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -229,9 +229,11 @@ ALL-y += $(obj)/boot.bin endif ifdef CONFIG_TPL_BUILD -ALL-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-tpl.bin +ALL-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-tpl.bin \ + $(obj)/u-boot-x86-reset16-tpl.bin else -ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-spl.bin +ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-spl.bin \ + $(obj)/u-boot-x86-reset16-spl.bin endif ALL-$(CONFIG_ARCH_ZYNQ) += $(obj)/boot.bin @@ -337,12 +339,20 @@ OBJCOPYFLAGS_$(SPL_BIN)-nodtb.bin = $(SPL_OBJCFLAGS) -O binary \ $(obj)/$(SPL_BIN)-nodtb.bin: $(obj)/$(SPL_BIN) FORCE $(call if_changed,objcopy) -OBJCOPYFLAGS_u-boot-x86-16bit-spl.bin := -O binary -j .start16 -j .resetvec -$(obj)/u-boot-x86-16bit-spl.bin: $(obj)/u-boot-spl FORCE +OBJCOPYFLAGS_u-boot-x86-start16-spl.bin := -O binary -j .start16 +$(obj)/u-boot-x86-start16-spl.bin: $(obj)/u-boot-spl FORCE $(call if_changed,objcopy) -OBJCOPYFLAGS_u-boot-x86-16bit-tpl.bin := -O binary -j .start16 -j .resetvec -$(obj)/u-boot-x86-16bit-tpl.bin: $(obj)/u-boot-tpl FORCE +OBJCOPYFLAGS_u-boot-x86-start16-tpl.bin := -O binary -j .start16 +$(obj)/u-boot-x86-start16-tpl.bin: $(obj)/u-boot-tpl FORCE + $(call if_changed,objcopy) + +OBJCOPYFLAGS_u-boot-x86-reset16-spl.bin := -O binary -j .resetvec +$(obj)/u-boot-x86-reset16-spl.bin: $(obj)/u-boot-spl FORCE + $(call if_changed,objcopy) + +OBJCOPYFLAGS_u-boot-x86-reset16-tpl.bin := -O binary -j .resetvec +$(obj)/u-boot-x86-reset16-tpl.bin: $(obj)/u-boot-tpl FORCE $(call if_changed,objcopy) LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL) diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 55e3fa0dcc..d17b3cb078 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -989,14 +989,15 @@ Entry: x86-start16: x86 16-bit start-up code for U-Boot ------------------------------------------------------- Properties / Entry arguments: - - filename: Filename of u-boot-x86-16bit.bin (default - 'u-boot-x86-16bit.bin') + - filename: Filename of u-boot-x86-start16.bin (default + 'u-boot-x86-start16.bin') x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code -must be placed at a particular address. This entry holds that code. It is -typically placed at offset CONFIG_SYS_X86_START16. The code is responsible -for changing to 32-bit mode and jumping to U-Boot's entry point, which -requires 32-bit mode (for 32-bit U-Boot). +must be placed in the top 64KB of the ROM. The reset code jumps to it. This +entry holds that code. It is typically placed at offset +CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode +and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit +U-Boot). For 64-bit U-Boot, the 'x86_start16_spl' entry type is used instead. @@ -1006,16 +1007,17 @@ Entry: x86-start16-spl: x86 16-bit start-up code for SPL -------------------------------------------------------- Properties / Entry arguments: - - filename: Filename of spl/u-boot-x86-16bit-spl.bin (default - 'spl/u-boot-x86-16bit-spl.bin') + - filename: Filename of spl/u-boot-x86-start16-spl.bin (default + 'spl/u-boot-x86-start16-spl.bin') -x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code -must be placed at a particular address. This entry holds that code. It is -typically placed at offset CONFIG_SYS_X86_START16. The code is responsible -for changing to 32-bit mode and starting SPL, which in turn changes to -64-bit mode and jumps to U-Boot (for 64-bit U-Boot). +x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code +must be placed in the top 64KB of the ROM. The reset code jumps to it. This +entry holds that code. It is typically placed at offset +CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode +and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit +U-Boot). -For 32-bit U-Boot, the 'x86_start16' entry type is used instead. +For 32-bit U-Boot, the 'x86-start16' entry type is used instead. @@ -1023,15 +1025,17 @@ Entry: x86-start16-tpl: x86 16-bit start-up code for TPL -------------------------------------------------------- Properties / Entry arguments: - - filename: Filename of tpl/u-boot-x86-16bit-tpl.bin (default - 'tpl/u-boot-x86-16bit-tpl.bin') + - filename: Filename of tpl/u-boot-x86-start16-tpl.bin (default + 'tpl/u-boot-x86-start16-tpl.bin') -x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code -must be placed at a particular address. This entry holds that code. It is -typically placed at offset CONFIG_SYS_X86_START16. The code is responsible -for changing to 32-bit mode and starting TPL, which in turn jumps to SPL. +x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code +must be placed in the top 64KB of the ROM. The reset code jumps to it. This +entry holds that code. It is typically placed at offset +CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode +and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit +U-Boot). -If TPL is not being used, the 'x86_start16_spl or 'x86_start16' entry types +If TPL is not being used, the 'x86-start16-spl or 'x86-start16' entry types may be used instead. diff --git a/tools/binman/etype/x86_start16.py b/tools/binman/etype/x86_start16.py index 7d32ecd321..6736b692d5 100644 --- a/tools/binman/etype/x86_start16.py +++ b/tools/binman/etype/x86_start16.py @@ -12,14 +12,15 @@ class Entry_x86_start16(Entry_blob): """x86 16-bit start-up code for U-Boot Properties / Entry arguments: - - filename: Filename of u-boot-x86-16bit.bin (default - 'u-boot-x86-16bit.bin') + - filename: Filename of u-boot-x86-start16.bin (default + 'u-boot-x86-start16.bin') x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code - must be placed at a particular address. This entry holds that code. It is - typically placed at offset CONFIG_SYS_X86_START16. The code is responsible - for changing to 32-bit mode and jumping to U-Boot's entry point, which - requires 32-bit mode (for 32-bit U-Boot). + must be placed in the top 64KB of the ROM. The reset code jumps to it. This + entry holds that code. It is typically placed at offset + CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode + and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit + U-Boot). For 64-bit U-Boot, the 'x86_start16_spl' entry type is used instead. """ @@ -27,4 +28,4 @@ class Entry_x86_start16(Entry_blob): Entry_blob.__init__(self, section, etype, node) def GetDefaultFilename(self): - return 'u-boot-x86-16bit.bin' + return 'u-boot-x86-start16.bin' diff --git a/tools/binman/etype/x86_start16_spl.py b/tools/binman/etype/x86_start16_spl.py index d85909e7ae..c8c70639de 100644 --- a/tools/binman/etype/x86_start16_spl.py +++ b/tools/binman/etype/x86_start16_spl.py @@ -12,19 +12,20 @@ class Entry_x86_start16_spl(Entry_blob): """x86 16-bit start-up code for SPL Properties / Entry arguments: - - filename: Filename of spl/u-boot-x86-16bit-spl.bin (default - 'spl/u-boot-x86-16bit-spl.bin') + - filename: Filename of spl/u-boot-x86-start16-spl.bin (default + 'spl/u-boot-x86-start16-spl.bin') - x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code - must be placed at a particular address. This entry holds that code. It is - typically placed at offset CONFIG_SYS_X86_START16. The code is responsible - for changing to 32-bit mode and starting SPL, which in turn changes to - 64-bit mode and jumps to U-Boot (for 64-bit U-Boot). + x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code + must be placed in the top 64KB of the ROM. The reset code jumps to it. This + entry holds that code. It is typically placed at offset + CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode + and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit + U-Boot). - For 32-bit U-Boot, the 'x86_start16' entry type is used instead. + For 32-bit U-Boot, the 'x86-start16' entry type is used instead. """ def __init__(self, section, etype, node): Entry_blob.__init__(self, section, etype, node) def GetDefaultFilename(self): - return 'spl/u-boot-x86-16bit-spl.bin' + return 'spl/u-boot-x86-start16-spl.bin' diff --git a/tools/binman/etype/x86_start16_tpl.py b/tools/binman/etype/x86_start16_tpl.py index 46ce169ae0..5261a8adf0 100644 --- a/tools/binman/etype/x86_start16_tpl.py +++ b/tools/binman/etype/x86_start16_tpl.py @@ -12,19 +12,21 @@ class Entry_x86_start16_tpl(Entry_blob): """x86 16-bit start-up code for TPL Properties / Entry arguments: - - filename: Filename of tpl/u-boot-x86-16bit-tpl.bin (default - 'tpl/u-boot-x86-16bit-tpl.bin') + - filename: Filename of tpl/u-boot-x86-start16-tpl.bin (default + 'tpl/u-boot-x86-start16-tpl.bin') - x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code - must be placed at a particular address. This entry holds that code. It is - typically placed at offset CONFIG_SYS_X86_START16. The code is responsible - for changing to 32-bit mode and starting TPL, which in turn jumps to SPL. + x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code + must be placed in the top 64KB of the ROM. The reset code jumps to it. This + entry holds that code. It is typically placed at offset + CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode + and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit + U-Boot). - If TPL is not being used, the 'x86_start16_spl or 'x86_start16' entry types + If TPL is not being used, the 'x86-start16-spl or 'x86-start16' entry types may be used instead. """ def __init__(self, section, etype, node): Entry_blob.__init__(self, section, etype, node) def GetDefaultFilename(self): - return 'tpl/u-boot-x86-16bit-tpl.bin' + return 'tpl/u-boot-x86-start16-tpl.bin' diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 77445814a7..04127faa6f 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -120,10 +120,10 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA) - TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) - TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin', + TestFunctional._MakeInputFile('u-boot-x86-start16.bin', X86_START16_DATA) + TestFunctional._MakeInputFile('spl/u-boot-x86-start16-spl.bin', X86_START16_SPL_DATA) - TestFunctional._MakeInputFile('tpl/u-boot-x86-16bit-tpl.bin', + TestFunctional._MakeInputFile('tpl/u-boot-x86-start16-tpl.bin', X86_START16_TPL_DATA) TestFunctional._MakeInputFile('u-boot-x86-reset16.bin', From 5af1207ec96e101e893605c0074205472f794982 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:50 -0600 Subject: [PATCH 10/61] binman: Add support for Intel FIT A Firmware Image Table (FIT) is a data structure defined by Intel which contains information about various things needed by the SoC, such as microcode. Add support for this entry as well as the pointer to it. The contents of FIT are fixed at present. Future work is needed to support adding microcode, etc. Signed-off-by: Simon Glass --- tools/binman/README.entries | 19 ++++++++++ tools/binman/etype/intel_fit.py | 32 ++++++++++++++++ tools/binman/etype/intel_fit_ptr.py | 41 +++++++++++++++++++++ tools/binman/ftest.py | 20 ++++++++++ tools/binman/test/147_intel_fit.dts | 20 ++++++++++ tools/binman/test/148_intel_fit_missing.dts | 17 +++++++++ 6 files changed, 149 insertions(+) create mode 100644 tools/binman/etype/intel_fit.py create mode 100644 tools/binman/etype/intel_fit_ptr.py create mode 100644 tools/binman/test/147_intel_fit.dts create mode 100644 tools/binman/test/148_intel_fit_missing.dts diff --git a/tools/binman/README.entries b/tools/binman/README.entries index d17b3cb078..dba51e6daa 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -391,6 +391,25 @@ See README.x86 for information about x86 binary blobs. +Entry: intel-fit: Intel Firmware Image Table (FIT) +-------------------------------------------------- + +This entry contains a dummy FIT as required by recent Intel CPUs. The FIT +contains information about the firmware and microcode available in the +image. + +At present binman only supports a basic FIT with no microcode. + + + +Entry: intel-fit-ptr: Intel Firmware Image Table (FIT) pointer +-------------------------------------------------------------- + +This entry contains a pointer to the FIT. It is required to be at address +0xffffffc0 in the image. + + + Entry: intel-fsp: Entry containing an Intel Firmware Support Package (FSP) file ------------------------------------------------------------------------------- diff --git a/tools/binman/etype/intel_fit.py b/tools/binman/etype/intel_fit.py new file mode 100644 index 0000000000..23606d27d0 --- /dev/null +++ b/tools/binman/etype/intel_fit.py @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for Intel Firmware Image Table +# + +import struct + +from blob import Entry_blob + +class Entry_intel_fit(Entry_blob): + """Intel Firmware Image Table (FIT) + + This entry contains a dummy FIT as required by recent Intel CPUs. The FIT + contains information about the firmware and microcode available in the + image. + + At present binman only supports a basic FIT with no microcode. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def ReadNode(self): + """Force 16-byte alignment as required by FIT pointer""" + Entry_blob.ReadNode(self) + self.align = 16 + + def ObtainContents(self): + data = struct.pack('<8sIHBB', '_FIT_ ', 1, 0x100, 0x80, 0x7d) + self.SetContents(data) + return True diff --git a/tools/binman/etype/intel_fit_ptr.py b/tools/binman/etype/intel_fit_ptr.py new file mode 100644 index 0000000000..148b206c3c --- /dev/null +++ b/tools/binman/etype/intel_fit_ptr.py @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for a pointer to an Intel Firmware Image Table +# + +import struct + +from blob import Entry_blob + +class Entry_intel_fit_ptr(Entry_blob): + """Intel Firmware Image Table (FIT) pointer + + This entry contains a pointer to the FIT. It is required to be at address + 0xffffffc0 in the image. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + if self.HasSibling('intel-fit') is False: + self.Raise("'intel-fit-ptr' section must have an 'intel-fit' sibling") + + def _GetContents(self): + fit_pos = self.GetSiblingImagePos('intel-fit') + return struct.pack('; + #size-cells = <1>; + + binman { + end-at-4gb; + size = <0x80>; + + u-boot { + }; + + intel-fit { + }; + + intel-fit-ptr { + }; + }; +}; diff --git a/tools/binman/test/148_intel_fit_missing.dts b/tools/binman/test/148_intel_fit_missing.dts new file mode 100644 index 0000000000..388c76b1ab --- /dev/null +++ b/tools/binman/test/148_intel_fit_missing.dts @@ -0,0 +1,17 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + end-at-4gb; + size = <0x80>; + + u-boot { + }; + + intel-fit-ptr { + }; + }; +}; From e95be637c47463f771998fe7b890daec032dcb8e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:51 -0600 Subject: [PATCH 11/61] binman: Fix IFWI output when using an Intel FIT image At present this entry does not work correctly when a FIT image is used as the input. It updates the FIT instead of the output image. The test passed because the FIT image happened to have the right data already. Fix it. Signed-off-by: Simon Glass --- tools/binman/etype/intel_ifwi.py | 6 +++--- tools/binman/ftest.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index f3745f7a8c..e4da3e498a 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -75,10 +75,10 @@ class Entry_intel_ifwi(Entry_blob): self._pathname = outname else: # Provide a different code path here to ensure we have test coverage - inname = self._pathname + outname = self._pathname # Delete OBBP if it is there, then add the required new items. - tools.RunIfwiTool(inname, tools.CMD_DELETE, subpart='OBBP') + tools.RunIfwiTool(outname, tools.CMD_DELETE, subpart='OBBP') for entry in self._ifwi_entries.values(): # First get the input data and put it in a file @@ -89,7 +89,7 @@ class Entry_intel_ifwi(Entry_blob): input_fname = tools.GetOutputFilename('input.%s' % uniq) tools.WriteFile(input_fname, data) - tools.RunIfwiTool(inname, + tools.RunIfwiTool(outname, tools.CMD_REPLACE if entry._ifwi_replace else tools.CMD_ADD, input_fname, entry._ifwi_subpart, entry._ifwi_entry_name) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 080599fee3..bba07e7275 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -2044,7 +2044,7 @@ class TestFunctional(unittest.TestCase): subpart='IBBP', entry_name='IBBL') tpl_data = tools.ReadFile(tpl_fname) - self.assertEqual(tpl_data[:len(U_BOOT_TPL_DATA)], U_BOOT_TPL_DATA) + self.assertEqual(U_BOOT_TPL_DATA, tpl_data[:len(U_BOOT_TPL_DATA)]) def testPackX86RomIfwi(self): """Test that an x86 ROM with Integrated Firmware Image can be created""" From 180f556b090c2e3c84c904d3e6bc884acb423e1f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:52 -0600 Subject: [PATCH 12/61] binman: Use tools.Run() to run objdump At present this command silently fails if something goes wrong. Use the tools.Run() function instead, since it reports errors. Signed-off-by: Simon Glass --- tools/binman/elf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 66cfe796a2..7bc7cf61b5 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -49,7 +49,7 @@ def GetSymbols(fname, patterns): key: Name of symbol value: Hex value of symbol """ - stdout = command.Output('objdump', '-t', fname, raise_on_error=False) + stdout = tools.Run('objdump', '-t', fname) lines = stdout.splitlines() if patterns: re_syms = re.compile('|'.join(patterns)) From 53e22bf38c202d5ef3bc092d55095c672994a15b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:53 -0600 Subject: [PATCH 13/61] binman: Use the Makefile to build ELF test files At present the ELF test files are checked into the U-Boot tree. This is covenient since the files never change and can be used on non-x86 platforms. However it is not good practice to check in binaries and in this case it does not seem essential. Update the binman test-file Makefile to support having source in a different directory. Adjust binman to run it to build bss_data, as a start. We can add other files as needed. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 23 +++++++++++++++++++++++ tools/binman/ftest.py | 24 ++++++++++++++++++------ tools/binman/test/Makefile | 3 ++- tools/binman/test/bss_data | Bin 5020 -> 0 bytes 4 files changed, 43 insertions(+), 7 deletions(-) delete mode 100755 tools/binman/test/bss_data diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index cc6e9c5128..736b931fd5 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -50,6 +50,29 @@ class FakeSection: return self.sym_value +def BuildElfTestFiles(target_dir): + """Build ELF files used for testing in binman + + This compiles and links the test files into the specified directory. It the + Makefile and source files in the binman test/ directory. + + Args: + target_dir: Directory to put the files into + """ + if not os.path.exists(target_dir): + os.mkdir(target_dir) + testdir = os.path.join(binman_dir, 'test') + + # If binman is involved from the main U-Boot Makefile the -r and -R + # flags are set in MAKEFLAGS. This prevents this Makefile from working + # correctly. So drop any make flags here. + if 'MAKEFLAGS' in os.environ: + del os.environ['MAKEFLAGS'] + tools.Run('make', '-C', target_dir, '-f', + os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir, + 'bss_data', 'u_boot_ucode_ptr') + + class TestElf(unittest.TestCase): @classmethod def setUpClass(self): diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index bba07e7275..fad62bb04f 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -23,6 +23,7 @@ import cmdline import command import control import elf +import elf_test import fdt from etype import fdtmap from etype import image_header @@ -147,6 +148,9 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA) TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) + cls._elf_testdir = os.path.join(cls._indir, 'elftest') + elf_test.BuildElfTestFiles(cls._elf_testdir) + # ELF file with a '_dt_ucode_base_size' symbol with open(cls.TestFile('u_boot_ucode_ptr'), 'rb') as fd: TestFunctional._MakeInputFile('u-boot', fd.read()) @@ -484,13 +488,21 @@ class TestFunctional(unittest.TestCase): Args: Filename of ELF file to use as SPL """ - with open(cls.TestFile(src_fname), 'rb') as fd: - TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) + # TODO(sjg@chromium.org): Drop this when all Elf files use ElfTestFile() + if src_fname in ['bss_data']: + fname = cls.ElfTestFile(src_fname) + else: + fname = cls.TestFile(src_fname) + TestFunctional._MakeInputFile('spl/u-boot-spl', tools.ReadFile(fname)) @classmethod def TestFile(cls, fname): return os.path.join(cls._binman_dir, 'test', fname) + @classmethod + def ElfTestFile(cls, fname): + return os.path.join(cls._elf_testdir, fname) + def AssertInList(self, grep_list, target): """Assert that at least one of a list of things is in a target @@ -1551,7 +1563,7 @@ class TestFunctional(unittest.TestCase): def testTpl(self): """Test that an image with TPL and ots device tree can be created""" # ELF file with a '__bss_size' symbol - with open(self.TestFile('bss_data'), 'rb') as fd: + with open(self.ElfTestFile('bss_data'), 'rb') as fd: TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) data = self._DoReadFile('078_u_boot_tpl.dts') self.assertEqual(U_BOOT_TPL_DATA + U_BOOT_TPL_DTB_DATA, data) @@ -1861,16 +1873,16 @@ class TestFunctional(unittest.TestCase): def testElf(self): """Basic test of ELF entries""" self._SetupSplElf() - with open(self.TestFile('bss_data'), 'rb') as fd: + with open(self.ElfTestFile('bss_data'), 'rb') as fd: TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) - with open(self.TestFile('bss_data'), 'rb') as fd: + with open(self.ElfTestFile('bss_data'), 'rb') as fd: TestFunctional._MakeInputFile('-boot', fd.read()) data = self._DoReadFile('096_elf.dts') def testElfStrip(self): """Basic test of ELF entries""" self._SetupSplElf() - with open(self.TestFile('bss_data'), 'rb') as fd: + with open(self.ElfTestFile('bss_data'), 'rb') as fd: TestFunctional._MakeInputFile('-boot', fd.read()) data = self._DoReadFile('097_elf_strip.dts') diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile index e58fc80775..ce1c2f900c 100644 --- a/tools/binman/test/Makefile +++ b/tools/binman/test/Makefile @@ -7,6 +7,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +VPATH := $(SRC) CFLAGS := -march=i386 -m32 -nostdlib -I ../../../include LDS_UCODE := -T u_boot_ucode_ptr.lds @@ -25,7 +26,7 @@ u_boot_no_ucode_ptr: u_boot_no_ucode_ptr.c u_boot_ucode_ptr: CFLAGS += $(LDS_UCODE) u_boot_ucode_ptr: u_boot_ucode_ptr.c -bss_data: CFLAGS += bss_data.lds +bss_data: CFLAGS += $(SRC)bss_data.lds bss_data: bss_data.c u_boot_binman_syms.bin: u_boot_binman_syms diff --git a/tools/binman/test/bss_data b/tools/binman/test/bss_data deleted file mode 100755 index afa28282aa157f6717c1ba244ecbfc6e1b081734..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5020 zcmeHLyKWOf6uoP&!GJ+|Af+(H7C{(6hJ>s{1O*}i;vz!9k|7jmvEv0>!j5FGr4S(= z1rl`m016r?sner~AE2ip9R*N@0-1AWb`nc8lqu#)$M-R39(#6N?0tS?>89s-Vl5+C zVfN$CU=YG@j+l{90?A29j!9mR>*@YU@kF< zm|&e)-boq-EK+#s=ZTZ35qA7G#*zMGT%X&LM}8Jqyj7L$-{T)Z{jc>) zoA)Lv)i*nzb0r)u1JV{C_dj{X>=n-E`M(bagY)oQhvscm#Cw|eiUr?)4ZOE;EwK{y#HNI)1&RP})m zBwkNM#m(qpx7LoMW}~~GiE7l6ny7lOCu()A-HtoS|Lal&^)SHCcil&Tp9HMgPjH0- zzvtN-*hQ~l7v6r;Bi!p{glWw6bl(A!hIw|q`5|6_-b4W29BS4qZwUqN%N~U8gQR^A zrZmf|AkG8i1!zb3;PIVU3)0{&JlC5}bMnrmF&)Q2Mv+e-r`{#_QQVFIo;@!(Jhvxj;Qe&}5sc3w z=l$WG7=v Date: Sat, 24 Aug 2019 07:22:54 -0600 Subject: [PATCH 14/61] binman: Use the Makefile for u_boot_ucode_ptr Remove this file from git and instead build it using the Makefile. Update tools.GetInputFilename() to support reading files from an absolute path, so that we can read the Elf test files easily. Also make sure that the temp directory is report in ELF tests as this was commented out. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 19 +++++++++++++++---- tools/binman/ftest.py | 14 +++++++------- tools/binman/test/Makefile | 2 +- tools/binman/test/u_boot_ucode_ptr | Bin 4175 -> 0 bytes tools/binman/test/u_boot_ucode_ptr.lds | 3 ++- tools/patman/tools.py | 2 +- 6 files changed, 26 insertions(+), 14 deletions(-) delete mode 100755 tools/binman/test/u_boot_ucode_ptr diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 736b931fd5..403ca2b412 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -75,18 +75,29 @@ def BuildElfTestFiles(target_dir): class TestElf(unittest.TestCase): @classmethod - def setUpClass(self): + def setUpClass(cls): + cls._indir = tempfile.mkdtemp(prefix='elf.') tools.SetInputDirs(['.']) + BuildElfTestFiles(cls._indir) + + @classmethod + def tearDownClass(cls): + if cls._indir: + shutil.rmtree(cls._indir) + + @classmethod + def ElfTestFile(cls, fname): + return os.path.join(cls._indir, fname) def testAllSymbols(self): """Test that we can obtain a symbol from the ELF file""" - fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr') + fname = self.ElfTestFile('u_boot_ucode_ptr') syms = elf.GetSymbols(fname, []) self.assertIn('.ucode', syms) def testRegexSymbols(self): """Test that we can obtain from the ELF file by regular expression""" - fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr') + fname = self.ElfTestFile('u_boot_ucode_ptr') syms = elf.GetSymbols(fname, ['ucode']) self.assertIn('.ucode', syms) syms = elf.GetSymbols(fname, ['missing']) @@ -201,7 +212,7 @@ class TestElf(unittest.TestCase): self.assertEqual(elf.ElfInfo(b'\0\0' + expected[2:], load, entry, len(expected)), elf.DecodeElf(data, load + 2)) - #shutil.rmtree(outdir) + shutil.rmtree(outdir) if __name__ == '__main__': diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index fad62bb04f..e7ade0fddf 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -152,8 +152,8 @@ class TestFunctional(unittest.TestCase): elf_test.BuildElfTestFiles(cls._elf_testdir) # ELF file with a '_dt_ucode_base_size' symbol - with open(cls.TestFile('u_boot_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(cls.ElfTestFile('u_boot_ucode_ptr'))) # Intel flash descriptor file with open(cls.TestFile('descriptor.bin'), 'rb') as fd: @@ -489,7 +489,7 @@ class TestFunctional(unittest.TestCase): Filename of ELF file to use as SPL """ # TODO(sjg@chromium.org): Drop this when all Elf files use ElfTestFile() - if src_fname in ['bss_data']: + if src_fname in ['bss_data', 'u_boot_ucode_ptr']: fname = cls.ElfTestFile(src_fname) else: fname = cls.TestFile(src_fname) @@ -1101,8 +1101,8 @@ class TestFunctional(unittest.TestCase): finally: # Put the original file back - with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(self.ElfTestFile('u_boot_ucode_ptr'))) def testMicrocodeNotInImage(self): """Test that microcode must be placed within the image""" @@ -1818,8 +1818,8 @@ class TestFunctional(unittest.TestCase): u-boot-tpl.dtb with the microcode removed the microcode """ - with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) + TestFunctional._MakeInputFile('tpl/u-boot-tpl', + tools.ReadFile(self.ElfTestFile('u_boot_ucode_ptr'))) first, pos_and_size = self._RunMicrocodeTest('093_x86_tpl_ucode.dts', U_BOOT_TPL_NODTB_DATA) self.assertEqual(b'tplnodtb with microc' + pos_and_size + diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile index ce1c2f900c..fd660eac6e 100644 --- a/tools/binman/test/Makefile +++ b/tools/binman/test/Makefile @@ -10,7 +10,7 @@ VPATH := $(SRC) CFLAGS := -march=i386 -m32 -nostdlib -I ../../../include -LDS_UCODE := -T u_boot_ucode_ptr.lds +LDS_UCODE := -T $(SRC)u_boot_ucode_ptr.lds LDS_BINMAN := -T u_boot_binman_syms.lds LDS_BINMAN_BAD := -T u_boot_binman_syms_bad.lds diff --git a/tools/binman/test/u_boot_ucode_ptr b/tools/binman/test/u_boot_ucode_ptr deleted file mode 100755 index dbfb184cecfbcf55cf43ed4f4ac0ee90a7364d93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4175 zcmeHKze~eV5WfDv>Y%NqTOB%ds7Rl!MiB>>qFqFAD7b~B30kpLh}je}Vs) zgM)i3QgG0CU(yE=7YE1p!Ew2t@9xWVH@o|LsZ@#-(v%@sqt7rjSl=(i5rZlmsZoxy zQ9SaF!jM>&I0rHVXMs3_>*wPh=u>4I0zc&NRXVJG0rgz2p&8H&Xa+O`ngPv#Wh9TCMV?U7?UiPJBvzCKcpQta-m##SW0$~TeGpF8jNCaKqaY=Oj ze&6*ZKlNvnIWxzC`EXm}&a5V?u^%8_A>)8o(X9qLQXD z#1~o6OQFqqJIY{<8~_@#DLmzgZrQ+Xi@EVGZrnMRWWNeKSJ|ha`YAi9u{Z4aQjhnG z?c~ddtBklhOXCp#9(;g{)Q?Fq+c>PTU-d6wo4~YvUz*V$GtcEfbjfs-ZCgXv9QLkU KGKbO{NcskUZF7hK diff --git a/tools/binman/test/u_boot_ucode_ptr.lds b/tools/binman/test/u_boot_ucode_ptr.lds index 0cf9b762b5..cf4d1b8bbd 100644 --- a/tools/binman/test/u_boot_ucode_ptr.lds +++ b/tools/binman/test/u_boot_ucode_ptr.lds @@ -9,9 +9,10 @@ ENTRY(_start) SECTIONS { - . = 0xfffffdf0; + . = 0xfffffe14; _start = .; .ucode : { *(.ucode) } + .interp : { *(.interp*) } } diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 0952681579..4a7fcdad21 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -125,7 +125,7 @@ def GetInputFilename(fname): Returns: The full path of the filename, within the input directory """ - if not indir: + if not indir or fname[:1] == '/': return fname for dirname in indir: pathname = os.path.join(dirname, fname) From bccd91da9bdac8bf947a299ab9a7b821d2702696 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:55 -0600 Subject: [PATCH 15/61] binman: Use the Makefile for u_boot_no_ucode_ptr Remove this file from git and instead build it using the Makefile. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 2 +- tools/binman/ftest.py | 10 +++++----- tools/binman/test/u_boot_no_ucode_ptr | Bin 4182 -> 0 bytes 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100755 tools/binman/test/u_boot_no_ucode_ptr diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 403ca2b412..c7f51bb86a 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -70,7 +70,7 @@ def BuildElfTestFiles(target_dir): del os.environ['MAKEFLAGS'] tools.Run('make', '-C', target_dir, '-f', os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir, - 'bss_data', 'u_boot_ucode_ptr') + 'bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr') class TestElf(unittest.TestCase): diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index e7ade0fddf..30a8b0b14c 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -489,7 +489,7 @@ class TestFunctional(unittest.TestCase): Filename of ELF file to use as SPL """ # TODO(sjg@chromium.org): Drop this when all Elf files use ElfTestFile() - if src_fname in ['bss_data', 'u_boot_ucode_ptr']: + if src_fname in ['bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr']: fname = cls.ElfTestFile(src_fname) else: fname = cls.TestFile(src_fname) @@ -1091,8 +1091,8 @@ class TestFunctional(unittest.TestCase): """Test that a U-Boot binary without the microcode symbol is detected""" # ELF file without a '_dt_ucode_base_size' symbol try: - with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr'))) with self.assertRaises(ValueError) as e: self._RunPackUbootSingleMicrocode() @@ -1114,8 +1114,8 @@ class TestFunctional(unittest.TestCase): def testWithoutMicrocode(self): """Test that we can cope with an image without microcode (e.g. qemu)""" - with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd: - TestFunctional._MakeInputFile('u-boot', fd.read()) + TestFunctional._MakeInputFile('u-boot', + tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr'))) data, dtb, _, _ = self._DoReadFileDtb('044_x86_optional_ucode.dts', True) # Now check the device tree has no microcode diff --git a/tools/binman/test/u_boot_no_ucode_ptr b/tools/binman/test/u_boot_no_ucode_ptr deleted file mode 100755 index f72462f0be41a934d468481bf627d6c1ec9a8e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4182 zcmeHKy-EW?5T5*Cv``}iEVQ^HMMSbDdWK+O6Euwq7AdTbT<(Ygb0^7OVG6bMF|2$8 zpFw;En;;05iM_7#<+2d5v9R2MkJ51hV9kJT?hJ(n9X3>XFs1BL;^fMLKe zU>GnA7zPXjhJk-z0Q*;tkz&+O8uWhlJbWr0zYHsC`1(-IehePl*#DA<*J^uKq2We> zj4WGJgSdDb~a)^k?3D_Wz%IXd$B&(ry!KRXa|vSqt1m_?06)iR_OU8 zT4A^A2a>P)v#fDuhJp8Cx5S>ApQ*-t5W&D4m^1gKRF3!4c|L2=dAsaDUTGS@9=oZN zrZL1<80e*?&UyRVV2vCIG~TA=ewpZ&4eYjfH}1ubyTF+3XR))wJ}tVRwr4fwh8=I} z@qDp8do$uXBd$)(xO`84NJ_C$;LPaVgT TQ=i-H`%b?z@X6`RW>3;L6WVxU From 1542c8b5fce0f81ace585ac87218bfd79eb077f3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:56 -0600 Subject: [PATCH 16/61] binman: Use the Makefile for u_boot_binman_syms Remove this file from git and instead build it using the Makefile. With this change a few things need to be adjusted: 1. The 'notes' section no-longer appears at the start of the ELF file (before the code), so update testSymbols to adjust the offsets. 2. The dynamic linker is disabled to avoid errors like: "Not enough room for program headers, try linking with -N" 3. The interpreter note is moved to the end of the image, so that the binman symbols appear first. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 9 +++++---- tools/binman/ftest.py | 7 ++++--- tools/binman/test/Makefile | 5 +++-- tools/binman/test/u_boot_binman_syms | Bin 4924 -> 0 bytes tools/binman/test/u_boot_binman_syms.lds | 1 + 5 files changed, 13 insertions(+), 9 deletions(-) delete mode 100755 tools/binman/test/u_boot_binman_syms diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index c7f51bb86a..ff036cb655 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -70,7 +70,8 @@ def BuildElfTestFiles(target_dir): del os.environ['MAKEFLAGS'] tools.Run('make', '-C', target_dir, '-f', os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir, - 'bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr') + 'bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', + 'u_boot_binman_syms', 'u_boot_binman_syms.bin') class TestElf(unittest.TestCase): @@ -118,7 +119,7 @@ class TestElf(unittest.TestCase): """Test a symbol which extends outside the entry area is detected""" entry = FakeEntry(10) section = FakeSection() - elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') + elf_fname = self.ElfTestFile('u_boot_binman_syms') with self.assertRaises(ValueError) as e: syms = elf.LookupAndWriteSymbols(elf_fname, entry, section) self.assertIn('entry_path has offset 4 (size 8) but the contents size ' @@ -158,7 +159,7 @@ class TestElf(unittest.TestCase): """ entry = FakeEntry(20) section = FakeSection(sym_value=None) - elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') + elf_fname = self.ElfTestFile('u_boot_binman_syms') syms = elf.LookupAndWriteSymbols(elf_fname, entry, section) self.assertEqual(tools.GetBytes(255, 16) + tools.GetBytes(ord('a'), 4), entry.data) @@ -169,7 +170,7 @@ class TestElf(unittest.TestCase): tout.Init(tout.DEBUG) entry = FakeEntry(20) section = FakeSection() - elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') + elf_fname = self.ElfTestFile('u_boot_binman_syms') with test_util.capture_sys_output() as (stdout, stderr): syms = elf.LookupAndWriteSymbols(elf_fname, entry, section) self.assertTrue(len(stdout.getvalue()) > 0) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 30a8b0b14c..507c481881 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -489,7 +489,8 @@ class TestFunctional(unittest.TestCase): Filename of ELF file to use as SPL """ # TODO(sjg@chromium.org): Drop this when all Elf files use ElfTestFile() - if src_fname in ['bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr']: + if src_fname in ['bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', + 'u_boot_binman_syms']: fname = cls.ElfTestFile(src_fname) else: fname = cls.TestFile(src_fname) @@ -1223,14 +1224,14 @@ class TestFunctional(unittest.TestCase): def testSymbols(self): """Test binman can assign symbols embedded in U-Boot""" - elf_fname = self.TestFile('u_boot_binman_syms') + elf_fname = self.ElfTestFile('u_boot_binman_syms') syms = elf.GetSymbols(elf_fname, ['binman', 'image']) addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start') self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr) self._SetupSplElf('u_boot_binman_syms') data = self._DoReadFile('053_symbols.dts') - sym_values = struct.pack('b@{x4c zE5;WsFm2Hg^@?wr9YU~>YH4`}5c1&&ByC=kmIE-njg7@cOGNIMMrEqY*0%Jew;7a^sB_W@r02_y_o5))_MHhhw82$s+oLkVEs6T@@=QIAe5MwG*swm5} ziUw&Crm7exh3p9vPRSx4ZmE2fu9lN4Ibsc9FJs@4 ncxM85*3jr@_lETl{jT6ScUlE_F7M+JFyC(j{k|b*%=G&MuziL^ diff --git a/tools/binman/test/u_boot_binman_syms.lds b/tools/binman/test/u_boot_binman_syms.lds index 29cf9d0e54..926df873cb 100644 --- a/tools/binman/test/u_boot_binman_syms.lds +++ b/tools/binman/test/u_boot_binman_syms.lds @@ -25,5 +25,6 @@ SECTIONS KEEP(*(SORT(.binman_sym*))); __binman_sym_end = .; } + .interp : { *(.interp*) } } From e9d2ee3862488e98278a0201263c276c12729484 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:57 -0600 Subject: [PATCH 17/61] binman: Use the Makefile for u_boot_binman_syms_size Remove this file from git and instead build it using the Makefile. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 5 +++-- tools/binman/ftest.py | 2 +- tools/binman/test/u_boot_binman_syms_size | Bin 4825 -> 0 bytes 3 files changed, 4 insertions(+), 3 deletions(-) delete mode 100755 tools/binman/test/u_boot_binman_syms_size diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index ff036cb655..a913970150 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -71,7 +71,8 @@ def BuildElfTestFiles(target_dir): tools.Run('make', '-C', target_dir, '-f', os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir, 'bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', - 'u_boot_binman_syms', 'u_boot_binman_syms.bin') + 'u_boot_binman_syms', 'u_boot_binman_syms.bin', + 'u_boot_binman_syms_size') class TestElf(unittest.TestCase): @@ -145,7 +146,7 @@ class TestElf(unittest.TestCase): """ entry = FakeEntry(10) section = FakeSection() - elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_size') + elf_fname =self.ElfTestFile('u_boot_binman_syms_size') with self.assertRaises(ValueError) as e: syms = elf.LookupAndWriteSymbols(elf_fname, entry, section) self.assertIn('has size 1: only 4 and 8 are supported', diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 507c481881..51eab6fbfa 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -490,7 +490,7 @@ class TestFunctional(unittest.TestCase): """ # TODO(sjg@chromium.org): Drop this when all Elf files use ElfTestFile() if src_fname in ['bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', - 'u_boot_binman_syms']: + 'u_boot_binman_syms', 'u_boot_binman_syms_size']: fname = cls.ElfTestFile(src_fname) else: fname = cls.TestFile(src_fname) diff --git a/tools/binman/test/u_boot_binman_syms_size b/tools/binman/test/u_boot_binman_syms_size deleted file mode 100755 index d691e897c0f1842cb82efbc67f57d9f62853b99c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4825 zcmeHLyKWOv5FI~+mChk_G%jq(2>Hq;D?t(oMY4z$2|-f0i*)7nuFOi_hrD+Sryze| zet;iH2NGo(I=XcH0Tm7Tf^f#WV{DlQ>O0c$+?hEuyZ6|Q=jzq#lTxWfVr8n3L=KW4 z>v_eY1}bf;Q8lj@d9Jn!Jm3KNYT?=D&rP=W*Agf^anP^*B!EMcZ%C C$!_BS From 8dc60f99f9a2fe7873a753f1ab0254efd3cd6bd4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:58 -0600 Subject: [PATCH 18/61] binman: Use the Makefile for u_boot_binman_syms_bad Remove this file from git and instead build it using the Makefile. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 4 ++-- tools/binman/test/Makefile | 2 +- tools/binman/test/u_boot_binman_syms_bad | Bin 4890 -> 0 bytes 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100755 tools/binman/test/u_boot_binman_syms_bad diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index a913970150..1ee5d9d57c 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -72,7 +72,7 @@ def BuildElfTestFiles(target_dir): os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir, 'bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', 'u_boot_binman_syms', 'u_boot_binman_syms.bin', - 'u_boot_binman_syms_size') + 'u_boot_binman_syms_size', 'u_boot_binman_syms_bad') class TestElf(unittest.TestCase): @@ -134,7 +134,7 @@ class TestElf(unittest.TestCase): """ entry = FakeEntry(10) section = FakeSection() - elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_bad') + elf_fname = self.ElfTestFile('u_boot_binman_syms_bad') self.assertEqual(elf.LookupAndWriteSymbols(elf_fname, entry, section), None) diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile index 7af5459793..593bbe9bd9 100644 --- a/tools/binman/test/Makefile +++ b/tools/binman/test/Makefile @@ -13,7 +13,7 @@ CFLAGS := -march=i386 -m32 -nostdlib -I $(SRC)../../../include \ LDS_UCODE := -T $(SRC)u_boot_ucode_ptr.lds LDS_BINMAN := -T $(SRC)u_boot_binman_syms.lds -LDS_BINMAN_BAD := -T u_boot_binman_syms_bad.lds +LDS_BINMAN_BAD := -T $(SRC)u_boot_binman_syms_bad.lds TARGETS = u_boot_ucode_ptr u_boot_no_ucode_ptr bss_data \ u_boot_binman_syms u_boot_binman_syms.bin u_boot_binman_syms_bad \ diff --git a/tools/binman/test/u_boot_binman_syms_bad b/tools/binman/test/u_boot_binman_syms_bad deleted file mode 100755 index 8da3d9d48f388a9be53e92590984411691f6721f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4890 zcmeHLJ!=$E6up~WjOjLFrOg&wtVkY797F^`2yqpRVv#}#JZ3VBF6_=MJ8y(ENwASv zTZuow-an8(k|ITFk^BHXXW!gp@?m5BF5I~v=e#@bo!MsJ-ulaDjYdP%=A?|UEab!>$^ba;d9Esg+fF-hI&dUhZQ7UZ1yrOXM4R zYC2Er>!RM|@O-r9g*UTShR0j-`;X7g>pMufp8HzF`iCBxJ=-|V6J$O3O*rv)h}25? zACdEJh}H)F8BzDcT1uPbxwGeAzOYH0nr+cmMJOgCJDKJaJIM>Ng^Q=|8p>*oQ;n?F U$JtH|)8YK34YE{hz2S%d1wo~NOaK4? From c9a0b27589a49d4beaaa4f75500597ab07cfff39 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:22:59 -0600 Subject: [PATCH 19/61] binman: Clean up unnecessary code related to ELF test files We use the Makefile for all ELF test files now, so drop all the code that checks whether to get the test file from the Makefile or from the git repo. Also add a comment to the Makefile indicating that it is run from binman. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 5 +---- tools/binman/ftest.py | 9 ++------- tools/binman/test/Makefile | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 1ee5d9d57c..f05545bcb1 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -69,10 +69,7 @@ def BuildElfTestFiles(target_dir): if 'MAKEFLAGS' in os.environ: del os.environ['MAKEFLAGS'] tools.Run('make', '-C', target_dir, '-f', - os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir, - 'bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', - 'u_boot_binman_syms', 'u_boot_binman_syms.bin', - 'u_boot_binman_syms_size', 'u_boot_binman_syms_bad') + os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir) class TestElf(unittest.TestCase): diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 51eab6fbfa..1d774e28e5 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -488,13 +488,8 @@ class TestFunctional(unittest.TestCase): Args: Filename of ELF file to use as SPL """ - # TODO(sjg@chromium.org): Drop this when all Elf files use ElfTestFile() - if src_fname in ['bss_data', 'u_boot_ucode_ptr', 'u_boot_no_ucode_ptr', - 'u_boot_binman_syms', 'u_boot_binman_syms_size']: - fname = cls.ElfTestFile(src_fname) - else: - fname = cls.TestFile(src_fname) - TestFunctional._MakeInputFile('spl/u-boot-spl', tools.ReadFile(fname)) + TestFunctional._MakeInputFile('spl/u-boot-spl', + tools.ReadFile(cls.ElfTestFile(src_fname))) @classmethod def TestFile(cls, fname): diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile index 593bbe9bd9..bdbb009874 100644 --- a/tools/binman/test/Makefile +++ b/tools/binman/test/Makefile @@ -1,5 +1,5 @@ # -# Builds test programs +# Builds test programs. This is launched from elf_test.BuildElfTestFiles() # # Copyright (C) 2017 Google, Inc # Written by Simon Glass From 2090f1e3d096bd124790e1716240e17e56325755 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:00 -0600 Subject: [PATCH 20/61] binman: Allow symbols to be resolved inside sections At present we only support symbols inside binaries which are at the top level of an image. This restrictions seems unreasonable since more complex images may want to group binaries within different sections. Relax the restriction, adding a new _SetupTplElf() helper function. Also fix a typo in the comment for testTpl(). Signed-off-by: Simon Glass --- tools/binman/etype/u_boot_spl.py | 2 +- tools/binman/etype/u_boot_tpl.py | 2 +- tools/binman/ftest.py | 45 ++++++++++++++++++++++----- tools/binman/test/149_symbols_tpl.dts | 28 +++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 tools/binman/test/149_symbols_tpl.dts diff --git a/tools/binman/etype/u_boot_spl.py b/tools/binman/etype/u_boot_spl.py index ab78714c8d..7fedd00021 100644 --- a/tools/binman/etype/u_boot_spl.py +++ b/tools/binman/etype/u_boot_spl.py @@ -40,4 +40,4 @@ class Entry_u_boot_spl(Entry_blob): return 'spl/u-boot-spl.bin' def WriteSymbols(self, section): - elf.LookupAndWriteSymbols(self.elf_fname, self, section) + elf.LookupAndWriteSymbols(self.elf_fname, self, section.GetImage()) diff --git a/tools/binman/etype/u_boot_tpl.py b/tools/binman/etype/u_boot_tpl.py index 4d4bb92596..1b69c4f4a7 100644 --- a/tools/binman/etype/u_boot_tpl.py +++ b/tools/binman/etype/u_boot_tpl.py @@ -40,4 +40,4 @@ class Entry_u_boot_tpl(Entry_blob): return 'tpl/u-boot-tpl.bin' def WriteSymbols(self, section): - elf.LookupAndWriteSymbols(self.elf_fname, self, section) + elf.LookupAndWriteSymbols(self.elf_fname, self, section.GetImage()) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 1d774e28e5..0eb0667aac 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -40,7 +40,7 @@ import tout U_BOOT_DATA = b'1234' U_BOOT_IMG_DATA = b'img' U_BOOT_SPL_DATA = b'56780123456789abcde' -U_BOOT_TPL_DATA = b'tpl' +U_BOOT_TPL_DATA = b'tpl9876543210fedcb' BLOB_DATA = b'89' ME_DATA = b'0abcd' VGA_DATA = b'vga' @@ -491,6 +491,16 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('spl/u-boot-spl', tools.ReadFile(cls.ElfTestFile(src_fname))) + @classmethod + def _SetupTplElf(cls, src_fname='bss_data'): + """Set up an ELF file with a '_dt_ucode_base_size' symbol + + Args: + Filename of ELF file to use as TPL + """ + TestFunctional._MakeInputFile('tpl/u-boot-tpl', + tools.ReadFile(cls.ElfTestFile(src_fname))) + @classmethod def TestFile(cls, fname): return os.path.join(cls._binman_dir, 'test', fname) @@ -1557,10 +1567,9 @@ class TestFunctional(unittest.TestCase): "'other'", str(e.exception)) def testTpl(self): - """Test that an image with TPL and ots device tree can be created""" + """Test that an image with TPL and its device tree can be created""" # ELF file with a '__bss_size' symbol - with open(self.ElfTestFile('bss_data'), 'rb') as fd: - TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) + self._SetupTplElf() data = self._DoReadFile('078_u_boot_tpl.dts') self.assertEqual(U_BOOT_TPL_DATA + U_BOOT_TPL_DTB_DATA, data) @@ -1814,8 +1823,7 @@ class TestFunctional(unittest.TestCase): u-boot-tpl.dtb with the microcode removed the microcode """ - TestFunctional._MakeInputFile('tpl/u-boot-tpl', - tools.ReadFile(self.ElfTestFile('u_boot_ucode_ptr'))) + self._SetupTplElf('u_boot_ucode_ptr') first, pos_and_size = self._RunMicrocodeTest('093_x86_tpl_ucode.dts', U_BOOT_TPL_NODTB_DATA) self.assertEqual(b'tplnodtb with microc' + pos_and_size + @@ -1869,8 +1877,7 @@ class TestFunctional(unittest.TestCase): def testElf(self): """Basic test of ELF entries""" self._SetupSplElf() - with open(self.ElfTestFile('bss_data'), 'rb') as fd: - TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read()) + self._SetupTplElf() with open(self.ElfTestFile('bss_data'), 'rb') as fd: TestFunctional._MakeInputFile('-boot', fd.read()) data = self._DoReadFile('096_elf.dts') @@ -2029,6 +2036,7 @@ class TestFunctional(unittest.TestCase): fname: Filename of input file to provide (fitimage.bin or ifwi.bin) """ self._SetupSplElf() + self._SetupTplElf() # Intel Integrated Firmware Image (IFWI) file with gzip.open(self.TestFile('%s.gz' % fname), 'rb') as fd: @@ -3292,6 +3300,27 @@ class TestFunctional(unittest.TestCase): self.assertIn("'intel-fit-ptr' section must have an 'intel-fit' sibling", str(e.exception)) + def testSymbolsTplSection(self): + """Test binman can assign symbols embedded in U-Boot TPL in a section""" + self._SetupSplElf('u_boot_binman_syms') + self._SetupTplElf('u_boot_binman_syms') + data = self._DoReadFile('149_symbols_tpl.dts') + sym_values = struct.pack('; + #size-cells = <1>; + + binman { + pad-byte = <0xff>; + u-boot-spl { + offset = <4>; + }; + + u-boot-spl2 { + offset = <0x18>; + type = "u-boot-spl"; + }; + + u-boot { + offset = <0x30>; + }; + + section { + u-boot-tpl { + type = "u-boot-tpl"; + }; + }; + }; +}; From 9255f3c58ef509ea8d6480edcb0bd332b99ee63a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:01 -0600 Subject: [PATCH 21/61] binman: Use underscore in test filenames At present a small number of test files use hyphens instead of underscores. Rename them for consistency. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 28 +++++++++---------- .../test/{029_x86-rom.dts => 029_x86_rom.dts} | 0 ...no-desc.dts => 030_x86_rom_me_no_desc.dts} | 0 ...{031_x86-rom-me.dts => 031_x86_rom_me.dts} | 0 .../{032_intel-vga.dts => 032_intel_vga.dts} | 0 ...33_x86-start16.dts => 033_x86_start16.dts} | 0 .../{042_intel-fsp.dts => 042_intel_fsp.dts} | 0 .../{043_intel-cmc.dts => 043_intel_cmc.dts} | 0 .../{046_intel-vbt.dts => 046_intel_vbt.dts} | 0 ...tart16-spl.dts => 048_x86_start16_spl.dts} | 0 ...tart16-tpl.dts => 081_x86_start16_tpl.dts} | 0 ..._x86-rom-ifwi.dts => 111_x86_rom_ifwi.dts} | 0 ...nodesc.dts => 112_x86_rom_ifwi_nodesc.dts} | 0 ...nodata.dts => 113_x86_rom_ifwi_nodata.dts} | 0 14 files changed, 14 insertions(+), 14 deletions(-) rename tools/binman/test/{029_x86-rom.dts => 029_x86_rom.dts} (100%) rename tools/binman/test/{030_x86-rom-me-no-desc.dts => 030_x86_rom_me_no_desc.dts} (100%) rename tools/binman/test/{031_x86-rom-me.dts => 031_x86_rom_me.dts} (100%) rename tools/binman/test/{032_intel-vga.dts => 032_intel_vga.dts} (100%) rename tools/binman/test/{033_x86-start16.dts => 033_x86_start16.dts} (100%) rename tools/binman/test/{042_intel-fsp.dts => 042_intel_fsp.dts} (100%) rename tools/binman/test/{043_intel-cmc.dts => 043_intel_cmc.dts} (100%) rename tools/binman/test/{046_intel-vbt.dts => 046_intel_vbt.dts} (100%) rename tools/binman/test/{048_x86-start16-spl.dts => 048_x86_start16_spl.dts} (100%) rename tools/binman/test/{081_x86-start16-tpl.dts => 081_x86_start16_tpl.dts} (100%) rename tools/binman/test/{111_x86-rom-ifwi.dts => 111_x86_rom_ifwi.dts} (100%) rename tools/binman/test/{112_x86-rom-ifwi-nodesc.dts => 112_x86_rom_ifwi_nodesc.dts} (100%) rename tools/binman/test/{113_x86-rom-ifwi-nodata.dts => 113_x86_rom_ifwi_nodata.dts} (100%) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 0eb0667aac..2e85a87e30 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -921,7 +921,7 @@ class TestFunctional(unittest.TestCase): def testPackX86Rom(self): """Test that a basic x86 ROM can be created""" self._SetupSplElf() - data = self._DoReadFile('029_x86-rom.dts') + data = self._DoReadFile('029_x86_rom.dts') self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 7) + U_BOOT_SPL_DATA + tools.GetBytes(0, 2), data) @@ -929,21 +929,21 @@ class TestFunctional(unittest.TestCase): """Test that an invalid Intel descriptor entry is detected""" TestFunctional._MakeInputFile('descriptor.bin', b'') with self.assertRaises(ValueError) as e: - self._DoTestFile('031_x86-rom-me.dts') + self._DoTestFile('031_x86_rom_me.dts') self.assertIn("Node '/binman/intel-descriptor': Cannot find Intel Flash Descriptor (FD) signature", str(e.exception)) def testPackX86RomBadDesc(self): """Test that the Intel requires a descriptor entry""" with self.assertRaises(ValueError) as e: - self._DoTestFile('030_x86-rom-me-no-desc.dts') + self._DoTestFile('030_x86_rom_me_no_desc.dts') self.assertIn("Node '/binman/intel-me': No offset set with " "offset-unset: should another entry provide this correct " "offset?", str(e.exception)) def testPackX86RomMe(self): """Test that an x86 ROM with an ME region can be created""" - data = self._DoReadFile('031_x86-rom-me.dts') + data = self._DoReadFile('031_x86_rom_me.dts') expected_desc = tools.ReadFile(self.TestFile('descriptor.bin')) if data[:0x1000] != expected_desc: self.fail('Expected descriptor binary at start of image') @@ -951,12 +951,12 @@ class TestFunctional(unittest.TestCase): def testPackVga(self): """Test that an image with a VGA binary can be created""" - data = self._DoReadFile('032_intel-vga.dts') + data = self._DoReadFile('032_intel_vga.dts') self.assertEqual(VGA_DATA, data[:len(VGA_DATA)]) def testPackStart16(self): """Test that an image with an x86 start16 region can be created""" - data = self._DoReadFile('033_x86-start16.dts') + data = self._DoReadFile('033_x86_start16.dts') self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)]) def testPackPowerpcMpc85xxBootpgResetvec(self): @@ -1144,17 +1144,17 @@ class TestFunctional(unittest.TestCase): def testPackFsp(self): """Test that an image with a FSP binary can be created""" - data = self._DoReadFile('042_intel-fsp.dts') + data = self._DoReadFile('042_intel_fsp.dts') self.assertEqual(FSP_DATA, data[:len(FSP_DATA)]) def testPackCmc(self): """Test that an image with a CMC binary can be created""" - data = self._DoReadFile('043_intel-cmc.dts') + data = self._DoReadFile('043_intel_cmc.dts') self.assertEqual(CMC_DATA, data[:len(CMC_DATA)]) def testPackVbt(self): """Test that an image with a VBT binary can be created""" - data = self._DoReadFile('046_intel-vbt.dts') + data = self._DoReadFile('046_intel_vbt.dts') self.assertEqual(VBT_DATA, data[:len(VBT_DATA)]) def testSplBssPad(self): @@ -1175,7 +1175,7 @@ class TestFunctional(unittest.TestCase): def testPackStart16Spl(self): """Test that an image with an x86 start16 SPL region can be created""" - data = self._DoReadFile('048_x86-start16-spl.dts') + data = self._DoReadFile('048_x86_start16_spl.dts') self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)]) def _PackUbootSplMicrocode(self, dts, ucode_second=False): @@ -1594,7 +1594,7 @@ class TestFunctional(unittest.TestCase): def testPackStart16Tpl(self): """Test that an image with an x86 start16 TPL region can be created""" - data = self._DoReadFile('081_x86-start16-tpl.dts') + data = self._DoReadFile('081_x86_start16_tpl.dts') self.assertEqual(X86_START16_TPL_DATA, data[:len(X86_START16_TPL_DATA)]) def testSelectImage(self): @@ -2065,20 +2065,20 @@ class TestFunctional(unittest.TestCase): def testPackX86RomIfwi(self): """Test that an x86 ROM with Integrated Firmware Image can be created""" self._SetupIfwi('fitimage.bin') - data = self._DoReadFile('111_x86-rom-ifwi.dts') + data = self._DoReadFile('111_x86_rom_ifwi.dts') self._CheckIfwi(data) def testPackX86RomIfwiNoDesc(self): """Test that an x86 ROM with IFWI can be created from an ifwi.bin file""" self._SetupIfwi('ifwi.bin') - data = self._DoReadFile('112_x86-rom-ifwi-nodesc.dts') + data = self._DoReadFile('112_x86_rom_ifwi_nodesc.dts') self._CheckIfwi(data) def testPackX86RomIfwiNoData(self): """Test that an x86 ROM with IFWI handles missing data""" self._SetupIfwi('ifwi.bin') with self.assertRaises(ValueError) as e: - data = self._DoReadFile('113_x86-rom-ifwi-nodata.dts') + data = self._DoReadFile('113_x86_rom_ifwi_nodata.dts') self.assertIn('Could not complete processing of contents', str(e.exception)) diff --git a/tools/binman/test/029_x86-rom.dts b/tools/binman/test/029_x86_rom.dts similarity index 100% rename from tools/binman/test/029_x86-rom.dts rename to tools/binman/test/029_x86_rom.dts diff --git a/tools/binman/test/030_x86-rom-me-no-desc.dts b/tools/binman/test/030_x86_rom_me_no_desc.dts similarity index 100% rename from tools/binman/test/030_x86-rom-me-no-desc.dts rename to tools/binman/test/030_x86_rom_me_no_desc.dts diff --git a/tools/binman/test/031_x86-rom-me.dts b/tools/binman/test/031_x86_rom_me.dts similarity index 100% rename from tools/binman/test/031_x86-rom-me.dts rename to tools/binman/test/031_x86_rom_me.dts diff --git a/tools/binman/test/032_intel-vga.dts b/tools/binman/test/032_intel_vga.dts similarity index 100% rename from tools/binman/test/032_intel-vga.dts rename to tools/binman/test/032_intel_vga.dts diff --git a/tools/binman/test/033_x86-start16.dts b/tools/binman/test/033_x86_start16.dts similarity index 100% rename from tools/binman/test/033_x86-start16.dts rename to tools/binman/test/033_x86_start16.dts diff --git a/tools/binman/test/042_intel-fsp.dts b/tools/binman/test/042_intel_fsp.dts similarity index 100% rename from tools/binman/test/042_intel-fsp.dts rename to tools/binman/test/042_intel_fsp.dts diff --git a/tools/binman/test/043_intel-cmc.dts b/tools/binman/test/043_intel_cmc.dts similarity index 100% rename from tools/binman/test/043_intel-cmc.dts rename to tools/binman/test/043_intel_cmc.dts diff --git a/tools/binman/test/046_intel-vbt.dts b/tools/binman/test/046_intel_vbt.dts similarity index 100% rename from tools/binman/test/046_intel-vbt.dts rename to tools/binman/test/046_intel_vbt.dts diff --git a/tools/binman/test/048_x86-start16-spl.dts b/tools/binman/test/048_x86_start16_spl.dts similarity index 100% rename from tools/binman/test/048_x86-start16-spl.dts rename to tools/binman/test/048_x86_start16_spl.dts diff --git a/tools/binman/test/081_x86-start16-tpl.dts b/tools/binman/test/081_x86_start16_tpl.dts similarity index 100% rename from tools/binman/test/081_x86-start16-tpl.dts rename to tools/binman/test/081_x86_start16_tpl.dts diff --git a/tools/binman/test/111_x86-rom-ifwi.dts b/tools/binman/test/111_x86_rom_ifwi.dts similarity index 100% rename from tools/binman/test/111_x86-rom-ifwi.dts rename to tools/binman/test/111_x86_rom_ifwi.dts diff --git a/tools/binman/test/112_x86-rom-ifwi-nodesc.dts b/tools/binman/test/112_x86_rom_ifwi_nodesc.dts similarity index 100% rename from tools/binman/test/112_x86-rom-ifwi-nodesc.dts rename to tools/binman/test/112_x86_rom_ifwi_nodesc.dts diff --git a/tools/binman/test/113_x86-rom-ifwi-nodata.dts b/tools/binman/test/113_x86_rom_ifwi_nodata.dts similarity index 100% rename from tools/binman/test/113_x86-rom-ifwi-nodata.dts rename to tools/binman/test/113_x86_rom_ifwi_nodata.dts From dfdd2b62173e473580e51804b718389bad37ee3a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:02 -0600 Subject: [PATCH 22/61] binman: Rename some two-digit test files Two of the test files somehow were not converted to three digits. Fix them, using the next available numbers. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 4 ++-- ...rt_together.dts => 098_4gb_and_skip_at_start_together.dts} | 0 ...g_resetvec.dts => 150_powerpc_mpc85xx_bootpg_resetvec.dts} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename tools/binman/test/{80_4gb_and_skip_at_start_together.dts => 098_4gb_and_skip_at_start_together.dts} (100%) rename tools/binman/test/{81_powerpc_mpc85xx_bootpg_resetvec.dts => 150_powerpc_mpc85xx_bootpg_resetvec.dts} (100%) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 2e85a87e30..fe3365255f 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -906,7 +906,7 @@ class TestFunctional(unittest.TestCase): """Test that the end-at-4gb and skip-at-size property can't be used together""" with self.assertRaises(ValueError) as e: - self._DoTestFile('80_4gb_and_skip_at_start_together.dts') + self._DoTestFile('098_4gb_and_skip_at_start_together.dts') self.assertIn("Image '/binman': Provide either 'end-at-4gb' or " "'skip-at-start'", str(e.exception)) @@ -962,7 +962,7 @@ class TestFunctional(unittest.TestCase): def testPackPowerpcMpc85xxBootpgResetvec(self): """Test that an image with powerpc-mpc85xx-bootpg-resetvec can be created""" - data = self._DoReadFile('81_powerpc_mpc85xx_bootpg_resetvec.dts') + data = self._DoReadFile('150_powerpc_mpc85xx_bootpg_resetvec.dts') self.assertEqual(PPC_MPC85XX_BR_DATA, data[:len(PPC_MPC85XX_BR_DATA)]) def _RunMicrocodeTest(self, dts_fname, nodtb_data, ucode_second=False): diff --git a/tools/binman/test/80_4gb_and_skip_at_start_together.dts b/tools/binman/test/098_4gb_and_skip_at_start_together.dts similarity index 100% rename from tools/binman/test/80_4gb_and_skip_at_start_together.dts rename to tools/binman/test/098_4gb_and_skip_at_start_together.dts diff --git a/tools/binman/test/81_powerpc_mpc85xx_bootpg_resetvec.dts b/tools/binman/test/150_powerpc_mpc85xx_bootpg_resetvec.dts similarity index 100% rename from tools/binman/test/81_powerpc_mpc85xx_bootpg_resetvec.dts rename to tools/binman/test/150_powerpc_mpc85xx_bootpg_resetvec.dts From bf4d0e284267067a65000f37c66cd4f05253381f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:03 -0600 Subject: [PATCH 23/61] binman: Avoid needing the section size in advance Entries which include a section and need to obtain its contents call GetData(), as with any other entry. But the current implementation of this method in entry_Section requires the size of the section to be known. If it is unknown, an error is produced, since size is None: TypeError: can't multiply sequence by non-int of type 'NoneType' There is no need to know the size in advance since the code can be adjusted to build up the section piece by piece, instead of patching each entry into an existing bytearray. Update the code to handle this and add a test. Signed-off-by: Simon Glass --- tools/binman/etype/section.py | 14 +++++--- tools/binman/ftest.py | 6 ++++ .../binman/test/151_x86_rom_ifwi_section.dts | 33 +++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 tools/binman/test/151_x86_rom_ifwi_section.dts diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 8179daf562..8fea6e0b24 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -142,13 +142,19 @@ class Entry_section(Entry): return self.GetEntryContents() def GetData(self): - section_data = tools.GetBytes(self._pad_byte, self.size) + section_data = b'' for entry in self._entries.values(): data = entry.GetData() - base = self.pad_before + entry.offset - self._skip_at_start - section_data = (section_data[:base] + data + - section_data[base + len(data):]) + base = self.pad_before + (entry.offset or 0) - self._skip_at_start + pad = base - len(section_data) + if pad > 0: + section_data += tools.GetBytes(self._pad_byte, pad) + section_data += data + if self.size: + pad = self.size - len(section_data) + if pad > 0: + section_data += tools.GetBytes(self._pad_byte, pad) self.Detail('GetData: %d entries, total size %#x' % (len(self._entries), len(section_data))) return section_data diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index fe3365255f..6b0ab7fdc2 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -3321,6 +3321,12 @@ class TestFunctional(unittest.TestCase): expected4 = sym_values + U_BOOT_TPL_DATA[16:] self.assertEqual(expected4, data[upto3:]) + def testPackX86RomIfwiSectiom(self): + """Test that a section can be placed in an IFWI region""" + self._SetupIfwi('fitimage.bin') + data = self._DoReadFile('151_x86_rom_ifwi_section.dts') + self._CheckIfwi(data) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/151_x86_rom_ifwi_section.dts b/tools/binman/test/151_x86_rom_ifwi_section.dts new file mode 100644 index 0000000000..7e455c3a4b --- /dev/null +++ b/tools/binman/test/151_x86_rom_ifwi_section.dts @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + sort-by-offset; + end-at-4gb; + size = <0x800000>; + intel-descriptor { + filename = "descriptor.bin"; + }; + + intel-ifwi { + offset-unset; + filename = "fitimage.bin"; + convert-fit; + + section { + ifwi-replace; + ifwi-subpart = "IBBP"; + ifwi-entry = "IBBL"; + u-boot-tpl { + }; + u-boot-dtb { + }; + }; + }; + }; +}; From eb0086fa59e61561a5eca61b9ab8323d8a0cbf9c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:04 -0600 Subject: [PATCH 24/61] binman: Increase size of TPL and SPL test data At present these are large enough to hold 20 bytes of symbol data. Add four more bytes so we can add another test. Unfortunately at present this involves changing a few test files to make room. We could adjust the test files to not specify sizes for entries. Then we could make the tests check the actual sizes. But for now, leave it as it is, since the effort is minor. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 14 +++++++------- tools/binman/test/021_image_pad.dts | 2 +- tools/binman/test/024_sorted.dts | 2 +- tools/binman/test/028_pack_4gb_outside.dts | 2 +- tools/binman/test/029_x86_rom.dts | 2 +- tools/binman/test/053_symbols.dts | 2 +- tools/binman/test/149_symbols_tpl.dts | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 6b0ab7fdc2..5433c80e8e 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -39,8 +39,8 @@ import tout # Contents of test files, corresponding to different entry types U_BOOT_DATA = b'1234' U_BOOT_IMG_DATA = b'img' -U_BOOT_SPL_DATA = b'56780123456789abcde' -U_BOOT_TPL_DATA = b'tpl9876543210fedcb' +U_BOOT_SPL_DATA = b'56780123456789abcdefghi' +U_BOOT_TPL_DATA = b'tpl9876543210fedcbazyw' BLOB_DATA = b'89' ME_DATA = b'0abcd' VGA_DATA = b'vga' @@ -922,7 +922,7 @@ class TestFunctional(unittest.TestCase): """Test that a basic x86 ROM can be created""" self._SetupSplElf() data = self._DoReadFile('029_x86_rom.dts') - self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 7) + U_BOOT_SPL_DATA + + self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 3) + U_BOOT_SPL_DATA + tools.GetBytes(0, 2), data) def testPackX86RomMeNoDesc(self): @@ -1236,7 +1236,7 @@ class TestFunctional(unittest.TestCase): self._SetupSplElf('u_boot_binman_syms') data = self._DoReadFile('053_symbols.dts') - sym_values = struct.pack('; + offset = <24>; }; }; }; diff --git a/tools/binman/test/024_sorted.dts b/tools/binman/test/024_sorted.dts index d35d39f077..b79d9adf68 100644 --- a/tools/binman/test/024_sorted.dts +++ b/tools/binman/test/024_sorted.dts @@ -7,7 +7,7 @@ binman { sort-by-offset; u-boot { - offset = <22>; + offset = <26>; }; u-boot-spl { diff --git a/tools/binman/test/028_pack_4gb_outside.dts b/tools/binman/test/028_pack_4gb_outside.dts index 2216abfb70..11a1f6059e 100644 --- a/tools/binman/test/028_pack_4gb_outside.dts +++ b/tools/binman/test/028_pack_4gb_outside.dts @@ -13,7 +13,7 @@ }; u-boot-spl { - offset = <0xffffffeb>; + offset = <0xffffffe7>; }; }; }; diff --git a/tools/binman/test/029_x86_rom.dts b/tools/binman/test/029_x86_rom.dts index d5c69f9d4a..88aa007bba 100644 --- a/tools/binman/test/029_x86_rom.dts +++ b/tools/binman/test/029_x86_rom.dts @@ -13,7 +13,7 @@ }; u-boot-spl { - offset = <0xffffffeb>; + offset = <0xffffffe7>; }; }; }; diff --git a/tools/binman/test/053_symbols.dts b/tools/binman/test/053_symbols.dts index 9f135676cb..8af575158f 100644 --- a/tools/binman/test/053_symbols.dts +++ b/tools/binman/test/053_symbols.dts @@ -10,7 +10,7 @@ }; u-boot { - offset = <20>; + offset = <24>; }; u-boot-spl2 { diff --git a/tools/binman/test/149_symbols_tpl.dts b/tools/binman/test/149_symbols_tpl.dts index 087e10f292..dfc84af5e7 100644 --- a/tools/binman/test/149_symbols_tpl.dts +++ b/tools/binman/test/149_symbols_tpl.dts @@ -11,12 +11,12 @@ }; u-boot-spl2 { - offset = <0x18>; + offset = <0x1c>; type = "u-boot-spl"; }; u-boot { - offset = <0x30>; + offset = <0x34>; }; section { From b87064c2496785dde9e33fcdf84175d64163db57 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:05 -0600 Subject: [PATCH 25/61] binman: Allow support for writing a size symbol to binaries It is useful to be able to access the size of an image in SPL, with something like: binman_sym_declare(unsigned long, u_boot_any, size); ... ulong u_boot_size = binman_sym(ulong, u_boot_any, size); Add support for this and update the tests. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 4 ++-- tools/binman/etype/section.py | 2 ++ tools/binman/ftest.py | 14 +++++++------- tools/binman/test/u_boot_binman_syms.c | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index f05545bcb1..c0c11cb340 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -155,11 +155,11 @@ class TestElf(unittest.TestCase): This should produce -1 values for all thress symbols, taking up the first 16 bytes of the image. """ - entry = FakeEntry(20) + entry = FakeEntry(24) section = FakeSection(sym_value=None) elf_fname = self.ElfTestFile('u_boot_binman_syms') syms = elf.LookupAndWriteSymbols(elf_fname, entry, section) - self.assertEqual(tools.GetBytes(255, 16) + tools.GetBytes(ord('a'), 4), + self.assertEqual(tools.GetBytes(255, 20) + tools.GetBytes(ord('a'), 4), entry.data) def testDebug(self): diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 8fea6e0b24..ab0c42cee0 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -344,6 +344,8 @@ class Entry_section(Entry): return entry.offset elif prop_name == 'image_pos': return entry.image_pos + if prop_name == 'size': + return entry.size else: raise ValueError("%s: No such property '%s'" % (msg, prop_name)) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 5433c80e8e..6d59fa4874 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -1236,10 +1236,10 @@ class TestFunctional(unittest.TestCase): self._SetupSplElf('u_boot_binman_syms') data = self._DoReadFile('053_symbols.dts') - sym_values = struct.pack(' Date: Sat, 24 Aug 2019 07:23:07 -0600 Subject: [PATCH 26/61] binman: Add support for Intel FSP meminit The Intel FSP supports initialising memory early during boot using a binary blob called 'fspm'. Add support for this. Signed-off-by: Simon Glass --- tools/binman/README.entries | 17 +++++++++++++++++ tools/binman/etype/intel_fsp_m.py | 27 +++++++++++++++++++++++++++ tools/binman/ftest.py | 8 ++++++++ tools/binman/test/152_intel_fsp_m.dts | 14 ++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_m.py create mode 100644 tools/binman/test/152_intel_fsp_m.dts diff --git a/tools/binman/README.entries b/tools/binman/README.entries index dba51e6daa..bce2244596 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -427,6 +427,23 @@ See README.x86 for information about x86 binary blobs. +Entry: intel-fsp-m: Entry containing Intel Firmware Support Package (FSP) memory init +------------------------------------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of file to read into entry + +This file contains a binary blob which is used on some devices to set up +SDRAM. U-Boot executes this code in SPL so that it can make full use of +memory. Documentation is typically not available in sufficient detail to +allow U-Boot do this this itself.. + +An example filename is 'fsp_m.bin' + +See README.x86 for information about x86 binary blobs. + + + Entry: intel-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file ---------------------------------------------------------------------------------- diff --git a/tools/binman/etype/intel_fsp_m.py b/tools/binman/etype/intel_fsp_m.py new file mode 100644 index 0000000000..2d6b2b6621 --- /dev/null +++ b/tools/binman/etype/intel_fsp_m.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass +# +# Entry-type module for Intel Firmware Support Package binary blob (T section) +# + +from entry import Entry +from blob import Entry_blob + +class Entry_intel_fsp_m(Entry_blob): + """Entry containing Intel Firmware Support Package (FSP) memory init + + Properties / Entry arguments: + - filename: Filename of file to read into entry + + This file contains a binary blob which is used on some devices to set up + SDRAM. U-Boot executes this code in SPL so that it can make full use of + memory. Documentation is typically not available in sufficient detail to + allow U-Boot do this this itself.. + + An example filename is 'fsp_m.bin' + + See README.x86 for information about x86 binary blobs. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 6d59fa4874..481f0dd21a 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -72,6 +72,7 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " + b"sorry you're alive\n") COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data' REFCODE_DATA = b'refcode' +FSP_M_DATA = b'fsp_m' # The expected size for the device tree in some tests EXTRACT_DTB_SIZE = 0x3c9 @@ -147,6 +148,7 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputDir('devkeys') TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA) TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) + TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA) cls._elf_testdir = os.path.join(cls._indir, 'elftest') elf_test.BuildElfTestFiles(cls._elf_testdir) @@ -3327,6 +3329,12 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('151_x86_rom_ifwi_section.dts') self._CheckIfwi(data) + def testPackFspM(self): + """Test that an image with a FSP memory-init binary can be created""" + data = self._DoReadFile('152_intel_fsp_m.dts') + self.assertEqual(FSP_M_DATA, data[:len(FSP_M_DATA)]) + + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/152_intel_fsp_m.dts b/tools/binman/test/152_intel_fsp_m.dts new file mode 100644 index 0000000000..b6010f31c2 --- /dev/null +++ b/tools/binman/test/152_intel_fsp_m.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-m { + filename = "fsp_m.bin"; + }; + }; +}; From 7d645e08d6cf0c926d1fdfccd6e72d73ced0b68e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:08 -0600 Subject: [PATCH 27/61] binman: Fix entry comment for Intel descriptor This comment references another entry type. Fix it. Signed-off-by: Simon Glass --- tools/binman/etype/intel_descriptor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/etype/intel_descriptor.py b/tools/binman/etype/intel_descriptor.py index fb5e889ebf..b6477931d6 100644 --- a/tools/binman/etype/intel_descriptor.py +++ b/tools/binman/etype/intel_descriptor.py @@ -2,7 +2,7 @@ # Copyright (c) 2016 Google, Inc # Written by Simon Glass # -# Entry-type module for 'u-boot' +# Entry-type module for Intel flash descriptor # import struct From afc68a8a4d068a7cbfdb6f85ad7d474b901ad4fb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:09 -0600 Subject: [PATCH 28/61] binman: Update IFWI entry to read entries outside constructor At present this class reads its entries in the constructor. This is not how things should be done now. Update it. Signed-off-by: Simon Glass --- tools/binman/etype/intel_ifwi.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index e4da3e498a..ef2b35706f 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -48,7 +48,10 @@ class Entry_intel_ifwi(Entry_blob): Entry_blob.__init__(self, section, etype, node) self._convert_fit = fdt_util.GetBool(self._node, 'convert-fit') self._ifwi_entries = OrderedDict() + + def ReadNode(self): self._ReadSubnodes() + Entry_blob.ReadNode(self) def ObtainContents(self): """Get the contects for the IFWI From 51f20726ca0e49663b018daa8b42150dd3c58748 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:10 -0600 Subject: [PATCH 29/61] binman: Update IFWI entry to support updates Add support for the ProcessContents() method in this entry so that it is possible to support entries which change after initial creation. Signed-off-by: Simon Glass --- tools/binman/etype/intel_ifwi.py | 46 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index ef2b35706f..17792defe9 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -53,22 +53,8 @@ class Entry_intel_ifwi(Entry_blob): self._ReadSubnodes() Entry_blob.ReadNode(self) - def ObtainContents(self): - """Get the contects for the IFWI - - Unfortunately we cannot create anything from scratch here, as Intel has - tools which create precursor binaries with lots of data and settings, - and these are not incorporated into binman. - - The first step is to get a file in the IFWI format. This is either - supplied directly or is extracted from a fitimage using the 'create' - subcommand. - - After that we delete the OBBP sub-partition and add each of the files - that we want in the IFWI file, one for each sub-entry of the IWFI node. - """ - self._pathname = tools.GetInputFilename(self._filename) - + def _BuildIfwi(self): + """Build the contents of the IFWI and write it to the 'data' property""" # Create the IFWI file if needed if self._convert_fit: inname = self._pathname @@ -85,8 +71,6 @@ class Entry_intel_ifwi(Entry_blob): for entry in self._ifwi_entries.values(): # First get the input data and put it in a file - if not entry.ObtainContents(): - return False data = entry.GetData() uniq = self.GetUniqueName() input_fname = tools.GetOutputFilename('input.%s' % uniq) @@ -99,6 +83,32 @@ class Entry_intel_ifwi(Entry_blob): self.ReadBlobContents() return True + def ObtainContents(self): + """Get the contects for the IFWI + + Unfortunately we cannot create anything from scratch here, as Intel has + tools which create precursor binaries with lots of data and settings, + and these are not incorporated into binman. + + The first step is to get a file in the IFWI format. This is either + supplied directly or is extracted from a fitimage using the 'create' + subcommand. + + After that we delete the OBBP sub-partition and add each of the files + that we want in the IFWI file, one for each sub-entry of the IWFI node. + """ + self._pathname = tools.GetInputFilename(self._filename) + for entry in self._ifwi_entries.values(): + if not entry.ObtainContents(): + return False + return self._BuildIfwi() + + def ProcessContents(self): + orig_data = self.data + self._BuildIfwi() + same = orig_data == self.data + return same + def _ReadSubnodes(self): """Read the subnodes to find out what should go in this IFWI""" for node in self._node.subnodes: From ed9571d269e814975c0626f92e6f322343178edf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:11 -0600 Subject: [PATCH 30/61] binman: Support writing symbols into entries within an IFWI The Intel IFWI (Integrated Firmware Image) is effectively a section with other entries inside it. Support writing symbol information into entries within it. Signed-off-by: Simon Glass --- tools/binman/etype/intel_ifwi.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index 17792defe9..36aadc210c 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -118,3 +118,8 @@ class Entry_intel_ifwi(Entry_blob): entry._ifwi_subpart = fdt_util.GetString(node, 'ifwi-subpart') entry._ifwi_entry_name = fdt_util.GetString(node, 'ifwi-entry') self._ifwi_entries[entry._ifwi_subpart] = entry + + def WriteSymbols(self, section): + """Write symbol values into binary files for access at run time""" + for entry in self._ifwi_entries.values(): + entry.WriteSymbols(self) From 261cbe0b3716737e328481b6f3f51cfcb7f13e31 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:12 -0600 Subject: [PATCH 31/61] binman: Write symbol info before image inclusion At present the symbol information is written to binaries just before binman exits. This is fine for entries within sections since the section contents is calculated when it is needed, so the updated symbol values are included in the image that is written. However some binaries are inside entries which have already generated their contents and do not notice that the entries have changed (e.g. Intel IFWI). Move the symbol writing earlier to cope with this. Signed-off-by: Simon Glass --- tools/binman/control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/control.py b/tools/binman/control.py index 8268eda37e..fe24b2a6a7 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -437,6 +437,7 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True, for dtb_item in state.GetAllFdts(): dtb_item.Sync() dtb_item.Flush() + image.WriteSymbols() sizes_ok = image.ProcessEntryContents() if sizes_ok: break @@ -445,7 +446,6 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True, image.Raise('Entries changed size after packing (tried %s passes)' % passes) - image.WriteSymbols() image.BuildImage() if write_map: image.WriteMap() From aed6c0b04350aaecdf3d93db5ee9b374f425222b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:13 -0600 Subject: [PATCH 32/61] binman: Add logging for the number of pack passes Sometimes binman takes multiple passes to complete packing an image. Add logging to indicate this. Signed-off-by: Simon Glass --- tools/binman/control.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/binman/control.py b/tools/binman/control.py index fe24b2a6a7..68ad5fc2c0 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -442,6 +442,7 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True, if sizes_ok: break image.ResetForPack() + tout.Info('Pack completed after %d pass(es)' % (pack_pass + 1)) if not sizes_ok: image.Raise('Entries changed size after packing (tried %s passes)' % passes) From d1d5ffd554a88562a88801273a2f8d134827605a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 24 Aug 2019 07:23:14 -0600 Subject: [PATCH 33/61] binman: Drop comment-out code in testUpdateFdtOutput() This code is not needed so drop it. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 481f0dd21a..7000de9d42 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -1668,8 +1668,6 @@ class TestFunctional(unittest.TestCase): # source file (e.g. test/075_fdt_update_all.dts) thus does not enter # binman as a file called u-boot.dtb. To fix this, copy the file # over to the expected place. - #tools.WriteFile(os.path.join(self._indir, 'u-boot.dtb'), - #tools.ReadFile(tools.GetOutputFilename('source.dtb'))) start = 0 for fname in ['u-boot.dtb.out', 'spl/u-boot-spl.dtb.out', 'tpl/u-boot-tpl.dtb.out']: From c20851b3d850dd859f202d2395e8dde0fc81c1ce Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 2 Aug 2019 14:48:00 +0200 Subject: [PATCH 34/61] dm: pinctrl: introduce PINCONF_RECURSIVE option In the Linux pinctrl binding, the pin configuration nodes don't need to be direct children of the pin controller device (may be grandchildren for example). This behavior is managed with the pinconfig u-class which recursively bind all the sub-node of the pin controller. But for some binding (when pin configuration is only children of pin controller) that is not necessary. U-Boot can save memory and reduce the number of pinconf instance when this feature is deactivated (for arch stm32mp for example for SPL). This patch allows to control this feature with a new option CONFIG_PINCONF_RECURSIVE when it is possible for each individual pin controller device. Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- drivers/pinctrl/Kconfig | 25 +++++++++++++++++++++++++ drivers/pinctrl/pinctrl-uclass.c | 2 ++ 2 files changed, 27 insertions(+) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index a0ac167d14..deee92411c 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -59,6 +59,22 @@ config PINCONF This option enables pin configuration through the generic pinctrl framework. +config PINCONF_RECURSIVE + bool "Support recursive binding for pin configuration nodes" + depends on PINCTRL_FULL + default n if ARCH_STM32MP + default y + help + In the Linux pinctrl binding, the pin configuration nodes need not be + direct children of the pin controller device (may be grandchildren for + example). It is define is each individual pin controller device. + Say Y here if you want to keep this behavior with the pinconfig + u-class: all sub are recursivelly bounded. + If the option is disabled, this behavior is deactivated and only + the direct children of pin controller will be assumed as pin + configuration; you can save memory footprint when this feature is + no needed. + config SPL_PINCTRL bool "Support pin controllers in SPL" depends on SPL && SPL_DM @@ -104,6 +120,15 @@ config SPL_PINCONF This option is an SPL-variant of the PINCONF option. See the help of PINCONF for details. +config SPL_PINCONF_RECURSIVE + bool "Support recursive binding for pin configuration nodes in SPL" + depends on SPL_PINCTRL_FULL + default n if ARCH_STM32MP + default y + help + This option is an SPL-variant of the PINCONF_RECURSIVE option. + See the help of PINCONF_RECURSIVE for details. + if PINCTRL || SPL_PINCTRL config PINCTRL_AR933X diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index 5b1cd29d86..bf799a701c 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -151,7 +151,9 @@ static int pinconfig_post_bind(struct udevice *dev) UCLASS_DRIVER(pinconfig) = { .id = UCLASS_PINCONFIG, +#if CONFIG_IS_ENABLED(PINCONFIG_RECURSIVE) .post_bind = pinconfig_post_bind, +#endif .name = "pinconfig", }; From 2cde3ea1d01f4b72770b7c0c812a7377be15ea43 Mon Sep 17 00:00:00 2001 From: Ralph Siemsen Date: Mon, 19 Aug 2019 15:00:30 -0400 Subject: [PATCH 35/61] doc: add full path to patman README Make it a little easier to find the documentation. Signed-off-by: Ralph Siemsen Reviewed-by: Simon Glass --- doc/driver-model/spi-howto.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/driver-model/spi-howto.rst b/doc/driver-model/spi-howto.rst index a538fdcb93..5540eb7d38 100644 --- a/doc/driver-model/spi-howto.rst +++ b/doc/driver-model/spi-howto.rst @@ -650,7 +650,7 @@ Prepare patches and send them to the mailing lists -------------------------------------------------- You can use 'tools/patman/patman' to prepare, check and send patches for -your work. See the README for details. +your work. See tools/patman/README for details. A little note about SPI uclass features --------------------------------------- From 073e6d65d138edd015ece4d94dcfe2a3e00dccde Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 27 Aug 2019 17:17:03 +0900 Subject: [PATCH 36/61] sandbox: fix cpu property in test.dts for pytest When I tried to run some new efi tests with pytest, efi_smbios_register() triggered a segmentation fault. Here is the location where it happened: efi_init_obj_list() efi_smbios_register() write_smbios_table() smbios_write_type4() smbios_write_type4_dm() where dev_get_parent_platdata() should return a pointer to struct cpu_platdata, but it is actually NULL because any cpu device on sandbox is attached to "root_driver." With this patch, this issue will be fixed by moving all the definitions of cpus under "cpus" node so that they have a "cpu_bus" parent. Signed-off-by: AKASHI Takahiro Reviewed-by: Bin Meng Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 5d9ab3724f..42b41fbf62 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -393,19 +393,21 @@ mbox-names = "other", "test"; }; - cpu-test1 { - compatible = "sandbox,cpu_sandbox"; - u-boot,dm-pre-reloc; - }; + cpus { + cpu-test1 { + compatible = "sandbox,cpu_sandbox"; + u-boot,dm-pre-reloc; + }; - cpu-test2 { - compatible = "sandbox,cpu_sandbox"; - u-boot,dm-pre-reloc; - }; + cpu-test2 { + compatible = "sandbox,cpu_sandbox"; + u-boot,dm-pre-reloc; + }; - cpu-test3 { - compatible = "sandbox,cpu_sandbox"; - u-boot,dm-pre-reloc; + cpu-test3 { + compatible = "sandbox,cpu_sandbox"; + u-boot,dm-pre-reloc; + }; }; i2s: i2s { From ce2dae3a44ccc2fe87a9589e3a70ba51885930ab Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Thu, 5 Sep 2019 10:48:46 +0200 Subject: [PATCH 37/61] libfdt: fdt_address_cells() and fdt_size_cells() Add internal fdt_cells() to avoid copy and paste. Fix typo in fdt_size_cells() documentation comment. This is based in upstream commit: c12b2b0 ("libfdt: fdt_address_cells() and fdt_size_cells()") but misses the test cases, as we don't implement them in U-Boot. Signed-off-by: Matthias Brugger Reviewed-by: Simon Glass --- scripts/dtc/libfdt/fdt_addresses.c | 35 +++++++++++------------------- scripts/dtc/libfdt/libfdt.h | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c index eff4dbcc72..49537b578d 100644 --- a/scripts/dtc/libfdt/fdt_addresses.c +++ b/scripts/dtc/libfdt/fdt_addresses.c @@ -1,6 +1,7 @@ /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2014 David Gibson + * Copyright (C) 2018 embedded brains GmbH * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. @@ -55,42 +56,32 @@ #include "libfdt_internal.h" -int fdt_address_cells(const void *fdt, int nodeoffset) +static int fdt_cells(const void *fdt, int nodeoffset, const char *name) { - const fdt32_t *ac; + const fdt32_t *c; int val; int len; - ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len); - if (!ac) + c = fdt_getprop(fdt, nodeoffset, name, &len); + if (!c) return 2; - if (len != sizeof(*ac)) + if (len != sizeof(*c)) return -FDT_ERR_BADNCELLS; - val = fdt32_to_cpu(*ac); + val = fdt32_to_cpu(*c); if ((val <= 0) || (val > FDT_MAX_NCELLS)) return -FDT_ERR_BADNCELLS; return val; } +int fdt_address_cells(const void *fdt, int nodeoffset) +{ + return fdt_cells(fdt, nodeoffset, "#address-cells"); +} + int fdt_size_cells(const void *fdt, int nodeoffset) { - const fdt32_t *sc; - int val; - int len; - - sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len); - if (!sc) - return 2; - - if (len != sizeof(*sc)) - return -FDT_ERR_BADNCELLS; - - val = fdt32_to_cpu(*sc); - if ((val < 0) || (val > FDT_MAX_NCELLS)) - return -FDT_ERR_BADNCELLS; - - return val; + return fdt_cells(fdt, nodeoffset, "#size-cells"); } diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index cf86ddba88..66f01fec53 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -1109,7 +1109,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset); * * returns: * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property + * 2, if the node has no #size-cells property * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid * #size-cells property * -FDT_ERR_BADMAGIC, From 0ba41ce1b7816c229cc19e0621148b98f990cb68 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Thu, 5 Sep 2019 10:48:47 +0200 Subject: [PATCH 38/61] libfdt: return correct value if #size-cells property is not present According to the device tree specification, the default value for was not present. This patch also makes fdt_address_cells() and fdt_size_cells() conform to the behaviour documented in libfdt.h. The defaults are only returned if fdt_getprop() returns -FDT_ERR_NOTFOUND, otherwise the actual error is returned. This is based on upstream commit: aa7254d ("libfdt: return correct value if #size-cells property is not present") but misses the test case part, as we don't implement them in U-Boot. Signed-off-by: Matthias Brugger --- scripts/dtc/libfdt/fdt_addresses.c | 16 +++++++++++++--- scripts/dtc/libfdt/libfdt.h | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c index 49537b578d..f13a87dfa0 100644 --- a/scripts/dtc/libfdt/fdt_addresses.c +++ b/scripts/dtc/libfdt/fdt_addresses.c @@ -64,7 +64,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name) c = fdt_getprop(fdt, nodeoffset, name, &len); if (!c) - return 2; + return len; if (len != sizeof(*c)) return -FDT_ERR_BADNCELLS; @@ -78,10 +78,20 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name) int fdt_address_cells(const void *fdt, int nodeoffset) { - return fdt_cells(fdt, nodeoffset, "#address-cells"); + int val; + + val = fdt_cells(fdt, nodeoffset, "#address-cells"); + if (val == -FDT_ERR_NOTFOUND) + return 2; + return val; } int fdt_size_cells(const void *fdt, int nodeoffset) { - return fdt_cells(fdt, nodeoffset, "#size-cells"); + int val; + + val = fdt_cells(fdt, nodeoffset, "#size-cells"); + if (val == -FDT_ERR_NOTFOUND) + return 1; + return val; } diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index 66f01fec53..5c778b115b 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -1109,7 +1109,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset); * * returns: * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #size-cells property + * 1, if the node has no #size-cells property * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid * #size-cells property * -FDT_ERR_BADMAGIC, From 8076fc298ee1004cfbd9f9f4882931aff1ffda06 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Thu, 5 Sep 2019 10:48:48 +0200 Subject: [PATCH 39/61] libfdt: Allow #size-cells of 0 The commit "libfdt: fdt_address_cells() and fdt_size_cells()" introduced a bug as it consolidated code between the helpers for getting be 0, and is frequently found so in practice for /cpus. IEEE1275 only requires implementations to handle 1..4 for #address-cells, although one could make a case for #address-cells == #size-cells == 0 being used to represent a bridge with a single port. While we're there, it's not totally obvious that the existing implicit cast of a u32 to int will give the correct results according to strict C, although it does work in practice. Straighten that up to cast only after we've made our range checks. This is based on upstream commit: b8d6eca ("libfdt: Allow #size-cells of 0") but misses the test cases,as we don't implement them in U-Boot. Signed-off-by: Matthias Brugger --- scripts/dtc/libfdt/fdt_addresses.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c index f13a87dfa0..788c143113 100644 --- a/scripts/dtc/libfdt/fdt_addresses.c +++ b/scripts/dtc/libfdt/fdt_addresses.c @@ -59,7 +59,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name) { const fdt32_t *c; - int val; + uint32_t val; int len; c = fdt_getprop(fdt, nodeoffset, name, &len); @@ -70,10 +70,10 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name) return -FDT_ERR_BADNCELLS; val = fdt32_to_cpu(*c); - if ((val <= 0) || (val > FDT_MAX_NCELLS)) + if (val > FDT_MAX_NCELLS) return -FDT_ERR_BADNCELLS; - return val; + return (int)val; } int fdt_address_cells(const void *fdt, int nodeoffset) @@ -81,6 +81,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset) int val; val = fdt_cells(fdt, nodeoffset, "#address-cells"); + if (val == 0) + return -FDT_ERR_BADNCELLS; if (val == -FDT_ERR_NOTFOUND) return 2; return val; From 7a3f15e7181cf5a9667ff410260397f0e51c9020 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Thu, 5 Sep 2019 10:48:49 +0200 Subject: [PATCH 40/61] dm: Fix default address cells return value Default address cells value on the livetree access function returns the wrong value. Fix this so that the value returned corresponds to the device tree specification. Signed-off-by: Matthias Brugger --- include/dm/of.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dm/of.h b/include/dm/of.h index 461e25aa19..6bef73b441 100644 --- a/include/dm/of.h +++ b/include/dm/of.h @@ -111,7 +111,7 @@ static inline const char *of_node_full_name(const struct device_node *np) /* Default #address and #size cells */ #if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT) -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1 +#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2 #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 #endif From d8206ff198afaf36061efb14ff6af5e6119b30e7 Mon Sep 17 00:00:00 2001 From: Kayla Theil Date: Fri, 6 Sep 2019 12:40:45 +0200 Subject: [PATCH 41/61] tpm2: Don't assume active low reset value The reset function sets the pin to 0 then 1 but if the pin is marked ACTIVE_LOW in the DT it gets inverted and leaves the TPM in reset. Let the gpio driver take care of the reset polarity. Signed-off-by: Kayla Theil --- drivers/tpm/tpm2_tis_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c index 7186c179d1..3d105fddba 100644 --- a/drivers/tpm/tpm2_tis_spi.c +++ b/drivers/tpm/tpm2_tis_spi.c @@ -596,9 +596,9 @@ static int tpm_tis_spi_probe(struct udevice *dev) log(LOGC_NONE, LOGL_NOTICE, "%s: missing reset GPIO\n", __func__); } else { - dm_gpio_set_value(&reset_gpio, 0); - mdelay(1); dm_gpio_set_value(&reset_gpio, 1); + mdelay(1); + dm_gpio_set_value(&reset_gpio, 0); } } From 7f3289bf6dee6e4e6c7d95d3ee16d3ab3d55de55 Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Fri, 6 Sep 2019 07:51:18 -0400 Subject: [PATCH 42/61] dm: device: Request next sequence number For CONFIG_OF_PRIOR_STAGE, in the absence of a device tree alias for a given device, use the next request number for that type of device. This allows aliases to be used when they're available, while still allowing unaliased devices to be probed. Signed-off-by: Thomas Fitzsimmons Cc: Bin Meng Cc: Simon Glass --- drivers/core/device.c | 5 +++++ drivers/core/uclass.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index ce66c72e5e..24b940eac2 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -82,6 +82,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { if (uc->uc_drv->name && ofnode_valid(node)) dev_read_alias_seq(dev, &dev->req_seq); +#if CONFIG_IS_ENABLED(OF_PRIOR_STAGE) + if (dev->req_seq == -1) + dev->req_seq = + uclass_find_next_free_req_seq(drv->id); +#endif } else { dev->req_seq = uclass_find_next_free_req_seq(drv->id); } diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index f217876cd2..36f4d1c289 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -269,7 +269,9 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name, return -ENODEV; } -#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA) +#if !CONFIG_IS_ENABLED(OF_CONTROL) || \ + CONFIG_IS_ENABLED(OF_PLATDATA) || \ + CONFIG_IS_ENABLED(OF_PRIOR_STAGE) int uclass_find_next_free_req_seq(enum uclass_id id) { struct uclass *uc; From 640abba50763b215317468062a5e1b867ae57a76 Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Fri, 6 Sep 2019 07:51:19 -0400 Subject: [PATCH 43/61] dm: spi: Do not assume first SPI bus When CONFIG_OF_PRIOR_STAGE is enabled, this workaround was needed before device_bind_common assigned request numbers sequentially in the absence of aliases. Signed-off-by: Thomas Fitzsimmons Cc: Bin Meng Cc: Simon Glass --- drivers/spi/spi-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 76c4b53c16..a4d1b65682 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -299,7 +299,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, bool created = false; int ret; -#if CONFIG_IS_ENABLED(OF_PLATDATA) || CONFIG_IS_ENABLED(OF_PRIOR_STAGE) +#if CONFIG_IS_ENABLED(OF_PLATDATA) ret = uclass_first_device_err(UCLASS_SPI, &bus); #else ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus); From 9c1e982218b2eaa4afed835fe12ef91d14c9659c Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 17 Sep 2019 09:29:19 +0000 Subject: [PATCH 44/61] power: domain: add dev_power_domain_on Add this new API to power on multiple domains attached to a device. Signed-off-by: Peng Fan Reviewed-by: Lokesh Vutla Changed to static inline and added a condition into C file: Signed-off-by: Simon Glass --- drivers/power/domain/power-domain-uclass.c | 21 +++++++++++++++++++++ include/power-domain.h | 17 +++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index 2ea0ff24c7..c961436d62 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -107,6 +107,27 @@ int power_domain_off(struct power_domain *power_domain) return ops->off(power_domain); } +#if !CONFIG_IS_ENABLED(OF_PLATDATA) +int dev_power_domain_on(struct udevice *dev) +{ + struct power_domain pd; + int i, count, ret; + + count = dev_count_phandle_with_args(dev, "power-domains", + "#power-domain-cells"); + for (i = 0; i < count; i++) { + ret = power_domain_get_by_index(dev, &pd, i); + if (ret) + return ret; + ret = power_domain_on(&pd); + if (ret) + return ret; + } + + return 0; +} +#endif + UCLASS_DRIVER(power_domain) = { .id = UCLASS_POWER_DOMAIN, .name = "power_domain", diff --git a/include/power-domain.h b/include/power-domain.h index ef15dc9f60..490fedbb12 100644 --- a/include/power-domain.h +++ b/include/power-domain.h @@ -155,4 +155,21 @@ static inline int power_domain_off(struct power_domain *power_domain) } #endif +/** + * dev_power_domain_on - Enable power domains for a device . + * + * @dev: The client device. + * + * @return 0 if OK, or a negative error code. + */ +#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \ + CONFIG_IS_ENABLED(POWER_DOMAIN) +int dev_power_domain_on(struct udevice *dev); +#else +static inline int dev_power_domain_on(struct udevice *dev) +{ + return 0; +} +#endif + #endif From f0cc4eae9a1702a768817ea25d9f23cece69d021 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 17 Sep 2019 09:29:22 +0000 Subject: [PATCH 45/61] core: device: use dev_power_domain_on When multiple power domains attached to a device, need power on them all, so use dev_power_domain_on to do that. Signed-off-by: Peng Fan --- drivers/core/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index 24b940eac2..28363ff00b 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -312,7 +312,6 @@ static void *alloc_priv(int size, uint flags) int device_probe(struct udevice *dev) { - struct power_domain pd; const struct driver *drv; int size = 0; int ret; @@ -395,8 +394,9 @@ int device_probe(struct udevice *dev) if (CONFIG_IS_ENABLED(POWER_DOMAIN) && dev->parent && device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) { - if (!power_domain_get(dev, &pd)) - power_domain_on(&pd); + ret = dev_power_domain_on(dev); + if (ret) + goto fail; } ret = uclass_pre_probe_device(dev); From 36a90eda84dec49c2c850852d7e246c9a01bf59c Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Tue, 17 Sep 2019 22:06:03 +0200 Subject: [PATCH 46/61] dm: pinctrl: Skip not associated gpio phandle and rise a warning message Skip not associated gpio phandle let register the other gpios on a group. We need anyway to send out a warning to the user to fix their uboot-board.dtsi. Thhe handle id can be found inside the decompiled dtb dtc -I dtb -O dts -o devicetree.dts spl/u-boot-spl.dtb Signed-off-by: Michael Trimarchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-uclass.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index bf799a701c..a2da63f598 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -91,12 +91,18 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename) phandle = fdt32_to_cpu(*list++); ret = uclass_get_device_by_phandle_id(UCLASS_PINCONFIG, phandle, &config); - if (ret) - return ret; + if (ret) { + dev_warn(dev, "%s: uclass_get_device_by_phandle_id: err=%d\n", + __func__, ret); + continue; + } ret = pinctrl_config_one(config); - if (ret) - return ret; + if (ret) { + dev_warn(dev, "%s: pinctrl_config_one: err=%d\n", + __func__, ret); + continue; + } } return 0; From ce5172cf655533eabb977556036509416385cd90 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Wed, 18 Sep 2019 16:04:53 +0200 Subject: [PATCH 47/61] pytest: vboot: add a test for required key This commit add a test in the vboot test to check that when a required key is asked, only FIT signed with this key is used/accepted by u-boot. Signed-off-by: Philippe Reynes --- test/py/tests/test_vboot.py | 57 +++++++++++++++++++ .../vboot/sign-configs-sha256-pss-prod.its | 46 +++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 test/py/tests/vboot/sign-configs-sha256-pss-prod.its diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 4627ceb026..9c41ee56b1 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -80,6 +80,8 @@ def test_vboot(u_boot_console): assert(expect_string in ''.join(output)) if boots: assert('sandbox: continuing, as we cannot run' in ''.join(output)) + else: + assert('sandbox: continuing, as we cannot run' not in ''.join(output)) def make_fit(its): """Make a new FIT from the .its source file. @@ -106,6 +108,20 @@ def test_vboot(u_boot_console): util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb, '-r', fit]) + def sign_fit_norequire(sha_algo): + """Sign the FIT + + Signs the FIT and writes the signature into it. It also writes the + public key into the dtb. + + Args: + sha_algo: Either 'sha1' or 'sha256', to select the algorithm to + use. + """ + cons.log.action('%s: Sign images' % sha_algo) + util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb, + fit]) + def replace_fit_totalsize(size): """Replace FIT header's totalsize with something greater. @@ -195,6 +211,35 @@ def test_vboot(u_boot_console): util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit, '-k', dtb], 1, 'Failed to verify required signature') + def test_required_key(sha_algo, padding): + """Test verified boot with the given hash algorithm. + + This function test if u-boot reject an image when a required + key isn't used to sign a FIT. + + Args: + sha_algo: Either 'sha1' or 'sha256', to select the algorithm to + use. + """ + # Compile our device tree files for kernel and U-Boot. These are + # regenerated here since mkimage will modify them (by adding a + # public key) below. + dtc('sandbox-kernel.dts') + dtc('sandbox-u-boot.dts') + + # Build the FIT with prod key (keys required) + # Build the FIT with dev key (keys NOT required) + # The dtb contain the key prod and dev and the key prod are set as required. + # Then try to boot the FIT with dev key + # This FIT should not be accepted by u-boot because the key prod is required + cons.log.action('%s: Test FIT with configs images' % sha_algo) + make_fit('sign-configs-%s%s-prod.its' % (sha_algo , padding)) + sign_fit(sha_algo) + make_fit('sign-configs-%s%s.its' % (sha_algo , padding)) + sign_fit(sha_algo) + + run_bootm(sha_algo, 'signed configs', '', False) + cons = u_boot_console tmpdir = cons.config.result_dir + '/' tmp = tmpdir + 'vboot.tmp' @@ -217,6 +262,17 @@ def test_vboot(u_boot_console): util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sdev.key -out ' '%sdev.crt' % (tmpdir, tmpdir)) + # Create an RSA key pair (prod) + public_exponent = 65537 + util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %sprod.key ' + '-pkeyopt rsa_keygen_bits:2048 ' + '-pkeyopt rsa_keygen_pubexp:%d' % + (tmpdir, public_exponent)) + + # Create a certificate containing the public key (prod) + util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sprod.key -out ' + '%sprod.crt' % (tmpdir, tmpdir)) + # Create a number kernel image with zeroes with open('%stest-kernel.bin' % tmpdir, 'w') as fd: fd.write(5000 * chr(0)) @@ -230,6 +286,7 @@ def test_vboot(u_boot_console): test_with_algo('sha1','-pss') test_with_algo('sha256','') test_with_algo('sha256','-pss') + test_required_key('sha256','-pss') finally: # Go back to the original U-Boot with the correct dtb. cons.config.dtb = old_dtb diff --git a/test/py/tests/vboot/sign-configs-sha256-pss-prod.its b/test/py/tests/vboot/sign-configs-sha256-pss-prod.its new file mode 100644 index 0000000000..aac732e304 --- /dev/null +++ b/test/py/tests/vboot/sign-configs-sha256-pss-prod.its @@ -0,0 +1,46 @@ +/dts-v1/; + +/ { + description = "Chrome OS kernel image with one or more FDT blobs"; + #address-cells = <1>; + + images { + kernel { + data = /incbin/("test-kernel.bin"); + type = "kernel_noload"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + load = <0x4>; + entry = <0x8>; + kernel-version = <1>; + hash-1 { + algo = "sha256"; + }; + }; + fdt-1 { + description = "snow"; + data = /incbin/("sandbox-kernel.dtb"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + fdt-version = <1>; + hash-1 { + algo = "sha256"; + }; + }; + }; + configurations { + default = "conf-1"; + conf-1 { + kernel = "kernel"; + fdt = "fdt-1"; + signature { + algo = "sha256,rsa2048"; + padding = "pss"; + key-name-hint = "prod"; + sign-images = "fdt", "kernel"; + }; + }; + }; +}; From 0772a1f4973031d6a30482cf7610f691b6bc1e6d Mon Sep 17 00:00:00 2001 From: Daniele Alessandrelli Date: Wed, 18 Sep 2019 16:04:54 +0200 Subject: [PATCH 48/61] rsa: Return immediately if required-key verification fails Currently, if image verification with a required key fails, rsa_verify() code tries to find another key to verify the FIT image. This however, is not the intended behavior as the documentation says that required keys "must be verified for the image / configuration to be considered valid". This patch fixes the issue by making rsa_verify() return immediately if the verification of a required key fails. Signed-off-by: Daniele Alessandrelli --- lib/rsa/rsa-verify.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 287fcc4d23..82dc513260 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -437,8 +437,7 @@ int rsa_verify(struct image_sign_info *info, if (info->required_keynode != -1) { ret = rsa_verify_with_keynode(info, hash, sig, sig_len, info->required_keynode); - if (!ret) - return ret; + return ret; } /* Look for a key that matches our hint */ From 4ab6a45ec7ee6380f66098814f0d2e46a64158e8 Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Wed, 18 Sep 2019 17:22:13 +0200 Subject: [PATCH 49/61] libfdt: fix typo on comment Signed-off-by: Giulio Benetti --- scripts/dtc/libfdt/libfdt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index 5c778b115b..c400f2f5d5 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -734,7 +734,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); /** * fdt_get_alias_namelen - get alias based on substring * @fdt: pointer to the device tree blob - * @name: name of the alias th look up + * @name: name of the alias to look up * @namelen: number of characters of name to consider * * Identical to fdt_get_alias(), but only examine the first namelen From 8d694395502df38b7b114e2b866cba68a0832927 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Tue, 24 Sep 2019 11:32:27 +0200 Subject: [PATCH 50/61] sandbox: enable command aes This commit enable the command aes on sandbox. Then, it may be used on pytest. Signed-off-by: Philippe Reynes --- configs/sandbox_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 3f2dc99277..20ebc68997 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -67,6 +67,7 @@ CONFIG_CMD_QFW=y CONFIG_CMD_BOOTSTAGE=y CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y +CONFIG_CMD_AES=y CONFIG_CMD_TPM=y CONFIG_CMD_TPM_TEST=y CONFIG_CMD_BTRFS=y From 5fff9b3bc9da677bef8b5f7b5cb4e9e12c84a7d9 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Tue, 24 Sep 2019 11:32:28 +0200 Subject: [PATCH 51/61] sandbox64: enable command aes This commit add the support of command aes. Then, it may be used on pytest. Signed-off-by: Philippe Reynes --- configs/sandbox64_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7aa2d38b7b..1fea683d89 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -59,6 +59,7 @@ CONFIG_CMD_QFW=y CONFIG_CMD_BOOTSTAGE=y CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y +CONFIG_CMD_AES=y CONFIG_CMD_TPM=y CONFIG_CMD_TPM_TEST=y CONFIG_CMD_BTRFS=y From ed7ea058a904a0db5c007039adfa79d27da5bcde Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Tue, 24 Sep 2019 11:32:29 +0200 Subject: [PATCH 52/61] cmd: aes: use map_sysmem when accessing memory The aes command used to segfault when accessing memory in sandbox. The pointer accesses should be mapped. Signed-off-by: Philippe Reynes --- cmd/aes.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/aes.c b/cmd/aes.c index 7ff4a71709..8c61cee8e8 100644 --- a/cmd/aes.c +++ b/cmd/aes.c @@ -11,6 +11,7 @@ #include #include #include +#include /** * do_aes() - Handle the "aes" command-line command @@ -46,10 +47,10 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) dst_addr = simple_strtoul(argv[5], NULL, 16); len = simple_strtoul(argv[6], NULL, 16); - key_ptr = (uint8_t *)key_addr; - iv_ptr = (uint8_t *)iv_addr; - src_ptr = (uint8_t *)src_addr; - dst_ptr = (uint8_t *)dst_addr; + key_ptr = (uint8_t *)map_sysmem(key_addr, 128 / 8); + iv_ptr = (uint8_t *)map_sysmem(iv_addr, 128 / 8); + src_ptr = (uint8_t *)map_sysmem(src_addr, len); + dst_ptr = (uint8_t *)map_sysmem(dst_addr, len); /* First we expand the key. */ aes_expand_key(key_ptr, key_exp); @@ -64,6 +65,11 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) aes_cbc_decrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr, aes_blocks); + unmap_sysmem(key_ptr); + unmap_sysmem(iv_ptr); + unmap_sysmem(src_ptr); + unmap_sysmem(dst_ptr); + return 0; } From 833e4192cd791733ddc0106996a4f86f9269ceba Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 27 Sep 2019 09:23:56 -0700 Subject: [PATCH 53/61] patman: Use the Change-Id, version, and prefix in the Message-Id As per the centithread on ksummit-discuss [1], there are folks who feel that if a Change-Id is present in a developer's local commit that said Change-Id could be interesting to include in upstream posts. Specifically if two commits are posted with the same Change-Id there's a reasonable chance that they are either the same commit or a newer version of the same commit. Specifically this is because that's how gerrit has trained people to work. There is much angst about Change-Id in upstream Linux, but one thing that seems safe and non-controversial is to include the Change-Id as part of the string of crud that makes up a Message-Id. Let's give that a try. In theory (if there is enough adoption) this could help a tool more reliably find various versions of a commit. This actually might work pretty well for U-Boot where (I believe) quite a number of developers use patman, so there could be critical mass (assuming that enough of these people also use a git hook that adds Change-Id to their commits). I was able to find this git hook by searching for "gerrit change id git hook" in my favorite search engine. In theory one could imagine something like this could be integrated into other tools, possibly even git-send-email. Getting it into patman seems like a sane first step, though. NOTE: this patch is being posted using a patman containing this patch, so you should be able to see the Message-Id of this patch and see that it contains my local Change-Id, which ends in 2b9 if you want to check. [1] https://lists.linuxfoundation.org/pipermail/ksummit-discuss/2019-August/006739.html Signed-off-by: Douglas Anderson --- tools/patman/README | 8 ++++- tools/patman/commit.py | 3 ++ tools/patman/patchstream.py | 64 +++++++++++++++++++++++++++++++++++-- tools/patman/test.py | 15 +++++++-- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/tools/patman/README b/tools/patman/README index 7917fc8bdc..02d5829744 100644 --- a/tools/patman/README +++ b/tools/patman/README @@ -259,12 +259,18 @@ Series-process-log: sort, uniq unique entries. If omitted, no change log processing is done. Separate each tag with a comma. +Change-Id: + This tag is stripped out but is used to generate the Message-Id + of the emails that will be sent. When you keep the Change-Id the + same you are asserting that this is a slightly different version + (but logically the same patch) as other patches that have been + sent out with the same Change-Id. + Various other tags are silently removed, like these Chrome OS and Gerrit tags: BUG=... TEST=... -Change-Id: Review URL: Reviewed-on: Commit-xxxx: (except Commit-notes) diff --git a/tools/patman/commit.py b/tools/patman/commit.py index 2bf3a0ba5b..48d0529c53 100644 --- a/tools/patman/commit.py +++ b/tools/patman/commit.py @@ -21,6 +21,8 @@ class Commit: The dict is indexed by change version (an integer) cc_list: List of people to aliases/emails to cc on this commit notes: List of lines in the commit (not series) notes + change_id: the Change-Id: tag that was stripped from this commit + and can be used to generate the Message-Id. """ def __init__(self, hash): self.hash = hash @@ -30,6 +32,7 @@ class Commit: self.cc_list = [] self.signoff_set = set() self.notes = [] + self.change_id = None def AddChange(self, version, info): """Add a new change line to the change list for a version. diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index b6455b0fa3..ef06606297 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -2,6 +2,7 @@ # Copyright (c) 2011 The Chromium OS Authors. # +import datetime import math import os import re @@ -14,7 +15,7 @@ import gitutil from series import Series # Tags that we detect and remove -re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Change-Id:|^Review URL:' +re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Review URL:' '|Reviewed-on:|Commit-\w*:') # Lines which are allowed after a TEST= line @@ -32,6 +33,9 @@ re_cover_cc = re.compile('^Cover-letter-cc: *(.*)') # Patch series tag re_series_tag = re.compile('^Series-([a-z-]*): *(.*)') +# Change-Id will be used to generate the Message-Id and then be stripped +re_change_id = re.compile('^Change-Id: *(.*)') + # Commit series tag re_commit_tag = re.compile('^Commit-([a-z-]*): *(.*)') @@ -156,6 +160,7 @@ class PatchStream: # Handle state transition and skipping blank lines series_tag_match = re_series_tag.match(line) + change_id_match = re_change_id.match(line) commit_tag_match = re_commit_tag.match(line) cover_match = re_cover.match(line) cover_cc_match = re_cover_cc.match(line) @@ -177,7 +182,7 @@ class PatchStream: self.state = STATE_MSG_HEADER # If a tag is detected, or a new commit starts - if series_tag_match or commit_tag_match or \ + if series_tag_match or commit_tag_match or change_id_match or \ cover_match or cover_cc_match or signoff_match or \ self.state == STATE_MSG_HEADER: # but we are already in a section, this means 'END' is missing @@ -275,6 +280,16 @@ class PatchStream: self.AddToSeries(line, name, value) self.skip_blank = True + # Detect Change-Id tags + elif change_id_match: + value = change_id_match.group(1) + if self.is_log: + if self.commit.change_id: + raise ValueError("%s: Two Change-Ids: '%s' vs. '%s'" % + (self.commit.hash, self.commit.change_id, value)) + self.commit.change_id = value + self.skip_blank = True + # Detect Commit-xxx tags elif commit_tag_match: name = commit_tag_match.group(1) @@ -345,6 +360,47 @@ class PatchStream: self.warn.append('Found %d lines after TEST=' % self.lines_after_test) + def WriteMessageId(self, outfd): + """Write the Message-Id into the output. + + This is based on the Change-Id in the original patch, the version, + and the prefix. + + Args: + outfd: Output stream file object + """ + if not self.commit.change_id: + return + + # If the count is -1 we're testing, so use a fixed time + if self.commit.count == -1: + time_now = datetime.datetime(1999, 12, 31, 23, 59, 59) + else: + time_now = datetime.datetime.now() + + # In theory there is email.utils.make_msgid() which would be nice + # to use, but it already produces something way too long and thus + # will produce ugly commit lines if someone throws this into + # a "Link:" tag in the final commit. So (sigh) roll our own. + + # Start with the time; presumably we wouldn't send the same series + # with the same Change-Id at the exact same second. + parts = [time_now.strftime("%Y%m%d%H%M%S")] + + # These seem like they would be nice to include. + if 'prefix' in self.series: + parts.append(self.series['prefix']) + if 'version' in self.series: + parts.append("v%s" % self.series['version']) + + parts.append(str(self.commit.count + 1)) + + # The Change-Id must be last, right before the @ + parts.append(self.commit.change_id) + + # Join parts together with "." and write it out. + outfd.write('Message-Id: <%s@changeid>\n' % '.'.join(parts)) + def ProcessStream(self, infd, outfd): """Copy a stream from infd to outfd, filtering out unwanting things. @@ -358,6 +414,9 @@ class PatchStream: fname = None last_fname = None re_fname = re.compile('diff --git a/(.*) b/.*') + + self.WriteMessageId(outfd) + while True: line = infd.readline() if not line: @@ -481,6 +540,7 @@ def FixPatches(series, fnames): for fname in fnames: commit = series.commits[count] commit.patch = fname + commit.count = count result = FixPatch(backup_dir, fname, series, commit) if result: print('%d warnings for %s:' % (len(result), fname)) diff --git a/tools/patman/test.py b/tools/patman/test.py index e1b94bd1a7..cc61c20606 100644 --- a/tools/patman/test.py +++ b/tools/patman/test.py @@ -12,6 +12,7 @@ import checkpatch import gitutil import patchstream import series +import commit class TestPatch(unittest.TestCase): @@ -48,7 +49,8 @@ Signed-off-by: Simon Glass arch/arm/cpu/armv7/tegra2/ap20.c | 57 ++---- arch/arm/cpu/armv7/tegra2/clock.c | 163 +++++++++++++++++ ''' - expected=''' + expected='''Message-Id: <19991231235959.0.I80fe1d0c0b7dd10aa58ce5bb1d9290b6664d5413@changeid> + From 656c9a8c31fa65859d924cd21da920d6ba537fad Mon Sep 17 00:00:00 2001 From: Simon Glass @@ -79,7 +81,16 @@ Signed-off-by: Simon Glass expfd.write(expected) expfd.close() - patchstream.FixPatch(None, inname, series.Series(), None) + # Normally by the time we call FixPatch we've already collected + # metadata. Here, we haven't, but at least fake up something. + # Set the "count" to -1 which tells FixPatch to use a bogus/fixed + # time for generating the Message-Id. + com = commit.Commit('') + com.change_id = 'I80fe1d0c0b7dd10aa58ce5bb1d9290b6664d5413' + com.count = -1 + + patchstream.FixPatch(None, inname, series.Series(), com) + rc = os.system('diff -u %s %s' % (inname, expname)) self.assertEqual(rc, 0) From d8efa2ce2abe293c97576f47ccac708e233553b6 Mon Sep 17 00:00:00 2001 From: Jean-Jacques Hiblot Date: Thu, 26 Sep 2019 15:43:54 +0200 Subject: [PATCH 54/61] dm: device: Fix typo in the non-DEVRES version of devm_kmalloc_array() When DEVRES is not set, devm_kmalloc_array() is spelled devm_kmaloc_array() (with one 'l' only). Fixing it so that the name is the same with and without DEVRES. Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Simon Glass --- include/dm/device.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dm/device.h b/include/dm/device.h index defda0aebc..44cc3d2bd0 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -945,8 +945,8 @@ static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp) return kzalloc(size, gfp); } -static inline void *devm_kmaloc_array(struct udevice *dev, - size_t n, size_t size, gfp_t flags) +static inline void *devm_kmalloc_array(struct udevice *dev, + size_t n, size_t size, gfp_t flags) { /* TODO: add kmalloc_array() to linux/compat.h */ if (size != 0 && n > SIZE_MAX / size) From af94ad418dc72957d3b7398d83bfc5a1efd415db Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Fri, 27 Sep 2019 13:48:12 +0530 Subject: [PATCH 55/61] dm: core: Allow for not controlling the power-domain by DM framework In some remoteproc cases, enabling the power domain of the core will start running the core. In such cases image should be loaded before enabling the power domain. But the current DM framework enables the power-domain by default during probe. This is causing the remotecore to start and crash as there is no valid image loaded. In order to avoid this introduce a DM flag that doesn't allow for enabling/disabling the power-domain by DM framework. Signed-off-by: Lokesh Vutla Reviewed-by: Simon Glass --- drivers/core/device.c | 3 ++- include/dm/device.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index 28363ff00b..95f26efdd3 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -393,7 +393,8 @@ int device_probe(struct udevice *dev) pinctrl_select_state(dev, "default"); if (CONFIG_IS_ENABLED(POWER_DOMAIN) && dev->parent && - device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) { + (device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) && + !(drv->flags & DM_FLAG_DEFAULT_PD_CTRL_OFF)) { ret = dev_power_domain_on(dev); if (ret) goto fail; diff --git a/include/dm/device.h b/include/dm/device.h index 44cc3d2bd0..d7ad9d6728 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -61,6 +61,9 @@ struct driver_info; */ #define DM_FLAG_OS_PREPARE (1 << 10) +/* DM does not enable/disable the power domains corresponding to this device */ +#define DM_FLAG_DEFAULT_PD_CTRL_OFF (1 << 11) + /* * One or multiple of these flags are passed to device_remove() so that * a selective device removal as specified by the remove-stage and the From af17b0dad556889ebdaf5c3e62a4844e15189374 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Fri, 27 Sep 2019 13:48:13 +0530 Subject: [PATCH 56/61] remoteproc: k3_arm64: Enable DM_FLAG_DEFAULT_PD_CTRL_OFF Enable DM_FLAG_DEFAULT_PD_CTRL_OFF for arm64 remote core so that pd can be enabled after loading the image. Signed-off-by: Lokesh Vutla Reviewed-by: Simon Glass --- drivers/remoteproc/ti_k3_arm64_rproc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/remoteproc/ti_k3_arm64_rproc.c b/drivers/remoteproc/ti_k3_arm64_rproc.c index 9676a96f98..3e35293514 100644 --- a/drivers/remoteproc/ti_k3_arm64_rproc.c +++ b/drivers/remoteproc/ti_k3_arm64_rproc.c @@ -225,4 +225,5 @@ U_BOOT_DRIVER(k3_arm64) = { .ops = &k3_arm64_ops, .probe = k3_arm64_probe, .priv_auto_alloc_size = sizeof(struct k3_arm64_privdata), + .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; From 0cf795a8024f36e2aaea3db8ab8b4d3805dc541c Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Fri, 27 Sep 2019 13:48:14 +0530 Subject: [PATCH 57/61] power: domain: Introduce dev_power_domain_off Add dev_power_domain_off() api to disable all the power-domains corresponding to a device Signed-off-by: Lokesh Vutla Reviewed-by: Simon Glass --- drivers/power/domain/power-domain-uclass.c | 35 +++++++++++++++++----- include/power-domain.h | 17 +++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index c961436d62..80df5aff50 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -7,6 +7,7 @@ #include #include #include +#include static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev) { @@ -107,11 +108,11 @@ int power_domain_off(struct power_domain *power_domain) return ops->off(power_domain); } -#if !CONFIG_IS_ENABLED(OF_PLATDATA) -int dev_power_domain_on(struct udevice *dev) +#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +static int dev_power_domain_ctrl(struct udevice *dev, bool on) { struct power_domain pd; - int i, count, ret; + int i, count, ret = 0; count = dev_count_phandle_with_args(dev, "power-domains", "#power-domain-cells"); @@ -119,12 +120,32 @@ int dev_power_domain_on(struct udevice *dev) ret = power_domain_get_by_index(dev, &pd, i); if (ret) return ret; - ret = power_domain_on(&pd); - if (ret) - return ret; + if (on) + ret = power_domain_on(&pd); + else + ret = power_domain_off(&pd); } - return 0; + /* + * power_domain_get() bound the device, thus + * we must remove it again to prevent unbinding + * active devices (which would result in unbind + * error). + */ + if (count > 0 && !on) + device_remove(pd.dev, DM_REMOVE_NORMAL); + + return ret; +} + +int dev_power_domain_on(struct udevice *dev) +{ + return dev_power_domain_ctrl(dev, true); +} + +int dev_power_domain_off(struct udevice *dev) +{ + return dev_power_domain_ctrl(dev, false); } #endif diff --git a/include/power-domain.h b/include/power-domain.h index 490fedbb12..72ff2ff25b 100644 --- a/include/power-domain.h +++ b/include/power-domain.h @@ -172,4 +172,21 @@ static inline int dev_power_domain_on(struct udevice *dev) } #endif +/** + * dev_power_domain_off - Disable power domains for a device . + * + * @dev: The client device. + * + * @return 0 if OK, or a negative error code. + */ +#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \ + CONFIG_IS_ENABLED(POWER_DOMAIN) +int dev_power_domain_off(struct udevice *dev); +#else +static inline int dev_power_domain_off(struct udevice *dev) +{ + return 0; +} +#endif + #endif From 52edfed65de967a86983a55c51ba0727090efc43 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 27 Sep 2019 13:48:15 +0530 Subject: [PATCH 58/61] dm: core: device: switch off power domain after device removal The power domain associated with a device is enabled when probing, but currently the domain remains enabled when the device is removed. Some boards started to disable power domains for selected devices via custom board_quiesce_devices(), but it doesn't work in many cases, i. e. because devices still can be accessed later in .remove() callback on behalf of dm_remove_devices_flags(). Utilize the DM core to power off the device power domain, but add a device flag to be able to selectively let the power domain enabled after device removal. This might be required for devices that must remain enabled when booting OS, i. e. serial console for debug output, etc. Signed-off-by: Anatolij Gustschin Signed-off-by: Lokesh Vutla Reviewed-by: Simon Glass --- drivers/core/device-remove.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 586fadee0a..5c8dc4ad70 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -16,6 +16,7 @@ #include #include #include +#include int device_chld_unbind(struct udevice *dev, struct driver *drv) { @@ -192,6 +193,10 @@ int device_remove(struct udevice *dev, uint flags) } } + if (!(drv->flags & DM_FLAG_DEFAULT_PD_CTRL_OFF) && + (dev != gd->cur_serial_dev)) + dev_power_domain_off(dev); + if (flags_remove(flags, drv->flags)) { device_free(dev); From e878b53a79d1a4f06c7c03d706da6b2993e8ff41 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 2 Aug 2019 14:48:00 +0200 Subject: [PATCH 59/61] dm: pinctrl: introduce PINCONF_RECURSIVE option In the Linux pinctrl binding, the pin configuration nodes don't need to be direct children of the pin controller device (may be grandchildren for example). This behavior is managed with the pinconfig u-class which recursively bind all the sub-node of the pin controller. But for some binding (when pin configuration is only children of pin controller) that is not necessary. U-Boot can save memory and reduce the number of pinconf instance when this feature is deactivated (for arch stm32mp for example for SPL). This patch allows to control this feature with a new option CONFIG_PINCONF_RECURSIVE when it is possible for each individual pin controller device. Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass Fixed CONFIG_IF_ENABLED() condition, added __maybe_unused: Signed-off-by: Simon Glass --- drivers/pinctrl/Kconfig | 25 +++++++++++++++++++++++++ drivers/pinctrl/pinctrl-uclass.c | 4 +++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index deee92411c..6b41f66a86 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -75,6 +75,22 @@ config PINCONF_RECURSIVE configuration; you can save memory footprint when this feature is no needed. +config PINCONF_RECURSIVE + bool "Support recursive binding for pin configuration nodes" + depends on PINCTRL_FULL + default n if ARCH_STM32MP + default y + help + In the Linux pinctrl binding, the pin configuration nodes need not be + direct children of the pin controller device (may be grandchildren for + example). It is define is each individual pin controller device. + Say Y here if you want to keep this behavior with the pinconfig + u-class: all sub are recursivelly bounded. + If the option is disabled, this behavior is deactivated and only + the direct children of pin controller will be assumed as pin + configuration; you can save memory footprint when this feature is + no needed. + config SPL_PINCTRL bool "Support pin controllers in SPL" depends on SPL && SPL_DM @@ -129,6 +145,15 @@ config SPL_PINCONF_RECURSIVE This option is an SPL-variant of the PINCONF_RECURSIVE option. See the help of PINCONF_RECURSIVE for details. +config SPL_PINCONF_RECURSIVE + bool "Support recursive binding for pin configuration nodes in SPL" + depends on SPL_PINCTRL_FULL + default n if ARCH_STM32MP + default y + help + This option is an SPL-variant of the PINCONF_RECURSIVE option. + See the help of PINCONF_RECURSIVE for details. + if PINCTRL || SPL_PINCTRL config PINCTRL_AR933X diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index a2da63f598..0b1eb7fab4 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -403,7 +403,7 @@ int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf, * @dev: pinctrl device * @return: 0 on success, or negative error code on failure */ -static int pinctrl_post_bind(struct udevice *dev) +static int __maybe_unused pinctrl_post_bind(struct udevice *dev) { const struct pinctrl_ops *ops = pinctrl_get_ops(dev); @@ -426,7 +426,9 @@ static int pinctrl_post_bind(struct udevice *dev) UCLASS_DRIVER(pinctrl) = { .id = UCLASS_PINCTRL, +#if CONFIG_IS_ENABLED(PINCONF_RECURSIVE) .post_bind = pinctrl_post_bind, +#endif .flags = DM_UC_FLAG_SEQ_ALIAS, .name = "pinctrl", }; From 2a43dbdf9668dc9fbfc309e085eb0c7fa64c2f15 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Mon, 30 Sep 2019 10:19:13 +0200 Subject: [PATCH 60/61] dm: Tidy up dump output when there are many devices At present the 'Index' column of 'dm tree' assumes there is two digits, this patch increase it to 3 digits. It also aligns output of 'dm uclass', assuming the same 3 digits index. The boards with CONFIG_PINCTRL_FULL activated have one pinconfig by pin configuration, so they can have more than 100 devices pinconfig (for example with stm32mp157c-ev1 board we have 106 pinconfig node). Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- drivers/core/dump.c | 4 ++-- test/py/tests/test_bind.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 8fbfd93fb5..4704049aee 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -16,7 +16,7 @@ static void show_devices(struct udevice *dev, int depth, int last_flag) struct udevice *child; /* print the first 20 characters to not break the tree-format. */ - printf(" %-10.10s %2d [ %c ] %-20.20s ", dev->uclass->uc_drv->name, + printf(" %-10.10s %3d [ %c ] %-20.20s ", dev->uclass->uc_drv->name, dev_get_uclass_index(dev, NULL), dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name); @@ -64,7 +64,7 @@ void dm_dump_all(void) */ static void dm_display_line(struct udevice *dev, int index) { - printf("%i %c %s @ %08lx", index, + printf("%-3i %c %s @ %08lx", index, dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ', dev->name, (ulong)map_to_sysmem(dev)); if (dev->seq != -1 || dev->req_seq != -1) diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py index ccf6d62ea8..2d48484c6a 100644 --- a/test/py/tests/test_bind.py +++ b/test/py/tests/test_bind.py @@ -13,7 +13,7 @@ def in_tree(response, name, uclass, drv, depth, last_child): else: leaf = leaf + '`' leaf = leaf + '-- ' + name - line = (' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$' + line = (' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$' .format(uclass, drv, leaf)) prog = re.compile(line) for l in lines: From d11ef4d54cab0e740efbceb9c6b5697a41770eea Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Fri, 4 Oct 2019 13:45:18 +0900 Subject: [PATCH 61/61] sandbox: fix build error due to missing struct udevice definition Without this patch, compiling may potentially fail. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass --- arch/sandbox/include/asm/u-boot-sandbox.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index b2b8e36455..798d003077 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -26,6 +26,8 @@ int cleanup_before_linux(void); /* drivers/video/sandbox_sdl.c */ int sandbox_lcd_sdl_early_init(void); +struct udevice; + /** * pci_map_physmem() - map a PCI device into memory *