diff mbox series

[1/9] mmc: sandbox: Add support for writing

Message ID 20201231224853.1431364-2-sean.anderson@seco.com
State Superseded
Delegated to: Tom Rini
Headers show
Series This series adds support for flashing eMMC boot partitions, and for | expand

Commit Message

Sean Anderson Dec. 31, 2020, 10:48 p.m. UTC
This adds support writing to the sandbox mmc backed by an in-memory buffer.
The unit test has been updated to test reading, writing, and erasing. I'm
not sure what MMC erase to; I picked 0, but if it's 0xFF then that can be
easily changed.

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---

 drivers/mmc/sandbox_mmc.c | 41 ++++++++++++++++++++++++++++++++++-----
 test/dm/mmc.c             | 19 +++++++++++++-----
 2 files changed, 50 insertions(+), 10 deletions(-)

Comments

Simon Glass Jan. 7, 2021, 12:35 p.m. UTC | #1
On Thu, 31 Dec 2020 at 15:49, Sean Anderson <sean.anderson@seco.com> wrote:
>
> This adds support writing to the sandbox mmc backed by an in-memory buffer.
> The unit test has been updated to test reading, writing, and erasing. I'm
> not sure what MMC erase to; I picked 0, but if it's 0xFF then that can be
> easily changed.
>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> ---
>
>  drivers/mmc/sandbox_mmc.c | 41 ++++++++++++++++++++++++++++++++++-----
>  test/dm/mmc.c             | 19 +++++++++++++-----
>  2 files changed, 50 insertions(+), 10 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox series

Patch

diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c
index e86ea8fe09..3daf708451 100644
--- a/drivers/mmc/sandbox_mmc.c
+++ b/drivers/mmc/sandbox_mmc.c
@@ -17,6 +17,17 @@  struct sandbox_mmc_plat {
 	struct mmc mmc;
 };
 
+#define MMC_CSIZE 0
+#define MMC_CMULT 8 /* 8 because the card is high-capacity */
+#define MMC_BL_LEN_SHIFT 10
+#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT)
+#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \
+		      * MMC_BL_LEN) /* 1 MiB */
+
+struct sandbox_mmc_priv {
+	u8 buf[MMC_CAPACITY];
+};
+
 /**
  * sandbox_mmc_send_cmd() - Emulate SD commands
  *
@@ -26,6 +37,10 @@  struct sandbox_mmc_plat {
 static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 				struct mmc_data *data)
 {
+	struct sandbox_mmc_priv *priv = dev_get_priv(dev);
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+	static ulong erase_start, erase_end;
+
 	switch (cmd->cmdidx) {
 	case MMC_CMD_ALL_SEND_CID:
 		memset(cmd->response, '\0', sizeof(cmd->response));
@@ -44,8 +59,9 @@  static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 		break;
 	case MMC_CMD_SEND_CSD:
 		cmd->response[0] = 0;
-		cmd->response[1] = 10 << 16;	/* 1 << block_len */
-		cmd->response[2] = 0;
+		cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) |
+				   ((MMC_CSIZE >> 16) & 0x3f);
+		cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
 		cmd->response[3] = 0;
 		break;
 	case SD_CMD_SWITCH_FUNC: {
@@ -59,13 +75,27 @@  static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 		break;
 	}
 	case MMC_CMD_READ_SINGLE_BLOCK:
-		memset(data->dest, '\0', data->blocksize);
-		break;
 	case MMC_CMD_READ_MULTIPLE_BLOCK:
-		strcpy(data->dest, "this is a test");
+		memcpy(data->dest, &priv->buf[cmd->cmdarg * data->blocksize],
+		       data->blocks * data->blocksize);
+		break;
+	case MMC_CMD_WRITE_SINGLE_BLOCK:
+	case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+		memcpy(&priv->buf[cmd->cmdarg * data->blocksize], data->src,
+		       data->blocks * data->blocksize);
 		break;
 	case MMC_CMD_STOP_TRANSMISSION:
 		break;
+	case SD_CMD_ERASE_WR_BLK_START:
+		erase_start = cmd->cmdarg;
+		break;
+	case SD_CMD_ERASE_WR_BLK_END:
+		erase_end = cmd->cmdarg;
+		break;
+	case MMC_CMD_ERASE:
+		memset(&priv->buf[erase_start * mmc->write_bl_len], '\0',
+		       (erase_end - erase_start + 1) * mmc->write_bl_len);
+		break;
 	case SD_CMD_APP_SEND_OP_COND:
 		cmd->response[0] = OCR_BUSY | OCR_HCS;
 		cmd->response[1] = 0;
@@ -148,5 +178,6 @@  U_BOOT_DRIVER(mmc_sandbox) = {
 	.bind		= sandbox_mmc_bind,
 	.unbind		= sandbox_mmc_unbind,
 	.probe		= sandbox_mmc_probe,
+	.priv_auto_alloc_size = sizeof(struct sandbox_mmc_priv),
 	.platdata_auto_alloc_size = sizeof(struct sandbox_mmc_plat),
 };
diff --git a/test/dm/mmc.c b/test/dm/mmc.c
index 4e5136c850..f744452ff2 100644
--- a/test/dm/mmc.c
+++ b/test/dm/mmc.c
@@ -29,16 +29,25 @@  static int dm_test_mmc_blk(struct unit_test_state *uts)
 {
 	struct udevice *dev;
 	struct blk_desc *dev_desc;
-	char cmp[1024];
+	int i;
+	char write[1024], read[1024];
 
 	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
 	ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
 
-	/* Read a few blocks and look for the string we expect */
+	/* Write a few blocks and verify that we get the same data back */
 	ut_asserteq(512, dev_desc->blksz);
-	memset(cmp, '\0', sizeof(cmp));
-	ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
-	ut_assertok(strcmp(cmp, "this is a test"));
+	for (i = 0; i < sizeof(write); i++)
+		write[i] = i;
+	ut_asserteq(2, blk_dwrite(dev_desc, 0, 2, write));
+	ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
+	ut_asserteq_mem(write, read, sizeof(write));
+
+	/* Now erase them */
+	memset(write, '\0', sizeof(write));
+	ut_asserteq(2, blk_derase(dev_desc, 0, 2));
+	ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
+	ut_asserteq_mem(write, read, sizeof(write));
 
 	return 0;
 }