Merge "platform: msm8953: correct the max peripheral address of pmi8950" into lk.lnx.1.0-dev.1.0
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 33ee59b..8ef8857 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -819,7 +819,7 @@
  * start: Start of the memory region
  * size: Size of the memory region
  */
-int check_aboot_addr_range_overlap(uint32_t start, uint32_t size)
+int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size)
 {
 	/* Check for boundary conditions. */
 	if ((UINT_MAX - start) < size)
@@ -1128,7 +1128,7 @@
 	boot_verifier_init();
 #endif
 
-	if (check_aboot_addr_range_overlap((uint32_t) image_addr, imagesize_actual))
+	if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
 	{
 		dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
 		return -1;
@@ -1179,7 +1179,7 @@
 	if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
 	{
 		offset = imagesize_actual;
-		if (check_aboot_addr_range_overlap((uint32_t)image_addr + offset, page_size))
+		if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
 		{
 			dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
 			return -1;
@@ -2649,8 +2649,29 @@
 	int i, images;
 	meta_header_t *meta_header;
 	img_header_entry_t *img_header_entry;
+	/*End of the image address*/
+	uintptr_t data_end;
+
+	if( (UINT_MAX - sz) > (uintptr_t)data )
+		data_end  = (uintptr_t)data + sz;
+	else
+	{
+		fastboot_fail("Cannot  flash: image header corrupt");
+		return;
+	}
+
+	if( data_end < ((uintptr_t)data + sizeof(meta_header_t)))
+	{
+		fastboot_fail("Cannot  flash: image header corrupt");
+		return;
+	}
 
 	meta_header = (meta_header_t*) data;
+	if( data_end < ((uintptr_t)data + meta_header->img_hdr_sz))
+	{
+		fastboot_fail("Cannot  flash: image header corrupt");
+		return;
+	}
 	img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
 
 	images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
@@ -2662,6 +2683,13 @@
 			(img_header_entry[i].size == 0))
 			break;
 
+		if( data_end < ((uintptr_t)data + img_header_entry[i].start_offset
+						+ img_header_entry[i].size) )
+		{
+			fastboot_fail("Cannot  flash: image size mismatch");
+			break;
+		}
+
 		cmd_flash_mmc_img(img_header_entry[i].ptn_name,
 					(void *) data + img_header_entry[i].start_offset,
 					img_header_entry[i].size);
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index e1e9568..f021759 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -72,7 +72,7 @@
 uint32_t g_mdtp_version = (((MDTP_MAJOR_VERSION << 16) & 0xFFFF0000) | (MDTP_MINOR_VERSION & 0x0000FFFF));
 static int is_mdtp_activated = -1;
 
-int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+extern int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size);
 int scm_random(uint32_t * rbuf, uint32_t  r_len);
 extern void mdelay(unsigned msecs);
 void free_mdtp_image(void);
@@ -272,7 +272,7 @@
 
 	/* initiating parameters for hash calculation using HW crypto */
 	target_crypto_init_params();
-	if (check_aboot_addr_range_overlap((uint32_t)buf, ROUNDUP(MDTP_FWLOCK_BLOCK_SIZE, block_size)))
+	if (check_aboot_addr_range_overlap((uintptr_t)buf, ROUNDUP(MDTP_FWLOCK_BLOCK_SIZE, block_size)))
 	{
 		dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: image buffer address overlaps with aboot addresses.\n", name);
 		return -1;
@@ -514,7 +514,7 @@
 		/* 3) Signature may or may not be at the end of the image. Read the signature if needed. */
 		if (!ext_partition->sig_avail)
 		{
-			if (check_aboot_addr_range_overlap((uint32_t)(ext_partition->image_addr + ext_partition->image_size), ext_partition->page_size))
+			if (check_aboot_addr_range_overlap((uintptr_t)(ext_partition->image_addr + ext_partition->image_size), ext_partition->page_size))
 			{
 				dprintf(CRITICAL, "ERROR: Signature read buffer address overlaps with aboot addresses.\n");
 				return -1;
diff --git a/app/aboot/recovery.c b/app/aboot/recovery.c
index 96441e2..8aa4a8c 100644
--- a/app/aboot/recovery.c
+++ b/app/aboot/recovery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2016, 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
@@ -654,7 +654,7 @@
 		retval = -1;
 		goto cleanup;
 	}
-	ffbm_page_buffer = (char*)malloc(page_size);
+	ffbm_page_buffer = (char*)memalign(CACHE_LINE, page_size);
 	if (!ffbm_page_buffer)
 	{
 		dprintf(CRITICAL, "Failed to alloc buffer for ffbm cookie\n");
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 40c24a4..6a73826 100755
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -58,7 +58,7 @@
 /* TODO: This function needs to be moved to target layer to check violations
  * against all the other regions as well.
  */
-extern int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+extern int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size);
 
 int fdt_check_header_ext(const void *fdt)
 {
@@ -486,11 +486,6 @@
 			break;
 		dtb_size = fdt_totalsize(&dtb_hdr);
 
-		if (check_aboot_addr_range_overlap((uint32_t)tags, dtb_size)) {
-			dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
-			return NULL;
-		}
-
 		dev_tree_compatible(dtb, dtb_size, dt_entry_queue);
 
 		/* goto the next device tree if any */
@@ -521,6 +516,10 @@
 	}
 
 	if(bestmatch_tag) {
+		if (check_aboot_addr_range_overlap((uintptr_t)tags, bestmatch_tag_size)) {
+			dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+			return NULL;
+		}
 		memcpy(tags, bestmatch_tag, bestmatch_tag_size);
 		/* clear out the old DTB magic so kernel doesn't find it */
 		*((uint32_t *)(kernel + app_dtb_offset)) = 0;
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
index c955e1b..fb4e0a8 100644
--- a/platform/msm_shared/display_menu.c
+++ b/platform/msm_shared/display_menu.c
@@ -94,7 +94,8 @@
 		[0] = "START\n",
 		[1] = "Restart bootloader\n",
 		[2] = "Recovery mode\n",
-		[3] = "Power off\n"};
+		[3] = "Power off\n",
+		[4] = "Boot to FFBM\n"};
 
 static int big_factor = 2;
 static int common_factor = 1;
@@ -362,6 +363,7 @@
 			msg_type = FBCON_RED_MSG;
 			break;
 		case 3:
+		case 4:
 			msg_type = FBCON_COMMON_MSG;
 			break;
 	}
diff --git a/platform/msm_shared/include/menu_keys_detect.h b/platform/msm_shared/include/menu_keys_detect.h
index 2d51aa1..4f904c4 100644
--- a/platform/msm_shared/include/menu_keys_detect.h
+++ b/platform/msm_shared/include/menu_keys_detect.h
@@ -37,6 +37,7 @@
 	BACK,
 
 	CONTINUE,
+	FFBM,
 };
 
 enum keys_option {
diff --git a/platform/msm_shared/menu_keys_detect.c b/platform/msm_shared/menu_keys_detect.c
index d3bc107..7430329 100644
--- a/platform/msm_shared/menu_keys_detect.c
+++ b/platform/msm_shared/menu_keys_detect.c
@@ -88,6 +88,7 @@
 		[1] = FASTBOOT,
 		[2] = RECOVER,
 		[3] = POWEROFF,
+		[4] = FFBM,
 };
 
 static uint32_t unlock_index_action[] = {
@@ -111,6 +112,7 @@
 
 static void update_device_status(struct select_msg_info* msg_info, int reason)
 {
+	char ffbm_page_buffer[FFBM_MODE_BUF_SIZE];
 	fbcon_clear();
 	switch (reason) {
 		case RECOVER:
@@ -150,6 +152,12 @@
 			before_time = current_time();
 
 			break;
+		case FFBM:
+			snprintf(ffbm_page_buffer, sizeof(ffbm_page_buffer), "ffbm-00");
+			write_misc(0, ffbm_page_buffer, sizeof(ffbm_page_buffer));
+
+			reboot_device(0);
+			break;
 	}
 }