Merge tag 'u-boot-imx-20220207' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx

u-boot-imx-20211022
-------------------

CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/10887

- imx8 : Toradex Verdin MX8M Plus
	 Kontron pitx-imx8m
- imx8ulp: several fixes and improvements
- imx6ull fixes
- switching to binman
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 3a8b2b6..94d18ca 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -65,6 +65,9 @@
 	struct efi_device_path *device, *image;
 	efi_status_t ret;
 
+	log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev,
+		  devnr, path, buffer, buffer_size);
+
 	/* Forget overwritten image */
 	if (buffer + buffer_size >= image_addr &&
 	    image_addr + image_size >= buffer)
@@ -72,18 +75,19 @@
 
 	/* Remember only PE-COFF and FIT images */
 	if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) {
-#ifdef CONFIG_FIT
-		if (fit_check_format(buffer, IMAGE_SIZE_INVAL))
+		if (IS_ENABLED(CONFIG_FIT) &&
+		    !fit_check_format(buffer, IMAGE_SIZE_INVAL)) {
+			/*
+			 * FIT images of type EFI_OS are started via command
+			 * bootm. We should not use their boot device with the
+			 * bootefi command.
+			 */
+			buffer = 0;
+			buffer_size = 0;
+		} else {
+			log_debug("- not remembering image\n");
 			return;
-		/*
-		 * FIT images of type EFI_OS are started via command bootm.
-		 * We should not use their boot device with the bootefi command.
-		 */
-		buffer = 0;
-		buffer_size = 0;
-#else
-		return;
-#endif
+		}
 	}
 
 	/* efi_set_bootdev() is typically called repeatedly, recover memory */
@@ -103,7 +107,11 @@
 			efi_free_pool(image_tmp);
 		}
 		bootefi_image_path = image;
+		log_debug("- recorded device %ls\n", efi_dp_str(device));
+		if (image)
+			log_debug("- and image %ls\n", efi_dp_str(image));
 	} else {
+		log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
 		efi_clear_bootdev();
 	}
 }
@@ -451,6 +459,7 @@
 	u16 *load_options;
 
 	if (!bootefi_device_path || !bootefi_image_path) {
+		log_debug("Not loaded from disk\n");
 		/*
 		 * Special case for efi payload not loaded from disk,
 		 * such as 'bootefi hello' or for example payload
@@ -476,6 +485,7 @@
 		file_path = efi_dp_append(bootefi_device_path,
 					  bootefi_image_path);
 		msg_path = bootefi_image_path;
+		log_debug("Loaded from disk\n");
 	}
 
 	log_info("Booting %pD\n", msg_path);
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index 3d15f22..8cf8a31 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -105,4 +105,4 @@
 CONFIG_SPLASH_SCREEN_ALIGN=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_FDT_FIXUP_PARTITIONS=y
-# CONFIG_EFI_UNICODE_CAPITALIZATION is not set
+# CONFIG_EFI_LOADER is not set
diff --git a/include/efi_loader.h b/include/efi_loader.h
index f4ae84d..e390d32 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -769,6 +769,7 @@
 efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
 				    struct efi_device_path **device_path,
 				    struct efi_device_path **file_path);
+struct efi_device_path *efi_dp_from_uart(void);
 efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
 			      const char *path,
 			      struct efi_device_path **device,
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 1ea04de..82128ac 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -467,7 +467,7 @@
 {
 	efi_status_t r;
 
-	EFI_ENTRY("%d, %zd, %p", pool_type, size, buffer);
+	EFI_ENTRY("%d, %zu, %p", pool_type, size, buffer);
 	r = efi_allocate_pool(pool_type, size, buffer);
 	return EFI_EXIT(r);
 }
@@ -914,7 +914,7 @@
 {
 	int i;
 
-	EFI_ENTRY("%zd, %p, %p", num_events, event, index);
+	EFI_ENTRY("%zu, %p, %p", num_events, event, index);
 
 	/* Check parameters */
 	if (!num_events || !event)
@@ -2028,7 +2028,7 @@
 	efi_status_t ret;
 	void *dest_buffer;
 
-	EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image,
+	EFI_ENTRY("%d, %p, %pD, %p, %zu, %p", boot_policy, parent_image,
 		  file_path, source_buffer, source_size, image_handle);
 
 	if (!image_handle || (!source_buffer && !file_path) ||
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 3b012e1..ba68a15 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -25,6 +25,8 @@
 	int present;
 };
 
+__maybe_unused static struct efi_object uart_obj;
+
 static struct cout_mode efi_cout_modes[] = {
 	/* EFI Mode 0 is 80x25 and always present */
 	{
@@ -1258,37 +1260,33 @@
 efi_status_t efi_console_register(void)
 {
 	efi_status_t r;
-	efi_handle_t console_output_handle;
-	efi_handle_t console_input_handle;
+	struct efi_device_path *dp;
 
 	/* Set up mode information */
 	query_console_size();
 
-	/* Create handles */
-	r = efi_create_handle(&console_output_handle);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
+	/* Install protocols on root node */
+	r = EFI_CALL(efi_install_multiple_protocol_interfaces
+		     (&efi_root,
+		      &efi_guid_text_output_protocol, &efi_con_out,
+		      &efi_guid_text_input_protocol, &efi_con_in,
+		      &efi_guid_text_input_ex_protocol, &efi_con_in_ex,
+		      NULL));
 
-	r = efi_add_protocol(console_output_handle,
-			     &efi_guid_text_output_protocol, &efi_con_out);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
-	systab.con_out_handle = console_output_handle;
-	systab.stderr_handle = console_output_handle;
+	/* Create console node and install device path protocols */
+	if (CONFIG_IS_ENABLED(DM_SERIAL)) {
+		dp = efi_dp_from_uart();
+		if (!dp)
+			goto out_of_memory;
 
-	r = efi_create_handle(&console_input_handle);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
+		/* Hook UART up to the device list */
+		efi_add_handle(&uart_obj);
 
-	r = efi_add_protocol(console_input_handle,
-			     &efi_guid_text_input_protocol, &efi_con_in);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
-	systab.con_in_handle = console_input_handle;
-	r = efi_add_protocol(console_input_handle,
-			     &efi_guid_text_input_ex_protocol, &efi_con_in_ex);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
+		/* Install device path */
+		r = efi_add_protocol(&uart_obj, &efi_guid_device_path, dp);
+		if (r != EFI_SUCCESS)
+			goto out_of_memory;
+	}
 
 	/* Create console events */
 	r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify,
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index c61f485..dc787b4 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -494,7 +494,7 @@
 	if (!dev || !dev->driver)
 		return sizeof(ROOT);
 
-	switch (dev->driver->id) {
+	switch (device_get_uclass_id(dev)) {
 	case UCLASS_ROOT:
 	case UCLASS_SIMPLE_BUS:
 		/* stop traversing parents at this point: */
@@ -579,7 +579,7 @@
 	if (!dev || !dev->driver)
 		return buf;
 
-	switch (dev->driver->id) {
+	switch (device_get_uclass_id(dev)) {
 	case UCLASS_ROOT:
 	case UCLASS_SIMPLE_BUS: {
 		/* stop traversing parents at this point: */
@@ -759,9 +759,9 @@
 		return &udp[1];
 	}
 	default:
-		debug("%s(%u) %s: unhandled device class: %s (%u)\n",
-		      __FILE__, __LINE__, __func__,
-		      dev->name, dev->driver->id);
+		/* If the uclass driver is missing, this will show NULL */
+		log_debug("unhandled device class: %s (%s)\n", dev->name,
+			  dev_get_uclass_name(dev));
 		return dp_fill(buf, dev->parent);
 	}
 }
@@ -769,13 +769,8 @@
 static unsigned dp_part_size(struct blk_desc *desc, int part)
 {
 	unsigned dpsize;
-	struct udevice *dev;
-	int ret;
+	struct udevice *dev = desc->bdev;
 
-	ret = blk_find_device(desc->if_type, desc->devnum, &dev);
-
-	if (ret)
-		dev = desc->bdev->parent;
 	dpsize = dp_size(dev);
 
 	if (part == 0) /* the actual disk, not a partition */
@@ -866,13 +861,8 @@
  */
 static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
 {
-	struct udevice *dev;
-	int ret;
-
-	ret = blk_find_device(desc->if_type, desc->devnum, &dev);
+	struct udevice *dev = desc->bdev;
 
-	if (ret)
-		dev = desc->bdev->parent;
 	buf = dp_fill(buf, dev);
 
 	if (part == 0) /* the actual disk, not a partition */
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index d8a83c8..4d73954 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <blk.h>
 #include <efi_loader.h>
+#include <malloc.h>
 
 #define MAC_OUTPUT_LEN 22
 #define UNKNOWN_OUTPUT_LEN 23
@@ -121,16 +122,26 @@
 	case DEVICE_PATH_SUB_TYPE_MSG_UART: {
 		struct efi_device_path_uart *uart =
 			(struct efi_device_path_uart *)dp;
-		s += sprintf(s, "Uart(%lld,%d,%d,", uart->baud_rate,
-			     uart->data_bits, uart->parity);
-		switch (uart->stop_bits) {
-		case 2:
-			s += sprintf(s, "1.5)");
-			break;
-		default:
+		const char parity_str[6] = {'D', 'N', 'E', 'O', 'M', 'S'};
+		const char *stop_bits_str[4] = { "D", "1", "1.5", "2" };
+
+		s += sprintf(s, "Uart(%lld,%d,", uart->baud_rate,
+			     uart->data_bits);
+
+		/*
+		 * Parity and stop bits can either both use keywords or both use
+		 * numbers but numbers and keywords should not be mixed. Let's
+		 * go for keywords as this is what EDK II does. For illegal
+		 * values fall back to numbers.
+		 */
+		if (uart->parity < 6)
+			s += sprintf(s, "%c,", parity_str[uart->parity]);
+		else
+			s += sprintf(s, "%d,", uart->parity);
+		if (uart->stop_bits < 4)
+			s += sprintf(s, "%s)", stop_bits_str[uart->stop_bits]);
+		else
 			s += sprintf(s, "%d)", uart->stop_bits);
-			break;
-		}
 		break;
 	}
 	case DEVICE_PATH_SUB_TYPE_MSG_USB: {
@@ -292,10 +303,18 @@
 	case DEVICE_PATH_SUB_TYPE_FILE_PATH: {
 		struct efi_device_path_file_path *fp =
 			(struct efi_device_path_file_path *)dp;
-		int slen = (dp->length - sizeof(*dp)) / 2;
-		if (slen > MAX_NODE_LEN - 2)
-			slen = MAX_NODE_LEN - 2;
-		s += sprintf(s, "%-.*ls", slen, fp->str);
+		u16 *buffer;
+		int slen = dp->length - sizeof(*dp);
+
+		/* two bytes for \0, extra byte if dp->length is odd */
+		buffer = calloc(1, slen + 3);
+		if (!buffer) {
+			log_err("Out of memory\n");
+			return s;
+		}
+		memcpy(buffer, fp->str, dp->length - sizeof(*dp));
+		s += snprintf(s, MAX_NODE_LEN - 1, "%ls", buffer);
+		free(buffer);
 		break;
 	}
 	default:
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 519a472..a5ff32f 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -302,7 +302,7 @@
 	efi_status_t (*progress)(efi_uintn_t completion),
 	u16 **abort_reason)
 {
-	EFI_ENTRY("%p %d %p %zd %p %p %p\n", this, image_index, image,
+	EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
 		  image_size, vendor_code, progress, abort_reason);
 
 	if (!image || image_index != 1)
@@ -417,7 +417,7 @@
 	efi_status_t status;
 	efi_uintn_t capsule_payload_size;
 
-	EFI_ENTRY("%p %d %p %zd %p %p %p\n", this, image_index, image,
+	EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
 		  image_size, vendor_code, progress, abort_reason);
 
 	if (!image)
diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c
index f4a7fcb..114ac58 100644
--- a/lib/efi_selftest/efi_selftest_fdt.c
+++ b/lib/efi_selftest/efi_selftest_fdt.c
@@ -1,15 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * efi_selftest_pos
+ * efi_selftest_fdt
  *
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ * Copyright (c) 2022 Ventana Micro Systems Inc
  *
- * Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
- *
- * The following services are tested:
- * OutputString, TestString, SetAttribute.
+ * Check the device tree, test the RISCV_EFI_BOOT_PROTOCOL.
  */
 
+#include <efi_riscv.h>
 #include <efi_selftest.h>
 #include <linux/libfdt.h>
 
@@ -22,6 +21,8 @@
 
 static const efi_guid_t fdt_guid = EFI_FDT_GUID;
 static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
+static const efi_guid_t riscv_efi_boot_protocol_guid =
+				RISCV_EFI_BOOT_PROTOCOL_GUID;
 
 /**
  * f2h() - convert FDT value to host endianness.
@@ -189,6 +190,29 @@
 	return EFI_ST_SUCCESS;
 }
 
+__maybe_unused static efi_status_t get_boot_hartid(efi_uintn_t *efi_hartid)
+{
+	efi_status_t ret;
+	struct riscv_efi_boot_protocol *prot;
+
+	/* Get RISC-V boot protocol */
+	ret = boottime->locate_protocol(&riscv_efi_boot_protocol_guid, NULL,
+					(void **)&prot);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("RISC-V Boot Protocol not available\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Get boot hart ID from EFI protocol */
+	ret = prot->get_boot_hartid(prot, efi_hartid);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Could not retrieve boot hart ID\n");
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
 /*
  * Execute unit test.
  *
@@ -220,19 +244,37 @@
 			return EFI_ST_FAILURE;
 		}
 	}
-	str = get_property(u"boot-hartid", u"chosen");
 	if (IS_ENABLED(CONFIG_RISCV)) {
-		if (str) {
-			efi_st_printf("boot-hartid: %u\n",
-				      f2h(*(fdt32_t *)str));
-			ret = boottime->free_pool(str);
-			if (ret != EFI_SUCCESS) {
-				efi_st_error("FreePool failed\n");
+		u32 fdt_hartid;
+
+		str = get_property(u"boot-hartid", u"chosen");
+		if (!str) {
+			efi_st_error("boot-hartid missing in devicetree\n");
+			return EFI_ST_FAILURE;
+		}
+		fdt_hartid = f2h(*(fdt32_t *)str);
+		efi_st_printf("boot-hartid: %u\n", fdt_hartid);
+
+		ret = boottime->free_pool(str);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("FreePool failed\n");
+			return EFI_ST_FAILURE;
+		}
+
+		if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) {
+			efi_uintn_t efi_hartid;
+			int r;
+
+			r = get_boot_hartid(&efi_hartid);
+			if (r != EFI_ST_SUCCESS)
+				return r;
+			/* Boot hart ID should be same */
+			if (efi_hartid != fdt_hartid) {
+				efi_st_error("boot-hartid differs: prot 0x%p, DT 0x%.8x\n",
+					     (void *)(uintptr_t)efi_hartid,
+					     fdt_hartid);
 				return EFI_ST_FAILURE;
 			}
-		} else {
-			efi_st_error("boot-hartid not found\n");
-			return EFI_ST_FAILURE;
 		}
 	}
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 69b2f6a..fe06aa2 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -285,15 +285,25 @@
 	if (!(flags & LEFT))
 		for (; len < field_width; --field_width)
 			ADDCH(buf, ' ');
-	for (i = 0; i < len && buf + utf16_utf8_strnlen(str, 1) <= end; ++i) {
+	if (buf < end)
+		*buf = 0;
+	for (i = 0; i < len; ++i) {
+		int slen = utf16_utf8_strnlen(str, 1);
 		s32 s = utf16_get(&str);
 
 		if (s < 0)
 			s = '?';
-		utf8_put(s, &buf);
+		if (buf + slen < end) {
+			utf8_put(s, &buf);
+			if (buf < end)
+				*buf = 0;
+		} else {
+			buf += slen;
+		}
 	}
 	for (; len < field_width; --field_width)
 		ADDCH(buf, ' ');
+
 	return buf;
 }
 
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index f821e5a..f2f63d5 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -97,6 +97,7 @@
 static int unicode_test_string16(struct unit_test_state *uts)
 {
 	char buf[20];
+	int ret;
 
 	/* Test length and precision */
 	memset(buf, 0xff, sizeof(buf));
@@ -130,6 +131,36 @@
 	sprintf(buf, "%ls", i3);
 	ut_asserteq_str("i3?", buf);
 
+	memset(buf, 0xff, sizeof(buf));
+	ret = snprintf(buf, 4, "%ls", c1);
+	ut_asserteq(6, ret);
+	ut_asserteq_str("U-B", buf);
+
+	memset(buf, 0xff, sizeof(buf));
+	ret = snprintf(buf, 6, "%ls", c2);
+	ut_asserteq_str("kafb", buf);
+	ut_asserteq(9, ret);
+
+	memset(buf, 0xff, sizeof(buf));
+	ret = snprintf(buf, 7, "%ls", c2);
+	ut_asserteq_str("kafb\xC3\xA1", buf);
+	ut_asserteq(9, ret);
+
+	memset(buf, 0xff, sizeof(buf));
+	ret = snprintf(buf, 8, "%ls", c3);
+	ut_asserteq_str("\xE6\xBD\x9C\xE6\xB0\xB4", buf);
+	ut_asserteq(9, ret);
+
+	memset(buf, 0xff, sizeof(buf));
+	ret = snprintf(buf, 11, "%ls", c4);
+	ut_asserteq_str("\xF0\x90\x92\x8D\xF0\x90\x92\x96", buf);
+	ut_asserteq(12, ret);
+
+	memset(buf, 0xff, sizeof(buf));
+	ret = snprintf(buf, 4, "%ls", c4);
+	ut_asserteq_str("", buf);
+	ut_asserteq(12, ret);
+
 	return 0;
 }
 UNICODE_TEST(unicode_test_string16);
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 243fd6e..d6e3725 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -5,7 +5,6 @@
  */
 
 #include <getopt.h>
-#include <malloc.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>