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

Pull request for efi-2022-07-rc3-2

UEFI:
* Fix build errors due to
  - using sed with non-standard extension for regular expression
  - target architecture not recognized for CROSS_COMPILE=armv7a-*
  - CONFIG_EVENT not selected
* add sha384/512 on certificate revocation

Others:
* factor out the user input handling in bootmenu command
diff --git a/cmd/gpt.c b/cmd/gpt.c
index 1c0525f..007a68e 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -586,6 +586,15 @@
 	return errno;
 }
 
+static int gpt_repair(struct blk_desc *blk_dev_desc)
+{
+	int ret = 0;
+
+	ret = gpt_repair_headers(blk_dev_desc);
+
+	return ret;
+}
+
 static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
 {
 	int ret;
@@ -997,7 +1006,10 @@
 		return CMD_RET_FAILURE;
 	}
 
-	if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
+	if (strcmp(argv[1], "repair") == 0) {
+		printf("Repairing GPT: ");
+		ret = gpt_repair(blk_dev_desc);
+	} else if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
 		printf("Writing GPT: ");
 		ret = gpt_default(blk_dev_desc, argv[4]);
 	} else if ((strcmp(argv[1], "verify") == 0)) {
@@ -1036,6 +1048,8 @@
 	" Restore or verify GPT information on a device connected\n"
 	" to interface\n"
 	" Example usage:\n"
+	" gpt repair mmc 0\n"
+	"    - repair the GPT on the device\n"
 	" gpt write mmc 0 $partitions\n"
 	"    - write the GPT to device\n"
 	" gpt verify mmc 0 $partitions\n"
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 8662bd2..7e9e654 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1544,14 +1544,6 @@
 #endif
 
 	ret = fdt_setprop_cell(fdt, nodeoffset, "phandle", phandle);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * For now, also set the deprecated "linux,phandle" property, so that we
-	 * don't break older kernels.
-	 */
-	ret = fdt_setprop_cell(fdt, nodeoffset, "linux,phandle", phandle);
 
 	return ret;
 }
diff --git a/disk/part_efi.c b/disk/part_efi.c
index f1f3e5b..829ccb6 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -705,6 +705,92 @@
 	return 0;
 }
 
+static void restore_primary_gpt_header(gpt_header *gpt_h, struct blk_desc *dev_desc)
+{
+	u32 calc_crc32;
+	u64 val;
+
+	/* recalculate the values for the Primary GPT Header */
+	val = le64_to_cpu(gpt_h->my_lba);
+	gpt_h->my_lba = gpt_h->alternate_lba;
+	gpt_h->alternate_lba = cpu_to_le64(val);
+	gpt_h->partition_entry_lba = cpu_to_le64(partition_entries_offset(dev_desc));
+
+	gpt_h->header_crc32 = 0;
+
+	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
+			       le32_to_cpu(gpt_h->header_size));
+	gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+}
+
+static int write_one_gpt_table(struct blk_desc *dev_desc,
+			       gpt_header *gpt_h, gpt_entry *gpt_e)
+{
+	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
+					   * sizeof(gpt_entry)), dev_desc);
+	lbaint_t start;
+	int ret = 0;
+
+	start = le64_to_cpu(gpt_h->my_lba);
+	if (blk_dwrite(dev_desc, start, 1, gpt_h) != 1) {
+		ret = -1;
+		goto out;
+	}
+
+	start = le64_to_cpu(gpt_h->partition_entry_lba);
+	if (blk_dwrite(dev_desc, start, pte_blk_cnt, gpt_e) != pte_blk_cnt) {
+		ret = -1;
+		goto out;
+	}
+
+ out:
+	return ret;
+}
+
+int gpt_repair_headers(struct blk_desc *dev_desc)
+{
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h1, 1, dev_desc->blksz);
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h2, 1, dev_desc->blksz);
+	gpt_entry *gpt_e1 = NULL, *gpt_e2 = NULL;
+	int is_gpt1_valid, is_gpt2_valid;
+	int ret = -1;
+
+	is_gpt1_valid = is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
+				     gpt_h1, &gpt_e1);
+	is_gpt2_valid = is_gpt_valid(dev_desc, dev_desc->lba - 1,
+				     gpt_h2, &gpt_e2);
+
+	if (is_gpt1_valid && is_gpt2_valid) {
+		ret = 0;
+		goto out;
+	}
+
+	if (is_gpt1_valid && !is_gpt2_valid) {
+		prepare_backup_gpt_header(gpt_h1);
+		ret = write_one_gpt_table(dev_desc, gpt_h1, gpt_e1);
+		goto out;
+	}
+
+	if (!is_gpt1_valid && is_gpt2_valid) {
+		restore_primary_gpt_header(gpt_h2, dev_desc);
+		ret = write_one_gpt_table(dev_desc, gpt_h2, gpt_e2);
+		goto out;
+	}
+
+	if (!is_gpt1_valid && !is_gpt2_valid) {
+		ret = -1;
+		goto out;
+	}
+
+ out:
+	if (is_gpt1_valid)
+		free(gpt_e1);
+	if (is_gpt2_valid)
+		free(gpt_e2);
+
+	return ret;
+}
+
 int gpt_verify_partitions(struct blk_desc *dev_desc,
 			  struct disk_partition *partitions, int parts,
 			  gpt_header *gpt_head, gpt_entry **gpt_pte)
diff --git a/include/part.h b/include/part.h
index 3a6958d..6f604e7 100644
--- a/include/part.h
+++ b/include/part.h
@@ -467,6 +467,16 @@
 		       gpt_entry **gpt_pte);
 
 /**
+ * gpt_repair_headers() - Function to repair the GPT's header
+ *                        and partition table entries (PTE)
+ *
+ * @param dev_desc - block device descriptor
+ *
+ * Return: - '0' on success, otherwise error
+ */
+int gpt_repair_headers(struct blk_desc *dev_desc);
+
+/**
  * gpt_verify_partitions() - Function to check if partitions' name, start and
  *                           size correspond to '$partitions' env variable
  *
diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py
index 229d7eb..f707d9f 100644
--- a/test/py/tests/test_gpt.py
+++ b/test/py/tests/test_gpt.py
@@ -101,6 +101,16 @@
 @pytest.mark.boardspec('sandbox')
 @pytest.mark.buildconfigspec('cmd_gpt')
 @pytest.mark.requiredtool('sgdisk')
+def test_gpt_repair(state_disk_image, u_boot_console):
+    """Test the gpt repair command."""
+
+    u_boot_console.run_command('host bind 0 ' + state_disk_image.path)
+    output = u_boot_console.run_command('gpt repair host 0')
+    assert 'Repairing GPT: success!' in output
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_gpt')
+@pytest.mark.requiredtool('sgdisk')
 def test_gpt_guid(state_disk_image, u_boot_console):
     """Test the gpt guid command."""