/*
 * Copyright 2016, Amlogic Inc
 * yonghui.yu
 *
 * Based vaguely on the Linux code
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>
#include <command.h>
#include <errno.h>
#include <mmc.h>
#include <part.h>
#include <memalign.h>
#include <malloc.h>
#include <linux/list.h>
#include <div64.h>
#include "mmc_private.h"
#include <emmc_partitions.h>
#include <asm/arch-g12a/cpu_id.h>
#include <part_efi.h>

DECLARE_GLOBAL_DATA_PTR;
/* using mbr*/
#define CONFIG_PTBL_MBR	(0)
#if (CONFIG_PTBL_MBR)
	/* cmpare partition name? */
	#define CONFIG_CMP_PARTNAME	(0)
	/* cmpare partition mask */
	#define CONFIG_CMP_PARTMASK	(0)
#else
	#define CONFIG_CMP_PARTNAME	(1)
	#define CONFIG_CMP_PARTMASK	(1)
#endif
/* debug info*/
#define CONFIG_MPT_DEBUG 	(0)
#define GPT_PRIORITY             (1)

#ifdef CONFIG_AML_GPT_SYNC_ENTIRE_ENTRY
#define FALSE 0
#define TRUE 1
#endif
#define apt_err(fmt, ...) printf( "%s()-%d: " fmt , \
                  __func__, __LINE__, ##__VA_ARGS__)

#if (CONFIG_MPT_DEBUG)
#define apt_wrn(fmt, ...) printf( "%s()-%d: " fmt , \
                  __func__, __LINE__, ##__VA_ARGS__)
/* for detail debug info */
#define apt_info(fmt, ...) printf( "%s()-%d: " fmt , \
                  __func__, __LINE__, ##__VA_ARGS__)
#else
#define apt_wrn(fmt, ...)
#define apt_info(fmt, ...)
#endif

/* creat MBR for emmc */
#define MAX_PNAME_LEN 	(16)
#define MAX_PART_COUNT	(32)

/*
  Global offset of reserved partition is 36MBytes
  since MMC_BOOT_PARTITION_RESERVED is 32MBytes and
  MMC_BOOT_DEVICE_SIZE is 4MBytes.
  MMC_RESERVED_SIZE is 64MBytes for now.
  layout detail inside reserved partition.
  0x000000 - 0x003fff: partition table
  0x004000 - 0x03ffff: storage key area	(16k offset & 256k size)
  0x400000 - 0x47ffff: dtb area  (4M offset & 512k size)
  0x480000 - 64MBytes: resv for other usage.
  ...
 */
/*
#define RSV_DTB_OFFSET_GLB	(SZ_1M*40)
#define RSV_DTB_SIZE		(512*1024UL)
#define RSV_PTBL_OFFSET		(SZ_1M*0)
#define RSV_PTBL_SIZE		(16*1024UL)
#define RSV_SKEY_OFFSET		(16*1024UL)
#define RSV_SKEY_SIZE		(256*1024UL)
#define RSV_DTB_OFFSET		(SZ_1M*4)
*/

/* virtual partitions which are in "reserved" */
#define MAX_MMC_VIRTUAL_PART_CNT	(5)


/* BinaryLayout of partition table stored in rsv area */
struct ptbl_rsv {
    char magic[4];				/* MPT */
    unsigned char version[12];	/* binary version */
    unsigned int count;	/* partition count in using */
    int checksum;
    struct partitions partitions[MAX_MMC_PART_NUM];
};

/* partition table for innor usage*/
struct _iptbl {
	struct partitions *partitions;
	unsigned int count;	/* partition count in use */
};

unsigned device_boot_flag = 0xff;
bool is_partition_checked = false;

#ifndef CONFIG_AML_MMC_INHERENT_PART
/* fixme, name should be changed as aml_inherent_ptbl */
struct partitions emmc_partition_table[] = {
	PARTITION_ELEMENT(MMC_BOOT_NAME, MMC_BOOT_DEVICE_SIZE, 0),
	PARTITION_ELEMENT(MMC_RESERVED_NAME, MMC_RESERVED_SIZE, 0),
	/* prior partitions, same partition name with dts*/
	/* partition size will be overide by dts*/
	/* not needed for google*/
#if 0
	PARTITION_ELEMENT(MMC_CACHE_NAME, 0, 0),
#endif
	PARTITION_ELEMENT(MMC_ENV_NAME, MMC_ENV_SIZE, 0),
};

struct virtual_partition virtual_partition_table[] = {
/* partition for name idx, off & size will not be used! */
#if (CONFIG_PTBL_MBR)
	VIRTUAL_PARTITION_ELEMENT(MMC_MBR_NAME, MMC_MBR_OFFSET, MMC_MBR_SIZE),
#endif
	VIRTUAL_PARTITION_ELEMENT(MMC_BOOT_NAME0, 0, 0),
	VIRTUAL_PARTITION_ELEMENT(MMC_BOOT_NAME1, 0, 0),

    /* virtual partition in reserved partition, take care off and size */
#ifdef CONFIG_AML_PARTITION
	VIRTUAL_PARTITION_ELEMENT(MMC_TABLE_NAME, MMC_TABLE_OFFSET,
				  MMC_TABLE_SIZE),
#endif
	VIRTUAL_PARTITION_ELEMENT(MMC_KEY_NAME, EMMCKEY_RESERVE_OFFSET,
				  MMC_KEY_SIZE),
	VIRTUAL_PARTITION_ELEMENT(MMC_PATTERN_NAME, CALI_PATTERN_OFFSET,
				  CALI_PATTERN_SIZE),
#ifndef DTB_BIND_KERNEL
	VIRTUAL_PARTITION_ELEMENT(MMC_DTB_NAME, DTB_OFFSET, DTB_SIZE),
#endif
	VIRTUAL_PARTITION_ELEMENT(MMC_FASTBOOT_CONTEXT_NAME,
				  FASTBOOT_CONTEXT_OFFSET,
				  FASTBOOT_CONTEXT_SIZE),
	VIRTUAL_PARTITION_ELEMENT(MMC_DDR_PARAMETER_NAME, DDR_PARAMETER_OFFSET,
				  DDR_PARAMETER_SIZE),
	// Partition for storing secure storage data.
	// Rerserve the entry here so that merging of any upstream code change
	// on the table will be made aware of this local change.
	VIRTUAL_PARTITION_ELEMENT(MMC_SECURE_STORAGE_NAME,
				  MMC_SECURE_STORAGE_OFFSET,
				  MMC_SECURE_STORAGE_SIZE),
};

int get_emmc_partition_arraysize(void)
{
    return ARRAY_SIZE(emmc_partition_table);
}

int get_emmc_virtual_partition_arraysize(void)
{
    return ARRAY_SIZE(virtual_partition_table);
}

#endif

void __attribute__((unused)) _dump_part_tbl(struct partitions *p, int count)
{
	int i = 0;
	apt_info("count %d\n", count);
	while (i < count) {
		printf("%02d %10s %016llx %016llx\n", i, p[i].name, p[i].offset, p[i].size);
		i++;
	}
	return;
}

static int _get_part_index_by_name(struct partitions *tbl,
					   int cnt, const char *name)
{
	int i=0;
	struct partitions *part = NULL;

	while (i < cnt) {
		part = &tbl[i];
		if (!strcmp(name, part->name)) {
			apt_info("find %s @ tbl[%d]\n", name, i);
			break;
		}
		i++;
	};
	if (i == cnt) {
		i = -1;
		apt_wrn("do not find match in table %s\n", name);
	}
	return i;
}



static struct partitions *_find_partition_by_name(struct partitions *tbl,
			int cnt, const char *name)
{
	int i = 0;
	struct partitions *part = NULL;

	while (i < cnt) {

		part = &tbl[i];
		if (!strcmp(name, part->name)) {
			apt_info("find %s @ tbl[%d]\n", name, i);
			break;
		}
		i++;
	};
	if (i == cnt) {
		part = NULL;
		apt_wrn("do not find match in table %s\n", name);
	}
	return part;
}

/* fixme, must called after offset was calculated. */
static ulong _get_inherent_offset(const char *name)
{
	struct partitions *part;

	part = _find_partition_by_name(emmc_partition_table,
			get_emmc_partition_arraysize(), name);
	if (NULL == part)
		return -1;
	else
		return part->offset;
}
/* partition table (Emmc Partition Table) */
struct _iptbl *p_iptbl_ept = NULL;

/* trans byte into lba manner for rsv area read/write */
#ifdef CONFIG_AML_PARTITION
static ulong _mmc_rsv_read(struct mmc *mmc, ulong offset, ulong size, void * buffer)
{
	lbaint_t _blk, _cnt;
	if (0 == size)
		return 0;

	_blk = offset / mmc->read_bl_len;
	_cnt = size / mmc->read_bl_len;
	_cnt = blk_dread(mmc_get_blk_desc(mmc), _blk, _cnt, buffer);

	return (ulong)(_cnt * mmc->read_bl_len);
}

static ulong _mmc_rsv_write(struct mmc *mmc, ulong offset, ulong size, void * buffer)
{
	lbaint_t _blk, _cnt;
	if (0 == size)
		return 0;

	_blk = offset / mmc->read_bl_len;
	_cnt = size / mmc->read_bl_len;
	_cnt = blk_dwrite(mmc_get_blk_desc(mmc), _blk, _cnt, buffer);

	return (ulong)(_cnt * mmc->read_bl_len);
}
#endif


static struct partitions * get_ptbl_from_dtb(struct mmc *mmc)
{
	struct partitions * ptbl = NULL;
#ifdef CONFIG_AML_PARTITION
#ifndef DTB_BIND_KERNEL
	unsigned char * buffer = NULL;
	ulong ret, offset;
	struct virtual_partition *vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);

	/* try get dtb table from ddr, which may exsit while usb burning */
	if (NULL == get_partitions()) {
		/* if failed, try rsv dtb area then. */
		buffer = malloc(vpart->size * DTB_COPIES);
		if (NULL == buffer) {
			apt_err("Can not alloc enough buffer\n");
			goto _err;
		}
		offset = _get_inherent_offset(MMC_RESERVED_NAME) + vpart->offset;
		ret = _mmc_rsv_read(mmc, offset, (vpart->size * DTB_COPIES), buffer);
		if (ret != (vpart->size * DTB_COPIES)) {
			apt_err("Can not alloc enough buffer\n");
			goto _err1;
		}
		/* parse it */
		if (get_partition_from_dts(buffer)) {
			apt_err("get partition table from dts faild\n");
			goto _err1;
		}
		/* double check part_table(glb) */
		if (NULL == get_partitions()) {
			goto _err1;
		}
		apt_info("get partition table from dts successfully\n");

		free(buffer);
		buffer = NULL;
	}
#endif
#endif
	/* asign partition info to *ptbl */
	ptbl = get_partitions();
	return ptbl;
#ifdef CONFIG_AML_PARTITION
#ifndef DTB_BIND_KERNEL
_err1:
	if (buffer)
		free(buffer);
_err:
	free (ptbl);
	return NULL;
#endif
#endif
}




static struct partitions *is_prio_partition(struct _iptbl *list, struct partitions *part)
{
	int i;
	struct partitions *plist = NULL;

	if (list->count == 0)
		goto _out;

	apt_info("count %d\n", list->count);
	for (i=0; i<list->count; i++) {
		plist = &list->partitions[i];
		apt_info("%d: %s, %s\n", i, part->name, plist->name);
		if (!strcmp(plist->name, part->name)) {
			apt_info("%s is prio in list[%d]\n", part->name, i);
			break;
		}
	}
	if (i == list->count)
		plist = NULL;
_out:
	return plist;
}

/*  calculate offset of each partitions.
	bottom is a flag for considering
 */
static int _calculate_offset(struct mmc *mmc, struct _iptbl *itbl, u32 bottom)
{
	int i;
	struct partitions *part;
	ulong  gap = PARTITION_RESERVED;
	int ret = 0;

	if (itbl->count <= 0)
		return -1;
	part = itbl->partitions;
#if (CONFIG_MPT_DEBUG)
	_dump_part_tbl(part, itbl->count);
#endif

#if CONFIG_AML_GPT
	part->offset = RESERVED_GPT_OFFSET;
#endif

	if (!strcmp(part->name, "bootloader")) {
		part->offset = 0;
		gap = MMC_BOOT_PARTITION_RESERVED;
	}
	for (i=1; i<itbl->count; i++) {
		/**/
		part[i].offset = part[i-1].offset + part[i-1].size + gap;
		/* check capicity overflow ?*/
		if (((part[i].offset + part[i].size) > mmc->capacity) ||
				(part[i].size == -1)) {
			part[i].size = mmc->capacity - part[i].offset;
			/* reserv space @ the bottom */
			if (bottom && (part[i].size > MMC_BOTTOM_RSV_SIZE)) {
				apt_info("reserv %d bytes at bottom\n", MMC_BOTTOM_RSV_SIZE);
				part[i].size -= MMC_BOTTOM_RSV_SIZE;
			}
			break;
		}
		gap = PARTITION_RESERVED;
	}
	if (i < (itbl->count - 1)) {
		apt_err("too large partition table for current emmc, overflow!\n");
		ret = -1;
	}
#if (CONFIG_MPT_DEBUG)
	_dump_part_tbl(part, itbl->count);
#endif
	return ret;
}

static void compose_ept(struct _iptbl *dtb, struct _iptbl *inh,
			struct _iptbl *ept)
{
	int i;
	struct partitions *partition = NULL;
	struct partitions *dst, *src, *prio;

	/* overide inh info by dts */
	apt_info("dtb %p, inh %p, ept %p\n", dtb, inh, ept);
	apt_info("ept->partitions %p\n", ept->partitions);
	partition = ept->partitions;
	apt_info("partition %p\n", partition);
	for (i=0; i<MAX_PART_COUNT; i++) {
		apt_info("i %d, ept->count %d\n", i, ept->count);
		dst = &partition[ept->count];
		src = (i < inh->count) ? &inh->partitions[i]:&dtb->partitions[i-inh->count];

		prio = is_prio_partition(ept, src);
		if (prio) {
			/* overide prio partition by new */
			apt_info("override %d: %s\n", ept->count, prio->name);
			//*prio = *src;
			dst = prio;
		} else
			ept->count ++;
		*dst = *src;
		if (-1 == src->size) {
			apt_info("break! %s\n", src->name);
			break;
		}
	}

	return;
}
#ifdef CONFIG_AML_PARTITION
static int _get_version(unsigned char * s)
{
	int version = 0;
	if (!strncmp((char *)s, MMC_MPT_VERSION_2, sizeof(MMC_MPT_VERSION_2)))
		version = 2;
	else if (!strncmp((char *)s, MMC_MPT_VERSION_1, sizeof(MMC_MPT_VERSION_1)))
		version = 1;
	else
		version = -1;

	return version;
}

/*  calc checksum.
	there's a bug on v1 which did not calculate all the partitios.
 */
static int _calc_iptbl_check_v2(struct partitions * part, int count)
{
	int ret = 0, i;
	int size = count * sizeof(struct partitions) >> 2;
	int *buf = (int *)part;

	for (i = 0; i < size; i++)
		ret +=buf[i];

	return ret;
}

static int _calc_iptbl_check_v1(struct partitions *part, int count)
{
    int i, j;
	u32 checksum = 0, *p;

	for (i = 0; i < count; i++) {
		p = (u32*)part;
		/*BUG here, do not fix it!!*/
		for (j = sizeof(struct partitions)/sizeof(checksum); j > 0; j--) {
			checksum += *p;
			p++;
	    }
    }

	return checksum;
}

static int _calc_iptbl_check(struct partitions * part, int count, int version)
{
	if (1 == version)
		return _calc_iptbl_check_v1(part, count);
	else if (2 == version)
		return _calc_iptbl_check_v2(part, count);
	else
		return -1;
}

/* ept is malloced out side */
static int _cpy_iptbl(struct _iptbl * dst, struct _iptbl * src)
{
	int ret = 0;
	if (!dst || !src) {
		apt_err("invalid arg %s\n", !dst ? "dst" : "src");
		ret = -1;
		goto _out;
	}
	if (!dst->partitions || !src->partitions) {
		apt_err("invalid arg %s->partitions\n", !dst ? "dst" : "src");
		ret = -2;
		goto _out;
	}
	if (src->count > MAX_MMC_PART_NUM) {
		ret = -3;
		goto _out;
	}
	dst->count = src->count;
	memcpy(dst->partitions, src->partitions, sizeof(struct partitions) * src->count);

_out:
	return ret;
}


/* get ptbl from rsv area from emmc */
static int get_ptbl_rsv(struct mmc *mmc, struct _iptbl *rsv)
{
	struct ptbl_rsv * ptbl_rsv = NULL;
	uchar * buffer = NULL;
	ulong size, offset;
	int checksum, version, ret = 0;
	struct virtual_partition *vpart = aml_get_virtual_partition_by_name(MMC_TABLE_NAME);

	size = (sizeof(struct ptbl_rsv) + 511) / 512 * 512;
	if (vpart->size < size) {
		apt_err("too much partitons\n");
		ret = -1;
		goto _out;
	}
	buffer = malloc(size);
	if (NULL == buffer) {
		apt_err("no enough memory for ptbl rsv\n");
		ret = -2;
		goto _out;
	}
	/* read it from emmc. */
	offset = _get_inherent_offset(MMC_RESERVED_NAME) + vpart->offset;
	if (size != _mmc_rsv_read(mmc, offset, size, buffer)) {
		apt_err("read ptbl from rsv failed\n");
		ret = -3;
		goto _out;
	}

	ptbl_rsv = (struct ptbl_rsv *) buffer;
	apt_info("magic %3.3s, version %8.8s, checksum %x\n", ptbl_rsv->magic,
			ptbl_rsv->version, ptbl_rsv->checksum);
	/* fixme, check magic ?*/
	if (strncmp(ptbl_rsv->magic, MMC_PARTITIONS_MAGIC, sizeof(MMC_PARTITIONS_MAGIC))) {
		apt_err("magic faild %s, %3.3s\n", MMC_PARTITIONS_MAGIC, ptbl_rsv->magic);
		ret = -4;
		goto _out;
	}
	/* check version*/
	version = _get_version(ptbl_rsv->version);
	if (version < 0) {
		apt_err("version faild %s, %3.3s\n", MMC_PARTITIONS_MAGIC, ptbl_rsv->magic);
		ret = -5;
		goto _out;
	}
	if (ptbl_rsv->count > MAX_MMC_PART_NUM) {
		apt_err("invalid partition count %d\n", ptbl_rsv->count);
		ret = -1;
		goto _out;
	}
	/* check sum */
	checksum = _calc_iptbl_check(ptbl_rsv->partitions, ptbl_rsv->count, version);
	if (checksum != ptbl_rsv->checksum) {
		apt_err("checksum faild 0x%x, 0x%x\n", ptbl_rsv->checksum, checksum);
		ret = -6;
		goto _out;
	}

	rsv->count = ptbl_rsv->count;
	memcpy(rsv->partitions, ptbl_rsv->partitions, rsv->count * sizeof(struct partitions));

_out:
	if (buffer)
		free (buffer);
	return ret;
}


/* update partition tables from src
	if success, return 0;
	else, return 1
	*/
static int update_ptbl_rsv(struct mmc *mmc, struct _iptbl *src)
{
	struct ptbl_rsv *ptbl_rsv = NULL;
	uchar *buffer;
	ulong size, offset;
	int ret = 0, version;
	struct virtual_partition *vpart = aml_get_virtual_partition_by_name(MMC_TABLE_NAME);

	size = (sizeof(struct ptbl_rsv) + 511) / 512 * 512;
	buffer = malloc(size);
	if (NULL == buffer) {
		apt_err("no enough memory for ptbl rsv\n");
		return -1;
	}
	memset(buffer, 0 , size);
	/* version, magic and checksum */
	ptbl_rsv = (struct ptbl_rsv *) buffer;
	strcpy((char *)ptbl_rsv->version, MMC_MPT_VERSION);
	strcpy(ptbl_rsv->magic, MMC_PARTITIONS_MAGIC);
	if (src->count > MAX_MMC_PART_NUM) {
		apt_err("too much partitions\n");
		ret = -1;
		goto _err;
	}
	ptbl_rsv->count = src->count;
	memcpy(ptbl_rsv->partitions, src->partitions,
		sizeof(struct partitions)*src->count);
	version = _get_version(ptbl_rsv->version);
	ptbl_rsv->checksum = _calc_iptbl_check(src->partitions, src->count, version);
	/* write it to emmc. */
	apt_info("magic %3.3s, version %8.8s, checksum %x\n", ptbl_rsv->magic, ptbl_rsv->version, ptbl_rsv->checksum);
	offset = _get_inherent_offset(MMC_RESERVED_NAME) + vpart->offset;
	if (_mmc_rsv_write(mmc, offset, size, buffer) != size) {
		apt_err("write ptbl to rsv failed\n");
		ret = -1;
		goto _err;
	}
_err:
	free (buffer);
	return ret;
}

static void _free_iptbl(struct _iptbl *iptbl)
{
	if (iptbl && iptbl->partitions) {
		free(iptbl->partitions);
		iptbl->partitions = NULL;
	}
	if (iptbl) {
		free(iptbl);
		iptbl = NULL;
	}

	return;
}

#endif
static int _cmp_partition(struct partitions *dst, struct partitions *src, int overide)
{
	int ret = 0;
#if (CONFIG_CMP_PARTNAME)
	if (strncmp(dst->name, src->name, sizeof(src->name)))
		ret = -2;
#endif
	if (dst->size != src->size)
		ret = -3;
	if (dst->offset != src->offset)
		ret = -4;
#if (CONFIG_CMP_PARTMASK)
	if (dst->mask_flags != src->mask_flags)
		ret = -5;
#endif

	if (ret && (!overide)) {
		apt_err("name: %10.10s<->%10.10s\n", dst->name, src->name);
		apt_err("size: %llx<->%llx\n", dst->size, src->size);
		apt_err("offset: %llx<->%llx\n", dst->offset, src->offset);
		apt_err("mask: %08x<->%08x\n", dst->mask_flags, src->mask_flags);
	}

	if (overide) {
		*dst = *src;
		ret = 0;
	}

	return ret;
}

/* compare partition tables
	if same, do nothing then return 0;
	else, print the diff ones and return -x
	-1:count
	-2:name
	-3:size
	-4:offset
	*/
static int _cmp_iptbl(struct _iptbl * dst, struct _iptbl * src)
{
	int ret = 0, i = 0;
	struct partitions *dstp;
	struct partitions *srcp;

	if (dst->count != src->count) {
		apt_err("partition count is not same %d:%d\n", dst->count, src->count);
		ret = -1;
		goto _out;
	}

	while (i < dst->count) {
		dstp = &dst->partitions[i];
		srcp = &src->partitions[i];
		ret = _cmp_partition(dstp, srcp, 0);
		if (ret) {
			apt_err("partition %d has changed\n", i);
			break;
		}
		i++;
	}

_out:
	return ret;
}


/* iptbl buffer opt. */
static int _zalloc_iptbl(struct _iptbl **_iptbl)
{
	int ret = 0;
	struct _iptbl *iptbl;
	struct partitions *partition = NULL;

	partition = malloc(sizeof(struct partitions)*MAX_PART_COUNT);
	if (NULL == partition) {
		ret = -1;
		apt_err("no enough memory for partitions\n");
		goto _out;
	}

	iptbl = malloc(sizeof(struct _iptbl));
	if (NULL == iptbl) {
		ret = -2;
		apt_err("no enough memory for ept\n");
		free(partition);
		goto _out;
	}
	memset(partition, 0, sizeof(struct partitions)*MAX_PART_COUNT);
	memset(iptbl, 0, sizeof(struct _iptbl));

	iptbl->partitions = partition;
	apt_info("iptbl %p, partition %p, iptbl->partitions %p\n",
		iptbl, partition, iptbl->partitions);
	*_iptbl = iptbl;
_out:
	return ret;
}


/*
 * fixme, need check space size later.
 */

static inline int le32_to_int(unsigned char *le32)
{
	return ((le32[3] << 24) +
	    (le32[2] << 16) +
	    (le32[1] << 8) +
	     le32[0]
	   );
}

static int test_block_type(unsigned char *buffer)
{
	int slot;
	struct dos_partition *p;

	if ((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
		return (-1);
	} /* no DOS Signature at all */
	p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
	for (slot = 0; slot < 3; slot++) {
		if (p->boot_ind != 0 && p->boot_ind != 0x80) {
			if (!slot &&
			    (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
				     "FAT", 3) == 0 ||
			     strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
				     "FAT32", 5) == 0)) {
				return DOS_PBR; /* is PBR */
			} else {
				return -1;
			}
		}
	}
	return DOS_MBR;	    /* Is MBR */
}

//DOS_MBR OR DOS_PBR
/*
 * re-constructe iptbl from mbr&ebr infos.
 * memory for  iptbl_mbr must be alloced outside.
 *
 */
static void _construct_ptbl_by_mbr(struct mmc *mmc, struct _iptbl *iptbl_mbr)
{
	int ret,i;
	int flag = 0;
	lbaint_t read_offset = 0;
	int part_num = 0;
	int primary_num = 0;
	uint64_t logic_start = 0;
	uint64_t externed_start = 0;
	struct dos_partition *pt;
	struct partitions *partitions = iptbl_mbr->partitions;

	apt_info("aml MBR&EBR debug...\n");
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 512);
	for (;;) {
		apt_info("**%02d: read_offset %016llx\n", part_num, (uint64_t)read_offset<<9);
		ret = blk_dread(mmc_get_blk_desc(mmc), read_offset, 1, buffer);
		if (read_offset == 0)
			flag = 1;
		else
			flag = 0;
		/* debug code */
		// print_buffer(0,buffer,1,512,16);
		if (ret != 1) {
			apt_err("ret %d fail to read current ebr&mbr from emmc! \n", ret);
			break;
		}
		ret = test_block_type(buffer);
		if (ret != 0 && ret != 1) {
			apt_err("invalid magic value: 0x%02x%02x\n",
				buffer[DOS_PART_MAGIC_OFFSET], buffer[DOS_PART_MAGIC_OFFSET + 1]);
			break;
		}

		pt = (dos_partition_t *)(&buffer[0] + DOS_PART_TBL_OFFSET);
		for (i = 0; i < 4; i++, pt++) {
			if ( (pt->boot_ind == 0x00 || pt->boot_ind == 0x80) && pt->sys_ind == 0x83 ) {
				//emmc_partition[part_num]->name = NULL;
				partitions[part_num].offset = ((uint64_t)(le32_to_int(pt->start4)+read_offset) << 9ULL);
				partitions[part_num].size = (uint64_t)le32_to_int(pt->size4) << 9ULL;
				partitions[part_num].mask_flags = pt->sys_ind;

				apt_info("--partition[%d]: %016llx, %016llx, 0x%08x \n",
					part_num, partitions[part_num].offset,
					partitions[part_num].size,
					le32_to_int(pt->size4));
				part_num++;
				if ( flag )
					primary_num++;
			}else{/* get the next externed partition info */
				if ( pt->boot_ind == 0x00 && pt->sys_ind == 0x05) {
					logic_start = (uint64_t)le32_to_int (pt->start4);
					//logic_size = (uint64_t)le32_to_int (pt->size4);
				}
			}
		}
		/* mbr & ebr debug infos */
		apt_info("******%02d: read_offset=%016llx, logic_start=%016llx\n",
			part_num,(uint64_t)read_offset*512ULL,logic_start*512ULL);

		if (part_num == primary_num) {
			externed_start = logic_start;
			read_offset = externed_start;
		}else
			read_offset = externed_start + logic_start;
		if (logic_start == 0)
			break;
		logic_start = 0;

	}
	iptbl_mbr->count = part_num;
	apt_info("iptbl_mbr->count = %d\n", iptbl_mbr->count);

	return;
}

static int __attribute__((unused)) _check_ptbl_mbr(struct mmc *mmc, struct _iptbl *ept)
{
	int ret = 0;
	/* re-constructed by mbr */
	struct _iptbl *iptbl_mbr = NULL;
	struct partitions *partitions = NULL;

	iptbl_mbr = malloc(sizeof(struct _iptbl));
	if (NULL == iptbl_mbr) {
		apt_err("no enough memory for iptbl_mbr\n");
		return -1;
	}
	memset(iptbl_mbr , 0, sizeof(struct _iptbl));
	partitions = (struct partitions *)malloc(sizeof(struct partitions) * DOS_PARTITION_COUNT);
	if (NULL == partitions) {
		apt_err("no enough memory for partitions\n");
		free(iptbl_mbr);
		return -1;
	}
	memset(partitions, 0, sizeof(struct partitions) * DOS_PARTITION_COUNT);
	iptbl_mbr->partitions = partitions;

	_construct_ptbl_by_mbr(mmc, iptbl_mbr);

	ret = _cmp_iptbl(iptbl_mbr, ept);

	if (partitions)
		free(partitions);
	if (iptbl_mbr)
		free(iptbl_mbr);

	apt_wrn("MBR is %s\n", ret?"Improper!":"OK!");
	return ret;
}

/* construct a partition table entry of EBR */
static int _construct_ebr_1st_entry(struct _iptbl *p_iptbl,struct dos_partition *p_ebr, int part_num )
{
	uint64_t start_offset = 0;
	uint64_t logic_size = 0;

	p_ebr->boot_ind = 0x00;
	p_ebr->sys_ind = 0x83;
	/* Starting = relative offset between this EBR sector and the first sector of the logical partition
	* the gap between two partition is a fixed value of PARTITION_RESERVED ,otherwise the emmc partiton
	* is different with reserved */
	start_offset = PARTITION_RESERVED >> 9;
	/* Number of sectors = total count of sectors for this logical partition */
	// logic_size = (p_iptbl->partitions[part_num].size) >> 9ULL;
	logic_size = lldiv(p_iptbl->partitions[part_num].size, 512);
	apt_info("*** %02d: size 0x%016llx, logic_size 0x%016llx\n", part_num, p_iptbl->partitions[part_num].size, logic_size);
	memcpy((unsigned char *)(p_ebr->start4), &start_offset, 4);
	memcpy((unsigned char *)(p_ebr->size4), &logic_size, 4);
	return 0;
}

static int _construct_ebr_2nd_entry(struct _iptbl *p_iptbl, struct dos_partition *p_ebr, int part_num)
{
	uint64_t start_offset = 0;
	uint64_t logic_size = 0;

	if ((part_num+2) > p_iptbl->count)
		return 0;

	p_ebr->boot_ind = 0x00;
	p_ebr->sys_ind = 0x05;
	/* Starting sector = LBA address of next EBR minus LBA address of extended partition's first EBR */
	start_offset = (p_iptbl->partitions[part_num+1].offset - PARTITION_RESERVED -
					(p_iptbl->partitions[3].offset - PARTITION_RESERVED)) >> 9;
	/* total count of sectors for next logical partition, but count starts from the next EBR sector */
	logic_size = (p_iptbl->partitions[part_num+1].size + PARTITION_RESERVED) >> 9;

	memcpy((unsigned char *)(p_ebr->start4), &start_offset, 4);
	memcpy((unsigned char *)(p_ebr->size4), &logic_size, 4);

	return 0;
}

/* construct a partition table entry of MBR OR EBR */
static int _construct_mbr_entry(struct _iptbl *p_iptbl, struct dos_partition *p_entry, int part_num)
{
	uint64_t start_offset = 0;
	uint64_t primary_size = 0;
	uint64_t externed_size = 0;
	int i;
	/* the entry is active or not */
	if (part_num == 0 )
		p_entry->boot_ind = 0x00;
	else
		p_entry->boot_ind = 0x00;

	if (part_num == 3) {/* the logic partion entry */
		/* the entry type */
		p_entry->sys_ind = 0x05;
		start_offset = (p_iptbl->partitions[3].offset - PARTITION_RESERVED) >> 9;
		for ( i = 3;i< p_iptbl->count;i++)
			externed_size = p_iptbl->partitions[i].size >> 9;

		memcpy((unsigned char *)p_entry->start4, &start_offset, 4);
		memcpy((unsigned char *)p_entry->size4, &externed_size, 4);
	}else{/* the primary partion entry */
		/* the entry type */
		p_entry->sys_ind = 0x83;
		start_offset = (p_iptbl->partitions[part_num].offset) >> 9;
		primary_size = (p_iptbl->partitions[part_num].size)>>9;
		memcpy((unsigned char *)p_entry->start4, &start_offset, 4);
		memcpy((unsigned char *)p_entry->size4, &primary_size, 4);
	}

	return 0;
}

static int _construct_mbr_or_ebr(struct _iptbl *p_iptbl, struct dos_mbr_or_ebr *p_br,
	int part_num, int type)
{
	int i;

	if (DOS_MBR == type) {
		/* constuct a integral MBR */
		for (i = 0; i<4 ; i++)
			_construct_mbr_entry(p_iptbl, &p_br->part_entry[i], i);

	}else{
		/* constuct a integral EBR */
		p_br->bootstart[DOS_PBR32_FSTYPE_OFFSET] = 'F';
		p_br->bootstart[DOS_PBR32_FSTYPE_OFFSET + 1] = 'A';
		p_br->bootstart[DOS_PBR32_FSTYPE_OFFSET + 2] = 'T';
		p_br->bootstart[DOS_PBR32_FSTYPE_OFFSET + 3] = '3';
		p_br->bootstart[DOS_PBR32_FSTYPE_OFFSET + 4] = '2';

		_construct_ebr_1st_entry(p_iptbl, &p_br->part_entry[0], part_num);
		_construct_ebr_2nd_entry(p_iptbl, &p_br->part_entry[1], part_num);
	}

	p_br->magic[0] = 0x55 ;
	p_br->magic[1] = 0xAA ;
	return 0;
}

static __attribute__((unused)) int _update_ptbl_mbr(struct mmc *mmc, struct _iptbl *p_iptbl)
{
	int ret = 0, start_blk = 0, blk_cnt = 1;
	unsigned char *src;
	int i;
	struct dos_mbr_or_ebr *mbr;
	struct _iptbl *ptb ;

	ptb = p_iptbl;
	mbr = malloc(sizeof(struct dos_mbr_or_ebr));

	for (i=0;i<ptb->count;i++) {
		apt_info("-update MBR-: partition[%02d]: %016llx - %016llx\n",i,
			ptb->partitions[i].offset, ptb->partitions[i].size);
	}

	for (i = 0;i < ptb->count;) {
		memset(mbr ,0 ,sizeof(struct dos_mbr_or_ebr));
		if (i == 0) {
			_construct_mbr_or_ebr(ptb, mbr, i, 0);
			i = i+2;
		} else
			_construct_mbr_or_ebr(ptb, mbr, i, 2);
		src = (unsigned char *)mbr;
		apt_info("--%s(): %02d(%02d), off %x\n", __func__, i, ptb->count, start_blk);
		ret = blk_dwrite(mmc_get_blk_desc(mmc), start_blk, blk_cnt, src);
		i++;
		if (ret != blk_cnt) {
			apt_err("write current MBR failed! ret: %d != cnt: %d\n",ret,blk_cnt);
			break;
		}
		start_blk = (ptb->partitions[i].offset - PARTITION_RESERVED) >> 9;
	}
	free(mbr);

	ret = !ret;
	if (ret)
		apt_err("write MBR failed!\n");

	return ret;
}

#ifdef CONFIG_AML_GPT
int is_gpt_changed(struct mmc *mmc, struct _iptbl *p_iptbl_ept)
{
	int i, k;
	gpt_entry *gpt_pte = NULL;
	size_t efiname_len;
	struct _iptbl *ept = p_iptbl_ept;
	struct partitions *partitions = ept->partitions;
	int parts_num = ept->count;
	uint64_t offset;
	uint64_t size;
	char name[PARTNAME_SZ];
	int gpt_changed = 0;
	struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return 1;
	}

	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
				gpt_head, &gpt_pte) != 1) {
		printf("%s: ***ERROR:Invalid GPT ***\n", __func__);
		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
					gpt_head, &gpt_pte) != 1) {
			printf("%s: ***ERROR: Invalid Backup GPT ***\n",
					__func__);
			return 1;
		} else {
			printf("%s: *** Using Backup GPT ***\n",
					__func__);
		}
			//return 1;
	}
	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
		if (!is_pte_valid(&gpt_pte[i]))
			break;

		offset = le64_to_cpu(gpt_pte[i].starting_lba<<9ULL);
		if (partitions[i].offset != offset) {
#ifdef BL33_DEBUG_PRINT
			printf("Caution! GPT offset had been changed\n");
#endif
			gpt_changed = 1;
			break;
		}

		size = ((le64_to_cpu(gpt_pte[i].ending_lba)+1) -
			le64_to_cpu(gpt_pte[i].starting_lba)) << 9ULL;
		if (i == parts_num - 1) {
			if ((partitions[i].size - GPT_TOTAL_SIZE) != size) {
#ifdef BL33_DEBUG_PRINT
				printf("Caution! GPT size had been changed\n");
#endif
				gpt_changed = 1;
				break;
			}
		} else {
		if (partitions[i].size != size) {
#ifdef BL33_DEBUG_PRINT
			printf("Caution! GPT size had been changed\n");
#endif
			gpt_changed = 1;
			break;
			}
		}

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

		memset(name, 0, PARTNAME_SZ);
		for (k = 0; k < efiname_len; k++)
			name[k] = (char)gpt_pte[i].partition_name[k];
		if (strcmp(name, partitions[i].name) != 0) {
#ifdef BL33_DEBUG_PRINT
			printf("Caution! GPT name had been changed\n");
#endif
			gpt_changed = 1;
			break;
		}

	}
	if ((i != parts_num) && (gpt_changed == 0)) {
		gpt_changed = 1;
#ifdef BL33_DEBUG_PRINT
		printf("Caution! GPT number had been changed\n");
#endif
	}

	free(gpt_pte);
	return gpt_changed;
}
int is_gpt_broken(struct mmc *mmc)
{
	gpt_entry *gpt_pte = NULL;
	int broken_status = 0;
	struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return 1;
	}

	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
				gpt_head, &gpt_pte) != 1) {
		broken_status += 1;
		printf("%s: ***ERROR:Invalid GPT ***\n", __func__);
	} else {
		free(gpt_pte);
	}
	if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
				gpt_head, &gpt_pte) != 1) {
		printf("%s: ***ERROR: Invalid Backup GPT ***\n",
					__func__);
		broken_status += 2;
	} else {
		free(gpt_pte);
	}

	return broken_status;

}

int fill_ept_by_gpt(struct mmc *mmc, struct _iptbl *p_iptbl_ept)
{
	struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
	gpt_entry *gpt_pte = NULL;
	int i, k;
	size_t efiname_len, dosname_len;
	struct _iptbl *ept = p_iptbl_ept;
	struct partitions *partitions = ept->partitions;

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return 1;
	}

	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
				gpt_head, &gpt_pte) != 1) {
		printf("%s: ***ERROR:Invalid GPT ***\n", __func__);
		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
					gpt_head, &gpt_pte) != 1) {
			printf("%s: ***ERROR: Invalid Backup GPT ***\n",
					__func__);
			return 1;
		} else {
			printf("%s: *** Using Backup GPT ***\n",
					__func__);
		}
			//return 1;
	}

	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
		if (!is_pte_valid(&gpt_pte[i]))
			break;

		partitions[i].offset = le64_to_cpu(gpt_pte[i].starting_lba<<9ULL);
		partitions[i].size = ((le64_to_cpu(gpt_pte[i].ending_lba)+1) -
			le64_to_cpu(gpt_pte[i].starting_lba)) << 9ULL;

		#ifdef CONFIG_AML_GPT_SYNC_ENTIRE_ENTRY
		memcpy(partitions[i].type_guid.b, gpt_pte[i].partition_type_guid.b, sizeof(efi_guid_t));
		memcpy(partitions[i].uuid.b, gpt_pte[i].unique_partition_guid.b, sizeof(efi_guid_t));
		memcpy(&(partitions[i].attributes), &(gpt_pte[i].attributes), sizeof(gpt_entry_attributes));
		#endif
		/* partition name */
		efiname_len = sizeof(gpt_pte[i].partition_name)
			/ sizeof(efi_char16_t);
		dosname_len = sizeof(partitions[i].name);

		memset(partitions[i].name, 0, sizeof(partitions[i].name));
		for (k = 0; k < min(dosname_len, efiname_len); k++)
			partitions[i].name[k] = (char)gpt_pte[i].partition_name[k];

	}
	ept->count = i;
	free(gpt_pte);
	return 0;
}
#ifdef CONFIG_AML_GPT_SYNC_ENTIRE_ENTRY
void trans_ept_to_diskpart(struct _iptbl *ept, disk_partition_t *disk_part, bool gpt_broken_status) {
#else
void trans_ept_to_diskpart(struct _iptbl *ept, disk_partition_t *disk_part) {
#endif
	struct partitions *part = ept->partitions;
	int count = ept->count;
	int i;
	for (i = 0; i < count; i++) {
		disk_part[i].start = part[i].offset >> 9;
		strcpy((char *)disk_part[i].name, part[i].name);
#ifdef CONFIG_AML_GPT_SYNC_ENTIRE_ENTRY
	if (gpt_broken_status) {
		memcpy(disk_part[i].partition_type_guid.b, part[i].type_guid.b, sizeof(efi_guid_t));
		memcpy(disk_part[i].unique_partition_guid.b, part[i].uuid.b, sizeof(efi_guid_t));
		memcpy(&(disk_part[i].attributes), &(part[i].attributes), sizeof(gpt_entry_attributes));
	} else {
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
	char *str_uuid;
	unsigned char *bin_uuid;
#endif
#ifdef CONFIG_PARTITION_TYPE_GUID
	char *str_type_guid;
	unsigned char *bin_type_guid;
#endif
#ifdef CONFIG_PARTITION_TYPE_GUID
	str_type_guid = part[i].name;
	bin_type_guid = disk_part[i].partition_type_guid.b;
#endif
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
	gen_rand_uuid_str(disk_part[i].uuid, UUID_STR_FORMAT_STD);
	str_uuid = disk_part[i].uuid;
	bin_uuid = disk_part[i].unique_partition_guid.b;
#endif
#ifdef CONFIG_PARTITION_TYPE_GUID
		if (strlen(str_type_guid)) {
			if (uuid_str_to_bin(str_type_guid, bin_type_guid,
						UUID_STR_FORMAT_GUID)) {
#ifdef CONFIG_AML_GPT
				char str[8] = {"default"};
				uuid_str_to_bin(str, bin_type_guid,
						UUID_STR_FORMAT_GUID);
			}
		}
#else
				printf("Partition no. %d: invalid type guid: %s\n",
						i, str_type_guid);
				return;
			}
		}
#endif
#endif
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
		if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) {
			printf("Partition no. %d: invalid guid: %s\n",
					i, str_uuid);
			return;
		}
#endif
	}
#else
		strcpy((char *)disk_part[i].type_guid, part[i].name);
		gen_rand_uuid_str(disk_part[i].uuid, UUID_STR_FORMAT_STD);
#endif
		disk_part[i].bootable = 0;
		if ( i == (count - 1))
			disk_part[i].size = 0;
		else
			disk_part[i].size = (part[i].size) >> 9;
	}
	return;
}




#endif

/***************************************************
 *	init partition table for emmc device.
 *	returns 0 means ok.
 *			other means failure.
 ***************************************************
 *  work flows:
 *	source of logic partition table(LPT) is from dts
 *	no matter MACRO is on/off
 *		1. try to get LPT from dtb
 *			1.1 if dtb exist, compose ept by LPT&inh
 *			1.2 if not, go ahead
 *      2. try to get ept from emmc rsv partition
 *			2.1 if not:
 * 				2.1.1 when dtb exists
 *					2.1.1.1 check ept with dtb
 *					2.1.1.2 update rsv if needed
 * 				2.1.1 without dtb, exit
 *			2.2 if got:
 *				2.2.1 try to reconstruct ept by MBR
 *				2.2.2 check it with ept
 *				2.2.3 update MBR if needed
 ***************************************************
 *	when normal boot:
 *		without dtb, with rsv, with MBR
 *  when blank emmc:
 *		without dtb, without rsv, without MBR
 *  when burning MBR on a blank emmc:
 *		with dtb, without rsv, without MBR
 *  when burning MBR on a emmc with rsv:
 *		with dtb, with rsv, without MBR
 *  when burning MBR on a emmc with rsv&MBR:
 *		with dtb, with rsv, with MBR
 ***************************************************/
int mmc_device_init (struct mmc *mmc)
{
	int ret = 1;
#if (CONFIG_PTBL_MBR)  || (!CONFIG_AML_PARTITION)
	cpu_id_t cpu_id = get_cpu_id();
#endif
	/* partition table from dtb/code/emmc rsv */
	struct _iptbl iptbl_dtb, iptbl_inh;

	/* calculate inherent offset */
	iptbl_inh.count = get_emmc_partition_arraysize();
	if (iptbl_inh.count) {
		iptbl_inh.partitions = emmc_partition_table;
		_calculate_offset(mmc, &iptbl_inh, 0);
	}
	apt_info("inh count %d\n",  iptbl_inh.count);
#if (CONFIG_MPT_DEBUG)
	apt_info("inherent partition table\n");
	_dump_part_tbl(iptbl_inh.partitions, iptbl_inh.count);
#endif
	/* For re-entry */
	if (NULL == p_iptbl_ept) {
		ret = _zalloc_iptbl(&p_iptbl_ept);
		if (ret)
			goto _out;
	} else {
		p_iptbl_ept->count = 0;
		memset(p_iptbl_ept->partitions, 0,
			sizeof(struct partitions)*MAX_PART_COUNT);
	}

	/* try to get partition table from dtb(ddr or emmc) */
	iptbl_dtb.partitions = get_ptbl_from_dtb(mmc);
	/* construct ept by dtb if exist */
	if (iptbl_dtb.partitions) {
		iptbl_dtb.count = get_partition_count();
		apt_info("dtb %p, count %d\n", iptbl_dtb.partitions, iptbl_dtb.count);
		/* reserved partition must exist! */
		if (iptbl_inh.count) {
			compose_ept(&iptbl_dtb, &iptbl_inh, p_iptbl_ept);
			if (0 == p_iptbl_ept->count) {
				apt_err("compose partition table failed!\n");
				goto _out;
			}
			/* calculate offset infos. considering GAPs */
			if (_calculate_offset(mmc, p_iptbl_ept, 1)) {
				goto _out;
			}
		#if (CONFIG_MPT_DEBUG)
			apt_info("ept partition table\n");
			_dump_part_tbl(p_iptbl_ept->partitions, p_iptbl_ept->count);
		#endif
		} else {
			/* report fail, because there is no reserved partitions */
			apt_err("compose partition table failed!\n");
			ret = -1;
			goto _out;
		}
	} else {
#ifdef BL33_DEBUG_PRINT
		apt_wrn("get partition table from dtb failed\n");
#endif
	}
#ifndef CONFIG_AML_PARTITION
	if (cpu_id.family_id < MESON_CPU_MAJOR_ID_G12B) {
		printf("CONFIG_AML_PARTITION should define before G12B\n");
		goto _out;
	}
#endif

#ifdef CONFIG_AML_PARTITION
	int update = 1;
	struct _iptbl *p_iptbl_rsv = NULL;
	/* try to get partiton table from rsv */
	ret = _zalloc_iptbl(&p_iptbl_rsv);
	if (ret)
		goto _out;
	ret = get_ptbl_rsv(mmc, p_iptbl_rsv);
	if (p_iptbl_rsv->count) {
		/* dtb exist, p_iptbl_ept already inited */
		if (iptbl_dtb.partitions) {
			ret = _cmp_iptbl(p_iptbl_ept, p_iptbl_rsv);
			if (!ret) {
				update = 0;
			}
		} else {
			/* without dtb, update ept with rsv */
		#if 0
			p_iptbl_ept->count = p_iptbl_rsv->count;
			memcpy(p_iptbl_ept->partitions, p_iptbl_rsv->partitions,
				p_iptbl_ept->count * sizeof(struct partitions));
		#endif
			_cpy_iptbl(p_iptbl_ept, p_iptbl_rsv);
			update = 0;
		}
	} else {
		/* without dtb& rsv */
		if (!iptbl_dtb.partitions) {
			apt_err("dtb&rsv are not exist, no LPT source\n");
			ret = -9;
			goto _out;
		}
	}

	if (update && iptbl_dtb.partitions) {
		apt_wrn("update rsv with dtb!\n");
		ret = update_ptbl_rsv(mmc, p_iptbl_ept);
	}
#endif
	//apt_wrn("ept source is %s\n", (ept_source == p_iptbl_ept)?"ept":"rsv");
#if (CONFIG_PTBL_MBR)
	/* 1st sector was reserved by romboot after gxl */
	if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) {
		if (_check_ptbl_mbr(mmc, p_iptbl_ept)) {
			/*fixme, comaptible for mbr&ebr */
			ret |= _update_ptbl_mbr(mmc, p_iptbl_ept);
			apt_wrn("MBR Updated!\n");
		}
	}
#endif
#ifdef CONFIG_AML_GPT
	char *str_disk_guid;
	int gpt_priority = GPT_PRIORITY;
	disk_partition_t *disk_partition;
	int dcount = p_iptbl_ept->count;
	struct blk_desc *dev_desc = mmc_get_blk_desc(mmc);
	disk_partition = calloc(1, PAD_TO_BLOCKSIZE(sizeof(disk_partition_t) * dcount, dev_desc));
#ifdef CONFIG_AML_GPT_SYNC_ENTIRE_ENTRY
	trans_ept_to_diskpart(p_iptbl_ept, disk_partition, FALSE);
#else
	trans_ept_to_diskpart(p_iptbl_ept, disk_partition);
#endif
	str_disk_guid = malloc(UUID_STR_LEN + 1);
	if (str_disk_guid == NULL) {
		free(disk_partition);
		return -ENOMEM;
	}
	gen_rand_uuid_str(str_disk_guid, UUID_STR_FORMAT_STD);

	if (part_test_efi(mmc_get_blk_desc(mmc)) != 0) {
		ret = gpt_restore(mmc_get_blk_desc(mmc), str_disk_guid, disk_partition, dcount);
		printf("GPT IS RESTORED %s\n", ret ? "Failed!" : "OK!");
	} else if (is_gpt_changed(mmc, p_iptbl_ept)) {
		if (gpt_priority) {
			fill_ept_by_gpt(mmc, p_iptbl_ept);
#ifdef BL33_DEBUG_PRINT
			printf("and gpt has higher priority, so ept had been update\n");
#endif
		} else {
			gpt_restore(mmc_get_blk_desc(mmc), str_disk_guid, disk_partition, dcount);
#ifdef BL33_DEBUG_PRINT
			printf("but EPT has higher priority, so gpt had been recover\n");
#endif
		}
	}

	int broken_status = is_gpt_broken(mmc);
	if (broken_status != 0 && broken_status != 3) {
		fill_ept_by_gpt(mmc, p_iptbl_ept);
		free(disk_partition);
		dcount = p_iptbl_ept->count;
		disk_partition = calloc(1, PAD_TO_BLOCKSIZE(sizeof(disk_partition_t) * dcount, dev_desc));
#ifdef CONFIG_AML_GPT_SYNC_ENTIRE_ENTRY
		trans_ept_to_diskpart(p_iptbl_ept, disk_partition, TRUE);
		memset(str_disk_guid, 0, UUID_STR_LEN + 1);
		get_disk_guid(mmc_get_blk_desc(mmc), str_disk_guid);
#else
		trans_ept_to_diskpart(p_iptbl_ept, disk_partition);
#endif
		ret = gpt_restore(mmc_get_blk_desc(mmc), str_disk_guid, disk_partition, p_iptbl_ept->count);
		if (broken_status == 1)
			printf("The first gpt has been restore\n");
		else if (broken_status == 2)
			printf("The second gpt has been restore\n");
		else
			printf("Both gpt has been restore\n");
	}

	free(str_disk_guid);
	free(disk_partition);
#endif
	/* init part again */
	part_init(mmc_get_blk_desc(mmc));

_out:
#ifdef CONFIG_AML_PARTITION
	if (p_iptbl_rsv)
		_free_iptbl(p_iptbl_rsv);
#endif
	return ret;
}


struct partitions *find_mmc_partition_by_name (char const *name)
{
	struct partitions *partition = NULL;

	if (NULL == p_iptbl_ept) {
		goto _out;
	}
	partition = p_iptbl_ept->partitions;
	partition = _find_partition_by_name(partition,
			p_iptbl_ept->count, name);
_out:
	return partition;
}

/*
 find virtual partition in inherent table.
*/
int find_virtual_partition_by_name (char const *name, struct partitions *partition)
{
	int ret = 0;
	ulong offset;
	struct virtual_partition *vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	if (NULL == partition)
		return -1;

	offset = _get_inherent_offset(MMC_RESERVED_NAME);
	if (-1 == offset) {
		apt_err("can't find %s in inherent\n", MMC_RESERVED_NAME);
		return -1;
	}

	if (!strcmp(name, "dtb")) {
		strcpy(partition->name, name);
		partition->offset = offset + vpart->offset;
		partition->size = (vpart->size * DTB_COPIES);
	}

	return ret;
}

int find_dev_num_by_partition_name (char const *name)
{
	int dev = -1;

	/* card */
	if (!strcmp(name, MMC_CARD_PARTITION_NAME)) {
		dev = 0;
    } else { /* eMMC OR TSD */
		/* partition name is valid */
		if (find_mmc_partition_by_name(name)) {
			dev = 1;
		}
	}
	return dev;
}

static inline uint64_t get_part_size(struct partitions *part, int num)
{
    return part[num].size;
}

static inline uint64_t get_part_offset(struct partitions *part, int num)
{
    return part[num].offset;
}

static inline char * get_part_name(struct partitions *part, int num)
{
    return (char *)part[num].name;
}

int get_part_info_from_tbl(struct blk_desc *dev_desc,
	int num, disk_partition_t *info)
{
    int ret = 0;
    struct partitions *part;

	if (NULL == p_iptbl_ept)
        return -1;
	if (num > (p_iptbl_ept->count-1))
        return -1;
    part = p_iptbl_ept->partitions;

    /*get partition info by index! */
    info->start = (lbaint_t)(get_part_offset(part, num)/dev_desc->blksz);
    info->size = (lbaint_t)(get_part_size(part, num)/dev_desc->blksz);
	info->blksz = dev_desc->blksz;
    strcpy((char *)info->name, get_part_name(part, num));

    return ret;
}
#if (CONFIG_MPT_DEBUG)
void show_partition_info(disk_partition_t *info)
{
	printf("----------%s----------\n", __func__);
	printf("name %10s\n", info->name);
	printf("blksz " LBAFU "\n", info->blksz);
	printf("sart %ld\n", info->start);
	printf("size %ld\n", info->size);
	printf("----------end----------\n");
}
#endif


struct partitions *aml_get_partition_by_name(const char *name)
{
	struct partitions *partition = NULL;
	partition = _find_partition_by_name(emmc_partition_table,
			get_emmc_partition_arraysize(), name);
	if (partition == NULL)
		apt_wrn("do not find match in inherent table %s\n", name);
	return partition;
}

struct virtual_partition *aml_get_virtual_partition_by_name(const char *name)
{
	int i = 0, cnt;
	struct virtual_partition *part = NULL;
	cnt = get_emmc_virtual_partition_arraysize();
	while (i < cnt) {

		part = &virtual_partition_table[i];
		if (!strcmp(name, part->name)) {
			apt_info("find %10s @ tbl[%d]\n", name, i);
			break;
		}
		i++;
	};
	if (i == cnt) {
		part = NULL;
		apt_wrn("do not find match in table %10s\n", name);
	}
	return part;
}

int get_part_info_by_name(struct blk_desc *dev_desc,
	const char *name, disk_partition_t *info)
{
	struct partitions *partition = NULL;
	struct partitions virtual;
	int ret = 0;
	cpu_id_t cpu_id = get_cpu_id();

	partition = find_mmc_partition_by_name((char *)name);
	if (partition) {
		info->start = (lbaint_t)(partition->offset/dev_desc->blksz);
		info->size = (lbaint_t)(partition->size/dev_desc->blksz);
		info->blksz = dev_desc->blksz;
		strcpy((char *)info->name, partition->name);
	} else if (!find_virtual_partition_by_name((char *)name, &virtual)) {
		/* try virtual partitions */
		apt_wrn("Got %s in virtual table\n", name);
		info->start = (lbaint_t)(virtual.offset/dev_desc->blksz);
		info->size = (lbaint_t)(virtual.size/dev_desc->blksz);
		info->blksz = dev_desc->blksz;
		strcpy((char *)info->name, virtual.name);
	} else {
		/* all partitions were tried, fail */
		ret = -1;
		goto _out;
	}
	/* for bootloader */
	if ((0 == info->start) && (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL)) {
		info->start = 1;
		info->size -= 1;
	}

#if (CONFIG_MPT_DEBUG)
	show_partition_info(info);
#endif
_out:
	return ret;
}


/*
 * get the partition number by name
 * return value
 *     < 0 means no partition found
 *     >= 0 means valid partition
 */
__weak int get_partition_num_by_name(char const *name)
{
	   int ret = -1;
	   struct partitions *partition = NULL;

       if (NULL == p_iptbl_ept)
			   goto _out;
	   partition = p_iptbl_ept->partitions;
	   ret = _get_part_index_by_name(partition,
					   p_iptbl_ept->count, name);
_out:
	   return ret;
}

