Merge "app: aboot: Add bootlunen test to fastboot test"
diff --git a/app/aboot/fastboot_test.c b/app/aboot/fastboot_test.c
index f32435c..5cad0b5 100644
--- a/app/aboot/fastboot_test.c
+++ b/app/aboot/fastboot_test.c
@@ -33,6 +33,8 @@
 #include "fastboot.h"
 #include "fastboot_test.h"
 #include <app/tests.h>
+#include <target.h>
+#include <boot_device.h>
 #if USE_RPMB_FOR_DEVINFO
 #include <rpmb.h>
 #endif
@@ -40,10 +42,37 @@
 
 extern void ramdump_table_map();
 extern void kauth_test();
+extern int ufs_get_boot_lun();
+extern int ufs_set_boot_lun(uint32_t bootlunid);
+extern int fastboot_init();
 
 void cmd_oem_runtests()
 {
 	dprintf(INFO, "Running LK tests ... \n");
+
+	// Test boot lun enable for UFS
+	if (!platform_boot_dev_isemmc())
+	{
+		int ret = 0;
+		uint32_t set_lun = 0x2, get_lun;
+		ret = ufs_set_boot_lun(set_lun);
+		if (ret == UFS_SUCCESS)
+		{
+			get_lun = ufs_get_boot_lun();
+			if (get_lun == set_lun)
+			{
+				dprintf(INFO, "UFS Boot LUN En TEST: [ PASS ]\n");
+				set_lun = 0x1; // default is 0x1 LUN A, revert back to 0x1
+				ret = ufs_set_boot_lun(set_lun);
+			}
+			else
+				dprintf(INFO, "UFS Boot LUN En TEST: [ FAIL ]\n");
+		}
+		else
+			dprintf(INFO, "UFS Boot LUN En TEST: [ FAIL ]\n");
+	}
+
+
 #if LPAE
 	ramdump_table_map();
 #endif
diff --git a/platform/msm_shared/dme.c b/platform/msm_shared/dme.c
index f83ee93..c6d651d 100644
--- a/platform/msm_shared/dme.c
+++ b/platform/msm_shared/dme.c
@@ -96,7 +96,7 @@
 	}
 	if (resp_upiu->basic_hdr.response != UPIU_QUERY_RESP_SUCCESS)
 	{
-		dprintf(CRITICAL, "%s:%d UPIU Response is not SUCCESS\n", __func__, __LINE__);
+		dprintf(CRITICAL, "%s:%d UPIU Response is not SUCCESS, response code: 0x%x\n", __func__, __LINE__, resp_upiu->basic_hdr.response);
 		return -UFS_FAILURE;
 	}
 
@@ -111,8 +111,9 @@
 										return -UFS_FAILURE;
 									  }
 
-									  *((uint32_t *) buffer) = resp_upiu->flag_value;
+									  *((uint32_t *) buffer) = resp_upiu->resv_1[3]; //resv_1[3] contains the data for flag
 									  break;
+		case UPIU_QUERY_OP_WRITE_ATTRIBUTE:
 		case UPIU_QUERY_OP_TOGGLE_FLAG:
 		case UPIU_QUERY_OP_CLEAR_FLAG:
 		case UPIU_QUERY_OP_READ_DESCRIPTOR:
@@ -149,6 +150,9 @@
 		req_upiu.resp_data_len = query->buf_len;
 	}
 
+	if (query->opcode == UPIU_QUERY_OP_WRITE_ATTRIBUTE)
+		req_upiu.data_buffer_addr = query->buf; // attribute is 4 byte value
+
 	ret = utp_enqueue_upiu(dev, &req_upiu);
 	if (ret)
 		goto utp_send_query_upiu_err;
@@ -161,6 +165,47 @@
 	return ret;
 }
 
+int dme_set_bbootlunen(struct ufs_dev *dev, uint32_t val)
+{
+	int ret = 0;
+	STACKBUF_DMA_ALIGN(value, sizeof(uint32_t));
+	memset((void *)value, 0, sizeof(uint32_t));
+	*value = val;
+	struct utp_query_req_upiu_type set_query = {UPIU_QUERY_OP_WRITE_ATTRIBUTE,
+												 UFS_IDX_bBootLunEn,
+												 0,
+												 0,
+												 (addr_t)value,
+												 sizeof(uint32_t)};
+	if ((ret = dme_send_query_upiu(dev, &set_query)))
+	{
+		arch_invalidate_cache_range((addr_t) value, sizeof(uint32_t));
+		dprintf(CRITICAL, "%s:%d DME Set Boot Lun Query failed. Value 0x%x\n", __func__, __LINE__, *value);
+		return -UFS_FAILURE;
+	}
+	return UFS_SUCCESS;
+}
+
+int dme_get_bbootlunen(struct ufs_dev *dev)
+{
+	STACKBUF_DMA_ALIGN(value, sizeof(uint32_t));
+	memset((void *)value, 0, sizeof(uint32_t));
+	int ret = 0;
+	struct utp_query_req_upiu_type set_query = {UPIU_QUERY_OP_READ_ATTRIBUTE,
+												 UFS_IDX_bBootLunEn,
+												 0,
+												 0,
+												 (addr_t)value,
+												 sizeof(uint32_t)};
+	if ((ret = dme_send_query_upiu(dev, &set_query)))
+	{
+		dprintf(CRITICAL, "%s:%d DME Set Boot Lun Query failed\n", __func__, __LINE__);
+		return -UFS_FAILURE;
+	}
+	arch_invalidate_cache_range((addr_t) value, sizeof(uint32_t));
+	return *value;
+}
+
 int dme_set_fpurgeenable(struct ufs_dev *dev)
 {
 	STACKBUF_DMA_ALIGN(result, sizeof(uint32_t));
@@ -551,6 +596,7 @@
 											req_upiu->basic_hdr.query_task_mgmt_func = UPIU_QUERY_FUNC_STD_READ_REQ;
 											break;
 		case UPIU_QUERY_OP_TOGGLE_FLAG:
+		case UPIU_QUERY_OP_WRITE_ATTRIBUTE:
 		case UPIU_QUERY_OP_CLEAR_FLAG:
 		case UPIU_QUERY_OP_SET_FLAG:
 									 req_upiu->basic_hdr.query_task_mgmt_func = UPIU_QUERY_FUNC_STD_WRITE_REQ;
@@ -559,6 +605,13 @@
 				dprintf(CRITICAL, "%s:%d UPIU query opcode not supported.\n", __func__, __LINE__);
 				return -UFS_FAILURE;
 	}
+	if (upiu_data->opcode == UPIU_QUERY_OP_WRITE_ATTRIBUTE)
+	{
+		req_upiu->resv_1[0] = (*(uint32_t *)(upiu_data->data_buffer_addr) >> 24);
+		req_upiu->resv_1[1] = (*(uint32_t *)(upiu_data->data_buffer_addr) >> 16);
+		req_upiu->resv_1[2] = (*(uint32_t *)(upiu_data->data_buffer_addr) >> 8);
+		req_upiu->resv_1[3] = (*(uint32_t *)(upiu_data->data_buffer_addr) & 0xFF);
+	}
 
 	return UFS_SUCCESS;
 }
diff --git a/platform/msm_shared/include/dme.h b/platform/msm_shared/include/dme.h
index aa11c54..4930024 100644
--- a/platform/msm_shared/include/dme.h
+++ b/platform/msm_shared/include/dme.h
@@ -73,6 +73,7 @@
 #define UFS_IDX_bBootLunEn          0x00
 #define UFS_IDX_bCurrentPowerMode   0x01
 #define UFS_IDX_bActiveICCLevel     0x03
+#define UFS_IDX_bBootLunID          0x04
 #define UFS_IDX_bPurgeStatus        0x06
 #define UFS_IDX_bRefClkFreq         0x0a
 #define UFS_IDX_bConfigDescrLock    0x0b
@@ -268,4 +269,9 @@
 */
 int dme_read_geo_desc(struct ufs_dev *dev);
 
+/* function to return the boot lun currently booting from */
+int dme_get_bbootlunen(struct ufs_dev *dev);
+
+/* function to set the boot lun to either 0, 1 or 2 */
+int dme_set_bbootlunen(struct ufs_dev *dev, uint32_t val);
 #endif
diff --git a/platform/msm_shared/include/mmc_wrapper.h b/platform/msm_shared/include/mmc_wrapper.h
index f52a117..fbae494 100644
--- a/platform/msm_shared/include/mmc_wrapper.h
+++ b/platform/msm_shared/include/mmc_wrapper.h
@@ -49,4 +49,6 @@
 uint8_t mmc_get_lun(void);
 void  mmc_read_partition_table(uint8_t arg);
 uint32_t mmc_write_protect(const char *name, int set_clr);
+int ufs_set_boot_lun(uint32_t boot_lun_id);
+int ufs_get_boot_lun();
 #endif
diff --git a/platform/msm_shared/include/upiu.h b/platform/msm_shared/include/upiu.h
index e081909..2c8fee5 100644
--- a/platform/msm_shared/include/upiu.h
+++ b/platform/msm_shared/include/upiu.h
@@ -74,8 +74,8 @@
 	uint8_t                   selector;

 	uint8_t                   resv_0[2];

 	uint16_t                  resp_len;

-	uint8_t                   resv_1[3];

-	uint8_t                   flag_value;

+	// this structure is used for several queries. resv_1 field is reserved for some and used for others

+	uint8_t                   resv_1[4];

 	uint8_t                   resv_2[4];

 }__PACKED;

 

diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index 10e9955..495767a 100755
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -534,6 +534,41 @@
 }
 
 /*
+ * Function    : ufs_get_boot_lun
+ * Arg         : none
+ * Return type : current boot lun
+ */
+
+int ufs_get_boot_lun()
+{
+	int ret = 0;
+	void *dev;
+	dev = target_mmc_device();
+
+	if (!(platform_boot_dev_isemmc()))
+		ret = dme_get_bbootlunen((struct ufs_dev *)dev);
+	return ret;
+}
+
+
+/*
+ * Function    : ufs_set_boot_lun
+ * Arg         : boot lun id
+ * Return type : status
+ */
+
+int ufs_set_boot_lun(uint32_t boot_lun_id)
+{
+	int ret = 0;
+	void *dev;
+	dev = target_mmc_device();
+
+	if (!(platform_boot_dev_isemmc()))
+		ret = dme_set_bbootlunen((struct ufs_dev *)dev, boot_lun_id);
+	return ret;
+}
+
+/*
  * Function     : mmc set LUN for ufs
  * Arg          : LUN number
  * Return type  : void