[U-Boot,25/25] mmc: Add hardware partition support

Message ID 20181106222142.94537-26-sjg@chromium.org
State New
Delegated to: Simon Glass
Headers show
Series
  • sandbox: Changes and improvements to support verified boot
Related show

Commit Message

Simon Glass Nov. 6, 2018, 10:21 p.m.
MMC devices support multiple partitions, defined by the hardware. At
present U-Boot can only access partition zero. Add support for selecting
other partitions.

Also add a way to check if a partition is write-protected.
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/mmc/mmc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     | 31 +++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

Comments

Faiz Abbas Nov. 7, 2018, 7:38 a.m. | #1
Hi Simon,

On Wednesday 07 November 2018 03:51 AM, Simon Glass wrote:
> MMC devices support multiple partitions, defined by the hardware. At
> present U-Boot can only access partition zero. Add support for selecting
> other partitions.
> 

There is already support to switch to another hardware partition.

See: mmc_select_hwpart()

Is this not the same thing?

Thanks,
Faiz

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d6b9cdc9922..5b542524338 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1128,6 +1128,52 @@  int mmc_hwpart_config(struct mmc *mmc,
 
 	return 0;
 }
+
+int mmc_hwpart_access(struct mmc *mmc, int part)
+{
+	int err;
+	struct mmc_cmd cmd;
+
+	cmd.cmdidx = MMC_CMD_SWITCH;
+	cmd.resp_type = MMC_RSP_R1b;
+
+	/* Clear partition access bits */
+	cmd.cmdarg = (MMC_SWITCH_MODE_CLEAR_BITS << 24) |
+			(EXT_CSD_PART_CONF << 16) |
+			(EXT_CSD_PARTITION_ACCESS(0x7) << 8);
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("Failed to clear partition access bits\n");
+		return err;
+	}
+
+	/* Set partition access bits */
+	cmd.cmdarg = (MMC_SWITCH_MODE_SET_BITS << 24) |
+			(EXT_CSD_PART_CONF << 16) |
+			(EXT_CSD_PARTITION_ACCESS(part) << 8);
+
+	err = mmc_send_cmd(mmc, &cmd, NULL);
+	if (err) {
+		debug("Failed to change partition\n");
+		return err;
+	}
+
+	return 0;
+}
+
+int mmc_get_boot_wp(struct mmc *mmc)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+	int err;
+
+	err = mmc_send_ext_csd(mmc, ext_csd);
+	if (err)
+		return err;
+
+	return ext_csd[EXT_CSD_BOOT_WP] & (EXT_CSD_BOOT_WP_PWR_WP_EN
+			| EXT_CSD_BOOT_WP_PERM_WP_EN);
+}
 #endif
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
diff --git a/include/mmc.h b/include/mmc.h
index 95548e94c4d..1d0f978f8af 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -215,6 +215,7 @@  static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_WR_REL_PARAM		166	/* R */
 #define EXT_CSD_WR_REL_SET		167	/* R/W */
 #define EXT_CSD_RPMB_MULT		168	/* RO */
+#define EXT_CSD_BOOT_WP			173	/* R/W */
 #define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
 #define EXT_CSD_BOOT_BUS_WIDTH		177
 #define EXT_CSD_PART_CONF		179	/* R/W */
@@ -279,6 +280,15 @@  static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_EXTRACT_BOOT_PART(x)		(((x) >> 3) & 0x7)
 #define EXT_CSD_EXTRACT_PARTITION_ACCESS(x)	((x) & 0x7)
 
+/* Enable boot power-on write protect */
+#define EXT_CSD_BOOT_WP_PWR_WP_EN	BIT(0)
+/* Enable boot permanent write protect */
+#define EXT_CSD_BOOT_WP_PERM_WP_EN	BIT(2)
+/* Disable use of boot power-on write protect */
+#define EXT_CSD_BOOT_WP_PWR_WP_DIS	BIT(6)
+/* Bit 1 (Power-on) or Bit 3 (Permanent) selects the partition to protect */
+#define EXT_CSD_BOOT_WP_PART_SELECT	BIT(7)
+
 #define EXT_CSD_BOOT_BUS_WIDTH_MODE(x)	(x << 3)
 #define EXT_CSD_BOOT_BUS_WIDTH_RESET(x)	(x << 2)
 #define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x)	(x)
@@ -735,6 +745,27 @@  int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
 		      enum mmc_hwpart_conf_mode mode);
 
+/**
+ * Get boot partition write protect status
+ *
+ * @param mmc	MMC to get status of
+ * @return	0 if WP is not asserted, non-zero if WP is asserted
+ */
+int mmc_get_boot_wp(struct mmc *mmc);
+
+/**
+ * Change MMC Partition
+ *
+ * Switch access to partition specified in part.  Unlike mmc_boot_part_access,
+ * this function will not affect the configured boot partition or boot ack
+ * settings.
+ *
+ * @param mmc	MMC to configure
+ * @param part	Partition to access (one of PARTITION_ACCESS from spec)
+ * #return 0 on success, -ve on error
+ */
+int mmc_hwpart_access(struct mmc *mmc, int part);
+
 #if !CONFIG_IS_ENABLED(DM_MMC)
 int mmc_getcd(struct mmc *mmc);
 int board_mmc_getcd(struct mmc *mmc);