Merge "dev: qpnp-lcdb: Initialize LDO/NCP voltage step wise"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 930621e..d252c25 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1110,8 +1110,8 @@
 	generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
 #endif
 
-#if VERIFIED_BOOT
-	if (VB_M == target_get_vb_version())
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
+	if (VB_M <= target_get_vb_version())
 	{
 		if (device.verity_mode == 0) {
 #if FBCON_DISPLAY_MSG
@@ -1545,6 +1545,10 @@
 	second_actual  = ROUND_TO_PAGE(hdr->second_size, page_mask);
 
 	image_addr = (unsigned char *)target_get_scratch_address();
+#if VERIFIED_BOOT_2
+	/* Create hole in start of image for VB salt to copy */
+	image_addr += SALT_BUFF_OFFSET;
+#endif
 	memcpy(image_addr, (void *)buf, page_size);
 
 	/* ensure commandline is terminated */
@@ -1553,8 +1557,9 @@
 #if DEVICE_TREE
 #ifndef OSVERSION_IN_BOOTIMAGE
 	dt_size = hdr->dt_size;
-#endif
+#else
 	dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
+#endif
 
 	dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
 	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
@@ -1582,7 +1587,9 @@
 	{
 		struct boot_img_hdr_v1 *hdr1 =
 			(struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
+		unsigned int recovery_dtbo_actual = 0;
 
+		recovery_dtbo_actual = ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
 		if ((hdr1->header_size !=
 				sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
 		{
@@ -1590,25 +1597,26 @@
 			return -1;
 		}
 
-		if (UINT_MAX < (hdr1->recovery_dtbo_offset + hdr1->recovery_dtbo_size)) {
-			dprintf(CRITICAL,
-				"Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
-			return -1;
-		}
-
-		if (hdr1->recovery_dtbo_size > MAX_SUPPORTED_DTBO_IMG_BUF) {
-			dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", hdr1->recovery_dtbo_size,
+		if (recovery_dtbo_actual > MAX_SUPPORTED_DTBO_IMG_BUF)
+		{
+			dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", recovery_dtbo_actual,
 				MAX_SUPPORTED_DTBO_IMG_BUF);
 			return -1;
 		}
 
-		if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_size))
+		if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_actual))
 		{
 			dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
 			return -1;
 		}
 
-		if (hdr1->recovery_dtbo_offset + recovery_dtbo_size > image_size)
+		if (UINT_MAX < (hdr1->recovery_dtbo_offset + recovery_dtbo_actual)) {
+			dprintf(CRITICAL,
+				"Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
+			return -1;
+		}
+
+		if (hdr1->recovery_dtbo_offset + recovery_dtbo_actual > image_size)
 		{
 			dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
 				" Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
@@ -1617,7 +1625,7 @@
 		}
 
 		recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
-		recovery_dtbo_size = hdr1->recovery_dtbo_size;
+		recovery_dtbo_size = recovery_dtbo_actual;
 		imagesize_actual += recovery_dtbo_size;
 
 		dprintf(SPEW, "Header version: %d\n", hdr->header_version);
@@ -1714,14 +1722,15 @@
 	memset(&info, 0, sizeof(bootinfo));
 
 	/* Pass loaded boot image passed */
-	info.images[IMG_BOOT].image_buffer = image_addr;
+	info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(image_addr);
 	info.images[IMG_BOOT].imgsize = imagesize_actual;
 	info.images[IMG_BOOT].name = ptn_name;
 	++info.num_loaded_images;
 
 	/* Pass loaded dtbo image */
 	if (dtbo_image_buf != NULL) {
-		info.images[IMG_DTBO].image_buffer = dtbo_image_buf;
+		info.images[IMG_DTBO].image_buffer =
+					SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
 		info.images[IMG_DTBO].imgsize = dtbo_image_sz;
 		info.images[IMG_DTBO].name = "dtbo";
 		++info.num_loaded_images;
@@ -1988,6 +1997,9 @@
 		 * If appended dev tree is found, update the atags with
 		 * memory address to the DTB appended location on RAM.
 		 * Else update with the atags address in the kernel header
+		 *
+		 * Make sure everything from scratch address is read before next step!
+		 * In case of dtbo, this API is going to read dtbo on scratch.
 		 */
 		void *dtb;
 		dtb = dev_tree_appended(
@@ -2272,6 +2284,9 @@
 		 * If appended dev tree is found, update the atags with
 		 * memory address to the DTB appended location on RAM.
 		 * Else update with the atags address in the kernel header
+		 *
+		 * Make sure everything from scratch address is read before next step!
+		 * In case of dtbo, this API is going to read dtbo on scratch.
 		 */
 		void *dtb = NULL;
 		dtb = dev_tree_appended((void*)(image_addr + page_size ),hdr->kernel_size, dtb_offset, (void *)hdr->tags_addr);
@@ -5028,7 +5043,7 @@
 	{
 		boot_reason_alarm = true;
 	}
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
 	else if (VB_M <= target_get_vb_version())
 	{
 		if (reboot_mode == DM_VERITY_ENFORCING)
diff --git a/platform/msm_shared/avb/VerifiedBoot.c b/platform/msm_shared/avb/VerifiedBoot.c
index 585d6a9..d76b209 100644
--- a/platform/msm_shared/avb/VerifiedBoot.c
+++ b/platform/msm_shared/avb/VerifiedBoot.c
@@ -548,7 +548,7 @@
 	GUARD_OUT(AppendVBCommonCmdLine(Info));
 	GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
 	DevInfo_vb.is_unlocked = !is_device_locked();
-	set_os_version((unsigned char *)Info->images[0].image_buffer);
+	set_os_version(ADD_SALT_BUFF_OFFSET(Info->images[0].image_buffer));
 	if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
 		return EFI_LOAD_ERROR;
 	dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
diff --git a/platform/msm_shared/avb/libavb/avb_ops.c b/platform/msm_shared/avb/libavb/avb_ops.c
index 4c1b81c..2199d34 100644
--- a/platform/msm_shared/avb/libavb/avb_ops.c
+++ b/platform/msm_shared/avb/libavb/avb_ops.c
@@ -160,8 +160,9 @@
 	AvbIOResult Result = AVB_IO_RESULT_OK;
 	EFI_STATUS Status = EFI_SUCCESS;
 	VOID *Page = NULL;
-	UINT32 Offset = 0;
+	UINTN Offset = 0;
 	UINTN ptn = 0;
+	UINTN part_size = 0;
 	UINT32 PageSize = 0;
 	UINT32 StartBlock = 0;
 	UINT32 LastBlock = 0;
@@ -178,46 +179,46 @@
 
 	if (!getimage(Buffer, OutNumRead, Partition)) {
 		/* API returns previously loaded Images buffer address and size */
-		dprintf(SPEW, "DEBUG: %s already loadded \n", Partition);
+                dprintf(SPEW, "DEBUG: %s already loaded \n", Partition);
 		return AVB_IO_RESULT_OK;
 	}
-	dprintf(SPEW, "%s Loading image\n", Partition);
+	dprintf(SPEW, "Loading image %s\n", Partition);
 	index = partition_get_index(Partition);
 	ptn = partition_get_offset(index);
+	part_size = partition_get_size(index);
 
 	if (ReadOffset < 0) {
-		if ((-ReadOffset) > (int64_t)ptn) {
+		if ((-ReadOffset) > (int64_t)part_size) {
 			dprintf(CRITICAL,
 			       "Negative Offset outside range.\n");
 			Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
 			goto out;
 		}
-		Offset = ptn - (-ReadOffset);
+		Offset = part_size - (-ReadOffset);
 		dprintf(DEBUG,
-		       "negative Offset (%lld) converted to (%u) \n", ReadOffset, Offset);
+		       "negative Offset (%lld) converted to (0x%llx) \n", ReadOffset, Offset);
 	} else {
 		// check int64_t to UINT32 converstion?
 		Offset = ReadOffset;
 	}
 
-	if (Offset > ptn) {
+	if (Offset > part_size) {
 		dprintf(CRITICAL, "Offset outside range.\n");
 		Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
 		goto out;
 	}
 
-	if (NumBytes > ptn - Offset) {
-		NumBytes = ptn - Offset;
+	if (NumBytes > part_size - Offset) {
+		NumBytes = part_size - Offset;
 	}
 
 	dprintf(CRITICAL,
-	       "read from %s, 0x%x bytes at Offset 0x%x, partition size %llu\n",
+	       "read from %s, 0x%x bytes at Offset 0x%llx, partition size %llu\n",
 	       Partition, NumBytes, Offset, ptn);
 
-	/* |NumBytes| and or |Offset| can be unaligned to block size/page size.
+	/* |NumBytes| and or |Offset| can be unaligned to block size.
 	 */
-	//PageSize = mmc_get_device_blocksize();
-	PageSize = get_page_size();
+	PageSize = mmc_get_device_blocksize();
 	Page = avb_malloc(PageSize);
 	if (Page == NULL) {
 		dprintf(CRITICAL, "Allocate for partial read failed!");
@@ -256,7 +257,7 @@
 			goto out;
 		}
 
-		Status = mmc_read(ptn, Page, PageSize);
+		Status = mmc_read(ptn + (StartBlock * PageSize), Page, PageSize);
 		if (Status == EFI_SUCCESS) {
 			avb_memcpy(Buffer, Page + StartPageReadOffset, StartPageReadSize);
 			*OutNumRead += StartPageReadSize;
diff --git a/platform/msm_shared/avb/libavb/avb_slot_verify.c b/platform/msm_shared/avb/libavb/avb_slot_verify.c
index b279e22..6d3e64f 100644
--- a/platform/msm_shared/avb/libavb/avb_slot_verify.c
+++ b/platform/msm_shared/avb/libavb/avb_slot_verify.c
@@ -185,17 +185,17 @@
 
   if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) {
     uint32_t complete_len = hash_desc.salt_len + hash_desc.image_size;
-    uint8_t *complete_buf = (uint8_t *)target_get_scratch_address()+0x08000000;
     digest = avb_malloc(AVB_SHA256_DIGEST_SIZE);
-    if(digest == NULL)
+    if(digest == NULL || hash_desc.salt_len > SALT_BUFF_OFFSET )
     {
         avb_errorv(part_name, ": Failed to allocate memory\n", NULL);
         ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
         goto out;
     }
-    avb_memcpy(complete_buf, desc_salt, hash_desc.salt_len);
-    avb_memcpy(complete_buf + hash_desc.salt_len, image_buf, hash_desc.image_size);
-    hash_find(complete_buf, complete_len, digest, CRYPTO_AUTH_ALG_SHA256);
+    image_buf = ADD_SALT_BUFF_OFFSET(image_buf) - hash_desc.salt_len;
+    avb_memcpy(image_buf, desc_salt, hash_desc.salt_len);
+    hash_find(image_buf, complete_len, digest, CRYPTO_AUTH_ALG_SHA256);
+    image_buf = SUB_SALT_BUFF_OFFSET(image_buf) +  hash_desc.salt_len;
     digest_len = AVB_SHA256_DIGEST_SIZE;
   } else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) {
     AvbSHA512Ctx sha512_ctx;
@@ -370,7 +370,7 @@
   char full_partition_name[PART_NAME_MAX_SIZE];
   AvbSlotVerifyResult ret;
   AvbIOResult io_ret;
-  size_t vbmeta_offset;
+  UINTN vbmeta_offset;
   size_t vbmeta_size;
   uint8_t* vbmeta_buf = NULL;
   size_t vbmeta_num_read;
@@ -462,17 +462,30 @@
       ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
       goto out;
     }
-
     vbmeta_offset = footer.vbmeta_offset;
     vbmeta_size = footer.vbmeta_size;
   }
 
-  io_ret = ops->read_from_partition(ops,
+  if (avb_strcmp(full_partition_name, "vbmeta") == 0) {
+    io_ret = ops->read_from_partition(ops,
                                     full_partition_name,
                                     vbmeta_offset,
                                     vbmeta_size,
                                     &vbmeta_buf,
                                     &vbmeta_num_read);
+  } else { // for chain partitions
+    vbmeta_buf = avb_malloc(vbmeta_size);
+    if (vbmeta_buf == NULL) {
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+        goto out;
+    }
+    io_ret = ops->read_from_partition(ops,
+                                    full_partition_name,
+                                    vbmeta_offset,
+                                    vbmeta_size,
+                                    vbmeta_buf,
+                                    &vbmeta_num_read);
+  }
   if (vbmeta_buf == NULL) {
     ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
     goto out;
@@ -717,6 +730,11 @@
    */
   descriptors =
       avb_descriptor_get_all(vbmeta_buf, vbmeta_num_read, &num_descriptors);
+  if (descriptors == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
   for (n = 0; n < num_descriptors; n++) {
     AvbDescriptor desc;
 
diff --git a/platform/msm_shared/avb/libavb/avb_util.c b/platform/msm_shared/avb/libavb/avb_util.c
index 43662b4..09b05f1 100644
--- a/platform/msm_shared/avb/libavb/avb_util.c
+++ b/platform/msm_shared/avb/libavb/avb_util.c
@@ -299,9 +299,8 @@
       char* new_str;
       num_new = ret_len + num_before + replace_len + 1;
       new_str = avb_malloc(num_new);
-      if (ret == NULL) {
+      if (new_str == NULL)
         goto out;
-      }
       avb_memcpy(new_str, ret, ret_len);
       avb_memcpy(new_str + ret_len, str, num_before);
       avb_memcpy(new_str + ret_len + num_before, replace, replace_len);
@@ -324,9 +323,8 @@
     size_t num_remaining = avb_strlen(str_after_last_replace);
     size_t num_new = ret_len + num_remaining + 1;
     char* new_str = avb_malloc(num_new);
-    if (ret == NULL) {
+    if (new_str == NULL)
       goto out;
-    }
     avb_memcpy(new_str, ret, ret_len);
     avb_memcpy(new_str + ret_len, str_after_last_replace, num_remaining);
     new_str[num_new - 1] = '\0';
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 6a99514..2df16f0 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -47,6 +47,7 @@
 #include <libufdt_sysdeps.h>
 #include <ufdt_overlay.h>
 #include <boot_stats.h>
+#include <verifiedboot.h>
 
 #define BOOT_DEV_MAX_LEN        64
 #define NODE_PROPERTY_MAX_LEN   64
@@ -245,7 +246,7 @@
 		dtbo_image_buf = target_get_scratch_address() +
 					(target_get_max_flash_size() - DTBO_IMG_BUF);
 		dtbo_image_buf =
-			(void *)ROUND_TO_PAGE((addr_t)dtbo_image_buf, (ADDR_ALIGNMENT-1) );
+			(void *)ROUND_TO_PAGE((addr_t)dtbo_image_buf, (ADDR_ALIGNMENT-1));
 		if(dtbo_image_buf == (void *)UINT_MAX)
 		{
 			dprintf(CRITICAL, "ERROR: Invalid DTBO image buf addr\n");
@@ -253,6 +254,8 @@
 			goto out;
 		}
 
+		/* Add offset for salt buffer for verification */
+		dtbo_image_buf += SALT_BUFF_OFFSET;
 		/* Read dtbo partition with header */
 		if (mmc_read(ptn, (uint32_t *)(dtbo_image_buf), dtbo_partition_size))
 		{
diff --git a/platform/msm_shared/include/verifiedboot.h b/platform/msm_shared/include/verifiedboot.h
index 7534c14..e2eb3c2 100644
--- a/platform/msm_shared/include/verifiedboot.h
+++ b/platform/msm_shared/include/verifiedboot.h
@@ -55,6 +55,10 @@
 
 #define EFIERR(_a)		(-1 * (_a))
 
+#define SALT_BUFF_OFFSET (1024)
+#define ADD_SALT_BUFF_OFFSET(addr) (SALT_BUFF_OFFSET + (addr))
+#define SUB_SALT_BUFF_OFFSET(addr) ((addr) - SALT_BUFF_OFFSET)
+
 #define EFI_SUCCESS               0
 #define EFI_LOAD_ERROR            EFIERR (1)
 #define EFI_INVALID_PARAMETER     EFIERR (2)
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index d862e0b..ce035e6 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -523,6 +523,7 @@
 	HW_PLATFORM_SUBTYPE_POLARIS = 64,
 	HW_PLATFORM_SUBTYPE_SWOC_WEAR = 9,
 	HW_PLATFORM_SUBTYPE_SWOC_NOWGR_CIRC = 13,
+	HW_PLATFORM_SUBTYPE_8909_PM8916 = 2,
 	HW_PLATFORM_SUBTYPE_8909_PM660 = 15,
 	HW_PLATFORM_SUBTYPE_8909_COMPAL_ALPHA = 19,
 	HW_PLATFORM_SUBTYPE_8909_PM660_V1 = 18,
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index b6a51e5..4a5ebe1 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -872,9 +872,17 @@
 
 uint32_t target_get_pmic()
 {
-	if ((board_hardware_subtype() == HW_PLATFORM_SUBTYPE_8909_PM660) ||
-		(board_hardware_subtype() == HW_PLATFORM_SUBTYPE_8909_PM660_V1) ||
-		(board_hardware_subtype() == HW_PLATFORM_SUBTYPE_8909_COMPAL_ALPHA))
+	uint32_t hw_id = board_hardware_id();
+	uint32_t platform = board_platform_id();
+	uint32_t platform_subtype = board_hardware_subtype();
+
+	if ((MSM8909 == platform) &&
+		(HW_PLATFORM_MTP == hw_id) &&
+		(HW_PLATFORM_SUBTYPE_8909_PM8916 == platform_subtype))
+		return PMIC_IS_PM8916;
+	else if ((platform_subtype == HW_PLATFORM_SUBTYPE_8909_PM660) ||
+		(platform_subtype == HW_PLATFORM_SUBTYPE_8909_PM660_V1) ||
+		(platform_subtype == HW_PLATFORM_SUBTYPE_8909_COMPAL_ALPHA))
 		return PMIC_IS_PM660;
 	else
 		return PMIC_IS_PM8909;