platform: msm_shared: Fix block size assumptions in partition parser.

Partition parser assumes BLOCK_SIZE to a constant value, fix this
by passing block size from device attributes as an argument to
partition parser.

Change-Id: I4e4df69c83fc7556f6eb6bc3351751f42ca914da
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 6c0ae6c..e2d548e 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -31,8 +31,8 @@
 #include "mmc.h"
 #include "partition_parser.h"
 
-static uint32_t mmc_boot_read_gpt();
-static uint32_t mmc_boot_read_mbr();
+static uint32_t mmc_boot_read_gpt(uint32_t block_size);
+static uint32_t mmc_boot_read_mbr(uint32_t block_size);
 static void mbr_fill_name(struct partition_entry *partition_ent,
 						  uint32_t type);
 static uint32_t partition_verify_mbr_signature(uint32_t size,
@@ -48,8 +48,8 @@
 										   uint32_t *header_size,
 										   uint32_t *max_partition_count);
 
-static uint32_t write_mbr(uint32_t, uint8_t *mbrImage);
-static uint32_t write_gpt(uint32_t size, uint8_t *gptImage);
+static uint32_t write_mbr(uint32_t, uint8_t *mbrImage, uint32_t block_size);
+static uint32_t write_gpt(uint32_t size, uint8_t *gptImage, uint32_t block_size);
 
 char *ext3_partitions[] =
     { "system", "userdata", "persist", "cache", "tombstones" };
@@ -65,9 +65,12 @@
 unsigned int partition_read_table()
 {
 	unsigned int ret;
+	uint32_t block_size;
+
+	block_size = mmc_get_device_blocksize();
 
 	/* Read MBR of the card */
-	ret = mmc_boot_read_mbr();
+	ret = mmc_boot_read_mbr(block_size);
 	if (ret) {
 		dprintf(CRITICAL, "MMC Boot: MBR read failed!\n");
 		return 1;
@@ -75,7 +78,7 @@
 
 	/* Read GPT of the card if exist */
 	if (gpt_partitions_exist) {
-		ret = mmc_boot_read_gpt();
+		ret = mmc_boot_read_gpt(block_size);
 		if (ret) {
 			dprintf(CRITICAL, "MMC Boot: GPT read failed!\n");
 			return 1;
@@ -87,9 +90,9 @@
 /*
  * Read MBR from MMC card and fill partition table.
  */
-static unsigned int mmc_boot_read_mbr()
+static unsigned int mmc_boot_read_mbr(uint32_t block_size)
 {
-	BUF_DMA_ALIGN(buffer, BLOCK_SIZE);
+	uint8_t *buffer = NULL;
 	unsigned int dtype;
 	unsigned int dfirstsec;
 	unsigned int EBR_first_sec;
@@ -97,17 +100,26 @@
 	int ret = 0;
 	int idx, i;
 
+	buffer = (uint8_t *)memalign(CACHE_LINE, ROUNDUP(block_size, CACHE_LINE));
+
+	if (!buffer)
+	{
+		dprintf(CRITICAL, "Error allocating memory while reading partition table\n");
+		ret = -1;
+		goto end;
+	}
+
 	/* Print out the MBR first */
-	ret = mmc_read(0, (unsigned int *)buffer, BLOCK_SIZE);
+	ret = mmc_read(0, (unsigned int *)buffer, block_size);
 	if (ret) {
 		dprintf(CRITICAL, "Could not read partition from mmc\n");
-		return ret;
+		goto end;
 	}
 
 	/* Check to see if signature exists */
-	ret = partition_verify_mbr_signature(BLOCK_SIZE, buffer);
+	ret = partition_verify_mbr_signature(block_size, buffer);
 	if (ret) {
-		return ret;
+		goto end;
 	}
 
 	/*
@@ -121,7 +133,7 @@
 		dtype = buffer[idx + i * TABLE_ENTRY_SIZE + OFFSET_TYPE];
 		if (dtype == MBR_PROTECTED_TYPE) {
 			gpt_partitions_exist = 1;
-			return ret;
+			goto end;
 		}
 		partition_entries[partition_count].dtype = dtype;
 		partition_entries[partition_count].attribute_flag =
@@ -139,24 +151,24 @@
 			      partition_entries[partition_count].dtype);
 		partition_count++;
 		if (partition_count == NUM_PARTITIONS)
-			return ret;
+			goto end;
 	}
 
 	/* See if the last partition is EBR, if not, parsing is done */
 	if (dtype != MBR_EBR_TYPE) {
-		return ret;
+		goto end;
 	}
 
 	EBR_first_sec = dfirstsec;
 	EBR_current_sec = dfirstsec;
 
-	ret = mmc_read((EBR_first_sec * 512), (unsigned int *)buffer, BLOCK_SIZE);
+	ret = mmc_read((EBR_first_sec * block_size), (unsigned int *)buffer, block_size);
 	if (ret)
-		return ret;
+		goto end;
 
 	/* Loop to parse the EBR */
 	for (i = 0;; i++) {
-		ret = partition_verify_mbr_signature(BLOCK_SIZE, buffer);
+		ret = partition_verify_mbr_signature(block_size, buffer);
 		if (ret) {
 			ret = 0;
 			break;
@@ -175,7 +187,7 @@
 			      partition_entries[partition_count].dtype);
 		partition_count++;
 		if (partition_count == NUM_PARTITIONS)
-			return ret;
+			goto end;
 
 		dfirstsec =
 		    GET_LWORD_FROM_BYTE(&buffer
@@ -187,22 +199,25 @@
 		/* More EBR to follow - read in the next EBR sector */
 		dprintf(SPEW, "Reading EBR block from 0x%X\n", EBR_first_sec
 			+ dfirstsec);
-		ret = mmc_read(((EBR_first_sec + dfirstsec) * 512),(unsigned int *)buffer,
-						BLOCK_SIZE);
+		ret = mmc_read(((EBR_first_sec + dfirstsec) * block_size),(unsigned int *)buffer,
+						block_size);
 		if (ret)
-			return ret;
+			goto end;
 
 		EBR_current_sec = EBR_first_sec + dfirstsec;
 	}
+end:
+	if (buffer)
+		free(buffer);
+
 	return ret;
 }
 
 /*
  * Read GPT from MMC and fill partition table
  */
-static unsigned int mmc_boot_read_gpt()
+static unsigned int mmc_boot_read_gpt(uint32_t block_size)
 {
-	BUF_DMA_ALIGN(data, BLOCK_SIZE);
 	int ret = 0;
 	unsigned int header_size;
 	unsigned long long first_usable_lba;
@@ -210,13 +225,15 @@
 	unsigned long long card_size_sec;
 	unsigned int max_partition_count = 0;
 	unsigned int partition_entry_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 i = 0;	/* Counter for each block */
+	unsigned int j = 0;	/* Counter for each entry in a 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;
 	uint64_t device_density;
+	uint8_t *data = NULL;
+	uint32_t part_entry_cnt = block_size / ENTRY_SIZE;
 
 	partition_count = 0;
 
@@ -224,12 +241,20 @@
 
 	device_density = mmc_get_device_capacity();
 
+	data = (uint8_t *)memalign(CACHE_LINE, ROUNDUP(block_size, CACHE_LINE));
+	if (!data)
+	{
+		dprintf(CRITICAL, "Failed to Allocate memory to read partition table\n");
+		ret = -1;
+		goto end;
+	}
+
 	/* Print out the GPT first */
-	ret = mmc_read(PROTECTIVE_MBR_SIZE, (unsigned int *)data, BLOCK_SIZE);
+	ret = mmc_read(block_size, (unsigned int *)data, block_size);
 	if (ret)
 	{
 		dprintf(CRITICAL, "GPT: Could not read primary gpt from mmc\n");
-		return ret;
+		goto end;
 	}
 
 	ret = partition_parse_gpt_header(data, &first_usable_lba,
@@ -241,17 +266,17 @@
 		/* Check the backup gpt */
 
 		/* Get size of MMC */
-		card_size_sec = (device_density) / BLOCK_SIZE;
+		card_size_sec = (device_density) / block_size;
 		ASSERT (card_size_sec > 0);
 
 		backup_header_lba = card_size_sec - 1;
-		ret = mmc_read((backup_header_lba * BLOCK_SIZE), (unsigned int *)data,
-						BLOCK_SIZE);
+		ret = mmc_read((backup_header_lba * block_size), (unsigned int *)data,
+						block_size);
 
 		if (ret) {
 			dprintf(CRITICAL,
 				"GPT: Could not read backup gpt from mmc\n");
-			return ret;
+			goto end;
 		}
 
 		ret = partition_parse_gpt_header(data, &first_usable_lba,
@@ -261,23 +286,23 @@
 		if (ret) {
 			dprintf(CRITICAL,
 				"GPT: Primary and backup signatures invalid\n");
-			return ret;
+			goto end;
 		}
 	}
 	partition_0 = GET_LLWORD_FROM_BYTE(&data[PARTITION_ENTRIES_OFFSET]);
 	/* Read GPT Entries */
-	for (i = 0; i < (ROUNDUP(max_partition_count, 4)) / 4; i++) {
+	for (i = 0; i < (ROUNDUP(max_partition_count, part_entry_cnt)) / part_entry_cnt; i++) {
 		ASSERT(partition_count < NUM_PARTITIONS);
-		ret = mmc_read((partition_0 * BLOCK_SIZE) + (i * BLOCK_SIZE),
-						(uint32_t *) data, BLOCK_SIZE);
+		ret = mmc_read((partition_0 * block_size) + (i * block_size),
+						(uint32_t *) data, block_size);
 
 		if (ret) {
 			dprintf(CRITICAL,
 				"GPT: mmc read card failed reading partition entries.\n");
-			return ret;
+			goto end;
 		}
 
-		for (j = 0; j < 4; j++) {
+		for (j = 0; j < part_entry_cnt; j++) {
 			memcpy(&(partition_entries[partition_count].type_guid),
 			       &data[(j * partition_entry_size)],
 			       PARTITION_TYPE_GUID_SIZE);
@@ -285,7 +310,7 @@
 			    0x00
 			    && partition_entries[partition_count].
 			    type_guid[1] == 0x00) {
-				i = ROUNDUP(max_partition_count, 4);
+				i = ROUNDUP(max_partition_count, part_entry_cnt);
 				break;
 			}
 			memcpy(&
@@ -325,10 +350,14 @@
 			partition_count++;
 		}
 	}
+end:
+	if (data)
+		free(data);
+
 	return ret;
 }
 
-static unsigned int write_mbr_in_blocks(unsigned size, unsigned char *mbrImage)
+static unsigned int write_mbr_in_blocks(uint32_t size, uint8_t *mbrImage, uint32_t block_size)
 {
 	unsigned int dtype;
 	unsigned int dfirstsec;
@@ -339,7 +368,7 @@
 	unsigned int ret;
 
 	/* Write the first block */
-	ret = mmc_write(0, BLOCK_SIZE, (unsigned int *)mbrImage);
+	ret = mmc_write(0, block_size, (unsigned int *)mbrImage);
 	if (ret) {
 		dprintf(CRITICAL, "Failed to write mbr partition\n");
 		goto end;
@@ -362,7 +391,7 @@
 		goto end;
 	}
 	/* EBR exists.  Write each EBR block to mmc */
-	ebrImage = mbrImage + BLOCK_SIZE;
+	ebrImage = mbrImage + block_size;
 	ebrSectorOffset =
 	    GET_LWORD_FROM_BYTE(&mbrImage
 				[idx + i * TABLE_ENTRY_SIZE +
@@ -372,10 +401,10 @@
 	lastAddress = mbrImage + size;
 	while (ebrImage < lastAddress) {
 		dprintf(SPEW, "writing to 0x%X\n",
-			(ebrSectorOffset + dfirstsec) * BLOCK_SIZE);
+			(ebrSectorOffset + dfirstsec) * block_size);
 		ret =
-		    mmc_write((ebrSectorOffset + dfirstsec) * BLOCK_SIZE,
-			      BLOCK_SIZE, (unsigned int *)ebrImage);
+		    mmc_write((ebrSectorOffset + dfirstsec) * block_size,
+			      block_size, (unsigned int *)ebrImage);
 		if (ret) {
 			dprintf(CRITICAL,
 				"Failed to write EBR block to sector 0x%X\n",
@@ -385,7 +414,7 @@
 		dfirstsec =
 		    GET_LWORD_FROM_BYTE(&ebrImage
 					[TABLE_ENTRY_1 + OFFSET_FIRST_SEC]);
-		ebrImage += BLOCK_SIZE;
+		ebrImage += block_size;
 	}
 	dprintf(INFO, "MBR written to mmc successfully\n");
  end:
@@ -393,7 +422,7 @@
 }
 
 /* Write the MBR/EBR to the MMC. */
-static unsigned int write_mbr(unsigned size, unsigned char *mbrImage)
+static unsigned int write_mbr(uint32_t size, uint8_t *mbrImage, uint32_t block_size)
 {
 	unsigned int ret;
 
@@ -404,13 +433,13 @@
 	}
 
 	/* Write the MBR/EBR to mmc */
-	ret = write_mbr_in_blocks(size, mbrImage);
+	ret = write_mbr_in_blocks(size, mbrImage, block_size);
 	if (ret) {
 		dprintf(CRITICAL, "Failed to write MBR block to mmc.\n");
 		goto end;
 	}
 	/* Re-read the MBR partition into mbr table */
-	ret = mmc_boot_read_mbr();
+	ret = mmc_boot_read_mbr(block_size);
 	if (ret) {
 		dprintf(CRITICAL, "Failed to re-read mbr partition.\n");
 		goto end;
@@ -475,9 +504,10 @@
  * Write the GPT Partition Entry Array to the MMC.
  */
 static unsigned int
-write_gpt_partition_array(unsigned char *header,
-			  unsigned int partition_array_start,
-			  unsigned int array_size)
+write_gpt_partition_array(uint8_t *header,
+						  uint32_t partition_array_start,
+						  uint32_t array_size,
+						  uint32_t block_size)
 {
 	unsigned int ret = 1;
 	unsigned long long partition_entry_lba;
@@ -485,7 +515,7 @@
 
 	partition_entry_lba =
 	    GET_LLWORD_FROM_BYTE(&header[PARTITION_ENTRIES_OFFSET]);
-	partition_entry_array_start_location = partition_entry_lba * BLOCK_SIZE;
+	partition_entry_array_start_location = partition_entry_lba * block_size;
 
 	ret = mmc_write(partition_entry_array_start_location, array_size,
 			(unsigned int *)partition_array_start);
@@ -500,8 +530,8 @@
 }
 
 static void
-patch_gpt(unsigned char *gptImage, uint64_t density, unsigned int array_size,
-		  unsigned int max_part_count, unsigned int part_entry_size)
+patch_gpt(uint8_t *gptImage, uint64_t density, uint32_t array_size,
+		  uint32_t max_part_count, uint32_t part_entry_size, uint32_t block_size)
 {
 	unsigned int partition_entry_array_start;
 	unsigned char *primary_gpt_header;
@@ -513,14 +543,14 @@
 	unsigned int crc_value;
 
 	/* Get size of MMC */
-	card_size_sec = (density) / 512;
+	card_size_sec = (density) / block_size;
 	/* Working around cap at 4GB */
 	if (card_size_sec == 0) {
 		card_size_sec = 4 * 1024 * 1024 * 2 - 1;
 	}
 
 	/* Patching primary header */
-	primary_gpt_header = (gptImage + PROTECTIVE_MBR_SIZE);
+	primary_gpt_header = (gptImage + block_size);
 	PUT_LONG_LONG(primary_gpt_header + BACKUP_HEADER_OFFSET,
 		      ((long long)(card_size_sec - 1)));
 	PUT_LONG_LONG(primary_gpt_header + LAST_USABLE_LBA_OFFSET,
@@ -528,7 +558,7 @@
 
 	/* Patching backup GPT */
 	offset = (2 * array_size);
-	secondary_gpt_header = offset + BLOCK_SIZE + primary_gpt_header;
+	secondary_gpt_header = offset + block_size + primary_gpt_header;
 	PUT_LONG_LONG(secondary_gpt_header + PRIMARY_HEADER_OFFSET,
 		      ((long long)(card_size_sec - 1)));
 	PUT_LONG_LONG(secondary_gpt_header + LAST_USABLE_LBA_OFFSET,
@@ -537,7 +567,7 @@
 		      ((long long)(card_size_sec - 33)));
 
 	/* Find last partition */
-	while (*(primary_gpt_header + BLOCK_SIZE + total_part * ENTRY_SIZE) !=
+	while (*(primary_gpt_header + block_size + total_part * ENTRY_SIZE) !=
 	       0) {
 		total_part++;
 	}
@@ -545,13 +575,13 @@
 	/* Patching last partition */
 	last_part_offset =
 	    (total_part - 1) * ENTRY_SIZE + PARTITION_ENTRY_LAST_LBA;
-	PUT_LONG_LONG(primary_gpt_header + BLOCK_SIZE + last_part_offset,
+	PUT_LONG_LONG(primary_gpt_header + block_size + last_part_offset,
 		      (long long)(card_size_sec - 34));
-	PUT_LONG_LONG(primary_gpt_header + BLOCK_SIZE + last_part_offset +
+	PUT_LONG_LONG(primary_gpt_header + block_size + last_part_offset +
 		      array_size, (long long)(card_size_sec - 34));
 
 	/* Updating CRC of the Partition entry array in both headers */
-	partition_entry_array_start = primary_gpt_header + BLOCK_SIZE;
+	partition_entry_array_start = primary_gpt_header + block_size;
 	crc_value = calculate_crc32(partition_entry_array_start,
 				    max_part_count * part_entry_size);
 	PUT_LONG(primary_gpt_header + PARTITION_CRC_OFFSET, crc_value);
@@ -574,7 +604,7 @@
 /*
  * Write the GPT to the MMC.
  */
-static unsigned int write_gpt(unsigned size, unsigned char *gptImage)
+static unsigned int write_gpt(uint32_t size, uint8_t *gptImage, uint32_t block_size)
 {
 	unsigned int ret = 1;
 	unsigned int header_size;
@@ -592,7 +622,7 @@
 	uint64_t device_density;
 
 	/* Verify that passed block has a valid GPT primary header */
-	primary_gpt_header = (gptImage + PROTECTIVE_MBR_SIZE);
+	primary_gpt_header = (gptImage + block_size);
 	ret = partition_parse_gpt_header(primary_gpt_header, &first_usable_lba,
 					 &partition_entry_size, &header_size,
 					 &max_partition_count);
@@ -612,7 +642,7 @@
 		partition_entry_array_size = MIN_PARTITION_ARRAY_SIZE;
 	}
 	offset = (2 * partition_entry_array_size);
-	secondary_gpt_header = offset + BLOCK_SIZE + primary_gpt_header;
+	secondary_gpt_header = offset + block_size + primary_gpt_header;
 	ret =
 	    partition_parse_gpt_header(secondary_gpt_header, &first_usable_lba,
 				       &partition_entry_size, &header_size,
@@ -625,7 +655,7 @@
 
 	/* Patching the primary and the backup header of the GPT table */
 	patch_gpt(gptImage, device_density, partition_entry_array_size,
-		  max_partition_count, partition_entry_size);
+		  max_partition_count, partition_entry_size, block_size);
 
 	/* Erasing the eMMC card before writing */
 	ret = mmc_erase_card(0x00000000, device_density);
@@ -635,14 +665,14 @@
 	}
 
 	/* Writing protective MBR */
-	ret = mmc_write(0, PROTECTIVE_MBR_SIZE, (unsigned int *)gptImage);
+	ret = mmc_write(0, block_size, (unsigned int *)gptImage);
 	if (ret) {
 		dprintf(CRITICAL, "Failed to write Protective MBR\n");
 		goto end;
 	}
 	/* Writing the primary GPT header */
-	primary_header_location = PROTECTIVE_MBR_SIZE;
-	ret = mmc_write(primary_header_location, BLOCK_SIZE,
+	primary_header_location = block_size;
+	ret = mmc_write(primary_header_location, block_size,
 			(unsigned int *)primary_gpt_header);
 	if (ret) {
 		dprintf(CRITICAL, "Failed to write GPT header\n");
@@ -652,8 +682,8 @@
 	/* Writing the backup GPT header */
 	backup_header_lba = GET_LLWORD_FROM_BYTE
 	    (&primary_gpt_header[BACKUP_HEADER_OFFSET]);
-	secondary_header_location = backup_header_lba * BLOCK_SIZE;
-	ret = mmc_write(secondary_header_location, BLOCK_SIZE,
+	secondary_header_location = backup_header_lba * block_size;
+	ret = mmc_write(secondary_header_location, block_size,
 			(unsigned int *)secondary_gpt_header);
 	if (ret) {
 		dprintf(CRITICAL, "Failed to write GPT backup header\n");
@@ -661,10 +691,10 @@
 	}
 
 	/* Writing the partition entries array for the primary header */
-	partition_entry_array_start = primary_gpt_header + BLOCK_SIZE;
+	partition_entry_array_start = primary_gpt_header + block_size;
 	ret = write_gpt_partition_array(primary_gpt_header,
 					partition_entry_array_start,
-					partition_entry_array_size);
+					partition_entry_array_size, block_size);
 	if (ret) {
 		dprintf(CRITICAL,
 			"GPT: Could not write GPT Partition entries array\n");
@@ -672,11 +702,11 @@
 	}
 
 	/*Writing the partition entries array for the backup header */
-	partition_entry_array_start = primary_gpt_header + BLOCK_SIZE +
+	partition_entry_array_start = primary_gpt_header + block_size +
 	    partition_entry_array_size;
 	ret = write_gpt_partition_array(secondary_gpt_header,
 					partition_entry_array_start,
-					partition_entry_array_size);
+					partition_entry_array_size, block_size);
 	if (ret) {
 		dprintf(CRITICAL,
 			"GPT: Could not write GPT Partition entries array\n");
@@ -685,7 +715,7 @@
 
 	/* Re-read the GPT partition table */
 	dprintf(INFO, "Re-reading the GPT Partition Table\n");
-	ret = mmc_boot_read_gpt();
+	ret = mmc_boot_read_gpt(block_size);
 	if (ret) {
 		dprintf(CRITICAL,
 			"GPT: Failure to re- read the GPT Partition table\n");
@@ -703,12 +733,14 @@
 {
 	unsigned int ret = 1;
 	unsigned int partition_type;
+	uint32_t block_size;
 
 	if (partition == 0) {
 		dprintf(CRITICAL, "NULL partition\n");
 		goto end;
 	}
 
+	block_size = mmc_get_device_blocksize();
 	ret = partition_get_type(size, partition, &partition_type);
 	if (ret)
 		goto end;
@@ -716,12 +748,12 @@
 	switch (partition_type) {
 	case PARTITION_TYPE_MBR:
 		dprintf(INFO, "Writing MBR partition\n");
-		ret = write_mbr(size, partition);
+		ret = write_mbr(size, partition, block_size);
 		break;
 
 	case PARTITION_TYPE_GPT:
 		dprintf(INFO, "Writing GPT partition\n");
-		ret = write_gpt(size, partition);
+		ret = write_gpt(size, partition, block_size);
 		dprintf(CRITICAL, "Re-Flash all the partitions\n");
 		break;
 
@@ -833,20 +865,28 @@
 /* Get size of the partition */
 unsigned long long partition_get_size(int index)
 {
+	uint32_t block_size;
+
+	block_size = mmc_get_device_blocksize();
+
 	if (index == INVALID_PTN)
 		return 0;
 	else {
-		return partition_entries[index].size * BLOCK_SIZE;
+		return partition_entries[index].size * block_size;
 	}
 }
 
 /* Get offset of the partition */
 unsigned long long partition_get_offset(int index)
 {
+	uint32_t block_size;
+
+	block_size = mmc_get_device_blocksize();
+
 	if (index == INVALID_PTN)
 		return 0;
 	else {
-		return partition_entries[index].first_lba * BLOCK_SIZE;
+		return partition_entries[index].first_lba * block_size;
 	}
 }