diff options
author | Philippe Mathieu-Daudé <philmd@linaro.org> | 2024-06-20 11:57:54 +0200 |
---|---|---|
committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2024-07-05 23:53:57 +0200 |
commit | e7364ae74c51666e83f43975decb61b7f66cd409 (patch) | |
tree | d2549abe7a1ca93ebf205e8235d79ea52074c9da | |
parent | a7487722dc1c6bd278feb0a1ec58e9455cb3daa2 (diff) | |
download | qemu-e7364ae74c51666e83f43975decb61b7f66cd409.zip qemu-e7364ae74c51666e83f43975decb61b7f66cd409.tar.gz qemu-e7364ae74c51666e83f43975decb61b7f66cd409.tar.bz2 |
hw/sd/sdcard: Add sd_cmd_GEN_CMD handler (CMD56)
"General command" (GEN_CMD, CMD56) is described as:
GEN_CMD is the same as the single block read or write
commands (CMD24 or CMD17). The difference is that [...]
the data block is not a memory payload data but has a
vendor specific format and meaning.
Thus this block must not be stored overwriting data block
on underlying storage drive. Handle as RAZ/WI.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240703134356.85972-3-philmd@linaro.org>
-rw-r--r-- | hw/sd/sd.c | 54 |
1 files changed, 20 insertions, 34 deletions
@@ -243,7 +243,6 @@ static const char *sd_cmd_name(SDState *sd, uint8_t cmd) [25] = "WRITE_MULTIPLE_BLOCK", [26] = "MANUF_RSVD", [40] = "DPS_spec", - [56] = "GEN_CMD", [60] = "MANUF_RSVD", [61] = "MANUF_RSVD", [62] = "MANUF_RSVD", [63] = "MANUF_RSVD", }; @@ -902,9 +901,6 @@ static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len) } } -#define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len) -#define APP_WRITE_BLOCK(a, len) - static void sd_erase(SDState *sd) { uint64_t erase_start = sd->erase_start; @@ -1641,6 +1637,22 @@ static sd_rsp_type_t sd_cmd_APP_CMD(SDState *sd, SDRequest req) return sd_r1; } +/* CMD56 */ +static sd_rsp_type_t sd_cmd_GEN_CMD(SDState *sd, SDRequest req) +{ + if (sd->state != sd_transfer_state) { + return sd_invalid_state_for_cmd(sd, req); + } + + /* Vendor specific command: our model is RAZ/WI */ + if (req.arg & 1) { + memset(sd->data, 0, sizeof(sd->data)); + return sd_cmd_to_sendingdata(sd, req, 0, NULL, 0); + } else { + return sd_cmd_to_receivingdata(sd, req, 0, 0); + } +} + /* CMD58 */ static sd_rsp_type_t spi_cmd_READ_OCR(SDState *sd, SDRequest req) { @@ -1836,22 +1848,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req) case 26: /* CMD26: PROGRAM_CID */ return sd_cmd_to_receivingdata(sd, req, 0, sizeof(sd->cid)); - /* Application specific commands (Class 8) */ - case 56: /* CMD56: GEN_CMD */ - switch (sd->state) { - case sd_transfer_state: - sd->data_offset = 0; - if (req.arg & 1) - sd->state = sd_sendingdata_state; - else - sd->state = sd_receivingdata_state; - return sd_r1; - - default: - break; - } - break; - default: qemu_log_mask(LOG_GUEST_ERROR, "SD: Unknown CMD%i\n", req.cmd); return sd_illegal; @@ -2187,11 +2183,7 @@ void sd_write_byte(SDState *sd, uint8_t value) break; 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); - sd->state = sd_transfer_state; - } + sd_generic_write_byte(sd, value); break; default: @@ -2233,6 +2225,7 @@ uint8_t sd_read_byte(SDState *sd) case 22: /* ACMD22: SEND_NUM_WR_BLOCKS */ case 30: /* CMD30: SEND_WRITE_PROT */ case 51: /* ACMD51: SEND_SCR */ + case 56: /* CMD56: GEN_CMD */ sd_generic_read_byte(sd, &ret); break; @@ -2260,15 +2253,6 @@ uint8_t sd_read_byte(SDState *sd) } break; - 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 ++]; - - if (sd->data_offset >= sd->blk_len) - sd->state = sd_transfer_state; - break; - default: qemu_log_mask(LOG_GUEST_ERROR, "%s: unknown command\n", __func__); return 0x00; @@ -2323,6 +2307,7 @@ static const SDProto sd_proto_spi = { [52] = {9, sd_spi, "IO_RW_DIRECT", sd_cmd_optional}, [53] = {9, sd_spi, "IO_RW_EXTENDED", sd_cmd_optional}, [55] = {8, sd_spi, "APP_CMD", sd_cmd_APP_CMD}, + [56] = {8, sd_spi, "GEN_CMD", sd_cmd_GEN_CMD}, [57] = {10, sd_spi, "DIRECT_SECURE_WRITE", sd_cmd_optional}, [58] = {0, sd_spi, "READ_OCR", spi_cmd_READ_OCR}, [59] = {0, sd_spi, "CRC_ON_OFF", spi_cmd_CRC_ON_OFF}, @@ -2383,6 +2368,7 @@ static const SDProto sd_proto_sd = { [52] = {9, sd_bc, "IO_RW_DIRECT", sd_cmd_optional}, [53] = {9, sd_bc, "IO_RW_EXTENDED", sd_cmd_optional}, [55] = {8, sd_ac, "APP_CMD", sd_cmd_APP_CMD}, + [56] = {8, sd_adtc, "GEN_CMD", sd_cmd_GEN_CMD}, [57] = {10, sd_adtc, "DIRECT_SECURE_WRITE", sd_cmd_optional}, [58] = {11, sd_adtc, "READ_EXTR_MULTI", sd_cmd_optional}, [59] = {11, sd_adtc, "WRITE_EXTR_MULTI", sd_cmd_optional}, |