SD/MMC patches

- Fix a bug in CMD6/SWITCH_FUNCTION (Bin Meng)
 - Minor housekeeping patches
 
 CI jobs result:
 . https://cirrus-ci.com/build/5461987880599552
 . https://gitlab.com/philmd/qemu/-/pipelines/207532287
 . https://travis-ci.org/github/philmd/qemu/builds/738901111
 . https://app.shippable.com/github/philmd/qemu/runs/888/summary/console
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAl+WrL4ACgkQ4+MsLN6t
 wN621w//dqTyjE314mFw4dfr3sUO8NPo7EkwVzqFsrD0i01oQqlDQa1UI5cAo+WD
 l812CBLosNKOrcyqe0Jqk+nAblOQcy04H7KO1isG2pzdcuCm48kMpQW5AbLH48z3
 X/D/N2frrhjoqtkH1bHZp1khLvdTJuUSYI5LaKS69LQZp1TcSHdzY6E4zAuxVdrh
 whKj99fCMYhS/mxb3F1SPZ2MviD7WfnJXWyGUhfbH2eGlaWld24kxnEnVW6mRMMb
 1bIBeRAM5LOsseJSI5gXCHydfJeQA4xefvzxoE/mO2z13fD8XPGRKV5zmYvwOsb+
 gJsMJ/SW9+PyNt7scGGvT1nT9U2Te+0wn8pV+r2/ddEvfPj2IcVdtX2jYi2RS1Ra
 FLfVq0t+E8LVuRXyUICZvaBv/p7N/eSUErXsk195eAzM7/FFlVeTGjXgMQwRH4v+
 wemJ7TAIFiyK+x2qSY5P2HmaKIm6Pz5UDh5eQ8lXuhv2DSFxeIPL477DFODm031p
 cn+6S0N6qJgDcNRIlzgg05dxNB73y3vRGNXDQcBVcigHKEgE93B6SJd2Bo/MtLb4
 CnbpjukFSbCT77QY2ghGz5RXdbQ71/lnqNL0mkW671G27Dr7YjO4GEEg1d0ZSa2y
 wm41oo1eoD8QwOKxRIPMe9MG19KDff3LpYbCtuwHvrtivD8VPgo=
 =TASC
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/philmd-gitlab/tags/sd-next-20201026' into staging

SD/MMC patches

- Fix a bug in CMD6/SWITCH_FUNCTION (Bin Meng)
- Minor housekeeping patches

CI jobs result:
. https://cirrus-ci.com/build/5461987880599552
. https://gitlab.com/philmd/qemu/-/pipelines/207532287
. https://travis-ci.org/github/philmd/qemu/builds/738901111
. https://app.shippable.com/github/philmd/qemu/runs/888/summary/console

# gpg: Signature made Mon 26 Oct 2020 11:02:22 GMT
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* remotes/philmd-gitlab/tags/sd-next-20201026:
  hw/sd/sdcard: Zero out function selection fields before being populated
  hw/sd/sdcard: Make iolen unsigned
  hw/sd/sdcard: Constify sd_crc*()'s message argument
  hw/sd/sdcard: Simplify cmd_valid_while_locked()
  hw/sd/sdcard: Update the SDState documentation

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-10-26 17:19:26 +00:00
commit 1dc887329a
2 changed files with 16 additions and 13 deletions

View File

@ -102,11 +102,14 @@ struct SDState {
uint32_t card_status; uint32_t card_status;
uint8_t sd_status[64]; uint8_t sd_status[64];
/* Configurable properties */ /* Static properties */
uint8_t spec_version; uint8_t spec_version;
BlockBackend *blk; BlockBackend *blk;
bool spi; bool spi;
/* Runtime changeables */
uint32_t mode; /* current card mode, one of SDCardModes */ uint32_t mode; /* current card mode, one of SDCardModes */
int32_t state; /* current card state, one of SDCardStates */ int32_t state; /* current card state, one of SDCardStates */
uint32_t vhs; uint32_t vhs;
@ -251,11 +254,11 @@ static const int sd_cmd_class[SDMMC_CMD_MAX] = {
7, 7, 10, 7, 9, 9, 9, 8, 8, 10, 8, 8, 8, 8, 8, 8, 7, 7, 10, 7, 9, 9, 9, 8, 8, 10, 8, 8, 8, 8, 8, 8,
}; };
static uint8_t sd_crc7(void *message, size_t width) static uint8_t sd_crc7(const void *message, size_t width)
{ {
int i, bit; int i, bit;
uint8_t shift_reg = 0x00; uint8_t shift_reg = 0x00;
uint8_t *msg = (uint8_t *) message; const uint8_t *msg = (const uint8_t *)message;
for (i = 0; i < width; i ++, msg ++) for (i = 0; i < width; i ++, msg ++)
for (bit = 7; bit >= 0; bit --) { for (bit = 7; bit >= 0; bit --) {
@ -267,11 +270,11 @@ static uint8_t sd_crc7(void *message, size_t width)
return shift_reg; return shift_reg;
} }
static uint16_t sd_crc16(void *message, size_t width) static uint16_t sd_crc16(const void *message, size_t width)
{ {
int i, bit; int i, bit;
uint16_t shift_reg = 0x0000; uint16_t shift_reg = 0x0000;
uint16_t *msg = (uint16_t *) message; const uint16_t *msg = (const uint16_t *)message;
width <<= 1; width <<= 1;
for (i = 0; i < width; i ++, msg ++) for (i = 0; i < width; i ++, msg ++)
@ -824,6 +827,7 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
sd->data[12] = 0x80; /* Supported group 1 functions */ sd->data[12] = 0x80; /* Supported group 1 functions */
sd->data[13] = 0x03; sd->data[13] = 0x03;
memset(&sd->data[14], 0, 3);
for (i = 0; i < 6; i ++) { for (i = 0; i < 6; i ++) {
new_func = (arg >> (i * 4)) & 0x0f; new_func = (arg >> (i * 4)) & 0x0f;
if (mode && new_func != 0x0f) if (mode && new_func != 0x0f)
@ -1676,7 +1680,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
return sd_illegal; return sd_illegal;
} }
static int cmd_valid_while_locked(SDState *sd, SDRequest *req) static int cmd_valid_while_locked(SDState *sd, const uint8_t cmd)
{ {
/* Valid commands in locked state: /* Valid commands in locked state:
* basic class (0) * basic class (0)
@ -1687,13 +1691,12 @@ static int cmd_valid_while_locked(SDState *sd, SDRequest *req)
* Anything else provokes an "illegal command" response. * Anything else provokes an "illegal command" response.
*/ */
if (sd->expecting_acmd) { if (sd->expecting_acmd) {
return req->cmd == 41 || req->cmd == 42; return cmd == 41 || cmd == 42;
} }
if (req->cmd == 16 || req->cmd == 55) { if (cmd == 16 || cmd == 55) {
return 1; return 1;
} }
return sd_cmd_class[req->cmd] == 0 return sd_cmd_class[cmd] == 0 || sd_cmd_class[cmd] == 7;
|| sd_cmd_class[req->cmd] == 7;
} }
int sd_do_command(SDState *sd, SDRequest *req, int sd_do_command(SDState *sd, SDRequest *req,
@ -1719,7 +1722,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
} }
if (sd->card_status & CARD_IS_LOCKED) { if (sd->card_status & CARD_IS_LOCKED) {
if (!cmd_valid_while_locked(sd, req)) { if (!cmd_valid_while_locked(sd, req->cmd)) {
sd->card_status |= ILLEGAL_COMMAND; sd->card_status |= ILLEGAL_COMMAND;
sd->expecting_acmd = false; sd->expecting_acmd = false;
qemu_log_mask(LOG_GUEST_ERROR, "SD: Card is locked\n"); qemu_log_mask(LOG_GUEST_ERROR, "SD: Card is locked\n");
@ -1980,7 +1983,7 @@ uint8_t sd_read_byte(SDState *sd)
{ {
/* TODO: Append CRCs */ /* TODO: Append CRCs */
uint8_t ret; uint8_t ret;
int io_len; uint32_t io_len;
if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable) if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable)
return 0x00; return 0x00;

View File

@ -52,7 +52,7 @@ sdcard_unlock(void) ""
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x" sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x" sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x" sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int length) "%s %20s/ CMD%02d len %d" sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t length) "%s %20s/ CMD%02d len %" PRIu32
sdcard_set_voltage(uint16_t millivolts) "%u mV" sdcard_set_voltage(uint16_t millivolts) "%u mV"
# milkymist-memcard.c # milkymist-memcard.c