platform/msm_shared/partition_parser.c
unsigned int
mmc_boot_read_gpt(struct mmc_boot_host *mmc_host,
		  struct mmc_boot_card *mmc_card)
{

	int ret = MMC_BOOT_E_SUCCESS;
	unsigned int header_size;
	unsigned long long first_usable_lba;
	unsigned long long backup_header_lba;
	unsigned long long card_size_sec;
	unsigned int max_partition_count = 0;
	unsigned int partition_entry_size;
	unsigned char data[BLOCK_SIZE];
	unsigned int i = 0;	/* Counter for each 512 block */
	unsigned int j = 0;	/* Counter for each 128 entry in the 512 block */
	unsigned int n = 0;	/* Counter for UTF-16 -> 8 conversion */
	unsigned char UTF16_name[MAX_GPT_NAME_SIZE];
	/* LBA of first partition -- 1 Block after Protected MBR + 1 for PT */
	unsigned long long partition_0;
	partition_count = 0;

	/* Print out the GPT first */
	ret = mmc_boot_read_from_card(mmc_host, mmc_card,
				      PROTECTIVE_MBR_SIZE,
				      BLOCK_SIZE, (unsigned int *)data);
	if (ret){
		dprintf(CRITICAL, "GPT: Could not read primary gpt from mmc\n");
	}

	ret = partition_parse_gpt_header(data, &first_usable_lba,
					 &partition_entry_size, &header_size,
					 &max_partition_count);
	if (ret) {
		dprintf(INFO, "GPT: (WARNING) Primary signature invalid\n");

		/* Check the backup gpt */

		/* Get size of MMC */
		card_size_sec = (mmc_card->capacity) / BLOCK_SIZE;
		ASSERT (card_size_sec > 0);

		backup_header_lba = card_size_sec - 1;
		ret =
		    mmc_boot_read_from_card(mmc_host, mmc_card,
					    (backup_header_lba * BLOCK_SIZE),
					    BLOCK_SIZE, (unsigned int *)data);

		if (ret) {
			dprintf(CRITICAL,
				"GPT: Could not read backup gpt from mmc\n");
			return ret;
		}

		ret = partition_parse_gpt_header(data, &first_usable_lba,
						 &partition_entry_size,
						 &header_size,
						 &max_partition_count);
		if (ret) {
			dprintf(CRITICAL,
				"GPT: Primary and backup signatures invalid\n");
			return ret;
		}
	}
	partition_0 = GET_LLWORD_FROM_BYTE(&data[PARTITION_ENTRIES_OFFSET]);
	/* Read GPT Entries */
	for (i = 0; i < (max_partition_count / 4); i++) {
		ASSERT(partition_count < NUM_PARTITIONS);
		ret = mmc_boot_read_from_card(mmc_host, mmc_card,
					      (partition_0 * BLOCK_SIZE) +
					      (i * BLOCK_SIZE),
					      BLOCK_SIZE, (uint32_t *) data);

		if (ret) {
			dprintf(CRITICAL,
				"GPT: mmc read card failed reading partition entries.\n");
			return ret;
		}

		for (j = 0; j < 4; j++) {
			memcpy(&(partition_entries[partition_count].type_guid),
			       &data[(j * partition_entry_size)],
			       PARTITION_TYPE_GUID_SIZE);
			if (partition_entries[partition_count].type_guid[0] ==
			    0x00
			    && partition_entries[partition_count].
			    type_guid[1] == 0x00) {
				i = max_partition_count;
				break;
			}
			memcpy(&
			       (partition_entries[partition_count].
				unique_partition_guid),
			       &data[(j * partition_entry_size) +
				     UNIQUE_GUID_OFFSET],
			       UNIQUE_PARTITION_GUID_SIZE);
			partition_entries[partition_count].first_lba =
			    GET_LLWORD_FROM_BYTE(&data
						 [(j * partition_entry_size) +
						  FIRST_LBA_OFFSET]);
			partition_entries[partition_count].last_lba =
			    GET_LLWORD_FROM_BYTE(&data
						 [(j * partition_entry_size) +
						  LAST_LBA_OFFSET]);
			partition_entries[partition_count].size =
			    partition_entries[partition_count].last_lba -
			    partition_entries[partition_count].first_lba + 1;
			partition_entries[partition_count].attribute_flag =
			    GET_LLWORD_FROM_BYTE(&data
						 [(j * partition_entry_size) +
						  ATTRIBUTE_FLAG_OFFSET]);

			memset(&UTF16_name, 0x00, MAX_GPT_NAME_SIZE);
			memcpy(UTF16_name, &data[(j * partition_entry_size) +
						 PARTITION_NAME_OFFSET],
			       MAX_GPT_NAME_SIZE);
			/*
			 * Currently partition names in *.xml are UTF-8 and lowercase
			 * Only supporting english for now so removing 2nd byte of UTF-16
			 */
			for (n = 0; n < MAX_GPT_NAME_SIZE / 2; n++) {
				partition_entries[partition_count].name[n] =
				    UTF16_name[n * 2];
			}
			partition_count++;
		}
	}
	return ret;
}
/*
 * Read GPT from MMC and fill partition table
 */
Read GPT from MMC and fill partition table
Read GPT from MMC and fill partition table
unsigned int
mmc_boot_read_gpt(struct mmc_boot_host *mmc_host,
		  struct mmc_boot_card *mmc_card)
{
	int ret = MMC_BOOT_E_SUCCESS;
	unsigned int header_size;
	unsigned long long first_usable_lba;
	unsigned long long backup_header_lba;
	unsigned long long card_size_sec;
	unsigned int max_partition_count = 0;
	unsigned int partition_entry_size;
	unsigned char data[BLOCK_SIZE];
	unsigned int i = 0;	
	unsigned int j = 0;	
	unsigned int n = 0;	
	unsigned char UTF16_name[MAX_GPT_NAME_SIZE];
	unsigned long long partition_0;
	partition_count = 0;
	ret = mmc_boot_read_from_card(mmc_host, mmc_card,
				      PROTECTIVE_MBR_SIZE,
				      BLOCK_SIZE, (unsigned int *)data);
	if (ret){
		dprintf(CRITICAL, "GPT: Could not read primary gpt from mmc\n");
	}
	ret = partition_parse_gpt_header(data, &first_usable_lba,
					 &partition_entry_size, &header_size,
					 &max_partition_count);
	if (ret) {
		dprintf(INFO, "GPT: (WARNING) Primary signature invalid\n");
		card_size_sec = (mmc_card->capacity) / BLOCK_SIZE;
		ASSERT (card_size_sec > 0);
		backup_header_lba = card_size_sec - 1;
		ret =
		    mmc_boot_read_from_card(mmc_host, mmc_card,
					    (backup_header_lba * BLOCK_SIZE),
					    BLOCK_SIZE, (unsigned int *)data);
		if (ret) {
			dprintf(CRITICAL,
				"GPT: Could not read backup gpt from mmc\n");
			return ret;
		}
		ret = partition_parse_gpt_header(data, &first_usable_lba,
						 &partition_entry_size,
						 &header_size,
						 &max_partition_count);
		if (ret) {
			dprintf(CRITICAL,
				"GPT: Primary and backup signatures invalid\n");
			return ret;
		}
	}
	partition_0 = GET_LLWORD_FROM_BYTE(&data[PARTITION_ENTRIES_OFFSET]);
	for (i = 0; i < (max_partition_count / 4); i++) {
		ASSERT(partition_count < NUM_PARTITIONS);
		ret = mmc_boot_read_from_card(mmc_host, mmc_card,
					      (partition_0 * BLOCK_SIZE) +
					      (i * BLOCK_SIZE),
					      BLOCK_SIZE, (uint32_t *) data);
		if (ret) {
			dprintf(CRITICAL,
				"GPT: mmc read card failed reading partition entries.\n");
			return ret;
		}
		for (j = 0; j < 4; j++) {
			memcpy(&(partition_entries[partition_count].type_guid),
			       &data[(j * partition_entry_size)],
			       PARTITION_TYPE_GUID_SIZE);
			if (partition_entries[partition_count].type_guid[0] ==
			    0x00
			    && partition_entries[partition_count].
			    type_guid[1] == 0x00) {
				i = max_partition_count;
				break;
			}
			memcpy(&
			       (partition_entries[partition_count].
				unique_partition_guid),
			       &data[(j * partition_entry_size) +
				     UNIQUE_GUID_OFFSET],
			       UNIQUE_PARTITION_GUID_SIZE);
			partition_entries[partition_count].first_lba =
			    GET_LLWORD_FROM_BYTE(&data
						 [(j * partition_entry_size) +
						  FIRST_LBA_OFFSET]);
			partition_entries[partition_count].last_lba =
			    GET_LLWORD_FROM_BYTE(&data
						 [(j * partition_entry_size) +
						  LAST_LBA_OFFSET]);
			partition_entries[partition_count].size =
			    partition_entries[partition_count].last_lba -
			    partition_entries[partition_count].first_lba + 1;
			partition_entries[partition_count].attribute_flag =
			    GET_LLWORD_FROM_BYTE(&data
						 [(j * partition_entry_size) +
						  ATTRIBUTE_FLAG_OFFSET]);
			memset(&UTF16_name, 0x00, MAX_GPT_NAME_SIZE);
			memcpy(UTF16_name, &data[(j * partition_entry_size) +
						 PARTITION_NAME_OFFSET],
			       MAX_GPT_NAME_SIZE);
			for (n = 0; n < MAX_GPT_NAME_SIZE / 2; n++) {
				partition_entries[partition_count].name[n] =
				    UTF16_name[n * 2];
			}
			partition_count++;
		}
	}
	return ret;
}
unsigned int mmc_boot_read_gpt ( struct mmc_boot_host * mmc_host , struct mmc_boot_card * mmc_card ) { int ret = MMC_BOOT_E_SUCCESS ; unsigned int header_size ; unsigned long long first_usable_lba ; unsigned long long backup_header_lba ; unsigned long long card_size_sec ; unsigned int max_partition_count = 0 ; unsigned int partition_entry_size ; unsigned char data [ BLOCK_SIZE ] ; unsigned int i = 0 ; unsigned int j = 0 ; unsigned int n = 0 ; unsigned char UTF16_name [ MAX_GPT_NAME_SIZE ] ; unsigned long long partition_0 ; partition_count = 0 ; ret = mmc_boot_read_from_card ( mmc_host , mmc_card , PROTECTIVE_MBR_SIZE , BLOCK_SIZE , ( unsigned int * ) data ) ; if ( ret ) { dprintf ( CRITICAL , " \n " ) ; } ret = partition_parse_gpt_header ( data , & first_usable_lba , & partition_entry_size , & header_size , & max_partition_count ) ; if ( ret ) { dprintf ( INFO , " \n " ) ; card_size_sec = ( mmc_card -> capacity ) / BLOCK_SIZE ; ASSERT ( card_size_sec > 0 ) ; backup_header_lba = card_size_sec - 1 ; ret = mmc_boot_read_from_card ( mmc_host , mmc_card , ( backup_header_lba * BLOCK_SIZE ) , BLOCK_SIZE , ( unsigned int * ) data ) ; if ( ret ) { dprintf ( CRITICAL , " \n " ) ; return ret ; } ret = partition_parse_gpt_header ( data , & first_usable_lba , & partition_entry_size , & header_size , & max_partition_count ) ; if ( ret ) { dprintf ( CRITICAL , " \n " ) ; return ret ; } } partition_0 = GET_LLWORD_FROM_BYTE ( & data [ PARTITION_ENTRIES_OFFSET ] ) ; for ( i = 0 ; i < ( max_partition_count / 4 ) ; i ++ ) { ASSERT ( partition_count < NUM_PARTITIONS ) ; ret = mmc_boot_read_from_card ( mmc_host , mmc_card , ( partition_0 * BLOCK_SIZE ) + ( i * BLOCK_SIZE ) , BLOCK_SIZE , ( uint32_t * ) data ) ; if ( ret ) { dprintf ( CRITICAL , " \n " ) ; return ret ; } for ( j = 0 ; j < 4 ; j ++ ) { memcpy ( & ( partition_entries [ partition_count ] . type_guid ) , & data [ ( j * partition_entry_size ) ] , PARTITION_TYPE_GUID_SIZE ) ; if ( partition_entries [ partition_count ] . type_guid [ 0 ] == 0x00 && partition_entries [ partition_count ] . type_guid [ 1 ] == 0x00 ) { i = max_partition_count ; break ; } memcpy ( & ( partition_entries [ partition_count ] . unique_partition_guid ) , & data [ ( j * partition_entry_size ) + UNIQUE_GUID_OFFSET ] , UNIQUE_PARTITION_GUID_SIZE ) ; partition_entries [ partition_count ] . first_lba = GET_LLWORD_FROM_BYTE ( & data [ ( j * partition_entry_size ) + FIRST_LBA_OFFSET ] ) ; partition_entries [ partition_count ] . last_lba = GET_LLWORD_FROM_BYTE ( & data [ ( j * partition_entry_size ) + LAST_LBA_OFFSET ] ) ; partition_entries [ partition_count ] . size = partition_entries [ partition_count ] . last_lba - partition_entries [ partition_count ] . first_lba + 1 ; partition_entries [ partition_count ] . attribute_flag = GET_LLWORD_FROM_BYTE ( & data [ ( j * partition_entry_size ) + ATTRIBUTE_FLAG_OFFSET ] ) ; memset ( & UTF16_name , 0x00 , MAX_GPT_NAME_SIZE ) ; memcpy ( UTF16_name , & data [ ( j * partition_entry_size ) + PARTITION_NAME_OFFSET ] , MAX_GPT_NAME_SIZE ) ; for ( n = 0 ; n < MAX_GPT_NAME_SIZE / 2 ; n ++ ) { partition_entries [ partition_count ] . name [ n ] = UTF16_name [ n * 2 ] ; } partition_count ++ ; } } return ret ; }
Read GPT from MMC and fill partition table
Read GPT from MMC and fill partition table
/* Counter for each 512 block */ /* Counter for each 128 entry in the 512 block */ /* Counter for UTF-16 -> 8 conversion */ /* LBA of first partition -- 1 Block after Protected MBR + 1 for PT */ /* Print out the GPT first */ /* Check the backup gpt */ /* Get size of MMC */ /* Read GPT Entries */ /*
			 * Currently partition names in *.xml are UTF-8 and lowercase
			 * Only supporting english for now so removing 2nd byte of UTF-16
			 */