/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of The Linux Foundation nor
 *       the names of its contributors may be used to endorse or promote
 *       products derived from this software without specific prior written
 *       permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#include <stdlib.h>
#include <string.h>
#include <crc32.h>
#include <ab_partition_parser.h>
#include <partition_parser.h>
#include <boot_device.h>
#if defined(MMC_SDHCI_SUPPORT) || defined(UFS_SUPPORT)
#include <mmc_wrapper.h>
#include <ufs.h>
#endif

//#define AB_DEBUG

/* Slot suffix */
const char *suffix_slot[] = {"_a",
		"_b"};
const char *suffix_delimiter = "_";

/* local global variables */
static signed active_slot;		/* to store current active slot */
static bool attributes_updated;		/* to store if we need to update partition table */
static bool multislot_support;		/* to store if multislot support is present */

static int boot_slot_index[AB_SUPPORTED_SLOTS];	/* store index for boot parition */

/* local functions. */
static void attributes_update();
static void mark_all_partitions_active(signed slot);
/*
	Function: To read slot attribute of
		of the partition_entry
*/
inline bool slot_is_active(struct partition_entry *partition_entries,
					unsigned index)
{
	if ((partition_entries[index].attribute_flag &
		PART_ATT_ACTIVE_VAL)>>PART_ATT_ACTIVE_BIT)
		return true;
	else
		return false;
}

inline bool slot_is_sucessful(struct partition_entry *partition_entries,
						unsigned index)
{
	if ((partition_entries[index].attribute_flag &
		PART_ATT_SUCCESSFUL_VAL)>>PART_ATT_SUCCESS_BIT)
		return true;
	else
		return false;
}

inline unsigned slot_retry_count(struct partition_entry *partition_entries,
						unsigned index)
{
	return ((partition_entries[index].attribute_flag
		& PART_ATT_MAX_RETRY_COUNT_VAL) >> PART_ATT_MAX_RETRY_CNT_BIT);
}

inline unsigned slot_priority(struct partition_entry *partition_entries,
						unsigned index)
{
	return ((partition_entries[index].attribute_flag
		& PART_ATT_PRIORITY_VAL)>>PART_ATT_PRIORITY_BIT);
}

inline bool slot_is_bootable(struct partition_entry *partition_entries,
						unsigned index)
{
	if ((partition_entries[index].attribute_flag &
		PART_ATT_UNBOOTABLE_VAL)>>PART_ATT_UNBOOTABLE_BIT)
		return false;
	else
		return true;
}

void
partition_deactivate_slot(int slot)
{
	struct partition_entry *partition_entries =
			partition_get_partition_entries();
	int slt_index = boot_slot_index[slot];

	/* Set Unbootable bit */
	SET_BIT(partition_entries[slt_index].attribute_flag, PART_ATT_UNBOOTABLE_BIT);

	/* Clear Sucess bit and Active bits */
	CLR_BIT(partition_entries[slt_index].attribute_flag, PART_ATT_SUCCESS_BIT);
	CLR_BIT(partition_entries[slt_index].attribute_flag, PART_ATT_ACTIVE_BIT);

	/* Clear Max retry count and priority value */
	partition_entries[slt_index].attribute_flag &= (~PART_ATT_PRIORITY_VAL &
							~PART_ATT_MAX_RETRY_COUNT_VAL);

	return;
}

void
partition_activate_slot(int slot)
{
	struct partition_entry *partition_entries =
			partition_get_partition_entries();
	int slt_index = boot_slot_index[slot];

	/* CLR Unbootable bit and Sucess bit*/
	CLR_BIT(partition_entries[slt_index].attribute_flag, PART_ATT_UNBOOTABLE_BIT);
	CLR_BIT(partition_entries[slt_index].attribute_flag, PART_ATT_SUCCESS_BIT);

	/* Set Active bits */
	SET_BIT(partition_entries[slt_index].attribute_flag, PART_ATT_ACTIVE_BIT);

	/* Set Max retry count and priority value */
	partition_entries[slt_index].attribute_flag |= (PART_ATT_PRIORITY_VAL |
							PART_ATT_MAX_RETRY_COUNT_VAL);

	return;
}

/*
	Function scan boot partition to find SLOT_A/SLOT_B suffix.
	If found than make multislot_boot flag true and
	scans another partition.
*/
bool partition_scan_for_multislot()
{
	int i, j, count = 0;
	char *pname = NULL;
	int strlen_boot = strlen("boot");
	int partition_count = partition_get_partition_count();
	struct partition_entry *partition_entries =
				partition_get_partition_entries();

	/* Intialize all slot specific variables */
	multislot_support = false;
	active_slot = INVALID;
	attributes_updated = false;

	if (partition_count > NUM_PARTITIONS)
	{
		dprintf(CRITICAL, "ERROR: partition_count more than supported.\n");
		return multislot_support;
	}

	for (i = 0; i < partition_count; i++)
	{
		pname = (char *)partition_entries[i].name;
#ifdef AB_DEBUG
		dprintf(INFO, "Transversing partition %s\n", pname);
#endif
		if (!strncmp((const char *)partition_entries[i].name, "boot", strlen_boot))
		{
			pname += strlen_boot;
			if (*pname)
			{
#ifdef AB_DEBUG
		dprintf(INFO, "Suffix: %s\n", pname);
#endif
				for (j =0; j<AB_SUPPORTED_SLOTS; j++)
				{
					if (!strcmp(pname, suffix_slot[j]))
					{
						/* cache these variables as they are used multiple times */
						boot_slot_index[j] = i;
						if (!multislot_support)
							multislot_support =true;
						count ++;
					}
				}
				/* Break out of loop if all slot index are found*/
				if (count == AB_SUPPORTED_SLOTS)
					break;
			}
			else
			{
#ifdef AB_DEBUG
		dprintf(INFO, "Partition Table is not a/b supported\n");
#endif
				break;
			}
		}
	}
	return multislot_support;
}

/*
	Function: To reset partition attributes
	This function reset partition_priority, retry_count
	and clear successful and bootable bits.
*/
void partition_reset_attributes(unsigned index)
{
	struct partition_entry *partition_entries =
					partition_get_partition_entries();

	partition_entries[index].attribute_flag |= (PART_ATT_PRIORITY_VAL |
				PART_ATT_MAX_RETRY_COUNT_VAL);

	partition_entries[index].attribute_flag &= ((~PART_ATT_SUCCESSFUL_VAL) &
						(~PART_ATT_UNBOOTABLE_VAL));

	if (!attributes_updated)
		attributes_updated = true;

	/* Make attributes persistant */
	partition_mark_active_slot(active_slot);
}

/*
	Function: Switch active partitions.
*/
void partition_switch_slots(int old_slot, int new_slot, boolean reset_success_bit)
{
#ifdef AB_DEBUG
	dprintf(INFO, "Switching slots %s to %s\n",
				SUFFIX_SLOT(old_slot), SUFFIX_SLOT(new_slot));
#endif
	struct partition_entry *partition_entries =
					partition_get_partition_entries();
	int old_slot_index = boot_slot_index[old_slot];
	int new_slot_index = boot_slot_index[new_slot];

	/* Mark current slot inactive, keeping all other attributes intact */
	partition_entries[old_slot_index].attribute_flag &= ~PART_ATT_ACTIVE_VAL;

	/* Mark new slot active */
	partition_entries[new_slot_index].attribute_flag |=
						((PART_ATT_PRIORITY_VAL |
						PART_ATT_ACTIVE_VAL |
						PART_ATT_MAX_RETRY_COUNT_VAL));

	partition_entries[new_slot_index].attribute_flag &=
						(~PART_ATT_UNBOOTABLE_VAL);
	if (reset_success_bit &&
		(partition_entries[new_slot_index].attribute_flag &
						PART_ATT_SUCCESSFUL_VAL)) {
		partition_entries[new_slot_index].attribute_flag &=
						(~PART_ATT_SUCCESSFUL_VAL);
	}

	if (!attributes_updated)
		attributes_updated = true;

	/* Update active slot and gpt table */
	partition_mark_active_slot(new_slot);
	return;
}

/*
	This function returns the most priority and active slot,
	also you need to update the global state seperately.

*/
int partition_find_active_slot()
{
	unsigned current_priority;
	int i, count = 0;
	bool current_bootable_bit;
	bool current_active_bit;
	unsigned boot_priority;
	struct partition_entry *partition_entries = partition_get_partition_entries();

#ifdef AB_DEBUG
	dprintf(INFO, "partition_find_active_slot() called\n");
#endif
	/* Return current active slot if already found */
	if (active_slot != INVALID)
		goto out;

	for (boot_priority = MAX_PRIORITY;
			boot_priority > 0; boot_priority--)
	{
		/* Search valid boot slot with highest priority */
		for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
		{
			current_priority = slot_priority(partition_entries, boot_slot_index[i]);
			current_active_bit = slot_is_active(partition_entries, boot_slot_index[i]);
			current_bootable_bit = slot_is_bootable(partition_entries, boot_slot_index[i]);

			/* Count number of slots with all attributes as zero */
			if ( !current_priority &&
				!current_active_bit &&
				current_bootable_bit)
			{
				count ++;
				continue;
			}

#ifdef AB_DEBUG
	dprintf(INFO, "Slot:Priority:Active:Bootable %s:%d:%d:%d \n",
						partition_entries[boot_slot_index[i]].name,
						current_priority,
						current_active_bit,
						current_bootable_bit);
#endif
			if (boot_priority == current_priority)
			{
				if (current_active_bit &&
					current_bootable_bit)
				{
#ifdef AB_DEBUG
	dprintf(INFO, "Slot (%s) is Valid High Priority Slot\n", SUFFIX_SLOT(i));
#endif
					active_slot = i;
					goto out;
				}
			}
		}

		/* All slots are zeroed, this is first bootup */
		/* Marking and trying SLOT 0 as default */
		if (count == AB_SUPPORTED_SLOTS)
		{
			/* Update the priority of the boot slot */
			partition_activate_slot(SLOT_A);

			active_slot = SLOT_A;

			/* This is required to mark all bits as active,
			for fresh boot post fresh flash */
			mark_all_partitions_active(active_slot);
			goto out;
		}
	}
out:
	return active_slot;
}

static int
next_active_bootable_slot(struct partition_entry *ptn_entry)
{
	int i, slt_index;
	for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
	{
		slt_index = boot_slot_index[i];
		if (slot_is_bootable(ptn_entry, slt_index) &&
					slot_is_sucessful(ptn_entry, slt_index))
			return i;
	}

	dprintf(CRITICAL, "ERROR: Unable to find any bootable slot");
	return INVALID;
}

int partition_find_boot_slot()
{
	int boot_slot, next_slot;
	int slt_index;
	uint64_t boot_retry_count;
	struct partition_entry *partition_entries = partition_get_partition_entries();

	boot_retry_count = 0;
	boot_slot = partition_find_active_slot();

	if (boot_slot == INVALID)
		goto out;

	slt_index = boot_slot_index[boot_slot];

	/*  Boot if partition flag is set to sucessful */
	if (partition_entries[slt_index].attribute_flag & PART_ATT_SUCCESSFUL_VAL)
		goto out;

	boot_retry_count = slot_retry_count(partition_entries, slt_index);

#ifdef AB_DEBUG
	dprintf(INFO, "Boot Partition:RetryCount %s:%lld\n", partition_entries[slt_index].name,
							boot_retry_count);
#endif
	if (!boot_retry_count)
	{
		/* Mark slot invalid and unbootable */
		partition_deactivate_slot(boot_slot);

		next_slot = next_active_bootable_slot(partition_entries);
		if (next_slot != INVALID)
		{
			partition_switch_slots(boot_slot, next_slot, false);
			reboot_device(0);
		}
		else
		{
			boot_slot = INVALID;
		}
	}
	else
	{
		/* Do normal boot */
		/* Decrement retry count */
		partition_entries[slt_index].attribute_flag =
					(partition_entries[slt_index].attribute_flag
					& ~PART_ATT_MAX_RETRY_COUNT_VAL)
					| ((boot_retry_count-1) << PART_ATT_MAX_RETRY_CNT_BIT);

		if (!attributes_updated)
			attributes_updated = true;

		goto out;
	}

out:
#ifdef AB_DEBUG
	dprintf(INFO, "Booting SLOT %d\n", boot_slot);
#endif
	return boot_slot;
}

static
void guid_update(struct partition_entry *partition_entries,
		unsigned old_index,
		unsigned new_index)
{
	unsigned char tmp_guid[PARTITION_TYPE_GUID_SIZE];

#ifdef AB_DEBUG
	dprintf(INFO, "Swapping GUID (%s) --> (%s) \n",
			partition_entries[old_index].name,
			partition_entries[new_index].name);
#endif
	memcpy(tmp_guid, partition_entries[old_index].type_guid,
				PARTITION_TYPE_GUID_SIZE);
	memcpy(partition_entries[old_index].type_guid,
			partition_entries[new_index].type_guid,
			PARTITION_TYPE_GUID_SIZE);
	memcpy(partition_entries[new_index].type_guid, tmp_guid,
				PARTITION_TYPE_GUID_SIZE);
	return;
}

/*
	Function to swap guids of slots
*/
static void
swap_guid(int old_slot,	int new_slot)
{
	unsigned i, j, tmp_strlen;
	unsigned partition_cnt = partition_get_partition_count();
	struct partition_entry *partition_entries =
			partition_get_partition_entries();
	const char *ptr_pname, *ptr_suffix;

	if ( old_slot == new_slot)
		return;

	for(i = 0; i < partition_cnt; i++)
	{
		ptr_pname = (const char *)partition_entries[i].name;

	        /* Search for suffix in partition name */
		if ((ptr_suffix = strstr(ptr_pname, SUFFIX_SLOT(new_slot))))
		{
			for (j = i+1; j < partition_cnt; j++)
			{
				tmp_strlen = strlen(ptr_pname)-strlen(SUFFIX_SLOT(new_slot));
				if (!strncmp((const char*)partition_entries[j].name, ptr_pname, tmp_strlen) &&
					strstr((const char*)partition_entries[j].name, SUFFIX_SLOT(old_slot)))
					guid_update(partition_entries, j, i);
			}
		}
		else if ((ptr_suffix = strstr(ptr_pname, SUFFIX_SLOT(old_slot))))
		{
			for (j = i+1; j < partition_cnt; j++)
			{
				tmp_strlen = strlen(ptr_pname)-strlen(SUFFIX_SLOT(old_slot));
				if (!strncmp((const char *)partition_entries[j].name, ptr_pname, tmp_strlen) &&
					strstr((const char *)partition_entries[j].name, SUFFIX_SLOT(new_slot)))
					guid_update(partition_entries, i, j);
			}
		}
	}
}

/*
Function: To set active bit of all partitions of actve slot.
	also, unset active bits of all other slot
*/
static void
mark_all_partitions_active(signed slot)
{
	int i,j;
	char *pname = NULL;
	char *suffix_str = NULL;
	struct partition_entry *partition_entries =
				partition_get_partition_entries();
	int partition_count = partition_get_partition_count();

	for (i=0; i<partition_count; i++)
	{
		pname = (char *)partition_entries[i].name;
#ifdef AB_DEBUG
	dprintf(INFO, "Transversing partition %s\n", pname);
#endif
		/* 1. Find partition, if it is A/B enabled. */
		for ( j = 0; j<AB_SUPPORTED_SLOTS; j++)
		{
			suffix_str = strstr(pname, SUFFIX_SLOT(j));
			if (suffix_str)
				break;
		}

		if (suffix_str)
		{
			if (!strcmp(suffix_str, SUFFIX_SLOT(slot)))
				/* 2a. Mark matching partition as active. */
				partition_entries[i].attribute_flag |= PART_ATT_ACTIVE_VAL;
			else
				/* 2b. Unset active bit for all other partitions. */
				partition_entries[i].attribute_flag &= ~PART_ATT_ACTIVE_VAL;
		}
	}
	attributes_updated = true;
}

/*
	Function: Mark the slot to be active and also conditionally
	update the slot parameters if there is a change.
*/
void partition_mark_active_slot(signed slot)
{
	if (active_slot == slot)
		goto out;

	if(slot != INVALID)
	{
		dprintf(INFO, "Marking (%s) as active\n", SUFFIX_SLOT(slot));

		/* 1. Swap GUID's to new slot */
		swap_guid(active_slot, slot);

		/* 2. Set Active bit for all partitions of active slot */
		mark_all_partitions_active(slot);
	}

	active_slot = slot;
out:
	if (attributes_updated)
		attributes_update();

	return;
}

/* Function to find if multislot is supported */
bool partition_multislot_is_supported()
{
	return multislot_support;
}

/*
	Function to populate partition meta used
	for fastboot get var info publication.

	Input partition_entries, partition_count and
	buffer to fill information.

*/
int partition_fill_partition_meta(char has_slot_pname[][MAX_GET_VAR_NAME_SIZE],
					char has_slot_reply[][MAX_RSP_SIZE],
					int array_size)
{
	int i,j,tmp;
	int count = 0;
	char *pname = NULL;
	int pname_size;
	struct partition_entry *partition_entries =
				partition_get_partition_entries();
	int partition_count = partition_get_partition_count();
	char *suffix_str;

	for (i=0; i<partition_count; i++)
	{
		pname = (char *)partition_entries[i].name;
		pname_size = strlen(pname);
		suffix_str = NULL;
 #ifdef AB_DEBUG
	dprintf(INFO, "Transversing partition %s\n", pname);
 #endif
		/* 1. Find partition, if it is A/B enabled. */
		for ( j = 0; j<AB_SUPPORTED_SLOTS; j++)
		{
			suffix_str = strstr(pname, SUFFIX_SLOT(j));
			if (suffix_str)
				break;
		}

		if (suffix_str)
		{
			if (!strcmp(suffix_str, SUFFIX_SLOT(SLOT_A)))
			{
				/* 2. put the partition name in array */
				tmp = pname_size-strlen(suffix_str);
				strlcpy(has_slot_pname[count], pname, tmp+1);
				strlcpy(has_slot_reply[count], "yes", MAX_RSP_SIZE);
				count++;
			}
		}
		else
		{
			strlcpy(has_slot_pname[count], pname, MAX_GET_VAR_NAME_SIZE);
			strlcpy(has_slot_reply[count], "no", MAX_RSP_SIZE);
			count++;
		}

		/* Avoid over population of array provided */
		if (count >= array_size)
		{
			dprintf(CRITICAL, "ERROR: Not able to parse all partitions\n");
			return count;
		}
	}
#ifdef AB_DEBUG
	for (i=0; i<count; i++)
		dprintf(INFO, "has-slot:%s:%s\n", has_slot_pname[i], has_slot_reply[i]);
#endif
	return count;
}

/*
	Function to populate the slot meta used
	for fastboot get var info publication.
*/
void partition_fill_slot_meta(struct ab_slot_info *slot_info)
{
	int i, current_slot_index;
	struct partition_entry *ptn_entries = partition_get_partition_entries();
	char buff[3];

	/* Update slot info */
	for(i=0; i<AB_SUPPORTED_SLOTS; i++)
	{
		current_slot_index = boot_slot_index[i];
		strlcpy(slot_info[i].slot_is_unbootable_rsp,
				slot_is_bootable(ptn_entries, current_slot_index)?"No":"Yes",
				MAX_RSP_SIZE);
		strlcpy(slot_info[i].slot_is_active_rsp,
				slot_is_active(ptn_entries, current_slot_index)?"Yes":"No",
				MAX_RSP_SIZE);
		strlcpy(slot_info[i].slot_is_succesful_rsp,
				slot_is_sucessful(ptn_entries, current_slot_index)?"Yes":"No",
				MAX_RSP_SIZE);
		itoa(slot_retry_count(ptn_entries, current_slot_index),
				(unsigned char *)buff, 2, 10);
		strlcpy(slot_info[i].slot_retry_count_rsp, buff, MAX_RSP_SIZE);
	}
}

/*
	Function to read and update the attributes of
	GPT
*/
static int
update_gpt(uint64_t gpt_start_addr,
		uint64_t gpt_hdr_offset,
		uint64_t gpt_entries_offset)
{
	char *buffer = NULL;
	char *gpt_entries_ptr, *gpt_hdr_ptr, *tmp = NULL;
	struct partition_entry *partition_entries = partition_get_partition_entries();
	uint32_t partition_count = partition_get_partition_count();
	unsigned i,max_partition_count = 0;
	unsigned partition_entry_size = 0;
	uint32_t block_size = mmc_get_device_blocksize();
	uint32_t crc_val = 0;
	int ret = 0;
	uint64_t max_gpt_size_bytes =
		(PARTITION_ENTRY_SIZE*NUM_PARTITIONS + GPT_HEADER_BLOCKS*block_size);
	int lun = -1;

	/* Get Current LUN for UFS target */
	if (!platform_boot_dev_isemmc())
		lun = mmc_get_lun();

	buffer = memalign(CACHE_LINE, ROUNDUP(max_gpt_size_bytes, CACHE_LINE));
	if (!buffer)
	{
		dprintf(CRITICAL, "update_gpt: Failed at memory allocation\n");
		goto out;
	}

	ret = mmc_read(gpt_start_addr, (uint32_t *)buffer,
				max_gpt_size_bytes);
	if (ret)
	{
		dprintf(CRITICAL, "Failed to read GPT\n");
		goto out;
	}

	/* 0. Intialise ptrs for header and entries */
	gpt_entries_ptr = buffer + gpt_entries_offset*block_size;
	gpt_hdr_ptr = buffer + gpt_hdr_offset*block_size;

	/* 1. Update attributes_flag of partition entry */
	tmp = gpt_entries_ptr;
	for (i=0;i<partition_count;i++)
	{
		if (lun != -1)
		{
			/* Partition table is populated with entries from lun 0 to max lun.
			* break out of the loop once we see the partition lun is > current lun */
			if (partition_entries[i].lun > lun)
				break;
			/* Find the entry where the partition table for 'lun' starts
			and then update the attributes */
			if (partition_entries[i].lun != lun)
				continue;
		}

		/* Update the partition attributes */
		PUT_LONG_LONG(&tmp[ATTRIBUTE_FLAG_OFFSET],
			partition_entries[i].attribute_flag);
		memscpy(tmp, PARTITION_TYPE_GUID_SIZE, partition_entries[i].type_guid,
				PARTITION_TYPE_GUID_SIZE);

		/* point to the next partition entry */
		tmp += PARTITION_ENTRY_SIZE;
	}

	/* Calculate and update CRC of partition entries array */
	max_partition_count =
		    GET_LWORD_FROM_BYTE(&gpt_hdr_ptr[PARTITION_COUNT_OFFSET]);
	partition_entry_size =
		    GET_LWORD_FROM_BYTE(&gpt_hdr_ptr[PENTRY_SIZE_OFFSET]);

	/* Check for partition entry size */
	if (partition_entry_size != PARTITION_ENTRY_SIZE) {
		dprintf(CRITICAL,"Invalid parition entry size\n");
		goto out;
	}

	/* Check for maximum partition size */
	if ((max_partition_count) > (MIN_PARTITION_ARRAY_SIZE /(partition_entry_size))) {
		dprintf(CRITICAL, "Invalid maximum partition count\n");
		goto out;
	}

	crc_val  = crc32(~0L, gpt_entries_ptr, ((max_partition_count) *
				(partition_entry_size))) ^ (~0L);
	PUT_LONG(&gpt_hdr_ptr[PARTITION_CRC_OFFSET], crc_val);


	/* Write CRC to 0 before we calculate the crc of the GPT header */
	crc_val = 0;
	PUT_LONG(&gpt_hdr_ptr[HEADER_CRC_OFFSET], crc_val);
	crc_val  = crc32(~0L,gpt_hdr_ptr, GPT_HEADER_SIZE) ^ (~0L);
	PUT_LONG(&gpt_hdr_ptr[HEADER_CRC_OFFSET], crc_val);

	/* write to mmc */
	ret = mmc_write(gpt_start_addr, max_gpt_size_bytes, buffer);
	if (ret)
	{
		dprintf(CRITICAL, "Failed to write gpt\n");
		goto out;
	}
out:
	if (buffer)
		free(buffer);
	return ret;
}

/**
	Function to update the backup and primary gpt
	partition.
**/
static void attributes_update()
{
	uint64_t offset;
	uint64_t gpt_entries_offset, gpt_hdr_offset;
	uint64_t gpt_start_addr;
	int ret;
	uint32_t block_size = mmc_get_device_blocksize();
	unsigned max_entries_size_bytes = PARTITION_ENTRY_SIZE*NUM_PARTITIONS;
	unsigned max_entries_blocks = max_entries_size_bytes/block_size;
	unsigned max_gpt_blocks = GPT_HEADER_BLOCKS + max_entries_blocks;
	int max_luns = 0, lun;
	int cur_lun = mmc_get_lun();

#if defined(MMC_SDHCI_SUPPORT) || defined(UFS_SUPPORT)
	if (platform_boot_dev_isemmc())
		max_luns = 1;
	else
		max_luns = ufs_get_num_of_luns((struct ufs_dev*)target_mmc_device());
#endif
	for (lun = 0; lun < max_luns; lun++)
	{
		/* Set current LUN */
		mmc_set_lun(lun);

		/* Update Primary GPT */
		offset = 0x01;	/*  offset is 0x1 for primary GPT */
		gpt_start_addr = offset*block_size;
		/* Take gpt_start_addr as start and calculate offset from that in block sz*/
		gpt_hdr_offset = 0; /* For primary partition offset is zero */
		gpt_entries_offset = GPT_HEADER_BLOCKS;

		ret = update_gpt(gpt_start_addr, gpt_hdr_offset, gpt_entries_offset);
		if (ret)
		{
			dprintf(CRITICAL, "Failed to update Primary GPT\n");
			return;
		}

		/* Update Secondary GPT */
		offset = ((mmc_get_device_capacity()/block_size) - max_gpt_blocks);
		gpt_start_addr = offset*block_size;
		gpt_hdr_offset = max_entries_blocks;
		gpt_entries_offset = 0; /* For secondary GPT entries offset is zero */

		ret = update_gpt(gpt_start_addr, gpt_hdr_offset, gpt_entries_offset);
		if (ret)
		{
			dprintf(CRITICAL, "Failed to update Secondary GPT\n");
			return;
		}
	}
	mmc_set_lun(cur_lun);
	return;
}
