
On 2/1/21 2:59 AM, Lukasz Majewski wrote:
Hi Sean,
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 MMCs erase to; I picked 0, but if it's 0xFF then that can be easily changed.
Could you rebase this patch series on top of: https://gitlab.denx.de/u-boot/custodians/u-boot-dfu/-/commits/master
I've encountered some conflicts with previous patches.
(And of course sorry for trouble - this patch series is the last one with the pile I've got for USB/DFU).
Thanks in advance.
Ok, I've resent after rebasing. However, I would appreciate if you could hold off on merging Patrick's first two patches. I think this series better solves his problem.
--Sean
Signed-off-by: Sean Anderson sean.anderson@seco.com Reviewed-by: Simon Glass sjg@chromium.org
(no changes since v1)
drivers/mmc/sandbox_mmc.c | 41 ++++++++++++++++++++++++++++++++++----- test/dm/mmc.c | 19 +++++++++++++----- 2 files changed, 50 insertions(+), 10 deletions(-)
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[3] = 0; break; case SD_CMD_SWITCH_FUNC: {cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
@@ -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);
case MMC_CMD_READ_MULTIPLE_BLOCK:break;
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,
break; case MMC_CMD_STOP_TRANSMISSION: break;data->blocks * data->blocksize);
- 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);
case SD_CMD_APP_SEND_OP_COND: cmd->response[0] = OCR_BUSY | OCR_HCS; cmd->response[1] = 0;break;
@@ -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; }
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de