Merge tag 'efi-2022-01-rc1-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request for efi-2022-01-rc1-2

doc:
	Remove obsolete PPC4XX references

UEFI:
	Implement missing TCG2 measurements
	Code clean up

# gpg: Signature made Tue 26 Oct 2021 05:56:47 PM EDT
# gpg:                using RSA key 6DC4F9C71F29A6FA06B76D33C481DBBC2C051AC4
# gpg: Good signature from "Heinrich Schuchardt <xypron.glpk@gmx.de>" [unknown]
# gpg:                 aka "[jpeg image of size 1389]" [unknown]
# Primary key fingerprint: 6DC4 F9C7 1F29 A6FA 06B7  6D33 C481 DBBC 2C05 1AC4
diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c
index 8e2bdf3..4f9b84b 100644
--- a/arch/arm/lib/spl.c
+++ b/arch/arm/lib/spl.c
@@ -77,3 +77,14 @@
 }
 #endif	/* CONFIG_ARM64 */
 #endif
+
+#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
+void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
+{
+	/* flush and turn off caches before jumping to OPTEE */
+	cleanup_before_linux();
+
+	spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
+			(void *)spl_image->entry_point);
+}
+#endif
diff --git a/cmd/load.c b/cmd/load.c
index 249ebd4..7e4a552 100644
--- a/cmd/load.c
+++ b/cmd/load.c
@@ -16,6 +16,7 @@
 #include <exports.h>
 #include <flash.h>
 #include <image.h>
+#include <lmb.h>
 #include <mapmem.h>
 #include <net.h>
 #include <s_record.h>
@@ -137,6 +138,7 @@
 
 static ulong load_serial(long offset)
 {
+	struct lmb lmb;
 	char	record[SREC_MAXRECLEN + 1];	/* buffer for one S-Record	*/
 	char	binbuf[SREC_MAXBINLEN];		/* buffer for binary data	*/
 	int	binlen;				/* no. of data bytes in S-Rec.	*/
@@ -147,6 +149,9 @@
 	ulong	start_addr = ~0;
 	ulong	end_addr   =  0;
 	int	line_count =  0;
+	long ret;
+
+	lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
 
 	while (read_record(record, SREC_MAXRECLEN + 1) >= 0) {
 		type = srec_decode(record, &binlen, &addr, binbuf);
@@ -172,7 +177,14 @@
 		    } else
 #endif
 		    {
+			ret = lmb_reserve(&lmb, store_addr, binlen);
+			if (ret) {
+				printf("\nCannot overwrite reserved area (%08lx..%08lx)\n",
+					store_addr, store_addr + binlen);
+				return ret;
+			}
 			memcpy((char *)(store_addr), binbuf, binlen);
+			lmb_free(&lmb, store_addr, binlen);
 		    }
 		    if ((store_addr) < start_addr)
 			start_addr = store_addr;
diff --git a/cmd/nand.c b/cmd/nand.c
index df5a4b1..e730484 100644
--- a/cmd/nand.c
+++ b/cmd/nand.c
@@ -17,6 +17,10 @@
  * and/or modified under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
+ *
+ * The function nand_biterror() in this file is inspired from
+ * mtd-utils/nand-utils/nandflipbits.c which was released under GPLv2
+ * only
  */
 
 #include <common.h>
@@ -44,6 +48,116 @@
 		      u8 *part_num, struct part_info **part);
 #endif
 
+#define MAX_NUM_PAGES 64
+
+static int nand_biterror(struct mtd_info *mtd, ulong off, int bit)
+{
+	int ret = 0;
+	int page = 0;
+	ulong  block_off;
+	u_char *datbuf[MAX_NUM_PAGES]; /* Data and OOB */
+	u_char data;
+	int pages_per_blk = mtd->erasesize / mtd->writesize;
+	struct erase_info einfo;
+
+	if (pages_per_blk > MAX_NUM_PAGES) {
+		printf("Too many pages in one erase block\n");
+		return 1;
+	}
+
+	if (bit < 0 || bit > 7) {
+		printf("bit position 0 to 7 is allowed\n");
+		return 1;
+	}
+
+	/* Allocate memory */
+	memset(datbuf, 0, sizeof(datbuf));
+	for (page = 0; page < pages_per_blk ; page++) {
+		datbuf[page] = malloc(mtd->writesize + mtd->oobsize);
+		if (!datbuf[page]) {
+			printf("No memory for page buffer\n");
+			ret = -ENOMEM;
+			goto free_memory;
+		}
+	}
+
+	/* Align to erase block boundary */
+	block_off = off & (~(mtd->erasesize - 1));
+
+	/* Read out memory as first step */
+	for (page = 0; page < pages_per_blk ; page++) {
+		struct mtd_oob_ops ops;
+		loff_t addr = (loff_t)block_off;
+
+		memset(&ops, 0, sizeof(ops));
+		ops.datbuf = datbuf[page];
+		ops.oobbuf = datbuf[page] + mtd->writesize;
+		ops.len = mtd->writesize;
+		ops.ooblen = mtd->oobsize;
+		ops.mode = MTD_OPS_RAW;
+		ret = mtd_read_oob(mtd, addr, &ops);
+		if (ret < 0) {
+			printf("Error (%d) reading page %08lx\n",
+			       ret, block_off);
+			ret = 1;
+			goto free_memory;
+		}
+		block_off += mtd->writesize;
+	}
+
+	/* Erase the block */
+	memset(&einfo, 0, sizeof(einfo));
+	einfo.mtd = mtd;
+	/* Align to erase block boundary */
+	einfo.addr = (loff_t)(off & (~(mtd->erasesize - 1)));
+	einfo.len = mtd->erasesize;
+	ret = mtd_erase(mtd, &einfo);
+	if (ret < 0) {
+		printf("Error (%d) nand_erase_nand page %08llx\n",
+		       ret, einfo.addr);
+		ret = 1;
+		goto free_memory;
+	}
+
+	/* Twist a bit in data part */
+	block_off = off & (mtd->erasesize - 1);
+	data = datbuf[block_off / mtd->writesize][block_off % mtd->writesize];
+	data ^= (1 << bit);
+	datbuf[block_off / mtd->writesize][block_off % mtd->writesize] = data;
+
+	printf("Flip data at 0x%lx with xor 0x%02x (bit=%d) to value=0x%02x\n",
+	       off, (1 << bit), bit, data);
+
+	/* Write back twisted data and unmodified OOB */
+	/* Align to erase block boundary */
+	block_off = off & (~(mtd->erasesize - 1));
+	for (page = 0; page < pages_per_blk; page++) {
+		struct mtd_oob_ops ops;
+		loff_t addr = (loff_t)block_off;
+
+		memset(&ops, 0, sizeof(ops));
+		ops.datbuf = datbuf[page];
+		ops.oobbuf = datbuf[page] + mtd->writesize;
+		ops.len = mtd->writesize;
+		ops.ooblen = mtd->oobsize;
+		ops.mode = MTD_OPS_RAW;
+		ret = mtd_write_oob(mtd, addr, &ops);
+		if (ret < 0) {
+			printf("Error (%d) write page %08lx\n", ret, block_off);
+			ret = 1;
+			goto free_memory;
+		}
+		block_off += mtd->writesize;
+	}
+
+free_memory:
+	for (page = 0; page < pages_per_blk ; page++) {
+		if (datbuf[page])
+			free(datbuf[page]);
+	}
+	return ret;
+}
+
 static int nand_dump(struct mtd_info *mtd, ulong off, int only_oob,
 		     int repeat)
 {
@@ -733,8 +847,15 @@
 	}
 
 	if (strcmp(cmd, "biterr") == 0) {
-		/* todo */
-		return 1;
+		int bit;
+
+		if (argc != 4)
+			goto usage;
+
+		off = (int)simple_strtoul(argv[2], NULL, 16);
+		bit = (int)simple_strtoul(argv[3], NULL, 10);
+		ret = nand_biterror(mtd, off, bit);
+		return ret;
 	}
 
 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
@@ -825,7 +946,7 @@
 	"nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
 	"    really clean NAND erasing bad blocks (UNSAFE)\n"
 	"nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
-	"nand biterr off - make a bit error at offset (UNSAFE)"
+	"nand biterr off bit - make a bit error at offset and bit position (UNSAFE)"
 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
 	"\n"
 	"nand lock [tight] [status]\n"
diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index 9b84a8d..c948d58 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -175,6 +175,13 @@
 	  device memory. Assure this size does not extend past expected storage
 	  space.
 
+config SPL_FIT_RSASSA_PSS
+	bool "Support rsassa-pss signature scheme of FIT image contents in SPL"
+	depends on SPL_FIT_SIGNATURE
+	help
+	  Enable this to support the pss padding algorithm as described
+	  in the rfc8017 (https://tools.ietf.org/html/rfc8017) in SPL.
+
 config SPL_LOAD_FIT
 	bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
 	select SPL_FIT
diff --git a/common/spl/spl.c b/common/spl/spl.c
index a9304d4..0c08da0 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -174,6 +174,14 @@
 {
 }
 
+#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
+__weak void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
+{
+	spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
+			(void *)spl_image->entry_point);
+}
+#endif
+
 __weak void spl_board_prepare_for_boot(void)
 {
 	/* Nothing to do! */
@@ -780,8 +788,7 @@
 	case IH_OS_TEE:
 		debug("Jumping to U-Boot via OP-TEE\n");
 		spl_board_prepare_for_optee(spl_image.fdt_addr);
-		spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
-				(void *)spl_image.entry_point);
+		jump_to_image_optee(&spl_image);
 		break;
 #endif
 #if CONFIG_IS_ENABLED(OPENSBI)
diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
index 48e41bc..8d7f13d 100644
--- a/drivers/dfu/Kconfig
+++ b/drivers/dfu/Kconfig
@@ -38,6 +38,13 @@
 	help
 	  This option enables using DFU to read and write to MMC based storage.
 
+config DFU_MTD
+	bool "MTD back end for DFU"
+	depends on DM_MTD
+	depends on CMD_MTDPARTS
+	help
+	  This option enables using DFU to read and write to on any MTD device.
+
 config DFU_NAND
 	bool "NAND back end for DFU"
 	depends on CMD_MTDPARTS
@@ -72,13 +79,6 @@
 	  This option enables the support of "part" and "partubi" target in
 	  SPI flash DFU back end.
 
-config DFU_MTD
-	bool "MTD back end for DFU"
-	depends on DM_MTD
-	depends on CMD_MTDPARTS
-	help
-	  This option enables using DFU to read and write to on any MTD device.
-
 config DFU_VIRT
 	bool "VIRTUAL flash back end for DFU"
 	help
diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
index 7e64ab7..b72493c 100644
--- a/drivers/dfu/dfu_sf.c
+++ b/drivers/dfu/dfu_sf.c
@@ -24,8 +24,18 @@
 static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
 			      long *len)
 {
-	return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
-		*len, buf);
+	long seglen = *len;
+	int ret;
+
+	if (seglen > (16 << 20))
+		seglen = (16 << 20);
+
+	ret = spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
+		seglen, buf);
+	if (!ret)
+		*len = seglen;
+
+	return ret;
 }
 
 static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
diff --git a/env/Kconfig b/env/Kconfig
index f75f2b1..06d72ba 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -200,6 +200,11 @@
 	  This value may also be positive or negative; this is handled in the
 	  same way as CONFIG_ENV_OFFSET.
 
+	  In case CONFIG_SYS_MMC_ENV_PART is 1 (i.e. environment in eMMC boot
+	  partition) then setting CONFIG_ENV_OFFSET_REDUND to the same value
+	  as CONFIG_ENV_OFFSET makes use of the second eMMC boot partition for
+	  the redundant environment copy.
+
 	  This value is also in units of bytes, but must also be aligned to
 	  an MMC sector boundary.
 
diff --git a/env/flash.c b/env/flash.c
index ebee906..473e824 100644
--- a/env/flash.c
+++ b/env/flash.c
@@ -210,8 +210,7 @@
 perror:
 	flash_perror(rc);
 done:
-	if (saved_data)
-		free(saved_data);
+	free(saved_data);
 	/* try to re-protect */
 	flash_sect_protect(1, (ulong)flash_addr, end_addr);
 	flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);
@@ -298,8 +297,7 @@
 perror:
 	flash_perror(rc);
 done:
-	if (saved_data)
-		free(saved_data);
+	free(saved_data);
 	/* try to re-protect */
 	flash_sect_protect(1, (long)flash_addr, end_addr);
 	return rc;
diff --git a/env/mmc.c b/env/mmc.c
index c4cb163..465b104 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -26,6 +26,18 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * In case the environment is redundant, stored in eMMC hardware boot
+ * partition and the environment and redundant environment offsets are
+ * identical, store the environment and redundant environment in both
+ * eMMC boot partitions, one copy in each.
+ * */
+#if (defined(CONFIG_SYS_REDUNDAND_ENVIRONMENT) && \
+     (CONFIG_SYS_MMC_ENV_PART == 1) && \
+     (CONFIG_ENV_OFFSET == CONFIG_ENV_OFFSET_REDUND))
+#define ENV_MMC_HWPART_REDUND
+#endif
+
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
 {
@@ -126,13 +138,11 @@
 
 static unsigned char env_mmc_orig_hwpart;
 
-static int mmc_set_env_part(struct mmc *mmc)
+static int mmc_set_env_part(struct mmc *mmc, uint part)
 {
-	uint part = mmc_get_env_part(mmc);
 	int dev = mmc_get_env_dev();
 	int ret = 0;
 
-	env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
 	ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
 	if (ret)
 		puts("MMC partition switch failed\n");
@@ -140,7 +150,7 @@
 	return ret;
 }
 #else
-static inline int mmc_set_env_part(struct mmc *mmc) {return 0; };
+static inline int mmc_set_env_part(struct mmc *mmc, uint part) {return 0; };
 #endif
 
 static const char *init_mmc_for_env(struct mmc *mmc)
@@ -157,7 +167,8 @@
 	if (mmc_init(mmc))
 		return "MMC init failed";
 #endif
-	if (mmc_set_env_part(mmc))
+	env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
+	if (mmc_set_env_part(mmc, mmc_get_env_part(mmc)))
 		return "MMC partition switch failed";
 
 	return NULL;
@@ -209,6 +220,13 @@
 #ifdef CONFIG_ENV_OFFSET_REDUND
 	if (gd->env_valid == ENV_VALID)
 		copy = 1;
+
+#ifdef ENV_MMC_HWPART_REDUND
+	ret = mmc_set_env_part(mmc, copy + 1);
+	if (ret)
+		goto fini;
+#endif
+
 #endif
 
 	if (mmc_get_env_addr(mmc, copy, &offset)) {
@@ -263,20 +281,32 @@
 		return 1;
 	}
 
-	if (mmc_get_env_addr(mmc, copy, &offset))
-		return CMD_RET_FAILURE;
+	if (mmc_get_env_addr(mmc, copy, &offset)) {
+		ret = CMD_RET_FAILURE;
+		goto fini;
+	}
 
 	ret = erase_env(mmc, CONFIG_ENV_SIZE, offset);
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
 	copy = 1;
 
-	if (mmc_get_env_addr(mmc, copy, &offset))
-		return CMD_RET_FAILURE;
+#ifdef ENV_MMC_HWPART_REDUND
+	ret = mmc_set_env_part(mmc, copy + 1);
+	if (ret)
+		goto fini;
+#endif
+
+	if (mmc_get_env_addr(mmc, copy, &offset)) {
+		ret = CMD_RET_FAILURE;
+		goto fini;
+	}
 
 	ret |= erase_env(mmc, CONFIG_ENV_SIZE, offset);
 #endif
 
+fini:
+	fini_mmc_for_env(mmc);
 	return ret;
 }
 #endif /* CONFIG_CMD_SAVEENV && !CONFIG_SPL_BUILD */
@@ -325,7 +355,20 @@
 		goto fini;
 	}
 
+#ifdef ENV_MMC_HWPART_REDUND
+	ret = mmc_set_env_part(mmc, 1);
+	if (ret)
+		goto fini;
+#endif
+
 	read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1);
+
+#ifdef ENV_MMC_HWPART_REDUND
+	ret = mmc_set_env_part(mmc, 2);
+	if (ret)
+		goto fini;
+#endif
+
 	read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
 
 	ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 2db7169..ef26e72 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -97,14 +97,14 @@
 
 /**
  * struct scmi_clk_state_in - Message payload for CLOCK_RATE_SET command
- * @clock_id:	SCMI clock ID
  * @flags:	Flags for the clock rate set request
+ * @clock_id:	SCMI clock ID
  * @rate_lsb:	32bit LSB of the clock rate in Hertz
  * @rate_msb:	32bit MSB of the clock rate in Hertz
  */
 struct scmi_clk_rate_set_in {
-	u32 clock_id;
 	u32 flags;
+	u32 clock_id;
 	u32 rate_lsb;
 	u32 rate_msb;
 };
diff --git a/include/spl.h b/include/spl.h
index 7ddb2ab..0af0ee3 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -469,6 +469,15 @@
 void __noreturn jump_to_image_linux(struct spl_image_info *spl_image);
 
 /**
+ * jump_to_image_linux() - Jump to OP-TEE OS from SPL
+ *
+ * This jumps into OP-TEE OS using the information in @spl_image.
+ *
+ * @spl_image: Image description to set up
+ */
+void __noreturn jump_to_image_optee(struct spl_image_info *spl_image);
+
+/**
  * spl_start_uboot() - Check if SPL should start the kernel or U-Boot
  *
  * This is called by the various SPL loaders to determine whether the board
@@ -759,7 +768,7 @@
  * @arg2: device tree address, (ARMv7 standard bootarg #2)
  * @arg3: non-secure entry address (ARMv7 bootarg #0)
  */
-void spl_optee_entry(void *arg0, void *arg1, void *arg2, void *arg3);
+void __noreturn spl_optee_entry(void *arg0, void *arg1, void *arg2, void *arg3);
 
 /**
  * spl_invoke_opensbi - boot using a RISC-V OpenSBI image
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 600c93a..83f7564 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -340,7 +340,7 @@
 	struct padding_algo *padding = info->padding;
 	int hash_len;
 
-	if (!prop || !sig || !hash || !checksum)
+	if (!prop || !sig || !hash || !checksum || !padding)
 		return -EIO;
 
 	if (sig_len != (prop->num_bits / 8)) {
diff --git a/lib/uuid.c b/lib/uuid.c
index 67267c6..e4703dc 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -257,7 +257,7 @@
 
 	if (IS_ENABLED(CONFIG_DM_RNG)) {
 		ret = uclass_get_device(UCLASS_RNG, 0, &devp);
-		if (ret) {
+		if (!ret) {
 			ret = dm_rng_read(devp, &randv, sizeof(randv));
 			if (ret < 0)
 				randv = 0;