/*
 * 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))
			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;
}
