diff --git a/cmd/trace.c b/cmd/trace.c
index 1e62a1a1999e37bae3c3bdfc413185568eff4a25..1a6d8c304746214689a6edbb5891593e6a6c82a3 100644
--- a/cmd/trace.c
+++ b/cmd/trace.c
@@ -43,7 +43,7 @@ static int create_func_list(int argc, char * const argv[])
 	err = trace_list_functions(buff + buff_ptr, avail, &needed);
 	if (err)
 		printf("Error: truncated (%#x bytes needed)\n", needed);
-	used = min(avail, needed);
+	used = min(avail, (size_t)needed);
 	printf("Function trace dumped to %08lx, size %#zx\n",
 	       (ulong)map_to_sysmem(buff + buff_ptr), used);
 	setenv_hex("profbase", map_to_sysmem(buff));
@@ -67,7 +67,7 @@ static int create_call_list(int argc, char * const argv[])
 	err = trace_list_calls(buff + buff_ptr, avail, &needed);
 	if (err)
 		printf("Error: truncated (%#x bytes needed)\n", needed);
-	used = min(avail, needed);
+	used = min(avail, (size_t)needed);
 	printf("Call list dumped to %08lx, size %#zx\n",
 	       (ulong)map_to_sysmem(buff + buff_ptr), used);
 
diff --git a/common/board_f.c b/common/board_f.c
index a960144b02f362434fe5985f22e6b56da16e5a91..622093a3915af1326d30bc4de5022f19b1582961 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -45,6 +45,7 @@
 #include <post.h>
 #include <spi.h>
 #include <status_led.h>
+#include <timer.h>
 #include <trace.h>
 #include <video.h>
 #include <watchdog.h>
@@ -805,6 +806,11 @@ static int initf_dm(void)
 	if (ret)
 		return ret;
 #endif
+#ifdef CONFIG_TIMER_EARLY
+	ret = dm_timer_init();
+	if (ret)
+		return ret;
+#endif
 
 	return 0;
 }
diff --git a/common/board_r.c b/common/board_r.c
index 6c238652790c2d1aa839015a359e3f69e9a09c7b..52a9b262eb1ee415d21b0610da94612912ef7eb8 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -46,6 +46,7 @@
 #include <serial.h>
 #include <spi.h>
 #include <stdio_dev.h>
+#include <timer.h>
 #include <trace.h>
 #include <watchdog.h>
 #ifdef CONFIG_CMD_AMBAPP
@@ -312,13 +313,22 @@ static int initr_noncached(void)
 #ifdef CONFIG_DM
 static int initr_dm(void)
 {
+	int ret;
+
 	/* Save the pre-reloc driver model and start a new one */
 	gd->dm_root_f = gd->dm_root;
 	gd->dm_root = NULL;
-#ifdef CONFIG_TIMER
+	ret = dm_init_and_scan(false);
+	if (ret)
+		return ret;
+#ifdef CONFIG_TIMER_EARLY
 	gd->timer = NULL;
+	ret = dm_timer_init();
+	if (ret)
+		return ret;
 #endif
-	return dm_init_and_scan(false);
+
+	return 0;
 }
 #endif
 
diff --git a/common/bootm.c b/common/bootm.c
index 99d574db2c52523f94946a01e65ca63a36521d37..df27089965c927bc625ed49c6be1ee03477ff7e5 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -201,7 +201,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 		images.ep += images.os.load;
 	}
 
-	images.os.start = (ulong)os_hdr;
+	images.os.start = map_to_sysmem(os_hdr);
 
 	return 0;
 }
diff --git a/common/image-fit.c b/common/image-fit.c
index c531ee74d7fde55c5ac52edb3949fb824954e750..fbd9e0d770571148ad4f79483bace326e9b9dc6b 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -851,6 +851,11 @@ static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
 	return 0;
 }
 
+ulong fit_get_end(const void *fit)
+{
+	return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
+}
+
 /**
  * fit_set_timestamp - set node timestamp property
  * @fit: pointer to the FIT format image header
@@ -1030,10 +1035,15 @@ int fit_image_verify(const void *fit, int image_noffset)
 					strlen(FIT_SIG_NODENAME))) {
 			ret = fit_image_check_sig(fit, noffset, data,
 							size, -1, &err_msg);
-			if (ret) {
+
+			/*
+			 * Show an indication on failure, but do not return
+			 * an error. Only keys marked 'required' can cause
+			 * an image validation failure. See the call to
+			 * fit_image_verify_required_sigs() above.
+			 */
+			if (ret)
 				puts("- ");
-				goto error;
-			}
 			else
 				puts("+ ");
 		}
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index b5b81caaae8ec5cdceb49b4419694427db366b82..02534bfea76119f47a7b98467711f67ac25da1ef 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -1,10 +1,13 @@
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_PCI=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_DM_PCI_COMPAT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
@@ -12,14 +15,10 @@ CONFIG_CMD_REMOTEPROC=y
 CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_SOUND=y
-CONFIG_BOOTSTAGE=y
-CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_TPM=y
 CONFIG_CMD_TPM_TEST=y
-CONFIG_CONSOLE_RECORD=y
-CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_REGMAP=y
@@ -52,6 +51,7 @@ CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
 CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
 CONFIG_PCI_SANDBOX=y
 CONFIG_PINCTRL=y
 CONFIG_PINCONF=y
@@ -68,6 +68,7 @@ CONFIG_SOUND=y
 CONFIG_SOUND_SANDBOX=y
 CONFIG_SANDBOX_SPI=y
 CONFIG_TIMER=y
+CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
 CONFIG_USB=y
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 895604d7367e13479787c7ecf96cbb8abeaaa88d..53470b90ce87a96d6a7feabc9d92318da2a6c271 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -142,13 +142,15 @@ static int sandbox_sf_probe(struct udevice *dev)
 		if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS)
 			spec = state->spi[bus->seq][cs].spec;
 		if (!spec) {
+			debug("%s:  No spec found for bus %d, cs %d\n",
+			      __func__, bus->seq, cs);
 			ret = -ENOENT;
 			goto error;
 		}
 
 		file = strchr(spec, ':');
 		if (!file) {
-			printf("sandbox_sf: unable to parse file\n");
+			printf("%s: unable to parse file\n", __func__);
 			ret = -EINVAL;
 			goto error;
 		}
@@ -174,7 +176,7 @@ static int sandbox_sf_probe(struct udevice *dev)
 			break;
 	}
 	if (!data->name) {
-		printf("sandbox_sf: unknown flash '%*s'\n", (int)idname_len,
+		printf("%s: unknown flash '%*s'\n", __func__, (int)idname_len,
 		       spec);
 		ret = -EINVAL;
 		goto error;
@@ -185,8 +187,7 @@ static int sandbox_sf_probe(struct udevice *dev)
 
 	sbsf->fd = os_open(pdata->filename, 02);
 	if (sbsf->fd == -1) {
-		free(sbsf);
-		printf("sandbox_sf: unable to open file '%s'\n",
+		printf("%s: unable to open file '%s'\n", __func__,
 		       pdata->filename);
 		ret = -EIO;
 		goto error;
@@ -553,6 +554,9 @@ static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state,
 	 * yet. Perhaps we can figure something out.
 	 */
 	state->spi[bus][cs].spec = spec;
+	debug("%s:  Setting up spec '%s' for bus %ld, cs %ld\n", __func__,
+	      spec, bus, cs);
+
 	return 0;
 }
 SANDBOX_CMDLINE_OPT(spi_sf, 1, "connect a SPI flash: <bus>:<cs>:<id>:<file>");
@@ -671,6 +675,8 @@ int dm_scan_other(bool pre_reloc_only)
 					      __func__, busnum, cs);
 					return ret;
 				}
+				debug("%s:  Setting up spec '%s' for bus %d, cs %d\n",
+				      __func__, spec, busnum, cs);
 			}
 		}
 	}
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index daa1d5b249ea93c2f4b9c067b02f27543e8ddfae..7b296378d2be4fa20a274219a63ae93fee95eae4 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -42,10 +42,8 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
 	}
 
 	ret = spi_flash_scan(flash);
-	if (ret) {
-		ret = -EINVAL;
+	if (ret)
 		goto err_read_id;
-	}
 
 #ifdef CONFIG_SPI_FLASH_MTD
 	ret = spi_flash_mtd_register(flash);
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 3c365d5e9ad8f94b11fd96388dbf934c58e7f5a6..2ae2e3c8c9ad592713a4a5fd4c9448c343f98745 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -989,7 +989,7 @@ int spi_flash_scan(struct spi_flash *flash)
 	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
 	if (ret) {
 		printf("SF: Failed to get idcodes\n");
-		return -EINVAL;
+		return ret;
 	}
 
 #ifdef DEBUG
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 88bc416c61628fd2c44042dbd22dd79eb0480729..ee9a854bda48b89c6b3f99124ac15d6933f503f1 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -30,7 +30,7 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
 	u8 header_type;
 	int rom_addr;
 	pci_addr_t bar_value;
-	struct pci_region *bar_res;
+	struct pci_region *bar_res = NULL;
 	int found_mem64 = 0;
 	u16 class;
 
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index ff65a731def3a073ba24a451263c4f39a6cc49ff..cb18f12fc99b90ee779e09c5dc37a1cfb9e0b6e4 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -9,6 +9,16 @@ config TIMER
 	  will be used. The timer is usually a 32 bits free-running up
 	  counter. There may be no real tick, and no timer interrupt.
 
+config TIMER_EARLY
+	bool "Allow timer to be used early in U-Boot"
+	depends on TIMER
+	help
+	  In some cases the timer must be accessible before driver model is
+	  active. Examples include when using CONFIG_TRACE to trace U-Boot's
+	  execution before driver model is set up. Enable this option to
+	  use an early timer. These functions must be supported by your timer
+	  driver: timer_early_get_count() and timer_early_get_rate().
+
 config ALTERA_TIMER
 	bool "Altera timer support"
 	depends on TIMER
diff --git a/drivers/timer/sandbox_timer.c b/drivers/timer/sandbox_timer.c
index a8da936349498cb817b22d291dd8007e1feb474c..6a6411afeb39bce1630af3cafe2db190d4ae8a6c 100644
--- a/drivers/timer/sandbox_timer.c
+++ b/drivers/timer/sandbox_timer.c
@@ -10,6 +10,8 @@
 #include <timer.h>
 #include <os.h>
 
+#define SANDBOX_TIMER_RATE	1000000
+
 /* system timer offset in ms */
 static unsigned long sandbox_timer_offset;
 
@@ -18,9 +20,19 @@ void sandbox_timer_add_offset(unsigned long offset)
 	sandbox_timer_offset += offset;
 }
 
-static int sandbox_timer_get_count(struct udevice *dev, u64 *count)
+u64 notrace timer_early_get_count(void)
+{
+	return os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
+}
+
+unsigned long notrace timer_early_get_rate(void)
+{
+	return SANDBOX_TIMER_RATE;
+}
+
+static notrace int sandbox_timer_get_count(struct udevice *dev, u64 *count)
 {
-	*count = os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
+	*count = timer_early_get_count();
 
 	return 0;
 }
@@ -30,7 +42,7 @@ static int sandbox_timer_probe(struct udevice *dev)
 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	if (!uc_priv->clock_rate)
-		uc_priv->clock_rate = 1000000;
+		uc_priv->clock_rate = SANDBOX_TIMER_RATE;
 
 	return 0;
 }
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 83d1a35e0622afc325fcc250a91d5aec52c20eb9..382c0f2bd15dbb961a764a2be2c4f50256973ff8 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -22,7 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
  * tick, and no timer interrupt.
  */
 
-int timer_get_count(struct udevice *dev, u64 *count)
+int notrace timer_get_count(struct udevice *dev, u64 *count)
 {
 	const struct timer_ops *ops = device_get_ops(dev);
 
@@ -32,9 +32,9 @@ int timer_get_count(struct udevice *dev, u64 *count)
 	return ops->get_count(dev, count);
 }
 
-unsigned long timer_get_rate(struct udevice *dev)
+unsigned long notrace timer_get_rate(struct udevice *dev)
 {
-	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct timer_dev_priv *uc_priv = dev->uclass_priv;
 
 	return uc_priv->clock_rate;
 }
diff --git a/include/image.h b/include/image.h
index 299d6d2a13d23c51982b7caea45bdbc6a4f7664e..518a4f5291f929809a57526bbbeaa1200bd6f719 100644
--- a/include/image.h
+++ b/include/image.h
@@ -818,10 +818,7 @@ static inline ulong fit_get_size(const void *fit)
  * returns:
  *     end address of the FIT image (blob) in memory
  */
-static inline ulong fit_get_end(const void *fit)
-{
-	return (ulong)fit + fdt_totalsize(fit);
-}
+ulong fit_get_end(const void *fit);
 
 /**
  * fit_get_name - get FIT node name
diff --git a/include/timer.h b/include/timer.h
index f14725cc280b5f93a8074f329b5b4641fbb69753..dcc803c392a014ae589d6e7768fcf3b39e5d42fc 100644
--- a/include/timer.h
+++ b/include/timer.h
@@ -67,4 +67,25 @@ struct timer_dev_priv {
 	unsigned long clock_rate;
 };
 
+/**
+ * timer_early_get_count() - Implement timer_get_count() before driver model
+ *
+ * If CONFIG_TIMER_EARLY is enabled, this function wil be called to return
+ * the current timer value before the proper driver model timer is ready.
+ * It should be implemented by one of the timer values. This is mostly useful
+ * for tracing.
+ */
+u64 timer_early_get_count(void);
+
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ *
+ * If CONFIG_TIMER_EARLY is enabled, this function wil be called to return
+ * the current timer rate in Hz before the proper driver model timer is ready.
+ * It should be implemented by one of the timer values. This is mostly useful
+ * for tracing. This corresponds to the clock_rate value in struct
+ * timer_dev_priv.
+ */
+unsigned long timer_early_get_rate(void);
+
 #endif	/* _TIMER_H_ */
diff --git a/lib/div64.c b/lib/div64.c
index 795ef0e1e4671ac7a68a189839d48028353c1c29..319fca50fa79e2a61b2bbb1b48f3dbecb339647e 100644
--- a/lib/div64.c
+++ b/lib/div64.c
@@ -18,8 +18,9 @@
 
 #include <div64.h>
 #include <linux/types.h>
+#include <linux/compiler.h>
 
-uint32_t __div64_32(uint64_t *n, uint32_t base)
+uint32_t notrace __div64_32(uint64_t *n, uint32_t base)
 {
 	uint64_t rem = *n;
 	uint64_t b = base;
diff --git a/lib/time.c b/lib/time.c
index e9f6861b9843773f780ec3bd278340dcb55a2a2e..f37150fddc150db21c5b147bfe8b6fffccc08498 100644
--- a/lib/time.c
+++ b/lib/time.c
@@ -43,11 +43,17 @@ extern unsigned long __weak timer_read_counter(void);
 #ifdef CONFIG_TIMER
 ulong notrace get_tbclk(void)
 {
-	int ret;
+	if (!gd->timer) {
+#ifdef CONFIG_TIMER_EARLY
+		return timer_early_get_rate();
+#else
+		int ret;
 
-	ret = dm_timer_init();
-	if (ret)
-		return ret;
+		ret = dm_timer_init();
+		if (ret)
+			return ret;
+#endif
+	}
 
 	return timer_get_rate(gd->timer);
 }
@@ -57,9 +63,17 @@ uint64_t notrace get_ticks(void)
 	u64 count;
 	int ret;
 
-	ret = dm_timer_init();
-	if (ret)
-		return ret;
+	if (!gd->timer) {
+#ifdef CONFIG_TIMER_EARLY
+		return timer_early_get_count();
+#else
+		int ret;
+
+		ret = dm_timer_init();
+		if (ret)
+			return ret;
+#endif
+	}
 
 	ret = timer_get_count(gd->timer, &count);
 	if (ret)
diff --git a/test/dm/Makefile b/test/dm/Makefile
index d4f3f22e583f803ab819a012af64612d7a1f3472..fd0198f1bacd2f1fec31e927ea8f567a596881bf 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -27,8 +27,8 @@ obj-y += regmap.o
 obj-$(CONFIG_REMOTEPROC) += remoteproc.o
 obj-$(CONFIG_RESET) += reset.o
 obj-$(CONFIG_DM_RTC) += rtc.o
-#obj-$(CONFIG_DM_SPI_FLASH) += sf.o
-#obj-$(CONFIG_DM_SPI) += spi.o
+obj-$(CONFIG_DM_SPI_FLASH) += sf.o
+obj-$(CONFIG_DM_SPI) += spi.o
 obj-y += syscon.o
 obj-$(CONFIG_DM_USB) += usb.o
 obj-$(CONFIG_DM_PMIC) += pmic.o
diff --git a/test/image/test-fit.py b/test/image/test-fit.py
index d5143cbb0fd2aed4ce313494f762e81990f3e9aa..db0649fca8d0138103a4bfc7b26246138728ba92 100755
--- a/test/image/test-fit.py
+++ b/test/image/test-fit.py
@@ -108,6 +108,10 @@ base_fdt = '''
         model = "Sandbox Verified Boot Test";
         compatible = "sandbox";
 
+	reset@0 {
+		compatible = "sandbox,reset";
+	};
+
 };
 '''
 
diff --git a/test/trace/test-trace.sh b/test/trace/test-trace.sh
index 3e8651ed60151b4aeea5541cf834d2b2868c184d..746793c83bc38a3ddb68c24d8613fa921a340804 100755
--- a/test/trace/test-trace.sh
+++ b/test/trace/test-trace.sh
@@ -45,7 +45,9 @@ check_results() {
 	# between calls 2 and 3, where tracing is paused.
 	# This code gets the sign of the difference between each number and
 	# its predecessor.
-	counts="$(tr -d , <${tmp} | awk '/traced function calls/ { diff = $1 - upto; upto = $1; printf "%d ", diff < 0 ? -1 : (diff > 0 ? 1 : 0)}')"
+	counts="$(tr -d ',\r' <${tmp} | awk \
+		'/traced function calls/ { diff = $1 - upto; upto = $1; \
+		printf "%d ", diff < 0 ? -1 : (diff > 0 ? 1 : 0)}')"
 
 	if [ "${counts}" != "1 1 0 1 " ]; then
 		fail "trace collection error: ${counts}"
diff --git a/test/vboot/sandbox-u-boot.dts b/test/vboot/sandbox-u-boot.dts
index a1e853c9caaea4bf388727d5060b5b78619c1a4a..63f8f401de486a3598cee2d4477e852fd01d0a74 100644
--- a/test/vboot/sandbox-u-boot.dts
+++ b/test/vboot/sandbox-u-boot.dts
@@ -4,4 +4,7 @@
 	model = "Sandbox Verified Boot Test";
 	compatible = "sandbox";
 
+	reset@0 {
+		compatible = "sandbox,reset";
+	};
 };