platform: msm_shared: Add support to write protect devinfo
Add API to write protect devinfo for verified boot feature. As
part of this add the following functions to support this
* Add api to get read-only attribute of a partition
* Enable RST_n_FUNC of emmc for power-on write protect to work
Change-Id: I466d7ee447680bf5dd2782a6a09232d866251197
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index 0098c0e..5f5ba72 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.h
@@ -86,6 +86,7 @@
/* EXT_CSD */
/* Offsets in the ext csd */
+#define MMC_EXT_CSD_RST_N_FUNC 162
#define MMC_EXT_MMC_BUS_WIDTH 183
#define MMC_EXT_MMC_HS_TIMING 185
#define MMC_DEVICE_TYPE 196
@@ -114,6 +115,7 @@
#define MMC_SEC_COUNT3_SHIFT 16
#define MMC_SEC_COUNT2_SHIFT 8
#define MMC_HC_ERASE_MULT (512 * 1024)
+#define RST_N_FUNC_ENABLE BIT(0)
/* Command related */
#define MMC_MAX_COMMAND_RETRY 1000
diff --git a/platform/msm_shared/include/mmc_wrapper.h b/platform/msm_shared/include/mmc_wrapper.h
index 57f74a0..f52a117 100644
--- a/platform/msm_shared/include/mmc_wrapper.h
+++ b/platform/msm_shared/include/mmc_wrapper.h
@@ -48,4 +48,5 @@
void mmc_set_lun(uint8_t lun);
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);
#endif
diff --git a/platform/msm_shared/include/partition_parser.h b/platform/msm_shared/include/partition_parser.h
index a2d3edd..af69e03 100644
--- a/platform/msm_shared/include/partition_parser.h
+++ b/platform/msm_shared/include/partition_parser.h
@@ -73,6 +73,7 @@
#define PARTITION_TYPE_GUID_SIZE 16
#define UNIQUE_PARTITION_GUID_SIZE 16
#define NUM_PARTITIONS 128
+#define PART_ATT_READONLY_OFFSET 60
/* Some useful define used to access the MBR/EBR table */
#define BLOCK_SIZE 0x200
@@ -179,5 +180,6 @@
/* For Debugging */
void partition_dump(void);
-
+/* Read only attribute for partition */
+int partition_read_only(int index);
#endif
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index 411f22c..76145eb 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -1665,6 +1665,18 @@
card->block_size = MMC_BLK_SZ;
+ /* Enable RST_n_FUNCTION */
+ if (!card->ext_csd[MMC_EXT_CSD_RST_N_FUNC])
+ {
+ mmc_return = mmc_switch_cmd(host, card, MMC_SET_BIT, MMC_EXT_CSD_RST_N_FUNC, RST_N_FUNC_ENABLE);
+
+ if (mmc_return)
+ {
+ dprintf(CRITICAL, "Failed to enable RST_n_FUNCTION\n");
+ return mmc_return;
+ }
+ }
+
return mmc_return;
}
diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index c660a5f..12bcd4d 100755
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -34,6 +34,7 @@
#include <ufs.h>
#include <target.h>
#include <string.h>
+#include <partition_parser.h>
/*
* Weak function for UFS.
@@ -586,3 +587,56 @@
}
}
}
+
+uint32_t mmc_write_protect(const char *ptn_name, int set_clr)
+{
+ void *dev = NULL;
+ struct mmc_card *card = NULL;
+ uint32_t block_size;
+ unsigned long long ptn = 0;
+ uint64_t size;
+ int index = -1;
+ int ret = 0;
+
+ dev = target_mmc_device();
+ block_size = mmc_get_device_blocksize();
+
+ if (platform_boot_dev_isemmc())
+ {
+ card = &((struct mmc_device *)dev)->card;
+
+ index = partition_get_index(ptn_name);
+
+ ptn = partition_get_offset(index);
+ if(!ptn)
+ {
+ return 1;
+ }
+
+ size = partition_get_size(index);
+
+ /*
+ * For read only partitions the minimum size allocated on the disk is
+ * 1 WP GRP size. If the size of partition is less than 1 WP GRP size
+ * protect atleast one WP group.
+ */
+ if (partition_read_only(index) && size < card->wp_grp_size)
+ {
+ size = card->wp_grp_size * block_size;
+ }
+ /* Set the power on WP bit */
+ return mmc_set_clr_power_on_wp_user((struct mmc_device *)dev, (ptn / block_size), size, set_clr);
+ }
+ else
+ {
+ /* Enable the power on WP fo all LUNs which have WP bit is enabled */
+ ret = dme_set_fpoweronwpen((struct ufs_dev*) dev);
+ if (ret < 0)
+ {
+ dprintf(CRITICAL, "Failure to WP UFS partition\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index d8774b9..d40fb8a 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -1057,3 +1057,8 @@
{
return (gpt_partitions_exist != 0);
}
+
+int partition_read_only(int index)
+{
+ return partition_entries[index].attribute_flag >> PART_ATT_READONLY_OFFSET;
+}