Merge tag 'dm-pull-13nov21' of https://source.denx.de/u-boot/custodians/u-boot-dm

env tidy-ups
test fixes
binman fixes and ELF enhancements
diff --git a/Makefile b/Makefile
index 299cd3f..194f93b 100644
--- a/Makefile
+++ b/Makefile
@@ -1314,7 +1314,7 @@
 		-a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
 		-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
 		-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
-		-a tpl-dtb=$(CONFIG_SPL_OF_REAL) \
+		-a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
 		$(BINMAN_$(@F))
 
 OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
diff --git a/boot/Kconfig b/boot/Kconfig
index a8d4be2..d3a12be 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -704,7 +704,7 @@
 	  151	common/cmd_nand.c	FIT image format OK
 
 config SPL_SHOW_BOOT_PROGRESS
-	bool "Show boot progress in a board-specific manner"
+	bool "Show boot progress in a board-specific manner in SPL"
 	depends on SPL
 	help
 	  Defining this option allows to add some board-specific code (calling
diff --git a/drivers/watchdog/sandbox_wdt.c b/drivers/watchdog/sandbox_wdt.c
index e05d827..535614f 100644
--- a/drivers/watchdog/sandbox_wdt.c
+++ b/drivers/watchdog/sandbox_wdt.c
@@ -39,6 +39,7 @@
 static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags)
 {
 	sandbox_wdt_start(dev, 1, flags);
+	sandbox_reset();
 
 	return 0;
 }
diff --git a/env/common.c b/env/common.c
index 99729ca..208e2ad 100644
--- a/env/common.c
+++ b/env/common.c
@@ -125,7 +125,7 @@
 	}
 
 	/* restricted capabilities before import */
-	if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
+	if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) >= 0)
 		return (char *)(gd->env_buf);
 
 	return NULL;
@@ -148,12 +148,10 @@
 	return ret;
 }
 
-/*
- * Look up variable from environment for restricted C runtime env.
- */
-int env_get_f(const char *name, char *buf, unsigned len)
+static int env_get_from_linear(const char *env, const char *name, char *buf,
+			       unsigned len)
 {
-	const char *env, *p, *end;
+	const char *p, *end;
 	size_t name_len;
 
 	if (name == NULL || *name == '\0')
@@ -161,11 +159,6 @@
 
 	name_len = strlen(name);
 
-	if (gd->env_valid == ENV_INVALID)
-		env = default_environment;
-	else
-		env = (const char *)gd->env_addr;
-
 	for (p = env; *p != '\0'; p = end + 1) {
 		const char *value;
 		unsigned res;
@@ -193,6 +186,21 @@
 	return -1;
 }
 
+/*
+ * Look up variable from environment for restricted C runtime env.
+ */
+int env_get_f(const char *name, char *buf, unsigned len)
+{
+	const char *env;
+
+	if (gd->env_valid == ENV_INVALID)
+		env = default_environment;
+	else
+		env = (const char *)gd->env_addr;
+
+	return env_get_from_linear(env, name, buf, len);
+}
+
 /**
  * Decode the integer value of an environment variable and return it.
  *
@@ -232,17 +240,12 @@
  */
 char *env_get_default(const char *name)
 {
-	char *ret_val;
-	unsigned long really_valid = gd->env_valid;
-	unsigned long real_gd_flags = gd->flags;
+	if (env_get_from_linear(default_environment, name,
+				(char *)(gd->env_buf),
+				sizeof(gd->env_buf)) >= 0)
+		return (char *)(gd->env_buf);
 
-	/* Pretend that the image is bad. */
-	gd->flags &= ~GD_FLG_ENV_READY;
-	gd->env_valid = ENV_INVALID;
-	ret_val = env_get(name);
-	gd->env_valid = really_valid;
-	gd->flags = real_gd_flags;
-	return ret_val;
+	return NULL;
 }
 
 void env_set_default(const char *s, int flags)
@@ -261,9 +264,11 @@
 	flags |= H_DEFAULT;
 	if (himport_r(&env_htab, default_environment,
 			sizeof(default_environment), '\0', flags, 0,
-			0, NULL) == 0)
+			0, NULL) == 0) {
 		pr_err("## Error: Environment import failed: errno = %d\n",
 		       errno);
+		return;
+	}
 
 	gd->flags |= GD_FLG_ENV_READY;
 	gd->flags |= GD_FLG_ENV_DEFAULT;
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 7de013f..548649f 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -106,6 +106,8 @@
 obj-$(CONFIG_DM_USB) += usb.o
 obj-$(CONFIG_DM_VIDEO) += video.o
 obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
-obj-$(CONFIG_WDT) += wdt.o
+ifeq ($(CONFIG_WDT_GPIO)$(CONFIG_WDT_SANDBOX),yy)
+obj-y += wdt.o
+endif
 endif
 endif # !SPL
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 614df54..35de93b 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -818,6 +818,42 @@
    # u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw)
 
 
+Updating an ELF file
+====================
+
+For the EFI app, where U-Boot is loaded from UEFI and runs as an app, there is
+no way to update the devicetree after U-Boot is built. Normally this works by
+creating a new u-boot.dtb.out with he updated devicetree, which is automatically
+built into the output image. With ELF this is not possible since the ELF is
+not part of an image, just a stand-along file. We must create an updated ELF
+file with the new devicetree.
+
+This is handled by the --update-fdt-in-elf option. It takes four arguments,
+separated by comma:
+
+   infile     - filename of input ELF file, e.g. 'u-boot's
+   outfile    - filename of output ELF file, e.g. 'u-boot.out'
+   begin_sym - symbol at the start of the embedded devicetree, e.g.
+   '__dtb_dt_begin'
+   end_sym   - symbol at the start of the embedded devicetree, e.g.
+   '__dtb_dt_end'
+
+When this flag is used, U-Boot does all the normal packaging, but as an
+additional step, it creates a new ELF file with the new devicetree embedded in
+it.
+
+If logging is enabled you will see a message like this::
+
+   Updating file 'u-boot' with data length 0x400a (16394) between symbols
+   '__dtb_dt_begin' and '__dtb_dt_end'
+
+There must be enough space for the updated devicetree. If not, an error like
+the following is produced::
+
+   ValueError: Not enough space in 'u-boot' for data length 0x400a (16394);
+   size is 0x1744 (5956)
+
+
 Entry Documentation
 ===================
 
diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py
index d6156df..e73ff78 100644
--- a/tools/binman/cmdline.py
+++ b/tools/binman/cmdline.py
@@ -71,6 +71,8 @@
              'given')
     build_parser.add_argument('-u', '--update-fdt', action='store_true',
         default=False, help='Update the binman node with offset/size info')
+    build_parser.add_argument('--update-fdt-in-elf', type=str,
+        help='Update an ELF file with the output dtb: infile,outfile,begin_sym,end_sym')
 
     entry_parser = subparsers.add_parser('entry-docs',
         help='Write out entry documentation (see entries.rst)')
@@ -99,7 +101,7 @@
     replace_parser.add_argument('-C', '--compressed', action='store_true',
         help='Input data is already compressed if needed for the entry')
     replace_parser.add_argument('-i', '--image', type=str, required=True,
-                                help='Image filename to extract')
+                                help='Image filename to update')
     replace_parser.add_argument('-f', '--filename', type=str,
                                 help='Input filename to read from')
     replace_parser.add_argument('-F', '--fix-size', action='store_true',
@@ -109,7 +111,7 @@
     replace_parser.add_argument('-m', '--map', action='store_true',
         default=False, help='Output a map file for the updated image')
     replace_parser.add_argument('paths', type=str, nargs='*',
-                                help='Paths within file to extract (wildcard)')
+                                help='Paths within file to replace (wildcard)')
 
     test_parser = subparsers.add_parser('test', help='Run tests')
     test_parser.add_argument('-P', '--processes', type=int,
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 0dbcbc2..304fc70 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -343,10 +343,10 @@
 
     Args:
         image_fname: Image filename to process
-        input_fname: Single input ilename to use if replacing one file, None
+        input_fname: Single input filename to use if replacing one file, None
             otherwise
         indir: Input directory to use (for any number of files), else None
-        entry_paths: List of entry paths to extract
+        entry_paths: List of entry paths to replace
         do_compress: True if the input data is uncompressed and may need to be
             compressed if the entry requires it, False if the data is already
             compressed.
@@ -595,6 +595,13 @@
             tools.FinaliseOutputDir()
         return 0
 
+    elf_params = None
+    if args.update_fdt_in_elf:
+        elf_params = args.update_fdt_in_elf.split(',')
+        if len(elf_params) != 4:
+            raise ValueError('Invalid args %s to --update-fdt-in-elf: expected infile,outfile,begin_sym,end_sym' %
+                             elf_params)
+
     # Try to figure out which device tree contains our image description
     if args.dt:
         dtb_fname = args.dt
@@ -641,6 +648,10 @@
             for dtb_item in state.GetAllFdts():
                 tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
 
+            if elf_params:
+                data = state.GetFdtForEtype('u-boot-dtb').GetContents()
+                elf.UpdateFile(*elf_params, data)
+
             if missing:
                 tout.Warning("\nSome images are invalid")
 
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
index 03b49d7..de2bb46 100644
--- a/tools/binman/elf.py
+++ b/tools/binman/elf.py
@@ -24,7 +24,14 @@
 except:  # pragma: no cover
     ELF_TOOLS = False
 
-Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak'])
+# Information about an EFL symbol:
+# section (str): Name of the section containing this symbol
+# address (int): Address of the symbol (its value)
+# size (int): Size of the symbol in bytes
+# weak (bool): True if the symbol is weak
+# offset (int or None): Offset of the symbol's data in the ELF file, or None if
+#   not known
+Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak', 'offset'])
 
 # Information about an ELF file:
 #    data: Extracted program contents of ELF file (this would be loaded by an
@@ -71,12 +78,52 @@
         section, size =  parts[:2]
         if len(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')
+            syms[name] = Symbol(section, int(value, 16), int(size, 16),
+                                flags[1] == 'w', None)
 
     # Sort dict by address
     return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
 
+def GetSymbolFileOffset(fname, patterns):
+    """Get the symbols from an ELF file
+
+    Args:
+        fname: Filename of the ELF file to read
+        patterns: List of regex patterns to search for, each a string
+
+    Returns:
+        None, if the file does not exist, or Dict:
+          key: Name of symbol
+          value: Hex value of symbol
+    """
+    def _GetFileOffset(elf, addr):
+        for seg in elf.iter_segments():
+            seg_end = seg['p_vaddr'] + seg['p_filesz']
+            if seg.header['p_type'] == 'PT_LOAD':
+                if addr >= seg['p_vaddr'] and addr < seg_end:
+                    return addr - seg['p_vaddr'] + seg['p_offset']
+
+    if not ELF_TOOLS:
+        raise ValueError('Python elftools package is not available')
+
+    syms = {}
+    with open(fname, 'rb') as fd:
+        elf = ELFFile(fd)
+
+        re_syms = re.compile('|'.join(patterns))
+        for section in elf.iter_sections():
+            if isinstance(section, SymbolTableSection):
+                for symbol in section.iter_symbols():
+                    if not re_syms or re_syms.search(symbol.name):
+                        addr = symbol.entry['st_value']
+                        syms[symbol.name] = Symbol(
+                            section.name, addr, symbol.entry['st_size'],
+                            symbol.entry['st_info']['bind'] == 'STB_WEAK',
+                            _GetFileOffset(elf, addr))
+
+    # Sort dict by address
+    return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
+
 def GetSymbolAddress(fname, sym_name):
     """Get a value of a symbol from an ELF file
 
@@ -301,3 +348,24 @@
                 segment.data()[offset:])
     return ElfInfo(output, data_start, elf.header['e_entry'] + virt_to_phys,
                    mem_end - data_start)
+
+def UpdateFile(infile, outfile, start_sym, end_sym, insert):
+    tout.Notice("Creating file '%s' with data length %#x (%d) between symbols '%s' and '%s'" %
+                (outfile, len(insert), len(insert), start_sym, end_sym))
+    syms = GetSymbolFileOffset(infile, [start_sym, end_sym])
+    if len(syms) != 2:
+        raise ValueError("Expected two symbols '%s' and '%s': got %d: %s" %
+                         (start_sym, end_sym, len(syms),
+                          ','.join(syms.keys())))
+
+    size = syms[end_sym].offset - syms[start_sym].offset
+    if len(insert) > size:
+        raise ValueError("Not enough space in '%s' for data length %#x (%d); size is %#x (%d)" %
+                         (infile, len(insert), len(insert), size, size))
+
+    data = tools.ReadFile(infile)
+    newdata = data[:syms[start_sym].offset]
+    newdata += insert + tools.GetBytes(0, size - len(insert))
+    newdata += data[syms[end_sym].offset:]
+    tools.WriteFile(outfile, newdata)
+    tout.Info('Written to offset %#x' % syms[start_sym].offset)
diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py
index 7a12801..ac69a95 100644
--- a/tools/binman/elf_test.py
+++ b/tools/binman/elf_test.py
@@ -6,6 +6,7 @@
 
 import os
 import shutil
+import struct
 import sys
 import tempfile
 import unittest
@@ -70,8 +71,12 @@
     # 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)
+    try:
+        tools.Run('make', '-C', target_dir, '-f',
+                  os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir)
+    except ValueError as e:
+        # The test system seems to suppress this in a strange way
+        print(e)
 
 
 class TestElf(unittest.TestCase):
@@ -217,6 +222,42 @@
                          elf.DecodeElf(data, load + 2))
         shutil.rmtree(outdir)
 
+    def testEmbedData(self):
+        """Test for the GetSymbolFileOffset() function"""
+        if not elf.ELF_TOOLS:
+            self.skipTest('Python elftools not available')
+
+        fname = self.ElfTestFile('embed_data')
+        offset = elf.GetSymbolFileOffset(fname, ['embed_start', 'embed_end'])
+        start = offset['embed_start'].offset
+        end = offset['embed_end'].offset
+        data = tools.ReadFile(fname)
+        embed_data = data[start:end]
+        expect = struct.pack('<III', 0x1234, 0x5678, 0)
+        self.assertEqual(expect, embed_data)
+
+    def testEmbedFail(self):
+        """Test calling GetSymbolFileOffset() without elftools"""
+        try:
+            old_val = elf.ELF_TOOLS
+            elf.ELF_TOOLS = False
+            fname = self.ElfTestFile('embed_data')
+            with self.assertRaises(ValueError) as e:
+                elf.GetSymbolFileOffset(fname, ['embed_start', 'embed_end'])
+            self.assertIn('Python elftools package is not available',
+                      str(e.exception))
+        finally:
+            elf.ELF_TOOLS = old_val
+
+    def testEmbedDataNoSym(self):
+        """Test for GetSymbolFileOffset() getting no symbols"""
+        if not elf.ELF_TOOLS:
+            self.skipTest('Python elftools not available')
+
+        fname = self.ElfTestFile('embed_data')
+        offset = elf.GetSymbolFileOffset(fname, ['missing_sym'])
+        self.assertEqual({}, offset)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 8199a4f..6be0037 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -309,7 +309,7 @@
                     entry_args=None, images=None, use_real_dtb=False,
                     use_expanded=False, verbosity=None, allow_missing=False,
                     extra_indirs=None, threads=None,
-                    test_section_timeout=False):
+                    test_section_timeout=False, update_fdt_in_elf=None):
         """Run binman with a given test file
 
         Args:
@@ -334,6 +334,12 @@
             extra_indirs: Extra input directories to add using -I
             threads: Number of threads to use (None for default, 0 for
                 single-threaded)
+            test_section_timeout: True to force the first time to timeout, as
+                used in testThreadTimeout()
+            update_fdt_in_elf: Value to pass with --update-fdt-in-elf=xxx
+
+        Returns:
+            int return code, 0 on success
         """
         args = []
         if debug:
@@ -363,6 +369,8 @@
                 args.append('-a%s=%s' % (arg, value))
         if allow_missing:
             args.append('-M')
+        if update_fdt_in_elf:
+            args += ['--update-fdt-in-elf', update_fdt_in_elf]
         if images:
             for image in images:
                 args += ['-i', image]
@@ -4575,6 +4583,84 @@
         self.assertIn('read:', stdout.getvalue())
         self.assertIn('compress:', stdout.getvalue())
 
+    def testUpdateFdtInElf(self):
+        """Test that we can update the devicetree in an ELF file"""
+        infile = elf_fname = self.ElfTestFile('u_boot_binman_embed')
+        outfile = os.path.join(self._indir, 'u-boot.out')
+        begin_sym = 'dtb_embed_begin'
+        end_sym = 'dtb_embed_end'
+        retcode = self._DoTestFile(
+            '060_fdt_update.dts', update_dtb=True,
+            update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym]))
+        self.assertEqual(0, retcode)
+
+        # Check that the output file does in fact contact a dtb with the binman
+        # definition in the correct place
+        syms = elf.GetSymbolFileOffset(infile,
+                                       ['dtb_embed_begin', 'dtb_embed_end'])
+        data = tools.ReadFile(outfile)
+        dtb_data = data[syms['dtb_embed_begin'].offset:
+                        syms['dtb_embed_end'].offset]
+
+        dtb = fdt.Fdt.FromData(dtb_data)
+        dtb.Scan()
+        props = self._GetPropTree(dtb, BASE_DTB_PROPS + REPACK_DTB_PROPS)
+        self.assertEqual({
+            'image-pos': 0,
+            'offset': 0,
+            '_testing:offset': 32,
+            '_testing:size': 2,
+            '_testing:image-pos': 32,
+            'section@0/u-boot:offset': 0,
+            'section@0/u-boot:size': len(U_BOOT_DATA),
+            'section@0/u-boot:image-pos': 0,
+            'section@0:offset': 0,
+            'section@0:size': 16,
+            'section@0:image-pos': 0,
+
+            'section@1/u-boot:offset': 0,
+            'section@1/u-boot:size': len(U_BOOT_DATA),
+            'section@1/u-boot:image-pos': 16,
+            'section@1:offset': 16,
+            'section@1:size': 16,
+            'section@1:image-pos': 16,
+            'size': 40
+        }, props)
+
+    def testUpdateFdtInElfInvalid(self):
+        """Test that invalid args are detected with --update-fdt-in-elf"""
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile('060_fdt_update.dts', update_fdt_in_elf='fred')
+        self.assertIn("Invalid args ['fred'] to --update-fdt-in-elf",
+                      str(e.exception))
+
+    def testUpdateFdtInElfNoSyms(self):
+        """Test that missing symbols are detected with --update-fdt-in-elf"""
+        infile = elf_fname = self.ElfTestFile('u_boot_binman_embed')
+        outfile = ''
+        begin_sym = 'wrong_begin'
+        end_sym = 'wrong_end'
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile(
+                '060_fdt_update.dts',
+                update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym]))
+        self.assertIn("Expected two symbols 'wrong_begin' and 'wrong_end': got 0:",
+                      str(e.exception))
+
+    def testUpdateFdtInElfTooSmall(self):
+        """Test that an over-large dtb is detected with --update-fdt-in-elf"""
+        infile = elf_fname = self.ElfTestFile('u_boot_binman_embed_sm')
+        outfile = os.path.join(self._indir, 'u-boot.out')
+        begin_sym = 'dtb_embed_begin'
+        end_sym = 'dtb_embed_end'
+        with self.assertRaises(ValueError) as e:
+            self._DoTestFile(
+                '060_fdt_update.dts', update_dtb=True,
+                update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym]))
+        self.assertRegex(
+            str(e.exception),
+            "Not enough space in '.*u_boot_binman_embed_sm' for data length.*")
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile
index 0b19b7d..387ba16 100644
--- a/tools/binman/test/Makefile
+++ b/tools/binman/test/Makefile
@@ -28,10 +28,12 @@
 LDS_BINMAN := -T $(SRC)u_boot_binman_syms.lds
 LDS_BINMAN_BAD := -T $(SRC)u_boot_binman_syms_bad.lds
 LDS_BINMAN_X86 := -T $(SRC)u_boot_binman_syms_x86.lds
+LDS_BINMAN_EMBED := -T $(SRC)u_boot_binman_embed.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 \
-	u_boot_binman_syms_size u_boot_binman_syms_x86
+	u_boot_binman_syms_size u_boot_binman_syms_x86 embed_data \
+	u_boot_binman_embed u_boot_binman_embed_sm
 
 all: $(TARGETS)
 
@@ -44,6 +46,9 @@
 bss_data: CFLAGS += $(SRC)bss_data.lds
 bss_data: bss_data.c
 
+embed_data: CFLAGS += $(SRC)embed_data.lds
+embed_data: embed_data.c
+
 u_boot_binman_syms.bin: u_boot_binman_syms
 	$(OBJCOPY) -O binary $< -R .note.gnu.build-id $@
 
@@ -59,6 +64,12 @@
 u_boot_binman_syms_size: CFLAGS += $(LDS_BINMAN)
 u_boot_binman_syms_size: u_boot_binman_syms_size.c
 
+u_boot_binman_embed: CFLAGS += $(LDS_BINMAN_EMBED)
+u_boot_binman_embed: u_boot_binman_embed.c
+
+u_boot_binman_embed_sm: CFLAGS += $(LDS_BINMAN_EMBED)
+u_boot_binman_embed_sm: u_boot_binman_embed_sm.c
+
 clean:
 	rm -f $(TARGETS)
 
diff --git a/tools/binman/test/bss_data.c b/tools/binman/test/bss_data.c
index 79537c3..4f9b64c 100644
--- a/tools/binman/test/bss_data.c
+++ b/tools/binman/test/bss_data.c
@@ -2,7 +2,7 @@
 /*
  * Copyright (c) 2016 Google, Inc
  *
- * Simple program to create a _dt_ucode_base_size symbol which can be read
+ * Simple program to create a bss_data region so the symbol can be read
  * by binutils. This is used by binman tests.
  */
 
diff --git a/tools/binman/test/embed_data.c b/tools/binman/test/embed_data.c
new file mode 100644
index 0000000..47d8c38
--- /dev/null
+++ b/tools/binman/test/embed_data.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Simple program including some embedded data that can be accessed by binman.
+ * This is used by binman tests.
+ */
+
+int first[10] = {1};
+int embed[3] __attribute__((section(".embed"))) = {0x1234, 0x5678};
+int second[10] = {1};
+
+int main(void)
+{
+	return 0;
+}
diff --git a/tools/binman/test/embed_data.lds b/tools/binman/test/embed_data.lds
new file mode 100644
index 0000000..908bf66
--- /dev/null
+++ b/tools/binman/test/embed_data.lds
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Google LLC
+ */
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+	_start = .;
+	__data_start = .;
+	.data :
+	{
+		. = ALIGN(32);
+		embed_start = .;
+		*(.embed*)
+		embed_end = .;
+		. = ALIGN(32);
+		*(.data*)
+	}
+}
diff --git a/tools/binman/test/u_boot_binman_embed.c b/tools/binman/test/u_boot_binman_embed.c
new file mode 100644
index 0000000..75874bb
--- /dev/null
+++ b/tools/binman/test/u_boot_binman_embed.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Simple program to embed a devicetree. This is used by binman tests.
+ */
+
+int __attribute__((section(".mydtb"))) dtb_data[4096];
+
+int main(void)
+{
+	return 0;
+}
diff --git a/tools/binman/test/u_boot_binman_embed.lds b/tools/binman/test/u_boot_binman_embed.lds
new file mode 100644
index 0000000..e213fa8
--- /dev/null
+++ b/tools/binman/test/u_boot_binman_embed.lds
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2016 Google, Inc
+ */
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+	. = 0x00000000;
+	_start = .;
+
+	. = ALIGN(4);
+	.text :
+	{
+		*(.text*)
+	}
+
+	. = ALIGN(4);
+	.data : {
+		dtb_embed_begin = .;
+		KEEP(*(.mydtb));
+		dtb_embed_end = .;
+	}
+	.interp : { *(.interp*) }
+
+}
diff --git a/tools/binman/test/u_boot_binman_embed_sm.c b/tools/binman/test/u_boot_binman_embed_sm.c
new file mode 100644
index 0000000..ae245d7
--- /dev/null
+++ b/tools/binman/test/u_boot_binman_embed_sm.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Simple program to embed a devicetree. This is used by binman tests.
+ */
+
+int __attribute__((section(".mydtb"))) dtb_data[16];
+
+int main(void)
+{
+	return 0;
+}
diff --git a/tools/patman/tools.py b/tools/patman/tools.py
index 710f1fd..86c4f61 100644
--- a/tools/patman/tools.py
+++ b/tools/patman/tools.py
@@ -349,7 +349,7 @@
         result = command.RunPipe([all_args], capture=True, capture_stderr=True,
                                  env=env, raise_on_error=False, binary=binary)
         if result.return_code:
-            raise Exception("Error %d running '%s': %s" %
+            raise ValueError("Error %d running '%s': %s" %
                (result.return_code,' '.join(all_args),
                 result.stderr))
         return result.stdout