Merge "app: aboot: zero out extra bits, while update misc partition."
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 834fe07..6e8f000 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -259,7 +259,7 @@
  * for fastboot
  */
 struct getvar_partition_info {
-	const char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
+	char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
 	char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
 	char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
 	char size_response[MAX_RSP_SIZE];        /* fastboot response for size */
@@ -267,10 +267,10 @@
 };
 
 /*
- * Right now, we are publishing the info for only
- * three partitions
+ * Update the part_type_known for known paritions types.
  */
-struct getvar_partition_info part_info[] =
+struct getvar_partition_info part_info[NUM_PARTITIONS];
+struct getvar_partition_info part_type_known[] =
 {
 	{ "system"  , "partition-size:", "partition-type:", "", "ext4" },
 	{ "userdata", "partition-size:", "partition-type:", "", "ext4" },
@@ -282,6 +282,13 @@
 char sn_buf[13];
 char display_panel_buf[MAX_PANEL_BUF_SIZE];
 char panel_display_mode[MAX_RSP_SIZE];
+#if PRODUCT_IOT
+char block_size_string[MAX_RSP_SIZE];
+
+/* For IOT we are using custom version */
+#define PRODUCT_IOT_VERSION "IOT001"
+char bootloader_version_string[MAX_RSP_SIZE];
+#endif
 
 #if CHECK_BAT_VOLTAGE
 char battery_voltage[MAX_RSP_SIZE];
@@ -980,6 +987,30 @@
 		return -1;
 }
 
+/* Function to check if the memory address range falls beyond ddr region.
+ * start: Start of the memory region
+ * size: Size of the memory region
+ */
+int check_ddr_addr_range_bound(uintptr_t start, uint32_t size)
+{
+	uintptr_t ddr_pa_start_addr = PA(get_ddr_start());
+	uint64_t ddr_size = smem_get_ddr_size();
+	uint64_t ddr_pa_end_addr = ddr_pa_start_addr + ddr_size;
+	uintptr_t pa_start_addr = PA(start);
+
+	/* Check for boundary conditions. */
+	if ((UINT_MAX - start) < size)
+		return -1;
+
+	/* Check if memory range is beyond the ddr range. */
+	if (pa_start_addr < ddr_pa_start_addr ||
+		pa_start_addr >= (ddr_pa_end_addr) ||
+		(pa_start_addr + size) > ddr_pa_end_addr)
+		return -1;
+	else
+		return 0;
+}
+
 #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
 
 BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize
@@ -1005,16 +1036,15 @@
 	dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
 
 #if VERIFIED_BOOT
-	if(boot_into_recovery)
-	{
-		ret = boot_verify_image((unsigned char *)bootimg_addr,
-				bootimg_size, "/recovery");
-	}
+	char *ptn_name = NULL;
+	if (boot_into_recovery &&
+		(!partition_multislot_is_supported()))
+		ptn_name = "/recovery";
 	else
-	{
-		ret = boot_verify_image((unsigned char *)bootimg_addr,
-				bootimg_size, "/boot");
-	}
+		ptn_name = "/boot";
+
+	ret = boot_verify_image((unsigned char *)bootimg_addr,
+				bootimg_size, ptn_name);
 	boot_verify_print_state();
 #else
 	ret = image_verify((unsigned char *)bootimg_addr,
@@ -1491,16 +1521,19 @@
 	kernel_size = ROUND_TO_PAGE(kernel_size,  page_mask);
 	/* Check if the addresses in the header are valid. */
 	if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
-		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+		check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
+		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
+		check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
 	{
-		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
 		return -1;
 	}
 
 #ifndef DEVICE_TREE
-	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
+		check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
 	{
-		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "Tags addresses are not valid.\n");
 		return -1;
 	}
 #endif
@@ -1566,18 +1599,20 @@
 		}
 
 		/* Validate and Read device device tree in the tags_addr */
-		if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size))
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
+			check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
 		{
-			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			dprintf(CRITICAL, "Device tree addresses are not valid\n");
 			return -1;
 		}
 
 		memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
 	} else {
 		/* Validate the tags_addr */
-		if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
+			check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
 		{
-			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			dprintf(CRITICAL, "Device tree addresses are not valid.\n");
 			return -1;
 		}
 		/*
@@ -1705,9 +1740,11 @@
 
 	/* Check if the addresses in the header are valid. */
 	if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
-		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+		check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
+		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
+		check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
 	{
-		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
 		return -1;
 	}
 
@@ -1718,9 +1755,10 @@
 	}
 	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
 
-	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
+		check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
 	{
-		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "Tags addresses are not valid.\n");
 		return -1;
 	}
 #else
@@ -1736,9 +1774,10 @@
 
 	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
 
-	if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size))
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
+		check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
 	{
-		dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "Device tree addresses are not valid.\n");
 		return -1;
 	}
 #endif
@@ -1813,8 +1852,9 @@
 			}
 
 			/* Validate and Read device device tree in the "tags_add */
-			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size)){
-				dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
+				check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size)){
+				dprintf(CRITICAL, "Device tree addresses are not valid.\n");
 				return -1;
 			}
 
@@ -1934,9 +1974,10 @@
 			}
 
 			/* Validate and Read device device tree in the "tags_add */
-			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
+			if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
+				check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
 			{
-				dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+				dprintf(CRITICAL, "Device tree addresses are not valid.\n");
 				return -1;
 			}
 
@@ -2469,9 +2510,10 @@
 			dtb_size = dt_entry.size;
 		}
 		/* Validate and Read device device tree in the "tags_add */
-		if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size))
+		if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
+			check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
 		{
-			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+			dprintf(CRITICAL, "Device tree addresses are not valid.\n");
 			return -1;
 		}
 
@@ -2672,9 +2714,11 @@
 	kernel_size  = ROUND_TO_PAGE(kernel_size,  page_mask);
 	/* Check if the addresses in the header are valid. */
 	if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
-		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
+		check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
+		check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
+		check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
 	{
-		dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
 		goto boot_failed;
 	}
 
@@ -2685,9 +2729,10 @@
 
 	dtb_copied = !ret ? 1 : 0;
 #else
-	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
+		check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
 	{
-		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "Tags addresses are not valid.\n");
 		goto boot_failed;
 	}
 #endif
@@ -2697,9 +2742,10 @@
 	memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
 
 #if DEVICE_TREE
-	if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
+		check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
 	{
-		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
+		dprintf(CRITICAL, "Tags addresses are not valid.\n");
 		goto boot_failed;
 	}
 
@@ -4059,9 +4105,28 @@
  */
 static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
 {
-	uint8_t i;
+	uint8_t i,n;
+	struct partition_entry *ptn_entry =
+				partition_get_partition_entries();
 
 	for (i = 0; i < num_parts; i++) {
+		strlcat(info[i].part_name, (char const *)ptn_entry[i].name, MAX_RSP_SIZE);
+		strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
+		strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
+
+		/* Mark partiton type for known paritions only */
+		for (n=0; n < ARRAY_SIZE(part_type_known); n++)
+		{
+			if (!strncmp(part_type_known[n].part_name, info[i].part_name,
+					strlen(part_type_known[n].part_name)))
+			{
+				strlcat(info[i].type_response,
+						part_type_known[n].type_response,
+						MAX_RSP_SIZE);
+				break;
+			}
+		}
+
 		get_partition_size(info[i].part_name, info[i].size_response);
 
 		if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
@@ -4111,6 +4176,7 @@
 		for (i=0; i<AB_SUPPORTED_SLOTS; i++)
 		{
 			tmp = SUFFIX_SLOT(i);
+			tmp++; // to remove "_" from slot_suffix.
 			snprintf(slot_info[i].slot_is_unbootable, sizeof(slot_info[i].slot_is_unbootable),
 										"slot-unbootable:%s", tmp);
 			snprintf(slot_info[i].slot_is_active, sizeof(slot_info[i].slot_is_active),
@@ -4136,8 +4202,11 @@
 
 	active_slt = partition_find_active_slot();
 	if (active_slt != INVALID)
-		snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s",
-			SUFFIX_SLOT(active_slt));
+	{
+		tmp = SUFFIX_SLOT(active_slt);
+		tmp++; // to remove "_" from slot_suffix.
+		snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s", tmp);
+	}
 	else
 		strlcpy(active_slot_suffix, "INVALID", sizeof(active_slot_suffix));
 
@@ -4152,6 +4221,19 @@
 	return;
 }
 
+#if PRODUCT_IOT
+void get_bootloader_version_iot(unsigned char *buf)
+{
+	if (buf != NULL)
+	{
+		strlcpy(buf, TARGET(BOARD), MAX_VERSION_LEN);
+		strlcat(buf, "-", MAX_VERSION_LEN);
+		strlcat(buf, PRODUCT_IOT_VERSION, MAX_VERSION_LEN);
+	}
+	return;
+}
+#endif
+
 void get_bootloader_version(unsigned char *buf)
 {
 	snprintf((char*)buf, MAX_RSP_SIZE, "%s",  device.bootloader_version);
@@ -4226,7 +4308,7 @@
 	 * devices.
 	 */
 	if (target_is_emmc_boot())
-		publish_getvar_partition_info(part_info, ARRAY_SIZE(part_info));
+		publish_getvar_partition_info(part_info, partition_get_partition_count());
 
 	if (partition_multislot_is_supported())
 		publish_getvar_multislot_vars();
@@ -4245,9 +4327,23 @@
 			device.display_panel);
 	fastboot_publish("display-panel",
 			(const char *) panel_display_mode);
+#if PRODUCT_IOT
+	get_bootloader_version_iot(&bootloader_version_string);
+	fastboot_publish("version-bootloader", (const char *) bootloader_version_string);
+
+	/* Version baseband is n/a for apq iot devices */
+	fastboot_publish("version-baseband", "N/A");
+
+	/* IOT targets support only mmc target */
+	snprintf(block_size_string, MAX_RSP_SIZE, "0x%x", mmc_get_device_blocksize());
+	fastboot_publish("erase-block-size", (const char *) block_size_string);
+	fastboot_publish("logical-block-size", (const char *) block_size_string);
+#else
 	fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
 	fastboot_publish("version-baseband", (const char *) device.radio_version);
+#endif
 	fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
+	fastboot_publish("unlocked", device.is_unlocked ? "yes":"no");
 	smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
 	snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
 		target_is_emmc_boot()? "eMMC":"UFS");
@@ -4444,11 +4540,18 @@
 				case ERR_INVALID_PAGE_SIZE:
 				case ERR_DT_PARSE:
 				case ERR_ABOOT_ADDR_OVERLAP:
+				case ERR_INVALID_BOOT_MAGIC:
 					if(partition_multislot_is_supported())
+					{
+						/*
+						 * Deactivate current slot, as it failed to
+						 * boot, and retry next slot.
+						 */
+						partition_deactivate_slot(boot_slot);
 						goto retry_boot;
+					}
 					else
 						break;
-				case ERR_INVALID_BOOT_MAGIC:
 				default:
 					break;
 				/* going to fastboot menu */
diff --git a/platform/msm_shared/ab_partition_parser.c b/platform/msm_shared/ab_partition_parser.c
index 9784481..a354316 100644
--- a/platform/msm_shared/ab_partition_parser.c
+++ b/platform/msm_shared/ab_partition_parser.c
@@ -102,6 +102,48 @@
 		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
@@ -291,12 +333,7 @@
 		if (count == AB_SUPPORTED_SLOTS)
 		{
 			/* Update the priority of the boot slot */
-			partition_entries[boot_slot_index[SLOT_A]].attribute_flag |=
-							((PART_ATT_PRIORITY_VAL |
-							PART_ATT_ACTIVE_VAL |
-							PART_ATT_MAX_RETRY_COUNT_VAL) &
-							(~PART_ATT_SUCCESSFUL_VAL &
-							~PART_ATT_UNBOOTABLE_VAL));
+			partition_activate_slot(SLOT_A);
 
 			active_slot = SLOT_A;
 
@@ -353,14 +390,10 @@
 #endif
 	if (!boot_retry_count)
 	{
-		/* Mark slot invalide and unbootable */
-		partition_entries[slt_index].attribute_flag |=
-					(PART_ATT_UNBOOTABLE_VAL &
-					~PART_ATT_ACTIVE_VAL &
-					~PART_ATT_PRIORITY_VAL);
+		/* Mark slot invalid and unbootable */
+		partition_deactivate_slot(boot_slot);
 
 		partition_switch_slots(boot_slot, next_active_bootable_slot(partition_entries));
-
 		reboot_device(0);
 	}
 	else
diff --git a/platform/msm_shared/include/ab_partition_parser.h b/platform/msm_shared/include/ab_partition_parser.h
index 0d49441..34520ac 100644
--- a/platform/msm_shared/include/ab_partition_parser.h
+++ b/platform/msm_shared/include/ab_partition_parser.h
@@ -32,6 +32,8 @@
 extern const char *suffix_delimiter;
 
 #define SUFFIX_SLOT(part_slot) suffix_slot[(part_slot)]
+#define SET_BIT(p,n) ((p) |= ((uint64_t)0x1 << (n)))
+#define CLR_BIT(p,n) ((p) &= (~(((uint64_t)0x1) << (n))))
 
 enum
 {
@@ -61,6 +63,8 @@
 void partition_reset_attributes();	/* Resetting slot attr. */
 void partition_fill_slot_meta();	/* Fill slot meta infomation */
 void partition_switch_slots();		/* Switching slots */
+void partition_deactivate_slot(int slot); /* Mark slot unbootable and reset other attributes*/
+void partition_activate_slot(int slot);	 /* Mark slot bootable and set other attributes*/
 int partition_find_boot_slot();		/* Find bootable partition */
 int partition_find_active_slot();	/* Find current active partition*/
 int partition_fill_partition_meta();	/* Fill partition slot info meta*/
diff --git a/platform/msm_shared/include/qseecom_lk_api.h b/platform/msm_shared/include/qseecom_lk_api.h
index c26da9b..1e2e35b 100644
--- a/platform/msm_shared/include/qseecom_lk_api.h
+++ b/platform/msm_shared/include/qseecom_lk_api.h
@@ -43,6 +43,16 @@
 int qseecom_init();
 
 /**
+ * Qseecom get version.
+ *	To be called before calls to set app region.
+ *
+ * @return unsigned int
+ *   Success:	Valid version
+ *   Failure:	Garbage value
+ */
+unsigned int qseecom_get_version();
+
+/**
 * Qseecom Tz Init
 *	To be called before any calls to qsee secure apps.
 *
diff --git a/platform/msm_shared/include/qseecomi_lk.h b/platform/msm_shared/include/qseecomi_lk.h
index 0a919de..a820cc5 100644
--- a/platform/msm_shared/include/qseecomi_lk.h
+++ b/platform/msm_shared/include/qseecomi_lk.h
@@ -44,6 +44,11 @@
 #define QSEOS_RESULT_FAIL_INCORRECT_PSWD      -71
 #define QSEOS_RESULT_FAIL_MAX_ATTEMPT         -72
 
+#define QSEOS_VERSION_14  0x14
+#define QSEE_VERSION_00   0x400000
+#define QSEE_VERSION_20   0x800000
+#define QSEE_VERSION_40   0x1000000  /* TZ.BF.4.0 */
+
 enum qseecom_command_scm_resp_type {
 	QSEOS_APP_ID = 0xEE01,
 	QSEOS_LISTENER_ID,
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index 265a0d6..e66950b 100644
--- a/platform/msm_shared/include/rpmb.h
+++ b/platform/msm_shared/include/rpmb.h
@@ -33,6 +33,7 @@
 #include <mmc_sdhci.h>
 #include <ufs.h>
 #include <debug.h>
+#include <qseecomi_lk.h>
 
 #define RPMB_SECTOR_SIZE            256
 #define RPMB_LSTNR_ID               0x2000
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
index 563d1e5..717c2a5 100644
--- a/platform/msm_shared/qseecom_lk.c
+++ b/platform/msm_shared/qseecom_lk.c
@@ -42,11 +42,6 @@
 #include <platform/iomap.h>
 #include <platform.h>
 
-#define QSEOS_VERSION_14  0x14
-#define QSEEE_VERSION_00  0x400000
-#define QSEE_VERSION_20   0x800000
-
-
 #define QSEOS_CHECK_VERSION_CMD  0x00001803
 
 #define MAX_SCM_ARGS 10
@@ -59,6 +54,7 @@
 #define GENERIC_ERROR -1
 #define LISTENER_ALREADY_PRESENT_ERROR -2
 
+#define TZ_FVER_QSEE 10
 #define TZ_CALL 6
 enum qseecom_client_handle_type {
 	QSEECOM_CLIENT_APP = 1,
@@ -1388,6 +1384,8 @@
 int qseecom_init()
 {
 	int rc = GENERIC_ERROR;
+	struct qseecom_command_scm_resp resp;
+	uint32_t ver = TZ_FVER_QSEE;
 
 	memset (&qseecom, 0, sizeof(struct qseecom_control));
 	dprintf(SPEW, "%s called\n", __func__);
@@ -1398,16 +1396,23 @@
 	list_initialize(&(qseecom.registered_app_list_head));
 	list_initialize(&(qseecom.registered_listener_list_head));
 
-	qseecom.qseos_version = QSEOS_VERSION_14;
-	rc = 0;
+	rc = qseecom_scm_call(TZ_SVC_INFO, 3,
+						  &ver, sizeof(ver),
+						  &resp, sizeof(resp));
 
 	if (!rc) {
 		qseecom.qseecom_init_done = 1;
-		dprintf(ALWAYS, "Qseecom Init Done in Appsbl\n");
+		qseecom.qseos_version = resp.result;
+		dprintf(ALWAYS, "Qseecom Init Done in Appsbl version is 0x%x\n",resp.result);
 	}
 	return rc;
 }
 
+unsigned int qseecom_get_version()
+{
+	return qseecom.qseos_version;
+}
+
 int qseecom_exit()
 {
 	dprintf(SPEW, "%s called\n", __func__);
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
index 41177ed..9d853ec 100644
--- a/platform/msm_shared/rpmb/rpmb.c
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -86,6 +86,16 @@
 				info.rel_wr_count = 32;
 			}
 		}
+
+		/*
+		 *  tz changes required for supporting
+		 *  multiple frames are not present
+		 *  force the number of frames to be minimum
+		 *  i.e. one for tz 3.0 and earlier.
+		 */
+		if( qseecom_get_version() < QSEE_VERSION_40 )
+			info.rel_wr_count = 1;
+
 		info.dev_type  = EMMC_RPMB;
 	}
 #ifdef UFS_SUPPORT
diff --git a/platform/msm_shared/uic.c b/platform/msm_shared/uic.c
index 3ba35b5..77a903e 100644
--- a/platform/msm_shared/uic.c
+++ b/platform/msm_shared/uic.c
Binary files differ
diff --git a/platform/msm_shared/utp.c b/platform/msm_shared/utp.c
index e0463b2..308ffee 100644
--- a/platform/msm_shared/utp.c
+++ b/platform/msm_shared/utp.c
@@ -216,7 +216,7 @@
 
 int utp_poll_utrd_complete(struct ufs_dev *dev)
 {
-	int ret;
+	int ret = ERROR;
 	struct ufs_req_irq_type irq;
 	uint32_t val, base, retry = 0;
 	base = dev->base;
@@ -264,11 +264,12 @@
 	int                           ret;
 	struct utp_trans_req_desc     *desc;
 	event_t                       utrd_evt;
-	struct ufs_req_node           req;
+	struct ufs_req_node           *req;
 	uint32_t                      door_bell_bit_val;
 	struct utp_bitmap_access_type bitmap_req;
 
 	ret = UFS_SUCCESS;
+	req = (struct ufs_req_node *)malloc(sizeof(struct ufs_req_node));
 
 	event_init(&utrd_evt, false, EVENT_FLAG_AUTOUNSIGNAL);
 
@@ -288,11 +289,11 @@
 
 	utp_enqueue_utrd_fill_desc(desc, utrd_req);
 
-	req.door_bell_bit = door_bell_bit_val;
-	req.event         = &utrd_evt;
+	req->door_bell_bit = door_bell_bit_val;
+	req->event         = &utrd_evt;
 
 	/* Enqueue the req in the device utrd list. */
-	list_add_head(&(dev->utrd_data.list_head.list_node), &(req.list_node));
+	list_add_head(&(dev->utrd_data.list_head.list_node), &(req->list_node));
 
 	dsb();
 
@@ -315,7 +316,7 @@
 	{
 		/* Transaction not completed even after timeout ms. */
 		dprintf(CRITICAL, "%s:%d Transaction timeout after polling %d times\n",__func__, __LINE__, UTP_MAX_COMMAND_RETRY);
-		ret = utp_utrd_process_timeout_req(dev, utrd_req, &req);
+		ret = utp_utrd_process_timeout_req(dev, utrd_req, req);
 		goto utp_enqueue_utrd_err;
 	}
 	else
@@ -338,7 +339,7 @@
 
 	/* Signal slot as free. */
 	bitmap_req.bitmap        = &dev->utrd_data.bitmap;
-	bitmap_req.door_bell_bit = req.door_bell_bit;
+	bitmap_req.door_bell_bit = req->door_bell_bit;
 	bitmap_req.mutx          = &(dev->utrd_data.bitmap_mutex);
 
 	ret = utp_remove_from_bitmap(&bitmap_req);