Merge branch '2020-01-07-master-imports'

- DT overlay support in FIT images in SPL
- remoteproc update
- Assorted SATA fixes
- Other assorted fixes
diff --git a/Kconfig b/Kconfig
index 46a31f4..99cc56f 100644
--- a/Kconfig
+++ b/Kconfig
@@ -444,6 +444,24 @@
 	  particular it can handle selecting from multiple device tree
 	  and passing the correct one to U-Boot.
 
+config SPL_LOAD_FIT_APPLY_OVERLAY
+	bool "Enable SPL applying DT overlays from FIT"
+	depends on SPL_LOAD_FIT
+	select OF_LIBFDT_OVERLAY
+	help
+	  The device tree is loaded from the FIT image. Allow the SPL is to
+	  also load device-tree overlays from the FIT image an apply them
+	  over the device tree.
+
+config SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
+	depends on SPL_LOAD_FIT_APPLY_OVERLAY
+	default 0x10000
+	hex "size of temporary buffer used to load the overlays"
+	help
+	  The size of the area where the overlays will be loaded and
+	  uncompress. Must be at least as large as biggest overlay
+	  (uncompressed)
+
 config SPL_LOAD_FIT_FULL
 	bool "Enable SPL loading U-Boot as a FIT (full fitImage features)"
 	select SPL_FIT
diff --git a/Makefile b/Makefile
index 1766f5a..cc126eb 100644
--- a/Makefile
+++ b/Makefile
@@ -1265,7 +1265,7 @@
 # from the SPL U-Boot version.
 #
 ifndef CONFIG_SYS_UBOOT_START
-CONFIG_SYS_UBOOT_START := 0
+CONFIG_SYS_UBOOT_START := $(CONFIG_SYS_TEXT_BASE)
 endif
 
 # Boards with more complex image requirements can provide an .its source file
@@ -1292,7 +1292,8 @@
 	-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
 	-p $(CONFIG_FIT_EXTERNAL_OFFSET) \
 	-n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \
-	$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+	$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) \
+	$(patsubst %,-b arch/$(ARCH)/dts/%.dtbo,$(subst ",,$(CONFIG_OF_OVERLAY_LIST)))
 else
 MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \
 	-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index ed7d9f6..6a71465 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -35,7 +35,9 @@
 #define TAMP_CR1		(STM32_TAMP_BASE + 0x00)
 
 #define PWR_CR1			(STM32_PWR_BASE + 0x00)
+#define PWR_MCUCR		(STM32_PWR_BASE + 0x14)
 #define PWR_CR1_DBP		BIT(8)
+#define PWR_MCUCR_SBF		BIT(6)
 
 /* DBGMCU register */
 #define DBGMCU_IDC		(STM32_DBGMCU_BASE + 0x00)
@@ -206,6 +208,11 @@
 	security_init();
 	update_bootmode();
 #endif
+	/* Reset Coprocessor state unless it wakes up from Standby power mode */
+	if (!(readl(PWR_MCUCR) & PWR_MCUCR_SBF)) {
+		writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE);
+		writel(0, TAMP_COPRO_RSC_TBL_ADDRESS);
+	}
 #endif
 
 	boot_mode = get_bootmode();
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index b3e9ccc..88126b8 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -86,9 +86,18 @@
 #define TAMP_BACKUP_REGISTER(x)		(STM32_TAMP_BASE + 0x100 + 4 * x)
 #define TAMP_BACKUP_MAGIC_NUMBER	TAMP_BACKUP_REGISTER(4)
 #define TAMP_BACKUP_BRANCH_ADDRESS	TAMP_BACKUP_REGISTER(5)
+#define TAMP_COPRO_RSC_TBL_ADDRESS	TAMP_BACKUP_REGISTER(17)
+#define TAMP_COPRO_STATE		TAMP_BACKUP_REGISTER(18)
 #define TAMP_BOOT_CONTEXT		TAMP_BACKUP_REGISTER(20)
 #define TAMP_BOOTCOUNT			TAMP_BACKUP_REGISTER(21)
 
+#define TAMP_COPRO_STATE_OFF		0
+#define TAMP_COPRO_STATE_INIT		1
+#define TAMP_COPRO_STATE_CRUN		2
+#define TAMP_COPRO_STATE_CSTOP		3
+#define TAMP_COPRO_STATE_STANDBY	4
+#define TAMP_COPRO_STATE_CRASH		5
+
 #define TAMP_BOOT_MODE_MASK		GENMASK(15, 8)
 #define TAMP_BOOT_MODE_SHIFT		8
 #define TAMP_BOOT_DEVICE_MASK		GENMASK(7, 4)
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index cee3500..1d4a54c 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -1096,10 +1096,8 @@
 	printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n",
 	       id, fw_image, fw_size, ret ? " Failed!" : " Success!");
 
-	if (!ret) {
+	if (!ret)
 		rproc_start(id);
-		env_set("copro_state", "booted");
-	}
 }
 
 U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 4e29e7b..5f2562b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -294,6 +294,7 @@
 
 config BOOTM_OSE
 	bool "Support booting Enea OSE images"
+	depends on (ARM && (ARM64 || CPU_V7A || CPU_V7R) || SANDBOX || PPC || X86)
 	depends on CMD_BOOTM
 	help
 	  Support booting Enea OSE images via the bootm command.
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index abd9151..d6a7175 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -349,6 +349,9 @@
 	printf("Early malloc usage: %lx / %x\n", gd->malloc_ptr,
 	       CONFIG_VAL(SYS_MALLOC_F_LEN));
 #endif
+#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
+	print_num("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
+#endif
 	if (gd->fdt_blob)
 		print_num("fdt_blob", (ulong)gd->fdt_blob);
 
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index cbc00a4..ac69d83 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -6,14 +6,20 @@
 
 #include <common.h>
 #include <errno.h>
+#include <board.h>
 #include <fpga.h>
 #include <gzip.h>
 #include <image.h>
-#include <linux/libfdt.h>
+#include <malloc.h>
 #include <spl.h>
+#include <linux/libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
+#define CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ (64 * 1024)
+#endif
+
 #ifndef CONFIG_SYS_BOOTM_LEN
 #define CONFIG_SYS_BOOTM_LEN	(64 << 20)
 #endif
@@ -27,6 +33,29 @@
 	return size;
 }
 
+static int find_node_from_desc(const void *fit, int node, const char *str)
+{
+	int child;
+
+	if (node < 0)
+		return -EINVAL;
+
+	/* iterate the FIT nodes and find a matching description */
+	for (child = fdt_first_subnode(fit, node); child >= 0;
+	     child = fdt_next_subnode(fit, child)) {
+		int len;
+		const char *desc = fdt_getprop(fit, child, "description", &len);
+
+		if (!desc)
+			continue;
+
+		if (!strcmp(desc, str))
+			return child;
+	}
+
+	return -ENOENT;
+}
+
 /**
  * spl_fit_get_image_name(): By using the matching configuration subnode,
  * retrieve the name of an image, specified by a property name and an index
@@ -41,12 +70,14 @@
  */
 static int spl_fit_get_image_name(const void *fit, int images,
 				  const char *type, int index,
-				  char **outname)
+				  const char **outname)
 {
+	struct udevice *board;
 	const char *name, *str;
 	__maybe_unused int node;
 	int conf_node;
 	int len, i;
+	bool found = true;
 
 	conf_node = fit_find_config_node(fit);
 	if (conf_node < 0) {
@@ -72,12 +103,45 @@
 	for (i = 0; i < index; i++) {
 		str = strchr(str, '\0') + 1;
 		if (!str || (str - name >= len)) {
-			debug("no string for index %d\n", index);
-			return -E2BIG;
+			found = false;
+			break;
 		}
 	}
 
+	if (!found && !board_get(&board)) {
+		int rc;
+		/*
+		 * no string in the property for this index. Check if the board
+		 * level code can supply one.
+		 */
+		rc = board_get_fit_loadable(board, index - i - 1, type, &str);
+		if (rc && rc != -ENOENT)
+			return rc;
+
+		if (!rc) {
+			/*
+			 * The board provided a name for a loadable.
+			 * Try to match it against the description properties
+			 * first. If no matching node is found, use it as a
+			 * node name.
+			 */
+			int node;
+			int images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+
-	*outname = (char *)str;
+			node = find_node_from_desc(fit, images, str);
+			if (node > 0)
+				str = fdt_get_name(fit, node, NULL);
+
+			found = true;
+		}
+	}
+
+	if (!found) {
+		debug("no string for index %d\n", index);
+		return -E2BIG;
+	}
+
+	*outname = str;
 	return 0;
 }
 
@@ -96,7 +160,7 @@
 static int spl_fit_get_image_node(const void *fit, int images,
 				  const char *type, int index)
 {
-	char *str;
+	const char *str;
 	int err;
 	int node;
 
@@ -108,7 +172,7 @@
 
 	node = fdt_subnode_offset(fit, images, str);
 	if (node < 0) {
-		debug("cannot find image node '%s': %d\n", str, node);
+		pr_err("cannot find image node '%s': %d\n", str, node);
 		return -EINVAL;
 	}
 
@@ -281,7 +345,7 @@
 			      void *fit, int images, ulong base_offset)
 {
 	struct spl_image_info image_info;
-	int node, ret = 0;
+	int node, ret = 0, index = 0;
 
 	/*
 	 * Use the address following the image as target address for the
@@ -290,7 +354,7 @@
 	image_info.load_addr = spl_image->load_addr + spl_image->size;
 
 	/* Figure out which device tree the board wants to use */
-	node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
+	node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, index++);
 	if (node < 0) {
 		debug("%s: cannot find FDT node\n", __func__);
 
@@ -313,8 +377,65 @@
 	/* Make the load-address of the FDT available for the SPL framework */
 	spl_image->fdt_addr = (void *)image_info.load_addr;
 #if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
+	if (CONFIG_IS_ENABLED(LOAD_FIT_APPLY_OVERLAY)) {
+		void *tmpbuffer = NULL;
+
+		for (; ; index++) {
+			node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP,
+						      index);
+			if (node == -E2BIG) {
+				debug("%s: No additional FDT node\n", __func__);
+				break;
+			} else if (node < 0) {
+				debug("%s: unable to find FDT node %d\n",
+				      __func__, index);
+				continue;
+			}
+
+			if (!tmpbuffer) {
+				/*
+				 * allocate memory to store the DT overlay
+				 * before it is applied. It may not be used
+				 * depending on how the overlay is stored, so
+				 * don't fail yet if the allocation failed.
+				 */
+				tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ);
+				if (!tmpbuffer)
+					debug("%s: unable to allocate space for overlays\n",
+					      __func__);
+			}
+			image_info.load_addr = (ulong)tmpbuffer;
+			ret = spl_load_fit_image(info, sector, fit, base_offset,
+						 node, &image_info);
+			if (ret < 0)
+				break;
+
+			/* Make room in FDT for changes from the overlay */
+			ret = fdt_increase_size(spl_image->fdt_addr,
+						image_info.size);
+			if (ret < 0)
+				break;
+
+			ret = fdt_overlay_apply_verbose(spl_image->fdt_addr,
+							(void *)image_info.load_addr);
+			if (ret) {
+				pr_err("failed to apply DT overlay %s\n",
+				       fit_get_name(fit, node, NULL));
+				break;
+			}
+
+			debug("%s: DT overlay %s applied\n", __func__,
+			      fit_get_name(fit, node, NULL));
+		}
+		if (tmpbuffer)
+			free(tmpbuffer);
+		if (ret)
+			return ret;
+	}
 	/* Try to make space, so we can inject details on the loadables */
 	ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
+	if (ret < 0)
+		return ret;
 #endif
 
 	return ret;
@@ -325,7 +446,7 @@
 {
 	int ret = 0;
 #if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
-	char *name;
+	const char *name;
 	int node;
 
 	ret = spl_fit_get_image_name(fit, images, "loadables",
@@ -373,6 +494,7 @@
 	int images, ret;
 	int base_offset, hsize, align_len = ARCH_DMA_MINALIGN - 1;
 	int index = 0;
+	int firmware_node;
 
 	/*
 	 * For FIT with external data, figure out where the external images
@@ -502,6 +624,7 @@
 		spl_fit_append_fdt(spl_image, info, sector, fit,
 				   images, base_offset);
 
+	firmware_node = node;
 	/* Now check if there are more images for us to load */
 	for (; ; index++) {
 		uint8_t os_type = IH_OS_INVALID;
@@ -510,6 +633,14 @@
 		if (node < 0)
 			break;
 
+		/*
+		 * if the firmware is also a loadable, skip it because
+		 * it already has been loaded. This is typically the case with
+		 * u-boot.img generated by mkimage.
+		 */
+		if (firmware_node == node)
+			continue;
+
 		ret = spl_load_fit_image(info, sector, fit, base_offset, node,
 					 &image_info);
 		if (ret < 0)
diff --git a/drivers/Makefile b/drivers/Makefile
index cb8c215..b51bdee 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -26,6 +26,7 @@
 obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/
 obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm/
 obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += power/acpi_pmc/
+obj-$(CONFIG_$(SPL_)BOARD) += board/
 
 ifndef CONFIG_TPL_BUILD
 ifdef CONFIG_SPL_BUILD
@@ -75,7 +76,6 @@
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
-obj-y += board/
 obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
 obj-y += cache/
 obj-$(CONFIG_CPU) += cpu/
diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c
index 6609bf8..c6680dc 100644
--- a/drivers/ata/fsl_sata.c
+++ b/drivers/ata/fsl_sata.c
@@ -22,6 +22,7 @@
 #include <dm.h>
 #include <ahci.h>
 #include <blk.h>
+#include <dm/device-internal.h>
 #else
 #ifndef CONFIG_SYS_SATA1_FLAGS
 	#define CONFIG_SYS_SATA1_FLAGS	FLAGS_DMA
@@ -122,7 +123,7 @@
 	/* Zero all of the device driver struct */
 	memset((void *)sata, 0, sizeof(fsl_sata_t));
 
-	snprintf(sata->name, 12, "SATA%d:\n", dev);
+	snprintf(sata->name, 12, "SATA%d:", dev);
 
 	/* Set the controller register base address to device struct */
 #if !CONFIG_IS_ENABLED(BLK)
@@ -233,10 +234,7 @@
 	mdelay(100);
 
 	/* print sata device name */
-	if (!dev)
-		printf("%s ", sata->name);
-	else
-		printf("       %s ", sata->name);
+	printf("%s ", sata->name);
 
 	/* Wait PHY RDY signal changed for 500ms */
 	ata_wait_register(&reg->hstatus, HSTATUS_PHY_RDY,
@@ -917,15 +915,32 @@
 	return 0;
 }
 
+static int fsl_unbind_device(struct udevice *dev)
+{
+	int ret;
+
+	ret = device_remove(dev, DM_REMOVE_NORMAL);
+	if (ret)
+		return ret;
+
+	ret = device_unbind(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int fsl_ata_probe(struct udevice *dev)
 {
 	struct fsl_ata_priv *blk_priv, *priv;
 	struct udevice *blk;
+	int failed_number;
 	char sata_name[10];
 	int nr_ports;
 	int ret;
 	int i;
 
+	failed_number = 0;
 	priv = dev_get_priv(dev);
 	nr_ports = priv->number;
 	nr_ports = min(nr_ports, CONFIG_SYS_SATA_MAX_DEVICE);
@@ -943,7 +958,12 @@
 		ret = init_sata(priv, i);
 		if (ret) {
 			debug("%s: Failed to init sata\n", __func__);
-			return ret;
+			ret = fsl_unbind_device(blk);
+			if (ret)
+				return ret;
+
+			failed_number++;
+			continue;
 		}
 
 		blk_priv = dev_get_platdata(blk);
@@ -952,10 +972,33 @@
 		ret = scan_sata(blk);
 		if (ret) {
 			debug("%s: Failed to scan bus\n", __func__);
-			return ret;
+			ret = fsl_unbind_device(blk);
+			if (ret)
+				return ret;
+
+			failed_number++;
+			continue;
 		}
 	}
 
+	if (failed_number == nr_ports)
+		return -ENODEV;
+	else
+		return 0;
+}
+
+static int fsl_ata_remove(struct udevice *dev)
+{
+	fsl_sata_t *sata;
+	struct fsl_ata_priv *priv;
+
+	priv = dev_get_priv(dev);
+	sata = priv->fsl_sata;
+
+	free(sata->cmd_hdr_tbl_offset);
+	free(sata->cmd_desc_offset);
+	free(sata);
+
 	return 0;
 }
 
@@ -982,6 +1025,7 @@
 	.ops = &sata_fsl_ahci_ops,
 	.ofdata_to_platdata = fsl_ata_ofdata_to_platdata,
 	.probe	= fsl_ata_probe,
+	.remove = fsl_ata_remove,
 	.priv_auto_alloc_size = sizeof(struct fsl_ata_priv),
 };
 #endif
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 4a50460..71ee0c0 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -20,6 +20,7 @@
 #if CONFIG_IS_ENABLED(BLK)
 #include <dm.h>
 #include <blk.h>
+#include <dm/device-internal.h>
 #endif
 
 #include "sata_sil.h"
@@ -763,15 +764,33 @@
 	.platdata_auto_alloc_size = sizeof(struct sil_sata_priv),
 };
 
+static int sil_unbind_device(struct udevice *dev)
+{
+	int ret;
+
+	ret = device_remove(dev, DM_REMOVE_NORMAL);
+	if (ret)
+		return ret;
+
+	ret = device_unbind(dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int sil_pci_probe(struct udevice *dev)
 {
 	struct udevice *blk;
+	int failed_number;
 	char sata_name[10];
 	pci_dev_t devno;
 	u16 word;
 	int ret;
 	int i;
 
+	failed_number = 0;
+
 	/* Get PCI device number */
 	devno = dm_pci_get_bdf(dev);
 	if (devno == -1)
@@ -824,12 +843,44 @@
 		}
 
 		ret = sil_init_sata(blk, i);
-		if (ret)
-			return -ENODEV;
+		if (ret) {
+			ret = sil_unbind_device(blk);
+			if (ret)
+				return ret;
+
+			failed_number++;
+			continue;
+		}
 
 		ret = scan_sata(blk, i);
-		if (ret)
-			return -ENODEV;
+		if (ret) {
+			ret = sil_unbind_device(blk);
+			if (ret)
+				return ret;
+
+			failed_number++;
+			continue;
+		}
+	}
+
+	if (failed_number == sata_info.maxport)
+		return -ENODEV;
+	else
+		return 0;
+}
+
+static int sil_pci_remove(struct udevice *dev)
+{
+	int i;
+	struct sil_sata *sata;
+	struct sil_sata_priv *priv;
+
+	priv = dev_get_priv(dev);
+
+	for (i = sata_info.portbase; i < sata_info.maxport; i++) {
+		sata = priv->sil_sata_desc[i];
+		if (sata)
+			free(sata);
 	}
 
 	return 0;
@@ -857,6 +908,7 @@
 	.of_match = sil_pci_ids,
 	.ops = &sata_sil_ops,
 	.probe = sil_pci_probe,
+	.remove = sil_pci_remove,
 	.priv_auto_alloc_size = sizeof(struct sil_sata_priv),
 };
 
diff --git a/drivers/board/Kconfig b/drivers/board/Kconfig
index 2a3fc9c..254f657 100644
--- a/drivers/board/Kconfig
+++ b/drivers/board/Kconfig
@@ -8,6 +8,9 @@
 
 if BOARD
 
+config SPL_BOARD
+	depends on SPL_DM
+	bool "Enable board driver support in SPL"
 
 config BOARD_GAZERBEAM
 	bool "Enable board driver for the Gazerbeam board"
diff --git a/drivers/board/Makefile b/drivers/board/Makefile
index c8dab4f..cc16361 100644
--- a/drivers/board/Makefile
+++ b/drivers/board/Makefile
@@ -2,6 +2,6 @@
 #
 # (C) Copyright 2017
 # Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
-obj-$(CONFIG_BOARD) += board-uclass.o
+obj-y += board-uclass.o
 obj-$(CONFIG_BOARD_GAZERBEAM) += gazerbeam.o
 obj-$(CONFIG_BOARD_SANDBOX) += sandbox.o
diff --git a/drivers/board/board-uclass.c b/drivers/board/board-uclass.c
index a516ba4..b5485e9 100644
--- a/drivers/board/board-uclass.c
+++ b/drivers/board/board-uclass.c
@@ -23,6 +23,17 @@
 	return ops->detect(dev);
 }
 
+int board_get_fit_loadable(struct udevice *dev, int index,
+			   const char *type, const char **strp)
+{
+	struct board_ops *ops = board_get_ops(dev);
+
+	if (!ops->get_fit_loadable)
+		return -ENOSYS;
+
+	return ops->get_fit_loadable(dev, index, type, strp);
+}
+
 int board_get_bool(struct udevice *dev, int id, bool *val)
 {
 	struct board_ops *ops = board_get_ops(dev);
diff --git a/drivers/power/regulator/regulator_common.c b/drivers/power/regulator/regulator_common.c
index 2041086..939efb2 100644
--- a/drivers/power/regulator/regulator_common.c
+++ b/drivers/power/regulator/regulator_common.c
@@ -37,7 +37,11 @@
 	dev_pdata->startup_delay_us = dev_read_u32_default(dev,
 							"startup-delay-us", 0);
 	dev_pdata->off_on_delay_us =
+		dev_read_u32_default(dev, "off-on-delay-us", 0);
+	if (!dev_pdata->off_on_delay_us) {
+		dev_pdata->off_on_delay_us =
 			dev_read_u32_default(dev, "u-boot,off-on-delay-us", 0);
+	}
 
 	return 0;
 }
diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c
index e8026cd..5384812 100644
--- a/drivers/remoteproc/rproc-elf-loader.c
+++ b/drivers/remoteproc/rproc-elf-loader.c
@@ -8,6 +8,39 @@
 #include <elf.h>
 #include <remoteproc.h>
 
+/**
+ * struct resource_table - firmware resource table header
+ * @ver: version number
+ * @num: number of resource entries
+ * @reserved: reserved (must be zero)
+ * @offset: array of offsets pointing at the various resource entries
+ *
+ * A resource table is essentially a list of system resources required
+ * by the remote processor. It may also include configuration entries.
+ * If needed, the remote processor firmware should contain this table
+ * as a dedicated ".resource_table" ELF section.
+ *
+ * Some resources entries are mere announcements, where the host is informed
+ * of specific remoteproc configuration. Other entries require the host to
+ * do something (e.g. allocate a system resource). Sometimes a negotiation
+ * is expected, where the firmware requests a resource, and once allocated,
+ * the host should provide back its details (e.g. address of an allocated
+ * memory region).
+ *
+ * The header of the resource table, as expressed by this structure,
+ * contains a version number (should we need to change this format in the
+ * future), the number of available resource entries, and their offsets
+ * in the table.
+ *
+ * Immediately following this header are the resource entries themselves.
+ */
+struct resource_table {
+	u32 ver;
+	u32 num;
+	u32 reserved[2];
+	u32 offset[0];
+} __packed;
+
 /* Basic function to verify ELF32 image format */
 int rproc_elf32_sanity_check(ulong addr, ulong size)
 {
@@ -276,3 +309,239 @@
 	else
 		return rproc_elf32_get_boot_addr(addr);
 }
+
+/*
+ * Search for the resource table in an ELF32 image.
+ * Returns the address of the resource table section if found, NULL if there is
+ * no resource table section, or error pointer.
+ */
+static Elf32_Shdr *rproc_elf32_find_rsc_table(struct udevice *dev,
+					      ulong fw_addr, ulong fw_size)
+{
+	int ret;
+	unsigned int i;
+	const char *name_table;
+	struct resource_table *table;
+	const u8 *elf_data = (void *)fw_addr;
+	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
+	Elf32_Shdr *shdr;
+
+	ret = rproc_elf32_sanity_check(fw_addr, fw_size);
+	if (ret) {
+		pr_debug("Invalid ELF32 Image %d\n", ret);
+		return ERR_PTR(ret);
+	}
+
+	/* look for the resource table and handle it */
+	shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff);
+	name_table = (const char *)(elf_data +
+				    shdr[ehdr->e_shstrndx].sh_offset);
+
+	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+		u32 size = shdr->sh_size;
+		u32 offset = shdr->sh_offset;
+
+		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
+			continue;
+
+		table = (struct resource_table *)(elf_data + offset);
+
+		/* make sure we have the entire table */
+		if (offset + size > fw_size) {
+			pr_debug("resource table truncated\n");
+			return ERR_PTR(-ENOSPC);
+		}
+
+		/* make sure table has at least the header */
+		if (sizeof(*table) > size) {
+			pr_debug("header-less resource table\n");
+			return ERR_PTR(-ENOSPC);
+		}
+
+		/* we don't support any version beyond the first */
+		if (table->ver != 1) {
+			pr_debug("unsupported fw ver: %d\n", table->ver);
+			return ERR_PTR(-EPROTONOSUPPORT);
+		}
+
+		/* make sure reserved bytes are zeroes */
+		if (table->reserved[0] || table->reserved[1]) {
+			pr_debug("non zero reserved bytes\n");
+			return ERR_PTR(-EBADF);
+		}
+
+		/* make sure the offsets array isn't truncated */
+		if (table->num * sizeof(table->offset[0]) +
+				 sizeof(*table) > size) {
+			pr_debug("resource table incomplete\n");
+			return ERR_PTR(-ENOSPC);
+		}
+
+		return shdr;
+	}
+
+	return NULL;
+}
+
+/* Load the resource table from an ELF32 image */
+int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
+			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
+{
+	const struct dm_rproc_ops *ops;
+	Elf32_Shdr *shdr;
+	void *src, *dst;
+
+	shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
+	if (!shdr)
+		return -ENODATA;
+	if (IS_ERR(shdr))
+		return PTR_ERR(shdr);
+
+	ops = rproc_get_ops(dev);
+	*rsc_addr = (ulong)shdr->sh_addr;
+	*rsc_size = (ulong)shdr->sh_size;
+
+	src = (void *)fw_addr + shdr->sh_offset;
+	if (ops->device_to_virt)
+		dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
+	else
+		dst = (void *)rsc_addr;
+
+	dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
+		(ulong)dst, *rsc_size);
+
+	memcpy(dst, src, *rsc_size);
+	flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+		    roundup((unsigned long)dst + *rsc_size,
+			    ARCH_DMA_MINALIGN) -
+		    rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
+
+	return 0;
+}
+
+/*
+ * Search for the resource table in an ELF64 image.
+ * Returns the address of the resource table section if found, NULL if there is
+ * no resource table section, or error pointer.
+ */
+static Elf64_Shdr *rproc_elf64_find_rsc_table(struct udevice *dev,
+					      ulong fw_addr, ulong fw_size)
+{
+	int ret;
+	unsigned int i;
+	const char *name_table;
+	struct resource_table *table;
+	const u8 *elf_data = (void *)fw_addr;
+	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)fw_addr;
+	Elf64_Shdr *shdr;
+
+	ret = rproc_elf64_sanity_check(fw_addr, fw_size);
+	if (ret) {
+		pr_debug("Invalid ELF64 Image %d\n", ret);
+		return ERR_PTR(ret);
+	}
+
+	/* look for the resource table and handle it */
+	shdr = (Elf64_Shdr *)(elf_data + ehdr->e_shoff);
+	name_table = (const char *)(elf_data +
+				    shdr[ehdr->e_shstrndx].sh_offset);
+
+	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+		u64 size = shdr->sh_size;
+		u64 offset = shdr->sh_offset;
+
+		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
+			continue;
+
+		table = (struct resource_table *)(elf_data + offset);
+
+		/* make sure we have the entire table */
+		if (offset + size > fw_size) {
+			pr_debug("resource table truncated\n");
+			return ERR_PTR(-ENOSPC);
+		}
+
+		/* make sure table has at least the header */
+		if (sizeof(*table) > size) {
+			pr_debug("header-less resource table\n");
+			return ERR_PTR(-ENOSPC);
+		}
+
+		/* we don't support any version beyond the first */
+		if (table->ver != 1) {
+			pr_debug("unsupported fw ver: %d\n", table->ver);
+			return ERR_PTR(-EPROTONOSUPPORT);
+		}
+
+		/* make sure reserved bytes are zeroes */
+		if (table->reserved[0] || table->reserved[1]) {
+			pr_debug("non zero reserved bytes\n");
+			return ERR_PTR(-EBADF);
+		}
+
+		/* make sure the offsets array isn't truncated */
+		if (table->num * sizeof(table->offset[0]) +
+				 sizeof(*table) > size) {
+			pr_debug("resource table incomplete\n");
+			return ERR_PTR(-ENOSPC);
+		}
+
+		return shdr;
+	}
+
+	return NULL;
+}
+
+/* Load the resource table from an ELF64 image */
+int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
+			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
+{
+	const struct dm_rproc_ops *ops;
+	Elf64_Shdr *shdr;
+	void *src, *dst;
+
+	shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
+	if (!shdr)
+		return -ENODATA;
+	if (IS_ERR(shdr))
+		return PTR_ERR(shdr);
+
+	ops = rproc_get_ops(dev);
+	*rsc_addr = (ulong)shdr->sh_addr;
+	*rsc_size = (ulong)shdr->sh_size;
+
+	src = (void *)fw_addr + shdr->sh_offset;
+	if (ops->device_to_virt)
+		dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
+	else
+		dst = (void *)rsc_addr;
+
+	dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
+		(ulong)dst, *rsc_size);
+
+	memcpy(dst, src, *rsc_size);
+	flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+		    roundup((unsigned long)dst + *rsc_size,
+			    ARCH_DMA_MINALIGN) -
+		    rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
+
+	return 0;
+}
+
+/* Load the resource table from an ELF32 or ELF64 image */
+int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
+			     ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
+
+{
+	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
+
+	if (!fw_addr)
+		return -EFAULT;
+
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return rproc_elf64_load_rsc_table(dev, fw_addr, fw_size,
+						  rsc_addr, rsc_size);
+	else
+		return rproc_elf32_load_rsc_table(dev, fw_addr, fw_size,
+						  rsc_addr, rsc_size);
+}
diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c
index 40bba37..c25488f 100644
--- a/drivers/remoteproc/stm32_copro.c
+++ b/drivers/remoteproc/stm32_copro.c
@@ -22,14 +22,14 @@
  * @hold_boot_regmap:	regmap for remote processor reset hold boot
  * @hold_boot_offset:	offset of the register controlling the hold boot setting
  * @hold_boot_mask:	bitmask of the register for the hold boot field
- * @is_running:		is the remote processor running
+ * @rsc_table_addr:	resource table address
  */
 struct stm32_copro_privdata {
 	struct reset_ctl reset_ctl;
 	struct regmap *hold_boot_regmap;
 	uint hold_boot_offset;
 	uint hold_boot_mask;
-	bool is_running;
+	ulong rsc_table_addr;
 };
 
 /**
@@ -141,6 +141,7 @@
 static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size)
 {
 	struct stm32_copro_privdata *priv;
+	ulong rsc_table_size;
 	int ret;
 
 	priv = dev_get_priv(dev);
@@ -155,6 +156,12 @@
 		return ret;
 	}
 
+	if (rproc_elf32_load_rsc_table(dev, addr, size, &priv->rsc_table_addr,
+				       &rsc_table_size)) {
+		priv->rsc_table_addr = 0;
+		dev_warn(dev, "No valid resource table for this firmware\n");
+	}
+
 	return rproc_elf32_load_image(dev, addr, size);
 }
 
@@ -180,7 +187,12 @@
 	 * rebooting autonomously
 	 */
 	ret = stm32_copro_set_hold_boot(dev, true);
-	priv->is_running = !ret;
+	writel(ret ? TAMP_COPRO_STATE_OFF : TAMP_COPRO_STATE_CRUN,
+	       TAMP_COPRO_STATE);
+	if (!ret)
+		/* Store rsc_address in bkp register */
+		writel(priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS);
+
 	return ret;
 }
 
@@ -206,7 +218,7 @@
 		return ret;
 	}
 
-	priv->is_running = false;
+	writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE);
 
 	return 0;
 }
@@ -224,14 +236,11 @@
 /**
  * stm32_copro_is_running() - Is the STM32 remote processor running
  * @dev:	corresponding STM32 remote processor device
- * @return 1 if the remote processor is running, 0 otherwise
+ * @return 0 if the remote processor is running, 1 otherwise
  */
 static int stm32_copro_is_running(struct udevice *dev)
 {
-	struct stm32_copro_privdata *priv;
-
-	priv = dev_get_priv(dev);
-	return priv->is_running;
+	return (readl(TAMP_COPRO_STATE) == TAMP_COPRO_STATE_OFF);
 }
 
 static const struct dm_rproc_ops stm32_copro_ops = {
diff --git a/dts/Kconfig b/dts/Kconfig
index 2bd959a..64c98dd 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -130,6 +130,14 @@
 	  device tree files (without the directory or .dtb suffix)
 	  separated by <space>.
 
+config OF_OVERLAY_LIST
+	string "List of device tree overlays to include for DT control"
+	depends on SPL_LOAD_FIT_APPLY_OVERLAY
+	help
+	  This option specifies a list of device tree overlays to use for DT
+	  control. This option can then be used by a FIT generator to include
+	  the overlays in the FIT image.
+
 choice
 	prompt "OF LIST compression"
 	depends on MULTI_DTB_FIT
diff --git a/include/board.h b/include/board.h
index 9dc7868..678b652 100644
--- a/include/board.h
+++ b/include/board.h
@@ -31,6 +31,7 @@
  * to read the serial number.
  */
 
+#if CONFIG_IS_ENABLED(BOARD)
 struct board_ops {
 	/**
 	 * detect() - Run the hardware info detection procedure for this
@@ -79,6 +80,24 @@
 	 * Return: 0 if OK, -ve on error.
 	 */
 	int (*get_str)(struct udevice *dev, int id, size_t size, char *val);
+
+	/**
+	 * get_fit_loadable - Get the name of an image to load from FIT
+	 * This function can be used to provide the image names based on runtime
+	 * detection. A classic use-case would when DTBOs are used to describe
+	 * additionnal daughter cards.
+	 *
+	 * @dev:	The board instance to gather the data.
+	 * @index:	Index of the image. Starts at 0 and gets incremented
+	 *		after each call to this function.
+	 * @type:	The type of image. For example, "fdt" for DTBs
+	 * @strp:	A pointer to string. Untouched if the function fails
+	 *
+	 * Return: 0 if OK, -ENOENT if no loadable is available else -ve on
+	 * error.
+	 */
+	int (*get_fit_loadable)(struct udevice *dev, int index,
+				const char *type, const char **strp);
 };
 
 #define board_get_ops(dev)	((struct board_ops *)(dev)->driver->ops)
@@ -137,3 +156,58 @@
  * Return: 0 if OK, -ve on error.
  */
 int board_get(struct udevice **devp);
+
+/**
+ * board_get_fit_loadable - Get the name of an image to load from FIT
+ * This function can be used to provide the image names based on runtime
+ * detection. A classic use-case would when DTBOs are used to describe
+ * additionnal daughter cards.
+ *
+ * @dev:	The board instance to gather the data.
+ * @index:	Index of the image. Starts at 0 and gets incremented
+ *		after each call to this function.
+ * @type:	The type of image. For example, "fdt" for DTBs
+ * @strp:	A pointer to string. Untouched if the function fails
+ *
+ *
+ * Return: 0 if OK, -ENOENT if no loadable is available else -ve on
+ * error.
+ */
+int board_get_fit_loadable(struct udevice *dev, int index,
+			   const char *type, const char **strp);
+
+#else
+
+static inline int board_detect(struct udevice *dev)
+{
+	return -ENOSYS;
+}
+
+static inline int board_get_bool(struct udevice *dev, int id, bool *val)
+{
+	return -ENOSYS;
+}
+
+static inline int board_get_int(struct udevice *dev, int id, int *val)
+{
+	return -ENOSYS;
+}
+
+static inline int board_get_str(struct udevice *dev, int id, size_t size,
+				char *val)
+{
+	return -ENOSYS;
+}
+
+static inline int board_get(struct udevice **devp)
+{
+	return -ENOSYS;
+}
+
+static inline int board_get_fit_loadable(struct udevice *dev, int index,
+					 const char *type, const char **strp)
+{
+	return -ENOSYS;
+}
+
+#endif
diff --git a/include/configs/gardena-smart-gateway-at91sam.h b/include/configs/gardena-smart-gateway-at91sam.h
index 482e471..f5ee65c 100644
--- a/include/configs/gardena-smart-gateway-at91sam.h
+++ b/include/configs/gardena-smart-gateway-at91sam.h
@@ -64,7 +64,6 @@
 #define CONFIG_SPL_NAND_RAW_ONLY
 #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x40000
 #define CONFIG_SYS_NAND_U_BOOT_SIZE	0xa0000
-#define	CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
 #define	CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_NAND_U_BOOT_DST	CONFIG_SYS_TEXT_BASE
 
diff --git a/include/configs/ls1046a_common.h b/include/configs/ls1046a_common.h
index cc8f4c0..6543cfd 100644
--- a/include/configs/ls1046a_common.h
+++ b/include/configs/ls1046a_common.h
@@ -98,7 +98,6 @@
 					CONFIG_SPL_BSS_MAX_SIZE)
 #define CONFIG_SYS_SPL_MALLOC_SIZE	0x100000
 #define CONFIG_SYS_MONITOR_LEN		0x100000
-#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
 #endif
 
 /* NAND SPL */
diff --git a/include/configs/mccmon6.h b/include/configs/mccmon6.h
index 045a9f7..0aee1e1 100644
--- a/include/configs/mccmon6.h
+++ b/include/configs/mccmon6.h
@@ -12,7 +12,6 @@
 #define CONFIG_SPL_LIBCOMMON_SUPPORT
 #include "imx6_spl.h"
 
-#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + 0x80000)
 #define CONFIG_SYS_SPL_ARGS_ADDR	0x18000000
 
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h
index 385b30c..8ca0e83 100644
--- a/include/configs/microblaze-generic.h
+++ b/include/configs/microblaze-generic.h
@@ -173,8 +173,6 @@
 /* Just for sure that there is a space for stack */
 #define CONFIG_SPL_STACK_SIZE		0x100
 
-#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
-
 #define CONFIG_SPL_MAX_FOOTPRINT	(CONFIG_SYS_INIT_RAM_SIZE - \
 					 CONFIG_SYS_INIT_RAM_ADDR - \
 					 CONFIG_SYS_MALLOC_F_LEN - \
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
index e5182ae..faab091 100644
--- a/include/configs/mt7623.h
+++ b/include/configs/mt7623.h
@@ -31,7 +31,6 @@
 #define CONFIG_ENV_OVERWRITE
 
 /* Preloader -> Uboot */
-#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
 					 GENERATED_GBL_DATA_SIZE)
 
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
index 4aef894..6a6c2f2 100644
--- a/include/configs/mt7629.h
+++ b/include/configs/mt7629.h
@@ -40,7 +40,6 @@
 #define CONFIG_SYS_UBOOT_BASE		(CONFIG_SPI_ADDR + CONFIG_SPL_PAD_TO)
 
 /* SPL -> Uboot */
-#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
 					 GENERATED_GBL_DATA_SIZE)
 
diff --git a/include/configs/mt8518.h b/include/configs/mt8518.h
index a7fe83a..514722b 100644
--- a/include/configs/mt8518.h
+++ b/include/configs/mt8518.h
@@ -29,7 +29,6 @@
 #define CONFIG_SYS_BOOTM_LEN			SZ_64M
 
 /* Uboot definition */
-#define CONFIG_SYS_UBOOT_START			CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_INIT_SP_ADDR			(CONFIG_SYS_TEXT_BASE + \
 						SZ_2M - \
 						GENERATED_GBL_DATA_SIZE)
diff --git a/include/configs/omap3_cairo.h b/include/configs/omap3_cairo.h
index 1b1a56d..c76c81d 100644
--- a/include/configs/omap3_cairo.h
+++ b/include/configs/omap3_cairo.h
@@ -26,7 +26,6 @@
  * other needs.  We use this rather than the inherited defines from
  * ti_armv7_common.h for backwards compatibility.
  */
-#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
 #define CONFIG_SPL_BSS_START_ADDR	0x80000000
 #define CONFIG_SPL_BSS_MAX_SIZE		(512 << 10)	/* 512 KB */
 #define CONFIG_SYS_SPL_MALLOC_START	0x80208000
diff --git a/include/configs/pumpkin.h b/include/configs/pumpkin.h
index 35e28be..9c52cae 100644
--- a/include/configs/pumpkin.h
+++ b/include/configs/pumpkin.h
@@ -23,7 +23,6 @@
 #define CONFIG_SYS_NS16550_COM1		0x11005000
 #define CONFIG_SYS_NS16550_CLK		26000000
 
-#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE + SZ_2M - \
 						 GENERATED_GBL_DATA_SIZE)
 
diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h
index b4da1f8..f2cdd9c 100644
--- a/include/configs/tegra-common.h
+++ b/include/configs/tegra-common.h
@@ -61,7 +61,6 @@
 #define PHYS_SDRAM_1		NV_PA_SDRC_CS0
 #define PHYS_SDRAM_1_SIZE	0x20000000	/* 512M */
 
-#define CONFIG_SYS_UBOOT_START	CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_SDRAM_BASE	PHYS_SDRAM_1
 
 #define CONFIG_SYS_BOOTMAPSZ	(256 << 20)	/* 256M */
diff --git a/include/configs/x600.h b/include/configs/x600.h
index 63092b2..8b6caae 100644
--- a/include/configs/x600.h
+++ b/include/configs/x600.h
@@ -27,7 +27,6 @@
 #define CONFIG_SYS_SPL_LEN			CONFIG_SPL_PAD_TO
 #define CONFIG_SYS_UBOOT_BASE			(CONFIG_SYS_FLASH_BASE + \
 						 CONFIG_SYS_SPL_LEN)
-#define CONFIG_SYS_UBOOT_START			CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_BASE			CONFIG_SYS_FLASH_BASE
 #define CONFIG_SYS_MONITOR_LEN			0x60000
 
diff --git a/include/configs/xilinx_zynqmp_r5.h b/include/configs/xilinx_zynqmp_r5.h
index 38d952d..155d7fe 100644
--- a/include/configs/xilinx_zynqmp_r5.h
+++ b/include/configs/xilinx_zynqmp_r5.h
@@ -35,8 +35,6 @@
 /* Extend size of kernel image for uncompression */
 #define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
 
-#define CONFIG_SYS_UBOOT_START	CONFIG_SYS_TEXT_BASE
-
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
 /* 0x0 - 0x40 is used for placing exception vectors */
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 274cc19..189ca81 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -274,6 +274,4 @@
 
 #define CONFIG_SPL_LOAD_FIT_ADDRESS 0x10000000
 
-#define CONFIG_SYS_UBOOT_START	CONFIG_SYS_TEXT_BASE
-
 #endif /* __CONFIG_ZYNQ_COMMON_H */
diff --git a/include/remoteproc.h b/include/remoteproc.h
index 046cd9e..a903acb 100644
--- a/include/remoteproc.h
+++ b/include/remoteproc.h
@@ -277,6 +277,64 @@
  * image.
  */
 ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr);
+
+/**
+ * rproc_elf32_load_rsc_table() - load the resource table from an ELF32 image
+ *
+ * Search for the resource table in an ELF32 image, and if found, copy it to
+ * device memory.
+ *
+ * @dev:	device loading the resource table
+ * @fw_addr:	ELF image address
+ * @fw_size:	size of the ELF image
+ * @rsc_addr:	pointer to the found resource table address. Updated on
+ *		operation success
+ * @rsc_size:	pointer to the found resource table size. Updated on operation
+ *		success
+ *
+ * @return 0 if a valid resource table is successfully loaded, -ENODATA if there
+ * is no resource table (which is optional), or another appropriate error value.
+ */
+int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
+			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
+/**
+ * rproc_elf64_load_rsc_table() - load the resource table from an ELF64 image
+ *
+ * Search for the resource table in an ELF64 image, and if found, copy it to
+ * device memory.
+ *
+ * @dev:	device loading the resource table
+ * @fw_addr:	ELF image address
+ * @fw_size:	size of the ELF image
+ * @rsc_addr:	pointer to the found resource table address. Updated on
+ *		operation success
+ * @rsc_size:	pointer to the found resource table size. Updated on operation
+ *		success
+ *
+ * @return 0 if a valid resource table is successfully loaded, -ENODATA if there
+ * is no resource table (which is optional), or another appropriate error value.
+ */
+int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
+			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
+/**
+ * rproc_elf_load_rsc_table() - load the resource table from an ELF image
+ *
+ * Auto detects if the image is ELF32 or ELF64 image and search accordingly for
+ * the resource table, and if found, copy it to device memory.
+ *
+ * @dev:	device loading the resource table
+ * @fw_addr:	ELF image address
+ * @fw_size:	size of the ELF image
+ * @rsc_addr:	pointer to the found resource table address. Updated on
+ *		operation success
+ * @rsc_size:	pointer to the found resource table size. Updated on operation
+ *		success
+ *
+ * @return 0 if a valid resource table is successfully loaded, -ENODATA if there
+ * is no resource table (which is optional), or another appropriate error value.
+ */
+int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
+			     ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
 #else
 static inline int rproc_init(void) { return -ENOSYS; }
 static inline int rproc_dev_init(int id) { return -ENOSYS; }
@@ -304,6 +362,18 @@
 { return -ENOSYS; }
 static inline ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
 { return 0; }
+static inline int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
+					     ulong fw_size, ulong *rsc_addr,
+					     ulong *rsc_size)
+{ return -ENOSYS; }
+static inline int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
+					     ulong fw_size, ulong *rsc_addr,
+					     ulong *rsc_size)
+{ return -ENOSYS; }
+static inline int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
+					   ulong fw_size, ulong *rsc_addr,
+					   ulong *rsc_size)
+{ return -ENOSYS; }
 #endif
 
 #endif	/* _RPROC_H_ */
diff --git a/include/test/suites.h b/include/test/suites.h
index 20970f0..0748185 100644
--- a/include/test/suites.h
+++ b/include/test/suites.h
@@ -13,6 +13,7 @@
  * cmd_ut_category() - Run a category of unit tests
  *
  * @name:	Category name
+ * @prefix:	Prefix of test name
  * @tests:	List of tests to run
  * @n_ents:	Number of tests in @tests
  * @argc:	Argument count provided. Must be >= 1. If this is 1 then all
@@ -20,7 +21,8 @@
  * @argv:	Arguments: argv[1] is the test to run (if @argc >= 2)
  * @return 0 if OK, CMD_RET_FAILURE on failure
  */
-int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
+int cmd_ut_category(const char *name, const char *prefix,
+		    struct unit_test *tests, int n_ents,
 		    int argc, char * const argv[]);
 
 int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index c10cd83..4ea898a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -292,6 +292,10 @@
 $(obj)/%.dtb.S: $(obj)/%.dtb
 	$(call cmd,dt_S_dtb)
 
+ifeq ($(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY),y)
+DTC_FLAGS += -@
+endif
+
 quiet_cmd_dtc = DTC     $@
 # Modified for U-Boot
 # Bring in any U-Boot-specific include at the end of the file
diff --git a/test/bloblist.c b/test/bloblist.c
index 89bdb01..d0f7296 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -183,5 +183,6 @@
 						 bloblist_test);
 	const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
 
-	return cmd_ut_category("bloblist", tests, n_ents, argc, argv);
+	return cmd_ut_category("bloblist", "bloblist_test_",
+			       tests, n_ents, argc, argv);
 }
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 2781f8b..400719e 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -11,17 +11,25 @@
 
 static int do_ut_all(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 
-int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
+int cmd_ut_category(const char *name, const char *prefix,
+		    struct unit_test *tests, int n_ents,
 		    int argc, char * const argv[])
 {
 	struct unit_test_state uts = { .fail_count = 0 };
 	struct unit_test *test;
+	int prefix_len = prefix ? strlen(prefix) : 0;
 
 	if (argc == 1)
 		printf("Running %d %s tests\n", n_ents, name);
 
 	for (test = tests; test < tests + n_ents; test++) {
-		if (argc > 1 && strcmp(argv[1], test->name))
+		const char *test_name = test->name;
+
+		/* Remove the prefix */
+		if (!strncmp(test_name, prefix, prefix_len))
+			test_name += prefix_len;
+
+		if (argc > 1 && strcmp(argv[1], test_name))
 			continue;
 		printf("Test: %s\n", test->name);
 
diff --git a/test/compression.c b/test/compression.c
index 48dccc0..cf040d7 100644
--- a/test/compression.c
+++ b/test/compression.c
@@ -540,5 +540,6 @@
 						 compression_test);
 	const int n_ents = ll_entry_count(struct unit_test, compression_test);
 
-	return cmd_ut_category("compression", tests, n_ents, argc, argv);
+	return cmd_ut_category("compression", "compression_test_",
+			       tests, n_ents, argc, argv);
 }
diff --git a/test/dm/remoteproc.c b/test/dm/remoteproc.c
index 1d9a9b3..4067596 100644
--- a/test/dm/remoteproc.c
+++ b/test/dm/remoteproc.c
@@ -103,8 +103,8 @@
 		0x00, 0x00, 0x00, 0x08,
 		/* phoff (program header offset @ 0x40)*/
 		0x40, 0x00, 0x00, 0x00,
-		/* shoff (section header offset : none) */
-		0x00, 0x00, 0x00, 0x00,
+		/* shoff (section header offset @ 0x90) */
+		0x90, 0x00, 0x00, 0x00,
 		/* flags */
 		0x00, 0x00, 0x00, 0x00,
 		/* ehsize (elf header size = 0x34) */
@@ -113,16 +113,17 @@
 		0x20, 0x00,
 		/* phnum (program header number : 1) */
 		0x01, 0x00,
+		/* shentsize (section header size : 40 bytes) */
+		0x28, 0x00,
+		/* shnum (section header number: 3) */
+		0x02, 0x00,
+		/* shstrndx (section header name section index: 1) */
+		0x01, 0x00,
-		/* shentsize (section heade size : none) */
-		0x00, 0x00,
-		/* shnum (section header number: none) */
-		0x00, 0x00,
-		/* shstrndx (section header name section index: none) */
-		0x00, 0x00,
 		/* padding */
 		0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00,
+
 		/* @0x40 - PROGRAM HEADER TABLE - */
 		/* type : PT_LOAD */
 		0x01, 0x00, 0x00, 0x00,
@@ -140,14 +141,63 @@
 		0x05, 0x00, 0x00, 0x00,
 		/* padding */
 		0x00, 0x00, 0x00, 0x00,
+
+		/* @0x60 - RESOURCE TABLE SECTION - */
+		/* version */
+		0x01, 0x00, 0x00, 0x00,
+		/* num (0, no entries) */
+		0x00, 0x00, 0x00, 0x00,
+		/* Reserved */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+		/* @0x70 - SECTION'S NAMES SECTION - */
+		/* section 0 name (".shrtrtab") */
+		0x2e, 0x73, 0x68, 0x73, 0x74, 0x72, 0x74, 0x61, 0x62, 0x00,
+		/* section 1 name (".resource_table") */
+		0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
+		0x74, 0x61, 0x62, 0x6c, 0x65, 0x00,
+		/* padding */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+		/* @0x90 - SECTION HEADER TABLE - */
+		/* Section 0 : resource table header */
+		/* sh_name - index into section header string table section */
+		0x0a, 0x00, 0x00, 0x00,
+		/* sh_type and sh_flags */
+		0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+		/* sh_addr = where the resource table has to be copied to */
+		0x00, 0x00, 0x00, 0x00,
+		/* sh_offset = 0x60 */
+		0x60, 0x00, 0x00, 0x00,
+		/* sh_size = 16 bytes */
+		0x10, 0x00, 0x00, 0x00,
+		/* sh_link, sh_info, sh_addralign, sh_entsize */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		/* Section 1 : section's names section header */
+		/* sh_name - index into section header string table section */
+		0x00, 0x00, 0x00, 0x00,
+		/* sh_type and sh_flags */
+		0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		/* sh_addr  */
+		0x00, 0x00, 0x00, 0x00,
+		/* sh_offset = 0x70 */
+		0x70, 0x00, 0x00, 0x00,
+		/* sh_size = 27 bytes */
+		0x1b, 0x00, 0x00, 0x00,
+		/* sh_link, sh_info, sh_addralign, sh_entsize */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	};
 	unsigned int size = ARRAY_SIZE(valid_elf32);
 	struct udevice *dev;
-	phys_addr_t loaded_firmware_paddr;
-	void *loaded_firmware;
-	u32 loaded_firmware_size;
+	phys_addr_t loaded_firmware_paddr, loaded_rsc_table_paddr;
+	void *loaded_firmware, *loaded_rsc_table;
+	u32 loaded_firmware_size, rsc_table_size;
+	ulong rsc_addr, rsc_size;
 	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)valid_elf32;
 	Elf32_Phdr *phdr = (Elf32_Phdr *)(valid_elf32 + ehdr->e_phoff);
+	Elf32_Shdr *shdr = (Elf32_Shdr *)(valid_elf32 + ehdr->e_shoff);
 
 	ut_assertok(uclass_get_device(UCLASS_REMOTEPROC, 0, &dev));
 
@@ -178,6 +228,25 @@
 		    0x08000000);
 	unmap_physmem(loaded_firmware, MAP_NOCACHE);
 
+	/* Resource table */
+	shdr->sh_addr = CONFIG_SYS_SDRAM_BASE;
+	rsc_table_size = shdr->sh_size;
+
+	loaded_rsc_table_paddr = shdr->sh_addr + DEVICE_TO_PHYSICAL_OFFSET;
+	loaded_rsc_table = map_physmem(loaded_rsc_table_paddr,
+				       rsc_table_size, MAP_NOCACHE);
+	ut_assertnonnull(loaded_rsc_table);
+	memset(loaded_rsc_table, 0, rsc_table_size);
+
+	/* Load and verify */
+	ut_assertok(rproc_elf32_load_rsc_table(dev, (ulong)valid_elf32, size,
+					       &rsc_addr, &rsc_size));
+	ut_asserteq(rsc_addr, CONFIG_SYS_SDRAM_BASE);
+	ut_asserteq(rsc_size, rsc_table_size);
+	ut_assertok(memcmp(loaded_firmware, valid_elf32 + shdr->sh_offset,
+			   shdr->sh_size));
+	unmap_physmem(loaded_firmware, MAP_NOCACHE);
+
 	/* Invalid ELF Magic */
 	valid_elf32[0] = 0;
 	ut_asserteq(-EPROTONOSUPPORT,
diff --git a/test/env/cmd_ut_env.c b/test/env/cmd_ut_env.c
index 54041a0..ad67dbe 100644
--- a/test/env/cmd_ut_env.c
+++ b/test/env/cmd_ut_env.c
@@ -15,5 +15,6 @@
 	struct unit_test *tests = ll_entry_start(struct unit_test, env_test);
 	const int n_ents = ll_entry_count(struct unit_test, env_test);
 
-	return cmd_ut_category("environment", tests, n_ents, argc, argv);
+	return cmd_ut_category("environment", "env_test_",
+			       tests, n_ents, argc, argv);
 }
diff --git a/test/lib/cmd_ut_lib.c b/test/lib/cmd_ut_lib.c
index eb90e53..c73e8d7 100644
--- a/test/lib/cmd_ut_lib.c
+++ b/test/lib/cmd_ut_lib.c
@@ -16,5 +16,5 @@
 	struct unit_test *tests = ll_entry_start(struct unit_test, lib_test);
 	const int n_ents = ll_entry_count(struct unit_test, lib_test);
 
-	return cmd_ut_category("lib", tests, n_ents, argc, argv);
+	return cmd_ut_category("lib", "lib_test_", tests, n_ents, argc, argv);
 }
diff --git a/test/optee/cmd_ut_optee.c b/test/optee/cmd_ut_optee.c
index 670682f..0927103 100644
--- a/test/optee/cmd_ut_optee.c
+++ b/test/optee/cmd_ut_optee.c
@@ -129,20 +129,20 @@
 	ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
 
 	expect_success = false;
-	ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
+	ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
 
 	/* (2) Try to copy optee nodes from prefilled dt */
 	ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
 
 	expect_success = true;
-	ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
+	ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
 
 	/* (3) Try to copy OP-TEE nodes into a already filled DT */
 	ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
 	ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
 
 	expect_success = true;
-	ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
+	ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
 
 	free(fdt);
 	return ret;
diff --git a/test/overlay/cmd_ut_overlay.c b/test/overlay/cmd_ut_overlay.c
index fc2491d..d0083fd6b 100644
--- a/test/overlay/cmd_ut_overlay.c
+++ b/test/overlay/cmd_ut_overlay.c
@@ -272,7 +272,7 @@
 	/* Apply the stacked overlay */
 	ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_stacked_copy));
 
-	ret = cmd_ut_category("overlay", tests, n_ents, argc, argv);
+	ret = cmd_ut_category("overlay", "", tests, n_ents, argc, argv);
 
 	free(fdt_overlay_stacked_copy);
 err3:
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 8875cdc..47532a6 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -585,5 +585,6 @@
 	struct unit_test *tests = ll_entry_start(struct unit_test, unicode_test);
 	const int n_ents = ll_entry_count(struct unit_test, unicode_test);
 
-	return cmd_ut_category("Unicode", tests, n_ents, argc, argv);
+	return cmd_ut_category("Unicode", "unicode_test_",
+			       tests, n_ents, argc, argv);
 }
diff --git a/tools/dumpimage.c b/tools/dumpimage.c
index ee3d41d..e548143 100644
--- a/tools/dumpimage.c
+++ b/tools/dumpimage.c
@@ -35,14 +35,23 @@
 	if (tparams->verify_header) {
 		retval = tparams->verify_header((unsigned char *)ptr,
 				sbuf->st_size, &params);
-		if (retval != 0)
+		if (retval != 0) {
+			fprintf(stderr, "%s: failed to verify header of %s\n",
+				params.cmdname, tparams->name);
 			return -1;
+		}
+
 		/*
 		 * Extract the file from the image
 		 * if verify is successful
 		 */
 		if (tparams->extract_subimage) {
 			retval = tparams->extract_subimage(ptr, &params);
+			if (retval != 0) {
+				fprintf(stderr, "%s: extract_subimage failed for %s\n",
+					params.cmdname, tparams->name);
+				return -3;
+			}
 		} else {
 			fprintf(stderr,
 				"%s: extract_subimage undefined for %s\n",
@@ -95,7 +104,6 @@
 			printf("dumpimage version %s\n", PLAIN_VERSION);
 			exit(EXIT_SUCCESS);
 		case 'h':
-			usage();
 		default:
 			usage();
 			break;
@@ -175,6 +183,9 @@
 		 * image type. Returns the error code if not matched
 		 */
 		retval = dumpimage_extract_subimage(tparams, ptr, &sbuf);
+		if (retval)
+			fprintf(stderr, "%s: Can't extract subimage from %s\n",
+				params.cmdname, params.imagefile);
 	} else {
 		/*
 		 * Print the image information for matched image type
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 0201cc4..114df5a 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -741,9 +741,14 @@
 {
 	const void *file_data;
 	size_t file_size = 0;
+	int ret;
 
-	/* get the "data" property of component at offset "image_noffset" */
-	fit_image_get_data(fit, image_noffset, &file_data, &file_size);
+	/* get the data address and size of component at offset "image_noffset" */
+	ret = fit_image_get_data_and_size(fit, image_noffset, &file_data, &file_size);
+	if (ret) {
+		fprintf(stderr, "Could not get component information\n");
+		return ret;
+	}
 
 	/* save the "file_data" into the file specified by "file_name" */
 	return imagetool_save_subimage(file_name, (ulong) file_data, file_size);