All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/21] eMMC support
@ 2021-02-28 19:33 Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 01/21] sd: sd: Remove usage of tabs in the file Sai Pavan Boddu
                   ` (21 more replies)
  0 siblings, 22 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Hi,

This patch series add support for eMMC cards. This work was previosly
submitted by Vincent, rebased few changes on top.

Cedric & Joel has helped to added boot partition access support. I
expect them to make a follow-up series to use it with aspeed machines.

Present series adds eMMC support to Versal SOC.

Initial patch series version is RFC
Changes for V2:
	Split Patch 1
	Add comments for eMMC Erase commands
	Added documentation about eMMC and Versal-virt board.
	Make eMMC optional for xlnx-versal-virt machines
Changes for V3:
	Revome addition of EMMC drive flag
	Add TYPE_EMMC device
	Add id strings for shci instances
	Update versal doc with eMMC example
	Fix signed-off-by lines for few patches

Cédric Le Goater (1):
  sd: sdmmc-internal: Add command string for SEND_OP_CMD

Joel Stanley (2):
  sd: emmc: Support boot area in emmc image
  sd: emmc: Subtract bootarea size from blk

Sai Pavan Boddu (14):
  sd: sd: Remove usage of tabs in the file
  sd: emmc: Add support for eMMC cards
  sd: emmc: Dont not update CARD_CAPACITY for eMMC cards
  sd: emmc: Update CMD1 definition for eMMC
  sd: emmc: support idle state in CMD2
  sd: emmc: Add mmc switch function support
  sd: emmc: add CMD21 tuning sequence
  sd: emmc: Make ACMD41 illegal for mmc
  sd: emmc: Add support for emmc erase
  sd: emmc: Update CID structure for eMMC
  sd: sdhci: Support eMMC devices
  arm: xlnx-versal: Add emmc to versal
  docs: devel: emmc: Add a doc for emmc card emulation
  docs: arm: xlnx-versal-virt: Add eMMC support documentation

Vincent Palatin (4):
  sd: emmc: Update SET_RELATIVE_ADDR command
  sd: emmc: update OCR fields for eMMC
  sd: emmc: Add support for EXT_CSD & CSD for eMMC
  sd: emmc: Update CMD8 to send EXT_CSD register

 docs/devel/emmc.txt                  |  16 +
 docs/system/arm/xlnx-versal-virt.rst |  14 +
 hw/sd/sdmmc-internal.h               |  97 ++++++
 include/hw/arm/xlnx-versal.h         |   1 +
 include/hw/sd/sd.h                   |   2 +
 hw/arm/xlnx-versal-virt.c            |  29 +-
 hw/arm/xlnx-versal.c                 |  14 +-
 hw/sd/sd.c                           | 563 ++++++++++++++++++++++++++---------
 hw/sd/sdhci.c                        |   4 -
 hw/sd/sdmmc-internal.c               |   2 +-
 10 files changed, 594 insertions(+), 148 deletions(-)
 create mode 100644 docs/devel/emmc.txt

-- 
2.7.4



^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v3 01/21] sd: sd: Remove usage of tabs in the file
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 02/21] sd: emmc: Add support for eMMC cards Sai Pavan Boddu
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Set tabstop as 4 and used expandtabs

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sd.c | 190 ++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 95 insertions(+), 95 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8517dbc..74b9162 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -332,39 +332,39 @@ static void sd_set_scr(SDState *sd)
     sd->scr[7] = 0x00;
 }
 
-#define MID	0xaa
-#define OID	"XY"
-#define PNM	"QEMU!"
-#define PRV	0x01
-#define MDT_YR	2006
-#define MDT_MON	2
+#define MID 0xaa
+#define OID "XY"
+#define PNM "QEMU!"
+#define PRV 0x01
+#define MDT_YR  2006
+#define MDT_MON 2
 
 static void sd_set_cid(SDState *sd)
 {
-    sd->cid[0] = MID;		/* Fake card manufacturer ID (MID) */
-    sd->cid[1] = OID[0];	/* OEM/Application ID (OID) */
+    sd->cid[0] = MID;       /* Fake card manufacturer ID (MID) */
+    sd->cid[1] = OID[0];    /* OEM/Application ID (OID) */
     sd->cid[2] = OID[1];
-    sd->cid[3] = PNM[0];	/* Fake product name (PNM) */
+    sd->cid[3] = PNM[0];    /* Fake product name (PNM) */
     sd->cid[4] = PNM[1];
     sd->cid[5] = PNM[2];
     sd->cid[6] = PNM[3];
     sd->cid[7] = PNM[4];
-    sd->cid[8] = PRV;		/* Fake product revision (PRV) */
-    sd->cid[9] = 0xde;		/* Fake serial number (PSN) */
+    sd->cid[8] = PRV;       /* Fake product revision (PRV) */
+    sd->cid[9] = 0xde;      /* Fake serial number (PSN) */
     sd->cid[10] = 0xad;
     sd->cid[11] = 0xbe;
     sd->cid[12] = 0xef;
-    sd->cid[13] = 0x00 |	/* Manufacture date (MDT) */
+    sd->cid[13] = 0x00 |    /* Manufacture date (MDT) */
         ((MDT_YR - 2000) / 10);
     sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
     sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
-#define HWBLOCK_SHIFT	9			/* 512 bytes */
-#define SECTOR_SHIFT	5			/* 16 kilobytes */
-#define WPGROUP_SHIFT	7			/* 2 megs */
-#define CMULT_SHIFT	9			/* 512 times HWBLOCK_SIZE */
-#define WPGROUP_SIZE	(1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
+#define HWBLOCK_SHIFT   9           /* 512 bytes */
+#define SECTOR_SHIFT    5           /* 16 kilobytes */
+#define WPGROUP_SHIFT   7           /* 2 megs */
+#define CMULT_SHIFT 9           /* 512 times HWBLOCK_SIZE */
+#define WPGROUP_SIZE    (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
 
 static const uint8_t sd_csd_rw_mask[16] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -385,31 +385,31 @@ static void sd_set_csd(SDState *sd, uint64_t size)
     csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
     if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
-        sd->csd[0] = 0x00;	/* CSD structure */
-        sd->csd[1] = 0x26;	/* Data read access-time-1 */
-        sd->csd[2] = 0x00;	/* Data read access-time-2 */
+        sd->csd[0] = 0x00;  /* CSD structure */
+        sd->csd[1] = 0x26;  /* Data read access-time-1 */
+        sd->csd[2] = 0x00;  /* Data read access-time-2 */
         sd->csd[3] = 0x32;      /* Max. data transfer rate: 25 MHz */
-        sd->csd[4] = 0x5f;	/* Card Command Classes */
-        sd->csd[5] = 0x50 |	/* Max. read data block length */
+        sd->csd[4] = 0x5f;  /* Card Command Classes */
+        sd->csd[5] = 0x50 | /* Max. read data block length */
             hwblock_shift;
-        sd->csd[6] = 0xe0 |	/* Partial block for read allowed */
+        sd->csd[6] = 0xe0 | /* Partial block for read allowed */
             ((csize >> 10) & 0x03);
-        sd->csd[7] = 0x00 |	/* Device size */
+        sd->csd[7] = 0x00 | /* Device size */
             ((csize >> 2) & 0xff);
-        sd->csd[8] = 0x3f |	/* Max. read current */
+        sd->csd[8] = 0x3f | /* Max. read current */
             ((csize << 6) & 0xc0);
-        sd->csd[9] = 0xfc |	/* Max. write current */
+        sd->csd[9] = 0xfc | /* Max. write current */
             ((CMULT_SHIFT - 2) >> 1);
-        sd->csd[10] = 0x40 |	/* Erase sector size */
+        sd->csd[10] = 0x40 |    /* Erase sector size */
             (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
-        sd->csd[11] = 0x00 |	/* Write protect group size */
+        sd->csd[11] = 0x00 |    /* Write protect group size */
             ((sectsize << 7) & 0x80) | wpsize;
-        sd->csd[12] = 0x90 |	/* Write speed factor */
+        sd->csd[12] = 0x90 |    /* Write speed factor */
             (hwblock_shift >> 2);
-        sd->csd[13] = 0x20 |	/* Max. write data block length */
+        sd->csd[13] = 0x20 |    /* Max. write data block length */
             ((hwblock_shift << 6) & 0xc0);
-        sd->csd[14] = 0x00;	/* File format group */
-    } else {			/* SDHC */
+        sd->csd[14] = 0x00; /* File format group */
+    } else {            /* SDHC */
         size /= 512 * KiB;
         size -= 1;
         sd->csd[0] = 0x40;
@@ -503,7 +503,7 @@ static int sd_req_crc_validate(SDRequest *req)
     buffer[0] = 0x40 | req->cmd;
     stl_be_p(&buffer[1], req->arg);
     return 0;
-    return sd_crc7(buffer, 5) != req->crc;	/* TODO */
+    return sd_crc7(buffer, 5) != req->crc;  /* TODO */
 }
 
 static void sd_response_r1_make(SDState *sd, uint8_t *response)
@@ -803,19 +803,19 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
     int i, mode, new_func;
     mode = !!(arg & 0x80000000);
 
-    sd->data[0] = 0x00;		/* Maximum current consumption */
+    sd->data[0] = 0x00;     /* Maximum current consumption */
     sd->data[1] = 0x01;
-    sd->data[2] = 0x80;		/* Supported group 6 functions */
+    sd->data[2] = 0x80;     /* Supported group 6 functions */
     sd->data[3] = 0x01;
-    sd->data[4] = 0x80;		/* Supported group 5 functions */
+    sd->data[4] = 0x80;     /* Supported group 5 functions */
     sd->data[5] = 0x01;
-    sd->data[6] = 0x80;		/* Supported group 4 functions */
+    sd->data[6] = 0x80;     /* Supported group 4 functions */
     sd->data[7] = 0x01;
-    sd->data[8] = 0x80;		/* Supported group 3 functions */
+    sd->data[8] = 0x80;     /* Supported group 3 functions */
     sd->data[9] = 0x01;
-    sd->data[10] = 0x80;	/* Supported group 2 functions */
+    sd->data[10] = 0x80;    /* Supported group 2 functions */
     sd->data[11] = 0x43;
-    sd->data[12] = 0x80;	/* Supported group 1 functions */
+    sd->data[12] = 0x80;    /* Supported group 1 functions */
     sd->data[13] = 0x03;
 
     memset(&sd->data[14], 0, 3);
@@ -940,7 +940,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 
     switch (req.cmd) {
     /* Basic commands (Class 0 and Class 1) */
-    case 0:	/* CMD0:   GO_IDLE_STATE */
+    case 0: /* CMD0:   GO_IDLE_STATE */
         switch (sd->state) {
         case sd_inactive_state:
             return sd->spi ? sd_r1 : sd_r0;
@@ -952,14 +952,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 1:	/* CMD1:   SEND_OP_CMD */
+    case 1: /* CMD1:   SEND_OP_CMD */
         if (!sd->spi)
             goto bad_cmd;
 
         sd->state = sd_transfer_state;
         return sd_r1;
 
-    case 2:	/* CMD2:   ALL_SEND_CID */
+    case 2: /* CMD2:   ALL_SEND_CID */
         if (sd->spi)
             goto bad_cmd;
         switch (sd->state) {
@@ -972,7 +972,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 3:	/* CMD3:   SEND_RELATIVE_ADDR */
+    case 3: /* CMD3:   SEND_RELATIVE_ADDR */
         if (sd->spi)
             goto bad_cmd;
         switch (sd->state) {
@@ -987,7 +987,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 4:	/* CMD4:   SEND_DSR */
+    case 4: /* CMD4:   SEND_DSR */
         if (sd->spi)
             goto bad_cmd;
         switch (sd->state) {
@@ -1002,7 +1002,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
     case 5: /* CMD5: reserved for SDIO cards */
         return sd_illegal;
 
-    case 6:	/* CMD6:   SWITCH_FUNCTION */
+    case 6: /* CMD6:   SWITCH_FUNCTION */
         switch (sd->mode) {
         case sd_data_transfer_mode:
             sd_function_switch(sd, req.arg);
@@ -1016,7 +1016,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 7:	/* CMD7:   SELECT/DESELECT_CARD */
+    case 7: /* CMD7:   SELECT/DESELECT_CARD */
         if (sd->spi)
             goto bad_cmd;
         switch (sd->state) {
@@ -1054,7 +1054,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 8:	/* CMD8:   SEND_IF_COND */
+    case 8: /* CMD8:   SEND_IF_COND */
         if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
             break;
         }
@@ -1072,7 +1072,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         sd->vhs = req.arg;
         return sd_r7;
 
-    case 9:	/* CMD9:   SEND_CSD */
+    case 9: /* CMD9:   SEND_CSD */
         switch (sd->state) {
         case sd_standby_state:
             if (sd->rca != rca)
@@ -1094,7 +1094,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 10:	/* CMD10:  SEND_CID */
+    case 10:    /* CMD10:  SEND_CID */
         switch (sd->state) {
         case sd_standby_state:
             if (sd->rca != rca)
@@ -1116,7 +1116,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 12:	/* CMD12:  STOP_TRANSMISSION */
+    case 12:    /* CMD12:  STOP_TRANSMISSION */
         switch (sd->state) {
         case sd_sendingdata_state:
             sd->state = sd_transfer_state;
@@ -1133,7 +1133,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 13:	/* CMD13:  SEND_STATUS */
+    case 13:    /* CMD13:  SEND_STATUS */
         switch (sd->mode) {
         case sd_data_transfer_mode:
             if (sd->rca != rca)
@@ -1146,7 +1146,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 15:	/* CMD15:  GO_INACTIVE_STATE */
+    case 15:    /* CMD15:  GO_INACTIVE_STATE */
         if (sd->spi)
             goto bad_cmd;
         switch (sd->mode) {
@@ -1163,7 +1163,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     /* Block read commands (Classs 2) */
-    case 16:	/* CMD16:  SET_BLOCKLEN */
+    case 16:    /* CMD16:  SET_BLOCKLEN */
         switch (sd->state) {
         case sd_transfer_state:
             if (req.arg > (1 << HWBLOCK_SHIFT)) {
@@ -1180,7 +1180,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 17:	/* CMD17:  READ_SINGLE_BLOCK */
+    case 17:    /* CMD17:  READ_SINGLE_BLOCK */
         switch (sd->state) {
         case sd_transfer_state:
 
@@ -1199,7 +1199,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 18:	/* CMD18:  READ_MULTIPLE_BLOCK */
+    case 18:    /* CMD18:  READ_MULTIPLE_BLOCK */
         switch (sd->state) {
         case sd_transfer_state:
 
@@ -1244,7 +1244,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     /* Block write commands (Class 4) */
-    case 24:	/* CMD24:  WRITE_SINGLE_BLOCK */
+    case 24:    /* CMD24:  WRITE_SINGLE_BLOCK */
         switch (sd->state) {
         case sd_transfer_state:
             /* Writing in SPI mode not implemented.  */
@@ -1274,7 +1274,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */
+    case 25:    /* CMD25:  WRITE_MULTIPLE_BLOCK */
         switch (sd->state) {
         case sd_transfer_state:
             /* Writing in SPI mode not implemented.  */
@@ -1304,7 +1304,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 26:	/* CMD26:  PROGRAM_CID */
+    case 26:    /* CMD26:  PROGRAM_CID */
         if (sd->spi)
             goto bad_cmd;
         switch (sd->state) {
@@ -1319,7 +1319,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 27:	/* CMD27:  PROGRAM_CSD */
+    case 27:    /* CMD27:  PROGRAM_CSD */
         switch (sd->state) {
         case sd_transfer_state:
             sd->state = sd_receivingdata_state;
@@ -1333,7 +1333,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     /* Write protection (Class 6) */
-    case 28:	/* CMD28:  SET_WRITE_PROT */
+    case 28:    /* CMD28:  SET_WRITE_PROT */
         switch (sd->state) {
         case sd_transfer_state:
             if (addr >= sd->size) {
@@ -1352,7 +1352,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 29:	/* CMD29:  CLR_WRITE_PROT */
+    case 29:    /* CMD29:  CLR_WRITE_PROT */
         switch (sd->state) {
         case sd_transfer_state:
             if (addr >= sd->size) {
@@ -1371,7 +1371,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 30:	/* CMD30:  SEND_WRITE_PROT */
+    case 30:    /* CMD30:  SEND_WRITE_PROT */
         switch (sd->state) {
         case sd_transfer_state:
             sd->state = sd_sendingdata_state;
@@ -1386,7 +1386,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     /* Erase commands (Class 5) */
-    case 32:	/* CMD32:  ERASE_WR_BLK_START */
+    case 32:    /* CMD32:  ERASE_WR_BLK_START */
         switch (sd->state) {
         case sd_transfer_state:
             sd->erase_start = req.arg;
@@ -1397,7 +1397,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 33:	/* CMD33:  ERASE_WR_BLK_END */
+    case 33:    /* CMD33:  ERASE_WR_BLK_END */
         switch (sd->state) {
         case sd_transfer_state:
             sd->erase_end = req.arg;
@@ -1408,7 +1408,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 38:	/* CMD38:  ERASE */
+    case 38:    /* CMD38:  ERASE */
         switch (sd->state) {
         case sd_transfer_state:
             if (sd->csd[14] & 0x30) {
@@ -1428,7 +1428,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     /* Lock card commands (Class 7) */
-    case 42:	/* CMD42:  LOCK_UNLOCK */
+    case 42:    /* CMD42:  LOCK_UNLOCK */
         switch (sd->state) {
         case sd_transfer_state:
             sd->state = sd_receivingdata_state;
@@ -1451,7 +1451,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         return sd_illegal;
 
     /* Application specific commands (Class 8) */
-    case 55:	/* CMD55:  APP_CMD */
+    case 55:    /* CMD55:  APP_CMD */
         switch (sd->state) {
         case sd_ready_state:
         case sd_identification_state:
@@ -1474,7 +1474,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         sd->card_status |= APP_CMD;
         return sd_r1;
 
-    case 56:	/* CMD56:  GEN_CMD */
+    case 56:    /* CMD56:  GEN_CMD */
         switch (sd->state) {
         case sd_transfer_state:
             sd->data_offset = 0;
@@ -1518,7 +1518,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
                              req.cmd, req.arg, sd_state_name(sd->state));
     sd->card_status |= APP_CMD;
     switch (req.cmd) {
-    case 6:	/* ACMD6:  SET_BUS_WIDTH */
+    case 6: /* ACMD6:  SET_BUS_WIDTH */
         if (sd->spi) {
             goto unimplemented_spi_cmd;
         }
@@ -1533,7 +1533,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         }
         break;
 
-    case 13:	/* ACMD13: SD_STATUS */
+    case 13:    /* ACMD13: SD_STATUS */
         switch (sd->state) {
         case sd_transfer_state:
             sd->state = sd_sendingdata_state;
@@ -1546,7 +1546,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         }
         break;
 
-    case 22:	/* ACMD22: SEND_NUM_WR_BLOCKS */
+    case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
         switch (sd->state) {
         case sd_transfer_state:
             *(uint32_t *) sd->data = sd->blk_written;
@@ -1561,7 +1561,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         }
         break;
 
-    case 23:	/* ACMD23: SET_WR_BLK_ERASE_COUNT */
+    case 23:    /* ACMD23: SET_WR_BLK_ERASE_COUNT */
         switch (sd->state) {
         case sd_transfer_state:
             return sd_r1;
@@ -1571,7 +1571,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         }
         break;
 
-    case 41:	/* ACMD41: SD_APP_OP_COND */
+    case 41:    /* ACMD41: SD_APP_OP_COND */
         if (sd->spi) {
             /* SEND_OP_CMD */
             sd->state = sd_transfer_state;
@@ -1613,7 +1613,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 
         return sd_r3;
 
-    case 42:	/* ACMD42: SET_CLR_CARD_DETECT */
+    case 42:    /* ACMD42: SET_CLR_CARD_DETECT */
         switch (sd->state) {
         case sd_transfer_state:
             /* Bringing in the 50KOhm pull-up resistor... Done.  */
@@ -1624,7 +1624,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         }
         break;
 
-    case 51:	/* ACMD51: SEND_SCR */
+    case 51:    /* ACMD51: SEND_SCR */
         switch (sd->state) {
         case sd_transfer_state:
             sd->state = sd_sendingdata_state;
@@ -1808,9 +1808,9 @@ static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
     }
 }
 
-#define BLK_READ_BLOCK(a, len)	sd_blk_read(sd, a, len)
-#define BLK_WRITE_BLOCK(a, len)	sd_blk_write(sd, a, len)
-#define APP_READ_BLOCK(a, len)	memset(sd->data, 0xec, len)
+#define BLK_READ_BLOCK(a, len)  sd_blk_read(sd, a, len)
+#define BLK_WRITE_BLOCK(a, len) sd_blk_write(sd, a, len)
+#define APP_READ_BLOCK(a, len)  memset(sd->data, 0xec, len)
 #define APP_WRITE_BLOCK(a, len)
 
 void sd_write_byte(SDState *sd, uint8_t value)
@@ -1833,7 +1833,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
                             sd_acmd_name(sd->current_cmd),
                             sd->current_cmd, value);
     switch (sd->current_cmd) {
-    case 24:	/* CMD24:  WRITE_SINGLE_BLOCK */
+    case 24:    /* CMD24:  WRITE_SINGLE_BLOCK */
         sd->data[sd->data_offset ++] = value;
         if (sd->data_offset >= sd->blk_len) {
             /* TODO: Check CRC before committing */
@@ -1846,7 +1846,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
         }
         break;
 
-    case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */
+    case 25:    /* CMD25:  WRITE_MULTIPLE_BLOCK */
         if (sd->data_offset == 0) {
             /* Start of the block - let's check the address is valid */
             if (sd->data_start + sd->blk_len > sd->size) {
@@ -1881,7 +1881,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
         }
         break;
 
-    case 26:	/* CMD26:  PROGRAM_CID */
+    case 26:    /* CMD26:  PROGRAM_CID */
         sd->data[sd->data_offset ++] = value;
         if (sd->data_offset >= sizeof(sd->cid)) {
             /* TODO: Check CRC before committing */
@@ -1900,7 +1900,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
         }
         break;
 
-    case 27:	/* CMD27:  PROGRAM_CSD */
+    case 27:    /* CMD27:  PROGRAM_CSD */
         sd->data[sd->data_offset ++] = value;
         if (sd->data_offset >= sizeof(sd->csd)) {
             /* TODO: Check CRC before committing */
@@ -1924,7 +1924,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
         }
         break;
 
-    case 42:	/* CMD42:  LOCK_UNLOCK */
+    case 42:    /* CMD42:  LOCK_UNLOCK */
         sd->data[sd->data_offset ++] = value;
         if (sd->data_offset >= sd->blk_len) {
             /* TODO: Check CRC before committing */
@@ -1935,7 +1935,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
         }
         break;
 
-    case 56:	/* CMD56:  GEN_CMD */
+    case 56:    /* CMD56:  GEN_CMD */
         sd->data[sd->data_offset ++] = value;
         if (sd->data_offset >= sd->blk_len) {
             APP_WRITE_BLOCK(sd->data_start, sd->data_offset);
@@ -1987,29 +1987,29 @@ uint8_t sd_read_byte(SDState *sd)
                            sd_acmd_name(sd->current_cmd),
                            sd->current_cmd, io_len);
     switch (sd->current_cmd) {
-    case 6:	/* CMD6:   SWITCH_FUNCTION */
+    case 6: /* CMD6:   SWITCH_FUNCTION */
         ret = sd->data[sd->data_offset ++];
 
         if (sd->data_offset >= 64)
             sd->state = sd_transfer_state;
         break;
 
-    case 9:	/* CMD9:   SEND_CSD */
-    case 10:	/* CMD10:  SEND_CID */
+    case 9:     /* CMD9:   SEND_CSD */
+    case 10:    /* CMD10:  SEND_CID */
         ret = sd->data[sd->data_offset ++];
 
         if (sd->data_offset >= 16)
             sd->state = sd_transfer_state;
         break;
 
-    case 13:	/* ACMD13: SD_STATUS */
+    case 13:    /* ACMD13: SD_STATUS */
         ret = sd->sd_status[sd->data_offset ++];
 
         if (sd->data_offset >= sizeof(sd->sd_status))
             sd->state = sd_transfer_state;
         break;
 
-    case 17:	/* CMD17:  READ_SINGLE_BLOCK */
+    case 17:    /* CMD17:  READ_SINGLE_BLOCK */
         if (sd->data_offset == 0)
             BLK_READ_BLOCK(sd->data_start, io_len);
         ret = sd->data[sd->data_offset ++];
@@ -2018,7 +2018,7 @@ uint8_t sd_read_byte(SDState *sd)
             sd->state = sd_transfer_state;
         break;
 
-    case 18:	/* CMD18:  READ_MULTIPLE_BLOCK */
+    case 18:    /* CMD18:  READ_MULTIPLE_BLOCK */
         if (sd->data_offset == 0) {
             if (sd->data_start + io_len > sd->size) {
                 sd->card_status |= ADDRESS_ERROR;
@@ -2049,28 +2049,28 @@ uint8_t sd_read_byte(SDState *sd)
         ret = sd_tuning_block_pattern[sd->data_offset++];
         break;
 
-    case 22:	/* ACMD22: SEND_NUM_WR_BLOCKS */
+    case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
         ret = sd->data[sd->data_offset ++];
 
         if (sd->data_offset >= 4)
             sd->state = sd_transfer_state;
         break;
 
-    case 30:	/* CMD30:  SEND_WRITE_PROT */
+    case 30:    /* CMD30:  SEND_WRITE_PROT */
         ret = sd->data[sd->data_offset ++];
 
         if (sd->data_offset >= 4)
             sd->state = sd_transfer_state;
         break;
 
-    case 51:	/* ACMD51: SEND_SCR */
+    case 51:    /* ACMD51: SEND_SCR */
         ret = sd->scr[sd->data_offset ++];
 
         if (sd->data_offset >= sizeof(sd->scr))
             sd->state = sd_transfer_state;
         break;
 
-    case 56:	/* CMD56:  GEN_CMD */
+    case 56:    /* CMD56:  GEN_CMD */
         if (sd->data_offset == 0)
             APP_READ_BLOCK(sd->data_start, sd->blk_len);
         ret = sd->data[sd->data_offset ++];
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 02/21] sd: emmc: Add support for eMMC cards
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 01/21] sd: sd: Remove usage of tabs in the file Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 11:02   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 03/21] sd: emmc: Update SET_RELATIVE_ADDR command Sai Pavan Boddu
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Add eMMC device built on top of SD card.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 include/hw/sd/sd.h |  2 ++
 hw/sd/sd.c         | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 05ef9b7..b402dad 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -90,6 +90,8 @@ typedef struct {
 } SDRequest;
 
 
+#define TYPE_EMMC "emmc"
+OBJECT_DECLARE_SIMPLE_TYPE(EMMCState, EMMC)
 #define TYPE_SD_CARD "sd-card"
 OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
 
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 74b9162..a23af6d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -108,6 +108,7 @@ struct SDState {
     uint8_t spec_version;
     BlockBackend *blk;
     bool spi;
+    bool emmc;
 
     /* Runtime changeables */
 
@@ -143,6 +144,10 @@ struct SDState {
     bool cmd_line;
 };
 
+struct EMMCState {
+    SDState parent;
+};
+
 static void sd_realize(DeviceState *dev, Error **errp);
 
 static const char *sd_state_name(enum SDCardStates state)
@@ -2105,6 +2110,13 @@ static void sd_instance_init(Object *obj)
     sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sd_ocr_powerup, sd);
 }
 
+static void emmc_instance_init(Object *obj)
+{
+    SDState *sd = SD_CARD(obj);
+
+    sd->emmc = true;
+}
+
 static void sd_instance_finalize(Object *obj)
 {
     SDState *sd = SD_CARD(obj);
@@ -2213,9 +2225,17 @@ static const TypeInfo sd_info = {
     .instance_finalize = sd_instance_finalize,
 };
 
+static const TypeInfo emmc_info = {
+    .name = TYPE_EMMC,
+    .parent = TYPE_SD_CARD,
+    .instance_size = sizeof(EMMCState),
+    .instance_init = emmc_instance_init,
+};
+
 static void sd_register_types(void)
 {
     type_register_static(&sd_info);
+    type_register_static(&emmc_info);
 }
 
 type_init(sd_register_types)
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 03/21] sd: emmc: Update SET_RELATIVE_ADDR command
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 01/21] sd: sd: Remove usage of tabs in the file Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 02/21] sd: emmc: Add support for eMMC cards Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 04/21] sd: emmc: update OCR fields for eMMC Sai Pavan Boddu
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Vincent Palatin <vpalatin@chromium.org>

Change SET_RELATIVE_ADDR command to assign relative address
as requested by user.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
[spb: Split original patch series]
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sd.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a23af6d..6de414b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -436,9 +436,13 @@ static void sd_set_csd(SDState *sd, uint64_t size)
     sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
 }
 
-static void sd_set_rca(SDState *sd)
+static void sd_set_rca(SDState *sd, uint16_t value)
 {
-    sd->rca += 0x4567;
+    if (sd->emmc) {
+        sd->rca = value;
+    } else {
+        sd->rca += 0x4567;
+    }
 }
 
 FIELD(CSR, AKE_SEQ_ERROR,               3,  1)
@@ -984,8 +988,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         case sd_identification_state:
         case sd_standby_state:
             sd->state = sd_standby_state;
-            sd_set_rca(sd);
-            return sd_r6;
+            sd_set_rca(sd, req.arg >> 16);
+            return sd->emmc ? sd_r1 : sd_r6;
 
         default:
             break;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 04/21] sd: emmc: update OCR fields for eMMC
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (2 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 03/21] sd: emmc: Update SET_RELATIVE_ADDR command Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 11:04   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD " Sai Pavan Boddu
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Vincent Palatin <vpalatin@chromium.org>

eMMC OCR register doesn't has UHS-II field and voltage fields are
different.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sd.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6de414b..bc9d913 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -287,6 +287,15 @@ FIELD(OCR, UHS_II_CARD,                29,  1) /* Only UHS-II */
 FIELD(OCR, CARD_CAPACITY,              30,  1) /* 0:SDSC, 1:SDHC/SDXC */
 FIELD(OCR, CARD_POWER_UP,              31,  1)
 
+/*
+ * eMMC OCR register
+ */
+FIELD(EMMC_OCR, VDD_WINDOW_0,  7, 1)
+FIELD(EMMC_OCR, VDD_WINDOW_1,  8, 7)
+FIELD(EMMC_OCR, VDD_WINDOW_2, 15, 9)
+FIELD(EMMC_OCR, ACCESS_MODE,  29, 2)
+FIELD(EMMC_OCR, POWER_UP,     31, 1)
+
 #define ACMD41_ENQUIRY_MASK     0x00ffffff
 #define ACMD41_R3_MASK          (R_OCR_VDD_VOLTAGE_WIN_HI_MASK \
                                | R_OCR_ACCEPT_SWITCH_1V8_MASK \
@@ -296,8 +305,16 @@ FIELD(OCR, CARD_POWER_UP,              31,  1)
 
 static void sd_set_ocr(SDState *sd)
 {
-    /* All voltages OK */
-    sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+    if (sd->emmc) {
+        /*
+         * Dual Voltage eMMC card
+         */
+        sd->ocr = R_EMMC_OCR_VDD_WINDOW_0_MASK |
+                  R_EMMC_OCR_VDD_WINDOW_2_MASK;
+    } else {
+        /* All voltages OK */
+        sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+    }
 }
 
 static void sd_ocr_powerup(void *opaque)
@@ -525,7 +542,11 @@ static void sd_response_r1_make(SDState *sd, uint8_t *response)
 
 static void sd_response_r3_make(SDState *sd, uint8_t *response)
 {
-    stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
+    if (sd->emmc) {
+        stl_be_p(response, sd->ocr);
+    } else {
+        stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
+    }
 }
 
 static void sd_response_r6_make(SDState *sd, uint8_t *response)
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD for eMMC
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (3 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 04/21] sd: emmc: update OCR fields for eMMC Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 11:08   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register Sai Pavan Boddu
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Vincent Palatin <vpalatin@chromium.org>

eMMC CSD is similar to SD with an option to refer EXT_CSD for larger
devices.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
[clg: Add user friendly macros for EXT_CSD register]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
[spb: updated commit message]
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sdmmc-internal.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/sd/sd.c             | 61 +++++++++++++++++++++++++++++--
 2 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
index d8bf17d..7ab7b4d 100644
--- a/hw/sd/sdmmc-internal.h
+++ b/hw/sd/sdmmc-internal.h
@@ -37,4 +37,101 @@ const char *sd_cmd_name(uint8_t cmd);
  */
 const char *sd_acmd_name(uint8_t cmd);
 
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_CMDQ_MODE_EN    15  /* R/W */
+#define EXT_CSD_FLUSH_CACHE   32      /* W */
+#define EXT_CSD_CACHE_CTRL    33      /* R/W */
+#define EXT_CSD_POWER_OFF_NOTIFICATION  34  /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX  35  /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS 36  /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS 54  /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL   56  /* R/W, 2 bytes */
+#define EXT_CSD_DATA_SECTOR_SIZE  61  /* R */
+#define EXT_CSD_GP_SIZE_MULT    143 /* R/W */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
+#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
+#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
+#define EXT_CSD_HPI_MGMT    161 /* R/W */
+#define EXT_CSD_RST_N_FUNCTION    162 /* R/W */
+#define EXT_CSD_BKOPS_EN    163 /* R/W */
+#define EXT_CSD_BKOPS_START   164 /* W */
+#define EXT_CSD_SANITIZE_START    165     /* W */
+#define EXT_CSD_WR_REL_PARAM    166 /* RO */
+#define EXT_CSD_RPMB_MULT   168 /* RO */
+#define EXT_CSD_FW_CONFIG   169 /* R/W */
+#define EXT_CSD_BOOT_WP     173 /* R/W */
+#define EXT_CSD_ERASE_GROUP_DEF   175 /* R/W */
+#define EXT_CSD_PART_CONFIG   179 /* R/W */
+#define EXT_CSD_ERASED_MEM_CONT   181 /* RO */
+#define EXT_CSD_BUS_WIDTH   183 /* R/W */
+#define EXT_CSD_STROBE_SUPPORT    184 /* RO */
+#define EXT_CSD_HS_TIMING   185 /* R/W */
+#define EXT_CSD_POWER_CLASS   187 /* R/W */
+#define EXT_CSD_REV     192 /* RO */
+#define EXT_CSD_STRUCTURE   194 /* RO */
+#define EXT_CSD_CARD_TYPE   196 /* RO */
+#define EXT_CSD_DRIVER_STRENGTH   197 /* RO */
+#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
+#define EXT_CSD_PART_SWITCH_TIME        199     /* RO */
+#define EXT_CSD_PWR_CL_52_195   200 /* RO */
+#define EXT_CSD_PWR_CL_26_195   201 /* RO */
+#define EXT_CSD_PWR_CL_52_360   202 /* RO */
+#define EXT_CSD_PWR_CL_26_360   203 /* RO */
+#define EXT_CSD_SEC_CNT     212 /* RO, 4 bytes */
+#define EXT_CSD_S_A_TIMEOUT   217 /* RO */
+#define EXT_CSD_S_C_VCCQ          219     /* RO */
+#define EXT_CSD_S_C_VCC                 220     /* RO */
+#define EXT_CSD_REL_WR_SEC_C    222 /* RO */
+#define EXT_CSD_HC_WP_GRP_SIZE    221 /* RO */
+#define EXT_CSD_ERASE_TIMEOUT_MULT  223 /* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
+#define EXT_CSD_ACC_SIZE    225 /* RO */
+#define EXT_CSD_BOOT_MULT   226 /* RO */
+#define EXT_CSD_BOOT_INFO   228 /* RO */
+#define EXT_CSD_SEC_TRIM_MULT   229 /* RO */
+#define EXT_CSD_SEC_ERASE_MULT    230 /* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
+#define EXT_CSD_TRIM_MULT   232 /* RO */
+#define EXT_CSD_PWR_CL_200_195    236 /* RO */
+#define EXT_CSD_PWR_CL_200_360    237 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
+#define EXT_CSD_BKOPS_STATUS    246 /* RO */
+#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
+#define EXT_CSD_CACHE_SIZE    249 /* RO, 4 bytes */
+#define EXT_CSD_PWR_CL_DDR_200_360  253 /* RO */
+#define EXT_CSD_FIRMWARE_VERSION  254 /* RO, 8 bytes */
+#define EXT_CSD_PRE_EOL_INFO    267 /* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A  268 /* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B  269 /* RO */
+#define EXT_CSD_CMDQ_DEPTH    307 /* RO */
+#define EXT_CSD_CMDQ_SUPPORT    308 /* RO */
+#define EXT_CSD_SUPPORTED_MODE    493 /* RO */
+#define EXT_CSD_TAG_UNIT_SIZE   498 /* RO */
+#define EXT_CSD_DATA_TAG_SUPPORT  499 /* RO */
+#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
+#define EXT_CSD_MAX_PACKED_READS  501 /* RO */
+#define EXT_CSD_BKOPS_SUPPORT   502 /* RO */
+#define EXT_CSD_HPI_FEATURES    503 /* RO */
+#define EXT_CSD_S_CMD_SET   504 /* RO */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_WR_REL_PARAM_EN   (1 << 2)
+#define EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR (1 << 4)
+
+#define EXT_CSD_PART_CONFIG_ACC_MASK  (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
+
+#define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3)
+#define EXT_CSD_PART_CONFIG_EN_BOOT0  (0x1 << 3)
+#define EXT_CSD_PART_CONFIG_EN_USER (0x7 << 3)
+
 #endif
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bc9d913..a26695b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -135,6 +135,7 @@ struct SDState {
     uint64_t data_start;
     uint32_t data_offset;
     uint8_t data[512];
+    uint8_t ext_csd[512];
     qemu_irq readonly_cb;
     qemu_irq inserted_cb;
     QEMUTimer *ocr_power_timer;
@@ -393,6 +394,55 @@ static const uint8_t sd_csd_rw_mask[16] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
 };
 
+static void mmc_set_ext_csd(SDState *sd, uint64_t size)
+{
+    uint32_t sectcount = size >> HWBLOCK_SHIFT;
+
+    memset(sd->ext_csd, 0, sizeof(sd->ext_csd));
+    sd->ext_csd[EXT_CSD_S_CMD_SET] = 0x1; /* supported command sets */
+    sd->ext_csd[EXT_CSD_HPI_FEATURES] = 0x3; /* HPI features  */
+    sd->ext_csd[EXT_CSD_BKOPS_SUPPORT] = 0x1; /* Background operations
+                                                 support */
+    sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning */
+    sd->ext_csd[EXT_CSD_TRIM_MULT] = 0x1; /* Trim multiplier */
+    sd->ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] = 0x15; /* Secure feature
+                                                        support */
+    sd->ext_csd[EXT_CSD_SEC_ERASE_MULT] = 0x96; /* Secure erase support */
+    sd->ext_csd[EXT_CSD_SEC_TRIM_MULT] = 0x96; /* Secure TRIM multiplier */
+    sd->ext_csd[EXT_CSD_BOOT_INFO] = 0x7; /* Boot information */
+    sd->ext_csd[EXT_CSD_BOOT_MULT] = 0x8; /* Boot partition size. 128KB unit */
+    sd->ext_csd[EXT_CSD_ACC_SIZE] = 0x6; /* Access size */
+    sd->ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] = 0x4; /* HC Erase unit size */
+    sd->ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] = 0x1; /* HC erase timeout */
+    sd->ext_csd[EXT_CSD_REL_WR_SEC_C] = 0x1; /* Reliable write sector count */
+    sd->ext_csd[EXT_CSD_HC_WP_GRP_SIZE] = 0x4; /* HC write protect group size */
+    sd->ext_csd[EXT_CSD_S_C_VCC] = 0x8; /* Sleep current VCC  */
+    sd->ext_csd[EXT_CSD_S_C_VCCQ] = 0x7; /* Sleep current VCCQ */
+    sd->ext_csd[EXT_CSD_S_A_TIMEOUT] = 0x11; /* Sleep/Awake timeout */
+    sd->ext_csd[215] = (sectcount >> 24) & 0xff; /* Sector count */
+    sd->ext_csd[214] = (sectcount >> 16) & 0xff; /* ... */
+    sd->ext_csd[213] = (sectcount >> 8) & 0xff;  /* ... */
+    sd->ext_csd[EXT_CSD_SEC_CNT] = (sectcount & 0xff);       /* ... */
+    sd->ext_csd[210] = 0xa; /* Min write perf for 8bit@52Mhz */
+    sd->ext_csd[209] = 0xa; /* Min read perf for 8bit@52Mhz  */
+    sd->ext_csd[208] = 0xa; /* Min write perf for 4bit@52Mhz */
+    sd->ext_csd[207] = 0xa; /* Min read perf for 4bit@52Mhz */
+    sd->ext_csd[206] = 0xa; /* Min write perf for 4bit@26Mhz */
+    sd->ext_csd[205] = 0xa; /* Min read perf for 4bit@26Mhz */
+    sd->ext_csd[EXT_CSD_PART_SWITCH_TIME] = 0x1; /* Partition switching
+                                                    timing */
+    sd->ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] = 0x1; /* Out-of-interrupt busy
+                                                         timing */
+    sd->ext_csd[EXT_CSD_CARD_TYPE] = 0xFF; /* Card type */
+    sd->ext_csd[EXT_CSD_STRUCTURE] = 0x2; /* CSD Structure version */
+    sd->ext_csd[EXT_CSD_REV] = 0x5; /* Extended CSD revision */
+    sd->ext_csd[EXT_CSD_RPMB_MULT] = 0x1; /* RPMB size */
+    sd->ext_csd[EXT_CSD_PARTITION_SUPPORT] = 0x3; /* Partinioning support */
+    sd->ext_csd[159] = 0x00; /* Max enhanced area size */
+    sd->ext_csd[158] = 0x00; /* ... */
+    sd->ext_csd[157] = 0xEC; /* ... */
+}
+
 static void sd_set_csd(SDState *sd, uint64_t size)
 {
     int hwblock_shift = HWBLOCK_SHIFT;
@@ -406,8 +456,11 @@ static void sd_set_csd(SDState *sd, uint64_t size)
     }
     csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
-    if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
-        sd->csd[0] = 0x00;  /* CSD structure */
+    if (size <= SDSC_MAX_CAPACITY || sd->emmc) { /* Standard Capacity SD */
+        if (sd->emmc && size >= SDSC_MAX_CAPACITY) {
+            csize = 0xfff;
+        }
+        sd->csd[0] = sd->emmc ? 0xd0 : 0x00;  /* CSD structure */
         sd->csd[1] = 0x26;  /* Data read access-time-1 */
         sd->csd[2] = 0x00;  /* Data read access-time-2 */
         sd->csd[3] = 0x32;      /* Max. data transfer rate: 25 MHz */
@@ -451,6 +504,10 @@ static void sd_set_csd(SDState *sd, uint64_t size)
         sd->csd[14] = 0x00;
     }
     sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
+
+    if (sd->emmc) {
+        mmc_set_ext_csd(sd, size);
+    }
 }
 
 static void sd_set_rca(SDState *sd, uint16_t value)
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (4 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD " Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 12:02   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD Sai Pavan Boddu
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Vincent Palatin <vpalatin@chromium.org>

Sends the EXT_CSD register as response to CMD8.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sd.c | 52 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a26695b..181e7e2 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1141,24 +1141,37 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
-    case 8: /* CMD8:   SEND_IF_COND */
-        if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
-            break;
-        }
-        if (sd->state != sd_idle_state) {
-            break;
-        }
-        sd->vhs = 0;
-
-        /* No response if not exactly one VHS bit is set.  */
-        if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
-            return sd->spi ? sd_r7 : sd_r0;
-        }
+    case 8:    /* CMD8:   SEND_IF_COND / SEND_EXT_CSD */
+        if (sd->emmc) {
+            switch (sd->state) {
+            case sd_transfer_state:
+                /* MMC : Sends the EXT_CSD register as a Block of data */
+                sd->state = sd_sendingdata_state;
+                memcpy(sd->data, sd->ext_csd, sizeof(sd->ext_csd));
+                sd->data_start = addr;
+                sd->data_offset = 0;
+                return sd_r1;
+            default:
+                break;
+            }
+        } else {
+            if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
+                break;
+            }
+            if (sd->state != sd_idle_state) {
+                break;
+            }
+            sd->vhs = 0;
 
-        /* Accept.  */
-        sd->vhs = req.arg;
-        return sd_r7;
+            /* No response if not exactly one VHS bit is set.  */
+            if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
+                return sd->spi ? sd_r7 : sd_r0;
+            }
 
+            /* Accept.  */
+            sd->vhs = req.arg;
+            return sd_r7;
+        }
     case 9: /* CMD9:   SEND_CSD */
         switch (sd->state) {
         case sd_standby_state:
@@ -2081,6 +2094,13 @@ uint8_t sd_read_byte(SDState *sd)
             sd->state = sd_transfer_state;
         break;
 
+    case 8:     /* CMD8: SEND_EXT_CSD on MMC */
+        ret = sd->data[sd->data_offset++];
+        if (sd->data_offset >= sizeof(sd->ext_csd)) {
+            sd->state = sd_transfer_state;
+        }
+        break;
+
     case 9:     /* CMD9:   SEND_CSD */
     case 10:    /* CMD10:  SEND_CID */
         ret = sd->data[sd->data_offset ++];
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (5 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 12:03   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 08/21] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards Sai Pavan Boddu
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Cédric Le Goater <clg@kaod.org>

This adds extra info to trace log.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sdmmc-internal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
index 2053def..8648a78 100644
--- a/hw/sd/sdmmc-internal.c
+++ b/hw/sd/sdmmc-internal.c
@@ -14,7 +14,7 @@
 const char *sd_cmd_name(uint8_t cmd)
 {
     static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
-         [0]    = "GO_IDLE_STATE",
+         [0]    = "GO_IDLE_STATE",           [1]    = "SEND_OP_CMD",
          [2]    = "ALL_SEND_CID",            [3]    = "SEND_RELATIVE_ADDR",
          [4]    = "SET_DSR",                 [5]    = "IO_SEND_OP_COND",
          [6]    = "SWITCH_FUNC",             [7]    = "SELECT/DESELECT_CARD",
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 08/21] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (6 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 09/21] sd: emmc: Update CMD1 definition for eMMC Sai Pavan Boddu
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

OCR.CARD_CAPACITY field is only valid for sd cards, So skip it for eMMC.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/sd/sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 181e7e2..2612135 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -328,7 +328,8 @@ static void sd_ocr_powerup(void *opaque)
     /* card power-up OK */
     sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1);
 
-    if (sd->size > SDSC_MAX_CAPACITY) {
+    /* eMMC supports only Byte mode */
+    if (!sd->emmc && sd->size > SDSC_MAX_CAPACITY) {
         sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
     }
 }
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 09/21] sd: emmc: Update CMD1 definition for eMMC
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (7 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 08/21] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 10/21] sd: emmc: support idle state in CMD2 Sai Pavan Boddu
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Add support to Power up the card and send response r3 in case of eMMC.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/sd/sd.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2612135..054ad1e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1041,8 +1041,16 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     case 1: /* CMD1:   SEND_OP_CMD */
-        if (!sd->spi)
+        /* MMC: Powerup & send r3
+         * SD: send r1 in spi mode
+         */
+        if (sd->emmc) {
+            sd_ocr_powerup(sd);
+            return sd->state == sd_idle_state ?
+                   sd_r3 : sd_r0;
+        } else if (!sd->spi) {
             goto bad_cmd;
+        }
 
         sd->state = sd_transfer_state;
         return sd_r1;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 10/21] sd: emmc: support idle state in CMD2
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (8 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 09/21] sd: emmc: Update CMD1 definition for eMMC Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 11/21] sd: emmc: Add mmc switch function support Sai Pavan Boddu
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

eMMC is expected to be in idle-state post CMD1. Ready state is an
intermediate stage which we don't come across in Device identification
mode.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/sd/sd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 054ad1e..8a7d0de 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1059,6 +1059,10 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         if (sd->spi)
             goto bad_cmd;
         switch (sd->state) {
+        case sd_idle_state:
+            if (!sd->emmc) {
+                break;
+            }
         case sd_ready_state:
             sd->state = sd_identification_state;
             return sd_r2_i;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 11/21] sd: emmc: Add mmc switch function support
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (9 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 10/21] sd: emmc: support idle state in CMD2 Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence Sai Pavan Boddu
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

switch operation in eMMC card updates the ext_csd register to
request changes in card operations. Here we implement similar
sequence but requests are mostly dummy and make no change.

Implement SWITCH_ERROR if the write operation extends goes beyond length
of ext_csd.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/sd/sd.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8a7d0de..bf963ec 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -523,6 +523,7 @@ static void sd_set_rca(SDState *sd, uint16_t value)
 FIELD(CSR, AKE_SEQ_ERROR,               3,  1)
 FIELD(CSR, APP_CMD,                     5,  1)
 FIELD(CSR, FX_EVENT,                    6,  1)
+FIELD(CSR, SWITCH_ERROR,                7,  1)
 FIELD(CSR, READY_FOR_DATA,              8,  1)
 FIELD(CSR, CURRENT_STATE,               9,  4)
 FIELD(CSR, ERASE_RESET,                13,  1)
@@ -886,6 +887,43 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
     return ret;
 }
 
+enum {
+    MMC_CMD6_ACCESS_COMMAND_SET = 0,
+    MMC_CMD6_ACCESS_SET_BITS,
+    MMC_CMD6_ACCESS_CLEAR_BITS,
+    MMC_CMD6_ACCESS_WRITE_BYTE,
+};
+
+static void mmc_function_switch(SDState *sd, uint32_t arg)
+{
+    uint32_t access = extract32(arg, 24, 2);
+    uint32_t index = extract32(arg, 16, 8);
+    uint32_t value = extract32(arg, 8, 8);
+    uint8_t b = sd->ext_csd[index];
+
+    switch (access) {
+    case MMC_CMD6_ACCESS_COMMAND_SET:
+        qemu_log_mask(LOG_UNIMP, "MMC Command set switching not supported\n");
+        return;
+    case MMC_CMD6_ACCESS_SET_BITS:
+        b |= value;
+        break;
+    case MMC_CMD6_ACCESS_CLEAR_BITS:
+        b &= ~value;
+        break;
+    case MMC_CMD6_ACCESS_WRITE_BYTE:
+        b = value;
+        break;
+    }
+
+    if (index >= 192) {
+        sd->card_status |= R_CSR_SWITCH_ERROR_MASK;
+        return;
+    }
+
+    sd->ext_csd[index] = b;
+}
+
 static void sd_function_switch(SDState *sd, uint32_t arg)
 {
     int i, mode, new_func;
@@ -1105,12 +1143,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
     case 6: /* CMD6:   SWITCH_FUNCTION */
         switch (sd->mode) {
         case sd_data_transfer_mode:
-            sd_function_switch(sd, req.arg);
-            sd->state = sd_sendingdata_state;
-            sd->data_start = 0;
-            sd->data_offset = 0;
-            return sd_r1;
-
+            if (sd->emmc) {
+                sd->state = sd_programming_state;
+                mmc_function_switch(sd, req.arg);
+                sd->state = sd_transfer_state;
+                return sd_r1b;
+            } else {
+                sd_function_switch(sd, req.arg);
+                sd->state = sd_sendingdata_state;
+                sd->data_start = 0;
+                sd->data_offset = 0;
+                return sd_r1;
+            }
         default:
             break;
         }
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (10 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 11/21] sd: emmc: Add mmc switch function support Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 10:42   ` Dr. David Alan Gilbert
  2021-02-28 19:33 ` [PATCH v3 13/21] sd: emmc: Make ACMD41 illegal for mmc Sai Pavan Boddu
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

eMMC cards support tuning sequence for entering HS200 mode.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/sd/sd.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bf963ec..174c28e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1386,6 +1386,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         }
         break;
 
+    case 21:    /* CMD21: mmc SEND TUNING_BLOCK */
+        if (sd->emmc && (sd->state == sd_transfer_state)) {
+            sd->state = sd_sendingdata_state;
+            sd->data_offset = 0;
+            return sd_r1;
+        }
+        break;
+
     case 23:    /* CMD23: SET_BLOCK_COUNT */
         if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
             break;
@@ -2120,6 +2128,30 @@ static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
     0xbb, 0xff, 0xf7, 0xff,         0xf7, 0x7f, 0x7b, 0xde,
 };
 
+#define EXCSD_BUS_WIDTH_OFFSET 183
+#define BUS_WIDTH_8_MASK    0x4
+#define BUS_WIDTH_4_MASK    0x2
+#define MMC_TUNING_BLOCK_SIZE   128
+
+static const uint8_t mmc_tunning_block_pattern[128] = {
+       0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+       0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+       0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+       0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+       0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+       0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+       0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+       0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+       0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+       0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+       0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+       0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+       0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+       0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+       0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+       0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
 uint8_t sd_read_byte(SDState *sd)
 {
     /* TODO: Append CRCs */
@@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
         ret = sd_tuning_block_pattern[sd->data_offset++];
         break;
 
+    case 21:    /* CMD21: SEND_TUNNING_BLOCK (MMC) */
+        if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
+            sd->state = sd_transfer_state;
+        }
+        if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
+            ret = mmc_tunning_block_pattern[sd->data_offset++];
+        } else {
+            /* Return LSB Nibbles of two byte from the 8bit tuning block
+             * for 4bit mode
+             */
+            ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
+            ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
+        }
+        break;
+
     case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
         ret = sd->data[sd->data_offset ++];
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 13/21] sd: emmc: Make ACMD41 illegal for mmc
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (11 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 14/21] sd: emmc: Add support for emmc erase Sai Pavan Boddu
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

ACMD41 is not applicable for eMMC.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/sd/sd.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 174c28e..09c1222 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1737,6 +1737,9 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
         break;
 
     case 41:    /* ACMD41: SD_APP_OP_COND */
+        if (sd->emmc) {
+            break;
+        }
         if (sd->spi) {
             /* SEND_OP_CMD */
             sd->state = sd_transfer_state;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 14/21] sd: emmc: Add support for emmc erase
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (12 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 13/21] sd: emmc: Make ACMD41 illegal for mmc Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 15/21] sd: emmc: Update CID structure for eMMC Sai Pavan Boddu
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Add CMD35 and CMD36 which sets the erase start and end.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/sd/sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 09c1222..bba0446 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1552,6 +1552,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 
     /* Erase commands (Class 5) */
     case 32:    /* CMD32:  ERASE_WR_BLK_START */
+    case 35:    /* CMD35:  ERASE_GROUP_START */
         switch (sd->state) {
         case sd_transfer_state:
             sd->erase_start = req.arg;
@@ -1563,6 +1564,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
         break;
 
     case 33:    /* CMD33:  ERASE_WR_BLK_END */
+    case 36:    /* CMD36:  ERASE_GROUP_END */
         switch (sd->state) {
         case sd_transfer_state:
             sd->erase_end = req.arg;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 15/21] sd: emmc: Update CID structure for eMMC
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (13 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 14/21] sd: emmc: Add support for emmc erase Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 12:09   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 16/21] sd: emmc: Support boot area in emmc image Sai Pavan Boddu
                   ` (6 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

CID structure is little different for eMMC, w.r.t to product name and
manufacturing date.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/sd/sd.c | 47 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bba0446..08b77ad 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -365,23 +365,36 @@ static void sd_set_scr(SDState *sd)
 
 static void sd_set_cid(SDState *sd)
 {
-    sd->cid[0] = MID;       /* Fake card manufacturer ID (MID) */
-    sd->cid[1] = OID[0];    /* OEM/Application ID (OID) */
-    sd->cid[2] = OID[1];
-    sd->cid[3] = PNM[0];    /* Fake product name (PNM) */
-    sd->cid[4] = PNM[1];
-    sd->cid[5] = PNM[2];
-    sd->cid[6] = PNM[3];
-    sd->cid[7] = PNM[4];
-    sd->cid[8] = PRV;       /* Fake product revision (PRV) */
-    sd->cid[9] = 0xde;      /* Fake serial number (PSN) */
-    sd->cid[10] = 0xad;
-    sd->cid[11] = 0xbe;
-    sd->cid[12] = 0xef;
-    sd->cid[13] = 0x00 |    /* Manufacture date (MDT) */
-        ((MDT_YR - 2000) / 10);
-    sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
-    sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
+    if (sd->emmc) {
+        sd->cid[0] = MID;
+        sd->cid[1] = 0x1;       /* CBX */
+        sd->cid[2] = OID[0];    /* OEM/Application ID (OID) */
+        sd->cid[8] = 0x0;
+        sd->cid[9] = PRV;        /* Fake product revision (PRV) */
+        sd->cid[10] = 0xde;      /* Fake serial number (PSN) */
+        sd->cid[11] = 0xad;
+        sd->cid[12] = 0xbe;
+        sd->cid[13] = 0xef;
+        sd->cid[14] = ((MDT_YR - 1997) % 0x10); /* MDT */
+    } else {
+        sd->cid[0] = MID;       /* Fake card manufacturer ID (MID) */
+        sd->cid[1] = OID[0];    /* OEM/Application ID (OID) */
+        sd->cid[2] = OID[1];
+        sd->cid[8] = PRV;       /* Fake product revision (PRV) */
+        sd->cid[9] = 0xde;      /* Fake serial number (PSN) */
+        sd->cid[10] = 0xad;
+        sd->cid[11] = 0xbe;
+        sd->cid[12] = 0xef;
+        sd->cid[13] = 0x00 |    /* Manufacture date (MDT) */
+            ((MDT_YR - 2000) / 10);
+        sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
+   }
+   sd->cid[3] = PNM[0];    /* Fake product name (PNM) 48bit */
+   sd->cid[4] = PNM[1];
+   sd->cid[5] = PNM[2];
+   sd->cid[6] = PNM[3];
+   sd->cid[7] = PNM[4];
+   sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
 #define HWBLOCK_SHIFT   9           /* 512 bytes */
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 16/21] sd: emmc: Support boot area in emmc image
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (14 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 15/21] sd: emmc: Update CID structure for eMMC Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-01 12:07   ` Cédric Le Goater
  2021-02-28 19:33 ` [PATCH v3 17/21] sd: emmc: Subtract bootarea size from blk Sai Pavan Boddu
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Joel Stanley <joel@jms.id.au>

This assumes a specially constructued image:

  dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M
  dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc
  dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc count=64 bs=1K
  cat mmc-bootarea.img obmc-phosphor-image.wic > mmc.img
  truncate --size 16GB mmc.img
  truncate --size 128MB mmc-bootarea.img

Signed-off-by: Joel Stanley <joel@jms.id.au>
[clg: - changes on the definition names ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
[spb: use data_start property to access right emmc partition,
      Clean up PARTITION_ENABLE support as incomplete,
      Fix commit message to be generic.]
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sd.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 08b77ad..d311477 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1044,6 +1044,34 @@ static void sd_lock_command(SDState *sd)
         sd->card_status &= ~CARD_IS_LOCKED;
 }
 
+/*
+ * This requires a disk image that has two boot partitions inserted at the
+ * beginning of it. The size of the boot partitions are configured in the
+ * ext_csd structure, which is hardcoded in qemu. They are currently set to
+ * 1MB each.
+ */
+static uint32_t sd_bootpart_offset(SDState *sd)
+{
+    unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
+        EXT_CSD_PART_CONFIG_ACC_MASK;
+    unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+    if (!sd->emmc) {
+        return 0;
+    }
+
+    switch (access) {
+    case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
+        return boot_capacity * 2;
+    case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+        return 0;
+    case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
+        return boot_capacity * 1;
+    default:
+         g_assert_not_reached();
+    }
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
     uint32_t rca = 0x0000;
@@ -1359,6 +1387,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
                 return sd_r1;
             }
 
+            if (sd->emmc) {
+                addr += sd_bootpart_offset(sd);
+            }
             sd->state = sd_sendingdata_state;
             sd->data_start = addr;
             sd->data_offset = 0;
@@ -1378,6 +1409,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
                 return sd_r1;
             }
 
+            if (sd->emmc) {
+                addr += sd_bootpart_offset(sd);
+            }
             sd->state = sd_sendingdata_state;
             sd->data_start = addr;
             sd->data_offset = 0;
@@ -1434,6 +1468,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
                 return sd_r1;
             }
 
+            if (sd->emmc) {
+                addr += sd_bootpart_offset(sd);
+            }
             sd->state = sd_receivingdata_state;
             sd->data_start = addr;
             sd->data_offset = 0;
@@ -1464,6 +1501,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
                 return sd_r1;
             }
 
+            if (sd->emmc) {
+                addr += sd_bootpart_offset(sd);
+            }
             sd->state = sd_receivingdata_state;
             sd->data_start = addr;
             sd->data_offset = 0;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 17/21] sd: emmc: Subtract bootarea size from blk
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (15 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 16/21] sd: emmc: Support boot area in emmc image Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 18/21] sd: sdhci: Support eMMC devices Sai Pavan Boddu
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

From: Joel Stanley <joel@jms.id.au>

The userdata size is derived from the file the user passes on the
command line, but we must take into account the boot areas.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/sd/sd.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index d311477..5135a64 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -657,6 +657,11 @@ static void sd_reset(DeviceState *dev)
     }
     size = sect << 9;
 
+    if (sd->emmc) {
+        unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+        size -= boot_capacity * 2;
+    }
+
     sect = sd_addr_to_wpnum(size) + 1;
 
     sd->state = sd_idle_state;
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 18/21] sd: sdhci: Support eMMC devices
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (16 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 17/21] sd: emmc: Subtract bootarea size from blk Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 19/21] arm: xlnx-versal: Add emmc to versal Sai Pavan Boddu
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Embedded device slots should be allowed as support of eMMC is available.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 hw/sd/sdhci.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 8ffa539..771212a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -99,10 +99,6 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
         msk = FIELD_DP64(msk, SDHC_CAPAB, ASYNC_INT, 0);
 
         val = FIELD_EX64(s->capareg, SDHC_CAPAB, SLOT_TYPE);
-        if (val) {
-            error_setg(errp, "slot-type not supported");
-            return;
-        }
         trace_sdhci_capareg("slot type", val);
         msk = FIELD_DP64(msk, SDHC_CAPAB, SLOT_TYPE, 0);
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 19/21] arm: xlnx-versal: Add emmc to versal
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (17 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 18/21] sd: sdhci: Support eMMC devices Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 20/21] docs: devel: emmc: Add a doc for emmc card emulation Sai Pavan Boddu
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Configuring SDHCI-0 to act as eMMC controller.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 include/hw/arm/xlnx-versal.h |  1 +
 hw/arm/xlnx-versal-virt.c    | 29 +++++++++++++++++++++++++----
 hw/arm/xlnx-versal.c         | 14 ++++++++++++--
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 2b76885..440f3b4 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -76,6 +76,7 @@ struct Versal {
     struct {
         MemoryRegion *mr_ddr;
         uint32_t psci_conduit;
+        bool has_emmc;
     } cfg;
 };
 
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 8482cd6..053a322 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -46,6 +46,7 @@ struct VersalVirt {
 
     struct {
         bool secure;
+        bool has_emmc;
     } cfg;
 };
 
@@ -333,6 +334,13 @@ static void fdt_add_sd_nodes(VersalVirt *s)
         qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
                                      2, addr, 2, MM_PMC_SD0_SIZE);
         qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
+        /*
+         * eMMC specific properties
+         */
+        if (s->cfg.has_emmc && i == 0) {
+            qemu_fdt_setprop(s->fdt, name, "non-removable", NULL, 0);
+            qemu_fdt_setprop_sized_cells(s->fdt, name, "bus-width", 1, 8);
+        }
         g_free(name);
     }
 }
@@ -524,11 +532,17 @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
                            &error_fatal);
 }
 
+static void versal_virt_set_emmc(Object *obj, bool value, Error **errp)
+{
+    VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+    s->cfg.has_emmc = value;
+}
+
 static void versal_virt_init(MachineState *machine)
 {
     VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
     int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
-    int i;
 
     /*
      * If the user provides an Operating System to be loaded, we expect them
@@ -560,6 +574,8 @@ static void versal_virt_init(MachineState *machine)
                              &error_abort);
     object_property_set_int(OBJECT(&s->soc), "psci-conduit", psci_conduit,
                             &error_abort);
+    object_property_set_bool(OBJECT(&s->soc), "has-emmc", s->cfg.has_emmc,
+                             &error_abort);
     sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
 
     fdt_create(s);
@@ -581,10 +597,12 @@ static void versal_virt_init(MachineState *machine)
     memory_region_add_subregion_overlap(get_system_memory(),
                                         0, &s->soc.fpd.apu.mr, 0);
 
-    /* Plugin SD cards.  */
-    for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
-        sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
+    if (!s->cfg.has_emmc) {
+        sd_plugin_card(&s->soc.pmc.iou.sd[0],
+            drive_get_next(IF_SD));
     }
+    /* Plugin SD cards.  */
+    sd_plugin_card(&s->soc.pmc.iou.sd[1], drive_get_next(IF_SD));
 
     s->binfo.ram_size = machine->ram_size;
     s->binfo.loader_start = 0x0;
@@ -621,6 +639,9 @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
     mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
     mc->no_cdrom = true;
     mc->default_ram_id = "ddr";
+    object_class_property_add_bool(oc, "emmc",
+        NULL, versal_virt_set_emmc);
+
 }
 
 static const TypeInfo versal_virt_machine_init_typeinfo = {
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 628e77e..6ca2c8f 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -230,6 +230,9 @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
 }
 
 #define SDHCI_CAPABILITIES  0x280737ec6481 /* Same as on ZynqMP.  */
+#define SDHCI_EMMC_CAPS ((SDHCI_CAPABILITIES & ~(3 << 30)) | \
+                     (1 << 30))
+
 static void versal_create_sds(Versal *s, qemu_irq *pic)
 {
     int i;
@@ -242,11 +245,17 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
                                 TYPE_SYSBUS_SDHCI);
         dev = DEVICE(&s->pmc.iou.sd[i]);
 
+        dev->id = g_strdup_printf("sdhci%d", i);
         object_property_set_uint(OBJECT(dev), "sd-spec-version", 3,
                                  &error_fatal);
-        object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES,
+        object_property_set_uint(OBJECT(dev), "capareg", SDHCI_EMMC_CAPS,
                                  &error_fatal);
-        object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal);
+        /*
+         * UHS is not applicable for eMMC
+         */
+        if (!s->cfg.has_emmc || i == 1) {
+            object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal);
+        }
         sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
 
         mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
@@ -386,6 +395,7 @@ static Property versal_properties[] = {
     DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
                      MemoryRegion *),
     DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0),
+    DEFINE_PROP_BOOL("has-emmc", Versal, cfg.has_emmc, false),
     DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 20/21] docs: devel: emmc: Add a doc for emmc card emulation
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (18 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 19/21] arm: xlnx-versal: Add emmc to versal Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-02-28 19:33 ` [PATCH v3 21/21] docs: arm: xlnx-versal-virt: Add eMMC support documentation Sai Pavan Boddu
  2021-03-02  9:52 ` [PATCH v3 00/21] eMMC support Cédric Le Goater
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Add few simple steps to create emmc card with boot and user data
partitions.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 docs/devel/emmc.txt | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 docs/devel/emmc.txt

diff --git a/docs/devel/emmc.txt b/docs/devel/emmc.txt
new file mode 100644
index 0000000..2d098fe
--- /dev/null
+++ b/docs/devel/emmc.txt
@@ -0,0 +1,16 @@
+====================
+eMMC block emulation
+====================
+
+Any eMMC devices has 3 kinds of partitions Boot, RPMB and User data. We
+are supporting Boot and User data partitions. Boot area partitions are
+expected to be 1MB size as hard coded in EXT_CSD register.
+
+Below is the example of combining two 1MB bootarea partition and
+user data partitions.
+
+      cat mmc-bootarea0.bin mmc-bootarea1.bin  image.wic > mmc.img
+      qemu-img resize mmc.img 4G
+
+Note: mmc-bootarea0/1 are just raw paritions. User data can have
+partition tables.
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v3 21/21] docs: arm: xlnx-versal-virt: Add eMMC support documentation
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (19 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 20/21] docs: devel: emmc: Add a doc for emmc card emulation Sai Pavan Boddu
@ 2021-02-28 19:33 ` Sai Pavan Boddu
  2021-03-02  9:52 ` [PATCH v3 00/21] eMMC support Cédric Le Goater
  21 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-02-28 19:33 UTC (permalink / raw)
  To: Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Cédric Le Goater, Vincent Palatin, Dr. David Alan Gilbert,
	Thomas Huth, Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

Add details of eMMC specific machine property and example for passing
eMMC device.

Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
---
 docs/system/arm/xlnx-versal-virt.rst | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
index 2602d0f..d1099fa 100644
--- a/docs/system/arm/xlnx-versal-virt.rst
+++ b/docs/system/arm/xlnx-versal-virt.rst
@@ -29,6 +29,7 @@ Implemented devices:
 - 2 GEMs (Cadence MACB Ethernet MACs)
 - 8 ADMA (Xilinx zDMA) channels
 - 2 SD Controllers
+    * SDHCI0 can be configured as eMMC
 - OCM (256KB of On Chip Memory)
 - DDR memory
 
@@ -43,6 +44,19 @@ Other differences between the hardware and the QEMU model:
 - QEMU provides 8 virtio-mmio virtio transports; these start at
   address ``0xa0000000`` and have IRQs from 111 and upwards.
 
+Enabling eMMC
+"""""""""""""
+In order to enable eMMC pass the following machine property "emmc=on".
+ex:
+    "-M xlnx-versal-virt,emmc=on"
+
+Above switch would configure SDHCI0 to accept eMMC. More details on eMMC
+emulation can be found in docs/devel/emmc.txt.
+
+Below is the command to pass eMMC device.
+    "-drive file=emmc.img,if=none,id=emmc,format=raw
+     -device emmc,drive=emmc,id=emmc0,bus=/sdhci0/sd-bus"
+
 Running
 """""""
 If the user provides an Operating System to be loaded, we expect users
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
  2021-02-28 19:33 ` [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence Sai Pavan Boddu
@ 2021-03-01 10:42   ` Dr. David Alan Gilbert
  2021-03-03  3:53     ` Sai Pavan Boddu
  0 siblings, 1 reply; 34+ messages in thread
From: Dr. David Alan Gilbert @ 2021-03-01 10:42 UTC (permalink / raw)
  To: Sai Pavan Boddu
  Cc: Kevin Wolf, Peter Maydell, Thomas Huth,
	Vladimir Sementsov-Ogievskiy, Vincent Palatin, Edgar E. Iglesias,
	qemu-block, qemu-devel, Markus Armbruster, Max Reitz, saipava,
	Alistair Francis, Joel Stanley, Stefan Hajnoczi, Paolo Bonzini,
	Luc Michel, Cédric Le Goater

* Sai Pavan Boddu (sai.pavan.boddu@xilinx.com) wrote:
> eMMC cards support tuning sequence for entering HS200 mode.
> 
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> ---
>  hw/sd/sd.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index bf963ec..174c28e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1386,6 +1386,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>          }
>          break;
>  
> +    case 21:    /* CMD21: mmc SEND TUNING_BLOCK */
> +        if (sd->emmc && (sd->state == sd_transfer_state)) {
> +            sd->state = sd_sendingdata_state;
> +            sd->data_offset = 0;
> +            return sd_r1;
> +        }
> +        break;
> +
>      case 23:    /* CMD23: SET_BLOCK_COUNT */
>          if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
>              break;
> @@ -2120,6 +2128,30 @@ static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
>      0xbb, 0xff, 0xf7, 0xff,         0xf7, 0x7f, 0x7b, 0xde,
>  };
>  
> +#define EXCSD_BUS_WIDTH_OFFSET 183
> +#define BUS_WIDTH_8_MASK    0x4
> +#define BUS_WIDTH_4_MASK    0x2
> +#define MMC_TUNING_BLOCK_SIZE   128
> +
> +static const uint8_t mmc_tunning_block_pattern[128] = {
> +       0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
> +       0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
> +       0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
> +       0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
> +       0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
> +       0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
> +       0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
> +       0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
> +       0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
> +       0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
> +       0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
> +       0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
> +       0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
> +       0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
> +       0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
> +       0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,

Where does this magic pattern come from?  Is it part of some spec?

Dave

> +};
> +
>  uint8_t sd_read_byte(SDState *sd)
>  {
>      /* TODO: Append CRCs */
> @@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
>          ret = sd_tuning_block_pattern[sd->data_offset++];
>          break;
>  
> +    case 21:    /* CMD21: SEND_TUNNING_BLOCK (MMC) */
> +        if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
> +            sd->state = sd_transfer_state;
> +        }
> +        if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
> +            ret = mmc_tunning_block_pattern[sd->data_offset++];
> +        } else {
> +            /* Return LSB Nibbles of two byte from the 8bit tuning block
> +             * for 4bit mode
> +             */
> +            ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
> +            ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
> +        }
> +        break;
> +
>      case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
>          ret = sd->data[sd->data_offset ++];
>  
> -- 
> 2.7.4
> 
-- 
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards
  2021-02-28 19:33 ` [PATCH v3 02/21] sd: emmc: Add support for eMMC cards Sai Pavan Boddu
@ 2021-03-01 11:02   ` Cédric Le Goater
  2021-03-03  3:57     ` Sai Pavan Boddu
  0 siblings, 1 reply; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 11:02 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> Add eMMC device built on top of SD card.
> 
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> ---
>  include/hw/sd/sd.h |  2 ++
>  hw/sd/sd.c         | 20 ++++++++++++++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
> index 05ef9b7..b402dad 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -90,6 +90,8 @@ typedef struct {
>  } SDRequest;
>  
>  
> +#define TYPE_EMMC "emmc"
> +OBJECT_DECLARE_SIMPLE_TYPE(EMMCState, EMMC)
>  #define TYPE_SD_CARD "sd-card"
>  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
>  
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 74b9162..a23af6d 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -108,6 +108,7 @@ struct SDState {
>      uint8_t spec_version;
>      BlockBackend *blk;
>      bool spi;
> +    bool emmc;
>  
>      /* Runtime changeables */
>  
> @@ -143,6 +144,10 @@ struct SDState {
>      bool cmd_line;
>  };
>  
> +struct EMMCState {
> +    SDState parent;
> +};
> +
>  static void sd_realize(DeviceState *dev, Error **errp);
>  
>  static const char *sd_state_name(enum SDCardStates state)
> @@ -2105,6 +2110,13 @@ static void sd_instance_init(Object *obj)
>      sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sd_ocr_powerup, sd);
>  }
>  
> +static void emmc_instance_init(Object *obj)
> +{
> +    SDState *sd = SD_CARD(obj);
> +
> +    sd->emmc = true;
> +}
I think field 'emmc' would fit better in SDCardClass since it is a device 
constant. You should not need 'struct EMMCState'. So something like below.
Then you can add handlers for specific emmc commands.

Thanks,

C.


diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 47360ba4ee98..80e7cd526a57 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -93,6 +93,8 @@ typedef struct {
 #define TYPE_SD_CARD "sd-card"
 OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
 
+#define TYPE_EMMC "emmc"
+
 struct SDCardClass {
     /*< private >*/
     DeviceClass parent_class;
@@ -124,6 +126,8 @@ struct SDCardClass {
     void (*enable)(SDState *sd, bool enable);
     bool (*get_inserted)(SDState *sd);
     bool (*get_readonly)(SDState *sd);
+
+    bool emmc;
 };
 
 #define TYPE_SD_BUS "sd-bus"
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 660026f2a667..95608f11b36e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2447,9 +2447,24 @@ static const TypeInfo sd_info = {
     .instance_finalize = sd_instance_finalize,
 };
 
+static void emmc_class_init(ObjectClass *klass, void *data)
+{
+    SDCardClass *sc = SD_CARD_CLASS(klass);
+
+    sc->emmc = true;
+}
+
+static const TypeInfo emmc_info = {
+    .name = TYPE_EMMC,
+    .parent = TYPE_SD_CARD,
+    .instance_size = sizeof(SDState),
+    .class_init = emmc_class_init,
+};
+
 static void sd_register_types(void)
 {
     type_register_static(&sd_info);
+    type_register_static(&emmc_info);
 }
 
 type_init(sd_register_types)



^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 04/21] sd: emmc: update OCR fields for eMMC
  2021-02-28 19:33 ` [PATCH v3 04/21] sd: emmc: update OCR fields for eMMC Sai Pavan Boddu
@ 2021-03-01 11:04   ` Cédric Le Goater
  0 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 11:04 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> From: Vincent Palatin <vpalatin@chromium.org>
> 
> eMMC OCR register doesn't has UHS-II field and voltage fields are
> different.
> 
> Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> ---
>  hw/sd/sd.c | 27 ++++++++++++++++++++++++---
>  1 file changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 6de414b..bc9d913 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -287,6 +287,15 @@ FIELD(OCR, UHS_II_CARD,                29,  1) /* Only UHS-II */
>  FIELD(OCR, CARD_CAPACITY,              30,  1) /* 0:SDSC, 1:SDHC/SDXC */
>  FIELD(OCR, CARD_POWER_UP,              31,  1)
>  
> +/*
> + * eMMC OCR register
> + */
> +FIELD(EMMC_OCR, VDD_WINDOW_0,  7, 1)
> +FIELD(EMMC_OCR, VDD_WINDOW_1,  8, 7)
> +FIELD(EMMC_OCR, VDD_WINDOW_2, 15, 9)
> +FIELD(EMMC_OCR, ACCESS_MODE,  29, 2)
> +FIELD(EMMC_OCR, POWER_UP,     31, 1)
> +
>  #define ACMD41_ENQUIRY_MASK     0x00ffffff
>  #define ACMD41_R3_MASK          (R_OCR_VDD_VOLTAGE_WIN_HI_MASK \
>                                 | R_OCR_ACCEPT_SWITCH_1V8_MASK \
> @@ -296,8 +305,16 @@ FIELD(OCR, CARD_POWER_UP,              31,  1)
>  
>  static void sd_set_ocr(SDState *sd)
>  {
> -    /* All voltages OK */
> -    sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
> +    if (sd->emmc) {
> +        /*
> +         * Dual Voltage eMMC card
> +         */
> +        sd->ocr = R_EMMC_OCR_VDD_WINDOW_0_MASK |
> +                  R_EMMC_OCR_VDD_WINDOW_2_MASK;
> +    } else {
> +        /* All voltages OK */
> +        sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;

'ocr' is a constant that could be in SDCardClass 

> +    }
>  }
>  
>  static void sd_ocr_powerup(void *opaque)
> @@ -525,7 +542,11 @@ static void sd_response_r1_make(SDState *sd, uint8_t *response)
>  
>  static void sd_response_r3_make(SDState *sd, uint8_t *response)
>  {
> -    stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
> +    if (sd->emmc) {
> +        stl_be_p(response, sd->ocr);
> +    } else {
> +        stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
> +    }
>  }
>  
>  static void sd_response_r6_make(SDState *sd, uint8_t *response)
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD for eMMC
  2021-02-28 19:33 ` [PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD " Sai Pavan Boddu
@ 2021-03-01 11:08   ` Cédric Le Goater
  0 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 11:08 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> From: Vincent Palatin <vpalatin@chromium.org>
> 
> eMMC CSD is similar to SD with an option to refer EXT_CSD for larger
> devices.
> 
> Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
> [clg: Add user friendly macros for EXT_CSD register]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> [spb: updated commit message]
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> ---
>  hw/sd/sdmmc-internal.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/sd/sd.c             | 61 +++++++++++++++++++++++++++++--
>  2 files changed, 156 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
> index d8bf17d..7ab7b4d 100644
> --- a/hw/sd/sdmmc-internal.h
> +++ b/hw/sd/sdmmc-internal.h
> @@ -37,4 +37,101 @@ const char *sd_cmd_name(uint8_t cmd);
>   */
>  const char *sd_acmd_name(uint8_t cmd);
>  
> +/*
> + * EXT_CSD fields
> + */
> +
> +#define EXT_CSD_CMDQ_MODE_EN    15  /* R/W */
> +#define EXT_CSD_FLUSH_CACHE   32      /* W */
> +#define EXT_CSD_CACHE_CTRL    33      /* R/W */
> +#define EXT_CSD_POWER_OFF_NOTIFICATION  34  /* R/W */
> +#define EXT_CSD_PACKED_FAILURE_INDEX  35  /* RO */
> +#define EXT_CSD_PACKED_CMD_STATUS 36  /* RO */
> +#define EXT_CSD_EXP_EVENTS_STATUS 54  /* RO, 2 bytes */
> +#define EXT_CSD_EXP_EVENTS_CTRL   56  /* R/W, 2 bytes */
> +#define EXT_CSD_DATA_SECTOR_SIZE  61  /* R */
> +#define EXT_CSD_GP_SIZE_MULT    143 /* R/W */
> +#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
> +#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
> +#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
> +#define EXT_CSD_HPI_MGMT    161 /* R/W */
> +#define EXT_CSD_RST_N_FUNCTION    162 /* R/W */
> +#define EXT_CSD_BKOPS_EN    163 /* R/W */
> +#define EXT_CSD_BKOPS_START   164 /* W */
> +#define EXT_CSD_SANITIZE_START    165     /* W */
> +#define EXT_CSD_WR_REL_PARAM    166 /* RO */
> +#define EXT_CSD_RPMB_MULT   168 /* RO */
> +#define EXT_CSD_FW_CONFIG   169 /* R/W */
> +#define EXT_CSD_BOOT_WP     173 /* R/W */
> +#define EXT_CSD_ERASE_GROUP_DEF   175 /* R/W */
> +#define EXT_CSD_PART_CONFIG   179 /* R/W */
> +#define EXT_CSD_ERASED_MEM_CONT   181 /* RO */
> +#define EXT_CSD_BUS_WIDTH   183 /* R/W */
> +#define EXT_CSD_STROBE_SUPPORT    184 /* RO */
> +#define EXT_CSD_HS_TIMING   185 /* R/W */
> +#define EXT_CSD_POWER_CLASS   187 /* R/W */
> +#define EXT_CSD_REV     192 /* RO */
> +#define EXT_CSD_STRUCTURE   194 /* RO */
> +#define EXT_CSD_CARD_TYPE   196 /* RO */
> +#define EXT_CSD_DRIVER_STRENGTH   197 /* RO */
> +#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
> +#define EXT_CSD_PART_SWITCH_TIME        199     /* RO */
> +#define EXT_CSD_PWR_CL_52_195   200 /* RO */
> +#define EXT_CSD_PWR_CL_26_195   201 /* RO */
> +#define EXT_CSD_PWR_CL_52_360   202 /* RO */
> +#define EXT_CSD_PWR_CL_26_360   203 /* RO */
> +#define EXT_CSD_SEC_CNT     212 /* RO, 4 bytes */
> +#define EXT_CSD_S_A_TIMEOUT   217 /* RO */
> +#define EXT_CSD_S_C_VCCQ          219     /* RO */
> +#define EXT_CSD_S_C_VCC                 220     /* RO */
> +#define EXT_CSD_REL_WR_SEC_C    222 /* RO */
> +#define EXT_CSD_HC_WP_GRP_SIZE    221 /* RO */
> +#define EXT_CSD_ERASE_TIMEOUT_MULT  223 /* RO */
> +#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
> +#define EXT_CSD_ACC_SIZE    225 /* RO */
> +#define EXT_CSD_BOOT_MULT   226 /* RO */
> +#define EXT_CSD_BOOT_INFO   228 /* RO */
> +#define EXT_CSD_SEC_TRIM_MULT   229 /* RO */
> +#define EXT_CSD_SEC_ERASE_MULT    230 /* RO */
> +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
> +#define EXT_CSD_TRIM_MULT   232 /* RO */
> +#define EXT_CSD_PWR_CL_200_195    236 /* RO */
> +#define EXT_CSD_PWR_CL_200_360    237 /* RO */
> +#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
> +#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
> +#define EXT_CSD_BKOPS_STATUS    246 /* RO */
> +#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
> +#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
> +#define EXT_CSD_CACHE_SIZE    249 /* RO, 4 bytes */
> +#define EXT_CSD_PWR_CL_DDR_200_360  253 /* RO */
> +#define EXT_CSD_FIRMWARE_VERSION  254 /* RO, 8 bytes */
> +#define EXT_CSD_PRE_EOL_INFO    267 /* RO */
> +#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A  268 /* RO */
> +#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B  269 /* RO */
> +#define EXT_CSD_CMDQ_DEPTH    307 /* RO */
> +#define EXT_CSD_CMDQ_SUPPORT    308 /* RO */
> +#define EXT_CSD_SUPPORTED_MODE    493 /* RO */
> +#define EXT_CSD_TAG_UNIT_SIZE   498 /* RO */
> +#define EXT_CSD_DATA_TAG_SUPPORT  499 /* RO */
> +#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
> +#define EXT_CSD_MAX_PACKED_READS  501 /* RO */
> +#define EXT_CSD_BKOPS_SUPPORT   502 /* RO */
> +#define EXT_CSD_HPI_FEATURES    503 /* RO */
> +#define EXT_CSD_S_CMD_SET   504 /* RO */
> +
> +/*
> + * EXT_CSD field definitions
> + */
> +
> +#define EXT_CSD_WR_REL_PARAM_EN   (1 << 2)
> +#define EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR (1 << 4)
> +
> +#define EXT_CSD_PART_CONFIG_ACC_MASK  (0x7)
> +#define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0)
> +#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
> +
> +#define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3)
> +#define EXT_CSD_PART_CONFIG_EN_BOOT0  (0x1 << 3)
> +#define EXT_CSD_PART_CONFIG_EN_USER (0x7 << 3)
> +
>  #endif
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index bc9d913..a26695b 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -135,6 +135,7 @@ struct SDState {
>      uint64_t data_start;
>      uint32_t data_offset;
>      uint8_t data[512];
> +    uint8_t ext_csd[512];

This is eMMC specific and one could argue that we need a EMMCState
structure but if this is the only extra field it seems over kill to
complexify the model for it.

>      qemu_irq readonly_cb;
>      qemu_irq inserted_cb;
>      QEMUTimer *ocr_power_timer;
> @@ -393,6 +394,55 @@ static const uint8_t sd_csd_rw_mask[16] = {
>      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
>  };
>  
> +static void mmc_set_ext_csd(SDState *sd, uint64_t size)

However, I think mmc_set_ext_csd() should be a SDCardClass handler.

C.


> +{
> +    uint32_t sectcount = size >> HWBLOCK_SHIFT;
> +
> +    memset(sd->ext_csd, 0, sizeof(sd->ext_csd));
> +    sd->ext_csd[EXT_CSD_S_CMD_SET] = 0x1; /* supported command sets */
> +    sd->ext_csd[EXT_CSD_HPI_FEATURES] = 0x3; /* HPI features  */
> +    sd->ext_csd[EXT_CSD_BKOPS_SUPPORT] = 0x1; /* Background operations
> +                                                 support */
> +    sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning */
> +    sd->ext_csd[EXT_CSD_TRIM_MULT] = 0x1; /* Trim multiplier */
> +    sd->ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] = 0x15; /* Secure feature
> +                                                        support */
> +    sd->ext_csd[EXT_CSD_SEC_ERASE_MULT] = 0x96; /* Secure erase support */
> +    sd->ext_csd[EXT_CSD_SEC_TRIM_MULT] = 0x96; /* Secure TRIM multiplier */
> +    sd->ext_csd[EXT_CSD_BOOT_INFO] = 0x7; /* Boot information */
> +    sd->ext_csd[EXT_CSD_BOOT_MULT] = 0x8; /* Boot partition size. 128KB unit */
> +    sd->ext_csd[EXT_CSD_ACC_SIZE] = 0x6; /* Access size */
> +    sd->ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] = 0x4; /* HC Erase unit size */
> +    sd->ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] = 0x1; /* HC erase timeout */
> +    sd->ext_csd[EXT_CSD_REL_WR_SEC_C] = 0x1; /* Reliable write sector count */
> +    sd->ext_csd[EXT_CSD_HC_WP_GRP_SIZE] = 0x4; /* HC write protect group size */
> +    sd->ext_csd[EXT_CSD_S_C_VCC] = 0x8; /* Sleep current VCC  */
> +    sd->ext_csd[EXT_CSD_S_C_VCCQ] = 0x7; /* Sleep current VCCQ */
> +    sd->ext_csd[EXT_CSD_S_A_TIMEOUT] = 0x11; /* Sleep/Awake timeout */
> +    sd->ext_csd[215] = (sectcount >> 24) & 0xff; /* Sector count */
> +    sd->ext_csd[214] = (sectcount >> 16) & 0xff; /* ... */
> +    sd->ext_csd[213] = (sectcount >> 8) & 0xff;  /* ... */
> +    sd->ext_csd[EXT_CSD_SEC_CNT] = (sectcount & 0xff);       /* ... */
> +    sd->ext_csd[210] = 0xa; /* Min write perf for 8bit@52Mhz */
> +    sd->ext_csd[209] = 0xa; /* Min read perf for 8bit@52Mhz  */
> +    sd->ext_csd[208] = 0xa; /* Min write perf for 4bit@52Mhz */
> +    sd->ext_csd[207] = 0xa; /* Min read perf for 4bit@52Mhz */
> +    sd->ext_csd[206] = 0xa; /* Min write perf for 4bit@26Mhz */
> +    sd->ext_csd[205] = 0xa; /* Min read perf for 4bit@26Mhz */
> +    sd->ext_csd[EXT_CSD_PART_SWITCH_TIME] = 0x1; /* Partition switching
> +                                                    timing */
> +    sd->ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] = 0x1; /* Out-of-interrupt busy
> +                                                         timing */
> +    sd->ext_csd[EXT_CSD_CARD_TYPE] = 0xFF; /* Card type */
> +    sd->ext_csd[EXT_CSD_STRUCTURE] = 0x2; /* CSD Structure version */
> +    sd->ext_csd[EXT_CSD_REV] = 0x5; /* Extended CSD revision */
> +    sd->ext_csd[EXT_CSD_RPMB_MULT] = 0x1; /* RPMB size */
> +    sd->ext_csd[EXT_CSD_PARTITION_SUPPORT] = 0x3; /* Partinioning support */
> +    sd->ext_csd[159] = 0x00; /* Max enhanced area size */
> +    sd->ext_csd[158] = 0x00; /* ... */
> +    sd->ext_csd[157] = 0xEC; /* ... */
> +}
> +
>  static void sd_set_csd(SDState *sd, uint64_t size)
>  {
>      int hwblock_shift = HWBLOCK_SHIFT;
> @@ -406,8 +456,11 @@ static void sd_set_csd(SDState *sd, uint64_t size)
>      }
>      csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
>  
> -    if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
> -        sd->csd[0] = 0x00;  /* CSD structure */
> +    if (size <= SDSC_MAX_CAPACITY || sd->emmc) { /* Standard Capacity SD */
> +        if (sd->emmc && size >= SDSC_MAX_CAPACITY) {
> +            csize = 0xfff;
> +        }
> +        sd->csd[0] = sd->emmc ? 0xd0 : 0x00;  /* CSD structure */
>          sd->csd[1] = 0x26;  /* Data read access-time-1 */
>          sd->csd[2] = 0x00;  /* Data read access-time-2 */
>          sd->csd[3] = 0x32;      /* Max. data transfer rate: 25 MHz */
> @@ -451,6 +504,10 @@ static void sd_set_csd(SDState *sd, uint64_t size)
>          sd->csd[14] = 0x00;
>      }
>      sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
> +
> +    if (sd->emmc) {
> +        mmc_set_ext_csd(sd, size);
> +    }
>  }
>  
>  static void sd_set_rca(SDState *sd, uint16_t value)
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register
  2021-02-28 19:33 ` [PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register Sai Pavan Boddu
@ 2021-03-01 12:02   ` Cédric Le Goater
  0 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 12:02 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> From: Vincent Palatin <vpalatin@chromium.org>
> 
> Sends the EXT_CSD register as response to CMD8.
> 
> Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> ---
>  hw/sd/sd.c | 52 ++++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 36 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index a26695b..181e7e2 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1141,24 +1141,37 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>          }
>          break;
>  
> -    case 8: /* CMD8:   SEND_IF_COND */
> -        if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
> -            break;
> -        }
> -        if (sd->state != sd_idle_state) {
> -            break;
> -        }
> -        sd->vhs = 0;
> -
> -        /* No response if not exactly one VHS bit is set.  */
> -        if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
> -            return sd->spi ? sd_r7 : sd_r0;
> -        }
> +    case 8:    /* CMD8:   SEND_IF_COND / SEND_EXT_CSD */
> +        if (sd->emmc) {
> +            switch (sd->state) {
> +            case sd_transfer_state:
> +                /* MMC : Sends the EXT_CSD register as a Block of data */
> +                sd->state = sd_sendingdata_state;
> +                memcpy(sd->data, sd->ext_csd, sizeof(sd->ext_csd));
> +                sd->data_start = addr;
> +                sd->data_offset = 0;
> +                return sd_r1;
> +            default:
> +                break;
> +            }

This is big enough to be a SDCardClass handler.

Thanks,

C.


> +        } else {
> +            if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
> +                break;
> +            }
> +            if (sd->state != sd_idle_state) {
> +                break;
> +            }
> +            sd->vhs = 0;
>  
> -        /* Accept.  */
> -        sd->vhs = req.arg;
> -        return sd_r7;
> +            /* No response if not exactly one VHS bit is set.  */
> +            if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
> +                return sd->spi ? sd_r7 : sd_r0;
> +            }
>  
> +            /* Accept.  */
> +            sd->vhs = req.arg;
> +            return sd_r7;
> +        }
>      case 9: /* CMD9:   SEND_CSD */
>          switch (sd->state) {
>          case sd_standby_state:
> @@ -2081,6 +2094,13 @@ uint8_t sd_read_byte(SDState *sd)
>              sd->state = sd_transfer_state;
>          break;
>  
> +    case 8:     /* CMD8: SEND_EXT_CSD on MMC */
> +        ret = sd->data[sd->data_offset++];
> +        if (sd->data_offset >= sizeof(sd->ext_csd)) {
> +            sd->state = sd_transfer_state;
> +        }
> +        break;
> +
>      case 9:     /* CMD9:   SEND_CSD */
>      case 10:    /* CMD10:  SEND_CID */
>          ret = sd->data[sd->data_offset ++];
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD
  2021-02-28 19:33 ` [PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD Sai Pavan Boddu
@ 2021-03-01 12:03   ` Cédric Le Goater
  0 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 12:03 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> From: Cédric Le Goater <clg@kaod.org>
> 
> This adds extra info to trace log.
> 
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>

From and Signed-off-by are not in sync :)

C.

> ---
>  hw/sd/sdmmc-internal.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
> index 2053def..8648a78 100644
> --- a/hw/sd/sdmmc-internal.c
> +++ b/hw/sd/sdmmc-internal.c
> @@ -14,7 +14,7 @@
>  const char *sd_cmd_name(uint8_t cmd)
>  {
>      static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
> -         [0]    = "GO_IDLE_STATE",
> +         [0]    = "GO_IDLE_STATE",           [1]    = "SEND_OP_CMD",
>           [2]    = "ALL_SEND_CID",            [3]    = "SEND_RELATIVE_ADDR",
>           [4]    = "SET_DSR",                 [5]    = "IO_SEND_OP_COND",
>           [6]    = "SWITCH_FUNC",             [7]    = "SELECT/DESELECT_CARD",
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 16/21] sd: emmc: Support boot area in emmc image
  2021-02-28 19:33 ` [PATCH v3 16/21] sd: emmc: Support boot area in emmc image Sai Pavan Boddu
@ 2021-03-01 12:07   ` Cédric Le Goater
  0 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 12:07 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> From: Joel Stanley <joel@jms.id.au>
> 
> This assumes a specially constructued image:
> 
>   dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M
>   dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc
>   dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc count=64 bs=1K
>   cat mmc-bootarea.img obmc-phosphor-image.wic > mmc.img
>   truncate --size 16GB mmc.img
>   truncate --size 128MB mmc-bootarea.img
> 
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> [clg: - changes on the definition names ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> [spb: use data_start property to access right emmc partition,
>       Clean up PARTITION_ENABLE support as incomplete,
>       Fix commit message to be generic.]
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> ---
>  hw/sd/sd.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 08b77ad..d311477 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1044,6 +1044,34 @@ static void sd_lock_command(SDState *sd)
>          sd->card_status &= ~CARD_IS_LOCKED;
>  }
>  
> +/*
> + * This requires a disk image that has two boot partitions inserted at the
> + * beginning of it. The size of the boot partitions are configured in the
> + * ext_csd structure, which is hardcoded in qemu. They are currently set to
> + * 1MB each.
> + */
> +static uint32_t sd_bootpart_offset(SDState *sd)
> +{
> +    unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
> +        EXT_CSD_PART_CONFIG_ACC_MASK;
> +    unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
> +
> +    if (!sd->emmc) {
> +        return 0;
> +    }
> +
> +    switch (access) {
> +    case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
> +        return boot_capacity * 2;
> +    case EXT_CSD_PART_CONFIG_ACC_BOOT0:
> +        return 0;
> +    case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
> +        return boot_capacity * 1;
> +    default:
> +         g_assert_not_reached();
> +    }
> +}
> +
>  static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>  {
>      uint32_t rca = 0x0000;
> @@ -1359,6 +1387,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>                  return sd_r1;
>              }
>  
> +            if (sd->emmc) {
> +                addr += sd_bootpart_offset(sd);


This could be a class handler. The default behavior would be to return 0.

C.

> +            }
>              sd->state = sd_sendingdata_state;
>              sd->data_start = addr;
>              sd->data_offset = 0;
> @@ -1378,6 +1409,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>                  return sd_r1;
>              }
>  
> +            if (sd->emmc) {
> +                addr += sd_bootpart_offset(sd);
> +            }
>              sd->state = sd_sendingdata_state;
>              sd->data_start = addr;
>              sd->data_offset = 0;
> @@ -1434,6 +1468,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>                  return sd_r1;
>              }
>  
> +            if (sd->emmc) {
> +                addr += sd_bootpart_offset(sd);
> +            }
>              sd->state = sd_receivingdata_state;
>              sd->data_start = addr;
>              sd->data_offset = 0;
> @@ -1464,6 +1501,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>                  return sd_r1;
>              }
>  
> +            if (sd->emmc) {
> +                addr += sd_bootpart_offset(sd);
> +            }
>              sd->state = sd_receivingdata_state;
>              sd->data_start = addr;
>              sd->data_offset = 0;
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 15/21] sd: emmc: Update CID structure for eMMC
  2021-02-28 19:33 ` [PATCH v3 15/21] sd: emmc: Update CID structure for eMMC Sai Pavan Boddu
@ 2021-03-01 12:09   ` Cédric Le Goater
  0 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-01 12:09 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini
  Cc: saipava, qemu-devel, qemu-block

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> CID structure is little different for eMMC, w.r.t to product name and
> manufacturing date.
> 
> Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> ---
>  hw/sd/sd.c | 47 ++++++++++++++++++++++++++++++-----------------
>  1 file changed, 30 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index bba0446..08b77ad 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -365,23 +365,36 @@ static void sd_set_scr(SDState *sd)
>  
>  static void sd_set_cid(SDState *sd)
>  {
> -    sd->cid[0] = MID;       /* Fake card manufacturer ID (MID) */
> -    sd->cid[1] = OID[0];    /* OEM/Application ID (OID) */
> -    sd->cid[2] = OID[1];
> -    sd->cid[3] = PNM[0];    /* Fake product name (PNM) */
> -    sd->cid[4] = PNM[1];
> -    sd->cid[5] = PNM[2];
> -    sd->cid[6] = PNM[3];
> -    sd->cid[7] = PNM[4];
> -    sd->cid[8] = PRV;       /* Fake product revision (PRV) */
> -    sd->cid[9] = 0xde;      /* Fake serial number (PSN) */
> -    sd->cid[10] = 0xad;
> -    sd->cid[11] = 0xbe;
> -    sd->cid[12] = 0xef;
> -    sd->cid[13] = 0x00 |    /* Manufacture date (MDT) */
> -        ((MDT_YR - 2000) / 10);
> -    sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
> -    sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
> +    if (sd->emmc) {
> +        sd->cid[0] = MID;
> +        sd->cid[1] = 0x1;       /* CBX */
> +        sd->cid[2] = OID[0];    /* OEM/Application ID (OID) */
> +        sd->cid[8] = 0x0;
> +        sd->cid[9] = PRV;        /* Fake product revision (PRV) */
> +        sd->cid[10] = 0xde;      /* Fake serial number (PSN) */
> +        sd->cid[11] = 0xad;
> +        sd->cid[12] = 0xbe;
> +        sd->cid[13] = 0xef;
> +        sd->cid[14] = ((MDT_YR - 1997) % 0x10); /* MDT */
> +    } else {
> +        sd->cid[0] = MID;       /* Fake card manufacturer ID (MID) */
> +        sd->cid[1] = OID[0];    /* OEM/Application ID (OID) */
> +        sd->cid[2] = OID[1];
> +        sd->cid[8] = PRV;       /* Fake product revision (PRV) */
> +        sd->cid[9] = 0xde;      /* Fake serial number (PSN) */
> +        sd->cid[10] = 0xad;
> +        sd->cid[11] = 0xbe;
> +        sd->cid[12] = 0xef;
> +        sd->cid[13] = 0x00 |    /* Manufacture date (MDT) */
> +            ((MDT_YR - 2000) / 10);
> +        sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
> +   }
> +   sd->cid[3] = PNM[0];    /* Fake product name (PNM) 48bit */
> +   sd->cid[4] = PNM[1];
> +   sd->cid[5] = PNM[2];
> +   sd->cid[6] = PNM[3];
> +   sd->cid[7] = PNM[4];
> +   sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
>  }


These are constant values and could be kept in SDCardClass. 

C.


>  #define HWBLOCK_SHIFT   9           /* 512 bytes */
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 00/21] eMMC support
  2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
                   ` (20 preceding siblings ...)
  2021-02-28 19:33 ` [PATCH v3 21/21] docs: arm: xlnx-versal-virt: Add eMMC support documentation Sai Pavan Boddu
@ 2021-03-02  9:52 ` Cédric Le Goater
  21 siblings, 0 replies; 34+ messages in thread
From: Cédric Le Goater @ 2021-03-02  9:52 UTC (permalink / raw)
  To: Sai Pavan Boddu, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis,
	Edgar E. Iglesias, Luc Michel, Paolo Bonzini,
	Philippe Mathieu-Daudé,
	Bin Meng
  Cc: saipava, qemu-devel, qemu-block

Hello,

Adding the SD maintainers for more feedback. 

Thanks,

C.

On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> Hi,
> 
> This patch series add support for eMMC cards. This work was previosly
> submitted by Vincent, rebased few changes on top.
> 
> Cedric & Joel has helped to added boot partition access support. I
> expect them to make a follow-up series to use it with aspeed machines.> 
> Present series adds eMMC support to Versal SOC.
> 
> Initial patch series version is RFC
> Changes for V2:
> 	Split Patch 1
> 	Add comments for eMMC Erase commands
> 	Added documentation about eMMC and Versal-virt board.
> 	Make eMMC optional for xlnx-versal-virt machines
> Changes for V3:
> 	Revome addition of EMMC drive flag
> 	Add TYPE_EMMC device
> 	Add id strings for shci instances
> 	Update versal doc with eMMC example
> 	Fix signed-off-by lines for few patches
> 
> Cédric Le Goater (1):
>   sd: sdmmc-internal: Add command string for SEND_OP_CMD
> 
> Joel Stanley (2):
>   sd: emmc: Support boot area in emmc image
>   sd: emmc: Subtract bootarea size from blk
> 
> Sai Pavan Boddu (14):
>   sd: sd: Remove usage of tabs in the file
>   sd: emmc: Add support for eMMC cards
>   sd: emmc: Dont not update CARD_CAPACITY for eMMC cards
>   sd: emmc: Update CMD1 definition for eMMC
>   sd: emmc: support idle state in CMD2
>   sd: emmc: Add mmc switch function support
>   sd: emmc: add CMD21 tuning sequence
>   sd: emmc: Make ACMD41 illegal for mmc
>   sd: emmc: Add support for emmc erase
>   sd: emmc: Update CID structure for eMMC
>   sd: sdhci: Support eMMC devices
>   arm: xlnx-versal: Add emmc to versal
>   docs: devel: emmc: Add a doc for emmc card emulation
>   docs: arm: xlnx-versal-virt: Add eMMC support documentation
> 
> Vincent Palatin (4):
>   sd: emmc: Update SET_RELATIVE_ADDR command
>   sd: emmc: update OCR fields for eMMC
>   sd: emmc: Add support for EXT_CSD & CSD for eMMC
>   sd: emmc: Update CMD8 to send EXT_CSD register
> 
>  docs/devel/emmc.txt                  |  16 +
>  docs/system/arm/xlnx-versal-virt.rst |  14 +
>  hw/sd/sdmmc-internal.h               |  97 ++++++
>  include/hw/arm/xlnx-versal.h         |   1 +
>  include/hw/sd/sd.h                   |   2 +
>  hw/arm/xlnx-versal-virt.c            |  29 +-
>  hw/arm/xlnx-versal.c                 |  14 +-
>  hw/sd/sd.c                           | 563 ++++++++++++++++++++++++++---------
>  hw/sd/sdhci.c                        |   4 -
>  hw/sd/sdmmc-internal.c               |   2 +-
>  10 files changed, 594 insertions(+), 148 deletions(-)
>  create mode 100644 docs/devel/emmc.txt
> 



^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
  2021-03-01 10:42   ` Dr. David Alan Gilbert
@ 2021-03-03  3:53     ` Sai Pavan Boddu
  2021-03-03  9:15       ` Dr. David Alan Gilbert
  0 siblings, 1 reply; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-03-03  3:53 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: Kevin Wolf, Peter Maydell, Thomas Huth,
	Vladimir Sementsov-Ogievskiy, Vincent Palatin, qemu-block,
	qemu-devel, Markus Armbruster, Max Reitz, Edgar Iglesias,
	Alistair Francis, Joel Stanley, Stefan Hajnoczi, Paolo Bonzini,
	Luc Michel, Cédric Le Goater

Hi David,

> -----Original Message-----
> From: Dr. David Alan Gilbert <dgilbert@redhat.com>
> Sent: Monday, March 1, 2021 4:12 PM
> To: Sai Pavan Boddu <saipava@xilinx.com>
> Cc: Markus Armbruster <armbru@redhat.com>; Kevin Wolf
> <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>; Vladimir Sementsov-
> Ogievskiy <vsementsov@virtuozzo.com>; Eric Blake <eblake@redhat.com>;
> Joel Stanley <joel@jms.id.au>; Cédric Le Goater <clg@kaod.org>; Vincent
> Palatin <vpalatin@chromium.org>; Thomas Huth <thuth@redhat.com>; Stefan
> Hajnoczi <stefanha@redhat.com>; Peter Maydell <peter.maydell@linaro.org>;
> Alistair Francis <alistair.francis@wdc.com>; Edgar Iglesias <edgari@xilinx.com>;
> Luc Michel <luc.michel@greensocs.com>; Paolo Bonzini
> <pbonzini@redhat.com>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Sai Pavan Boddu <saipava@xilinx.com>
> Subject: Re: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
> 
> * Sai Pavan Boddu (sai.pavan.boddu@xilinx.com) wrote:
> > eMMC cards support tuning sequence for entering HS200 mode.
> >
> > Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> > ---
> >  hw/sd/sd.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 47 insertions(+)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index bf963ec..174c28e 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -1386,6 +1386,14 @@ static sd_rsp_type_t
> sd_normal_command(SDState *sd, SDRequest req)
> >          }
> >          break;
> >
> > +    case 21:    /* CMD21: mmc SEND TUNING_BLOCK */
> > +        if (sd->emmc && (sd->state == sd_transfer_state)) {
> > +            sd->state = sd_sendingdata_state;
> > +            sd->data_offset = 0;
> > +            return sd_r1;
> > +        }
> > +        break;
> > +
> >      case 23:    /* CMD23: SET_BLOCK_COUNT */
> >          if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
> >              break;
> > @@ -2120,6 +2128,30 @@ static const uint8_t
> sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
> >      0xbb, 0xff, 0xf7, 0xff,         0xf7, 0x7f, 0x7b, 0xde,
> >  };
> >
> > +#define EXCSD_BUS_WIDTH_OFFSET 183
> > +#define BUS_WIDTH_8_MASK    0x4
> > +#define BUS_WIDTH_4_MASK    0x2
> > +#define MMC_TUNING_BLOCK_SIZE   128
> > +
> > +static const uint8_t mmc_tunning_block_pattern[128] = {
> > +       0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
> > +       0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
> > +       0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
> > +       0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
> > +       0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
> > +       0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
> > +       0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
> > +       0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
> > +       0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
> > +       0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
> > +       0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
> > +       0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
> > +       0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
> > +       0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
> > +       0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
> > +       0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
> 
> Where does this magic pattern come from?  Is it part of some spec?
[Sai Pavan Boddu] Yes its part of JEDEC eMMC spec. It's the tuning sequence for HS200 mode.

Regards,
Sai Pavan
> 
> Dave
> 
> > +};
> > +
> >  uint8_t sd_read_byte(SDState *sd)
> >  {
> >      /* TODO: Append CRCs */
> > @@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
> >          ret = sd_tuning_block_pattern[sd->data_offset++];
> >          break;
> >
> > +    case 21:    /* CMD21: SEND_TUNNING_BLOCK (MMC) */
> > +        if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
> > +            sd->state = sd_transfer_state;
> > +        }
> > +        if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
> > +            ret = mmc_tunning_block_pattern[sd->data_offset++];
> > +        } else {
> > +            /* Return LSB Nibbles of two byte from the 8bit tuning block
> > +             * for 4bit mode
> > +             */
> > +            ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
> > +            ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
> > +        }
> > +        break;
> > +
> >      case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
> >          ret = sd->data[sd->data_offset ++];
> >
> > --
> > 2.7.4
> >
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards
  2021-03-01 11:02   ` Cédric Le Goater
@ 2021-03-03  3:57     ` Sai Pavan Boddu
  0 siblings, 0 replies; 34+ messages in thread
From: Sai Pavan Boddu @ 2021-03-03  3:57 UTC (permalink / raw)
  To: Cédric Le Goater, Markus Armbruster, Kevin Wolf, Max Reitz,
	Vladimir Sementsov-Ogievskiy, Eric Blake, Joel Stanley,
	Vincent Palatin, Dr. David Alan Gilbert, Thomas Huth,
	Stefan Hajnoczi, Peter Maydell, Alistair Francis, Edgar Iglesias,
	Luc Michel, Paolo Bonzini
  Cc: qemu-devel, qemu-block

Hi Cedric,
> -----Original Message-----
> From: Cédric Le Goater <clg@kaod.org>
> Sent: Monday, March 1, 2021 4:32 PM
> To: Sai Pavan Boddu <saipava@xilinx.com>; Markus Armbruster
> <armbru@redhat.com>; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Vladimir Sementsov-Ogievskiy
> <vsementsov@virtuozzo.com>; Eric Blake <eblake@redhat.com>; Joel Stanley
> <joel@jms.id.au>; Vincent Palatin <vpalatin@chromium.org>; Dr. David Alan
> Gilbert <dgilbert@redhat.com>; Thomas Huth <thuth@redhat.com>; Stefan
> Hajnoczi <stefanha@redhat.com>; Peter Maydell <peter.maydell@linaro.org>;
> Alistair Francis <alistair.francis@wdc.com>; Edgar Iglesias <edgari@xilinx.com>;
> Luc Michel <luc.michel@greensocs.com>; Paolo Bonzini
> <pbonzini@redhat.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; Sai Pavan Boddu
> <saipava@xilinx.com>
> Subject: Re: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards
> 
> On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> > Add eMMC device built on top of SD card.
> >
> > Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> > ---
> >  include/hw/sd/sd.h |  2 ++
> >  hw/sd/sd.c         | 20 ++++++++++++++++++++
> >  2 files changed, 22 insertions(+)
> >
> > diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index
> > 05ef9b7..b402dad 100644
> > --- a/include/hw/sd/sd.h
> > +++ b/include/hw/sd/sd.h
> > @@ -90,6 +90,8 @@ typedef struct {
> >  } SDRequest;
> >
> >
> > +#define TYPE_EMMC "emmc"
> > +OBJECT_DECLARE_SIMPLE_TYPE(EMMCState, EMMC)
> >  #define TYPE_SD_CARD "sd-card"
> >  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 74b9162..a23af6d 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -108,6 +108,7 @@ struct SDState {
> >      uint8_t spec_version;
> >      BlockBackend *blk;
> >      bool spi;
> > +    bool emmc;
> >
> >      /* Runtime changeables */
> >
> > @@ -143,6 +144,10 @@ struct SDState {
> >      bool cmd_line;
> >  };
> >
> > +struct EMMCState {
> > +    SDState parent;
> > +};
> > +
> >  static void sd_realize(DeviceState *dev, Error **errp);
> >
> >  static const char *sd_state_name(enum SDCardStates state) @@ -2105,6
> > +2110,13 @@ static void sd_instance_init(Object *obj)
> >      sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > sd_ocr_powerup, sd);  }
> >
> > +static void emmc_instance_init(Object *obj) {
> > +    SDState *sd = SD_CARD(obj);
> > +
> > +    sd->emmc = true;
> > +}
> I think field 'emmc' would fit better in SDCardClass since it is a device constant.
> You should not need 'struct EMMCState'. So something like below.
> Then you can add handlers for specific emmc commands.
> 
> Thanks,
> 
> C.
> 
> 
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index
> 47360ba4ee98..80e7cd526a57 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -93,6 +93,8 @@ typedef struct {
>  #define TYPE_SD_CARD "sd-card"
>  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
> 
> +#define TYPE_EMMC "emmc"
> +
>  struct SDCardClass {
>      /*< private >*/
>      DeviceClass parent_class;
> @@ -124,6 +126,8 @@ struct SDCardClass {
>      void (*enable)(SDState *sd, bool enable);
>      bool (*get_inserted)(SDState *sd);
>      bool (*get_readonly)(SDState *sd);
> +
> +    bool emmc;
>  };
> 
>  #define TYPE_SD_BUS "sd-bus"
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 660026f2a667..95608f11b36e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -2447,9 +2447,24 @@ static const TypeInfo sd_info = {
>      .instance_finalize = sd_instance_finalize,  };
> 
> +static void emmc_class_init(ObjectClass *klass, void *data) {
> +    SDCardClass *sc = SD_CARD_CLASS(klass);
> +
> +    sc->emmc = true;
> +}
> +
> +static const TypeInfo emmc_info = {
> +    .name = TYPE_EMMC,
> +    .parent = TYPE_SD_CARD,
> +    .instance_size = sizeof(SDState),
> +    .class_init = emmc_class_init,
> +};
> +
[Sai Pavan Boddu] Yes, I see your point. Let me try, I was preferring a simpler approach just to not disturb the code much but lets see how this workout.

Thanks,
Sai Pavan
>  static void sd_register_types(void)
>  {
>      type_register_static(&sd_info);
> +    type_register_static(&emmc_info);
>  }
> 
>  type_init(sd_register_types)


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
  2021-03-03  3:53     ` Sai Pavan Boddu
@ 2021-03-03  9:15       ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 34+ messages in thread
From: Dr. David Alan Gilbert @ 2021-03-03  9:15 UTC (permalink / raw)
  To: Sai Pavan Boddu
  Cc: Kevin Wolf, Peter Maydell, Thomas Huth,
	Vladimir Sementsov-Ogievskiy, Vincent Palatin, qemu-block,
	qemu-devel, Markus Armbruster, Max Reitz, Edgar Iglesias,
	Alistair Francis, Joel Stanley, Stefan Hajnoczi, Paolo Bonzini,
	Luc Michel, Cédric Le Goater

* Sai Pavan Boddu (saipava@xilinx.com) wrote:
> Hi David,
> 
> > -----Original Message-----
> > From: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > Sent: Monday, March 1, 2021 4:12 PM
> > To: Sai Pavan Boddu <saipava@xilinx.com>
> > Cc: Markus Armbruster <armbru@redhat.com>; Kevin Wolf
> > <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>; Vladimir Sementsov-
> > Ogievskiy <vsementsov@virtuozzo.com>; Eric Blake <eblake@redhat.com>;
> > Joel Stanley <joel@jms.id.au>; Cédric Le Goater <clg@kaod.org>; Vincent
> > Palatin <vpalatin@chromium.org>; Thomas Huth <thuth@redhat.com>; Stefan
> > Hajnoczi <stefanha@redhat.com>; Peter Maydell <peter.maydell@linaro.org>;
> > Alistair Francis <alistair.francis@wdc.com>; Edgar Iglesias <edgari@xilinx.com>;
> > Luc Michel <luc.michel@greensocs.com>; Paolo Bonzini
> > <pbonzini@redhat.com>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> > Sai Pavan Boddu <saipava@xilinx.com>
> > Subject: Re: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
> > 
> > * Sai Pavan Boddu (sai.pavan.boddu@xilinx.com) wrote:
> > > eMMC cards support tuning sequence for entering HS200 mode.
> > >
> > > Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
> > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> > > ---
> > >  hw/sd/sd.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 47 insertions(+)
> > >
> > > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > > index bf963ec..174c28e 100644
> > > --- a/hw/sd/sd.c
> > > +++ b/hw/sd/sd.c
> > > @@ -1386,6 +1386,14 @@ static sd_rsp_type_t
> > sd_normal_command(SDState *sd, SDRequest req)
> > >          }
> > >          break;
> > >
> > > +    case 21:    /* CMD21: mmc SEND TUNING_BLOCK */
> > > +        if (sd->emmc && (sd->state == sd_transfer_state)) {
> > > +            sd->state = sd_sendingdata_state;
> > > +            sd->data_offset = 0;
> > > +            return sd_r1;
> > > +        }
> > > +        break;
> > > +
> > >      case 23:    /* CMD23: SET_BLOCK_COUNT */
> > >          if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
> > >              break;
> > > @@ -2120,6 +2128,30 @@ static const uint8_t
> > sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
> > >      0xbb, 0xff, 0xf7, 0xff,         0xf7, 0x7f, 0x7b, 0xde,
> > >  };
> > >
> > > +#define EXCSD_BUS_WIDTH_OFFSET 183
> > > +#define BUS_WIDTH_8_MASK    0x4
> > > +#define BUS_WIDTH_4_MASK    0x2
> > > +#define MMC_TUNING_BLOCK_SIZE   128
> > > +
> > > +static const uint8_t mmc_tunning_block_pattern[128] = {
> > > +       0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
> > > +       0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
> > > +       0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
> > > +       0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
> > > +       0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
> > > +       0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
> > > +       0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
> > > +       0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
> > > +       0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
> > > +       0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
> > > +       0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
> > > +       0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
> > > +       0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
> > > +       0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
> > > +       0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
> > > +       0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
> > 
> > Where does this magic pattern come from?  Is it part of some spec?
> [Sai Pavan Boddu] Yes its part of JEDEC eMMC spec. It's the tuning sequence for HS200 mode.

OK, if you have to repost it, then please add a comment saying that.

DAve

> Regards,
> Sai Pavan
> > 
> > Dave
> > 
> > > +};
> > > +
> > >  uint8_t sd_read_byte(SDState *sd)
> > >  {
> > >      /* TODO: Append CRCs */
> > > @@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
> > >          ret = sd_tuning_block_pattern[sd->data_offset++];
> > >          break;
> > >
> > > +    case 21:    /* CMD21: SEND_TUNNING_BLOCK (MMC) */
> > > +        if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
> > > +            sd->state = sd_transfer_state;
> > > +        }
> > > +        if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
> > > +            ret = mmc_tunning_block_pattern[sd->data_offset++];
> > > +        } else {
> > > +            /* Return LSB Nibbles of two byte from the 8bit tuning block
> > > +             * for 4bit mode
> > > +             */
> > > +            ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
> > > +            ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
> > > +        }
> > > +        break;
> > > +
> > >      case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
> > >          ret = sd->data[sd->data_offset ++];
> > >
> > > --
> > > 2.7.4
> > >
> > --
> > Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
> 
-- 
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2021-03-03  9:17 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-28 19:33 [PATCH v3 00/21] eMMC support Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 01/21] sd: sd: Remove usage of tabs in the file Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 02/21] sd: emmc: Add support for eMMC cards Sai Pavan Boddu
2021-03-01 11:02   ` Cédric Le Goater
2021-03-03  3:57     ` Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 03/21] sd: emmc: Update SET_RELATIVE_ADDR command Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 04/21] sd: emmc: update OCR fields for eMMC Sai Pavan Boddu
2021-03-01 11:04   ` Cédric Le Goater
2021-02-28 19:33 ` [PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD " Sai Pavan Boddu
2021-03-01 11:08   ` Cédric Le Goater
2021-02-28 19:33 ` [PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register Sai Pavan Boddu
2021-03-01 12:02   ` Cédric Le Goater
2021-02-28 19:33 ` [PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD Sai Pavan Boddu
2021-03-01 12:03   ` Cédric Le Goater
2021-02-28 19:33 ` [PATCH v3 08/21] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 09/21] sd: emmc: Update CMD1 definition for eMMC Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 10/21] sd: emmc: support idle state in CMD2 Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 11/21] sd: emmc: Add mmc switch function support Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence Sai Pavan Boddu
2021-03-01 10:42   ` Dr. David Alan Gilbert
2021-03-03  3:53     ` Sai Pavan Boddu
2021-03-03  9:15       ` Dr. David Alan Gilbert
2021-02-28 19:33 ` [PATCH v3 13/21] sd: emmc: Make ACMD41 illegal for mmc Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 14/21] sd: emmc: Add support for emmc erase Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 15/21] sd: emmc: Update CID structure for eMMC Sai Pavan Boddu
2021-03-01 12:09   ` Cédric Le Goater
2021-02-28 19:33 ` [PATCH v3 16/21] sd: emmc: Support boot area in emmc image Sai Pavan Boddu
2021-03-01 12:07   ` Cédric Le Goater
2021-02-28 19:33 ` [PATCH v3 17/21] sd: emmc: Subtract bootarea size from blk Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 18/21] sd: sdhci: Support eMMC devices Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 19/21] arm: xlnx-versal: Add emmc to versal Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 20/21] docs: devel: emmc: Add a doc for emmc card emulation Sai Pavan Boddu
2021-02-28 19:33 ` [PATCH v3 21/21] docs: arm: xlnx-versal-virt: Add eMMC support documentation Sai Pavan Boddu
2021-03-02  9:52 ` [PATCH v3 00/21] eMMC support Cédric Le Goater

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.