// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2008 RuggedCom, Inc.
 * Richard Retanubun <RichardRetanubun@RuggedCom.com>
 */

/*
 * NOTE:
 *   when CONFIG_SYS_64BIT_LBA is not defined, lbaint_t is 32 bits; this
 *   limits the maximum size of addressable storage to < 2 tebibytes
 */

#define LOG_CATEGORY LOGC_FS

#include <blk.h>
#include <log.h>
#include <part.h>
#include <u-boot/uuid.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <asm/unaligned.h>
#include <command.h>
#include <fdtdec.h>
#include <ide.h>
#include <malloc.h>
#include <memalign.h>
#include <part_efi.h>
#include <dm/ofnode.h>
#include <linux/compiler.h>
#include <linux/ctype.h>
#include <linux/printk.h>
#include <u-boot/crc.h>

/* GUID for basic data partitons */
#if CONFIG_IS_ENABLED(EFI_PARTITION)
static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID;
#endif

/**
 * efi_crc32() - EFI version of crc32 function
 * @buf: buffer to calculate crc32 of
 * @len - length of buf
 *
 * Description: Returns EFI-style CRC32 value for @buf
 */
static inline u32 efi_crc32(const void *buf, u32 len)
{
	return crc32(0, buf, len);
}

/*
 * Private function prototypes
 */

static int pmbr_part_valid(struct partition *part);
static int is_pmbr_valid(legacy_mbr * mbr);
static int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head,
			gpt_entry **pgpt_pte);
static gpt_entry *alloc_read_gpt_entries(struct blk_desc *desc,
					 gpt_header *pgpt_head);
static int is_pte_valid(gpt_entry * pte);
static int find_valid_gpt(struct blk_desc *desc, gpt_header *gpt_head,
			  gpt_entry **pgpt_pte);

static char *print_efiname(gpt_entry *pte)
{
	static char name[PARTNAME_SZ + 1];
	int i;
	for (i = 0; i < PARTNAME_SZ; i++) {
		u8 c;
		c = pte->partition_name[i] & 0xff;
		c = (c && !isprint(c)) ? '.' : c;
		name[i] = c;
	}
	name[PARTNAME_SZ] = 0;
	return name;
}

static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID;

static int get_bootable(gpt_entry *p)
{
	int ret = 0;

	if (!memcmp(&p->partition_type_guid, &system_guid, sizeof(efi_guid_t)))
		ret |=  PART_EFI_SYSTEM_PARTITION;
	if (p->attributes.fields.legacy_bios_bootable)
		ret |=  PART_BOOTABLE;
	return ret;
}

static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
		lbaint_t lastlba)
{
	uint32_t crc32_backup = 0;
	uint32_t calc_crc32;

	/* Check the GPT header signature */
	if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE_UBOOT) {
		log_debug("%s signature is wrong: %#llX != %#llX\n",
			  "GUID Partition Table Header",
			  le64_to_cpu(gpt_h->signature),
			  GPT_HEADER_SIGNATURE_UBOOT);
		return -1;
	}

	/* Check the GUID Partition Table CRC */
	memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup));
	memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32));

	calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
		le32_to_cpu(gpt_h->header_size));

	memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup));

	if (calc_crc32 != le32_to_cpu(crc32_backup)) {
		log_debug("%s: CRC is wrong: %#x != %#x\n",
			  "GUID Partition Table Header",
			  le32_to_cpu(crc32_backup), calc_crc32);
		return -1;
	}

	/*
	 * Check that the my_lba entry points to the LBA that contains the GPT
	 */
	if (le64_to_cpu(gpt_h->my_lba) != lba) {
		log_debug("GPT: my_lba incorrect: %llX != " LBAF "\n",
			  le64_to_cpu(gpt_h->my_lba), lba);
		return -1;
	}

	/*
	 * Check that the first_usable_lba and that the last_usable_lba are
	 * within the disk.
	 */
	if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) {
		log_debug("GPT: first_usable_lba incorrect: %llX > " LBAF "\n",
			  le64_to_cpu(gpt_h->first_usable_lba), lastlba);
		return -1;
	}
	if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) {
		log_debug("GPT: last_usable_lba incorrect: %llX > " LBAF "\n",
			  le64_to_cpu(gpt_h->last_usable_lba), lastlba);
		return -1;
	}

	debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: "
	      LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba),
	      le64_to_cpu(gpt_h->last_usable_lba), lastlba);

	return 0;
}

static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
{
	uint32_t calc_crc32;

	/* Check the GUID Partition Table Entry Array CRC */
	calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
		le32_to_cpu(gpt_h->num_partition_entries) *
		le32_to_cpu(gpt_h->sizeof_partition_entry));

	if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) {
		log_debug("%s: %#x != %#x\n",
			  "GUID Partition Table Entry Array CRC is wrong",
			  le32_to_cpu(gpt_h->partition_entry_array_crc32),
			  calc_crc32);
		return -1;
	}

	return 0;
}

static void prepare_backup_gpt_header(gpt_header *gpt_h)
{
	uint32_t calc_crc32;
	uint64_t val;

	/* recalculate the values for the Backup 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(le64_to_cpu(gpt_h->last_usable_lba) + 1);
	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);
}

#if CONFIG_IS_ENABLED(EFI_PARTITION)
/*
 * Public Functions (include/part.h)
 */

/*
 * UUID is displayed as 32 hexadecimal digits, in 5 groups,
 * separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
 */
int get_disk_guid(struct blk_desc *desc, char *guid)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz);
	gpt_entry *gpt_pte = NULL;
	unsigned char *guid_bin;

	/* This function validates AND fills in the GPT header and PTE */
	if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1)
		return -EINVAL;

	guid_bin = gpt_head->disk_guid.b;
	uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID);

	/* Remember to free pte */
	free(gpt_pte);
	return 0;
}

void part_print_efi(struct blk_desc *desc)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz);
	gpt_entry *gpt_pte = NULL;
	int i = 0;
	unsigned char *uuid;

	/* This function validates AND fills in the GPT header and PTE */
	if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1)
		return;

	debug("%s: gpt-entry at %p\n", __func__, gpt_pte);

	printf("Part\tStart LBA\tEnd LBA\t\tName\n");
	printf("\tAttributes\n");
	printf("\tType GUID\n");
	printf("\tPartition GUID\n");

	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
		/* Skip invalid PTE */
		if (!is_pte_valid(&gpt_pte[i]))
			continue;

		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
			le64_to_cpu(gpt_pte[i].starting_lba),
			le64_to_cpu(gpt_pte[i].ending_lba),
			print_efiname(&gpt_pte[i]));
		printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
		uuid = (unsigned char *)gpt_pte[i].partition_type_guid.b;
		if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID))
			printf("\ttype:\t%pUl\n\t\t(%pUs)\n", uuid, uuid);
		else
			printf("\ttype:\t%pUl\n", uuid);
		uuid = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
		printf("\tguid:\t%pUl\n", uuid);
	}

	/* Remember to free pte */
	free(gpt_pte);
	return;
}

int part_get_info_efi(struct blk_desc *desc, int part,
		      struct disk_partition *info)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz);
	gpt_entry *gpt_pte = NULL;

	/* "part" argument must be at least 1 */
	if (part < 1) {
		log_debug("Invalid Argument(s)\n");
		return -EINVAL;
	}

	/* This function validates AND fills in the GPT header and PTE */
	if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1)
		return -EINVAL;

	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
	    !is_pte_valid(&gpt_pte[part - 1])) {
		log_debug("Invalid partition number %d\n", part);
		free(gpt_pte);
		return -EPERM;
	}

	/* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
	info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
	/* The ending LBA is inclusive, to calculate size, add 1 to it */
	info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
		     - info->start;
	info->blksz = desc->blksz;

	snprintf((char *)info->name, sizeof(info->name), "%s",
		 print_efiname(&gpt_pte[part - 1]));
	strcpy((char *)info->type, "U-Boot");
	info->bootable = get_bootable(&gpt_pte[part - 1]);
	if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
		uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b,
				(char *)disk_partition_uuid(info),
				UUID_STR_FORMAT_GUID);
	}
	if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) {
		uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
				(char *)disk_partition_type_guid(info),
				UUID_STR_FORMAT_GUID);
	}

	log_debug("start 0x" LBAF ", size 0x" LBAF ", name %s\n", info->start,
		  info->size, info->name);

	/* Remember to free pte */
	free(gpt_pte);
	return 0;
}

static int part_test_efi(struct blk_desc *desc)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, desc->blksz);

	/* Read legacy MBR from block 0 and validate it */
	if ((blk_dread(desc, 0, 1, (ulong *)legacymbr) != 1)
		|| (is_pmbr_valid(legacymbr) != 1)) {
		return -1;
	}
	return 0;
}

/**
 * set_protective_mbr(): Set the EFI protective MBR
 * @param desc - block device descriptor
 *
 * Return: - zero on success, otherwise error
 */
static int set_protective_mbr(struct blk_desc *desc)
{
	/* Setup the Protective MBR */
	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, p_mbr, 1, desc->blksz);
	if (p_mbr == NULL) {
		log_debug("calloc failed!\n");
		return -ENOMEM;
	}

	/* Read MBR to backup boot code if it exists */
	if (blk_dread(desc, 0, 1, p_mbr) != 1) {
		log_debug("** Can't read from device %d **\n",
			  desc->devnum);
		return -EIO;
	}

	/* Clear all data in MBR except of backed up boot code */
	memset((char *)p_mbr + MSDOS_MBR_BOOT_CODE_SIZE, 0, sizeof(*p_mbr) -
			MSDOS_MBR_BOOT_CODE_SIZE);

	/* Append signature */
	p_mbr->signature = MSDOS_MBR_SIGNATURE;
	p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
	p_mbr->partition_record[0].start_sect = 1;
	p_mbr->partition_record[0].nr_sects = (u32)desc->lba - 1;

	/* Write MBR sector to the MMC device */
	if (blk_dwrite(desc, 0, 1, p_mbr) != 1) {
		log_debug("** Can't write to device %d **\n", desc->devnum);
		return -EIO;
	}

	return 0;
}

int write_gpt_table(struct blk_desc *desc, gpt_header *gpt_h, gpt_entry *gpt_e)
{
	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
					   * sizeof(gpt_entry)), desc);
	u32 calc_crc32;

	debug("max lba: %x\n", (u32)desc->lba);
	/* Setup the Protective MBR */
	if (set_protective_mbr(desc) < 0)
		goto err;

	/* Generate CRC for the Primary GPT Header */
	calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
			      le32_to_cpu(gpt_h->num_partition_entries) *
			      le32_to_cpu(gpt_h->sizeof_partition_entry));
	gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);

	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);

	/* Write the First GPT to the block right after the Legacy MBR */
	if (blk_dwrite(desc, 1, 1, gpt_h) != 1)
		goto err;

	if (blk_dwrite(desc, le64_to_cpu(gpt_h->partition_entry_lba),
		       pte_blk_cnt, gpt_e) != pte_blk_cnt)
		goto err;

	prepare_backup_gpt_header(gpt_h);

	if (blk_dwrite(desc, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)
		       + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt)
		goto err;

	if (blk_dwrite(desc, (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1,
		       gpt_h) != 1)
		goto err;

	debug("GPT successfully written to block device!\n");
	return 0;

 err:
	log_debug("** Can't write to device %d **\n", desc->devnum);
	return -EIO;
}

int gpt_fill_pte(struct blk_desc *desc,
		 gpt_header *gpt_h, gpt_entry *gpt_e,
		 struct disk_partition *partitions, int parts)
{
	lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba);
	lbaint_t last_usable_lba = (lbaint_t)
			le64_to_cpu(gpt_h->last_usable_lba);
	int i, k;
	size_t efiname_len, dosname_len;
	unsigned char *bin_uuid;
#ifdef CONFIG_PARTITION_TYPE_GUID
	char *str_type_guid;
	unsigned char *bin_type_guid;
#endif
	size_t hdr_start = gpt_h->my_lba;
	size_t hdr_end = hdr_start + 1;

	size_t pte_start = gpt_h->partition_entry_lba;
	size_t pte_end = pte_start +
		gpt_h->num_partition_entries * gpt_h->sizeof_partition_entry /
		desc->blksz;

	for (i = 0; i < parts; i++) {
		/* partition starting lba */
		lbaint_t start = partitions[i].start;
		lbaint_t size = partitions[i].size;

		if (start) {
			offset = start + size;
		} else {
			start = offset;
			offset += size;
		}

		/*
		 * If our partition overlaps with either the GPT
		 * header, or the partition entry, reject it.
		 */
		if (((start < hdr_end && hdr_start < (start + size)) ||
		     (start < pte_end && pte_start < (start + size)))) {
			log_debug("Partition overlap\n");
			return -ENOSPC;
		}

		gpt_e[i].starting_lba = cpu_to_le64(start);

		if (offset > (last_usable_lba + 1)) {
			log_debug("Partitions layout exceeds disk size\n");
			return -E2BIG;
		}
		/* partition ending lba */
		if ((i == parts - 1) && (size == 0))
			/* extend the last partition to maximuim */
			gpt_e[i].ending_lba = gpt_h->last_usable_lba;
		else
			gpt_e[i].ending_lba = cpu_to_le64(offset - 1);

#ifdef CONFIG_PARTITION_TYPE_GUID
		str_type_guid = partitions[i].type_guid;
		bin_type_guid = gpt_e[i].partition_type_guid.b;
		if (strlen(str_type_guid)) {
			if (uuid_str_to_bin(str_type_guid, bin_type_guid,
					    UUID_STR_FORMAT_GUID)) {
				log_debug("Partition no. %d: invalid type guid: %s\n",
					  i, str_type_guid);
				return -EINVAL;
			}
		} else {
			/* default partition type GUID */
			memcpy(bin_type_guid,
			       &partition_basic_data_guid, 16);
		}
#else
		/* partition type GUID */
		memcpy(gpt_e[i].partition_type_guid.b,
			&partition_basic_data_guid, 16);
#endif

		if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
			const char *str_uuid;

			str_uuid = disk_partition_uuid(&partitions[i]);
			bin_uuid = gpt_e[i].unique_partition_guid.b;

			if (uuid_str_to_bin(str_uuid, bin_uuid,
					    UUID_STR_FORMAT_GUID)) {
				log_debug("Partition no. %d: invalid guid: %s\n",
					  i, str_uuid);
				return -EINVAL;
			}
		}

		/* partition attributes */
		memset(&gpt_e[i].attributes, 0,
		       sizeof(gpt_entry_attributes));

		if (partitions[i].bootable & PART_BOOTABLE)
			gpt_e[i].attributes.fields.legacy_bios_bootable = 1;

		/* partition name */
		efiname_len = sizeof(gpt_e[i].partition_name)
			/ sizeof(efi_char16_t);
		dosname_len = sizeof(partitions[i].name);

		memset(gpt_e[i].partition_name, 0,
		       sizeof(gpt_e[i].partition_name));

		for (k = 0; k < min(dosname_len, efiname_len); k++)
			gpt_e[i].partition_name[k] =
				(efi_char16_t)(partitions[i].name[k]);

		debug("%s: name: %s offset[%d]: 0x" LBAF
		      " size[%d]: 0x" LBAF "\n",
		      __func__, partitions[i].name, i,
		      offset, i, size);
	}

	return 0;
}

static uint32_t partition_entries_offset(struct blk_desc *desc)
{
	uint32_t offset_blks = 2;
	uint32_t __maybe_unused offset_bytes;
	int __maybe_unused config_offset;

#if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF)
	/*
	 * Some architectures require their SPL loader at a fixed
	 * address within the first 16KB of the disk.  To avoid an
	 * overlap with the partition entries of the EFI partition
	 * table, the first safe offset (in bytes, from the start of
	 * the disk) for the entries can be set in
	 * CONFIG_EFI_PARTITION_ENTRIES_OFF.
	 */
	offset_bytes =
		PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, desc);
	offset_blks = offset_bytes / desc->blksz;
#endif

#if defined(CONFIG_OF_CONTROL)
	/*
	 * Allow the offset of the first partition entires (in bytes
	 * from the start of the device) to be specified as a property
	 * of the device tree '/config' node.
	 */
	config_offset = ofnode_conf_read_int(
		"u-boot,efi-partition-entries-offset", -EINVAL);
	if (config_offset != -EINVAL) {
		offset_bytes = PAD_TO_BLOCKSIZE(config_offset, desc);
		offset_blks = offset_bytes / desc->blksz;
	}
#endif

	debug("efi: partition entries offset (in blocks): %d\n", offset_blks);

	/*
	 * The earliest LBA this can be at is LBA#2 (i.e. right behind
	 * the (protective) MBR and the GPT header.
	 */
	if (offset_blks < 2)
		offset_blks = 2;

	return offset_blks;
}

int gpt_fill_header(struct blk_desc *desc, gpt_header *gpt_h, char *str_guid,
		    int parts_count)
{
	gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE_UBOOT);
	gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
	gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
	gpt_h->my_lba = cpu_to_le64(1);
	gpt_h->alternate_lba = cpu_to_le64(desc->lba - 1);
	gpt_h->last_usable_lba = cpu_to_le64(desc->lba - 34);
	gpt_h->partition_entry_lba =
		cpu_to_le64(partition_entries_offset(desc));
	gpt_h->first_usable_lba =
		cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32);
	gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
	gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
	gpt_h->header_crc32 = 0;
	gpt_h->partition_entry_array_crc32 = 0;

	if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID))
		return -1;

	return 0;
}

int gpt_restore(struct blk_desc *desc, char *str_disk_guid,
		struct disk_partition *partitions, int parts_count)
{
	gpt_header *gpt_h;
	gpt_entry *gpt_e;
	int ret, size;

	size = PAD_TO_BLOCKSIZE(sizeof(gpt_header), desc);
	gpt_h = malloc_cache_aligned(size);
	if (gpt_h == NULL) {
		log_debug("calloc failed!\n");
		return -ENOMEM;
	}
	memset(gpt_h, 0, size);

	size = PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
				desc);
	gpt_e = malloc_cache_aligned(size);
	if (gpt_e == NULL) {
		log_debug("calloc failed!\n");
		free(gpt_h);
		return -ENOMEM;
	}
	memset(gpt_e, 0, size);

	/* Generate Primary GPT header (LBA1) */
	ret = gpt_fill_header(desc, gpt_h, str_disk_guid, parts_count);
	if (ret)
		goto err;

	/* Generate partition entries */
	ret = gpt_fill_pte(desc, gpt_h, gpt_e, partitions, parts_count);
	if (ret)
		goto err;

	/* Write GPT partition table */
	ret = write_gpt_table(desc, gpt_h, gpt_e);

err:
	free(gpt_e);
	free(gpt_h);
	return ret;
}

/**
 * gpt_convert_efi_name_to_char() - convert u16 string to char string
 *
 * TODO: this conversion only supports ANSI characters
 *
 * @s:	target buffer
 * @es:	u16 string to be converted
 * @n:	size of target buffer
 */
static void gpt_convert_efi_name_to_char(char *s, void *es, int n)
{
	char *ess = es;
	int i, j;

	memset(s, '\0', n);

	for (i = 0, j = 0; j < n; i += 2, j++) {
		s[j] = ess[i];
		if (!ess[i])
			return;
	}
}

int gpt_verify_headers(struct blk_desc *desc, gpt_header *gpt_head,
		       gpt_entry **gpt_pte)
{
	/*
	 * This function validates AND
	 * fills in the GPT header and PTE
	 */
	if (is_gpt_valid(desc,
			 GPT_PRIMARY_PARTITION_TABLE_LBA,
			 gpt_head, gpt_pte) != 1) {
		log_debug("Invalid GPT\n");
		return -1;
	}

	/* Free pte before allocating again */
	free(*gpt_pte);

	/*
	 * Check that the alternate_lba entry points to the last LBA
	 */
	if (le64_to_cpu(gpt_head->alternate_lba) != (desc->lba - 1)) {
		log_debug("Misplaced Backup GPT\n");
		return -1;
	}

	if (is_gpt_valid(desc, (desc->lba - 1),
			 gpt_head, gpt_pte) != 1) {
		log_debug("Invalid Backup GPT\n");
		return -1;
	}

	return 0;
}

static void restore_primary_gpt_header(gpt_header *gpt_h, struct blk_desc *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(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 *desc, gpt_header *gpt_h,
			       gpt_entry *gpt_e)
{
	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
					   * sizeof(gpt_entry)), desc);
	lbaint_t start;
	int ret = 0;

	start = le64_to_cpu(gpt_h->my_lba);
	if (blk_dwrite(desc, start, 1, gpt_h) != 1) {
		ret = -1;
		goto out;
	}

	start = le64_to_cpu(gpt_h->partition_entry_lba);
	if (blk_dwrite(desc, start, pte_blk_cnt, gpt_e) != pte_blk_cnt) {
		ret = -1;
		goto out;
	}

 out:
	return ret;
}

int gpt_repair_headers(struct blk_desc *desc)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h1, 1, desc->blksz);
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h2, 1, 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(desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
				     gpt_h1, &gpt_e1);
	is_gpt2_valid = is_gpt_valid(desc, 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(desc, gpt_h1, gpt_e1);
		goto out;
	}

	if (!is_gpt1_valid && is_gpt2_valid) {
		restore_primary_gpt_header(gpt_h2, desc);
		ret = write_one_gpt_table(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 *desc,
			  struct disk_partition *partitions, int parts,
			  gpt_header *gpt_head, gpt_entry **gpt_pte)
{
	char efi_str[PARTNAME_SZ + 1];
	u64 gpt_part_size;
	gpt_entry *gpt_e;
	int ret, i;

	ret = gpt_verify_headers(desc, gpt_head, gpt_pte);
	if (ret)
		return ret;

	gpt_e = *gpt_pte;

	for (i = 0; i < parts; i++) {
		if (i == gpt_head->num_partition_entries) {
			pr_err("More partitions than allowed!\n");
			return -1;
		}

		/* Check if GPT and ENV partition names match */
		gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name,
					     PARTNAME_SZ + 1);

		debug("%s: part: %2d name - GPT: %16s, ENV: %16s ",
		      __func__, i, efi_str, partitions[i].name);

		if (strncmp(efi_str, (char *)partitions[i].name,
			    sizeof(partitions->name))) {
			pr_err("Partition name: %s does not match %s!\n",
			      efi_str, (char *)partitions[i].name);
			return -1;
		}

		/* Check if GPT and ENV sizes match */
		gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) -
			le64_to_cpu(gpt_e[i].starting_lba) + 1;
		debug("size(LBA) - GPT: %8llu, ENV: %8llu ",
		      (unsigned long long)gpt_part_size,
		      (unsigned long long)partitions[i].size);

		if (le64_to_cpu(gpt_part_size) != partitions[i].size) {
			/* We do not check the extend partition size */
			if ((i == parts - 1) && (partitions[i].size == 0))
				continue;

			pr_err("Partition %s size: %llu does not match %llu!\n",
			      efi_str, (unsigned long long)gpt_part_size,
			      (unsigned long long)partitions[i].size);
			return -1;
		}

		/*
		 * Start address is optional - check only if provided
		 * in '$partition' variable
		 */
		if (!partitions[i].start) {
			debug("\n");
			continue;
		}

		/* Check if GPT and ENV start LBAs match */
		debug("start LBA - GPT: %8llu, ENV: %8llu\n",
		      le64_to_cpu(gpt_e[i].starting_lba),
		      (unsigned long long)partitions[i].start);

		if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) {
			pr_err("Partition %s start: %llu does not match %llu!\n",
			      efi_str, le64_to_cpu(gpt_e[i].starting_lba),
			      (unsigned long long)partitions[i].start);
			return -1;
		}
	}

	return 0;
}

int is_valid_gpt_buf(struct blk_desc *desc, void *buf)
{
	gpt_header *gpt_h;
	gpt_entry *gpt_e;

	/* determine start of GPT Header in the buffer */
	gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * desc->blksz);
	if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA,
				desc->lba))
		return -1;

	/* determine start of GPT Entries in the buffer */
	gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
		       desc->blksz);
	if (validate_gpt_entries(gpt_h, gpt_e))
		return -1;

	return 0;
}

int write_mbr_and_gpt_partitions(struct blk_desc *desc, void *buf)
{
	gpt_header *gpt_h;
	gpt_entry *gpt_e;
	int gpt_e_blk_cnt;
	lbaint_t lba;
	int cnt;

	if (is_valid_gpt_buf(desc, buf))
		return -1;

	/* determine start of GPT Header in the buffer */
	gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * desc->blksz);

	/* determine start of GPT Entries in the buffer */
	gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) * desc->blksz);
	gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
				   le32_to_cpu(gpt_h->sizeof_partition_entry)),
				  desc);

	/* write MBR */
	lba = 0;	/* MBR is always at 0 */
	cnt = 1;	/* MBR (1 block) */
	if (blk_dwrite(desc, lba, cnt, buf) != cnt) {
		log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n",
			  "MBR", cnt, lba);
		return 1;
	}

	/* write Primary GPT */
	lba = GPT_PRIMARY_PARTITION_TABLE_LBA;
	cnt = 1;	/* GPT Header (1 block) */
	if (blk_dwrite(desc, lba, cnt, gpt_h) != cnt) {
		log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n",
			  "Primary GPT Header", cnt, lba);
		return 1;
	}

	lba = le64_to_cpu(gpt_h->partition_entry_lba);
	cnt = gpt_e_blk_cnt;
	if (blk_dwrite(desc, lba, cnt, gpt_e) != cnt) {
		log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n",
			  "Primary GPT Entries", cnt, lba);
		return 1;
	}

	prepare_backup_gpt_header(gpt_h);

	/* write Backup GPT */
	lba = le64_to_cpu(gpt_h->partition_entry_lba);
	cnt = gpt_e_blk_cnt;
	if (blk_dwrite(desc, lba, cnt, gpt_e) != cnt) {
		log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n",
			  "Backup GPT Entries", cnt, lba);
		return 1;
	}

	lba = le64_to_cpu(gpt_h->my_lba);
	cnt = 1;	/* GPT Header (1 block) */
	if (blk_dwrite(desc, lba, cnt, gpt_h) != cnt) {
		log_debug("failed writing '%s' (%d blks at 0x" LBAF ")\n",
			  "Backup GPT Header", cnt, lba);
		return 1;
	}

	/* Update the partition table entries*/
	part_init(desc);

	return 0;
}
#endif

/*
 * Private functions
 */
/*
 * pmbr_part_valid(): Check for EFI partition signature
 *
 * Returns: 1 if EFI GPT partition type is found.
 */
static int pmbr_part_valid(struct partition *part)
{
	if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
		get_unaligned_le32(&part->start_sect) == 1UL) {
		return 1;
	}

	return 0;
}

/*
 * is_pmbr_valid(): test Protective MBR for validity
 *
 * @mbr: Pointer to Master Boot-Record data
 *
 * Returns: 1 if PMBR is valid, 0 otherwise.
 * Validity depends on two things:
 *  1) MSDOS signature is in the last two bytes of the MBR
 *  2) One partition of type 0xEE is found, checked by pmbr_part_valid()
 */
static int is_pmbr_valid(legacy_mbr *mbr)
{
	uint sig = le16_to_cpu(mbr->signature);
	int i = 0;

	if (sig != MSDOS_MBR_SIGNATURE) {
		log_debug("Invalid signature %x\n", sig);
		return 0;
	}
	log_debug("Signature %x valid\n", sig);

	for (i = 0; i < 4; i++) {
		if (pmbr_part_valid(&mbr->partition_record[i])) {
			return 1;
		}
	}
	return 0;
}

/**
 * is_gpt_valid() - tests one GPT header and PTEs for validity
 *
 * lba is the logical block address of the GPT header to test
 * gpt is a GPT header ptr, filled on return.
 * ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if valid,  0 on error, 2 if ignored header
 * If valid, returns pointers to PTEs.
 */
static int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head,
			gpt_entry **pgpt_pte)
{
	/* Confirm valid arguments prior to allocation. */
	if (!desc || !pgpt_head) {
		log_debug("Invalid Argument(s)\n");
		return 0;
	}

	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, mbr, 1, desc->blksz);

	/* Read MBR Header from device */
	if (blk_dread(desc, 0, 1, (ulong *)mbr) != 1) {
		log_debug("Can't read MBR header\n");
		return 0;
	}

	/* Read GPT Header from device */
	if (blk_dread(desc, (lbaint_t)lba, 1, pgpt_head) != 1) {
		log_debug("Can't read GPT header\n");
		return 0;
	}

	/* Invalid but nothing to yell about. */
	if (le64_to_cpu(pgpt_head->signature) == GPT_HEADER_CHROMEOS_IGNORE) {
		log_debug("ChromeOS 'IGNOREME' GPT header found and ignored\n");
		return 2;
	}

	if (validate_gpt_header(pgpt_head, (lbaint_t)lba, desc->lba))
		return 0;

	if (desc->sig_type == SIG_TYPE_NONE) {
		efi_guid_t empty = {};
		if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) {
			desc->sig_type = SIG_TYPE_GUID;
			memcpy(&desc->guid_sig, &pgpt_head->disk_guid,
			       sizeof(empty));
		} else if (mbr->unique_mbr_signature != 0) {
			desc->sig_type = SIG_TYPE_MBR;
			desc->mbr_sig = mbr->unique_mbr_signature;
		}
	}

	/* Read and allocate Partition Table Entries */
	*pgpt_pte = alloc_read_gpt_entries(desc, pgpt_head);
	if (!*pgpt_pte)
		return 0;

	if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
		free(*pgpt_pte);
		return 0;
	}

	/* We're done, all's well */
	return 1;
}

/**
 * find_valid_gpt() - finds a valid GPT header and PTEs
 *
 * gpt is a GPT header ptr, filled on return.
 * ptes is a PTEs ptr, filled on return.
 *
 * Description: returns 1 if found a valid gpt,  0 on error.
 * If valid, returns pointers to PTEs.
 */
static int find_valid_gpt(struct blk_desc *desc, gpt_header *gpt_head,
			  gpt_entry **pgpt_pte)
{
	int r;

	r = is_gpt_valid(desc, GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_head,
			 pgpt_pte);

	if (r != 1) {
		if (r != 2)
			log_debug("Invalid GPT\n");

		if (is_gpt_valid(desc, desc->lba - 1, gpt_head, pgpt_pte)
		    != 1) {
			log_debug("Invalid Backup GPT\n");
			return 0;
		}
		if (r != 2)
			log_debug("        Using Backup GPT\n");
	}
	return 1;
}

/**
 * alloc_read_gpt_entries(): reads partition entries from disk
 * @desc
 * @gpt - GPT header
 *
 * Description: Returns ptes on success,  NULL on error.
 * Allocates space for PTEs based on information found in @gpt.
 * Notes: remember to free pte when you're done!
 */
static gpt_entry *alloc_read_gpt_entries(struct blk_desc *desc,
					 gpt_header *pgpt_head)
{
	size_t count = 0, blk_cnt;
	lbaint_t blk;
	gpt_entry *pte = NULL;

	if (!desc || !pgpt_head) {
		log_debug("Invalid Argument(s)\n");
		return NULL;
	}

	count = le32_to_cpu(pgpt_head->num_partition_entries) *
		le32_to_cpu(pgpt_head->sizeof_partition_entry);

	log_debug("count = %u * %u = %lu\n",
		  (u32)le32_to_cpu(pgpt_head->num_partition_entries),
		  (u32)le32_to_cpu(pgpt_head->sizeof_partition_entry),
		  (ulong)count);

	/* Allocate memory for PTE, remember to FREE */
	if (count != 0) {
		pte = memalign(ARCH_DMA_MINALIGN,
			       PAD_TO_BLOCKSIZE(count, desc));
	}

	if (count == 0 || pte == NULL) {
		log_debug("ERROR: Can't allocate %#lX bytes for GPT Entries\n",
			  (ulong)count);
		return NULL;
	}

	/* Read GPT Entries from device */
	blk = le64_to_cpu(pgpt_head->partition_entry_lba);
	blk_cnt = BLOCK_CNT(count, desc);
	if (blk_dread(desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) {
		log_debug("Can't read GPT Entries\n");
		free(pte);
		return NULL;
	}
	return pte;
}

/**
 * is_pte_valid(): validates a single Partition Table Entry
 * @gpt_entry - Pointer to a single Partition Table Entry
 *
 * Description: returns 1 if valid,  0 on error.
 */
static int is_pte_valid(gpt_entry * pte)
{
	efi_guid_t unused_guid;

	if (!pte) {
		log_debug("Invalid Argument(s)\n");
		return 0;
	}

	/* Only one validation for now:
	 * The GUID Partition Type != Unused Entry (ALL-ZERO)
	 */
	memset(unused_guid.b, 0, sizeof(unused_guid.b));

	if (memcmp(pte->partition_type_guid.b, unused_guid.b,
		sizeof(unused_guid.b)) == 0) {

		log_debug("Found an unused PTE GUID at 0x%08X\n",
			  (unsigned int)(uintptr_t)pte);

		return 0;
	} else {
		return 1;
	}
}

/*
 * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to
 * check EFI first, since a DOS partition is often used as a 'protective MBR'
 * with EFI.
 */
U_BOOT_PART_TYPE(a_efi) = {
	.name		= "EFI",
	.part_type	= PART_TYPE_EFI,
	.max_entries	= GPT_ENTRY_NUMBERS,
	.get_info	= part_get_info_ptr(part_get_info_efi),
	.print		= part_print_ptr(part_print_efi),
	.test		= part_test_efi,
};
