Merge branch '2023-12-20-assorted-general-updates' into next

- Assorted fixes around the tree
diff --git a/boot/bootm.c b/boot/bootm.c
index 301cfde..4cf66cc 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -1103,7 +1103,11 @@
 	if (!ret && (states & BOOTM_STATE_OS_BD_T))
 		ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
 	if (!ret && (states & BOOTM_STATE_OS_PREP)) {
-		ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX);
+		int flags = 0;
+		/* For Linux OS do all substitutions at console processing */
+		if (images->os.os == IH_OS_LINUX)
+			flags = BOOTM_CL_ALL;
+		ret = bootm_process_cmdline_env(flags);
 		if (ret) {
 			printf("Cmdline setup failed (err=%d)\n", ret);
 			ret = CMD_RET_FAILURE;
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index a92bb89..83bc167 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -700,6 +700,11 @@
 					       label->name);
 					goto cleanup;
 				}
+
+				if (label->fdtdir) {
+					printf("Skipping fdtdir %s for failure retrieving dts\n",
+						label->fdtdir);
+				}
 			}
 
 			if (label->kaslrseed)
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 24bfbe5..5a7678f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -495,6 +495,16 @@
 	help
 	  Extract a part of a multi-image.
 
+config SYS_XIMG_LEN
+	hex "imxtract max gunzip size"
+	default 0x800000
+	depends on CMD_XIMG && GZIP
+	help
+	  This provides the size of the commad-line argument area
+	  used by imxtract for extracting pieces of FIT image.
+	  It should be large enough to fit uncompressed size of
+	  FIT piece we are extracting.
+
 config CMD_SPL
 	bool "spl export - Export boot information for Falcon boot"
 	depends on SPL
diff --git a/cmd/armflash.c b/cmd/armflash.c
index d1466f7..fdaea5a 100644
--- a/cmd/armflash.c
+++ b/cmd/armflash.c
@@ -180,6 +180,7 @@
 {
 	struct afs_image *afi = NULL;
 	int i;
+	loff_t len_read = 0;
 
 	parse_flash();
 	for (i = 0; i < num_afs_images; i++) {
@@ -197,6 +198,7 @@
 
 	for (i = 0; i < afi->region_count; i++) {
 		ulong from, to;
+		u32 size;
 
 		from = afi->flash_mem_start + afi->regions[i].offset;
 		if (address) {
@@ -208,14 +210,20 @@
 			return CMD_RET_FAILURE;
 		}
 
-		memcpy((void *)to, (void *)from, afi->regions[i].size);
+		size = afi->regions[i].size;
+		memcpy((void *)to, (void *)from, size);
 
 		printf("loaded region %d from %08lX to %08lX, %08X bytes\n",
 		       i,
 		       from,
 		       to,
-		       afi->regions[i].size);
+		       size);
+
+		len_read += size;
 	}
+
+	env_set_hex("filesize", len_read);
+
 	return CMD_RET_SUCCESS;
 }
 
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 4a47265..cc6dfae 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -543,9 +543,9 @@
 	op = argv[1];
 	arg = argv[2];
 	if (*op == 's') {
-		if (argc < 4)
+		if (argc < 3)
 			return CMD_RET_USAGE;
-		val = argv[3];
+		val = argv[3] ?: (const char *)BOOTFLOWCL_EMPTY;
 	}
 
 	switch (*op) {
diff --git a/cmd/part.c b/cmd/part.c
index 0ce1900..c75f85a 100644
--- a/cmd/part.c
+++ b/cmd/part.c
@@ -308,9 +308,9 @@
 #ifdef CONFIG_PARTITION_TYPE_GUID
 	"part type <interface> <dev>:<part>\n"
 	"    - print partition type\n"
-#endif
 	"part type <interface> <dev>:<part> <varname>\n"
 	"    - set environment variable to partition type\n"
+#endif
 	"part set <interface> <dev> type\n"
 	"    - set partition type for a device\n"
 	"part types\n"
diff --git a/cmd/ximg.c b/cmd/ximg.c
index a50dd20..0e7eead 100644
--- a/cmd/ximg.c
+++ b/cmd/ximg.c
@@ -27,11 +27,6 @@
 #include <asm/cache.h>
 #include <asm/io.h>
 
-#ifndef CFG_SYS_XIMG_LEN
-/* use 8MByte as default max gunzip size */
-#define CFG_SYS_XIMG_LEN	0x800000
-#endif
-
 static int
 do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
@@ -52,7 +47,7 @@
 	size_t		fit_len;
 #endif
 #ifdef CONFIG_GZIP
-	uint		unc_len = CFG_SYS_XIMG_LEN;
+	uint		unc_len = CONFIG_SYS_XIMG_LEN;
 #endif
 	uint8_t		comp;
 
diff --git a/common/cli_readline.c b/common/cli_readline.c
index 06b8d46..85453be 100644
--- a/common/cli_readline.c
+++ b/common/cli_readline.c
@@ -12,6 +12,8 @@
 #include <bootretry.h>
 #include <cli.h>
 #include <command.h>
+#include <hang.h>
+#include <malloc.h>
 #include <time.h>
 #include <watchdog.h>
 #include <asm/global_data.h>
@@ -85,7 +87,6 @@
 static unsigned hist_num;
 
 static char *hist_list[HIST_MAX];
-static char hist_lines[HIST_MAX][HIST_SIZE + 1];	/* Save room for NULL */
 
 #define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)
 
@@ -97,8 +98,9 @@
 		getcmd_putch(ch);
 }
 
-static void hist_init(void)
+static int hist_init(void)
 {
+	unsigned char *hist;
 	int i;
 
 	hist_max = 0;
@@ -106,10 +108,14 @@
 	hist_cur = -1;
 	hist_num = 0;
 
-	for (i = 0; i < HIST_MAX; i++) {
-		hist_list[i] = hist_lines[i];
-		hist_list[i][0] = '\0';
-	}
+	hist = calloc(HIST_MAX, HIST_SIZE + 1);
+	if (!hist)
+		return -ENOMEM;
+
+	for (i = 0; i < HIST_MAX; i++)
+		hist_list[i] = hist + (i * (HIST_SIZE + 1));
+
+	return 0;
 }
 
 static void cread_add_to_hist(char *line)
@@ -493,8 +499,9 @@
 
 #else /* !CONFIG_CMDLINE_EDITING */
 
-static inline void hist_init(void)
+static inline int hist_init(void)
 {
+	return 0;
 }
 
 static int cread_line(const char *const prompt, char *buf, unsigned int *len,
@@ -643,8 +650,9 @@
 	 */
 	if (IS_ENABLED(CONFIG_CMDLINE_EDITING) && (gd->flags & GD_FLG_RELOC)) {
 		if (!initted) {
-			hist_init();
-			initted = 1;
+			rc = hist_init();
+			if (rc == 0)
+				initted = 1;
 		}
 
 		if (prompt)
diff --git a/common/command.c b/common/command.c
index 846e16e..7821c27 100644
--- a/common/command.c
+++ b/common/command.c
@@ -355,10 +355,9 @@
 	return len;
 }
 
-static char tmp_buf[CONFIG_SYS_CBSIZE + 1];	/* copy of console I/O buffer */
-
 int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
 {
+	char tmp_buf[CONFIG_SYS_CBSIZE + 1];	/* copy of console I/O buffer */
 	int n = *np, col = *colp;
 	char *argv[CONFIG_SYS_MAXARGS + 1];		/* NULL terminated	*/
 	char *cmdv[20];
diff --git a/doc/usage/fit/signature.rst b/doc/usage/fit/signature.rst
index 39edba1..03a71b5 100644
--- a/doc/usage/fit/signature.rst
+++ b/doc/usage/fit/signature.rst
@@ -671,7 +671,7 @@
 Sign the fitImage with the hardware key::
 
     $ ./tools/mkimage -F -k \
-    "model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29" \
+    "pkcs11:model=PKCS%2315%20emulated;manufacturer=ZeitControl;serial=000xxxxxxxxx;token=OpenPGP%20card%20%28User%20PIN%20%28sig%29%29" \
     -K u-boot.dtb -N pkcs11 -r fitImage
 
 
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index d20bdb5..7ae163f 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -116,15 +116,15 @@
 		if (keydir)
 			if (strstr(keydir, "object="))
 				snprintf(key_id, sizeof(key_id),
-					 "pkcs11:%s;type=public",
+					 "%s;type=public",
 					 keydir);
 			else
 				snprintf(key_id, sizeof(key_id),
-					 "pkcs11:%s;object=%s;type=public",
+					 "%s;object=%s;type=public",
 					 keydir, name);
 		else
 			snprintf(key_id, sizeof(key_id),
-				 "pkcs11:object=%s;type=public",
+				 "object=%s;type=public",
 				 name);
 	} else if (engine_id) {
 		if (keydir)
@@ -238,15 +238,15 @@
 		if (keydir)
 			if (strstr(keydir, "object="))
 				snprintf(key_id, sizeof(key_id),
-					 "pkcs11:%s;type=private",
+					 "%s;type=private",
 					 keydir);
 			else
 				snprintf(key_id, sizeof(key_id),
-					 "pkcs11:%s;object=%s;type=private",
+					 "%s;object=%s;type=private",
 					 keydir, name);
 		else
 			snprintf(key_id, sizeof(key_id),
-				 "pkcs11:object=%s;type=private",
+				 "object=%s;type=private",
 				 name);
 	} else if (engine_id) {
 		if (keydir && name)
diff --git a/lib/smbios.c b/lib/smbios.c
index d7f4999..3f0e1d5 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -9,11 +9,14 @@
 #include <dm.h>
 #include <env.h>
 #include <linux/stringify.h>
+#include <linux/string.h>
 #include <mapmem.h>
 #include <smbios.h>
 #include <sysinfo.h>
 #include <tables_csum.h>
 #include <version.h>
+#include <malloc.h>
+#include <dm/ofnode.h>
 #ifdef CONFIG_CPU
 #include <cpu.h>
 #include <dm/uclass-internal.h>
@@ -44,6 +47,25 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 /**
+ * struct map_sysinfo - Mapping of sysinfo strings to DT
+ *
+ * @sysinfo_str: sysinfo string
+ * @dt_str: DT string
+ * @max: Max index of the tokenized string to pick. Counting starts from 0
+ *
+ */
+struct map_sysinfo {
+	const char *sysinfo_str;
+	const char *dt_str;
+	int max;
+};
+
+static const struct map_sysinfo sysinfo_to_dt[] = {
+	{ .sysinfo_str = "product", .dt_str = "model", 2 },
+	{ .sysinfo_str = "manufacturer", .dt_str = "compatible", 1 },
+};
+
+/**
  * struct smbios_ctx - context for writing SMBIOS tables
  *
  * @node:	node containing the information to write (ofnode_null() if none)
@@ -87,6 +109,18 @@
 	const char *subnode_name;
 };
 
+static const struct map_sysinfo *convert_sysinfo_to_dt(const char *sysinfo_str)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sysinfo_to_dt); i++) {
+		if (!strcmp(sysinfo_str, sysinfo_to_dt[i].sysinfo_str))
+			return &sysinfo_to_dt[i];
+	}
+
+	return NULL;
+}
+
 /**
  * smbios_add_string() - add a string to the string area
  *
@@ -102,9 +136,6 @@
 	int i = 1;
 	char *p = ctx->eos;
 
-	if (!*str)
-		str = "Unknown";
-
 	for (;;) {
 		if (!*p) {
 			ctx->last_str = p;
@@ -128,31 +159,88 @@
 }
 
 /**
+ * get_str_from_dt - Get a substring from a DT property.
+ *                   After finding the property in the DT, the function
+ *                   will parse comma-separated values and return the value.
+ *                   If nprop->max exceeds the number of comma-separated
+ *                   elements, the last non NULL value will be returned.
+ *                   Counting starts from zero.
+ *
+ * @nprop: sysinfo property to use
+ * @str: pointer to fill with data
+ * @size: str buffer length
+ */
+static
+void get_str_from_dt(const struct map_sysinfo *nprop, char *str, size_t size)
+{
+	const char *dt_str;
+	int cnt = 0;
+	char *token;
+
+	memset(str, 0, size);
+	if (!nprop || !nprop->max)
+		return;
+
+	dt_str = ofnode_read_string(ofnode_root(), nprop->dt_str);
+	if (!dt_str)
+		return;
+
+	memcpy(str, dt_str, size);
+	token = strtok(str, ",");
+	while (token && cnt < nprop->max) {
+		strlcpy(str, token, strlen(token) + 1);
+		token = strtok(NULL, ",");
+		cnt++;
+	}
+}
+
+/**
  * smbios_add_prop_si() - Add a property from the devicetree or sysinfo
  *
  * Sysinfo is used if available, with a fallback to devicetree
  *
  * @ctx:	context for writing the tables
  * @prop:	property to write
+ * @dval:	Default value to use if the string is not found or is empty
  * Return:	0 if not found, else SMBIOS string number (1 or more)
  */
 static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop,
-			      int sysinfo_id)
+			      int sysinfo_id, const char *dval)
 {
+	int ret;
+
+	if (!dval || !*dval)
+		dval = "Unknown";
+
+	if (!prop)
+		return smbios_add_string(ctx, dval);
+
 	if (sysinfo_id && ctx->dev) {
 		char val[SMBIOS_STR_MAX];
-		int ret;
 
 		ret = sysinfo_get_str(ctx->dev, sysinfo_id, sizeof(val), val);
 		if (!ret)
 			return smbios_add_string(ctx, val);
 	}
 	if (IS_ENABLED(CONFIG_OF_CONTROL)) {
-		const char *str;
+		const char *str = NULL;
+		char str_dt[128] = { 0 };
+		/*
+		 * If the node is not valid fallback and try the entire DT
+		 * so we can at least fill in manufacturer and board type
+		 */
+		if (ofnode_valid(ctx->node)) {
+			str = ofnode_read_string(ctx->node, prop);
+		} else {
+			const struct map_sysinfo *nprop;
 
-		str = ofnode_read_string(ctx->node, prop);
-		if (str)
-			return smbios_add_string(ctx, str);
+			nprop = convert_sysinfo_to_dt(prop);
+			get_str_from_dt(nprop, str_dt, sizeof(str_dt));
+			str = (const char *)str_dt;
+		}
+
+		ret = smbios_add_string(ctx, str && *str ? str : dval);
+		return ret;
 	}
 
 	return 0;
@@ -161,12 +249,15 @@
 /**
  * smbios_add_prop() - Add a property from the devicetree
  *
- * @prop:	property to write
+ * @prop:	property to write. The default string will be written if
+ *		prop is NULL
+ * @dval:	Default value to use if the string is not found or is empty
  * Return:	0 if not found, else SMBIOS string number (1 or more)
  */
-static int smbios_add_prop(struct smbios_ctx *ctx, const char *prop)
+static int smbios_add_prop(struct smbios_ctx *ctx, const char *prop,
+			   const char *dval)
 {
-	return smbios_add_prop_si(ctx, prop, SYSINFO_ID_NONE);
+	return smbios_add_prop_si(ctx, prop, SYSINFO_ID_NONE, dval);
 }
 
 static void smbios_set_eos(struct smbios_ctx *ctx, char *eos)
@@ -228,11 +319,9 @@
 	memset(t, 0, sizeof(struct smbios_type0));
 	fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
 	smbios_set_eos(ctx, t->eos);
-	t->vendor = smbios_add_string(ctx, "U-Boot");
+	t->vendor = smbios_add_prop(ctx, NULL, "U-Boot");
 
-	t->bios_ver = smbios_add_prop(ctx, "version");
-	if (!t->bios_ver)
-		t->bios_ver = smbios_add_string(ctx, PLAIN_VERSION);
+	t->bios_ver = smbios_add_prop(ctx, "version", PLAIN_VERSION);
 	if (t->bios_ver)
 		gd->smbios_version = ctx->last_str;
 	log_debug("smbios_version = %p: '%s'\n", gd->smbios_version,
@@ -241,7 +330,7 @@
 	print_buffer((ulong)gd->smbios_version, gd->smbios_version,
 		     1, strlen(gd->smbios_version) + 1, 0);
 #endif
-	t->bios_release_date = smbios_add_string(ctx, U_BOOT_DMI_DATE);
+	t->bios_release_date = smbios_add_prop(ctx, NULL, U_BOOT_DMI_DATE);
 #ifdef CONFIG_ROM_SIZE
 	t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
 #endif
@@ -280,22 +369,19 @@
 	memset(t, 0, sizeof(struct smbios_type1));
 	fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
 	smbios_set_eos(ctx, t->eos);
-	t->manufacturer = smbios_add_prop(ctx, "manufacturer");
-	if (!t->manufacturer)
-		t->manufacturer = smbios_add_string(ctx, "Unknown");
-	t->product_name = smbios_add_prop(ctx, "product");
-	if (!t->product_name)
-		t->product_name = smbios_add_string(ctx, "Unknown Product");
+	t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown");
+	t->product_name = smbios_add_prop(ctx, "product", "Unknown");
 	t->version = smbios_add_prop_si(ctx, "version",
-					SYSINFO_ID_SMBIOS_SYSTEM_VERSION);
+					SYSINFO_ID_SMBIOS_SYSTEM_VERSION,
+					"Unknown");
 	if (serial_str) {
-		t->serial_number = smbios_add_string(ctx, serial_str);
+		t->serial_number = smbios_add_prop(ctx, NULL, serial_str);
 		strncpy((char *)t->uuid, serial_str, sizeof(t->uuid));
 	} else {
-		t->serial_number = smbios_add_prop(ctx, "serial");
+		t->serial_number = smbios_add_prop(ctx, "serial", "Unknown");
 	}
-	t->sku_number = smbios_add_prop(ctx, "sku");
-	t->family = smbios_add_prop(ctx, "family");
+	t->sku_number = smbios_add_prop(ctx, "sku", "Unknown");
+	t->family = smbios_add_prop(ctx, "family", "Unknown");
 
 	len = t->length + smbios_string_table_len(ctx);
 	*current += len;
@@ -314,15 +400,12 @@
 	memset(t, 0, sizeof(struct smbios_type2));
 	fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
 	smbios_set_eos(ctx, t->eos);
-	t->manufacturer = smbios_add_prop(ctx, "manufacturer");
-	if (!t->manufacturer)
-		t->manufacturer = smbios_add_string(ctx, "Unknown");
-	t->product_name = smbios_add_prop(ctx, "product");
-	if (!t->product_name)
-		t->product_name = smbios_add_string(ctx, "Unknown Product");
+	t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown");
+	t->product_name = smbios_add_prop(ctx, "product", "Unknown");
 	t->version = smbios_add_prop_si(ctx, "version",
-					SYSINFO_ID_SMBIOS_BASEBOARD_VERSION);
-	t->asset_tag_number = smbios_add_prop(ctx, "asset-tag");
+					SYSINFO_ID_SMBIOS_BASEBOARD_VERSION,
+					"Unknown");
+	t->asset_tag_number = smbios_add_prop(ctx, "asset-tag", "Unknown");
 	t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING;
 	t->board_type = SMBIOS_BOARD_MOTHERBOARD;
 
@@ -343,9 +426,7 @@
 	memset(t, 0, sizeof(struct smbios_type3));
 	fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
 	smbios_set_eos(ctx, t->eos);
-	t->manufacturer = smbios_add_prop(ctx, "manufacturer");
-	if (!t->manufacturer)
-		t->manufacturer = smbios_add_string(ctx, "Unknown");
+	t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown");
 	t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP;
 	t->bootup_state = SMBIOS_STATE_SAFE;
 	t->power_supply_state = SMBIOS_STATE_SAFE;
@@ -388,8 +469,8 @@
 #endif
 
 	t->processor_family = processor_family;
-	t->processor_manufacturer = smbios_add_string(ctx, vendor);
-	t->processor_version = smbios_add_string(ctx, name);
+	t->processor_manufacturer = smbios_add_prop(ctx, NULL, vendor);
+	t->processor_version = smbios_add_prop(ctx, NULL, name);
 }
 
 static int smbios_write_type4(ulong *current, int handle,
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index f3e5a83..a9b555c 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -1095,6 +1095,10 @@
 	ut_asserteq(0, run_command("bootflow cmdline get mary", 0));
 	ut_assert_nextline_empty();
 
+	ut_asserteq(0, run_command("bootflow cmdline set mary abc", 0));
+	ut_asserteq(0, run_command("bootflow cmdline set mary", 0));
+	ut_assert_nextline_empty();
+
 	ut_assert_console_end();
 
 	return 0;
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
index 04f64fd..8f9c4b2 100755
--- a/test/py/tests/test_fit.py
+++ b/test/py/tests/test_fit.py
@@ -339,6 +339,14 @@
                   'U-Boot loaded FDT from offset %#x, FDT is actually at %#x' %
                   (fit_offset, real_fit_offset))
 
+            # Check if bootargs strings substitution works
+            output = cons.run_command_list([
+                'env set bootargs \\\"\'my_boot_var=${foo}\'\\\"',
+                'env set foo bar',
+                'bootm prep',
+                'env print bootargs'])
+            assert 'bootargs="my_boot_var=bar"' in output, "Bootargs strings not substituted"
+
         # Now a kernel and an FDT
         with cons.log.section('Kernel + FDT load'):
             params['fdt_load'] = 'load = <%#x>;' % params['fdt_addr']