Merge branch 'qcom-main' of https://source.denx.de/u-boot/custodians/u-boot-snapdragon

CI: https://source.denx.de/u-boot/custodians/u-boot-snapdragon/-/pipelines/23474

- UFS support is enabled for SC7280 and SM8150 platforms.
- Qualcomm dt-bindings headers are all dropped in favour of
  dts/upstream.
- The SMMU driver now correctly handles stream ID 0 and is disabled in
  EL2.
- Initial support for capsule updates (using the new dynamic UUIDs) is
  added for the RB3 Gen 2 board alongside a new SCSI backend for DFU.
- CONFIG_PINCONF is enabled in qcom_defconfig.
- The vqmmc supply is now enabled for sdcard support on boards that need
  it.
- A quirk is added for reading GPIOs on the PM8550 PMIC
diff --git a/.gitignore b/.gitignore
index 502a7e6..e93c33d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,6 +75,9 @@
 /keep-syms-lto.*
 /*imx8mimage*
 /*imx8mcst*
+/drivers/video/u_boot_logo.S
+/test/overlay/test-fdt-overlay.dtbo.S
+/test/overlay/test-fdt-overlay-stacked.dtbo.S
 
 #
 # Generated include files
@@ -83,6 +86,8 @@
 /include/config.h
 /include/config/
 /include/generated/
+/include/bmp_logo.h
+/include/bmp_logo_data.h
 
 # stgit generated dirs
 patches-*
diff --git a/Kconfig b/Kconfig
index eb55f25..1f5b0f1 100644
--- a/Kconfig
+++ b/Kconfig
@@ -765,10 +765,15 @@
 
 config NO_NET
 	bool "No networking support"
+	help
+	  Do not include networking support
 
 config NET
 	bool "Legacy U-Boot networking stack"
 	imply NETDEVICES
+	help
+	  Include networking support with U-Boot's internal implementation of
+	  the TCP/IP protocol stack.
 
 config NET_LWIP
 	bool "Use lwIP for networking stack"
diff --git a/MAINTAINERS b/MAINTAINERS
index 452ec44..8c6c0c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -860,6 +860,7 @@
 S:	Maintained
 T:	git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git
 F:	arch/arm/mach-zynqmp/
+F:	drivers/bootcount/bootcount_zynqmp.c
 F:	drivers/clk/clk_zynqmp.c
 F:	driver/firmware/firmware-zynqmp.c
 F:	drivers/fpga/zynqpl.c
@@ -1698,6 +1699,7 @@
 F:	cmd/tpm*
 F:	drivers/tpm/
 F:	include/tpm*
+F:	lib/tpm*
 
 TQ GROUP
 #M:	Martin Krause <martin.krause@tq-systems.de>
diff --git a/Makefile b/Makefile
index da742ce..2eaae42 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@
 ifeq ("", "$(CROSS_COMPILE)")
   MK_ARCH="${shell uname -m}"
 else
-  MK_ARCH="${shell echo $(CROSS_COMPILE) | sed -n 's/^[[:space:]]*\([^\/]*\/\)*\([^-]*\)-[^[:space:]]*/\2/p'}"
+  MK_ARCH="${shell echo $(CROSS_COMPILE) | sed -n 's/^\(ccache\)\?[[:space:]]*\([^\/]*\/\)*\([^-]*\)-[^[:space:]]*/\3/p'}"
 endif
 unexport HOST_ARCH
 ifeq ("x86_64", $(MK_ARCH))
diff --git a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
index 0961ca6..63f2eed 100644
--- a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
+++ b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi
@@ -301,6 +301,54 @@
 					description = "U-Boot for phyCORE-AM62x";
 				};
 
+				som-no-rtc {
+					description = "k3-am6xx-phycore-disable-rtc";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F000000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-disable-rtc.dtbo";
+					};
+				};
+
+				som-no-spi {
+					description = "k3-am6xx-phycore-disable-spi-nor";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F001000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-disable-spi-nor.dtbo";
+					};
+				};
+
+				som-no-eth {
+					description = "k3-am6xx-phycore-disable-eth-phy";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F002000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-disable-eth-phy.dtbo";
+					};
+				};
+
+				som-qspi {
+					description = "k3-am6xx-phycore-qspi-nor";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F003000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-qspi-nor.dtbo";
+					};
+				};
+
 				fdt-0 {
 					description = "k3-am625-phyboard-lyra-rdk";
 					type = "flat_dt";
@@ -325,7 +373,11 @@
 				conf-0 {
 					description = "k3-am625-phyboard-lyra-rdk";
 					firmware = "uboot";
-					loadables = "uboot";
+					loadables = "uboot",
+						    "som-no-rtc",
+						    "som-no-spi",
+						    "som-no-eth",
+						    "som-qspi";
 					fdt = "fdt-0";
 				};
 			};
diff --git a/arch/arm/dts/k3-am642-phycore-som-binman.dtsi b/arch/arm/dts/k3-am642-phycore-som-binman.dtsi
index dd09670..88d6c40 100644
--- a/arch/arm/dts/k3-am642-phycore-som-binman.dtsi
+++ b/arch/arm/dts/k3-am642-phycore-som-binman.dtsi
@@ -344,6 +344,54 @@
 					description = "U-Boot for AM64 board";
 				};
 
+				som-no-rtc {
+					description = "k3-am6xx-phycore-disable-rtc";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F000000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-disable-rtc.dtbo";
+					};
+				};
+
+				som-no-spi {
+					description = "k3-am6xx-phycore-disable-spi-nor";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F001000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-disable-spi-nor.dtbo";
+					};
+				};
+
+				som-no-eth {
+					description = "k3-am6xx-phycore-disable-eth-phy";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F002000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-disable-eth-phy.dtbo";
+					};
+				};
+
+				som-qspi {
+					description = "k3-am6xx-phycore-qspi-nor";
+					type = "flat_dt";
+					compression = "none";
+					load = <0x8F003000>;
+					arch = "arm";
+
+					blob-ext {
+						filename = "dts/upstream/src/arm64/ti/k3-am6xx-phycore-qspi-nor.dtbo";
+					};
+				};
+
 				fdt-0 {
 					description = "k3-am642-phyboard-electra-rdk";
 					type = "flat_dt";
@@ -368,7 +416,11 @@
 				conf-0 {
 					description = "k3-am642-phyboard-electra-rdk";
 					firmware = "uboot";
-					loadables = "uboot";
+					loadables = "uboot",
+						    "som-no-rtc",
+						    "som-no-spi",
+						    "som-no-eth",
+						    "som-qspi";
 					fdt = "fdt-0";
 				};
 			};
diff --git a/arch/arm/dts/zynqmp-sc-revB.dts b/arch/arm/dts/zynqmp-sc-revB.dts
index 1af3f64..c4f7058 100644
--- a/arch/arm/dts/zynqmp-sc-revB.dts
+++ b/arch/arm/dts/zynqmp-sc-revB.dts
@@ -3,7 +3,7 @@
  * dts file for Xilinx ZynqMP Generic System Controller
  *
  * (C) Copyright 2021 - 2022, Xilinx, Inc.
- * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc.
+ * (C) Copyright 2022 - 2024, Advanced Micro Devices, Inc.
  *
  * Michal Simek <michal.simek@amd.com>
  */
@@ -80,7 +80,7 @@
 	pwm-fan {
 		compatible = "pwm-fan";
 		status = "okay";
-		pwms = <&ttc0 2 40000 1>;
+		pwms = <&ttc0 2 40000 0>;
 	};
 };
 
diff --git a/arch/arm/dts/zynqmp-sm-k26-revA.dts b/arch/arm/dts/zynqmp-sm-k26-revA.dts
index 8056f6b..8c43ade 100644
--- a/arch/arm/dts/zynqmp-sm-k26-revA.dts
+++ b/arch/arm/dts/zynqmp-sm-k26-revA.dts
@@ -387,6 +387,7 @@
 
 &rtc {
 	status = "okay";
+	calibration = <0x7fff>;
 };
 
 &lpd_dma_chan1 {
diff --git a/arch/arm/mach-imx/fdt.c b/arch/arm/mach-imx/fdt.c
index ac782e3..103c1fc5 100644
--- a/arch/arm/mach-imx/fdt.c
+++ b/arch/arm/mach-imx/fdt.c
@@ -115,7 +115,7 @@
 
 		temp = 0;
 		if (!strcmp(type, "critical"))
-			temp = 1000 * (maxc - 5);
+			temp = 1000 * maxc;
 		else if (!strcmp(type, "passive"))
 			temp = 1000 * (maxc - 10);
 		if (temp) {
diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h
index 49e449e..3c372bd 100644
--- a/arch/arm/mach-zynqmp/include/mach/hardware.h
+++ b/arch/arm/mach-zynqmp/include/mach/hardware.h
@@ -188,6 +188,8 @@
 	u32 gen_storage4; /* 0x40 */
 	u32 reserved1[1];
 	u32 gen_storage6; /* 0x48 */
+	u32 reserved2[3];
+	u32 pers_gen_storage2; /* 0x58 */
 };
 
 #define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR)
diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c
index 6e6da80..448bc53 100644
--- a/arch/arm/mach-zynqmp/mp.c
+++ b/arch/arm/mach-zynqmp/mp.c
@@ -352,7 +352,7 @@
 		 */
 		flush_dcache_all();
 
-		if (!strncmp(argv[1], "lockstep", 8)) {
+		if (!strcmp(argv[1], "lockstep") || !strcmp(argv[1], "0")) {
 			if (nr != ZYNQMP_CORE_RPU0) {
 				printf("Lockstep mode should run on ZYNQMP_CORE_RPU0\n");
 				return 1;
@@ -369,7 +369,7 @@
 			dcache_enable();
 			set_r5_halt_mode(nr, RELEASE, LOCK);
 			mark_r5_used(nr, LOCK);
-		} else if (!strncmp(argv[1], "split", 5)) {
+		} else if (!strcmp(argv[1], "split") || !strcmp(argv[1], "1")) {
 			printf("R5 split mode\n");
 			set_r5_reset(nr, SPLIT);
 			set_r5_tcm_mode(SPLIT);
diff --git a/board/phytec/common/k3/board.c b/board/phytec/common/k3/board.c
index 3d7e090..346b2b6 100644
--- a/board/phytec/common/k3/board.c
+++ b/board/phytec/common/k3/board.c
@@ -6,7 +6,9 @@
 
 #include <env_internal.h>
 #include <fdt_support.h>
+#include <dm/ofnode.h>
 #include <spl.h>
+#include <malloc.h>
 #include <asm/arch/hardware.h>
 
 #include "../am6_som_detection.h"
@@ -97,8 +99,79 @@
 #endif
 
 #if IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_OF_BOARD_SETUP)
+static int fdt_apply_overlay_from_fit(const char *overlay_path, void *fdt)
+{
+	u64 loadaddr;
+	ofnode node;
+	int ret;
+
+	node = ofnode_path(overlay_path);
+	if (!ofnode_valid(node))
+		return -FDT_ERR_NOTFOUND;
+
+	ret = ofnode_read_u64(node, "load", &loadaddr);
+	if (ret)
+		return ret;
+
+	return fdt_overlay_apply_verbose(fdt, (void *)loadaddr);
+}
+
+static void fdt_apply_som_overlays(void *blob)
+{
+	void *fdt_copy;
+	u32 fdt_size;
+	struct phytec_eeprom_data data;
+	int err;
+
+	fdt_size = fdt_totalsize(blob);
+	fdt_copy = malloc(fdt_size);
+	if (!fdt_copy)
+		goto fixup_error;
+
+	memcpy(fdt_copy, blob, fdt_size);
+
+	err = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR);
+	if (err)
+		goto fixup_error;
+
+	if (phytec_get_am6_rtc(&data) == 0) {
+		err = fdt_apply_overlay_from_fit("/fit-images/som-no-rtc", fdt_copy);
+		if (err)
+			goto fixup_error;
+	}
+
+	if (phytec_get_am6_spi(&data) == PHYTEC_EEPROM_VALUE_X) {
+		err = fdt_apply_overlay_from_fit("/fit-images/som-no-spi", fdt_copy);
+		if (err)
+			goto fixup_error;
+	}
+
+	if (phytec_get_am6_eth(&data) == 0) {
+		err = fdt_apply_overlay_from_fit("/fit-images/som-no-eth", fdt_copy);
+		if (err)
+			goto fixup_error;
+	}
+
+	if (phytec_am6_is_qspi(&data)) {
+		err = fdt_apply_overlay_from_fit("/fit-images/som-qspi-nor", fdt_copy);
+		if (err)
+			goto fixup_error;
+	}
+
+	memcpy(blob, fdt_copy, fdt_size);
+
+cleanup:
+	free(fdt_copy);
+	return;
+
+fixup_error:
+	pr_err("Failed to apply SoM overlays\n");
+	goto cleanup;
+}
+
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
+	fdt_apply_som_overlays(blob);
 	fdt_copy_fixed_partitions(blob);
 
 	return 0;
diff --git a/board/xilinx/Kconfig b/board/xilinx/Kconfig
index 0ff8440..f7152d6 100644
--- a/board/xilinx/Kconfig
+++ b/board/xilinx/Kconfig
@@ -40,6 +40,15 @@
 
 endif
 
+config XILINX_MINI
+	bool "Mini configuration"
+	depends on ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
+	help
+	  This option disables features which are not needed for Mini U-Boot
+	  configurations. Mini U-Boot is running in EL3 mostly on size contrained
+	  systems. It's purpose is to program non volatile memories or running
+	  initial memory tests.
+
 config XILINX_OF_BOARD_DTB_ADDR
 	hex "Default DTB pickup address"
 	default 0x1000 if ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 38dd805..a12dccd 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -19,6 +19,7 @@
 #include <i2c.h>
 #include <linux/sizes.h>
 #include <malloc.h>
+#include <memtop.h>
 #include <mtd_node.h>
 #include "board.h"
 #include <dm.h>
@@ -676,3 +677,31 @@
 	return 0;
 }
 #endif
+
+#ifndef CONFIG_XILINX_MINI
+
+#ifndef MMU_SECTION_SIZE
+#define MMU_SECTION_SIZE        (1 * 1024 * 1024)
+#endif
+
+phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
+{
+	phys_size_t size;
+	phys_addr_t reg;
+
+	if (!total_size)
+		return gd->ram_top;
+
+	if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
+		panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
+
+	size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
+	reg = get_mem_top(gd->ram_base, gd->ram_size, size,
+			  (void *)gd->fdt_blob);
+	if (!reg)
+		reg = gd->ram_top - size;
+
+	return reg + size;
+}
+
+#endif
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 3947467..fd5c6ce 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -12,12 +12,15 @@
 #include <env_internal.h>
 #include <log.h>
 #include <malloc.h>
+#include <memalign.h>
+#include <mmc.h>
 #include <time.h>
 #include <asm/cache.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
+#include <linux/sizes.h>
 #include <dm/device.h>
 #include <dm/uclass.h>
 #include <versalpl.h>
@@ -301,9 +304,11 @@
 	return 0;
 }
 
+#if !CONFIG_IS_ENABLED(SYSRESET)
 void reset_cpu(void)
 {
 }
+#endif
 
 #if defined(CONFIG_ENV_IS_NOWHERE)
 enum env_location env_get_location(enum env_operation op, int prio)
@@ -336,3 +341,41 @@
 	}
 }
 #endif
+
+#if defined(CONFIG_SET_DFU_ALT_INFO)
+
+#define DFU_ALT_BUF_LEN		SZ_1K
+
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+	int bootseq = 0, len = 0;
+	u32 bootmode = versal_get_bootmode();
+
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
+
+	if (env_get("dfu_alt_info"))
+		return;
+
+	memset(buf, 0, sizeof(buf));
+
+	switch (bootmode) {
+	case EMMC_MODE:
+	case SD_MODE:
+	case SD1_LSHFT_MODE:
+	case SD_MODE1:
+		bootseq = mmc_get_env_dev();
+
+		len += snprintf(buf + len, DFU_ALT_BUF_LEN, "mmc %d=boot",
+			       bootseq);
+
+		len += snprintf(buf + len, DFU_ALT_BUF_LEN, ".bin fat %d 1",
+			       bootseq);
+		break;
+	default:
+		return;
+	}
+
+	env_set("dfu_alt_info", buf);
+	puts("DFU alt info setting: done\n");
+}
+#endif
diff --git a/board/xilinx/zynqmp/zynqmp_kria.env b/board/xilinx/zynqmp/zynqmp_kria.env
index 927f398..ff3a092 100644
--- a/board/xilinx/zynqmp/zynqmp_kria.env
+++ b/board/xilinx/zynqmp/zynqmp_kria.env
@@ -77,6 +77,7 @@
 tpm_kd240=if test ${card1_rev} = A; then run tpm_reset; fi
 
 board_setup=\
+rtc dev 0; \
 zynqmp mmio_write 0xFFCA0010 0xfff 0; \
 if test ${card1_name} = SCK-KV-G; then run kv260_setup; run tpm_kv260; fi;\
 if test ${card1_name} = SCK-KR-G; then run kr260_setup; run tpm_reset; fi;\
diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c
index be8fbf4..c6ae6df 100644
--- a/boot/bootmeth_extlinux.c
+++ b/boot/bootmeth_extlinux.c
@@ -8,6 +8,7 @@
 
 #define LOG_CATEGORY UCLASS_BOOTSTD
 
+#include <asm/cache.h>
 #include <bootdev.h>
 #include <bootflow.h>
 #include <bootmeth.h>
@@ -159,7 +160,7 @@
 		return log_msg_ret("try", ret);
 	size = bflow->size;
 
-	ret = bootmeth_alloc_file(bflow, 0x10000, 1);
+	ret = bootmeth_alloc_file(bflow, 0x10000, ARCH_DMA_MINALIGN);
 	if (ret)
 		return log_msg_ret("read", ret);
 
diff --git a/boot/image-board.c b/boot/image-board.c
index 1757e58..b726bd6 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -624,9 +624,10 @@
 	void *buf;
 	int conf_noffset;
 	int fit_img_result;
-	const char *uname, *name;
+	const char *uname, *name, *compatible;
 	int err;
 	int devnum = 0; /* TODO support multi fpga platforms */
+	int flags = 0;
 
 	if (!IS_ENABLED(CONFIG_FPGA))
 		return -ENOSYS;
@@ -674,20 +675,29 @@
 			return fit_img_result;
 		}
 
+		conf_noffset = fit_image_get_node(buf, uname);
+		compatible = fdt_getprop(buf, conf_noffset, "compatible", NULL);
+		if (!compatible) {
+			printf("'fpga' image without 'compatible' property\n");
+		} else {
+			if (CONFIG_IS_ENABLED(FPGA_LOAD_SECURE))
+				flags = fpga_compatible2flag(devnum, compatible);
+		}
+
 		if (!fpga_is_partial_data(devnum, img_len)) {
 			name = "full";
 			err = fpga_loadbitstream(devnum, (char *)img_data,
 						 img_len, BIT_FULL);
 			if (err)
 				err = fpga_load(devnum, (const void *)img_data,
-						img_len, BIT_FULL, 0);
+						img_len, BIT_FULL, flags);
 		} else {
 			name = "partial";
 			err = fpga_loadbitstream(devnum, (char *)img_data,
 						 img_len, BIT_PARTIAL);
 			if (err)
 				err = fpga_load(devnum, (const void *)img_data,
-						img_len, BIT_PARTIAL, 0);
+						img_len, BIT_PARTIAL, flags);
 		}
 
 		if (err)
diff --git a/boot/upl_read.c b/boot/upl_read.c
index 5063897..be3e1d1 100644
--- a/boot/upl_read.c
+++ b/boot/upl_read.c
@@ -520,7 +520,7 @@
 		return log_msg_ret("reg", -EINVAL);
 	}
 
-	len = decode_addr_size(upl, buf, sizeof(buf), &gra->reg);
+	len = decode_addr_size(upl, buf, size, &gra->reg);
 	if (len < 0)
 		return log_msg_ret("buf", len);
 
diff --git a/cmd/hash.c b/cmd/hash.c
index 60d482b..5b40982 100644
--- a/cmd/hash.c
+++ b/cmd/hash.c
@@ -25,7 +25,7 @@
 	char *s;
 	int flags = HASH_FLAG_ENV;
 
-	if (argc < (HARGS - 1))
+	if (argc < 4)
 		return CMD_RET_USAGE;
 
 #if IS_ENABLED(CONFIG_HASH_VERIFY)
diff --git a/cmd/net-common.c b/cmd/net-common.c
index 1c9fb83..1c6f11c 100644
--- a/cmd/net-common.c
+++ b/cmd/net-common.c
@@ -101,9 +101,6 @@
 	return cp->cmd(cmdtp, flag, argc, argv);
 }
 
-U_BOOT_CMD(
-	net, 3, 1, do_net,
-	"NET sub-system",
-	"list - list available devices\n"
-	"stats <device> - dump statistics for specified device\n"
-);
+U_BOOT_CMD(net, 3, 1, do_net, "NET sub-system",
+	   "list - list available devices\n"
+	   "stats <device> - dump statistics for specified device\n");
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c
index 42f8bd6..6f5fc74 100644
--- a/cmd/net-lwip.c
+++ b/cmd/net-lwip.c
@@ -5,41 +5,28 @@
 #include <net.h>
 
 #if defined(CONFIG_CMD_DHCP)
-U_BOOT_CMD(
-        dhcp,   3,      1,      do_dhcp,
-        "boot image via network using DHCP/TFTP protocol",
-        "[loadAddress] [[hostIPaddr:]bootfilename]"
-);
+U_BOOT_CMD(dhcp, 3, 1, do_dhcp,
+	   "boot image via network using DHCP/TFTP protocol",
+	   "[loadAddress] [[hostIPaddr:]bootfilename]");
 #endif
 
 #if defined(CONFIG_CMD_PING)
-U_BOOT_CMD(
-	ping,	2,	1,	do_ping,
-	"send ICMP ECHO_REQUEST to network host",
-	"pingAddress"
-);
+U_BOOT_CMD(ping, 2, 1, do_ping, "send ICMP ECHO_REQUEST to network host",
+	   "pingAddress");
 #endif
 
 #if defined(CONFIG_CMD_TFTPBOOT)
-U_BOOT_CMD(
-	tftpboot,	3,	0,	do_tftpb,
-	"boot image via network using TFTP protocol\n",
-	"[loadAddress] [[hostIPaddr:]bootfilename]"
-);
+U_BOOT_CMD(tftpboot, 3, 0, do_tftpb,
+	   "boot image via network using TFTP protocol\n",
+	   "[loadAddress] [[hostIPaddr:]bootfilename]");
 #endif
 
 #if defined(CONFIG_CMD_DNS)
-U_BOOT_CMD(
-	dns,	3,	1,	do_dns,
-	"lookup the IP of a hostname",
-	"hostname [envvar]"
-);
+U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname",
+	   "hostname [envvar]");
 #endif
 
 #if defined(CONFIG_CMD_WGET)
-U_BOOT_CMD(
-	wget,   3,      1,      do_wget,
-	"boot image via network using HTTP protocol",
-	"[loadAddress] URL"
-);
+U_BOOT_CMD(wget, 3, 1, do_wget, "boot image via network using HTTP protocol",
+	   "[loadAddress] URL");
 #endif
diff --git a/cmd/upl.c b/cmd/upl.c
index 4996f36..c9a823b 100644
--- a/cmd/upl.c
+++ b/cmd/upl.c
@@ -50,7 +50,7 @@
 			char *const argv[])
 {
 	struct upl s_upl, *upl = &s_upl;
-	struct unit_test_state uts;
+	struct unit_test_state uts = { 0 };
 	struct abuf buf;
 	oftree tree;
 	ulong addr;
diff --git a/common/Makefile b/common/Makefile
index 2ee5ef9..3599156 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -7,6 +7,7 @@
 ifndef CONFIG_XPL_BUILD
 obj-y += init/
 obj-y += main.o
+obj-y += memtop.o
 obj-y += exports.o
 obj-y += cli_getch.o cli_simple.o cli_readline.o
 obj-$(CONFIG_HUSH_OLD_PARSER) += cli_hush.o
diff --git a/common/memtop.c b/common/memtop.c
new file mode 100644
index 0000000..841d89e
--- /dev/null
+++ b/common/memtop.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#include <fdt_support.h>
+#include <fdtdec.h>
+#include <memtop.h>
+
+#include <asm/types.h>
+
+#define MEM_RGN_COUNT	16
+
+struct region {
+	phys_addr_t base;
+	phys_size_t size;
+};
+
+struct mem_region {
+	struct region rgn[MEM_RGN_COUNT];
+	uint count;
+};
+
+static void add_mem_region(struct mem_region *mem_rgn, phys_addr_t base,
+			   phys_size_t size)
+{
+	long i;
+
+	for (i = mem_rgn->count; i >= 0; i--) {
+		if (i && base < mem_rgn->rgn[i - 1].base) {
+			mem_rgn->rgn[i] = mem_rgn->rgn[i - 1];
+		} else {
+			mem_rgn->rgn[i].base = base;
+			mem_rgn->rgn[i].size = size;
+			break;
+		}
+	}
+
+	mem_rgn->count++;
+}
+
+static void mem_regions_init(struct mem_region *mem)
+{
+	uint i;
+
+	mem->count = 0;
+	for (i = 0; i < MEM_RGN_COUNT; i++) {
+		mem->rgn[i].base = 0;
+		mem->rgn[i].size = 0;
+	}
+}
+
+static int fdt_add_reserved_regions(struct mem_region *free_mem,
+				    struct mem_region *reserved_mem,
+				    void *fdt_blob)
+{
+	u64 addr, size;
+	int i, total, ret;
+	int nodeoffset, subnode;
+	struct fdt_resource res;
+
+	if (fdt_check_header(fdt_blob) != 0)
+		return -1;
+
+	/* process memreserve sections */
+	total = fdt_num_mem_rsv(fdt_blob);
+	assert_noisy(total < MEM_RGN_COUNT);
+	for (i = 0; i < total; i++) {
+		if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
+			continue;
+		add_mem_region(reserved_mem, addr, size);
+	}
+
+	i = 0;
+	/* process reserved-memory */
+	nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
+	if (nodeoffset >= 0) {
+		subnode = fdt_first_subnode(fdt_blob, nodeoffset);
+		while (subnode >= 0) {
+			/* check if this subnode has a reg property */
+			ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
+					       &res);
+			if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) {
+				addr = res.start;
+				size = res.end - res.start + 1;
+				assert_noisy(i < MEM_RGN_COUNT);
+				add_mem_region(reserved_mem, addr, size);
+			}
+
+			subnode = fdt_next_subnode(fdt_blob, subnode);
+			++i;
+		}
+	}
+
+	return 0;
+}
+
+static long addrs_overlap(phys_addr_t base1, phys_size_t size1,
+			  phys_addr_t base2, phys_size_t size2)
+{
+	const phys_addr_t base1_end = base1 + size1 - 1;
+	const phys_addr_t base2_end = base2 + size2 - 1;
+
+	return ((base1 <= base2_end) && (base2 <= base1_end));
+}
+
+static long region_overlap_check(struct mem_region *mem_rgn, phys_addr_t base,
+				 phys_size_t size)
+{
+	unsigned long i;
+	struct region *rgn = mem_rgn->rgn;
+
+	for (i = 0; i < mem_rgn->count; i++) {
+		phys_addr_t rgnbase = rgn[i].base;
+		phys_size_t rgnsize = rgn[i].size;
+
+		if (addrs_overlap(base, size, rgnbase, rgnsize))
+			break;
+	}
+
+	return (i < mem_rgn->count) ? i : -1;
+}
+
+static int find_ram_top(struct mem_region *free_mem,
+			struct mem_region *reserved_mem, phys_size_t size)
+{
+	long i, rgn;
+	phys_addr_t base = 0;
+	phys_addr_t res_base;
+
+	for (i = free_mem->count - 1; i >= 0; i--) {
+		phys_addr_t rgnbase = free_mem->rgn[i].base;
+		phys_size_t rgnsize = free_mem->rgn[i].size;
+
+		if (rgnsize < size)
+			continue;
+
+		base = rgnbase + rgnsize - size;
+		while (base && rgnbase <= base) {
+			rgn = region_overlap_check(reserved_mem, base, size);
+			if (rgn < 0)
+				return base;
+
+			res_base = reserved_mem->rgn[rgn].base;
+			if (res_base < size)
+				break;
+			base = res_base - size;
+		}
+	}
+
+	return 0;
+}
+
+phys_addr_t get_mem_top(phys_addr_t ram_start, phys_size_t ram_size,
+			phys_size_t size, void *fdt)
+{
+	int i;
+	struct mem_region free_mem;
+	struct mem_region reserved_mem;
+
+	mem_regions_init(&free_mem);
+	mem_regions_init(&reserved_mem);
+
+	add_mem_region(&free_mem, ram_start, ram_size);
+
+	i = fdt_add_reserved_regions(&free_mem, &reserved_mem, fdt);
+	if (i < 0)
+		return 0;
+
+	return find_ram_top(&free_mem, &reserved_mem, size);
+}
diff --git a/common/xyzModem.c b/common/xyzModem.c
index 09f74a1..698a538 100644
--- a/common/xyzModem.c
+++ b/common/xyzModem.c
@@ -280,6 +280,7 @@
 	    {
 	    case SOH:
 	      xyz.total_SOH++;
+	      fallthrough;
 	    case STX:
 	      if (c == STX)
 		xyz.total_STX++;
diff --git a/configs/amd_versal2_mini_defconfig b/configs/amd_versal2_mini_defconfig
index ea22541..4c902e4 100644
--- a/configs/amd_versal2_mini_defconfig
+++ b/configs/amd_versal2_mini_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SYS_LOAD_ADDR=0xBBF80000
 CONFIG_DEBUG_UART_BASE=0xf1920000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEBUG_UART=y
diff --git a/configs/amd_versal2_mini_emmc_defconfig b/configs/amd_versal2_mini_emmc_defconfig
index 6d4b261..da3eebe 100644
--- a/configs/amd_versal2_mini_emmc_defconfig
+++ b/configs/amd_versal2_mini_emmc_defconfig
@@ -12,6 +12,7 @@
 CONFIG_SYS_LOAD_ADDR=0x8000000
 CONFIG_DEBUG_UART_BASE=0xf1920000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_XILINX_MINI=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEBUG_UART=y
 # CONFIG_EXPERT is not set
diff --git a/configs/amd_versal2_mini_ospi_defconfig b/configs/amd_versal2_mini_ospi_defconfig
index 71bd667..d881cd4 100644
--- a/configs/amd_versal2_mini_ospi_defconfig
+++ b/configs/amd_versal2_mini_ospi_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SYS_LOAD_ADDR=0xBBF80000
 CONFIG_DEBUG_UART_BASE=0xf1920000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEBUG_UART=y
diff --git a/configs/amd_versal2_mini_qspi_defconfig b/configs/amd_versal2_mini_qspi_defconfig
index 3947604..eb63f06 100644
--- a/configs/amd_versal2_mini_qspi_defconfig
+++ b/configs/amd_versal2_mini_qspi_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SYS_LOAD_ADDR=0xBBF80000
 CONFIG_DEBUG_UART_BASE=0xf1920000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_DEBUG_UART=y
diff --git a/configs/kmcoge5ne_defconfig b/configs/kmcoge5ne_defconfig
index 211880b..6b2fc2e 100644
--- a/configs/kmcoge5ne_defconfig
+++ b/configs/kmcoge5ne_defconfig
@@ -152,7 +152,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot,nand0=app"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);app:-(ubi1);"
diff --git a/configs/kmeter1_defconfig b/configs/kmeter1_defconfig
index b69410b..55e87b0 100644
--- a/configs/kmeter1_defconfig
+++ b/configs/kmeter1_defconfig
@@ -131,7 +131,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
diff --git a/configs/kmopti2_defconfig b/configs/kmopti2_defconfig
index 28ad18e..df419b0 100644
--- a/configs/kmopti2_defconfig
+++ b/configs/kmopti2_defconfig
@@ -138,7 +138,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
diff --git a/configs/kmsupx5_defconfig b/configs/kmsupx5_defconfig
index 42ced44..1436860 100644
--- a/configs/kmsupx5_defconfig
+++ b/configs/kmsupx5_defconfig
@@ -123,7 +123,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
diff --git a/configs/kmtepr2_defconfig b/configs/kmtepr2_defconfig
index 3488e26..cce7a04 100644
--- a/configs/kmtepr2_defconfig
+++ b/configs/kmtepr2_defconfig
@@ -137,7 +137,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig
index a9d595c..2e618d8 100644
--- a/configs/microblaze-generic_defconfig
+++ b/configs/microblaze-generic_defconfig
@@ -47,7 +47,6 @@
 CONFIG_BOOTP_BOOTFILESIZE=y
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_CACHE=y
-CONFIG_CMD_JFFS2=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
diff --git a/configs/phycore_am62x_a53_defconfig b/configs/phycore_am62x_a53_defconfig
index eb4c2ce..0b0cf17 100644
--- a/configs/phycore_am62x_a53_defconfig
+++ b/configs/phycore_am62x_a53_defconfig
@@ -72,6 +72,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_MULTI_DTB_FIT=y
+CONFIG_OF_OVERLAY_LIST="ti/k3-am6xx-phycore-disable-spi-nor ti/k3-am6xx-phycore-disable-rtc ti/k3-am6xx-phycore-disable-eth-phy ti/k3-am6xx-phycore-qspi-nor"
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_ENV_OVERWRITE=y
diff --git a/configs/phycore_am64x_a53_defconfig b/configs/phycore_am64x_a53_defconfig
index b77e19b..ac9731d 100644
--- a/configs/phycore_am64x_a53_defconfig
+++ b/configs/phycore_am64x_a53_defconfig
@@ -10,6 +10,7 @@
 CONFIG_SOC_K3_AM642=y
 CONFIG_K3_ATF_LOAD_ADDR=0x701c0000
 CONFIG_TARGET_PHYCORE_AM64X_A53=y
+CONFIG_PHYTEC_SOM_DETECTION=y
 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
 CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000
 CONFIG_ENV_SIZE=0x20000
@@ -77,6 +78,7 @@
 CONFIG_CMD_SMC=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_OVERLAY_LIST="ti/k3-am6xx-phycore-disable-spi-nor ti/k3-am6xx-phycore-disable-rtc ti/k3-am6xx-phycore-disable-eth-phy ti/k3-am6xx-phycore-qspi-nor"
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
diff --git a/configs/tuge1_defconfig b/configs/tuge1_defconfig
index 10f6055..d1b7719 100644
--- a/configs/tuge1_defconfig
+++ b/configs/tuge1_defconfig
@@ -123,7 +123,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
diff --git a/configs/tuxx1_defconfig b/configs/tuxx1_defconfig
index 816ac8f..1dc737e 100644
--- a/configs/tuxx1_defconfig
+++ b/configs/tuxx1_defconfig
@@ -137,7 +137,6 @@
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
-CONFIG_CMD_JFFS2=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=boot"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=boot:768k(u-boot),128k(env),128k(envred),-(ubi0);"
diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig
index 7388a78..ac3815b 100644
--- a/configs/xilinx_versal_mini_defconfig
+++ b/configs/xilinx_versal_mini_defconfig
@@ -12,6 +12,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SYS_MEMTEST_START=0x00000000
diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig
index a36e40d..21f241e 100644
--- a/configs/xilinx_versal_mini_emmc0_defconfig
+++ b/configs/xilinx_versal_mini_emmc0_defconfig
@@ -12,6 +12,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-emmc0"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 # CONFIG_PSCI_RESET is not set
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig
index 3ae2115..6cb654c 100644
--- a/configs/xilinx_versal_mini_emmc1_defconfig
+++ b/configs/xilinx_versal_mini_emmc1_defconfig
@@ -12,6 +12,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-emmc1"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 # CONFIG_PSCI_RESET is not set
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig
index d0ea2b6..c2a5624 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -13,6 +13,7 @@
 # CONFIG_DM_GPIO is not set
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-ospi-single"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_VERSAL_NO_DDR=y
 # CONFIG_PSCI_RESET is not set
diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig
index ef6eec0..4d23b35 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -11,6 +11,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-mini-qspi-single"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_VERSAL_NO_DDR=y
 # CONFIG_PSCI_RESET is not set
diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig
index 1640dfa..e489f70 100644
--- a/configs/xilinx_versal_net_mini_defconfig
+++ b/configs/xilinx_versal_net_mini_defconfig
@@ -14,6 +14,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini"
 CONFIG_SYS_LOAD_ADDR=0xBBF00000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SYS_MEMTEST_START=0x00000000
diff --git a/configs/xilinx_versal_net_mini_emmc_defconfig b/configs/xilinx_versal_net_mini_emmc_defconfig
index 4c6159a..ab20156 100644
--- a/configs/xilinx_versal_net_mini_emmc_defconfig
+++ b/configs/xilinx_versal_net_mini_emmc_defconfig
@@ -10,6 +10,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini-emmc"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 # CONFIG_PSCI_RESET is not set
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig b/configs/xilinx_versal_net_mini_ospi_defconfig
index 071eeb8..f5864b5 100644
--- a/configs/xilinx_versal_net_mini_ospi_defconfig
+++ b/configs/xilinx_versal_net_mini_ospi_defconfig
@@ -13,6 +13,7 @@
 # CONFIG_DM_GPIO is not set
 CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini-ospi-single"
 CONFIG_SYS_LOAD_ADDR=0xBBF80000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_LTO=y
diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig b/configs/xilinx_versal_net_mini_qspi_defconfig
index 227c45d..8453be5 100644
--- a/configs/xilinx_versal_net_mini_qspi_defconfig
+++ b/configs/xilinx_versal_net_mini_qspi_defconfig
@@ -11,6 +11,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini-qspi-single"
 CONFIG_SYS_LOAD_ADDR=0xBBF80000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_LTO=y
diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig
index a9320de..30d79ab 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -133,6 +133,7 @@
 CONFIG_CADENCE_OSPI_VERSAL=y
 CONFIG_ZYNQ_SPI=y
 CONFIG_ZYNQMP_GQSPI=y
+CONFIG_SPI_STACKED_PARALLEL=y
 CONFIG_TPM2_TIS_SPI=y
 CONFIG_USB=y
 CONFIG_DM_USB_GADGET=y
diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig
index f220cc0..c8f166c 100644
--- a/configs/xilinx_versal_virt_defconfig
+++ b/configs/xilinx_versal_virt_defconfig
@@ -4,6 +4,7 @@
 CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
 CONFIG_ARCH_VERSAL=y
 CONFIG_TEXT_BASE=0x8000000
+CONFIG_SYS_MALLOC_LEN=0x4000000
 CONFIG_SYS_MALLOC_F_LEN=0x100000
 CONFIG_NR_DRAM_BANKS=36
 CONFIG_SF_DEFAULT_SPEED=30000000
@@ -18,6 +19,10 @@
 CONFIG_SYS_MEMTEST_START=0x00000000
 CONFIG_SYS_MEMTEST_END=0x00001000
 CONFIG_REMAKE_ELF=y
+CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
+CONFIG_EFI_CAPSULE_ON_DISK=y
+CONFIG_EFI_CAPSULE_ON_DISK_EARLY=y
+CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
 CONFIG_EFI_HTTP_BOOT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
@@ -76,6 +81,7 @@
 CONFIG_SIMPLE_PM_BUS=y
 CONFIG_CLK_VERSAL=y
 CONFIG_DFU_TIMEOUT=y
+CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1800000
 CONFIG_ARM_FFA_TRANSPORT=y
@@ -99,11 +105,14 @@
 CONFIG_ZYNQ_SDHCI_MIN_FREQ=100000
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SOFT_RESET=y
+CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_ISSI=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
@@ -136,6 +145,9 @@
 CONFIG_CADENCE_OSPI_VERSAL=y
 CONFIG_ZYNQ_SPI=y
 CONFIG_ZYNQMP_GQSPI=y
+CONFIG_SPI_STACKED_PARALLEL=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
 CONFIG_TPM2_TIS_SPI=y
 CONFIG_USB=y
 CONFIG_DM_USB_GADGET=y
diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig
index e00b386..ed3d101 100644
--- a/configs/xilinx_zynq_virt_defconfig
+++ b/configs/xilinx_zynq_virt_defconfig
@@ -146,6 +146,7 @@
 CONFIG_ZYNQ_SERIAL=y
 CONFIG_ZYNQ_SPI=y
 CONFIG_ZYNQ_QSPI=y
+CONFIG_SPI_STACKED_PARALLEL=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_ULPI_VIEWPORT=y
diff --git a/configs/xilinx_zynqmp_kria_defconfig b/configs/xilinx_zynqmp_kria_defconfig
index 5757a0c..e5ffc70 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -187,7 +187,6 @@
 CONFIG_PWM_CADENCE_TTC=y
 CONFIG_RESET_ZYNQMP=y
 CONFIG_DM_RTC=y
-CONFIG_RTC_EMULATION=y
 CONFIG_RTC_ZYNQMP=y
 CONFIG_SCSI=y
 CONFIG_ARM_DCC=y
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
index 7aab69c..b58cf8a 100644
--- a/configs/xilinx_zynqmp_mini_defconfig
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -9,6 +9,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_SYS_MEMTEST_START=0x00000000
 CONFIG_SYS_MEMTEST_END=0x00001000
diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig
index c56b1e8..f47880b 100644
--- a/configs/xilinx_zynqmp_mini_emmc0_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SPL_BSS_MAX_SIZE=0x80000
 CONFIG_SYS_LOAD_ADDR=0x8000000
 CONFIG_SPL=y
+CONFIG_XILINX_MINI=y
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig
index a8dbf00..fc0070a 100644
--- a/configs/xilinx_zynqmp_mini_emmc1_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SPL_BSS_MAX_SIZE=0x80000
 CONFIG_SYS_LOAD_ADDR=0x8000000
 CONFIG_SPL=y
+CONFIG_XILINX_MINI=y
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index ba8f02c..6a7541f 100644
--- a/configs/xilinx_zynqmp_mini_nand_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_defconfig
@@ -10,6 +10,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-nand"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig
index a8a0055..3643cae 100644
--- a/configs/xilinx_zynqmp_mini_nand_single_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig
@@ -10,6 +10,7 @@
 CONFIG_ENV_SIZE=0x80
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-nand"
 CONFIG_SYS_LOAD_ADDR=0x8000000
+CONFIG_XILINX_MINI=y
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 # CONFIG_EFI_LOADER is not set
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index c08b10c..a60403d 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SPL=y
 # CONFIG_SPL_FS_FAT is not set
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
+CONFIG_XILINX_MINI=y
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_ZYNQMP_NO_DDR=y
 # CONFIG_PSCI_RESET is not set
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig
index f3d83a2..310efdf 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -210,6 +210,7 @@
 CONFIG_SPI=y
 CONFIG_ZYNQ_SPI=y
 CONFIG_ZYNQMP_GQSPI=y
+CONFIG_SPI_STACKED_PARALLEL=y
 CONFIG_SYSRESET=y
 CONFIG_SYSRESET_CMD_POWEROFF=y
 CONFIG_SYSRESET_PSCI=y
diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
index fa6d8e7..0080d2a 100644
--- a/drivers/bootcount/Kconfig
+++ b/drivers/bootcount/Kconfig
@@ -164,6 +164,13 @@
 
 	  Accessing the backend is done using the regmap interface.
 
+config DM_BOOTCOUNT_ZYNQMP
+	bool "Support ZynqMP PMUFW as a backing store for bootcount"
+	depends on ARCH_ZYNQMP
+	help
+	  Enable support for the bootcount API by utilising the Persistent
+	  Global General Storage Register 2 of the PMU.
+
 endmenu
 
 endif
diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile
index 245f879..0cf79e4 100644
--- a/drivers/bootcount/Makefile
+++ b/drivers/bootcount/Makefile
@@ -16,3 +16,4 @@
 obj-$(CONFIG_DM_BOOTCOUNT_I2C)	+= bootcount_dm_i2c.o
 obj-$(CONFIG_DM_BOOTCOUNT_SPI_FLASH)	+= spi-flash.o
 obj-$(CONFIG_DM_BOOTCOUNT_SYSCON) += bootcount_syscon.o
+obj-$(CONFIG_DM_BOOTCOUNT_ZYNQMP)	+= bootcount_zynqmp.o
diff --git a/drivers/bootcount/bootcount_zynqmp.c b/drivers/bootcount/bootcount_zynqmp.c
new file mode 100644
index 0000000..bc0984e
--- /dev/null
+++ b/drivers/bootcount/bootcount_zynqmp.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+// SPDX-FileCopyrightText: 2024 CERN (home.cern)
+
+#include <bootcount.h>
+#include <dm.h>
+#include <stdio.h>
+#include <zynqmp_firmware.h>
+#include <asm/arch/hardware.h>
+#include <dm/platdata.h>
+
+static int bootcount_zynqmp_set(struct udevice *dev, const u32 val)
+{
+	int ret;
+
+	ret = zynqmp_mmio_write((ulong)&pmu_base->pers_gen_storage2, 0xFF, val);
+	if (ret)
+		pr_info("%s write fail\n", __func__);
+
+	return ret;
+}
+
+static int bootcount_zynqmp_get(struct udevice *dev, u32 *val)
+{
+	int ret;
+
+	*val = 0;
+	ret = zynqmp_mmio_read((ulong)&pmu_base->pers_gen_storage2, val);
+	if (ret)
+		pr_info("%s read fail\n", __func__);
+
+	return ret;
+}
+
+U_BOOT_DRVINFO(bootcount_zynqmp) = {
+	.name = "bootcount_zynqmp",
+};
+
+static const struct bootcount_ops bootcount_zynqmp_ops = {
+	.get = bootcount_zynqmp_get,
+	.set = bootcount_zynqmp_set,
+};
+
+U_BOOT_DRIVER(bootcount_zynqmp) = {
+	.name = "bootcount_zynqmp",
+	.id = UCLASS_BOOTCOUNT,
+	.ops = &bootcount_zynqmp_ops,
+};
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 9c466f8..331a46d 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -251,13 +251,6 @@
 
 	priv->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, priv->ref_clk_hz);
 
-	/* Versal and Versal-NET use spi calibration to set read delay */
-	if (CONFIG_IS_ENABLED(ARCH_VERSAL) ||
-	    CONFIG_IS_ENABLED(ARCH_VERSAL_NET) ||
-	    CONFIG_IS_ENABLED(ARCH_VERSAL2))
-		if (priv->read_delay >= 0)
-			priv->read_delay = -1;
-
 	/* Reset ospi flash device */
 	return cadence_qspi_versal_flash_reset(bus);
 }
diff --git a/examples/api/Makefile b/examples/api/Makefile
index ca4eb1f..ec1643e 100644
--- a/examples/api/Makefile
+++ b/examples/api/Makefile
@@ -9,8 +9,12 @@
 LOAD_ADDR = 0x40000
 endif
 ifeq ($(ARCH),arm)
+ifdef CONFIG_64BIT
+LOAD_ADDR = 0x40400000
+else
 LOAD_ADDR = 0x1000000
 endif
+endif
 ifeq ($(ARCH),mips)
 ifdef CONFIG_64BIT
 LOAD_ADDR = 0xffffffff80200000
diff --git a/examples/api/crt0.S b/examples/api/crt0.S
index 06f6d1f..f1b88ed 100644
--- a/examples/api/crt0.S
+++ b/examples/api/crt0.S
@@ -24,7 +24,7 @@
 	mtctr	%r11
 	bctr
 
-#elif defined(CONFIG_ARM)
+#elif defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
 
 	.text
 	.globl _start
@@ -33,27 +33,28 @@
 	str	sp, [ip]
 	b	main
 
-#elif defined(CONFIG_ARM64)
-
-              .text
-              .globl _start
-_start:
-              ldr           ip0, =search_hint
-              str           sp_el2, [ip0]
-              b             main
-
-
-              .globl syscall
-syscall:
-              ldr           ip0, =syscall_ptr
-              ldr           pc_el2, [ip0]
-
 
 	.globl syscall
 syscall:
 	ldr	ip, =syscall_ptr
 	ldr	pc, [ip]
 
+#elif defined(CONFIG_ARM64)
+
+	.text
+	.globl _start
+_start:
+	ldr	x17, =search_hint
+	mov	x16, sp
+	str	x16, [x17]
+	b	main
+
+	.globl syscall
+syscall:
+	ldr	x16, =syscall_ptr
+	ldr	x16, [x16]
+	br	x16
+
 #elif defined(CONFIG_MIPS)
 #include <asm/asm.h>
 	.text
@@ -83,6 +84,8 @@
 #error No support for this arch!
 #endif
 
+.section .data
+
 	.globl syscall_ptr
 syscall_ptr:
 	.align	8
@@ -90,4 +93,4 @@
 
 	.globl search_hint
 search_hint:
-	.long   0
+	.long	0
diff --git a/examples/api/demo.c b/examples/api/demo.c
index 677d13b..9a55f76 100644
--- a/examples/api/demo.c
+++ b/examples/api/demo.c
@@ -43,12 +43,11 @@
 	if (sig->version > API_SIG_VERSION)
 		return -3;
 
-	printf("API signature found @%x\n", (unsigned int)sig);
+	printf("API signature found @%p\n", sig);
 	test_dump_sig(sig);
 
 	printf("\n*** Consumer API test ***\n");
-	printf("syscall ptr 0x%08x@%08x\n", (unsigned int)syscall_ptr,
-		(unsigned int)&syscall_ptr);
+	printf("syscall ptr 0x%p@%p\n", syscall_ptr, &syscall_ptr);
 
 	/* console activities */
 	ub_putc('B');
@@ -203,7 +202,7 @@
 	printf("signature:\n");
 	printf("  version\t= %d\n", sig->version);
 	printf("  checksum\t= 0x%08x\n", sig->checksum);
-	printf("  sc entry\t= 0x%08x\n", (unsigned int)sig->syscall);
+	printf("  sc entry\t= 0x%p\n", sig->syscall);
 }
 
 void test_dump_si(struct sys_info *si)
@@ -296,7 +295,7 @@
 	struct device_info *di = ub_dev_get(handle);
 
 	printf("device info (%d):\n", handle);
-	printf("  cookie\t= 0x%08x\n", (uint32_t)di->cookie);
+	printf("  cookie\t= 0x%p\n", di->cookie);
 	printf("  type\t\t= 0x%08x\n", di->type);
 
 	if (di->type == DEV_TYP_NET) {
diff --git a/examples/api/glue.c b/examples/api/glue.c
index 0aaa82b..478f7b6 100644
--- a/examples/api/glue.c
+++ b/examples/api/glue.c
@@ -41,8 +41,8 @@
 int api_search_sig(struct api_signature **sig)
 {
 	unsigned char *sp;
-	uint32_t search_start = 0;
-	uint32_t search_end = 0;
+	uintptr_t search_start = 0;
+	uintptr_t search_end = 0;
 
 	if (sig == NULL)
 		return 0;
diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c
index 350cff0..f3087f6 100644
--- a/fs/btrfs/btrfs.c
+++ b/fs/btrfs/btrfs.c
@@ -193,7 +193,7 @@
 	ret = btrfs_lookup_path(fs_info->fs_root, BTRFS_FIRST_FREE_OBJECTID,
 				file, &root, &ino, &type, 40);
 	if (ret < 0) {
-		printf("Cannot lookup file %s\n", file);
+		debug("Cannot lookup file %s\n", file);
 		return ret;
 	}
 	if (type != BTRFS_FT_REG_FILE) {
diff --git a/fs/fs.c b/fs/fs.c
index 1afa0fb..21a23ef 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -23,6 +23,7 @@
 #include <time.h>
 #include <ubifs_uboot.h>
 #include <btrfs.h>
+#include <asm/cache.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <div64.h>
@@ -1001,6 +1002,9 @@
 	char *buf;
 	int ret;
 
+	if (!align)
+		align = ARCH_DMA_MINALIGN;
+
 	buf = memalign(align, size + 1);
 	if (!buf)
 		return log_msg_ret("buf", -ENOMEM);
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h
index 6740ab2..3bcc4c4 100644
--- a/include/configs/microblaze-generic.h
+++ b/include/configs/microblaze-generic.h
@@ -82,7 +82,7 @@
 	"nor0=flash-0\0"\
 	"mtdparts=mtdparts=flash-0:"\
 	"256k(u-boot),256k(env),3m(kernel),"\
-	"1m(romfs),1m(cramfs),-(jffs2)\0"\
+	"1m(romfs),1m(cramfs),-(fs)\0"\
 	"nc=setenv stdout nc;"\
 	"setenv stdin nc\0" \
 	"serial=setenv stdout serial;"\
diff --git a/include/fs.h b/include/fs.h
index 6372756..2474880 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -325,7 +325,7 @@
  *
  * @fname: Filename to read
  * @size: Size of file to read (must be correct!)
- * @align: Alignment to use for memory allocation (0 for default)
+ * @align: Alignment to use for memory allocation (0 for default: ARCH_DMA_MINALIGN)
  * @bufp: On success, returns the allocated buffer with the nul-terminated file
  *	in it
  * Return: 0 if OK, -ENOMEM if out of memory, -EIO if read failed
diff --git a/include/memtop.h b/include/memtop.h
new file mode 100644
index 0000000..28f62e2
--- /dev/null
+++ b/include/memtop.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+/**
+ * get_mem_top() - Compute the value of ram_top
+ * @ram_start:	Start of RAM
+ * @ram_size:	RAM size
+ * @size:	Minimum RAM size requested
+ * @fdt:	FDT blob
+ *
+ * The function computes the top address of RAM memory that can be
+ * used by U-Boot. This is being done by going through the list of
+ * reserved memory regions specified in the devicetree blob passed
+ * to the function. The logic used here is derived from the lmb
+ * allocation function.
+ *
+ * Return: address of ram top on success, 0 on failure
+ */
+phys_addr_t get_mem_top(phys_addr_t ram_start, phys_size_t ram_size,
+			phys_size_t size, void *fdt);
diff --git a/include/net-common.h b/include/net-common.h
index fd7c5e7..524ed4a 100644
--- a/include/net-common.h
+++ b/include/net-common.h
@@ -68,7 +68,7 @@
 	u16		udp_dst;	/* UDP destination port		*/
 	u16		udp_len;	/* Length of UDP packet		*/
 	u16		udp_xsum;	/* Checksum			*/
-} __attribute__((packed));
+} __packed;
 
 #define IP_UDP_HDR_SIZE		(sizeof(struct ip_udp_hdr))
 #define UDP_HDR_SIZE		(IP_UDP_HDR_SIZE - IP_HDR_SIZE)
@@ -84,13 +84,13 @@
  */
 #define ARP_HLEN_ASCII (ARP_HLEN * 2) + (ARP_HLEN - 1)
 
-#define ARP_HDR_SIZE	(8+20)		/* Size assuming ethernet	*/
+#define ARP_HDR_SIZE	(8 + 20)	/* Size assuming ethernet	*/
 
 #   define ARP_ETHER	    1		/* Ethernet  hardware address	*/
 
 /*
  * Maximum packet size; used to allocate packet storage. Use
- * the maxium Ethernet frame size as specified by the Ethernet
+ * the maximum Ethernet frame size as specified by the Ethernet
  * standard including the 802.1Q tag (VLAN tagging).
  * maximum packet size =  1522
  * maximum packet size and multiple of 32 bytes =  1536
@@ -129,7 +129,7 @@
  * @nbytes:	Number of bytes to check (normally a multiple of 2)
  * Return: 16-bit IP checksum
  */
-unsigned compute_ip_checksum(const void *addr, unsigned nbytes);
+unsigned compute_ip_checksum(const void *addr, unsigned int nbytes);
 
 /**
  * ip_checksum_ok() - check if a checksum is correct
@@ -140,7 +140,7 @@
  * @nbytes:	Number of bytes to check (normally a multiple of 2)
  * Return: true if the checksum matches, false if not
  */
-int ip_checksum_ok(const void *addr, unsigned nbytes);
+int ip_checksum_ok(const void *addr, unsigned int nbytes);
 
 /**
  * add_ip_checksums() - add two IP checksums
@@ -150,7 +150,7 @@
  * @new_sum:	New checksum to add
  * Return: updated 16-bit IP checksum
  */
-unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum);
+unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned int new_sum);
 
 /*
  * The devname can be either an exact name given by the driver or device tree
@@ -185,7 +185,7 @@
  * Return: 0 if OK, other value on error
  */
 int eth_env_set_enetaddr_by_index(const char *base_name, int index,
-				 uchar *enetaddr);
+				  uchar *enetaddr);
 
 /*
  * Initialize USB ethernet device with CONFIG_DM_ETH
@@ -231,7 +231,7 @@
 	if (DEBUG_NET_PKT_TRACE)
 		print_hex_dump_bytes("tx: ", DUMP_PREFIX_OFFSET, pkt, len);
 	/* Currently no way to return errors from eth_send() */
-	(void) eth_send(pkt, len);
+	(void)eth_send(pkt, len);
 }
 
 enum eth_recv_flags {
@@ -327,7 +327,7 @@
 	u8		et_dest[ARP_HLEN];	/* Destination node	*/
 	u8		et_src[ARP_HLEN];	/* Source node		*/
 	u16		et_protlen;		/* Protocol or length	*/
-} __attribute__((packed));
+} __packed;
 
 /* Ethernet header size */
 #define ETHER_HDR_SIZE	(sizeof(struct ethernet_hdr))
@@ -445,10 +445,10 @@
 int update_tftp(ulong addr, char *interface, char *devstring);
 
 /**
- * env_get_ip() - Convert an environment value to to an ip address
+ * env_get_ip() - Convert an environment value to an ip address
  *
  * @var: Environment variable to convert. The value of this variable must be
- *	in the format format a.b.c.d, where each value is a decimal number from
+ *	in the format a.b.c.d, where each value is a decimal number from
  *	0 to 255
  * Return: IP address, or 0 if invalid
  */
diff --git a/include/net-legacy.h b/include/net-legacy.h
index ca1efd1..1f62ebf 100644
--- a/include/net-legacy.h
+++ b/include/net-legacy.h
@@ -43,9 +43,9 @@
  * @param sport  source UDP port
  * @param len    packet length
  */
-typedef void rxhand_f(uchar *pkt, unsigned dport,
-		      struct in_addr sip, unsigned sport,
-		      unsigned len);
+typedef void rxhand_f(uchar *pkt, unsigned int dport,
+		      struct in_addr sip, unsigned int sport,
+		      unsigned int len);
 
 /**
  * An incoming ICMP packet handler.
@@ -57,8 +57,9 @@
  * @param pkt	pointer to the ICMP packet data
  * @param len	packet length
  */
-typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
-		struct in_addr sip, unsigned sport, uchar *pkt, unsigned len);
+typedef void rxhand_icmp_f(unsigned type, unsigned int code, unsigned int dport,
+			   struct in_addr sip, unsigned int sport, uchar *pkt,
+			   unsigned int len);
 
 /*
  *	A timeout handler.  Called after time interval has expired.
@@ -87,7 +88,7 @@
  * Return: 0 if OK, other value on error
  */
 int eth_env_set_enetaddr_by_index(const char *base_name, int index,
-				 uchar *enetaddr);
+				  uchar *enetaddr);
 
 /*
  * Get the hardware address for an ethernet interface .
@@ -99,7 +100,7 @@
  *	Return true if the address is valid.
  */
 int eth_env_get_enetaddr_by_index(const char *base_name, int index,
-				 uchar *enetaddr);
+				  uchar *enetaddr);
 
 int eth_send(void *packet, int length);	   /* Send a packet */
 
@@ -127,7 +128,7 @@
 	u8		et_snap2;
 	u8		et_snap3;
 	u16		et_prot;		/* 802 protocol		*/
-} __attribute__((packed));
+} __packed;
 
 /* 802 + SNAP + ethernet header size */
 #define E802_HDR_SIZE	(sizeof(struct e802_hdr))
@@ -141,7 +142,7 @@
 	u16		vet_vlan_type;		/* PROT_VLAN		*/
 	u16		vet_tag;		/* TAG of VLAN		*/
 	u16		vet_type;		/* protocol type	*/
-} __attribute__((packed));
+} __packed;
 
 /* VLAN Ethernet header size */
 #define VLAN_ETHER_HDR_SIZE	(sizeof(struct vlan_ethernet_hdr))
@@ -160,7 +161,7 @@
 	u16		ip_sum;		/* checksum			*/
 	struct in_addr	ip_src;		/* Source IP address		*/
 	struct in_addr	ip_dst;		/* Destination IP address	*/
-} __attribute__((packed));
+} __packed;
 
 #define IP_OFFS		0x1fff /* ip offset *= 8 */
 #define IP_FLAGS	0xe000 /* first 3 bits */
@@ -205,8 +206,7 @@
 	u8		ar_tha[];	/* Target hardware address	*/
 	u8		ar_tpa[];	/* Target protocol address	*/
 #endif /* 0 */
-} __attribute__((packed));
-
+} __packed;
 
 /*
  * ICMP stuff (just enough to handle (host) redirect messages)
@@ -239,14 +239,14 @@
 		} frag;
 		u8 data[0];
 	} un;
-} __attribute__((packed));
+} __packed;
 
 #define ICMP_HDR_SIZE		(sizeof(struct icmp_hdr))
 #define IP_ICMP_HDR_SIZE	(IP_HDR_SIZE + ICMP_HDR_SIZE)
 
 /*
  * Maximum packet size; used to allocate packet storage. Use
- * the maxium Ethernet frame size as specified by the Ethernet
+ * the maximum Ethernet frame size as specified by the Ethernet
  * standard including the 802.1Q tag (VLAN tagging).
  * maximum packet size =  1522
  * maximum packet size and multiple of 32 bytes =  1536
@@ -307,6 +307,7 @@
 	NETCONS, SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT_UDP, FASTBOOT_TCP,
 	WOL, UDP, NCSI, WGET, RS
 };
+
 /* Indicates whether the file name was specified on the command line */
 extern bool	net_boot_file_name_explicit;
 /* The actual transferred size of the bootfile (in bytes) */
@@ -360,16 +361,16 @@
 void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
 		       u16 pkt_len, u8 proto);
 void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
-				int sport, int len);
+			int sport, int len);
 
 /* Callbacks */
 rxhand_f *net_get_udp_handler(void);	/* Get UDP RX packet handler */
-void net_set_udp_handler(rxhand_f *);	/* Set UDP RX packet handler */
+void net_set_udp_handler(rxhand_f *f);	/* Set UDP RX packet handler */
 rxhand_f *net_get_arp_handler(void);	/* Get ARP RX packet handler */
-void net_set_arp_handler(rxhand_f *);	/* Set ARP RX packet handler */
+void net_set_arp_handler(rxhand_f *f);	/* Set ARP RX packet handler */
 bool arp_is_waiting(void);		/* Waiting for ARP reply? */
 void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
-void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */
+void net_set_timeout_handler(ulong t, thand_f *f);/* Set timeout handler */
 
 /* Network loop state */
 enum net_loop_state {
@@ -378,6 +379,7 @@
 	NETLOOP_SUCCESS,
 	NETLOOP_FAIL
 };
+
 extern enum net_loop_state net_state;
 
 static inline void net_set_state(enum net_loop_state state)
@@ -429,8 +431,8 @@
 
 #if defined(CONFIG_NETCONSOLE) && !defined(CONFIG_XPL_BUILD)
 void nc_start(void);
-int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port,
-	unsigned src_port, unsigned len);
+int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned int dest_port,
+		    unsigned int src_port, unsigned int len);
 #endif
 
 static __always_inline int eth_is_on_demand_init(void)
@@ -522,7 +524,7 @@
 ushort string_to_vlan(const char *s);
 
 /* read a VLAN id from an environment variable */
-ushort env_get_vlan(char *);
+ushort env_get_vlan(char *var);
 
 /* check if serverip is specified in filename from the command line */
 int is_serverip_in_cmd(void);
diff --git a/lib/lmb.c b/lib/lmb.c
index 74ffa9f..14b9b84 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -481,16 +481,22 @@
 
 static void lmb_print_region_flags(enum lmb_flags flags)
 {
-	u64 bitpos;
 	const char *flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" };
+	unsigned int pflags = flags &
+			      (LMB_NOMAP | LMB_NOOVERWRITE | LMB_NONOTIFY);
+
+	if (flags != pflags) {
+		printf("invalid %#x\n", flags);
+		return;
+	}
 
 	do {
-		bitpos = flags ? fls(flags) - 1 : 0;
-		assert_noisy(bitpos < ARRAY_SIZE(flag_str));
+		int bitpos = pflags ? fls(pflags) - 1 : 0;
+
 		printf("%s", flag_str[bitpos]);
-		flags &= ~(1ull << bitpos);
-		puts(flags ? ", " : "\n");
-	} while (flags);
+		pflags &= ~(1u << bitpos);
+		puts(pflags ? ", " : "\n");
+	} while (pflags);
 }
 
 static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name)
@@ -500,7 +506,7 @@
 	enum lmb_flags flags;
 	int i;
 
-	printf(" %s.count = 0x%x\n", name, lmb_rgn_lst->count);
+	printf(" %s.count = %#x\n", name, lmb_rgn_lst->count);
 
 	for (i = 0; i < lmb_rgn_lst->count; i++) {
 		base = rgn[i].base;
@@ -508,7 +514,7 @@
 		end = base + size - 1;
 		flags = rgn[i].flags;
 
-		printf(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: ",
+		printf(" %s[%d]\t[%#llx-%#llx], %#llx bytes, flags: ",
 		       name, i, base, end, size);
 		lmb_print_region_flags(flags);
 	}
diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h
index 563d3bf..de13884 100644
--- a/lib/lwip/u-boot/arch/cc.h
+++ b/lib/lwip/u-boot/arch/cc.h
@@ -29,8 +29,9 @@
 
 #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
 
-#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
-				    x, __LINE__, __FILE__); } while (0)
+#define LWIP_PLATFORM_ASSERT(x) do { \
+	printf("Assertion \"%s\" failed at line %d in %s\n", \
+	       x, __LINE__, __FILE__); } while (0)
 
 #define atoi(str) (int)dectoul(str, NULL)
 #define lwip_strnstr(a, b, c)  strstr(a, b)
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 2304030..fa9e143 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -428,6 +428,15 @@
 			ret = rsa_err("Signer padding setup failed");
 			goto err_sign;
 		}
+
+		/* Per RFC 3447 (and convention) the Typical salt length is the
+		 * length of the output of the digest algorithm.
+		 */
+		if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ckey,
+						     checksum_algo->checksum_len) <= 0) {
+			ret = rsa_err("Signer salt length setup failed");
+			goto err_sign;
+		}
 	}
 
 	for (i = 0; i < region_count; i++) {
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 59e6cba..ad2b5ab 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -821,7 +821,7 @@
 	if (*recv_size < 12)
 		return -ENODATA;
 	*recv_size -= 12;
-	memcpy(recvbuf, recvbuf + 12, *recv_size);
+	memmove(recvbuf, recvbuf + 12, *recv_size);
 
 	return 0;
 }
diff --git a/net/lwip/Kconfig b/net/lwip/Kconfig
index a9ae9bf..40345ce 100644
--- a/net/lwip/Kconfig
+++ b/net/lwip/Kconfig
@@ -6,9 +6,16 @@
 
 config LWIP_DEBUG
 	bool "Enable debug traces in the lwIP library"
+	help
+	  Prints messages to the console regarding network packets that go in
+          and out of the lwIP library.
 
 config LWIP_ASSERT
 	bool "Enable assertions in the lwIP library"
+	help
+	  Compiles additional error checking code into the lwIP library. These
+	  checks are related to conditions that should not happen in typical
+	  use, but may be helpful to debug new features.
 
 config PROT_DHCP_LWIP
 	bool
diff --git a/net/lwip/eth_internal.h b/net/lwip/eth_internal.h
index 0b829a8..87561d5 100644
--- a/net/lwip/eth_internal.h
+++ b/net/lwip/eth_internal.h
@@ -25,7 +25,7 @@
  * Return: 0 if OK, other value on error
  */
 int eth_env_set_enetaddr_by_index(const char *base_name, int index,
-				 uchar *enetaddr);
+				  uchar *enetaddr);
 
 int eth_mac_skip(int index);
 void eth_current_changed(void);
diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c
index 5c2bb2e..4702177 100644
--- a/net/lwip/net-lwip.c
+++ b/net/lwip/net-lwip.c
@@ -203,7 +203,6 @@
 
 struct netif *net_lwip_new_netif_noip(struct udevice *udev)
 {
-
 	return new_netif(udev, false);
 }
 
@@ -224,24 +223,24 @@
 
 static struct pbuf *alloc_pbuf_and_copy(uchar *data, int len)
 {
-        struct pbuf *p, *q;
+	struct pbuf *p, *q;
 
-        /* We allocate a pbuf chain of pbufs from the pool. */
-        p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
-        if (!p) {
-                LINK_STATS_INC(link.memerr);
-                LINK_STATS_INC(link.drop);
-                return NULL;
-        }
+	/* We allocate a pbuf chain of pbufs from the pool. */
+	p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+	if (!p) {
+		LINK_STATS_INC(link.memerr);
+		LINK_STATS_INC(link.drop);
+		return NULL;
+	}
 
-        for (q = p; q != NULL; q = q->next) {
-                memcpy(q->payload, data, q->len);
-                data += q->len;
-        }
+	for (q = p; q != NULL; q = q->next) {
+		memcpy(q->payload, data, q->len);
+		data += q->len;
+	}
 
-        LINK_STATS_INC(link.recv);
+	LINK_STATS_INC(link.recv);
 
-        return p;
+	return p;
 }
 
 int net_lwip_rx(struct udevice *udev, struct netif *netif)
diff --git a/net/lwip/ping.c b/net/lwip/ping.c
index 8dafa25..aa61753 100644
--- a/net/lwip/ping.c
+++ b/net/lwip/ping.c
@@ -39,8 +39,8 @@
 	    pbuf_remove_header(p, IP_HLEN) == 0) {
 		iecho = (struct icmp_echo_hdr *)p->payload;
 
-		if ((iecho->id == PING_ID) &&
-		    (iecho->seqno == lwip_htons(ctx->seq_num))) {
+		if (iecho->id == PING_ID &&
+		    iecho->seqno == lwip_htons(ctx->seq_num)) {
 			ctx->alive = true;
 			printf("host %s is alive\n", ipaddr_ntoa(addr));
 			pbuf_free(p);
@@ -93,7 +93,7 @@
 	if (!p)
 		return;
 
-	if ((p->len == p->tot_len) && !p->next) {
+	if (p->len == p->tot_len && !p->next) {
 		ctx->iecho = (struct icmp_echo_hdr *)p->payload;
 		ping_prepare_echo(ctx);
 		raw_sendto(ctx->pcb, p, &ctx->target);
@@ -113,7 +113,7 @@
 	}
 }
 
-static int ping_loop(struct udevice *udev, const ip_addr_t* addr)
+static int ping_loop(struct udevice *udev, const ip_addr_t *addr)
 {
 	struct ping_ctx ctx = {};
 	struct netif *netif;
diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c
index f4d0a6a..fc4aff5 100644
--- a/net/lwip/tftp.c
+++ b/net/lwip/tftp.c
@@ -71,7 +71,7 @@
 	struct tftp_ctx *ctx = handle;
 	struct pbuf *q;
 
-	for (q = p; q != NULL; q = q->next) {
+	for (q = p; q; q = q->next) {
 		memcpy((void *)ctx->daddr, q->payload, q->len);
 		ctx->daddr += q->len;
 		ctx->size += q->len;
@@ -130,7 +130,7 @@
 
 	printf("Using %s device\n", udev->name);
 	printf("TFTP from server %s; our IP address is %s\n",
-		 ip4addr_ntoa(&srvip), env_get("ipaddr"));
+	       ip4addr_ntoa(&srvip), env_get("ipaddr"));
 	printf("Filename '%s'.\n", fname);
 	printf("Load address: 0x%lx\n", ctx.daddr);
 	printf("Loading: ");
@@ -187,7 +187,7 @@
 	char *server_port = NULL;
 	char *end;
 	ip_addr_t srvip;
-	uint16_t port = TFTP_PORT;
+	u16 port = TFTP_PORT;
 	ulong laddr;
 	ulong addr;
 	int i;
@@ -228,7 +228,7 @@
 	if (arg) {
 		/* Parse [ip:[port:]]fname */
 		i = 0;
-		while ((*(words + i) = strsep(&arg,":")))
+		while ((*(words + i) = strsep(&arg, ":")))
 			i++;
 
 		switch (i) {
diff --git a/net/lwip/wget.c b/net/lwip/wget.c
index ba85798..e85d57b 100644
--- a/net/lwip/wget.c
+++ b/net/lwip/wget.c
@@ -15,15 +15,15 @@
 #include <time.h>
 #include <dm/uclass.h>
 
-#define SERVER_NAME_SIZE 200
+#define SERVER_NAME_SIZE 254
 #define HTTP_PORT_DEFAULT 80
 #define HTTPS_PORT_DEFAULT 443
 #define PROGRESS_PRINT_STEP_BYTES (100 * 1024)
 
 enum done_state {
-        NOT_DONE = 0,
-        SUCCESS = 1,
-        FAILURE = 2
+	NOT_DONE = 0,
+	SUCCESS = 1,
+	FAILURE = 2
 };
 
 struct wget_ctx {
@@ -163,7 +163,7 @@
 
 	if (rem < n)
 		return -1;
-	strncpy(p, server, n);
+	strlcpy(p, server, n);
 	p += n;
 	rem -= n;
 	if (rem < 1)
@@ -174,7 +174,7 @@
 	n = strlen(path);
 	if (rem < n)
 		return -1;
-	strncpy(p, path, n);
+	strlcpy(p, path, n);
 	p += n;
 	rem -= n;
 	if (rem < 1)
@@ -334,7 +334,7 @@
 		return CMD_RET_USAGE;
 
 	dst_addr = hextoul(argv[1], &end);
-        if (end == (argv[1] + strlen(argv[1]))) {
+	if (end == (argv[1] + strlen(argv[1]))) {
 		if (argc < 3)
 			return CMD_RET_USAGE;
 		url = argv[2];
@@ -344,7 +344,7 @@
 	}
 
 	if (parse_legacy_arg(url, nurl, sizeof(nurl)))
-	    return CMD_RET_FAILURE;
+		return CMD_RET_FAILURE;
 
 	if (wget_with_dns(dst_addr, nurl))
 		return CMD_RET_FAILURE;
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index 5e4a204..583e7c2 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_COREBOOT_SYSINFO) += coreboot.o
 obj-$(CONFIG_CMD_FDT) += fdt.o
 obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o
+obj-$(CONFIG_CMD_HASH) += hash.o
 obj-$(CONFIG_CMD_HISTORY) += history.o
 obj-$(CONFIG_CMD_LOADM) += loadm.o
 obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c
index 770b3bf..bb419ab 100644
--- a/test/cmd/bdinfo.c
+++ b/test/cmd/bdinfo.c
@@ -107,7 +107,7 @@
 	enum lmb_flags flags;
 	int i;
 
-	ut_assert_nextline(" %s.count = 0x%hx", name, lmb_rgn_lst->count);
+	ut_assert_nextline(" %s.count = %#x", name, lmb_rgn_lst->count);
 
 	for (i = 0; i < lmb_rgn_lst->count; i++) {
 		base = rgn[i].base;
@@ -119,7 +119,7 @@
 			ut_assert_nextlinen(" %s[%d]\t[", name, i);
 			continue;
 		}
-		ut_assert_nextlinen(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: ",
+		ut_assert_nextlinen(" %s[%d]\t[%#llx-%#llx], %#llx bytes, flags: ",
 				    name, i, base, end, size);
 	}
 
diff --git a/test/cmd/hash.c b/test/cmd/hash.c
new file mode 100644
index 0000000..296dd76
--- /dev/null
+++ b/test/cmd/hash.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Tests for hash command
+ *
+ * Copyright 2024, Heinrich Schuchardt <heinrich.schuchardt@canoncal.com>
+ */
+
+#include <command.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int dm_test_cmd_hash_md5(struct unit_test_state *uts)
+{
+	if (!CONFIG_IS_ENABLED(MD5)) {
+		ut_assert(run_command("hash md5 $loadaddr 0", 0));
+
+		return 0;
+	}
+
+	ut_assertok(run_command("hash md5 $loadaddr 0", 0));
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_asserteq_ptr(uts->actual_str,
+			strstr(uts->actual_str, "md5 for "));
+	ut_assert(strstr(uts->actual_str,
+			 "d41d8cd98f00b204e9800998ecf8427e"));
+	ut_assert_console_end();
+
+	ut_assertok(run_command("hash md5 $loadaddr 0 foo; echo $foo", 0));
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_asserteq_ptr(uts->actual_str,
+			strstr(uts->actual_str, "md5 for "));
+	ut_assert(strstr(uts->actual_str,
+			 "d41d8cd98f00b204e9800998ecf8427e"));
+	ut_assertok(ut_check_console_line(uts,
+					  "d41d8cd98f00b204e9800998ecf8427e"));
+
+	if (!CONFIG_IS_ENABLED(HASH_VERIFY)) {
+		ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+		ut_assertok(ut_check_console_line(
+				uts, "hash - compute hash message digest"));
+
+		return 0;
+	}
+
+	ut_assertok(run_command("hash -v md5 $loadaddr 0 foo", 0));
+	ut_assert_console_end();
+
+	env_set("foo", "ffffffffffffffffffffffffffffffff");
+	ut_assert(run_command("hash -v md5 $loadaddr 0 foo", 0));
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_assert(strstr(uts->actual_str, "!="));
+	ut_assert_console_end();
+
+	return 0;
+}
+DM_TEST(dm_test_cmd_hash_md5, UTF_CONSOLE);
+
+static int dm_test_cmd_hash_sha256(struct unit_test_state *uts)
+{
+	if (!CONFIG_IS_ENABLED(SHA256)) {
+		ut_assert(run_command("hash sha256 $loadaddr 0", 0));
+
+		return 0;
+	}
+
+	ut_assertok(run_command("hash sha256 $loadaddr 0", 0));
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_asserteq_ptr(uts->actual_str,
+			strstr(uts->actual_str, "sha256 for "));
+	ut_assert(strstr(uts->actual_str,
+			 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+	ut_assert_console_end();
+
+	ut_assertok(run_command("hash sha256 $loadaddr 0 foo; echo $foo", 0));
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_asserteq_ptr(uts->actual_str,
+			strstr(uts->actual_str, "sha256 for "));
+	ut_assert(strstr(uts->actual_str,
+			 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+	ut_assertok(ut_check_console_line(
+			uts, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+
+	if (!CONFIG_IS_ENABLED(HASH_VERIFY)) {
+		ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+		ut_assertok(ut_check_console_line(
+				uts, "hash - compute hash message digest"));
+
+		return 0;
+	}
+
+	ut_assertok(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+	ut_assert_console_end();
+
+	env_set("foo", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+	ut_assert(run_command("hash -v sha256 $loadaddr 0 foo", 0));
+	console_record_readline(uts->actual_str, sizeof(uts->actual_str));
+	ut_assert(strstr(uts->actual_str, "!="));
+	ut_assert_console_end();
+
+	return 0;
+}
+DM_TEST(dm_test_cmd_hash_sha256, UTF_CONSOLE);
diff --git a/test/cmd/mbr.c b/test/cmd/mbr.c
index b14137e..d137378 100644
--- a/test/cmd/mbr.c
+++ b/test/cmd/mbr.c
@@ -257,8 +257,8 @@
 		strlen(mbr_parts_p3) +
 		max(strlen(mbr_parts_p4), strlen(mbr_parts_p5)) +
 		strlen(mbr_parts_tail);
-	ut_assertf(sizeof(mbr_parts_buf) >= mbr_parts_max, "Buffer avail: %ld; buffer req: %ld\n",
-		sizeof(mbr_parts_buf), mbr_parts_max);
+	ut_assertf(sizeof(mbr_parts_buf) >= mbr_parts_max, "Buffer avail: %zd; buffer req: %ld\n",
+		   sizeof(mbr_parts_buf), mbr_parts_max);
 
 	mbr_wbuf = map_sysmem(mbr_wa, BLKSZ);
 	ebr_wbuf = map_sysmem(ebr_wa, BLKSZ);
@@ -277,7 +277,7 @@
 				 (ulong)0xbffe00 / BLKSZ));
 
 	/* Test one MBR partition */
-	init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
+	init_write_buffers(mbr_wbuf, BLKSZ, ebr_wbuf, BLKSZ, __LINE__);
 	ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 1));
 	ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
 	memset(rbuf, '\0', BLKSZ);
diff --git a/test/common/print.c b/test/common/print.c
index f1eb907..464e425 100644
--- a/test/common/print.c
+++ b/test/common/print.c
@@ -115,8 +115,10 @@
 	snprintf(str, 0, "testing none");
 	ut_asserteq('x', *str);
 
-	sprintf(big_str, "_%ls_", u"foo");
-	ut_assertok(strcmp("_foo_", big_str));
+	if (CONFIG_IS_ENABLED(EFI_LOADER) || IS_ENABLED(CONFIG_EFI_APP)) {
+		sprintf(big_str, "_%ls_", u"foo");
+		ut_assertok(strcmp("_foo_", big_str));
+	}
 
 	/* Test the banner function */
 	s = display_options_get_banner(true, str, sizeof(str));
diff --git a/test/py/tests/test_spi.py b/test/py/tests/test_spi.py
index 44e5473..0abdfa7 100644
--- a/test/py/tests/test_spi.py
+++ b/test/py/tests/test_spi.py
@@ -75,7 +75,7 @@
     ''' Get SPI device test parameters from boardenv file '''
     f = u_boot_console.config.env.get('env__spi_device_test', None)
     if not f:
-        pytest.skip('No env file to read for SPI family device test')
+        pytest.skip('No SPI test device configured')
 
     bus = f.get('bus', 0)
     cs = f.get('chip_select', 0)
@@ -84,7 +84,7 @@
     timeout = f.get('timeout', None)
 
     if not part_name:
-        pytest.skip('No env file to read SPI family flash part name')
+        pytest.skip('No SPI test device configured')
 
     return bus, cs, mode, part_name, timeout
 
@@ -92,7 +92,7 @@
     '''Find out minimum and maximum frequnecies that SPI device can operate'''
     f = u_boot_console.config.env.get('env__spi_device_test', None)
     if not f:
-        pytest.skip('No env file to read for SPI family device test')
+        pytest.skip('No SPI test device configured')
 
     min_f = f.get('min_freq', None)
     max_f = f.get('max_freq', None)
@@ -116,21 +116,21 @@
         pytest.fail('No SPI device available')
 
     if not part_name in output:
-        pytest.fail('SPI flash part name not recognized')
+        pytest.fail('Not recognized the SPI flash part name')
 
     m = re.search('page size (.+?) Bytes', output)
     if m:
         try:
             page_size = int(m.group(1))
         except ValueError:
-            pytest.fail('SPI page size not recognized')
+            pytest.fail('Not recognized the SPI page size')
 
     m = re.search('erase size (.+?) KiB', output)
     if m:
         try:
             erase_size = int(m.group(1))
         except ValueError:
-            pytest.fail('SPI erase size not recognized')
+            pytest.fail('Not recognized the SPI erase size')
 
         erase_size *= 1024
 
@@ -139,7 +139,7 @@
         try:
             total_size = int(m.group(1))
         except ValueError:
-            pytest.fail('SPI total size not recognized')
+            pytest.fail('Not recognized the SPI total size')
 
         total_size *= 1024 * 1024
 
@@ -149,7 +149,7 @@
             flash_part = m.group(1)
             assert flash_part == part_name
         except ValueError:
-            pytest.fail('SPI flash part not recognized')
+            pytest.fail('Not recognized the SPI flash part')
 
     global SPI_DATA
     SPI_DATA = {
@@ -574,7 +574,7 @@
     min_f, max_f, loop = spi_find_freq_range(u_boot_console)
     flashes = u_boot_console.config.env.get('env__spi_lock_unlock', False)
     if not flashes:
-        pytest.skip('No supported flash list for lock/unlock provided')
+        pytest.skip('No SPI test device configured for lock/unlock')
 
     i = 0
     while i < loop:
diff --git a/tools/imx8image.c b/tools/imx8image.c
index 96ece28..7a06081 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -93,6 +93,7 @@
 	case CMD_DCD_SKIP:
 		if (!strncmp("true", token, 4))
 			dcd_skip = true;
+		break;
 	case CMD_FUSE_VERSION:
 		fuse_version = (uint8_t)(strtoll(token, NULL, 0) & 0xFF);
 		break;