platform: msm_shared: Add support for secure write protect for UFS

Add support for secure write protect for UFS.

Change-Id: If550cfe9b17ee6917a5206d81af69834690a25f6
diff --git a/include/km_main.h b/include/km_main.h
index 42920d1..fa606ad 100644
--- a/include/km_main.h
+++ b/include/km_main.h
@@ -67,6 +67,7 @@
     KEYMASTER_READ_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 2UL),
     KEYMASTER_WRITE_LK_DEVICE_STATE			= (KEYMASTER_UTILS_CMD_ID + 3UL),
     KEYMASTER_MILESTONE_CALL				= (KEYMASTER_UTILS_CMD_ID + 4UL),
+    KEYMASTER_SECURE_WRITE_PROTECT			= (KEYMASTER_UTILS_CMD_ID + 6UL),
 
     KEYMASTER_LAST_CMD_ENTRY				= (int)0xFFFFFFFFULL
 } keymaster_cmd_t;
@@ -163,4 +164,45 @@
 	int status;
 }__attribute__ ((packed)) key_op_delete_all_rsp_t;
 
+typedef enum _secure_write_prot_op_t
+{
+	SWP_READ_CONFIG,
+	SWP_WRITE_CONFIG,
+	SWP_LAST_CMD_ENTRY                    = (int)0xFFFFFFFFULL
+} secure_write_prot_op_t;
+
+/*
+	@brief
+	Data structure
+
+	@param[in]   cmd_id                   Command ID of the request
+	@param[in]   op                       Secure write protect operation (enum from secure_write_prot_op_t)
+	@param[in]   swp_write_data_offset    Offset of data for SWP operation
+	@param[in]   swp_write_data_len       Length of data for SWP operation
+*/
+
+typedef struct _secure_write_prot_req_t
+{
+	uint32 cmd_id;
+	uint32 op;
+	uint32 swp_write_data_offset;
+	uint32 swp_write_data_len;
+}__attribute__((packed)) secure_write_prot_req_t;
+
+/*
+	@brief
+	Data structure
+
+	@param[out]   status                  Status of the request
+	@param[out]   swp_read_data_offset    Offset of data for SWP operation
+	@param[out]   swp_read_data_len       Length of data for SWP operation
+*/
+
+typedef struct _secure_write_prot_rsp_t
+{
+	int status;
+	uint32 swp_read_data_offset;
+	uint32 swp_read_data_len;
+}__attribute__((packed)) secure_write_prot_rsp_t;
+
 #endif /* KM_MAIN_H */
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index 8e9f148..265a0d6 100644
--- a/platform/msm_shared/include/rpmb.h
+++ b/platform/msm_shared/include/rpmb.h
@@ -97,6 +97,23 @@
 	uint32_t dev_type;
 };
 
+/* Secure Write Protect Info Entry structure */
+typedef struct
+{
+	uint8_t  wp_enable;    /* UFS: WPF (Write Protect Flag), eMMC: SECURE_WP_MODE_ENABLE */
+	uint8_t  wp_type_mask; /* UFS: WPT (Write Protect Type), eMMC: SECURE_WP_MODE_CONFIG */
+	uint64_t addr;         /* UFS: LBA, eMMC: 0x1/0x2 (address of the device config register) */
+	uint32_t num_blocks;   /* UFS: Num LBA, eMMC: Set to 0 */
+} __attribute__ ((packed)) qsee_stor_secure_wp_info_entry_t;
+
+/* Secure Write Protect Info structure */
+typedef struct
+{
+	uint8_t                          lun_number;    /* UFS: LUN #, eMMC: Set to 0 */
+	uint8_t                          num_entries;   /* Number of Secure wp entries */
+	qsee_stor_secure_wp_info_entry_t wp_entries[4]; /* Max 4 entries total */
+} __attribute__ ((packed)) qsee_stor_secure_wp_info_t;
+
 /* dump a given RPMB frame */
 static inline void dump_rpmb_frame(uint8_t *frame, const char *frame_type)
 {
@@ -136,4 +153,6 @@
 int rpmb_write(uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len);
 int rpmb_read(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
 struct rpmb_init_info *rpmb_get_init_info();
+/* RPMB API to set secure write protect configuration block */
+int swp_write(qsee_stor_secure_wp_info_t swp_cb);
 #endif
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
index e0c94d3..3c85b8d 100644
--- a/platform/msm_shared/rpmb/rpmb.c
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -25,8 +25,11 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#include <stdlib.h>
+#include <string.h>
 #include <platform.h>
 #include <rpmb.h>
+#include <km_main.h>
 #include <rpmb_listener.h>
 #include <mmc_sdhci.h>
 #include <boot_device.h>
@@ -177,6 +180,35 @@
 	return 0;
 }
 
+/*
+ * SWP Write function is used to send a configuration block to rpmb
+ * for enabling a secure write protect based on LBAs. This function
+ * should is enabled by the keymaster secure app and this function
+ * can only be called before we send the milestone call to keymaster.
+ */
+int swp_write(qsee_stor_secure_wp_info_t swp_cb)
+{
+	secure_write_prot_req_t *req;
+	secure_write_prot_rsp_t rsp;
+	int ret = 0;
+	uint32_t tlen = sizeof(secure_write_prot_req_t) + sizeof(swp_cb);
+	if(!(req = (secure_write_prot_req_t *) malloc(tlen)))
+		ASSERT(0);
+	void *cpy_ptr = (uint8_t *) req + sizeof(secure_write_prot_req_t);
+	req->cmd_id = KEYMASTER_SECURE_WRITE_PROTECT;
+	req->op = SWP_WRITE_CONFIG;
+	req->swp_write_data_offset = sizeof(secure_write_prot_req_t);
+	req->swp_write_data_len = sizeof(swp_cb);
+	memcpy(cpy_ptr, (void *)&swp_cb, sizeof(swp_cb));
+	ret = qseecom_send_command(get_secapp_handle(), (void *)req, tlen, (void *)&rsp, sizeof(rsp));
+	if(ret < 0 || rsp.status < 0)
+	{
+		dprintf(CRITICAL, "Setting secure write protect configuration failed\n");
+		return -1;
+	}
+	return 0;
+}
+
 int rpmb_uninit()
 {
 	int ret = 0;